Compare commits

...

8 Commits

Author SHA1 Message Date
aweiker 7f31475330 Merge pull request 'fix(#157): add never-close constraint to spec, S9 invariant, and regression test' (#158) from issue-157 into main
CI / test (push) Successful in 18s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (push) Has been skipped
Reviewed-on: #158
Reviewed-by: security-review-bot <10+security-review-bot@noreply.gitea.weiker.me>
Reviewed-by: Aaron Weiker <aaron@weiker.org>
2026-05-15 22:56:44 +00:00
Rodin ec6fdbff42 fix(#158): address bot feedback — correct S8/S10 description, fix §9 prose break
PR Ready Gate / clear-labels (pull_request) Successful in 1s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 24s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 55s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 1m0s
2026-05-15 15:40:53 -07:00
aweiker 89596516d7 Merge pull request 'refactor(#154): extract baseSubprocessArgs helper in main_test.go subprocess tests' (#155) from issue-154 into main
CI / test (push) Successful in 19s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (push) Has been skipped
Reviewed-on: #155
Reviewed-by: security-review-bot <10+security-review-bot@noreply.gitea.weiker.me>
Reviewed-by: Aaron Weiker <aaron@weiker.org>
2026-05-15 21:28:41 +00:00
Rodin f883f39dbf fix(#158): address NIT feedback — clarify enforcement split, clean §9 prose
PR Ready Gate / clear-labels (pull_request) Successful in 2s
CI / test (pull_request) Successful in 18s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 22s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 24s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 1m7s
2026-05-15 11:06:49 -07:00
aweiker d3b9027da3 Merge pull request 'feat(#141): validate-docmap subcommand' (#156) from issue-141 into main
CI / test (push) Successful in 18s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (push) Has been skipped
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (push) Has been skipped
Reviewed-on: #156
Reviewed-by: security-review-bot <10+security-review-bot@noreply.gitea.weiker.me>
2026-05-15 17:43:05 +00:00
Rodin fb7d8d5e3b fix(#158): add S10 invariant to spec, fix enforcement wording in §8
PR Ready Gate / clear-labels (pull_request) Successful in 1s
CI / test (pull_request) Successful in 17s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 23s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 26s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 49s
Address MINOR and NIT findings from Sonnet and GPT review of PR #158.

MINOR (Sonnet + GPT): No static invariant for 'no close-PR in worker templates'.
- Add S10 to §6 Safety Invariants table: checks that no worker template contains
  close-PR API calls AND every template contains NEVER-close constraint text.
- Symmetric to S8 (no merge in worker templates) and S9 (no close in dispatch).

NIT (GPT): Enforcement mapping sentence in §8 was ambiguous.
- Rewrite to explicitly map: S1+S9 cover dispatch; S8+S10 cover worker templates.

NIT (Sonnet): The 'all 7 templates contain NEVER-close text' claim is now verified
by S10 (grep-based), not just prose.

Implementation: S10 added to check-invariants.sh + Bug-157-S10 regression tests
added to dispatch.bats (in rodin/workspace). All 11 invariants pass.
2026-05-15 10:26:14 -07:00
Rodin 282b6e0e86 nit(#154): add t.Fatal guard if baseSubprocessArgs flag not found
PR Ready Gate / clear-labels (pull_request) Successful in 2s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 22s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 38s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 40s
Address sonnet NIT: if --repo or --pr is ever removed from
baseSubprocessArgs(), the mutation loop silently no-ops and the test
becomes meaningless. Adding a found guard and t.Fatal makes the
regression immediately visible.
2026-05-15 08:06:18 -07:00
Rodin 6cefbb070e fix(#157): add S9 invariant and never-close constraint to dev-loop spec
CI / test (pull_request) Successful in 18s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 28s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 30s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Successful in 1m16s
- Add S9 to §6 Safety Invariants: zero close-PR API calls in dispatch
- Document worker ABSOLUTE CONSTRAINTS in §8 Worker Templates
- Add §9 entry for Issue #157 explaining the fix

All worker templates already contain the NEVER-close constraint from
a prior session. This commit makes the spec authoritative.

Companion changes in rodin/workspace:
- check-invariants.sh: add S9 static check
- dispatch.bats: add Bug-157-regression test
2026-05-15 14:47:54 +00:00
2 changed files with 34 additions and 1 deletions
+10
View File
@@ -903,12 +903,17 @@ func TestMainSubprocess_InvalidRepo(t *testing.T) {
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
args := baseSubprocessArgs()
// Replace the canonical --repo value with an invalid one.
found := false
for i, a := range args {
if a == "--repo" && i+1 < len(args) {
args[i+1] = "invalidrepo"
found = true
break
}
}
if !found {
t.Fatal("baseSubprocessArgs() does not contain --repo; test is broken")
}
os.Args = args
main()
return
@@ -930,12 +935,17 @@ func TestMainSubprocess_InvalidPRNumber(t *testing.T) {
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
args := baseSubprocessArgs()
// Replace the canonical --pr value with a non-numeric string.
found := false
for i, a := range args {
if a == "--pr" && i+1 < len(args) {
args[i+1] = "notanumber"
found = true
break
}
}
if !found {
t.Fatal("baseSubprocessArgs() does not contain --pr; test is broken")
}
os.Args = args
main()
return
+24 -1
View File
@@ -231,6 +231,8 @@ These are statically checked by `~/.openclaw/workspace/scripts/test/check-invari
| S6 | Active WIP does not cause early exit (only sets ACTIVE_WIP flag) |
| S7 | SPAWN:impl guarded by `ACTIVE_WIP == 0` check |
| S8 | No merge calls in any worker template |
| S9 | Zero close-PR API calls in dispatch script (`state=closed` does not appear) |
| S10 | No close-PR API calls in any worker template; every worker template contains `NEVER close a PR` |
---
@@ -263,9 +265,20 @@ Each worker receives a precise task description with substituted values:
Workers **always** remove the WIP label on completion and reply `NO_REPLY`.
### Worker Absolute Constraints
Every worker template begins with an `⛔ ABSOLUTE CONSTRAINTS` section containing these rules:
- **NEVER close a PR.** Never call `PATCH /pulls/{id}` with `state=closed`. Closing a PR requires human action. "Duplicate", "superseded", or "already done" are never a worker's call.
- **NEVER merge a PR.** Never call the merge API. Merging requires human approval.
- **NEVER use the gitea-aweiker token.** All API calls use the gitea-rodin token only.
- **NEVER act on a PR with active REQUEST_CHANGES.** Fix the findings first.
The first two constraints are statically enforced by `check-invariants.sh`: S1 and S9 cover the dispatch script (no merge, no close); S8 covers worker templates (no merge calls); S10 covers worker templates (no close calls, with NEVER-close text verified present in each). The remaining two constraints (token usage and REQUEST_CHANGES gate) are enforced by runtime logic.
---
## 9. Fixes for Issues #144 and #145
## 9. Fixes for Issues #144, #145, and #157
**Issue #144** (autonomous merge):
The dispatch script contains no merge API calls anywhere. The `~/.openclaw/workspace/scripts/test/check-invariants.sh`
@@ -276,3 +289,13 @@ Rule 2 is the **first** rule evaluated per PR. It cannot be skipped, reasoned pa
or bypassed. It is checked before CI, before self-review, before handoff. The check
uses latest-per-reviewer state, so a reviewer who re-approved after REQUEST_CHANGES
is correctly handled.
**Issue #157** (autonomous PR close):
Worker templates were missing an explicit constraint against closing PRs. The dispatch
script never had a close call, but workers could reason their way into calling
`PATCH /pulls/{id}` with `state=closed`. All worker templates now include
`NEVER close a PR` in their ABSOLUTE CONSTRAINTS section. Invariant S9 verifies
the dispatch script contains no close calls. Invariant S10 verifies
worker templates contain no close calls and each contains the NEVER-close text.
Regression tests in `dispatch.bats` statically verify all of these constraints.