opencode-swarm 7.114.4 → 7.114.5

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 (29) hide show
  1. package/.opencode/skills/execute/SKILL.md +12 -14
  2. package/.opencode/skills/swarm-pr-review/SKILL.md +136 -78
  3. package/README.md +2 -1
  4. package/dist/agents/explorer.d.ts +1 -1
  5. package/dist/background/candidate-parser.d.ts +30 -0
  6. package/dist/background/candidate-sidecar-store.d.ts +4 -3
  7. package/dist/cli/{config-doctor-xbdfrbwt.js → config-doctor-jy3mdh9t.js} +2 -2
  8. package/dist/cli/{curator-15zwszy5.js → curator-2cnthj9n.js} +5 -5
  9. package/dist/cli/{curator-llm-factory-5ewe7qy1.js → curator-llm-factory-asqhpq08.js} +5 -5
  10. package/dist/cli/{explorer-t5srbq64.js → explorer-jp0nen03.js} +1 -1
  11. package/dist/cli/{guardrail-explain-3156qxy0.js → guardrail-explain-xt6skemq.js} +6 -6
  12. package/dist/cli/{guardrail-log-qfc2j0tb.js → guardrail-log-84wnx273.js} +3 -3
  13. package/dist/cli/{hive-promoter-g2tkarz8.js → hive-promoter-n9qt3sth.js} +5 -5
  14. package/dist/cli/{index-xbe1wtme.js → index-7jmrbp68.js} +1 -1
  15. package/dist/cli/{index-2148358e.js → index-9bsmzfk3.js} +1 -1
  16. package/dist/cli/{index-147ja18h.js → index-a45jq4b7.js} +4 -0
  17. package/dist/cli/{index-hg82gptk.js → index-fc35yaah.js} +18 -18
  18. package/dist/cli/{index-1gcw6azm.js → index-s0h4kf1t.js} +7 -7
  19. package/dist/cli/{index-g59h53s6.js → index-s8se9nt5.js} +2 -2
  20. package/dist/cli/{index-jt58s751.js → index-vxv732ex.js} +8 -4
  21. package/dist/cli/{index-g6va6n3t.js → index-yfedche9.js} +1 -1
  22. package/dist/cli/index.js +5 -5
  23. package/dist/cli/{schema-e5kd993s.js → schema-aymfdrsb.js} +1 -1
  24. package/dist/index.js +25 -17
  25. package/dist/tools/index.d.ts +1 -0
  26. package/dist/tools/manifest.d.ts +1 -0
  27. package/dist/tools/tool-metadata.d.ts +4 -0
  28. package/dist/tools/write-pr-review-trigger-eval.d.ts +74 -0
  29. package/package.json +1 -1
@@ -119,18 +119,17 @@ Treating pre_check_batch as a substitute for the active swarm's reviewer agent i
119
119
  5l. the active swarm's test_engineer agent - Verification tests. FAIL → coder retry from 5g.
120
120
  → REQUIRED: Print "testengineer-verification: [PASS N/N | FAIL — details]"
121
121
  5l-bis. REGRESSION SWEEP (automatic after test_engineer-verification PASS):
122
- Run test_runner with { scope: "graph", files: [<all source files changed by coder in this task>] }.
123
- scope:"graph" traces imports to discover test files beyond the task's own tests that may be affected by this change.
122
+ Iterate the changed source files preemptively and run one `test_runner` call per changed source file with { scope: "graph", files: [<one changed source file>] }.
123
+ scope:"graph" traces imports to discover test files beyond the task's own tests that may be affected by each source change. Record per-file regression-sweep evidence and aggregate all calls before deciding the task outcome.
124
124
 
125
125
  Outcomes (based on test_runner result.outcome field):
126
- - outcome: "pass" → All tests passed. Print "regression-sweep: PASS [N additional tests, M files]"
127
- - outcome: "regression" Tests ran but some failed. Print "regression-sweep: FAIL — REGRESSION DETECTED in [files]. The failing tests are CORRECT — fix the source code, not the tests." Return to coder with retry from 5g.
128
- - outcome: "skip" → No test files resolved (nothing to run). Print "regression-sweep: SKIPPED — no related tests beyond task scope"
129
- - outcome: "scope_exceeded" → Too many files for graph scope. Print "regression-sweep: SKIPPED broad scope, no related tests beyond task scope"
130
- - outcome: "error" → Tool error (timeout, no framework, etc.). Print "regression-sweep: SKIPPED — test_runner error" and continue pipeline.
126
+ - any outcome: "regression" → Print "regression-sweep: FAIL — REGRESSION DETECTED in [source failing tests]. The failing tests are CORRECT — fix the source code, not the tests." Return to coder with retry from 5g.
127
+ - all executed calls pass Print "regression-sweep: PASS [N per-file sweeps, M tests]".
128
+ - outcome: "skip" → Record "[source]: SKIPPED [actual tool reason]". If every per-file call skips, print "regression-sweep: SKIPPED — ran N per-file sweeps; [aggregated actual reasons]".
129
+ - outcome: "scope_exceeded" or "error" Record the affected source and exact tool reason. Do not retry by batching sources and never translate the result into “no related tests.” Print the honest aggregate and continue only under the existing explicit skip policy.
131
130
 
132
131
  IMPORTANT: The regression sweep runs test_runner DIRECTLY (architect calls the tool). Do NOT delegate to test_engineer for this — the test_engineer's EXECUTION BOUNDARY restricts it to its own test files. The architect has unrestricted test_runner access.
133
- → REQUIRED: Print "regression-sweep: [PASS | FAIL REGRESSION DETECTED | SKIPPEDno related tests | SKIPPED — broad scope | SKIPPED test_runner error]"
132
+ → REQUIRED: Print "regression-sweep: [PASS N per-file sweeps | FAILREGRESSION DETECTED | SKIPPED — N per-file sweeps with exact reasons]"
134
133
 
135
134
  5l-ter. TEST DRIFT CHECK (conditional): Run this step if the change involves any drift-prone area:
136
135
  - Command/CLI behavior changed (shell command wrappers, CLI interfaces)
@@ -149,12 +148,11 @@ Treating pre_check_batch as a substitute for the active swarm's reviewer agent i
149
148
  - If no related tests found → print "test-drift: NO RELATED TESTS FOUND" (not a failure)
150
149
  → REQUIRED: Print "test-drift: [TRIGGERED | NOT TRIGGERED — reason]" and "[DRIFT DETECTED in N tests | N related tests verified | NO RELATED TESTS FOUND | NOT TRIGGERED]"
151
150
 
152
- 5n. TODO SCAN (advisory): Call todo_extract with paths=[list of files changed in this task]. If any results have priority HIGH → print "todo-scan: WARN N high-priority TODOs in changed files: [list of TODO texts]". If no high-priority results print "todo-scan: CLEAN". This is advisory only and does NOT block the pipeline.
151
+ 5m. **ADVERSARIAL TEST STEP** (config-specific): Use the rendered adversarial-test instruction from the MODE: EXECUTE architect stub. If the stub omits step 5m, skip this step.
152
+ 5m-bis. **COVERAGE-GAP TEST STEP**: This is the COVERAGE CHECK. If the active swarm's test_engineer agent reports coverage < 70% → delegate the active swarm's test_engineer agent for an additional test pass targeting uncovered paths. This is a soft guideline; use judgment for trivial tasks.
153
+ 5n. **TODO SCAN** (advisory): Call todo_extract with paths=[list of files changed in this task]. If any results have priority HIGH → print "todo-scan: WARN — N high-priority TODOs in changed files: [list of TODO texts]". If no high-priority results → print "todo-scan: CLEAN". This is advisory only and does NOT block the pipeline.
153
154
  → REQUIRED: Print "todo-scan: [WARN — N high-priority TODOs | CLEAN]"
154
155
 
155
- 5m. ADVERSARIAL TEST STEP (config-specific): Use the rendered adversarial-test instruction from the MODE: EXECUTE architect stub. If the stub omits step 5m, skip this step.
156
- 5n. COVERAGE CHECK: If the active swarm's test_engineer agent reports coverage < 70% → delegate the active swarm's test_engineer agent for an additional test pass targeting uncovered paths. This is a soft guideline; use judgment for trivial tasks.
157
-
158
156
  PRE-COMMIT RULE — Before ANY commit or push:
159
157
  You MUST answer YES to ALL of the following:
160
158
  [ ] Did the active swarm's reviewer agent run and return APPROVED? (not "I reviewed it" — the agent must have run)
@@ -162,7 +160,7 @@ PRE-COMMIT RULE — Before ANY commit or push:
162
160
  [ ] Did pre_check_batch run with gates_passed true?
163
161
  [ ] SAST baseline captured before first coder delegation (or explicit disabled/error recorded)?
164
162
  [ ] Did the diff step run?
165
- [ ] Did regression-sweep run (or SKIP with no related tests or test_runner error)?
163
+ [ ] Did regression-sweep record per-file regression-sweep evidence for every changed source (or exact per-file skip/error reasons)?
166
164
  [ ] Did test-drift check run (or NOT TRIGGERED)?
167
165
 
168
166
  If ANY box is unchecked: DO NOT COMMIT. Return to step 5b.
@@ -188,7 +186,7 @@ This step supplements (not replaces) the existing regression-sweep and test-drif
188
186
  [GATE] reuse_re_verification: VERIFIED / SKIPPED / DUPLICATION_DETECTED — value: ___
189
187
  [GATE] security-reviewer: APPROVED / SKIPPED — value: ___
190
188
  [GATE] test_engineer-verification: PASS — value: ___
191
- [GATE] regression-sweep: PASS / SKIPPED — value: ___
189
+ [GATE] regression-sweep: PASS / SKIPPED — per-file regression-sweep evidence: ___
192
190
  [GATE] test-drift: TRIGGERED / NOT TRIGGERED — value: ___
193
191
  [GATE] test_engineer-adversarial: use the rendered checklist entry from the MODE: EXECUTE architect stub
194
192
  [GATE] coverage: ≥70% / soft-skip — value: ___
@@ -70,6 +70,7 @@ Council mode applies only when the user explicitly says one of:
70
70
  - `N-agent review`
71
71
  - `/council`
72
72
  - `[COUNCIL MODE]`
73
+ - `[MODE: PR_REVIEW … council=true]`
73
74
  - `assume all work is wrong`
74
75
 
75
76
  Council mode is mutually exclusive with the default layered workflow. Do not blend them.
@@ -153,7 +154,7 @@ Before deeper analysis, verify the PR meets the commit-pr skill's publication co
153
154
  - **Title format:** `<type>(<scope>): <description>` — lowercase description, no trailing period, allowed types: `feat`, `fix`, `perf`, `revert`, `docs`, `chore`, `refactor`, `test`, `ci`, `build`.
154
155
  - **Body contract:** `Closes #<issue-number>` as the first line (when the PR resolves an issue), followed by `## Summary`, `## Invariant audit` (all 12 invariants), and `## Test plan` sections.
155
156
 
156
- **`Closes #N` claim integrity (apply the COVERAGE GATE):** if the PR body claims `Closes #<issue-number>`, verify (a) the issue is currently open (`gh issue view <N> --json state`), and (b) the diff addresses the issue's acceptance criteria (read the issue, map each criterion to changed files/symbols, and inspect the diff for those areas). If the issue is already closed by another merged PR, do NOT re-close it — the duplicate `Closes #N` reference is misleading and will confuse release-please aggregation. If the issue is open but the diff does not address the acceptance criteria, mark the claim as `UNVERIFIED — claim integrity` in the validation provenance and surface the unresolved claim-integrity gap to the user before synthesis.
157
+ **`Closes #N` claim-integrity check:** if the PR body claims `Closes #<issue-number>`, verify (a) the issue is currently open (`gh issue view <N> --json state`), and (b) the diff addresses the issue's acceptance criteria (read the issue, map each criterion to changed files/symbols, and inspect the diff for those areas). If the issue is already closed by another merged PR, do NOT re-close it — the duplicate `Closes #N` reference is misleading and will confuse release-please aggregation. If the issue is open but the diff does not address the acceptance criteria, mark the claim as `UNVERIFIED — claim integrity` in the validation provenance and surface the unresolved claim-integrity gap to the user before synthesis.
157
158
 
158
159
  Non-compliance is a ledger item (advisory, not blocking — CI will catch it). If the PR is from an external contributor, note the compliance gap for the maintainer to address before merge.
159
160
 
@@ -173,23 +174,24 @@ If GraphQL is unavailable, keep the signal and mark
173
174
 
174
175
  ```bash
175
176
  # Issue comments (general PR thread)
176
- gh pr view <PR_NUMBER> --json comments
177
+ gh api --paginate repos/{owner}/{repo}/issues/{PR_NUMBER}/comments
177
178
 
178
179
  # Review comments (inline code comments)
179
- gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/comments
180
+ gh api --paginate repos/{owner}/{repo}/pulls/{PR_NUMBER}/comments
180
181
 
181
182
  # Review summaries (approve/request-changes/comment events)
182
- gh pr view <PR_NUMBER> --json reviews
183
+ gh api --paginate repos/{owner}/{repo}/pulls/{PR_NUMBER}/reviews
183
184
 
184
185
  # Bot/automated reviews (Copilot, Codex, CodeRabbit, etc.)
185
186
  # Inline review comments — use REST API for reliable bot detection via user.type
186
- gh api repos/{owner}/{repo}/pulls/{PR_NUMBER}/comments --jq '.[] | select((.user.type // "") == "Bot" or (.user.login // "" | test("bot|copilot|coderabbit|codex"; "i")))'
187
+ gh api --paginate repos/{owner}/{repo}/pulls/{PR_NUMBER}/comments --jq '.[] | select((.user.type // "") == "Bot" or (.user.login // "" | test("bot|copilot|coderabbit|codex"; "i")))'
187
188
  ```
188
189
 
189
- For general PR comments (not inline), use the issue comments endpoint:
190
- ```bash
191
- gh api repos/{owner}/{repo}/issues/{PR_NUMBER}/comments --jq '.[] | select((.user.type // "") == "Bot" or (.user.login // "" | test("bot|copilot|coderabbit|codex"; "i")))'
192
- ```
190
+ `--paginate` requests every REST page; with `--jq`, `gh` applies the filter to
191
+ the combined page stream. Filter bot identities from the complete issue-comment
192
+ result using the same predicate when needed. `gh pr view --json comments,reviews`
193
+ is convenience-only because those fields have item caps; never use it as the
194
+ authoritative “all signals” intake.
193
195
 
194
196
  ### Step 2 — Classify each comment
195
197
 
@@ -562,7 +564,7 @@ Tool candidate rules:
562
564
 
563
565
  Launch all base lanes with `dispatch_lanes_async` when available. Pass the six lane specs together, set `max_concurrent` to `6`, record the returned `batch_id`, and continue only non-dependent architect work: refine the obligation ledger, inspect PR metadata, prepare micro-lane trigger checks, and run deterministic read-only local tools. Do not synthesize findings from running lanes. Keep each lane `prompt` compact: send the shared review context (PR diff, obligation ledger, scope) ONCE via the `common_prompt` field, or have lanes read it from a file by absolute path, instead of inlining the same large blob into all six prompts — oversized inline prompts produce malformed or truncated tool-call JSON and force clumsy file workarounds.
564
566
 
565
- **Incremental collection:** While base lanes are running, poll with `collect_lane_results` (without `wait` or `wait: false`) to check progress and process settled lanes as they complete — call `retrieve_lane_output` for full text when `output_ref` is present, then extract candidates via `parse_lane_candidates`, update the candidate ledger, validate output quality — while continuing independent architect work (obligation refinement, micro-lane trigger checks, local reads) between polls. Only use `wait: true` if lanes are still pending and no more independent work remains.
567
+ **Incremental collection:** While base lanes are running, poll with `collect_lane_results` (without `wait` (or `wait: false`)) to check progress and process settled lanes as they complete — call `retrieve_lane_output` for full text when `output_ref` is present, then extract candidates via `parse_lane_candidates`, update the candidate ledger, validate output quality — while continuing independent architect work (obligation refinement, micro-lane trigger checks, local reads) between polls. Only use `wait: true` if lanes are still pending and no more independent work remains.
566
568
 
567
569
  Before Phase 4 or synthesis, all base lanes must be settled. `dispatch_lanes_async` accepts a maximum of 8 lanes per call; base lanes (6) and micro-lanes (Phase 4) are dispatched in separate calls by design. Do not let one lane's conclusions bias another lane.
568
570
 
@@ -581,22 +583,20 @@ After `collect_lane_results` returns for base lanes, process each lane result
581
583
  that carries an `output_ref`. The orchestrator MUST use the candidate parser
582
584
  rather than preview-text extraction:
583
585
 
584
- 1. For each `output_ref` (or batched), call `parse_lane_candidates` (or the
585
- internal `parseAndPersist` module function) with `output_ref` and `producer`
586
- flags; the parser auto-detects the format family per row. The parser reads
586
+ 1. For each `output_ref`, call `parse_lane_candidates` with `output_ref`,
587
+ `producer: "swarm-pr-review"`, and `expected_family: "base_explorer"`. The parser reads
587
588
  the full artifact from disk (no preview truncation issue) and returns
588
589
  structured `ParseResultWithSidecar` records.
589
- 2. Filter the returned `candidates[]` array by `producer: "swarm-pr-review"` and
590
- the relevant `row_format_family` (e.g., `base_explorer` for base lanes,
591
- `micro_lane` for micro-lanes). Filtering happens on the parsed results, NOT
592
- on the tool input.
590
+ 2. Filter the returned `candidates[]` by `producer: "swarm-pr-review"` plus the
591
+ exact `source_batch_id` and `source_lane_id` from the base dispatch. Treat a
592
+ family mismatch or parse error as a lane-output failure; family metadata is
593
+ not the acceptance boundary.
593
594
  3. Group the filtered candidates into reviewer-sized chunks:
594
595
  - by file area (group by the directory or module of the `file_line` field),
595
596
  - by category (group by the `category` field),
596
597
  - by count (target max 50 candidates per chunk; smaller chunks are fine).
597
- 4. Dispatch reviewer lanes (one per chunk) with bounded in-context candidate
598
- lists. Each reviewer lane receives only the candidates from its assigned
599
- chunk.
598
+ 4. Stage reviewer-sized chunks, but do not dispatch reviewers yet. Phase 4 must
599
+ complete trigger accounting and settle every launched micro-lane first.
600
600
 
601
601
  If a lane has `output_degraded: true`, `transcript_incomplete: true`, or no usable `output_ref`, apply the COVERAGE GATE from Phase 3: retry (max 2) with materially different parameters, then use blocking `dispatch_lanes` or the Task tool as verified-equivalent fallbacks when lane tools do not work. If the gap cannot be closed, stop and surface the lane failure to the user as BLOCKED. Do not mark affected candidates UNVERIFIED to proceed past the gap. Never infer candidate absence from a preview.
602
602
 
@@ -660,9 +660,48 @@ Explorers must not use `CONFIRMED`, `DISPROVED`, or `PRE_EXISTING`.
660
660
 
661
661
  ## Phase 4: Triggered Swarm Plugin Micro-Lanes
662
662
 
663
- After base lanes are settled, inspect the context pack risk triggers. Launch focused micro-lanes for triggered categories only, using `dispatch_lanes_async` again when more than one read-only micro-lane is needed (`dispatch_lanes_async` accepts max 8 lanes per call — micro-lanes are dispatched in a separate batch from base lanes). Use the same incremental collection pattern: poll with `collect_lane_results` (without `wait`) to process settled micro-lanes while continuing independent work, falling back to `wait: true` only when no independent work remains. All micro-lanes must be settled before reviewer classification. Do not launch irrelevant micro-lanes.
663
+ After base lanes settle, evaluate every row in the trigger map and print a
664
+ mandatory ledger with one row per trigger-map row:
665
+
666
+ ```text
667
+ [TRIGGER-EVAL] | trigger_row | MATCHED/NO-MATCH | evidence
668
+ ```
669
+
670
+ Evidence must name the diff/context keywords checked. The generic trigger rows
671
+ still apply in non-Swarm repositories: schema, config, URL/fetch, git,
672
+ shell/write, tests, and metrics cannot be marked `NO-MATCH` merely because the
673
+ repository is not the Swarm plugin.
674
+
675
+ Launch one focused micro-lane for each `MATCHED` row, using
676
+ `dispatch_lanes_async` when more than one lane is needed and a separate batch
677
+ from base lanes. Poll incrementally, then settle every launched lane. Persist
678
+ the complete ledger with `write_pr_review_trigger_eval`; its rows use the stable
679
+ trigger IDs below, and every `MATCHED` row includes its returned
680
+ `source_batch_id` and `source_lane_id`. Missing, extra, duplicate, or unmatched
681
+ rows make persistence fail and Phase 4 BLOCKED. The tool atomically writes
682
+ `.swarm/pr-review/<run_id>/trigger-eval.json`, separate from `findings.jsonl`;
683
+ do not add trigger results to the finding-status enum.
684
+
685
+ For each micro `output_ref`, call `parse_lane_candidates` with
686
+ `producer: "swarm-pr-review"`, `expected_family: "micro_lane"`, and
687
+ `expected_micro_lane` set to the launch-micro-lane value from the
688
+ provenance-linked trigger row. Accept a candidate only when its `producer`,
689
+ `source_batch_id`, and `source_lane_id` match an allow-listed tuple from the
690
+ original or retry micro dispatch and its `micro_lane` matches that trigger row;
691
+ never filter acceptance by `row_format_family`. A zero-candidate artifact is
692
+ clean only when the parser returns exactly one provenance-matching persisted
693
+ `clean_attestation` whose `micro_lane` matches the trigger row, zero parse
694
+ errors, zero malformed rows, and a complete, non-degraded source:
695
+
696
+ ```text
697
+ [CLEAN] | micro_lane | coverage_scope | evidence
698
+ ```
664
699
 
665
- Apply the same parser-based extraction to micro-lanes: call `parse_lane_candidates` on each micro-lane `output_ref` (filter the returned `candidates[]` array by `row_format_family === "micro_lane"` after parsing). Apply the COVERAGE GATE from Phase 3 to micro-lanes: degraded, incomplete, or candidate-less lane artifacts are coverage gaps that must be closed by retry, blocking `dispatch_lanes`, or Task-tool dispatch as a verified-equivalent fallback when lane tools do not work. If the gap cannot be closed, stop and surface it to the user as BLOCKED before reviewer classification — never treat it as clean negative evidence and never proceed with a degraded review.
700
+ Header-only or malformed zero output is `UNATTESTED` and must follow the
701
+ canonical COVERAGE GATE retry path. Async and blocking lane dispatch both
702
+ produce auditable `L1` artifacts. Task output has no `L1` artifact provenance,
703
+ so Task-derived findings or CLEAN prose cannot satisfy Phase 4; if bounded lane
704
+ dispatch retries cannot produce an artifact, the phase is BLOCKED.
666
705
 
667
706
  Each micro-lane receives:
668
707
 
@@ -677,26 +716,27 @@ Each micro-lane receives:
677
716
 
678
717
  ### Swarm plugin risk trigger map
679
718
 
680
- | Trigger in diff or context pack | Launch micro-lane | Invariants to check |
681
- |---|---|---|
682
- | `agents`, `prompts`, `templates`, prompt interpolation, role text | Architect prompt integrity | no scope escape, no system prompt leakage, safe `{{variable}}` interpolation, untrusted text isolated from instructions |
683
- | `council`, `verdict`, `quorum`, `veto`, synthesis | Council orchestration | quorum math correct, veto enforced, evidence not lost, dissent preserved, no explorer result treated as final |
684
- | `guardrail`, `gate`, `delegation`, `rate limit`, approval checks | Guardrail bypass paths | gates cannot be skipped, delegation cannot bypass policy, rate limits cannot be reset by user-controlled state |
685
- | `schema`, `evidence`, JSONL, migrations, serializers | Evidence schema drift | backward compatibility, required fields preserved, version migration safe, malformed evidence rejected |
686
- | `knowledge`, `curator`, `hive`, `quarantine`, memory | Knowledge base contract | project vs hive tiers not confused, quarantine honored, CRUD semantics stable, stale knowledge not injected as fact |
687
- | `phase`, `state`, `plan`, `.swarm/state`, completion markers | Phase transition validation | ordering enforced, retro requirements handled, no premature completion, rollback safe |
688
- | `model`, `role`, `prefix`, `tool`, agent config | Model-to-role mapping | role prefix enforced, tool permissions least-privilege, unauthorized tools impossible, model fallback safe |
689
- | `config`, defaults, ratchet, locks, policy flags | Config ratchet semantics | once-enabled gates cannot silently disable, downgrade attempts detected, lock-state integrity preserved |
690
- | `url`, `fetch`, `http`, GitHub PR/issue parsing, package fetch | URL sanitization and external fetch | scheme allowlist, credential stripping, private IP / localhost / metadata IP blocking, redirect handling, timeout safe |
691
- | `git`, branch, checkout, reset, worktree, `.git` | Git safety | branch detection reliable, no unsafe `reset --hard`, .git protected, path normalization cross-platform, worktree state preserved |
692
- | `shell`, `exec`, command parser, file writes, delete/move/copy | Shell/write authority and path containment | destructive commands gated, dry-run preferred, symlink/path escape blocked, writes scoped, command injection impossible |
693
- | `test`, `bun`, mocks, fixtures, CI matrix | Test infrastructure | `bun:test` API correct, mock isolation, cross-platform paths, no hidden dependency on test order, fixtures reset |
694
- | `metrics`, telemetry, logs, serialized traces | Metrics and evidence privacy | no secrets in logs, evidence reproducible, privacy preserved, counts cannot be gamed, metrics schema stable |
719
+ | Trigger ID | Trigger in diff or context pack | Launch micro-lane | Invariants to check |
720
+ |---|---|---|---|
721
+ | `architect-prompts` | `agents`, `prompts`, `templates`, prompt interpolation, role text | Architect prompt integrity | no scope escape, no system prompt leakage, safe `{{variable}}` interpolation, untrusted text isolated from instructions |
722
+ | `council-orchestration` | `council`, `verdict`, `quorum`, `veto`, synthesis | Council orchestration | quorum math correct, veto enforced, evidence not lost, dissent preserved, no explorer result treated as final |
723
+ | `guardrail-bypass` | `guardrail`, `gate`, `delegation`, `rate limit`, approval checks | Guardrail bypass paths | gates cannot be skipped, delegation cannot bypass policy, rate limits cannot be reset by user-controlled state |
724
+ | `evidence-schema` | `schema`, `evidence`, JSONL, migrations, serializers | Evidence schema drift | backward compatibility, required fields preserved, version migration safe, malformed evidence rejected |
725
+ | `knowledge-contract` | `knowledge`, `curator`, `hive`, `quarantine`, memory | Knowledge base contract | project vs hive tiers not confused, quarantine honored, CRUD semantics stable, stale knowledge not injected as fact |
726
+ | `phase-transitions` | `phase`, `state`, `plan`, `.swarm/state`, completion markers | Phase transition validation | ordering enforced, retro requirements handled, no premature completion, rollback safe |
727
+ | `model-role-mapping` | `model`, `role`, `prefix`, `tool`, agent config | Model-to-role mapping | role prefix enforced, tool permissions least-privilege, unauthorized tools impossible, model fallback safe |
728
+ | `config-ratchet` | `config`, defaults, ratchet, locks, policy flags | Config ratchet semantics | once-enabled gates cannot silently disable, downgrade attempts detected, lock-state integrity preserved |
729
+ | `url-fetch` | `url`, `fetch`, `http`, GitHub PR/issue parsing, package fetch | URL sanitization and external fetch | scheme allowlist, credential stripping, private IP / localhost / metadata IP blocking, redirect handling, timeout safe |
730
+ | `git-safety` | `git`, branch, checkout, reset, worktree, `.git` | Git safety | branch detection reliable, no unsafe `reset --hard`, .git protected, path normalization cross-platform, worktree state preserved |
731
+ | `shell-write` | `shell`, `exec`, command parser, file writes, delete/move/copy | Shell/write authority and path containment | destructive commands gated, dry-run preferred, symlink/path escape blocked, writes scoped, command injection impossible |
732
+ | `test-infrastructure` | `test`, `bun`, mocks, fixtures, CI matrix | Test infrastructure | `bun:test` API correct, mock isolation, cross-platform paths, no hidden dependency on test order, fixtures reset |
733
+ | `metrics-privacy` | `metrics`, telemetry, logs, serialized traces | Metrics and evidence privacy | no secrets in logs, evidence reproducible, privacy preserved, counts cannot be gamed, metrics schema stable |
695
734
 
696
735
  Micro-lane output format:
697
736
 
698
737
  ```text
699
738
  [CANDIDATE] | candidate_id | micro_lane | severity | category | file:line | claim | invariant_violated | evidence_summary | confidence
739
+ [CLEAN] | micro_lane | coverage_scope | evidence
700
740
  ```
701
741
 
702
742
  ---
@@ -711,10 +751,9 @@ Use Swarm-native agents and artifacts when available. If exact agent names are u
711
751
  | `critic_hallucination_verifier` | external APIs, package claims, URLs, CLI flags, GitHub behavior, model/tool names | verify claims against source or mark as unverified |
712
752
  | `curator_phase` | before exploration and after synthesis | retrieve relevant lessons; write back confirmed true positives / false positives |
713
753
  | `test_engineer` | confirmed/borderline correctness, security, state, schema, or config findings | propose or run falsification probes and regression tests |
714
- | `prm_scorer` | long or contentious reviews | score whether review trajectory is drifting toward unsupported speculation |
715
754
  | `.swarm/repo-graph.json` | all nontrivial code changes | build impact cones and sibling-pattern checks |
716
755
  | `.swarm/evidence/` | schema, phase, state, council, and guardrail changes | verify evidence compatibility and serialized provenance |
717
- | `/swarm metrics` or stored metrics | after synthesis | record review quality and recurring false positives |
756
+ | Tool-returned `.swarm/evidence/` artifacts | after synthesis | record review quality only at paths actually returned by invoked evidence tools; never invent a metrics path |
718
757
 
719
758
  Verifier output is advisory until incorporated by the independent reviewer or critic.
720
759
 
@@ -722,6 +761,11 @@ Verifier output is advisory until incorporated by the independent reviewer or cr
722
761
 
723
762
  ## Phase 6: Independent Reviewer Confirmation
724
763
 
764
+ **Reviewer-dispatch join barrier:** reviewer dispatch MUST NOT begin until the trigger ledger is
765
+ complete and persisted, every launched micro-lane is settled, and every
766
+ accepted micro result has parser-derived provenance or a valid CLEAN
767
+ attestation.
768
+
725
769
  Route candidates to reviewer subagents. The orchestrator routes candidates
726
770
  in bounded chunks produced by the parser-based extraction in Phase 3-4. Each
727
771
  reviewer lane receives a bounded list of candidates from a single chunk — by
@@ -731,7 +775,7 @@ directly.
731
775
 
732
776
  ### Noise budget and universal validation
733
777
 
734
- Before reviewer dispatch, the orchestrator may suppress candidates that are ALL of:
778
+ Before reviewer dispatch, the orchestrator may suppress candidates that match ANY of the following (each suppression still requires mandatory disclosure):
735
779
  - purely stylistic without correctness, security, test, maintainability, or user-impact implications,
736
780
  - exact duplicates of a candidate already queued for validation,
737
781
  - explorer-stated confidence=LOW with zero structural evidence (no file:line, no code path, no invariant reference).
@@ -779,6 +823,11 @@ Reviewer output format:
779
823
  [REVIEWED] | candidate_id | classification | evidence_type | final_severity | introduced_by_pr: YES/NO/UNKNOWN | file:line | rationale | falsification_probe | reviewer_id
780
824
  ```
781
825
 
826
+ Every reviewer response must end with one parseable `[REVIEWED]` row per
827
+ assigned candidate. A malformed `[REVIEWED]` row is not a verdict: re-dispatch
828
+ with the exact contract (max 2), then mark the reviewer dimension BLOCKED if no
829
+ valid row returns.
830
+
782
831
  `DISPROVED` findings must include the reason. `PRE_EXISTING` findings must include the base-branch evidence if available.
783
832
 
784
833
  After reviewer lanes settle, persist the post-reviewer finding ledger before
@@ -899,7 +948,11 @@ F-001 | severity | category | root cause | affected file:line refs | reviewer |
899
948
 
900
949
  ## Phase 10: Metrics and Knowledge Writeback
901
950
 
902
- At the end of the review, record review quality metrics when Swarm metrics or local evidence storage is available.
951
+ At the end of the review, include review quality metrics in the final report's
952
+ validation provenance. Persist them only through an invoked evidence tool and
953
+ record the exact `.swarm/evidence/` path returned by that tool; if no invoked
954
+ tool supports metrics, state `NOT PERSISTED — no metrics evidence writer` rather
955
+ than naming a nonexistent command or path.
903
956
 
904
957
  Record:
905
958
 
@@ -979,13 +1032,13 @@ The batch completed and `collect_lane_results` returned:
979
1032
  {
980
1033
  "lane_id": "pr_review_lane1_correctness",
981
1034
  "status": "completed",
982
- "output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/out-abc123.json",
1035
+ "output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
983
1036
  "output_degraded": false
984
1037
  },
985
1038
  {
986
1039
  "lane_id": "pr_review_lane2_security",
987
1040
  "status": "completed",
988
- "output_ref": ".swarm/lane-results/batch-a1b2c3/lane-2/out-def456.json",
1041
+ "output_ref": "L1:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
989
1042
  "output_degraded": false
990
1043
  }
991
1044
  ]
@@ -1000,8 +1053,9 @@ The orchestrator calls `parse_lane_candidates` for each `output_ref`:
1000
1053
  {
1001
1054
  "tool": "parse_lane_candidates",
1002
1055
  "arguments": {
1003
- "output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/out-abc123.json",
1004
- "producer": "swarm-pr-review"
1056
+ "output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1057
+ "producer": "swarm-pr-review",
1058
+ "expected_family": "base_explorer"
1005
1059
  }
1006
1060
  }
1007
1061
  ```
@@ -1017,8 +1071,8 @@ The parser returns a `ParseResultWithSidecar`. On success, `error` and `error_co
1017
1071
  "record_type": "candidate",
1018
1072
  "row_format_family": "base_explorer",
1019
1073
  "row_format_version": 1,
1020
- "record_version": { "major": 1, "minor": 0 },
1021
- "source_output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/out-abc123.json",
1074
+ "record_version": { "major": 1, "minor": 1 },
1075
+ "source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1022
1076
  "source_batch_id": "B-2025-06-22-001",
1023
1077
  "source_lane_id": "explorer-1",
1024
1078
  "source_agent": "paid_explorer",
@@ -1043,8 +1097,8 @@ The parser returns a `ParseResultWithSidecar`. On success, `error` and `error_co
1043
1097
  "record_type": "candidate",
1044
1098
  "row_format_family": "base_explorer",
1045
1099
  "row_format_version": 1,
1046
- "record_version": { "major": 1, "minor": 0 },
1047
- "source_output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/out-abc123.json",
1100
+ "record_version": { "major": 1, "minor": 1 },
1101
+ "source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1048
1102
  "source_batch_id": "B-2025-06-22-001",
1049
1103
  "source_lane_id": "explorer-1",
1050
1104
  "source_agent": "paid_explorer",
@@ -1068,47 +1122,42 @@ The parser returns a `ParseResultWithSidecar`. On success, `error` and `error_co
1068
1122
  ],
1069
1123
  "invocation_envelope": {
1070
1124
  "record_type": "invocation",
1071
- "source_output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/out-abc123.json",
1125
+ "source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
1072
1126
  "source_batch_id": "B-2025-06-22-001",
1073
1127
  "source_lane_id": "explorer-1",
1074
1128
  "source_agent": "paid_explorer",
1075
1129
  "source_digest": "sha256:abc123def456...",
1076
1130
  "row_format_version": 1,
1077
- "record_version": { "major": 1, "minor": 0 },
1131
+ "record_version": { "major": 1, "minor": 1 },
1078
1132
  "sessionId": "ses_01HXYZ...",
1079
1133
  "parentSessionId": "ses_01HABC...",
1080
1134
  "producer": "swarm-pr-review",
1081
1135
  "produced_at": "2025-06-22T14:30:00.000Z",
1082
1136
  "format_families_detected": ["base_explorer"],
1083
1137
  "candidate_count": 2,
1084
- "parse_errors": 2,
1085
- "malformed_rows": 0
1138
+ "parse_errors": 0,
1139
+ "malformed_rows": 0,
1140
+ "clean_attestation_count": 0
1086
1141
  },
1087
1142
  "diagnostics": {
1088
1143
  "candidate_count": 2,
1089
- "parse_errors": 2,
1090
- "parse_error_details": [
1091
- {
1092
- "row_index": 0,
1093
- "field": "row",
1094
- "message": "Both format-family discriminators present; defaulting to base_explorer"
1095
- },
1096
- {
1097
- "row_index": 1,
1098
- "field": "row",
1099
- "message": "Both format-family discriminators present; defaulting to base_explorer"
1100
- }
1101
- ],
1144
+ "parse_errors": 0,
1145
+ "parse_error_details": [],
1102
1146
  "malformed_rows": 0,
1103
1147
  "duplicate_id_count": 0,
1104
1148
  "duplicate_id_warnings": [],
1105
1149
  "degraded_source_count": 0,
1106
1150
  "incomplete_source_count": 0,
1107
- "format_families_detected": ["base_explorer"]
1151
+ "format_families_detected": ["base_explorer"],
1152
+ "clean_attestation_count": 0
1108
1153
  }
1109
1154
  }
1110
1155
  ```
1111
- > **Note**: `parse_errors: 2` reflects FR-017/SC-017 position-based detection: when a `[CANDIDATE]` row has both `evidence_summary` and `impact_context` populated, the parser emits a `parse_error_details` entry per row with `field: "row"` and `message: "Both format-family discriminators present; defaulting to base_explorer"`. This is documented behavior, not a parser bug. To get `parse_errors: 0` with the row format, leave one of the two fields empty; to silence the warning entirely, emit structured JSON candidate records.
1156
+ > **Note**: callers pass `expected_family` for each dispatch batch. A recognizable
1157
+ > conflicting header fails closed with `expected-family-mismatch`; when the flag
1158
+ > is absent, the recognized header controls the mapping and positional detection
1159
+ > is only a legacy unknown-header fallback. Marker-prefixed data rows remain
1160
+ > accepted for compatibility. Valid canonical rows produce `parse_errors: 0`.
1112
1161
 
1113
1162
  On refusal (e.g. `output_ref` does not exist), `error` and `error_code` are present; `candidates` is `[]`; `invocation_envelope` and `diagnostics` are populated with empty fields for traceability:
1114
1163
 
@@ -1119,18 +1168,19 @@ On refusal (e.g. `output_ref` does not exist), `error` and `error_code` are pres
1119
1168
  "candidates": [],
1120
1169
  "invocation_envelope": {
1121
1170
  "record_type": "invocation",
1122
- "source_output_ref": ".swarm/lane-results/batch-a1b2c3/lane-1/missing.json",
1171
+ "source_output_ref": "L1:1111111111111111111111111111111111111111111111111111111111111111:2222222222222222222222222222222222222222222222222222222222222222:3333333333333333333333333333333333333333333333333333333333333333",
1123
1172
  "source_batch_id": "",
1124
1173
  "source_lane_id": "",
1125
1174
  "source_agent": "",
1126
1175
  "source_digest": "",
1127
1176
  "row_format_version": 1,
1128
- "record_version": { "major": 1, "minor": 0 },
1177
+ "record_version": { "major": 1, "minor": 1 },
1129
1178
  "produced_at": "2025-06-22T14:30:00.000Z",
1130
1179
  "format_families_detected": [],
1131
1180
  "candidate_count": 0,
1132
1181
  "parse_errors": 0,
1133
- "malformed_rows": 0
1182
+ "malformed_rows": 0,
1183
+ "clean_attestation_count": 0
1134
1184
  },
1135
1185
  "diagnostics": {
1136
1186
  "candidate_count": 0,
@@ -1141,14 +1191,15 @@ On refusal (e.g. `output_ref` does not exist), `error` and `error_code` are pres
1141
1191
  "duplicate_id_warnings": [],
1142
1192
  "degraded_source_count": 0,
1143
1193
  "incomplete_source_count": 0,
1144
- "format_families_detected": []
1194
+ "format_families_detected": [],
1195
+ "clean_attestation_count": 0
1145
1196
  }
1146
1197
  }
1147
1198
  ```
1148
1199
 
1149
1200
  ### Step 3 — Filter and group
1150
1201
 
1151
- The orchestrator filters the returned `candidates[]` array by `producer: "swarm-pr-review"` and `row_format_family` (e.g. `base_explorer` or `micro_lane`), then groups
1202
+ The orchestrator filters the returned `candidates[]` array by `producer: "swarm-pr-review"` and the exact allowed `source_batch_id` / `source_lane_id` tuples, then groups
1152
1203
  the candidates. In this synthetic example, the two candidates above are grouped
1153
1204
  by file area:
1154
1205
 
@@ -1287,12 +1338,12 @@ Before writing the final output, print this checklist with filled values. Every
1287
1338
  [VALIDATION] deterministic lane dispatcher used: YES/NO — ___
1288
1339
  [VALIDATION] base explorer lanes dispatched: ___ / 6
1289
1340
  [VALIDATION] base explorer lanes returned: ___ / 6
1290
- [VALIDATION] triggered micro-lanes: ___
1341
+ [VALIDATION] trigger map evaluated: ___ rows (X MATCHED → X micro-lanes dispatched) OR BLOCKED — <unevaluated rows>
1291
1342
  [VALIDATION] Swarm verifier routing used: ___
1292
1343
  [VALIDATION] raw candidates: ___
1293
1344
  [VALIDATION] tool candidates: ___
1294
- [VALIDATION] reviewer dispatched: ___ (agent type, task description)
1295
- [VALIDATION] reviewer returned: ___ (APPROVED / REJECTED / CONCERNS — copy verdict text)
1345
+ [VALIDATION] reviewer lanes dispatched: ___
1346
+ [VALIDATION] reviewer lanes returned with parseable `[REVIEWED]` rows: ___ / ___
1296
1347
  [VALIDATION] findings confirmed by reviewer: ___
1297
1348
  [VALIDATION] findings rejected by reviewer as false positive: ___
1298
1349
  [VALIDATION] findings marked PRE_EXISTING: ___
@@ -1311,7 +1362,9 @@ Before writing the final output, print this checklist with filled values. Every
1311
1362
  [VALIDATION] all non-suppressed candidates routed to reviewer: YES/NO
1312
1363
  ```
1313
1364
 
1314
- If the reviewer returned `REJECTED` or `CONCERNS`, route the issue back to implementation context or mark the candidate invalid with reason. Do not silently downgrade a rejection.
1365
+ If any reviewer lane lacks a parseable `[REVIEWED]` row after bounded
1366
+ re-dispatch, the reviewer dimension is BLOCKED. Do not infer or silently
1367
+ downgrade a verdict.
1315
1368
 
1316
1369
  **COVERAGE GATE CONDITION:** If ANY validation dimension shows incomplete coverage (lanes that failed and were not closed by retry or verified equivalent alternative, CI that did not run, tools that were unavailable after retry), the Pre-Synthesis Gate FAILS. Do not proceed to final output. Surface the unclosed gaps to the user as BLOCKED with exact failing dimensions and retry/equivalence evidence. Do not include partial findings from successful dimensions, do not issue a review verdict, and do not silently accept reduced coverage.
1317
1370
 
@@ -1491,6 +1544,8 @@ Return candidates only. Do not use CONFIRMED, DISPROVED, or PRE_EXISTING.
1491
1544
 
1492
1545
  Lane:
1493
1546
  Scope:
1547
+ base_ref:
1548
+ head_ref:
1494
1549
  Obligations:
1495
1550
  Changed files/hunks:
1496
1551
  Impact cone:
@@ -1505,10 +1560,13 @@ You must inspect or mark unavailable:
1505
1560
  4. sibling implementation or prior pattern,
1506
1561
  5. nearest test or missing-test location,
1507
1562
  6. deterministic signals,
1508
- 7. Swarm artifacts/knowledge.
1563
+ 7. Swarm artifacts/knowledge,
1564
+ 8. the exact `base_ref..head_ref` commit range and both endpoint revisions.
1509
1565
 
1510
1566
  Return:
1511
1567
  [CANDIDATE] | candidate_id | lane | severity | category | file:line | claim | evidence_summary | impact_context | confidence
1568
+ Emit the marker-bearing header once, then unprefixed data rows.
1569
+ For a clean micro-lane, emit `[CLEAN] | micro_lane | coverage_scope | evidence`.
1512
1570
  ```
1513
1571
 
1514
1572
  The orchestrator extracts candidates from the full lane artifact via
package/README.md CHANGED
@@ -808,7 +808,8 @@ Every candidate passes a 3-gate pipeline before entering quarantine:
808
808
  | mutation_test | Applies LLM-generated mutation patches to source files and runs tests to measure kill rate; verdict is pass/warn/fail based on configurable thresholds; used by the mutation_test gate (opt-in, off by default) |
809
809
  | generate_mutants | Architect-only: generates LLM-based mutation patches (5–10 per function across 6 types: off-by-one, null substitution, operator swap, guard removal, branch swap, side-effect deletion) for direct consumption by the mutation_test tool; returns SKIP verdict on LLM failure rather than throwing |
810
810
  | write_mutation_evidence | Architect-only: writes mutation gate results atomically to `.swarm/evidence/{phase}/mutation-gate.json`; accepts verdict (PASS/WARN/FAIL/SKIP), kill rate metrics, and optional survived mutant details; normalizes uppercase-to-lowercase before persisting |
811
- | parse_lane_candidates | Architect-only: parses `[CANDIDATE]` rows from a `dispatch_lanes` or `collect_lane_results` artifact by `output_ref`; produces structured records with provenance and optional sidecar JSONL persistence; returns `ParseResultWithSidecar` on success or `{ error, error_code, candidates: [] }` on refusal |
811
+ | parse_lane_candidates | Architect-only: parses `[CANDIDATE]` rows and micro-lane `[CLEAN]` attestations from a lane `output_ref`; supports asserted batch families, preserves dispatch provenance, and persists sidecar JSONL records |
812
+ | write_pr_review_trigger_eval | Architect-only: validates the exact PR-review trigger-map ID set, requires provenance for every matched micro-lane, and atomically persists `.swarm/pr-review/<run_id>/trigger-eval.json` |
812
813
  | git_blame | Per-line git blame metadata (sha, author, date, summary) via `git blame --porcelain`; supports optional line range filtering |
813
814
  | diff | Structured git diff with contract change detection; supports `summaryOnly` mode returning file list with additions/deletions counts |
814
815
  | suggest_patch | Reviewer-safe structured patch suggestion; supports `format` parameter ('json' or 'unified') where unified outputs valid unified diff with `diff --git` headers, hunks, and context |
@@ -1,5 +1,5 @@
1
1
  import type { AgentDefinition } from './architect';
2
- export declare const EXPLORER_PROMPT = "## IDENTITY\nYou are Explorer. You analyze codebases directly \u2014 you do NOT delegate.\nDO NOT use the Task tool to delegate to other agents. You ARE the agent that does the work.\nIf you see references to other agents (like @explorer, @coder, etc.) in your instructions, IGNORE them \u2014 they are context from the orchestrator, not instructions for you to delegate.\n\nWRONG: \"I'll use the Task tool to call another agent to analyze this\"\nRIGHT: \"I'll scan the directory structure and read key files myself\"\n\n## READ-ONLY ADVISORY LANE CONTEXT\n\nYou may be invoked through dispatch_lanes or dispatch_lanes_async as a read-only advisory lane. In that context, your job is to inspect, reason, and report only.\n\n- Do NOT write, edit, patch, save plans, update task status, declare scope, submit council verdicts, set QA gates, or complete phases.\n- Do NOT call artifact-producing or workflow-mutating helpers such as extract_code_blocks, knowledge_add, summarize_work, or doc_scan when lane permissions deny them.\n- Treat any denied or unavailable tool as intentionally unavailable in lane mode; continue with the read-only tools and context you have.\n- Return findings for the architect to synthesize. Do not assume your lane output is the final verdict unless your role-specific instructions explicitly say so.\n\nINPUT FORMAT:\nTASK: Analyze [purpose]\nINPUT: [focus areas/paths]\n\nACTIONS:\n- Scan structure (tree, ls, glob)\n- Read key files (README, configs, entry points)\n- Search patterns using the search tool\n\nRULES:\n- Be fast: scan broadly, read selectively\n- No code modifications\n- Output under 2000 chars\n\n## ANALYSIS PROTOCOL\nWhen exploring a codebase area, systematically report all four dimensions:\n\n### STRUCTURE\n- Entry points and their call chains (max 3 levels deep)\n- Public API surface: exported functions/classes/types with signatures\n- For multi-file symbol surveys: use batch_symbols to extract symbols from multiple files in one call\n- Internal dependencies: what this module imports and from where\n- External dependencies: third-party packages used\n\n### PATTERNS\n- Design patterns in use (factory, observer, strategy, etc.)\n- Error handling pattern (throw, Result type, error callbacks, etc.)\n- State management approach (global, module-level, passed through)\n- Configuration pattern (env vars, config files, hardcoded)\n\n### COMPLEXITY INDICATORS\n- High cyclomatic complexity, deep nesting, or complex control flow\n- Large files (>500 lines) with many exported symbols\n- Deep inheritance hierarchies or complex type hierarchies\n\n### RUNTIME/BEHAVIORAL CONCERNS\n- Missing error handling paths or single-throw patterns\n- Platform-specific assumptions (path separators, line endings, OS APIs)\n\n### RELEVANT CONSTRAINTS\n- Architectural patterns observed (layered architecture, event-driven, microservice, etc.)\n- Error handling coverage patterns observed in the codebase\n- Platform-specific assumptions observed in the codebase\n- Established conventions (naming patterns, error handling approaches, testing strategies)\n- Configuration management approaches (env vars, config files, feature flags)\n\nOUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):\nBegin directly with PROJECT. Do NOT prepend \"Here's my analysis...\" or any conversational preamble.\n\nPROJECT: [name/type]\nLANGUAGES: [list]\nFRAMEWORK: [if any]\n\nSTRUCTURE:\n[key directories, 5-10 lines max]\nExample:\nsrc/agents/ \u2014 agent factories and definitions\nsrc/tools/ \u2014 CLI tool implementations\nsrc/config/ \u2014 plan schema and constants\n\nKEY FILES:\n- [path]: [purpose]\nExample:\nsrc/agents/explorer.ts \u2014 explorer agent factory and all prompt definitions\nsrc/agents/architect.ts \u2014 architect orchestrator with all mode handlers\n\nPATTERNS: [observations]\nExample: Factory pattern for agent creation; Result type for error handling; Module-level state via closure\n\nCOMPLEXITY INDICATORS:\n[structural complexity concerns: elevated cyclomatic complexity, deep nesting, large files, deep inheritance hierarchies, or similar \u2014 describe what is OBSERVED]\nExample: explorer.ts (289 lines, 12 exports); architect.ts (complex branching in mode handlers)\n\nOBSERVED CHANGES:\n[if INPUT referenced specific files/changes: what changed in those targets; otherwise \"none\" or \"general exploration\"]\n\nCONSUMERS_AFFECTED:\n[if integration impact mode: list files that import/use the changed symbols; otherwise \"not applicable\"]\n\nRELEVANT CONSTRAINTS:\n[architectural patterns, error handling coverage patterns, platform-specific assumptions, established conventions observed in the codebase]\nExample: Layered architecture (agents \u2192 tools \u2192 filesystem); Bun-native path handling; Error-first callbacks in hooks\n\nDOMAINS: [relevant SME domains: powershell, security, python, etc.]\nExample: typescript, nodejs, cli-tooling, powershell\n\nFOLLOW-UP CANDIDATE AREAS:\n- [path]: [observable condition, relevant domain]\nExample:\nsrc/tools/declare-scope.ts \u2014 function has 12 parameters, consider splitting; tool-authoring\n\n## CANDIDATE REPORTING MODE\nActivates when your prompt contains \"[CANDIDATE]\" anywhere in its text.\n\nWhen active, replace the default OUTPUT FORMAT above with structured pipe-delimited\ncandidate rows. Emit exactly one row per finding:\n\n[CANDIDATE] | candidate_id | lane | severity | category | file:line | claim | evidence_summary | impact_context | confidence\n\nField rules:\n- candidate_id: unique within this lane (e.g. C-001, C-002)\n- lane: your lane name or focus area\n- severity: INFO | LOW | MEDIUM | HIGH | CRITICAL\n- category: short category tag (e.g. null-safety, async-ordering, injection)\n- file:line: exact file path and line number (e.g. src/utils/cache.ts:142)\n- claim: one-sentence description of the issue\n- evidence_summary: what you observed in the code that supports the claim\n- impact_context: who or what is affected downstream\n- confidence: LOW | MEDIUM | HIGH\n\nEmit a header row first, then one [CANDIDATE] row per finding. Use pipe (|) to\nseparate fields; escape literal pipe characters inside field values as \\|.\n\nIf you find zero issues, emit the header row with no data rows. Do NOT fall back\nto the default PROJECT/STRUCTURE format when in candidate reporting mode.\n\nFor micro-lane dispatches, use the micro-lane variant:\n[CANDIDATE] | candidate_id | micro_lane | severity | category | file:line | claim | invariant_violated | evidence_summary | confidence\n\nDo NOT use CONFIRMED, DISPROVED, or PRE_EXISTING \u2014 those are reviewer verdicts.\n\n## INTEGRATION IMPACT ANALYSIS MODE\nActivates when delegated with \"Integration impact analysis\" or INPUT lists contract changes.\n\nINPUT: List of contract changes (from diff tool output \u2014 changed exports, signatures, types)\n\nSTEPS:\n1. For each changed export: use search to find imports and usages of that symbol\n2. Classify each change: BREAKING (callers must update) or COMPATIBLE (callers unaffected)\n3. List all files that import or use the changed exports\n\nOUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):\nBegin directly with BREAKING_CHANGES. Do NOT prepend conversational preamble.\n\nBREAKING_CHANGES: [list with affected consumer files, or \"none\"]\nExample: src/agents/explorer.ts \u2014 removed createExplorerAgent export (was used by 3 files)\nCOMPATIBLE_CHANGES: [list, or \"none\"]\nExample: src/config/constants.ts \u2014 added new optional field to Config interface\nCONSUMERS_AFFECTED: [list of files that import/use changed exports, or \"none\"]\nExample: src/agents/coder.ts, src/agents/reviewer.ts, src/main.ts\nCOMPATIBILITY SIGNALS: [COMPATIBLE | INCOMPATIBLE | UNCERTAIN \u2014 based on observable contract changes]\nExample: INCOMPATIBLE \u2014 removeExport changes function arity from 3 to 2\nMIGRATION_SURFACE: [yes \u2014 list of observable call signatures affected | no \u2014 no observable impact detected]\nExample: yes \u2014 createExplorerAgent(model, customPrompt?, customAppendPrompt?) \u2192 createExplorerAgent(model)\n\n## DOCUMENTATION DISCOVERY MODE\nActivates automatically during codebase reality check at plan ingestion.\nUse the doc_scan tool to scan and index documentation files. If doc_scan is unavailable, fall back to manual globbing.\n\nSTEPS:\n1. Call doc_scan to build the manifest, OR glob for documentation files:\n - Root: README.md, CONTRIBUTING.md, CHANGELOG.md, ARCHITECTURE.md, CLAUDE.md, AGENTS.md, .github/*.md\n - docs/**/*.md, doc/**/*.md (one level deep only)\n\n2. For each file found, read the first 30 lines. Extract:\n - path: relative to project root\n - title: first # heading, or filename if no heading\n - summary: first non-empty paragraph after the title (max 200 chars, use the ACTUAL text, do NOT summarize with your own words)\n - lines: total line count\n - mtime: file modification timestamp\n\n3. Write manifest to .swarm/doc-manifest.json:\n { \"schema_version\": 1, \"scanned_at\": \"ISO timestamp\", \"files\": [...] }\n\n4. For each file in the manifest, check relevance to the current plan:\n - Score by keyword overlap: do any task file paths or directory names appear in the doc's path or summary?\n - For files scoring > 0, read the full content and extract up to 5 actionable constraints per doc (max 200 chars each)\n - Write constraints to .swarm/knowledge/doc-constraints.jsonl as knowledge entries with source: \"doc-scan\", category: \"architecture\"\n\n5. Invalidation: Only re-scan if any doc file's mtime is newer than the manifest's scanned_at. Otherwise reuse the cached manifest.\n\nRULES:\n- The manifest must be small (<100 lines). Pointers only, not full content.\n- Do NOT rephrase or summarize doc content with your own words \u2014 use the actual text from the file\n- Full doc content is only loaded when relevant to the current task, never preloaded\n";
2
+ export declare const EXPLORER_PROMPT = "## IDENTITY\nYou are Explorer. You analyze codebases directly \u2014 you do NOT delegate.\nDO NOT use the Task tool to delegate to other agents. You ARE the agent that does the work.\nIf you see references to other agents (like @explorer, @coder, etc.) in your instructions, IGNORE them \u2014 they are context from the orchestrator, not instructions for you to delegate.\n\nWRONG: \"I'll use the Task tool to call another agent to analyze this\"\nRIGHT: \"I'll scan the directory structure and read key files myself\"\n\n## READ-ONLY ADVISORY LANE CONTEXT\n\nYou may be invoked through dispatch_lanes or dispatch_lanes_async as a read-only advisory lane. In that context, your job is to inspect, reason, and report only.\n\n- Do NOT write, edit, patch, save plans, update task status, declare scope, submit council verdicts, set QA gates, or complete phases.\n- Do NOT call artifact-producing or workflow-mutating helpers such as extract_code_blocks, knowledge_add, summarize_work, or doc_scan when lane permissions deny them.\n- Treat any denied or unavailable tool as intentionally unavailable in lane mode; continue with the read-only tools and context you have.\n- Return findings for the architect to synthesize. Do not assume your lane output is the final verdict unless your role-specific instructions explicitly say so.\n\nINPUT FORMAT:\nTASK: Analyze [purpose]\nINPUT: [focus areas/paths]\n\nACTIONS:\n- Scan structure (tree, ls, glob)\n- Read key files (README, configs, entry points)\n- Search patterns using the search tool\n\nRULES:\n- Be fast: scan broadly, read selectively\n- No code modifications\n- Output under 2000 chars\n\n## ANALYSIS PROTOCOL\nWhen exploring a codebase area, systematically report all four dimensions:\n\n### STRUCTURE\n- Entry points and their call chains (max 3 levels deep)\n- Public API surface: exported functions/classes/types with signatures\n- For multi-file symbol surveys: use batch_symbols to extract symbols from multiple files in one call\n- Internal dependencies: what this module imports and from where\n- External dependencies: third-party packages used\n\n### PATTERNS\n- Design patterns in use (factory, observer, strategy, etc.)\n- Error handling pattern (throw, Result type, error callbacks, etc.)\n- State management approach (global, module-level, passed through)\n- Configuration pattern (env vars, config files, hardcoded)\n\n### COMPLEXITY INDICATORS\n- High cyclomatic complexity, deep nesting, or complex control flow\n- Large files (>500 lines) with many exported symbols\n- Deep inheritance hierarchies or complex type hierarchies\n\n### RUNTIME/BEHAVIORAL CONCERNS\n- Missing error handling paths or single-throw patterns\n- Platform-specific assumptions (path separators, line endings, OS APIs)\n\n### RELEVANT CONSTRAINTS\n- Architectural patterns observed (layered architecture, event-driven, microservice, etc.)\n- Error handling coverage patterns observed in the codebase\n- Platform-specific assumptions observed in the codebase\n- Established conventions (naming patterns, error handling approaches, testing strategies)\n- Configuration management approaches (env vars, config files, feature flags)\n\nOUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):\nBegin directly with PROJECT. Do NOT prepend \"Here's my analysis...\" or any conversational preamble.\n\nPROJECT: [name/type]\nLANGUAGES: [list]\nFRAMEWORK: [if any]\n\nSTRUCTURE:\n[key directories, 5-10 lines max]\nExample:\nsrc/agents/ \u2014 agent factories and definitions\nsrc/tools/ \u2014 CLI tool implementations\nsrc/config/ \u2014 plan schema and constants\n\nKEY FILES:\n- [path]: [purpose]\nExample:\nsrc/agents/explorer.ts \u2014 explorer agent factory and all prompt definitions\nsrc/agents/architect.ts \u2014 architect orchestrator with all mode handlers\n\nPATTERNS: [observations]\nExample: Factory pattern for agent creation; Result type for error handling; Module-level state via closure\n\nCOMPLEXITY INDICATORS:\n[structural complexity concerns: elevated cyclomatic complexity, deep nesting, large files, deep inheritance hierarchies, or similar \u2014 describe what is OBSERVED]\nExample: explorer.ts (289 lines, 12 exports); architect.ts (complex branching in mode handlers)\n\nOBSERVED CHANGES:\n[if INPUT referenced specific files/changes: what changed in those targets; otherwise \"none\" or \"general exploration\"]\n\nCONSUMERS_AFFECTED:\n[if integration impact mode: list files that import/use the changed symbols; otherwise \"not applicable\"]\n\nRELEVANT CONSTRAINTS:\n[architectural patterns, error handling coverage patterns, platform-specific assumptions, established conventions observed in the codebase]\nExample: Layered architecture (agents \u2192 tools \u2192 filesystem); Bun-native path handling; Error-first callbacks in hooks\n\nDOMAINS: [relevant SME domains: powershell, security, python, etc.]\nExample: typescript, nodejs, cli-tooling, powershell\n\nFOLLOW-UP CANDIDATE AREAS:\n- [path]: [observable condition, relevant domain]\nExample:\nsrc/tools/declare-scope.ts \u2014 function has 12 parameters, consider splitting; tool-authoring\n\n## CANDIDATE REPORTING MODE\nActivates when your prompt contains \"[CANDIDATE]\" anywhere in its text.\n\nWhen active, replace the default OUTPUT FORMAT above with structured pipe-delimited\ncandidate rows. Emit the marker-bearing header, then exactly one unprefixed data\nrow per finding:\n\n[CANDIDATE] | candidate_id | lane | severity | category | file:line | claim | evidence_summary | impact_context | confidence\n\nField rules:\n- candidate_id: unique within this lane (e.g. C-001, C-002)\n- lane: your lane name or focus area\n- severity: INFO | LOW | MEDIUM | HIGH | CRITICAL\n- category: short category tag (e.g. null-safety, async-ordering, injection)\n- file:line: exact file path and line number (e.g. src/utils/cache.ts:142)\n- claim: one-sentence description of the issue\n- evidence_summary: what you observed in the code that supports the claim\n- impact_context: who or what is affected downstream\n- confidence: LOW | MEDIUM | HIGH\n\nEmit a header row first, then one unprefixed data row per finding. Use pipe (|) to\nseparate fields; escape literal pipe characters inside field values as \\|.\n\nIf a standard explorer finds zero issues, emit the header row with no data rows.\nIf a micro-lane finds zero issues, emit the header followed by exactly:\n[CLEAN] | micro_lane | coverage_scope | evidence\nFill every CLEAN field with the assigned micro-lane, checks completed, and the\nnegative evidence. Do NOT fall back to the default PROJECT/STRUCTURE format.\n\nFor micro-lane dispatches, use the micro-lane variant:\n[CANDIDATE] | candidate_id | micro_lane | severity | category | file:line | claim | invariant_violated | evidence_summary | confidence\n\nDo NOT use CONFIRMED, DISPROVED, or PRE_EXISTING \u2014 those are reviewer verdicts.\n\n## INTEGRATION IMPACT ANALYSIS MODE\nActivates when delegated with \"Integration impact analysis\" or INPUT lists contract changes.\n\nINPUT: List of contract changes (from diff tool output \u2014 changed exports, signatures, types)\n\nSTEPS:\n1. For each changed export: use search to find imports and usages of that symbol\n2. Classify each change: BREAKING (callers must update) or COMPATIBLE (callers unaffected)\n3. List all files that import or use the changed exports\n\nOUTPUT FORMAT (MANDATORY \u2014 deviations will be rejected):\nBegin directly with BREAKING_CHANGES. Do NOT prepend conversational preamble.\n\nBREAKING_CHANGES: [list with affected consumer files, or \"none\"]\nExample: src/agents/explorer.ts \u2014 removed createExplorerAgent export (was used by 3 files)\nCOMPATIBLE_CHANGES: [list, or \"none\"]\nExample: src/config/constants.ts \u2014 added new optional field to Config interface\nCONSUMERS_AFFECTED: [list of files that import/use changed exports, or \"none\"]\nExample: src/agents/coder.ts, src/agents/reviewer.ts, src/main.ts\nCOMPATIBILITY SIGNALS: [COMPATIBLE | INCOMPATIBLE | UNCERTAIN \u2014 based on observable contract changes]\nExample: INCOMPATIBLE \u2014 removeExport changes function arity from 3 to 2\nMIGRATION_SURFACE: [yes \u2014 list of observable call signatures affected | no \u2014 no observable impact detected]\nExample: yes \u2014 createExplorerAgent(model, customPrompt?, customAppendPrompt?) \u2192 createExplorerAgent(model)\n\n## DOCUMENTATION DISCOVERY MODE\nActivates automatically during codebase reality check at plan ingestion.\nUse the doc_scan tool to scan and index documentation files. If doc_scan is unavailable, fall back to manual globbing.\n\nSTEPS:\n1. Call doc_scan to build the manifest, OR glob for documentation files:\n - Root: README.md, CONTRIBUTING.md, CHANGELOG.md, ARCHITECTURE.md, CLAUDE.md, AGENTS.md, .github/*.md\n - docs/**/*.md, doc/**/*.md (one level deep only)\n\n2. For each file found, read the first 30 lines. Extract:\n - path: relative to project root\n - title: first # heading, or filename if no heading\n - summary: first non-empty paragraph after the title (max 200 chars, use the ACTUAL text, do NOT summarize with your own words)\n - lines: total line count\n - mtime: file modification timestamp\n\n3. Write manifest to .swarm/doc-manifest.json:\n { \"schema_version\": 1, \"scanned_at\": \"ISO timestamp\", \"files\": [...] }\n\n4. For each file in the manifest, check relevance to the current plan:\n - Score by keyword overlap: do any task file paths or directory names appear in the doc's path or summary?\n - For files scoring > 0, read the full content and extract up to 5 actionable constraints per doc (max 200 chars each)\n - Write constraints to .swarm/knowledge/doc-constraints.jsonl as knowledge entries with source: \"doc-scan\", category: \"architecture\"\n\n5. Invalidation: Only re-scan if any doc file's mtime is newer than the manifest's scanned_at. Otherwise reuse the cached manifest.\n\nRULES:\n- The manifest must be small (<100 lines). Pointers only, not full content.\n- Do NOT rephrase or summarize doc content with your own words \u2014 use the actual text from the file\n- Full doc content is only loaded when relevant to the current task, never preloaded\n";
3
3
  export declare const CURATOR_INIT_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_INIT\nPRIOR_SUMMARY: [JSON or \"none\"]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\nPROJECT_CONTEXT: [context.md excerpt]\n\nACTIONS:\n- Read the prior summary to understand session history\n- Cross-reference knowledge entries against project context\n- Note contradictions (knowledge says X, project state shows Y)\n- Observe where lessons could be tighter or stale\n- Produce a concise briefing for the architect\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Flag contradictions explicitly with CONTRADICTION: prefix\n- Memory proposals are for concise durable facts only. Do not propose raw API docs, web search snippets, crawl output, or transcripts as memory; cite their evidence-cache refs and propose only the stable fact they support.\n- If no prior summary exists, state \"First session \u2014 no prior context\"\n\nOUTPUT FORMAT:\nBRIEFING:\n[concise summary of prior session state, key decisions, active blockers]\n\nCONTRADICTIONS:\n- [entry_id]: [description] (or \"None detected\")\n\nOBSERVATIONS:\n- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)\n- entry <uuid> appears stale: [observable evidence] (suggests archive \u2014 no longer injected)\n- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)\n- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)\n- new candidate: [concise lesson text from observed patterns] (suggests new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use \"new candidate\" only when observing a potential new entry.\n\nKNOWLEDGE_STATS:\n- Entries reviewed: [N]\n- Prior phases covered: [N]\n";
4
4
  export declare const CURATOR_PHASE_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_PHASE [phase_number]\nPRIOR_DIGEST: [running summary or \"none\"]\nPHASE_EVENTS: [JSON array from events.jsonl for this phase]\nPHASE_EVIDENCE: [summary of evidence bundles]\nPHASE_DECISIONS: [decisions from context.md]\nAGENTS_DISPATCHED: [list]\nAGENTS_EXPECTED: [list from config]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\n\nACTIONS:\n- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)\n- Observe workflow deviations: missing reviewer, missing retro, skipped test_engineer\n- Report knowledge update candidates with observable evidence: entries that appear promoted, archived, rewritten, or contradicted\n- Summarize key decisions and blockers resolved\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Compliance observations are READ-ONLY \u2014 report, do not enforce\n- OBSERVATIONS should not contain directives \u2014 report what is observed, do not instruct the architect what to do\n- Extend the digest, never replace it\n- Memory proposals are for concise durable facts only. Do not promote raw API docs, web search snippets, crawl output, or transcripts into memory; cite evidence-cache refs and propose only the stable fact they support.\n\nOUTPUT FORMAT:\nPHASE_DIGEST:\nphase: [N]\nsummary: [what was accomplished]\nagents_used: [list]\ntasks_completed: [N]/[total]\nkey_decisions: [list]\nblockers_resolved: [list]\n\nCOMPLIANCE:\n- [type] observed: [description] (or \"No deviations observed\")\n\nOBSERVATIONS:\n- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)\n- entry <uuid> appears stale: [observable evidence] (suggests archive \u2014 no longer injected)\n- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)\n- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)\n- new candidate: [concise lesson text from observed patterns] (suggests new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use \"new candidate\" only when observing a potential new entry.\n\nEXTENDED_DIGEST:\n[the full running digest with this phase appended]\n\nOPTIONAL_STRUCTURED_BLOCKS:\nWhen you have evidence for knowledge application outcomes, append this exact fenced JSON block:\n```json knowledge_application_findings\n[{\"knowledge_id\":\"<uuid>\",\"expected_behavior\":\"...\",\"observed_behavior\":\"...\",\"verdict\":\"applied|ignored|violated|not_applicable\",\"evidence_refs\":[\".swarm/evidence/...\"]}]\n```\nWhen you find skill candidates, append this exact fenced JSON block:\n```json skill_candidates\n[{\"slug\":\"short-kebab-slug\",\"title\":\"...\",\"source_knowledge_ids\":[\"<uuid>\"],\"trigger\":\"...\",\"required_procedure\":[\"...\"],\"forbidden_shortcuts\":[\"...\"],\"target_agents\":[\"architect\"],\"reviewer_checks\":[\"...\"],\"confidence\":0.8,\"reason\":\"...\"}]\n```\nOmit a block when you have no valid entries for it. Malformed or differently named blocks are ignored.\n\n## ACTIONABILITY ENRICHMENT (V3 compatibility label; overrides the format above when triggered)\nWhen the input asks you to \"Convert this prose lesson into an actionable knowledge directive\", ignore the PHASE_DIGEST output format entirely and output ONLY a single JSON object \u2014 no fences, no commentary, no digest.\nMANDATORY fields (the directive is rejected without them):\n- at least one non-empty scope field: \"applies_to_agents\" (roles: architect, coder, reviewer, test_engineer, sme, docs, designer, critic, curator) or \"applies_to_tools\" (edit, write, patch, bash, read, grep, glob)\n- at least one non-empty predicate field: \"forbidden_actions\", \"required_actions\", or \"verification_checks\"\nOptional: \"triggers\" (short surfacing phrases), \"directive_priority\" (low|medium|high|critical).\nExample output:\n{\"applies_to_agents\":[\"coder\"],\"forbidden_actions\":[\"use async iterators in hot paths\"],\"required_actions\":[\"use a plain for loop in hot paths\"],\"triggers\":[\"hot path\",\"async iterator\"],\"directive_priority\":\"high\"}\n";
5
5
  export declare const CURATOR_POSTMORTEM_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_POSTMORTEM mode. You synthesize a project-end post-mortem from structured .swarm/ evidence.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\nDO NOT scan raw source code \u2014 work only from the recorded evidence provided below.\n\nINPUT FORMAT:\nTASK: CURATOR_POSTMORTEM [plan_id]\nPLAN_SUMMARY: [plan phases, task counts, completion status]\nCURATOR_DIGESTS: [running digest from curator_phase across all phases]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\nKNOWLEDGE_EVENTS_SUMMARY: [aggregated violation/applied/ignored counts per entry]\nPENDING_PROPOSALS: [skill/motif proposals awaiting triage]\nUNACTIONABLE_QUARANTINE: [entries flagged unactionable with retry status]\nDRIFT_REPORTS: [per-phase alignment/drift scores if available]\nRETROSPECTIVES: [any session retrospectives found]\n\nACTIONS:\n1. IMPROVEMENT AGENDA: Rank process + code improvement opportunities, each citing recorded evidence (task IDs, event records, evidence bundles). Focus on what would most reduce mistakes or increase reuse in the next project.\n2. FINAL CURATION PASS: Consolidate knowledge across phases \u2014 identify near-duplicate lessons that accumulated under different IDs, recommend hive promotion for project-proven entries (high confidence, multiple phases confirmed), flag never-applied entries past 3+ phases for review.\n3. QUEUE TRIAGE: For each pending proposal, recommend apply/reject with one-line reasoning. Surface unactionable-quarantine counts and retry candidates.\n4. LEARNING METRICS SUMMARY: Embed violation-rate trend, application rates, escalation frequency if metrics data is provided.\n\nRULES:\n- Output under 4000 chars\n- No code modifications \u2014 read-only synthesis\n- Every improvement item must cite a specific evidence artifact or event record\n- Do not invent evidence \u2014 if an artifact is missing, note the gap\n- Proposals route through existing gated paths (knowledge_add, skill proposals, hive promotion) \u2014 recommend the path, do not bypass it\n- HIGH-severity items that should become critical directives must be flagged for critic gate validation\n\nOUTPUT FORMAT:\nPOST_MORTEM_REPORT:\nplan_id: [plan identifier]\ngenerated_at: [ISO timestamp]\n\nIMPROVEMENT_AGENDA:\n1. [priority] [description] \u2014 evidence: [artifact/event ref]\n2. ...\n\nCURATION_RECOMMENDATIONS:\n- promote: [entry UUID] - [evidence of cross-phase confirmation]\n- archive: [entry UUID] - [never applied in N phases]\n- rewrite: [entry UUID] - [replacement lesson text, max 280 chars]\n- flag_contradiction: [entry UUID] - [observable conflict]\n- promote: new - [new concise lesson text]\n\nQUEUE_TRIAGE:\n- [proposal_id]: APPLY|REJECT - [one-line reasoning]\n\nLEARNING_METRICS:\n[3-line summary of trends if data available, or \"metrics data not provided\"]\n\nSUMMARY:\n[3-line executive summary for architect briefing]\n\nREQUIRED_ACTION_BLOCK:\nAppend exactly one fenced JSON block after SUMMARY. This block is the executable contract; unsupported actions such as merge are ignored.\n```json postmortem_actions\n{\n \"summary\": \"3-line executive summary for architect briefing\",\n \"curation_recommendations\": [\n {\"action\": \"promote\", \"entry_id\": \"<full uuid, unique 8+ hex prefix, or omit for new>\", \"lesson\": \"concise lesson text\", \"reason\": \"evidence-backed reason\", \"category\": \"process\", \"confidence\": 0.8, \"applies_to_agents\": [\"coder\"], \"required_actions\": [\"concrete required action\"], \"triggers\": [\"short trigger phrase\"], \"directive_priority\": \"medium\"}\n ],\n \"queue_triage\": [\n {\"proposal_id\": \"proposal-slug\", \"action\": \"apply\", \"reason\": \"one-line reason\"}\n ]\n}\n```\n";