opencode-swarm 7.124.0 → 7.125.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.opencode/skills/critic-gate/SKILL.md +8 -0
  2. package/.opencode/skills/swarm/SKILL.md +12 -8
  3. package/.opencode/skills/swarm-pr-feedback/SKILL.md +245 -171
  4. package/.opencode/skills/swarm-pr-feedback/references/bot-claim-verification.md +71 -0
  5. package/.opencode/skills/swarm-pr-feedback/references/operational-gotchas.md +49 -0
  6. package/.opencode/skills/swarm-pr-review/SKILL.md +238 -412
  7. package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +235 -0
  8. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +103 -0
  9. package/.opencode/skills/writing-tests/SKILL.md +4 -123
  10. package/.opencode/skills/writing-tests/references/mock-and-seam-inventory.md +43 -0
  11. package/README.md +3 -1
  12. package/dist/background/lane-output-store.d.ts +10 -0
  13. package/dist/background/pending-delegations.d.ts +3 -0
  14. package/dist/background/workspace-snapshot.d.ts +59 -0
  15. package/dist/cli/{config-doctor-53mnpeke.js → config-doctor-g3m2q646.js} +2 -2
  16. package/dist/cli/{curation-policy-ny033330.js → curation-policy-vgbx8530.js} +2 -2
  17. package/dist/cli/{curator-llm-factory-e0tjz8qq.js → curator-llm-factory-7pvqy94w.js} +15 -14
  18. package/dist/cli/{curator-nvn1pdq6.js → curator-xk4g1nx2.js} +15 -14
  19. package/dist/cli/{evidence-summary-service-9hq7n9k9.js → evidence-summary-service-v4h2w487.js} +1 -1
  20. package/dist/cli/{guardrail-explain-d3dd57nf.js → guardrail-explain-wfk16bpr.js} +16 -15
  21. package/dist/cli/{guardrail-log-3q2z9axs.js → guardrail-log-5zz9xx6z.js} +3 -3
  22. package/dist/cli/{hive-promoter-9gbpepgm.js → hive-promoter-njwc5rt0.js} +15 -14
  23. package/dist/cli/{pending-delegations-e3bcqj77.js → index-0cz1ws47.js} +4 -18
  24. package/dist/cli/{index-3yyr4ynk.js → index-3k8pg467.js} +1 -1
  25. package/dist/cli/{index-x2mmnrnx.js → index-83rwq7pb.js} +1 -1
  26. package/dist/cli/{index-c6crt5rs.js → index-8yvqkbw7.js} +12 -2
  27. package/dist/cli/{index-z0m4angq.js → index-93cq8t5b.js} +5 -5
  28. package/dist/cli/{index-8pz0ypxz.js → index-cz6fv84h.js} +17 -16
  29. package/dist/cli/{index-mkkx1a4f.js → index-dsf1yv4s.js} +1588 -891
  30. package/dist/cli/{index-4rzzzjtg.js → index-fs02c7tz.js} +277 -16
  31. package/dist/cli/{index-zjedv2bd.js → index-ghteqdy1.js} +2 -2
  32. package/dist/cli/{index-13d2g7k9.js → index-kvrk3h8p.js} +1 -1
  33. package/dist/cli/{index-eeg04r0x.js → index-kws8zn6y.js} +1 -1
  34. package/dist/cli/index-mg54y5gc.js +564 -0
  35. package/dist/cli/{index-qd77aft9.js → index-mhhmecsw.js} +2 -2
  36. package/dist/cli/{index-2x4maxte.js → index-mwdcvh0e.js} +4 -4
  37. package/dist/cli/{index-e19mxn9f.js → index-pbjenws7.js} +1 -1
  38. package/dist/cli/{index-wqwpzhv1.js → index-rpg8qqjs.js} +2 -2
  39. package/dist/cli/{index-tyg0zezw.js → index-tn3shyqj.js} +3 -3
  40. package/dist/cli/{index-htbjqftb.js → index-txragda9.js} +1 -1
  41. package/dist/cli/{index-v5ecczts.js → index-z4sc6yxc.js} +1 -1
  42. package/dist/cli/index.js +15 -14
  43. package/dist/cli/{knowledge-escalator-r1s01m3z.js → knowledge-escalator-jtyykzqc.js} +3 -3
  44. package/dist/cli/{knowledge-events-a9hmxvke.js → knowledge-events-qhr97sy9.js} +1 -1
  45. package/dist/cli/{knowledge-store-jt31br5k.js → knowledge-store-332x3pjv.js} +1 -1
  46. package/dist/cli/{knowledge-validator-9vrwxr3z.js → knowledge-validator-3t8tgzsz.js} +4 -4
  47. package/dist/cli/pending-delegations-7j8xqg5f.js +34 -0
  48. package/dist/cli/{scan-cursor-bkjtsawg.js → scan-cursor-q21c9k9q.js} +2 -2
  49. package/dist/cli/{schema-y3z416z7.js → schema-y2d7j2jk.js} +1 -1
  50. package/dist/cli/{skill-generator-794hyndw.js → skill-generator-3gkxx98d.js} +5 -5
  51. package/dist/cli/workspace-snapshot-c9pxxt9a.js +48 -0
  52. package/dist/commands/close.d.ts +4 -2
  53. package/dist/commands/registry.d.ts +1 -1
  54. package/dist/config/schema.d.ts +4 -0
  55. package/dist/evidence/documents-retention.d.ts +116 -0
  56. package/dist/evidence/manager.d.ts +17 -0
  57. package/dist/hooks/pr-workflow-gate.d.ts +211 -0
  58. package/dist/hooks/pr-workflow-response-gate.d.ts +23 -0
  59. package/dist/hooks/pr-workflow-session-resolver.d.ts +14 -0
  60. package/dist/index.js +563 -523
  61. package/dist/tools/complete-pr-workflow.d.ts +5 -0
  62. package/dist/tools/dispatch-lanes.d.ts +44 -0
  63. package/dist/tools/index.d.ts +2 -0
  64. package/dist/tools/manifest.d.ts +2 -0
  65. package/dist/tools/run-pr-feedback-stage-a.d.ts +69 -0
  66. package/dist/tools/tool-metadata.d.ts +8 -0
  67. package/dist/tools/write-pr-review-trigger-eval.d.ts +56 -46
  68. package/package.json +1 -1
  69. package/dist/cli/index-dqh3zhhc.js +0 -133
  70. package/dist/cli/workspace-snapshot-eyf6gd0d.js +0 -22
@@ -6,9 +6,9 @@ description: >
6
6
  Use when addressing pasted PR feedback, GitHub review comments or threads,
7
7
  requested changes, CI/check failures, merge conflicts, stale PR branches, or
8
8
  PR follow-up work that must close all known issues without dropping findings.
9
- Supports multi-round bot reviews when the repo uses an auto-review bot that
10
- posts a new review after every push (in opencode-swarm, `hermes-pr-review`)
11
- via the iterative pattern documented in the body. Stage A
9
+ Supports multi-round bot reviews when the repo uses an auto-review bot that
10
+ posts a new review after every push, via the iterative pattern documented in
11
+ the body. Stage A
12
12
  (structural pre-checks) and Stage B (reviewer + test_engineer) gates and the
13
13
  reviewer + critic closeout gate are MANDATORY for any change made as part of
14
14
  this process.
@@ -17,6 +17,7 @@ description: >
17
17
  # Swarm PR Feedback
18
18
 
19
19
  Use this skill to close known PR feedback. This is not a fresh broad PR review.
20
+ Repository-specific bot names and examples below are illustrative; substitute the repo's actual bot and branch-state surfaces when they differ.
20
21
  `swarm-pr-review` discovers new findings; `swarm-pr-feedback` ingests existing
21
22
  feedback surfaces, verifies each claim, clusters related problems, fixes confirmed
22
23
  issues, validates the branch, and reports closure status for every item.
@@ -25,7 +26,8 @@ issues, validates the branch, and reports closure status for every item.
25
26
  (reviewer + test_engineer) gates and the reviewer + critic closeout gate are
26
27
  MANDATORY for any change made as part of this process. No fix lands, no closure
27
28
  ledger row is marked FIXED, and no PR is published until all three gates pass on
28
- the current diff. See "Mandatory Gates" below for the full protocol.
29
+ the current diff. There is no speed, efficiency, or time exception. See
30
+ "Mandatory Gates" below for the full protocol.
29
31
 
30
32
  When the work starts from a prior `swarm-pr-review` run, ingest the review's
31
33
  handoff artifact (for example
@@ -43,10 +45,10 @@ fixes.
43
45
 
44
46
  ## Multi-Round Bot Reviews (Iterative Pattern)
45
47
 
46
- When the repo uses an auto-review bot in opencode-swarm, `hermes-pr-review`
47
- (Qwen3.6 + Gemma-4 dual-model) it posts a new review comment after **every
48
- push** to the PR branch, not just the final state. Expect N rounds of review for
49
- N pushes, and budget for it.
48
+ When the repo uses an auto-review bot that posts a new review comment after
49
+ **every push** to the PR branch, identify that bot from the repository contract
50
+ and apply this pattern (for example `hermes-pr-review` in this repo). Expect N
51
+ rounds of review for N pushes, and budget for it.
50
52
 
51
53
  **Round N+1 deltas vs Round N:**
52
54
  - Fresh `FB-###` ledger IDs for new findings (do not reuse IDs from earlier rounds)
@@ -63,12 +65,15 @@ N pushes, and budget for it.
63
65
  2. **Carry forward unresolved items.** Findings you marked `PARTIAL` or `NEEDS_USER_DECISION`
64
66
  in round N will still be open in round N+1. The closure ledger should show their
65
67
  evolution (e.g., "PARTIAL round 1 → CONFIRMED round 2 after evidence collected").
66
- 3. **Apply the 3-strikes-then-defense-in-depth rule.** When the same finding is
67
- raised 3+ times across rounds, prefer to add the suggested code change with a
68
- defense-in-depth rationale comment rather than continue to debate. One extra
69
- condition is cheap; per-round debate is expensive. Document the parent-vs-inner
70
- relationship inline so future readers see the rationale.
71
- **When not to apply 3-strikes:** If the suggested fix would add incorrect or
68
+ 3. **Apply the 3-strikes evidence-escalation rule.** When the same finding is
69
+ raised 3+ times across rounds, re-run source verification with a fresh
70
+ reviewer context and surface the disagreement explicitly. Add a
71
+ defense-in-depth change only when that fresh verification proves the change
72
+ is correct, preserves the real invariant, and adds meaningful protection.
73
+ Repetition, time, token cost, and reviewer persistence are never substitutes
74
+ for evidence. Document any parent-vs-inner relationship inline so future
75
+ readers see the rationale.
76
+ **Do not add the repeated suggestion:** If it would add incorrect or
72
77
  misleading code about existing guards — e.g., an outer guard that already exists at an
73
78
  inner scope and whose addition would imply the inner guard is absent, a type
74
79
  narrowing that masks a real error class, or a check whose presence asserts a
@@ -96,71 +101,9 @@ N pushes, and budget for it.
96
101
  each round's work is bounded by new findings + carried-forward items only.
97
102
  This matches how the bot actually behaves and avoids wasted cycles.
98
103
 
99
- ### Bot Review Verification Traps
100
-
101
- When a bot or pasted review cites a code fact, verify the fact against the
102
- current branch before editing:
103
-
104
- - **Import/export claims:** Check the exact import path used by the changed file.
105
- A symbol may be missing from an internal submodule but correctly exported by the
106
- public barrel the tests or runtime actually import.
107
- - **Line numbers:** Treat bot line references as approximate after any follow-up
108
- push or local edit. Re-locate the symbol or block with `rg` before patching.
109
- - **Ordering claims:** If the concern is about rule precedence, add or run a
110
- direct precedence test that would fail under the wrong ordering; comments alone
111
- are not enough.
112
- - **Disproved findings:** Do not change unrelated code to satisfy a false claim.
113
- Keep the finding in the closure ledger with the source or test evidence that
114
- disproves it.
115
- - **Cache/state claims:** Test both relevant state orders when the behavior
116
- depends on cache priming, singleton state, or prior calls.
117
-
118
- ### Automated Security Finding Verification
119
-
120
- Automated security bots (e.g., hermes-pr-review, CodeRabbit, Gemini) frequently
121
- produce findings rated CRITICAL or HIGH that are false positives. In a recent
122
- PR review cycle, 7/7 bot security findings were false positives upon source
123
- verification. Before acting on any bot security finding, perform these
124
- source-level checks:
125
-
126
- 1. **`child_process.exec` vs `RegExp.exec`**: SAST rules pattern-match on
127
- `.exec(` and cannot distinguish `child_process.exec(userInput)` (real
128
- injection risk) from `/^pattern$/.exec(str)` (safe regex test). Read the
129
- actual line to determine which `.exec` is called.
130
-
131
- 2. **Schema validation already present**: Bots may flag "missing type
132
- validation" without checking the Zod schema. Search for the field name in
133
- `src/config/schema.ts` — `z.number().int()`, `z.string().min()`, etc. are
134
- runtime validators that run before the code path the bot reviewed.
135
-
136
- 3. **`Object.assign` mutation claims**: Bots may claim `Object.assign` mutates
137
- the source object. Check whether the call is `Object.assign(target, source)`
138
- (mutates target) vs `Object.assign({}, source)` or a manual copy loop into a
139
- new `{}` (creates a new object, source is safe). Read the actual assignment.
140
-
141
- 4. **Path containment for system-generated paths**: Bots may flag "path
142
- traversal" on file paths. Check whether the path is user-controlled (real
143
- risk) or system-generated from `provisionWorktree`, `mkdtempSync`, or
144
- similar (no user input reaches the path). Trace the variable's origin.
145
-
146
- 5. **Value validation vs key validation**: Bots may suggest validating env var
147
- *values* for shell injection characters. Check whether the value is passed
148
- through a sandbox executor that escapes arguments (e.g., `wrapCommand`
149
- which returns a shell-quoted / `psStringEscape`-escaped string for the
150
- `bunSpawn` array-form argv to consume). Value validation would break
151
- legitimate env vars (PATH with `;`, URLs with `$`); escaping is the
152
- sandbox's job — see `engineering-conventions` § "Sandbox env overrides"
153
- for the full escape contract.
154
-
155
- 6. **Deduplication for independent resources**: Bots may suggest deduplicating
156
- cache redirects or env var entries. Check whether the entries map to
157
- independent keys (different env var names) — independent keys cannot
158
- "collide" and deduplication is nonsensical.
159
-
160
- **Rule:** For any bot finding rated CRITICAL or HIGH, read the actual source
161
- line AND its surrounding context (parent function, schema definition, type
162
- annotations) before accepting the finding. If the finding is disproved, record
163
- it in the closure ledger with the specific source evidence that disproves it.
104
+ ### Bot and Security Claim Verification
105
+
106
+ Before trusting automated review findings (SAST bots, security scanners, AI reviewers), apply the verification protocol in `references/bot-claim-verification.md`. Key principle: every bot claim is unverified until you reproduce the exact finding against the current HEAD with the exact tool and rule it names.
164
107
 
165
108
  ## Operating Stance
166
109
 
@@ -187,11 +130,12 @@ tree:
187
130
 
188
131
  - If `head_ref` is a remote branch that is not checked out locally, fetch it
189
132
  (`git fetch origin <head_ref>`).
190
- - **Check for parallel work first.** Before checkout, run
191
- `file:.swarm/bundled-skills/parallel-work-check/SKILL.md` to
192
- detect concurrent pushes from other agents (e.g., `hermes-pr-review` bot
193
- following up, maintainer pushing fixes, parallel swarm work). If remote has new
194
- commits: read `git log local..remote`, evaluate whether the parallel work
133
+ - **Check for parallel work first.** Before checkout, use the repository or
134
+ runtime's parallel-work check. When the bundled
135
+ `parallel-work-check` skill exists, it is one conditional implementation to
136
+ detect concurrent pushes from other agents (for example the repo's
137
+ auto-review bot following up, a maintainer pushing fixes, or parallel swarm
138
+ work). If remote has new commits: read `git log local..remote`, evaluate whether the parallel work
195
139
  supersedes your planned fixes, and prefer the parallel work if it's more
196
140
  comprehensive (more tests, better edge coverage, clearer error handling).
197
141
  Abort your rebase, take the remote state, then add minor improvements on top.
@@ -200,12 +144,18 @@ tree:
200
144
  - **Check out the head branch locally.** Feedback verification reads the working-tree
201
145
  filesystem (`Read`/`Glob`/`Grep`), and fixes must land on the PR branch — without a
202
146
  checkout you would verify and patch the base branch's code instead. Record the
203
- `base_ref..head_ref` range for diff-scoped inspection.
204
- - Pass the `base_ref..head_ref` commit range in every read-only verification or
147
+ exact `merge_base...head_ref` range for diff-scoped inspection.
148
+ - Pass the exact `merge_base...head_ref` commit range in every read-only verification or
205
149
  explorer/advisory-lane delegation so lane agents can inspect specific revisions
206
150
  with `git show` when needed.
207
151
  - If no PR reference was provided (a pasted-feedback session on the current branch),
208
152
  confirm the current branch is the intended PR branch before editing.
153
+ - If the fetched PR head is detached or has no local tracking branch, establish
154
+ it only during this pre-bind transition with the constrained existing-remote
155
+ form `git switch -c <local-branch> --track <remote>/<remote-branch>` (or set
156
+ the upstream of an existing local branch with
157
+ `git branch --set-upstream-to=<remote>/<remote-branch> <local-branch>`).
158
+ Branch creation/tracking is blocked after the immutable head is bound.
209
159
 
210
160
  When a verification lane result includes `output_ref`, treat `output` as a
211
161
  preview and call `retrieve_lane_output` before using it to classify, resolve,
@@ -218,9 +168,7 @@ ledger items as `NEEDS_MORE_EVIDENCE` or re-dispatch a narrower read-only lane.
218
168
  Before staging any files for the PR commit, check the working tree state:
219
169
 
220
170
  **The problem:** `git add -A` stages every uncommitted change in the working tree,
221
- including pre-existing changes from other branches or prior work. This was hit twice
222
- in one session during PR #1472 review, producing a 59-file commit instead of the
223
- intended 2-file targeted fix.
171
+ including pre-existing changes from other branches or prior work.
224
172
 
225
173
  **The check:** Run `git status --porcelain` first. If output is non-empty, identify
226
174
  which files are PR-related vs pre-existing uncommitted changes.
@@ -235,29 +183,19 @@ git add src/foo.ts tests/foo.test.ts
235
183
  Never use `git add -A` when the working tree has pre-existing changes from other
236
184
  branches or prior work sessions.
237
185
 
238
- *Reference: Caught during PR #1472 Round 1 closure.*
239
-
240
186
  ## Batch Collection (mandatory before any fix)
241
187
 
242
- Read `file:.swarm/bundled-skills/ci-failure-batching/SKILL.md` for the full batch collection and fix protocol before proceeding.
243
-
244
- Issue #1746: 8+ push cycles where 3–4 would have sufficed with batching.
245
- The anti-pattern: iterating check-by-check, proposing a fix for one failure,
246
- pushing, waiting for CI, then discovering the next failure. Each cycle costs
247
- one push + one CI run.
188
+ When the runtime provides a CI-failure-batching workflow, load it before
189
+ proceeding. The bundled `ci-failure-batching` skill is one conditional
190
+ implementation; otherwise apply the host-neutral complete-ledger protocol
191
+ below.
248
192
 
249
- **The fix:** Collect all failures and their logs in one batch operation before
250
- proposing any fix.
193
+ For the detailed 6-step batch collection protocol, read `file:.swarm/bundled-skills/ci-failure-batching/SKILL.md`. The steps below are a summary:
251
194
 
252
- 1. `gh pr checks <n> --json name,bucket,state,link` get every check,
253
- its bucket/state, and the URL to its run details.
254
- 2. Filter to failing checks (`bucket == "fail"` | `bucket == "cancel"`).
255
- 3. For each failing check, extract the run ID from `link` and run
256
- `gh run view <run-id> --log-failed` to fetch the full log output.
257
- 4. Build a complete failure ledger: all checks + all failure logs collected.
258
- 5. Triage the full ledger to identify root causes.
259
- 6. Propose fixes for all failures in **one batch** — do not iterate
260
- check-by-check through push cycles.
195
+ 1. `gh pr checks <number> --json name,bucket,state,link` to collect all check results
196
+ 2. Filter to `bucket == "fail"` or `bucket == "cancel"`
197
+ 3. `gh run view <id> --log-failed` for each failing run
198
+ 4. Group failures by root cause before fixing
261
199
 
262
200
  **Rule:** The complete failure ledger must be collected before any
263
201
  modification is proposed. Verifying the ledger is complete is a prerequisite
@@ -265,6 +203,12 @@ for the Fix Planning step.
265
203
 
266
204
  ## Pre-flight: Scope Discipline
267
205
 
206
+ The following `save_plan` / `declare_scope` mechanics apply only when those
207
+ plugin tools are available. In other repositories or runtimes, use the native
208
+ scope controller; if none exists, put exact allowed files and non-goals in the
209
+ delegation and verify the resulting diff mechanically. Never bypass an
210
+ available scope controller merely to reduce ceremony.
211
+
268
212
  `declare_scope({ taskId, files })` enforces that the delegated coder agent may only modify the declared files. The enforcement requires an active `.swarm/plan.json` — calling `declare_scope` in a feedback-closure run (which does not go through `save_plan`) rejects with "No plan found."
269
213
 
270
214
  **When to use `declare_scope` (preferred):** any feedback round that touches 2+ files, OR any feedback round where the file scope is not 100% obvious from the prompt. Before delegating, save a minimal plan via `save_plan` with a single phase containing the feedback-closure tasks, then call `declare_scope` per task with the exact file list.
@@ -292,12 +236,17 @@ If a source is unavailable, retry with alternative access paths. If unavailable
292
236
  ### Async advisory verification lanes
293
237
 
294
238
  After the complete feedback ledger exists and before editing, use
295
- `dispatch_lanes_async` when available for independent read-only verification lanes:
239
+ `dispatch_lanes_async` with `mode: "swarm-pr-feedback:verification"`, the
240
+ complete immutable `feedback_inventory` ID list, the exact current
241
+ `pr_head_sha`, and each lane's exact
242
+ `feedback_item_ids` ownership list for independent read-only verification lanes:
296
243
  comment classification, CI/log root-cause inspection, test impact mapping,
297
244
  release/docs claim checks, and stale-branch/conflict analysis. Partition the
298
245
  ledger so each `FB-###` item is owned by exactly one verification lane and the
299
246
  union of lanes covers the entire ledger — no feedback item may be left
300
- unassigned to a lane; state each lane's owned `FB-###` range in its prompt. Scale
247
+ unassigned to a lane; state each lane's owned IDs both structurally and in its
248
+ prompt. The runtime rejects missing, duplicate, overlapping, or unknown item
249
+ ownership and blocks mutation until the verification batch settles. Scale
301
250
  the lane count to the ledger size: a 1–3 item round may use a single combined
302
251
  lane, while a large multi-round intake may warrant one lane per category above.
303
252
  Cap each `dispatch_lanes_async` batch at 8 lanes (`MAX_LANES`); if the ledger
@@ -308,6 +257,15 @@ architect work: normalize feedback IDs, gather deterministic PR metadata, prepar
308
257
  reproduction commands, and plan likely fix groups. Do not edit, close items, or
309
258
  mark feedback resolved from running lanes.
310
259
 
260
+ Every verification lane must end with one parseable row for each owned item:
261
+
262
+ ```text
263
+ [FEEDBACK-VERIFIED] | FB-### | CONFIRMED/PARTIAL/DISPROVED/PRE_EXISTING/NEEDS_MORE_EVIDENCE/NEEDS_USER_DECISION | evidence
264
+ ```
265
+
266
+ Non-empty prose without this marker contract is not a settled verification
267
+ artifact and cannot unlock mutation.
268
+
311
269
  Before the Verification step can mark any item `CONFIRMED`, `PARTIAL`,
312
270
  `DISPROVED`, `PRE_EXISTING`, `NEEDS_MORE_EVIDENCE`, or `NEEDS_USER_DECISION`,
313
271
  every open verification batch must be fully settled. Poll with
@@ -319,10 +277,12 @@ exhausted, to confirm every lane is settled.
319
277
  Missing, stale, cancelled, or failed lanes are coverage gaps that must be closed
320
278
  before marking any item CONFIRMED/PARTIAL/DISPROVED/PRE_EXISTING. Apply the
321
279
  COVERAGE GATE:
322
- retry failed lanes (max 2), deploy a verified equivalent alternative (same agent
323
- type, same prompt, same scope, same isolation, with Task-tool dispatch as the
324
- final fallback when lane tools do not work), or stop and surface the lane failure
325
- to the user as BLOCKED.
280
+ retry failed lanes (max 2) as another
281
+ `swarm-pr-feedback:verification` async batch with the same immutable inventory,
282
+ exact `pr_head_sha`, agent type, prompt, scope, and isolation, or stop and
283
+ surface the lane failure to the user as BLOCKED. Blocking and direct-Task
284
+ fallbacks are rejected because they cannot satisfy the durable ownership and
285
+ head-provenance gate.
326
286
  Do not proceed with "blocking verification and record that async advisory lanes
327
287
  were unavailable" — record-and-continue is not coverage closure.
328
288
 
@@ -351,6 +311,12 @@ entire pipeline. Before triaging, check:
351
311
 
352
312
  ### PR body claim verification
353
313
 
314
+ The `.swarm/evidence/` paths below apply only when the reviewed repository uses
315
+ this plugin's council evidence contract. For any other repository, locate the
316
+ authoritative CI attestation, code-host review record, or repository-declared
317
+ evidence store; the universal rule is that an approval claim needs a real,
318
+ retrievable provenance artifact.
319
+
354
320
  PR body text like "PHASE 2 council APPROVED (5/5, round 2)" or "Final council
355
321
  APPROVED" must be backed by an evidence file under `.swarm/evidence/` — phase
356
322
  councils write `.swarm/evidence/{phaseNumber}/phase-council.json`; the final
@@ -466,23 +432,7 @@ Verification checklist:
466
432
 
467
433
  ### DI seam migration validation
468
434
 
469
- When a test file mutates a DI seam object (e.g., `_internals.foo = mock`),
470
- verify that the production source reads from the seam at call time. A common
471
- anti-pattern: the test mutates the seam object, but the production code
472
- imports the named function (`import { foo } from './module'`) which is bound
473
- at module load. The seam mutation has no effect on the named reference,
474
- so the test fails even though the seam object's `foo === mock`.
475
-
476
- Verification: open the source file and grep for call sites. If you see
477
- `import { foo } from '...'` followed by `foo(...)` in the production code,
478
- and the test does `_internals.foo = mock`, the test will fail. The fix is
479
- to change the production code to call `_internals.foo(...)` (or equivalent
480
- active-seam pattern) so the seam mutation is read at call time.
481
-
482
- If only a few call sites exist, fix them in the source. If many call sites
483
- exist, consider whether the migration should use `mock.module()` instead,
484
- which replaces the entire module object (including the named export
485
- reference).
435
+ When the repository uses `_internals` seam / `mock.module()` patterns, apply the validation protocol in `references/operational-gotchas.md`.
486
436
 
487
437
  ## Fix Planning
488
438
 
@@ -523,25 +473,9 @@ or compatibility policy, mark the item `NEEDS_USER_DECISION` and ask.
523
473
  and let the merge queue perform final current-base validation. Still resolve real
524
474
  merge conflicts and SHA-dependent review threads before queuing.
525
475
 
526
- ### Operational Gotchas
527
-
528
- - **Plan identity change:** When switching from a review plan to a feedback-closure
529
- plan, `save_plan` rejects with `PLAN_IDENTITY_MISMATCH`. Pass
530
- `confirm_identity_change: true` to acknowledge the intentional overwrite.
531
- - **Stale gate evidence:** After a plan identity change, `check_gate_status` returns
532
- timestamps from the *prior* plan. Reset task statuses and re-run Stage A gates
533
- before trusting gate results. Do not accept cached gate verdicts from before the
534
- identity change.
535
- - **PowerShell PR comment posting:** Complex markdown bodies containing backticks,
536
- dollar signs, or nested quotes fail in PowerShell here-strings. Write the body
537
- to a temp file and use `gh pr comment <number> --body-file <tempfile>` instead
538
- of inline `--body "..."`.
539
- - **Same-file batching:** Multiple findings targeting the same file for the same
540
- review cycle CAN be fixed in one coder task when the fixes are trivially
541
- independent (e.g., a one-line guard and a typo fix). When findings require
542
- different fixes on different code paths, use separate coder tasks even if
543
- targeting the same file. The "ONE task per coder" rule is about distinct
544
- objectives, not about N edits to one file.
476
+ ### Conditional runtime/host gotchas
477
+
478
+ For portability gotchas (plan identity, stale gate evidence, PowerShell comment posting, same-file batching), read `references/operational-gotchas.md`.
545
479
 
546
480
  ## Mandatory Gates
547
481
 
@@ -554,6 +488,64 @@ pre-checks; Stage B = `reviewer` + `test_engineer` per-task gates (consistent
554
488
  with `execute`, `plan`, `specify`, `brainstorm`, `docs/swarm-briefing.md`, and
555
489
  `docs/council/README.md`).
556
490
 
491
+ **Mechanical controller contract.** Prose acknowledgements, direct `Task` calls,
492
+ blocking dispatch, reused conversations, and free-form `APPROVE`/`PASS` text do
493
+ not satisfy these gates. The durable controller requires this exact sequence on
494
+ one content digest:
495
+
496
+ Controller authority follows the parent/child session ancestry. Coder and
497
+ nested child tool calls inherit the parent feedback gate; delegation never
498
+ grants early commit, push, remote-write, checkout, or protected-evidence
499
+ authority.
500
+
501
+ 1. `run_pr_feedback_stage_a` with array-form commands for every concrete
502
+ workspace/category/source build, typecheck, and lint/format obligation
503
+ mechanically discovered from the repository's manifests, configs, scripts,
504
+ or bounded `.pr-validation.json` contract, plus exact
505
+ `["git", "diff", "--check"]`. A category with no repository-local signal is
506
+ not invented merely to reach a fixed command count.
507
+ Add one required proof command: use the exact failing CI/test reproduction
508
+ when the immutable inventory includes a defect or CI/test failure; otherwise
509
+ add a repo-appropriate targeted regression/test command that exercises the
510
+ changed behavior. The tool executes the commands; naming a category without
511
+ executing it is not evidence. The controller binds that reproduction receipt
512
+ to the complete immutable feedback inventory, so no feedback item can reach
513
+ Stage B with an unrelated or unowned Stage A receipt.
514
+ 2. One `dispatch_lanes_async` lane with
515
+ `mode: "swarm-pr-feedback:stage-b-reviewer"`,
516
+ `workflow_lane: "stage-b-reviewer"`, every immutable
517
+ `feedback_item_ids`, and `max_concurrent: 1`.
518
+ 3. After that lane settles positively, one fresh `test_engineer` lane with
519
+ `mode: "swarm-pr-feedback:stage-b-test"`, matching `workflow_lane`, the
520
+ complete inventory, and `max_concurrent: 1`.
521
+ 4. After Stage B settles, one separate fresh reviewer lane with
522
+ `mode: "swarm-pr-feedback:closeout-reviewer"`, then one separate fresh
523
+ critic lane with `mode: "swarm-pr-feedback:closeout-critic"`. Each owns the
524
+ complete inventory and uses `max_concurrent: 1`.
525
+
526
+ Every gate lane emits exactly one fully populated row per feedback ID:
527
+
528
+ ```text
529
+ [STAGE-B-REVIEW] | FB-001 | APPROVE|NEEDS_REVISION|BLOCKED | evidence
530
+ [STAGE-B-TEST] | FB-001 | PASS|FAIL|BLOCKED | evidence
531
+ [CLOSEOUT-REVIEW] | FB-001 | APPROVE|NEEDS_REVISION|BLOCKED | evidence
532
+ [CLOSEOUT-CRITIC] | FB-001 | APPROVE|NEEDS_REVISION|BLOCKED | evidence
533
+ ```
534
+
535
+ Only exact positive verdict fields pass. A sentence containing “not APPROVE,” a
536
+ header without item rows, duplicate rows, missing IDs, degraded/truncated
537
+ artifacts, wrong roles, stale content digests, parallel or out-of-order phases,
538
+ and reused pre-edit approvals all fail closed. Any content change after Stage A
539
+ invalidates Stage A and every later gate; restart at step 1. Publication tools
540
+ and `git commit`/`git push` remain blocked until all four ordered lane phases
541
+ settle on the Stage-A digest. After they settle, only one standalone `git commit`
542
+ command may create the reviewed commit; push and remote publication remain
543
+ blocked until that exact commit is armed. The first completion requires a clean
544
+ index/worktree and a non-merge direct child commit whose sole parent is the
545
+ immutable intake head, so zero commits, multiple commits, merge commits,
546
+ amend/non-descendant histories,
547
+ `--allow-empty`, and partially committed reviewed content fail closed. There is no speed, efficiency, token, or time exception.
548
+
557
549
  If a gate failure is suspected pre-existing, prove it on the base branch or
558
550
  label it `UNVERIFIED`. Do not call the branch green while required checks are
559
551
  non-green.
@@ -564,13 +556,56 @@ Run for every changed surface. No "where relevant" — every PR-feedback change
564
556
  runs these; if a surface is genuinely untouched, state that explicitly rather
565
557
  than skipping silently.
566
558
 
567
- - `bun run build` (or the repository's build command) — must succeed.
568
- - typecheck must pass.
569
- - lint/format (e.g. `biome ci .`) must pass.
559
+ - the repository's actual build validation for the changed surface — must
560
+ succeed when that surface participates in a build,
561
+ - the repository's actual typecheck/static-analysis validation for the changed
562
+ surface — must pass when such a check exists,
563
+ - the repository's actual lint/format validation for the changed surface — must
564
+ pass when such a check exists,
570
565
  - `git diff --check` — no whitespace or merge-marker errors.
571
- - exact failing CI/test command reproduced locally when a ledger item is rooted
572
- in a CI/test failure the reproduction must fail on the pre-fix tree and pass
573
- after the fix.
566
+ - one proof command is mandatory on every run:
567
+ - use the exact failing CI/test command when a ledger item is rooted in a
568
+ defect or CI/test failure; the reproduction must fail on the pre-fix tree
569
+ and pass after the fix.
570
+ - otherwise run a repo-appropriate targeted regression/test command that
571
+ exercises the changed behavior and passes on the post-fix tree.
572
+
573
+ Execute these through `run_pr_feedback_stage_a` when available. Its bounded
574
+ array-form commands are not arbitrary shell escape hatches: diff-check and a
575
+ targeted reproduction are unconditional, every mechanically discovered
576
+ workspace/category/source obligation is also required, and each command must
577
+ match its declared build/typecheck/lint/diff-check/reproduction intent. Multiple
578
+ commands in one category are mandatory when polyglot or monorepo discovery
579
+ produces multiple obligations; use the exact `working_directory` and
580
+ `obligation_id` for each. Every obligation ID gets exactly one independently
581
+ executed receipt; identical commands remain separate only when distinct
582
+ repository sources mechanically require them. The
583
+ reproduction command must name at least one exact test, package, path, or
584
+ regression selector in `targets`. Invoke recognized validators and test runners
585
+ directly. Standard contained `./gradlew` and `./mvnw` wrappers are supported. A
586
+ repository with a custom validator can declare its exact array-form command in a
587
+ bounded `.pr-validation.json` version-1 contract that is byte-identical to
588
+ the immutable `base_ref`/`base_sha` merge-base copy and reference the exact
589
+ contract path/id. A contract added or changed by the PR never authorizes a
590
+ command. When that trusted contract replaces an otherwise opaque named
591
+ package script, the controller preserves the contract identity on the discovered
592
+ obligation and receipt, requires non-empty execution evidence, and permits only
593
+ an exact inspected npm, pnpm, yarn, or Bun script selection. Unsupported
594
+ workspace-glob semantics fail closed rather than silently omitting a workspace.
595
+ Arbitrary opaque scripts and unverified package-script names remain non-proof
596
+ because a name such as `test` or `build` can hide a no-op. A
597
+ reproduction must also return non-empty machine-observable runner output.
598
+ The reproduction check also supplies one `feedback_targets` row per immutable
599
+ feedback ID, in inventory order: exact `feedback_item_id`, one executed `target`,
600
+ and concrete `expected_behavior`. Missing, duplicate, invented, or target-less
601
+ mappings block Stage B; the controller persists that exact per-item mapping
602
+ rather than stamping an unrelated test onto the whole inventory.
603
+ No-op/help/list/dry-run,
604
+ fix/update, package publication/deployment, Git mutation, remote client,
605
+ shell/eval/wrapper, and credentialed publication surfaces fail closed. The
606
+ controller snapshots the content revision plus HEAD, index, refs, upstream, and
607
+ Git config before and after every command (including failures/timeouts); any
608
+ mutation invalidates Stage A and prevents later commands from becoming proof.
574
609
 
575
610
  ### Stage B — reviewer + test_engineer (mandatory after Stage A passes)
576
611
 
@@ -582,15 +617,18 @@ risks the test_engineer pinning a not-yet-approved fix shape.
582
617
  - **reviewer** — independent (fresh context, not the implementer, not a continued
583
618
  conversation). Validates each fix on the current diff against the feedback
584
619
  item it closes. Verdict per item: APPROVE / NEEDS_REVISION / BLOCKED.
585
- - **test_engineer** — writes and runs the falsification probe or regression test
586
- that proves each fix actually resolves its item (tests for changed behavior or
587
- newly covered gaps). Verdict per item: PASS / FAIL / BLOCKED.
588
-
589
- Address every NEEDS_REVISION / BLOCKED / FAIL, then re-run the affected agent on
590
- the current diff. When the test_engineer authors or modifies test files during
591
- Stage B, re-run the Stage A structural pre-checks (build / typecheck / lint)
592
- over those test files before the Stage B verdict is considered final Stage A
593
- must be green over the full Stage-B-inclusive diff.
620
+ - **test_engineer** — independently designs and runs the falsification probe or
621
+ regression test that proves each fix resolves its item (tests for changed
622
+ behavior or newly covered gaps). The structured gate lane is read-only: if a
623
+ missing test must be authored, return `FAIL` with the exact requested probe so
624
+ implementation can add it before the sequence restarts. Verdict per item:
625
+ PASS / FAIL / BLOCKED.
626
+
627
+ Address every NEEDS_REVISION / BLOCKED / FAIL, then restart at Stage A on the
628
+ current diff. When implementation authors or modifies test files requested by
629
+ the test_engineer, the content-digest controller invalidates all earlier
630
+ receipts automatically. Stage A must be green over the full Stage-B-inclusive
631
+ diff before a new Stage B reviewer and test engineer run.
594
632
 
595
633
  ### Closeout gate — reviewer + critic (mandatory after Stage B)
596
634
 
@@ -613,10 +651,9 @@ reviewer's or critic's approval invalidates that approval** — re-run the
613
651
  affected gate on the current diff before publishing.
614
652
 
615
653
  Record both closeout verdicts (reviewer + critic, with HEAD/diff) in the
616
- runtime's session task-gates artifact (e.g. `.claude/session/tasks/<slug>/gates.md`
617
- under Claude Code, or the OpenCode/Codex equivalent) per the
618
- `durable-session-state` skill (`.swarm/` is the plugin's runtime state — never
619
- write task artifacts there).
654
+ runtime's session task-gates artifact using the repository/runtime-specific
655
+ durable-session guidance when one exists. `.swarm/` is the plugin's runtime
656
+ state never write task artifacts there.
620
657
 
621
658
  ### Post-publish verification (mandatory after the PR is pushed)
622
659
 
@@ -632,8 +669,35 @@ pre-checks and must not be folded into Stage A.
632
669
 
633
670
  ## Publishing And Communication
634
671
 
635
- Commits and pushes follow `file:.swarm/bundled-skills/commit-pr/SKILL.md` (the
636
- repository's commit/PR workflow) do not push ad-hoc.
672
+ After every ordered local gate passes on one unchanged content digest, create
673
+ the reviewed commit with one standalone `git commit` command. Then call
674
+ `complete_pr_workflow` once with `mode: "PR_FEEDBACK"` and the immutable intake
675
+ `pr_head_sha`. A `ready-to-publish` result arms publication but deliberately
676
+ keeps the durable gate active and binds that post-commit HEAD to the current
677
+ branch's exact upstream remote-tracking ref. Configure the repository's intended
678
+ PR-branch upstream before committing and arming. Push is blocked before this
679
+ transition. Arming fails unless the index/worktree are clean and the bound HEAD
680
+ is a non-merge direct child whose sole parent is the immutable intake head. Any content
681
+ mutation or amend after it is blocked; restart at Stage A if the approved
682
+ content must change.
683
+
684
+ After arming, publish with exactly one non-force, single-ref command of the
685
+ form `git push <bound-remote> <bound-commit>:refs/heads/<bound-branch>`. The
686
+ source must be the literal commit ID bound by the first completion call, not
687
+ `HEAD`; the destination must be the branch behind the bound upstream
688
+ remote-tracking ref. Force flags, mirror/all/tags/delete operations, extra
689
+ refspecs, URLs, wrappers, `git -C`, `gh` writes, aliases, and other publication
690
+ surfaces fail closed. Read-only inspection remains available. Immediately
691
+ after the exact push and read-only remote verification, call
692
+ `complete_pr_workflow` again to prove the bound remote-tracking ref points at
693
+ the bound commit. Completion also performs a bounded query of the actual remote
694
+ branch; a locally forged or fetched tracking ref is never publication proof.
695
+ The gate clears only after both observations agree, before any PR
696
+ comment/body/thread write.
697
+
698
+ Commits and pushes follow the repository's commit/PR workflow (for example
699
+ `file:.swarm/bundled-skills/commit-pr/SKILL.md` when that bundled workflow is
700
+ available) — do not push ad-hoc.
637
701
 
638
702
  After fixes, update the PR body or comment with a closure ledger:
639
703
 
@@ -653,6 +717,16 @@ head, and record the exact evidence used.
653
717
 
654
718
  ## Final Output
655
719
 
720
+ Before emitting the user-facing final response, call `complete_pr_workflow` a
721
+ second time with the same mode and immutable verification `pr_head_sha`. The
722
+ tool clears the durable session gate only when the content digest still equals
723
+ the independently approved digest, the exact approved commit remains current,
724
+ its bound upstream remote-tracking ref points to that exact commit, every
725
+ feedback ID has exact-provenance evidence, and no PR-workflow lanes remain
726
+ open. While the gate remains active, the runtime replaces architect
727
+ final-response text with a mechanical blocked notice and re-wakes an idle
728
+ parent session.
729
+
656
730
  Report:
657
731
 
658
732
  - intake sources checked and unavailable sources,