opencode-swarm 7.160.0 → 7.160.2

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 (97) hide show
  1. package/.opencode/skills/critic-gate/SKILL.md +8 -1
  2. package/.opencode/skills/execute/SKILL.md +4 -3
  3. package/.opencode/skills/phase-wrap/SKILL.md +2 -0
  4. package/.opencode/skills/running-tests/SKILL.md +6 -0
  5. package/.opencode/skills/swarm-implement/SKILL.md +2 -0
  6. package/.opencode/skills/swarm-pr-review/SKILL.md +29 -29
  7. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +21 -5
  8. package/dist/agents/architect.d.ts +1 -1
  9. package/dist/background/pending-delegations.d.ts +46 -1
  10. package/dist/background/pr-review-contract.d.ts +245 -2
  11. package/dist/build/command-resolution.d.ts +13 -0
  12. package/dist/build/discovery.d.ts +11 -4
  13. package/dist/cli/{coder-settlement-zn552sp9.js → coder-settlement-gzar5ypz.js} +9 -9
  14. package/dist/cli/{config-doctor-ddtdz2g0.js → config-doctor-ancn1sj7.js} +3 -3
  15. package/dist/cli/{core-embasn2j.js → core-bhmqtxev.js} +2 -2
  16. package/dist/cli/{curation-policy-agr6ga1s.js → curation-policy-47przjwg.js} +4 -4
  17. package/dist/cli/curator-llm-factory-6mw01jx1.js +67 -0
  18. package/dist/cli/{curator-dgp6dxxn.js → curator-sgmynbpm.js} +32 -32
  19. package/dist/cli/{dispatch-7r46tfr9.js → dispatch-q4v8x2pk.js} +1 -1
  20. package/dist/cli/{evidence-summary-service-sbnyann4.js → evidence-summary-service-1pcfsqhv.js} +13 -13
  21. package/dist/cli/{gate-evidence-5v67a1dz.js → gate-evidence-w0kjqmew.js} +5 -5
  22. package/dist/cli/guardrail-explain-k99eje1y.js +68 -0
  23. package/dist/cli/{guardrail-log-zbnbff1y.js → guardrail-log-md5gcpk7.js} +7 -7
  24. package/dist/cli/{guardrail-reset-3cnz54hx.js → guardrail-reset-3385eqmq.js} +32 -32
  25. package/dist/cli/{hive-promoter-7cr7t2kg.js → hive-promoter-r0ekyn5m.js} +32 -32
  26. package/dist/cli/{index-wzx6atbv.js → index-2123hwbj.js} +3 -3
  27. package/dist/cli/{index-nj6rmyeh.js → index-3146wmgv.js} +352 -149
  28. package/dist/cli/{index-5m7qjj29.js → index-3a35tt6a.js} +6 -6
  29. package/dist/cli/{index-q6gjwy7m.js → index-497a3hhj.js} +2 -2
  30. package/dist/cli/{index-7qv869f0.js → index-4d8cq6e1.js} +5 -5
  31. package/dist/cli/{index-w699ekk9.js → index-4dcz9fpn.js} +2 -2
  32. package/dist/cli/{index-zjvf7edj.js → index-5th50g17.js} +1 -1
  33. package/dist/cli/{index-va1edd2n.js → index-5xfx5sbw.js} +5 -5
  34. package/dist/cli/{index-1f4n43yz.js → index-6scakreq.js} +5 -4
  35. package/dist/cli/{index-962jgzdq.js → index-717pmdce.js} +1 -1
  36. package/dist/cli/{index-rq7k03rk.js → index-7ezv5j23.js} +1 -1
  37. package/dist/cli/{index-4mm22fzj.js → index-7h2armwf.js} +1 -1
  38. package/dist/cli/{index-gt8cxfbp.js → index-am5bz6mf.js} +2 -2
  39. package/dist/cli/{index-cn233hsy.js → index-awjx0wgk.js} +1 -1
  40. package/dist/cli/{index-h3re5c78.js → index-c9zp4xwc.js} +12 -1
  41. package/dist/cli/{index-p39xem8b.js → index-dh5q6z7y.js} +3 -3
  42. package/dist/cli/{index-xs15netk.js → index-j3ss86kf.js} +1 -1
  43. package/dist/cli/{index-d9s5hb0m.js → index-k0qy284k.js} +5 -5
  44. package/dist/cli/{index-sy5aeegg.js → index-k50kxd3w.js} +866 -37
  45. package/dist/cli/{index-fzkx24q5.js → index-kqzba6ex.js} +2 -2
  46. package/dist/cli/{index-e75bzfgd.js → index-mmr96pwr.js} +1 -1
  47. package/dist/cli/{index-85qjc7b2.js → index-nk498mx6.js} +1 -1
  48. package/dist/cli/{index-9fspg1xw.js → index-prv20xq6.js} +1 -1
  49. package/dist/cli/{index-ebz97mks.js → index-q8hm27yj.js} +8 -1
  50. package/dist/cli/{index-8bjv01t8.js → index-re338hf1.js} +4 -4
  51. package/dist/cli/{index-rnyt2z5r.js → index-s7w6ntw6.js} +321 -448
  52. package/dist/cli/{index-jmths6jj.js → index-vsy942dt.js} +34 -34
  53. package/dist/cli/{index-rhc8jve7.js → index-vv760pbg.js} +2 -2
  54. package/dist/cli/{index-3yh737hc.js → index-war2dt6a.js} +6 -6
  55. package/dist/cli/{index-yrar1ask.js → index-xkmzsfg5.js} +3 -3
  56. package/dist/cli/{index-3055dgzp.js → index-xsd7y4hp.js} +4 -4
  57. package/dist/cli/{index-py6bqwnb.js → index-xtwny1ae.js} +16 -2
  58. package/dist/cli/{index-9q6w7kke.js → index-yd6y4qr7.js} +1 -1
  59. package/dist/cli/{index-kkfgygvn.js → index-yp81ebrx.js} +4 -4
  60. package/dist/cli/{index-9k3zc2t8.js → index-zbnf26br.js} +6 -6
  61. package/dist/cli/{index-s7w428r3.js → index-znf683sm.js} +1 -1
  62. package/dist/cli/index.js +32 -32
  63. package/dist/cli/{knowledge-escalator-zksm9833.js → knowledge-escalator-saekqp8t.js} +12 -12
  64. package/dist/cli/{knowledge-events-ayta750w.js → knowledge-events-ej8yz3yq.js} +10 -10
  65. package/dist/cli/{knowledge-link-7c7fjnzc.js → knowledge-link-xezm8hr3.js} +3 -3
  66. package/dist/cli/{knowledge-store-q5axge8b.js → knowledge-store-3jamj5n4.js} +4 -4
  67. package/dist/cli/{knowledge-validator-3rrbva2p.js → knowledge-validator-26w2mvqv.js} +6 -6
  68. package/dist/cli/{model-preflight-x9szw1v4.js → model-preflight-yqqchzjn.js} +1 -1
  69. package/dist/cli/{pending-delegations-kc7tzxg9.js → pending-delegations-7xak7g59.js} +5 -3
  70. package/dist/cli/{pr-review-reentry-authorization-vag5gh50.js → pr-review-reentry-authorization-v97q63q4.js} +34 -33
  71. package/dist/cli/{pr-subscriptions-wbdw9a82.js → pr-subscriptions-asjevc5p.js} +3 -3
  72. package/dist/cli/{runner-p9wg6z34.js → runner-wsdcy2d6.js} +4 -4
  73. package/dist/cli/{scan-cursor-4fjwtt1k.js → scan-cursor-1agr50f8.js} +5 -5
  74. package/dist/cli/{schema-d0nbzj5k.js → schema-z0ygrqgy.js} +4 -2
  75. package/dist/cli/{scope-persistence-bckcbc8h.js → scope-persistence-tncg38by.js} +8 -8
  76. package/dist/cli/{skill-generator-kebhevet.js → skill-generator-jq20a09m.js} +14 -14
  77. package/dist/cli/{worktree-collision-ownership-h8qswnrp.js → worktree-collision-ownership-b9cp9zvw.js} +4 -4
  78. package/dist/cli/{worktree-isolation-q0kbmadz.js → worktree-isolation-dzyxf8hn.js} +32 -32
  79. package/dist/config/constants.d.ts +8 -0
  80. package/dist/config/evidence-schema.d.ts +21 -0
  81. package/dist/config/schema.d.ts +8 -0
  82. package/dist/hooks/pr-workflow-gate.d.ts +25 -1
  83. package/dist/index.js +333 -319
  84. package/dist/lang/default-backend.d.ts +1 -13
  85. package/dist/tools/build-check.d.ts +4 -0
  86. package/dist/tools/dispatch-lanes.d.ts +27 -3
  87. package/dist/tools/index.d.ts +1 -0
  88. package/dist/tools/manifest.d.ts +1 -0
  89. package/dist/tools/sast-baseline.d.ts +2 -0
  90. package/dist/tools/sast-scan.d.ts +2 -2
  91. package/dist/tools/submit-pr-review-result.d.ts +5 -0
  92. package/dist/tools/test-runner.d.ts +2 -0
  93. package/dist/tools/tool-metadata.d.ts +8 -0
  94. package/opencode-swarm.schema.json +4 -0
  95. package/package.json +1 -1
  96. package/dist/cli/curator-llm-factory-7cwvmc46.js +0 -67
  97. package/dist/cli/guardrail-explain-2gwarnca.js +0 -68
@@ -41,13 +41,20 @@ one-line `reason` (or ask the user to run `/swarm approve-plan-critic
41
41
  <reason>`). This records a manual `plan_critic_gate` approval snapshot
42
42
  tagged `method: "manual_override"`, audited to `.swarm/events.jsonl`.
43
43
  Architect-only. Use ONLY when a legitimate APPROVED was lost — this is an
44
- escape hatch, not a substitute for running the critic review.
44
+ escape hatch, not a substitute for running the critic review. It is also the sanctioned recovery for a bookkeeping-grade hashed-field repair under PLAN FREEZE below.
45
45
 
46
46
  CRITIC-GATE TRIGGER: Run ONCE when you first write the complete .swarm/plan.md.
47
47
  Do NOT re-run CRITIC-GATE before every project phase.
48
48
  If resuming a project with an existing approved plan, CRITIC-GATE is already satisfied.
49
49
  Caveat: this assumption breaks if the plan lacks a `plan_critic_gate`-tagged approval snapshot (e.g. a plan approved before this mechanical gate existed, or one where the recording heuristic didn't fire) — in that case the first coder dispatch will fail with `PLAN_CRITIC_GATE_VIOLATION`. If that happens, do not assume CRITIC-GATE is satisfied; re-run it and get a fresh APPROVED verdict.
50
50
 
51
+ PLAN FREEZE AFTER APPROVAL (issue #1994 P1): once the critic returns APPROVED, the plan is frozen. The coder dispatch gate compares the plan against the approval snapshot via the structure hash (`computePlanStructureHash`), so classify post-approval changes by what that hash actually covers:
52
+ - STATUS-ONLY changes (task status transitions via `update_task_status`) are excluded from the hash and never invalidate the approval — no re-critic needed.
53
+ - MATERIAL (invalidates the approval): adding or removing tasks; changing any task's `id`, `phase`, `description`, `acceptance`, or `depends`; or enumerating `removed_task_ids` on a re-save. Re-run MODE: CRITIC-GATE exactly ONCE on the revised plan and get a fresh APPROVED before the next coder dispatch — the dispatch fails `PLAN_CRITIC_GATE_VIOLATION` against the stale snapshot otherwise.
54
+ - `fr_refs` changes are MATERIAL on process grounds (spec traceability feeds the critic's obligation check) even though the hash deliberately excludes `fr_refs` — the runtime will not catch this for you; re-critic is still required.
55
+ - BOOKKEEPING-GRADE hashed fields (`size`, `evidence_path`, `blocked_reason`, `title`, `current_phase`, `files_touched`) trip the gate mechanically even for pure bookkeeping edits. For a genuine bookkeeping repair — most commonly a `files_touched`-only reconciliation aligned with an active `declare_scope` binding (the sanctioned `SCOPE_CONFLICT` repair path in the execute skill) — use the gate's own recovery: `approve_plan_critic` with a truthful one-line reason (audited to `.swarm/events.jsonl`), not a full re-critic. Any substantive scope growth beyond reconciliation is MATERIAL: re-critic.
56
+ Batching rule: material changes accumulated across multiple `save_plan` calls since the last APPROVED count as ONE batch — re-critic that batch once, and never split material changes across separate calls to dodge the re-critic. The pre-change approval is never valid for the changed plan.
57
+
51
58
  6j. SPEC-GATE (Execute BEFORE any save_plan call):
52
59
  - An effective spec exists iff `/swarm sdd status` reports a resolved spec (it reflects `readEffectiveSpecSync`, which returns null — NO effective spec — for no sources, multiple competing sources (openspec+specify), multi-feature Spec-Kit without a selected feature, or any unresolvable state). `save_plan` rejects (SPEC_REQUIRED) when `/swarm sdd status` reports no resolved spec. The gate is overridable via `SWARM_SKIP_SPEC_GATE=1`.
53
60
  - Before calling save_plan, verify an effective spec exists (via `/swarm sdd status` or `lint_spec`).
@@ -73,8 +73,9 @@ All other gates: failure → return to coder. No self-fixes. No workarounds.
73
73
  → REQUIRED: Print "diff: [PASS | CONTRACT CHANGE — details]"
74
74
  5d. Run `syntax_check` tool. SYNTACTIC ERRORS → return to coder. NO ERRORS → proceed to placeholder_scan.
75
75
  → REQUIRED: Print "syntaxcheck: [PASS | FAIL — N errors]"
76
- 5e. Run `placeholder_scan` tool. PLACEHOLDER FINDINGS → return to coder. NO FINDINGS → proceed to imports.
77
- REQUIRED: Print "placeholderscan: [PASS | FAILN findings]"
76
+ 5e. Run `placeholder_scan` tool WITH DIFF SCOPING: pass `added_lines` — a map of workspace-relative file path → the line numbers ADDED by this task's uncommitted work (from `git diff -U0 HEAD -- <task files>` for tracked files; the coder's edits are not committed yet, so a commit-range diff like `<base>...HEAD` returns zero added lines here) — so only task-added lines drive the verdict. PLACEHOLDER FINDINGS (on added lines) → return to coder. NO FINDINGS → proceed to imports.
77
+ Diff-scope fallback: for a file whose added lines you cannot map (new/untracked file, no diff available) or whose computed added-line set is EMPTY, OMIT that file from `added_lines` entirely the tool then scans it unfiltered (fail-closed) — and manually cross-check that file's findings against the changed lines before returning to coder. NEVER pass an empty line array for a file (an empty array suppresses every finding in it) and NEVER hand-enumerate guessed line numbers (a wrong map silently suppresses findings). A pre-existing TODO/FIXME on an unchanged line is existing debt to surface to the reviewer, not a coder bounce.
78
+ → REQUIRED: Print "placeholderscan: [PASS | FAIL — N findings (diff-scoped) | FAIL — N findings (unscoped — cross-checked against changed lines)]"
78
79
  5f. Run `imports` tool for dependency audit. ISSUES → return to coder.
79
80
  → REQUIRED: Print "imports: [PASS | ISSUES — details]"
80
81
  5g. Run `lint` tool with fix mode for auto-fixes. If issues remain → run `lint` tool with check mode. FAIL → return to coder.
@@ -193,7 +194,7 @@ This step supplements (not replaces) the existing regression-sweep and test-drif
193
194
  5o. ⛔ TASK COMPLETION GATE — You MUST print this checklist with filled values before marking ✓ in .swarm/plan.md:
194
195
  [TOOL] diff: PASS / SKIP — value: ___
195
196
  [TOOL] syntax_check: PASS — value: ___
196
- [TOOL] placeholder_scan: PASS — value: ___
197
+ [TOOL] placeholder_scan: PASS — value: ___ (diff-scoped | unscoped — cross-checked)
197
198
  [TOOL] imports: PASS — value: ___
198
199
  [TOOL] lint: PASS — value: ___
199
200
  [TOOL] build_check: PASS / SKIPPED — value: ___
@@ -105,6 +105,8 @@ If any required agent is missing, `phase_complete` returns `{ success: false, st
105
105
 
106
106
  The `docs` agent requirement is controlled by `phase_complete.require_docs` in plugin configuration, not by the QA gate profile returned by `get_qa_gate_profile`. It defaults to `true`. Set it to `false` only when the phase genuinely has no documentation obligation. A successful docs completion is persisted as plan- and phase-bound participation proof so `phase_complete` can recover it after a session restart; unrelated task-gate evidence does not count as docs participation.
107
107
 
108
+ Docs-attestation integrity (issue #1994 P2): when the docs agent concludes that a phase — especially a doc-only phase — needs no further documentation edits, that attestation is valid ONLY if the docs agent actually inspected the phase's changed files and recorded what it checked (files read, per-file verdict) in its completion report. A mechanical "no edits needed" reply dispatched only to satisfy `agentsDispatched` — without inspecting the phase's changes — is a process violation: the gate exists to catch documentation drift, not to be acknowledged past.
109
+
108
110
  The `coder` and `test_engineer` agents are required because every phase that modifies source code or tests must have at least one implementation and one test-verification delegation. For pure documentation or retrospective phases, these may be waived by the user explicitly.
109
111
 
110
112
  This is a hard enforcement mechanism, not a suggestion. `phase_complete` will not return `status: success` if any required agent is missing from `agentsDispatched`.
@@ -232,6 +232,12 @@ git worktree remove "$env:TEMP\repro-check"
232
232
 
233
233
  ---
234
234
 
235
+ ## Placeholder Scans Without Diff Line Numbers
236
+
237
+ `placeholder_scan` is diff-aware: when you can supply `added_lines` (a map of workspace-relative file path → added line numbers from the task/PR diff), its verdict covers only the added lines, so a pre-existing TODO/FIXME on an unchanged line inside a changed file no longer fails the gate. When you CANNOT map a file's added lines (new/untracked file, no diff access) — or the computed added-line set is EMPTY — omit that file from `added_lines` entirely: the tool scans it unfiltered, fail-closed, and you manually cross-check that file's findings against the changed lines before treating a finding as introduced by the change. NEVER pass an empty line array for a file (an empty array suppresses every finding in it) and NEVER hand-enumerate guessed line numbers: a wrong `added_lines` map silently suppresses findings.
238
+
239
+ ---
240
+
235
241
  ## Failure Classification
236
242
 
237
243
  Not all failures are equal. Before deciding what to do, classify the failure:
@@ -117,6 +117,8 @@ Implement in coherent, reviewable chunks. Follow existing repository patterns.
117
117
 
118
118
  **`declare_scope` discipline.** Before every coder or test-engineer delegation (and before every retry), call `declare_scope({ taskId, files, replace_existing: true })` with the exact workspace-relative file list the delegated agent may modify — including generated or lockfile paths the change will produce (for example, `dist/*`, `package-lock.json`, or `bun.lock`). Direct and shell writes are both scope-enforced. If the file list is not completely obvious, declare the containing workspace-relative directories instead. Treat `SCOPE_CONFLICT`, `SCOPE_BINDING_EXPIRED`, `SCOPE_BINDING_AMBIGUOUS`, and `SCOPE_WORKSPACE_MISMATCH` as architect-owned recovery signals: reconcile the named scope sources or lane root, replace the declaration, then redispatch. Never instruct the delegated agent to bypass the gate or switch write mechanisms.
119
119
 
120
+ **Smallest justified scope on `SCOPE_CONFLICT` (issue #1994 S4).** The replacement declaration must be the SMALLEST justified scope: first reconcile what the delegation actually intends to write (the task's files vs the conflicting scope source named in the diagnostic), then narrow the conflicting lower-precedence source to a subset of that list — repair stale plan scope with `save_plan` and/or the delegation's `FILE:` lines — and only then re-declare exactly that file list; re-declaring alone leaves the non-subset relation and reproduces the same `SCOPE_CONFLICT`. Split the task into separate delegations if the conflict reveals two disjoint write sets. NEVER resolve a `SCOPE_CONFLICT` by widening to a plan-inferred superset: auto-widening over-authorizes writes and hides an inaccurate plan or delegation prompt behind a bigger scope. This matches the execute skill's scope-recovery contract ("Do not widen scope just to make the sets agree"); a `save_plan` scope repair is a bookkeeping change covered by the critic-gate plan-freeze rule.
121
+
120
122
  If the project exposes `sast_scan` with `capture_baseline`, capture the
121
123
  phase-scoped SAST baseline before first coder delegation so later scans fail only
122
124
  on new findings rather than pre-existing infrastructure noise.
@@ -66,12 +66,7 @@ This protocol runs on any agent harness. Before Phase 0, detect which profile
66
66
  this session is in by checking the actual tool list — never assume from the
67
67
  harness name, and never guess:
68
68
 
69
- - **Profile A — structured PR-workflow controller.** The swarm plugin's
70
- controller tools are available in this session: `dispatch_lanes_async`,
71
- `collect_lane_results`, `retrieve_lane_output`, `parse_lane_candidates`,
72
- `write_pr_review_artifact`, `write_pr_review_trigger_eval`,
73
- `complete_pr_workflow`. Typical host: OpenCode with the swarm plugin. The
74
- controller mechanically enforces this skill's accounting: it computes the
69
+ - **Profile A — structured PR-workflow controller.** The swarm plugin's controller tools are available in this session: `dispatch_lanes_async`, `collect_lane_results`, `retrieve_lane_output`, `parse_lane_candidates`, `submit_pr_review_result`, `write_pr_review_artifact`, `write_pr_review_trigger_eval`, `complete_pr_workflow`. Typical host: OpenCode with the swarm plugin. The controller mechanically enforces this skill's accounting: it computes the
75
70
  depth tier itself from the bound merge-base diff (never from caller
76
71
  claims), enforces the tier's lane floors and full dimension/family
77
72
  partitions for consolidated dispatch, and gates structured reviewer/critic
@@ -101,11 +96,19 @@ harness name, and never guess:
101
96
 
102
97
  | Harness (typical) | Profile | Lane dispatch | Ledger persistence | Completion gate |
103
98
  |---|---|---|---|---|
104
- | OpenCode + swarm plugin | A | `dispatch_lanes_async` / `collect_lane_results` | `write_pr_review_artifact`, `write_pr_review_trigger_eval` | `complete_pr_workflow` |
99
+ | OpenCode + swarm plugin | A | `dispatch_lanes_async` / `collect_lane_results` | `submit_pr_review_result`, `write_pr_review_artifact`, `write_pr_review_trigger_eval` | `complete_pr_workflow` |
105
100
  | Claude Code | B | parallel `Agent`/`Task` subagents | ledger files in the session task workspace | Pre-Synthesis Gate checklist |
106
101
  | OpenAI Codex | B | parallel subagents (fresh context) | ledger files in working notes | Pre-Synthesis Gate checklist |
107
102
  | ZCode | B | parallel subagents (fresh context) | ledger files in working notes | Pre-Synthesis Gate checklist |
108
103
 
104
+ Host-native JSON-schema transport is optional and currently unregistered on the
105
+ tested OpenCode, Claude Code, Codex, and ZCode host matrix. Profile A therefore
106
+ uses the child-bound `submit_pr_review_result` tool as its supported baseline.
107
+ Any future native integration must implement the fixed internal
108
+ `promptJsonSchema({ sessionId, agent, schema, parts })` seam and pass the
109
+ adapter-present, unsupported-before-execution, provider-failure, timeout, and
110
+ per-session capability tests before registration.
111
+
109
112
  **Completion-gate assurance is NOT equivalent across profiles.** Only Profile A
110
113
  enforces completion MECHANICALLY: the controller's `complete_pr_workflow` receipt
111
114
  gate refuses synthesis unless base coverage, the 11-family trigger ledger, and the
@@ -155,10 +158,14 @@ ordering, vocabulary, or schema.
155
158
  Controller order is exact: bind the immutable head/base range; dispatch,
156
159
  settle, and parse base lanes; evaluate every trigger row; dispatch micro lanes;
157
160
  settle and parse every matched micro family; persist the trigger evaluation;
158
- persist post-explorer findings; run reviewers; run critics; then persist the
159
- final artifact and complete the workflow. The **initial** micro dispatch MUST
160
- supply the complete trigger-evaluation ledger; that dispatch freezes it for the
161
- session.
161
+ submit exactly one `submit_pr_review_result` receipt for each base/micro
162
+ discovery lane and then stop; persist post-explorer findings; run reviewers;
163
+ run critics; then persist the final artifact and complete the workflow. Transcript
164
+ `[CANDIDATE]` / `[CLEAN]` rows are deprecated legacy compatibility only for
165
+ lanes whose snapped `pr_review_legacy_transcript_compatibility` contract
166
+ explicitly enables them.
167
+ The **initial** micro dispatch MUST supply the complete trigger-evaluation
168
+ ledger; that dispatch freezes it for the session.
162
169
  Any subsequent micro batch in that same session MAY omit `trigger_evaluation`
163
170
  and reuse the frozen ledger. If a subsequent batch explicitly supplies a copy,
164
171
  that copy MUST remain exactly identical to the frozen ledger.
@@ -825,6 +832,7 @@ Tool candidate rules:
825
832
 
826
833
  - Confirm reachability before reporting.
827
834
  - Confirm PR-introducedness before reporting as a PR blocker.
835
+ - When `placeholder_scan` output is used as a signal, pass `added_lines` (file path → PR-added line numbers from the merge-base diff) so only added lines drive the scan; a placeholder finding on an unchanged line is a pre-existing-debt candidate, not a PR blocker. If added-line mapping is unavailable, treat the findings as unscoped and cross-check them against the PR diff before recording the row.
828
836
  - Confirm that a framework, schema, middleware, caller guard, or test isolation rule does not already mitigate it.
829
837
  - Do not report scanner output verbatim without reviewer validation.
830
838
  - Redact secrets; never paste raw credentials into the final output.
@@ -1107,28 +1115,17 @@ machine-readable rows as unfenced plain text; do not emit the backticks.
1107
1115
  [CANDIDATE] | candidate_id | lane | severity | category | file:line | claim | evidence_summary | impact_context | confidence | risk_impact | risk_tags
1108
1116
  ```
1109
1117
 
1110
- Profile A stores the full assistant transcript, so earlier unmarked progress
1111
- turns may precede the machine-readable section. The parser locates that section
1112
- at the first pipe-delimited line whose first field is exactly `[CANDIDATE]` and
1113
- ignores unmarked preamble, including incidental pipe-delimited text. That first
1114
- marker is authoritative and must be the exact canonical base or micro header;
1115
- a malformed marker or marker-prefixed data row without a header fails closed.
1116
- The Profile A controller coverage gate also refuses a missing marker. The pure
1117
- parser retains markerless positional fallback only for legacy callers outside
1118
- that controller trust boundary. Explorers should continue to make the canonical
1119
- header the first line of their final machine-readable response.
1118
+ Profile A now treats `submit_pr_review_result` as the authoritative settlement path for base and micro discovery lanes. The caller-bound structured receipt dominates later prose, truncation, or transcript incompleteness. Transcript candidate/clean rows remain deprecated compatibility only when `pr_review_legacy_transcript_compatibility` was explicitly enabled for that lane and no structured receipt exists; a present-but-invalid structured result fails closed and never falls back.
1119
+
1120
+ When compatibility mode is active, Profile A stores the full assistant transcript. The parser locates the first pipe-delimited line whose first field is exactly `[CANDIDATE]`, ignores unmarked preamble, and requires the exact canonical base/micro header; malformed markers or marker-prefixed rows without a header fail closed. The controller refuses a missing marker. Markerless positional fallback remains only for legacy callers outside that trust boundary; explorers should put the canonical header first.
1120
1121
 
1121
1122
  The confidence data value must be exactly LOW, MEDIUM, or HIGH.
1122
1123
 
1123
- Under Profile A the parser normalizes this into a structured `candidates[]`
1124
- array. On Profiles B/C — and as a Profile A fallback when the parser is
1125
- unavailable — the explorer emits the `[CANDIDATE]` row format directly in the
1126
- lane output as the extraction contract.
1124
+ Under Profile A the parser-backed transcript path is compatibility-only; a successful `submit_pr_review_result` receipt is authoritative. On Profiles B/C — and on a Profile A lane whose snapped contract explicitly enables deprecated legacy transcript compatibility and lacks a structured receipt — the explorer emits `[CANDIDATE]` rows directly as the extraction contract.
1127
1125
 
1128
1126
  Explorers must not use `CONFIRMED`, `DISPROVED`, or `PRE_EXISTING`.
1129
1127
 
1130
- A base lane that finds no surviving candidates must emit exactly one fully
1131
- populated clean row:
1128
+ A base lane that finds no surviving candidates must submit exactly one structured CLEAN result and then stop. Only a lane in the deprecated transcript-compatibility path may instead emit exactly one fully populated clean row:
1132
1129
 
1133
1130
  The fence below is documentation formatting only. Emit the clean attestation
1134
1131
  as unfenced plain text; do not emit the backticks.
@@ -1225,7 +1222,10 @@ artifact; and the completed ledger is persisted as `trigger-eval.json` in the
1225
1222
  session/task workspace before reviewer dispatch. A matched family with no
1226
1223
  attestation row is an unclosed coverage gap.
1227
1224
 
1228
- For each micro `output_ref` (Profile A), call `parse_lane_candidates` with
1225
+ For each micro lane in Profile A, prefer the single structured
1226
+ `submit_pr_review_result` receipt over transcript parsing. Only for a lane
1227
+ whose snapped contract explicitly enables deprecated transcript compatibility
1228
+ and lacks a structured receipt should you fall back to `parse_lane_candidates` against its `output_ref`, with
1229
1229
  `producer: "swarm-pr-review"`, `expected_family: "micro_lane"`, and
1230
1230
  `expected_micro_lane` set to the launch-micro-lane value from the
1231
1231
  provenance-linked trigger row. When the artifact came from a consolidated
@@ -1249,7 +1249,7 @@ errors, zero malformed rows, and a complete, non-degraded source:
1249
1249
  [CLEAN] | micro_lane | coverage_scope | evidence
1250
1250
  ```
1251
1251
 
1252
- Header-only or malformed zero output is `UNATTESTED`; apply the COVERAGE GATE (Phase 3). Under Profile A, the structured async PR-workflow path is required to preserve `L1`, exact-head, batch, and workflow-lane provenance; the active controller rejects blocking and direct-Task substitutes, and Task-derived findings or CLEAN prose cannot satisfy Phase 4's controller ledger. Under Profiles B/C, acceptance is the row contract itself: accept a candidate or clean row only when its `micro_lane` field matches the trigger row it claims, and treat prose-only "clean" claims as `UNATTESTED`.
1252
+ Header-only or malformed zero output is `UNATTESTED`; apply the COVERAGE GATE (Phase 3). Under Profile A, the structured async PR-workflow path must preserve `L1`, exact-head, batch, and workflow-lane provenance; the active controller rejects blocking and direct-Task substitutes, and Task-derived findings or CLEAN prose cannot satisfy Phase 4's controller ledger unless the lane explicitly runs deprecated transcript compatibility. Under Profiles B/C, acceptance is the row contract: accept a candidate or clean row only when its `micro_lane` matches the trigger row, and treat prose-only "clean" claims as `UNATTESTED`.
1253
1253
 
1254
1254
  Each micro-lane receives:
1255
1255
 
@@ -73,6 +73,13 @@ Use this template when dispatching a base explorer:
73
73
  ```text
74
74
  You are a base explorer. Optimize for recall, not final judgment.
75
75
  Return candidates only. Do not use CONFIRMED, DISPROVED, or PRE_EXISTING.
76
+ On Profile A structured PR-review discovery lanes, call `submit_pr_review_result`
77
+ exactly once with the canonical base-lane result and then stop. Do not append
78
+ duplicate `[CANDIDATE]` / `[CLEAN]` transcript rows or recap prose after that
79
+ tool call.
80
+ The transcript rows below are deprecated legacy compatibility only. Emit them
81
+ only when the dispatched lane explicitly enables
82
+ `pr_review_legacy_transcript_compatibility`.
76
83
  Do not narrate progress or repeat the prompt. Keep the complete final response at or below 12,000 characters; spend that budget on evidence-bearing rows and the minimum prose needed to make them auditable. When the controller-appended contract declares a per-lane final_response_char_budget, that number is authoritative over this template default.
77
84
 
78
85
  Lane:
@@ -114,6 +121,13 @@ Use this template when dispatching a micro-lane or council explorer:
114
121
  ```text
115
122
  You are a micro-lane or council explorer. Optimize for recall, not final judgment.
116
123
  Return candidates only. Do not use CONFIRMED, DISPROVED, or PRE_EXISTING.
124
+ On Profile A structured PR-review discovery lanes, call `submit_pr_review_result`
125
+ exactly once with the canonical micro-lane result and then stop. Do not append
126
+ duplicate `[CANDIDATE]` / `[CLEAN]` transcript rows or recap prose after that
127
+ tool call.
128
+ The transcript rows below are deprecated legacy compatibility only. Emit them
129
+ only when the dispatched lane explicitly enables
130
+ `pr_review_legacy_transcript_compatibility`.
117
131
  Do not narrate progress or repeat the prompt. Keep the complete final response at or below 12,000 characters; spend that budget on evidence-bearing rows and the minimum prose needed to make them auditable. When the controller-appended contract declares a per-lane final_response_char_budget, that number is authoritative over this template default.
118
132
 
119
133
  Micro/council lane:
@@ -146,10 +160,12 @@ Emit the final machine-readable header and rows as unfenced plain text. The
146
160
  Markdown fence around this prompt is documentation only; do not emit backticks.
147
161
  ```
148
162
 
149
- Under Profile A the orchestrator extracts candidates from the full lane
150
- artifact via `parse_lane_candidates` as the primary mechanism. On Profiles
151
- B/C and as a Profile A fallback when the parser is unavailable — the
152
- `[CANDIDATE]` row format above IS the extraction contract. Explorers emit
153
- structured records regardless of which harness runs them.
163
+ Under Profile A the authoritative discovery-settlement path is exactly one
164
+ `submit_pr_review_result` call per base/micro lane. Transcript
165
+ `[CANDIDATE]` / `[CLEAN]` rows remain a deprecated fallback only when the
166
+ lane's snapped `pr_review_legacy_transcript_compatibility` contract enables
167
+ them and no structured receipt exists. On Profiles B/C the `[CANDIDATE]` row
168
+ format above remains the extraction contract. Explorers emit structured
169
+ records regardless of which harness runs them.
154
170
 
155
171
  Do not let speed degrade validation quality.
@@ -20,7 +20,7 @@ export declare const ARCHITECT_MEMORY_OUTCOME_GUIDANCE = "After using recalled m
20
20
  * 5. Memory Rule (line ~101): Never store swarm identity in memory blocks
21
21
  * 6. CRITIC GATE (lines ~102-107): Plan review before implementation
22
22
  * 7. MANDATORY QA GATE (lines ~108-165):
23
- * - Stage A: Automated tool gates (diff → syntax_check → placeholder_scan → imports → lint → build_check → pre_check_batch)
23
+ * - Stage A: Automated tool gates (diff → syntax_check → placeholder_scan (diff-scoped via added_lines) → imports → lint → build_check → pre_check_batch)
24
24
  * - Stage B: Agent review gates (reviewer → security reviewer → test_engineer)
25
25
  * - ANTI-EXEMPTION RULES: 8 "WRONG thoughts" to ignore
26
26
  * - PARTIAL GATE RATIONALIZATIONS: 6 "WRONG thoughts" to ignore
@@ -36,6 +36,7 @@
36
36
  * escape `.swarm/` (Invariant 4).
37
37
  */
38
38
  import { type DelegationCheckpointAuditSummary } from './delegation-health.js';
39
+ import { type PrReviewResultReceipt } from './pr-review-contract.js';
39
40
  export declare const BACKGROUND_DELEGATIONS_FILE = "background-delegations.jsonl";
40
41
  export declare const BACKGROUND_DELEGATION_FALLBACK_DIR = "background-delegation-fallback";
41
42
  export declare const BACKGROUND_CODER_RESERVATIONS_FILE = "background-coder-reservations.json";
@@ -129,7 +130,7 @@ export type SweepableDelegationStatus = 'pending' | 'running' | 'ingestion_error
129
130
  */
130
131
  export declare const DEFAULT_SWEEPABLE_DELEGATION_STATUSES: ReadonlySet<SweepableDelegationStatus>;
131
132
  export interface BackgroundDelegationRecord {
132
- schemaVersion: 1 | 2 | 3;
133
+ schemaVersion: 1 | 2 | 3 | 4;
133
134
  /** Subagent session id from the dispatch envelope — the correlation key. */
134
135
  correlationId: string;
135
136
  /** Structured jobId from dispatch metadata when available, else null. */
@@ -164,6 +165,8 @@ export interface BackgroundDelegationRecord {
164
165
  * singleton lanes (legacy and tier-L dispatches).
165
166
  */
166
167
  ownedWorkflowLanes?: string[];
168
+ /** Dispatch-time snapshot; absent legacy records keep transcript compatibility. */
169
+ prReviewLegacyTranscriptCompatibility?: boolean;
167
170
  /** Canonical hash of prompt/provenance inputs captured at dispatch time. */
168
171
  promptHash?: string;
169
172
  /** Project/root provenance captured at dispatch time. */
@@ -281,6 +284,12 @@ export interface BackgroundDelegationResult {
281
284
  outputArtifactError?: string;
282
285
  transcriptIncomplete?: boolean;
283
286
  messageCount?: number;
287
+ /**
288
+ * Issue #2384: authoritative structured PR-review result receipt. Persisted
289
+ * separately from transcript text so compaction and preview truncation can
290
+ * never promote presentation-layer text into machine authority.
291
+ */
292
+ prReviewResultReceipt?: import('./pr-review-contract.js').PrReviewResultReceipt;
284
293
  /**
285
294
  * Durable failure provenance for a lane-atomic PR-workflow terminalization.
286
295
  * Optional because successful lanes and legacy terminal results have none.
@@ -487,6 +496,7 @@ export interface RecordPendingInput {
487
496
  mode?: string;
488
497
  workflowLane?: string;
489
498
  ownedWorkflowLanes?: string[];
499
+ prReviewLegacyTranscriptCompatibility?: boolean;
490
500
  promptHash?: string;
491
501
  workspace?: BackgroundWorkspaceSnapshot;
492
502
  taskChangeContext?: BackgroundTaskChangeContext;
@@ -533,6 +543,41 @@ export declare function appendDelegationTransition(directory: string, correlatio
533
543
  completedAt?: number;
534
544
  expectedCurrentStatuses?: readonly BackgroundDelegationStatus[];
535
545
  }): Promise<BackgroundDelegationRecord | null>;
546
+ export type PublishPrReviewResultReceiptOutcome = {
547
+ status: 'recorded';
548
+ record: BackgroundDelegationRecord;
549
+ } | {
550
+ status: 'duplicate';
551
+ record: BackgroundDelegationRecord;
552
+ } | {
553
+ status: 'conflict';
554
+ reason: string;
555
+ } | {
556
+ status: 'not_found';
557
+ reason: string;
558
+ } | {
559
+ status: 'terminal';
560
+ reason: string;
561
+ } | {
562
+ status: 'uncertain';
563
+ reason: string;
564
+ };
565
+ /**
566
+ * Atomically publish the child-bound PR-review receipt while its delegation is
567
+ * still live. The workflow gate performs the outer session-state validation;
568
+ * this inner transaction rechecks immutable delegation identity under the
569
+ * evidence lock and provides semantic exactly-once behavior.
570
+ */
571
+ export declare function publishPrReviewResultReceipt(directory: string, input: {
572
+ parentSessionId: string;
573
+ childSessionId: string;
574
+ batchId: string;
575
+ laneId: string;
576
+ expectedWorkflowInstanceId: string;
577
+ expectedWorkflowRevision: number;
578
+ expectedBaseSha: string;
579
+ receipt: PrReviewResultReceipt;
580
+ }): Promise<PublishPrReviewResultReceiptOutcome>;
536
581
  export interface BuildBackgroundCompletionEventIdInput {
537
582
  correlationId: string;
538
583
  jobId: string | null;
@@ -25,6 +25,249 @@ export type PrReviewRiskImpact = (typeof PR_REVIEW_RISK_IMPACTS)[number];
25
25
  */
26
26
  export declare const PR_REVIEW_RISK_TAGS: readonly ["SECURITY", "AUTH_PERMISSIONS", "STATE_INTEGRITY", "WRITE_PATH", "EVIDENCE_INTEGRITY", "GIT", "CONFIGURATION"];
27
27
  export type PrReviewRiskTag = (typeof PR_REVIEW_RISK_TAGS)[number];
28
+ export declare const PR_REVIEW_RESULT_LANE_MODES: readonly ["swarm-pr-review:base", "swarm-pr-review:micro"];
29
+ export declare const PR_REVIEW_RESULT_OUTCOMES: readonly ["CLEAN", "FINDINGS", "INCOMPLETE"];
30
+ export declare const PR_REVIEW_RESULT_FINDING_SEVERITIES: readonly ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"];
31
+ export declare const PR_REVIEW_RESULT_UNRESOLVED_REASONS: readonly ["NOT_EXECUTED", "PARTIAL_OUTPUT", "CONTRACT_FAILURE", "RESOURCE_LIMIT", "DEADLINE_EXCEEDED", "STALE_BINDING", "PARENT_CANCELLED"];
32
+ export declare const MAX_PR_REVIEW_RESULT_OWNED_LANES = 11;
33
+ export declare const MAX_PR_REVIEW_RESULT_FINDINGS = 256;
34
+ export declare const MAX_PR_REVIEW_RESULT_RECEIPT_BYTES: number;
35
+ export type PrReviewResultLaneMode = (typeof PR_REVIEW_RESULT_LANE_MODES)[number];
36
+ export type PrReviewResultOutcome = (typeof PR_REVIEW_RESULT_OUTCOMES)[number];
37
+ export type PrReviewResultFindingSeverity = (typeof PR_REVIEW_RESULT_FINDING_SEVERITIES)[number];
38
+ export type PrReviewResultUnresolvedReason = (typeof PR_REVIEW_RESULT_UNRESOLVED_REASONS)[number];
39
+ export declare function prReviewLegacyTranscriptCompatibilityEnabled(value: boolean | undefined): boolean;
40
+ export declare const PrReviewResultLocationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
41
+ kind: z.ZodLiteral<"local">;
42
+ file: z.ZodString;
43
+ line: z.ZodOptional<z.ZodNumber>;
44
+ endLine: z.ZodOptional<z.ZodNumber>;
45
+ column: z.ZodOptional<z.ZodNumber>;
46
+ endColumn: z.ZodOptional<z.ZodNumber>;
47
+ }, z.core.$strict>, z.ZodObject<{
48
+ kind: z.ZodLiteral<"non_local">;
49
+ label: z.ZodString;
50
+ detail: z.ZodString;
51
+ }, z.core.$strict>], "kind">;
52
+ export type PrReviewResultLocation = z.infer<typeof PrReviewResultLocationSchema>;
53
+ export declare const PrReviewResultFindingSchema: z.ZodObject<{
54
+ id: z.ZodString;
55
+ workflowLane: z.ZodString;
56
+ severity: z.ZodEnum<{
57
+ CRITICAL: "CRITICAL";
58
+ HIGH: "HIGH";
59
+ MEDIUM: "MEDIUM";
60
+ LOW: "LOW";
61
+ INFO: "INFO";
62
+ }>;
63
+ riskImpact: z.ZodEnum<{
64
+ ORDINARY: "ORDINARY";
65
+ HIGH_IMPACT: "HIGH_IMPACT";
66
+ UNKNOWN: "UNKNOWN";
67
+ }>;
68
+ riskTags: z.ZodArray<z.ZodEnum<{
69
+ SECURITY: "SECURITY";
70
+ AUTH_PERMISSIONS: "AUTH_PERMISSIONS";
71
+ STATE_INTEGRITY: "STATE_INTEGRITY";
72
+ WRITE_PATH: "WRITE_PATH";
73
+ EVIDENCE_INTEGRITY: "EVIDENCE_INTEGRITY";
74
+ GIT: "GIT";
75
+ CONFIGURATION: "CONFIGURATION";
76
+ }>>;
77
+ title: z.ZodString;
78
+ body: z.ZodString;
79
+ evidence: z.ZodString;
80
+ location: z.ZodDiscriminatedUnion<[z.ZodObject<{
81
+ kind: z.ZodLiteral<"local">;
82
+ file: z.ZodString;
83
+ line: z.ZodOptional<z.ZodNumber>;
84
+ endLine: z.ZodOptional<z.ZodNumber>;
85
+ column: z.ZodOptional<z.ZodNumber>;
86
+ endColumn: z.ZodOptional<z.ZodNumber>;
87
+ }, z.core.$strict>, z.ZodObject<{
88
+ kind: z.ZodLiteral<"non_local">;
89
+ label: z.ZodString;
90
+ detail: z.ZodString;
91
+ }, z.core.$strict>], "kind">;
92
+ }, z.core.$strict>;
93
+ export type PrReviewResultFinding = z.infer<typeof PrReviewResultFindingSchema>;
94
+ export declare const PrReviewCleanAttestationSchema: z.ZodObject<{
95
+ workflowLane: z.ZodString;
96
+ coverageScope: z.ZodString;
97
+ evidence: z.ZodString;
98
+ }, z.core.$strict>;
99
+ export type PrReviewCleanAttestation = z.infer<typeof PrReviewCleanAttestationSchema>;
100
+ export declare const PrReviewUnresolvedLaneSchema: z.ZodObject<{
101
+ workflowLane: z.ZodString;
102
+ reason: z.ZodEnum<{
103
+ NOT_EXECUTED: "NOT_EXECUTED";
104
+ PARTIAL_OUTPUT: "PARTIAL_OUTPUT";
105
+ CONTRACT_FAILURE: "CONTRACT_FAILURE";
106
+ RESOURCE_LIMIT: "RESOURCE_LIMIT";
107
+ DEADLINE_EXCEEDED: "DEADLINE_EXCEEDED";
108
+ STALE_BINDING: "STALE_BINDING";
109
+ PARENT_CANCELLED: "PARENT_CANCELLED";
110
+ }>;
111
+ detail: z.ZodString;
112
+ }, z.core.$strict>;
113
+ export type PrReviewUnresolvedLane = z.infer<typeof PrReviewUnresolvedLaneSchema>;
114
+ export declare const PrReviewLaneResultEnvelopeSchema: z.ZodObject<{
115
+ schemaVersion: z.ZodLiteral<1>;
116
+ outcome: z.ZodEnum<{
117
+ CLEAN: "CLEAN";
118
+ FINDINGS: "FINDINGS";
119
+ INCOMPLETE: "INCOMPLETE";
120
+ }>;
121
+ creditedLanes: z.ZodArray<z.ZodString>;
122
+ findings: z.ZodArray<z.ZodObject<{
123
+ id: z.ZodString;
124
+ workflowLane: z.ZodString;
125
+ severity: z.ZodEnum<{
126
+ CRITICAL: "CRITICAL";
127
+ HIGH: "HIGH";
128
+ MEDIUM: "MEDIUM";
129
+ LOW: "LOW";
130
+ INFO: "INFO";
131
+ }>;
132
+ riskImpact: z.ZodEnum<{
133
+ ORDINARY: "ORDINARY";
134
+ HIGH_IMPACT: "HIGH_IMPACT";
135
+ UNKNOWN: "UNKNOWN";
136
+ }>;
137
+ riskTags: z.ZodArray<z.ZodEnum<{
138
+ SECURITY: "SECURITY";
139
+ AUTH_PERMISSIONS: "AUTH_PERMISSIONS";
140
+ STATE_INTEGRITY: "STATE_INTEGRITY";
141
+ WRITE_PATH: "WRITE_PATH";
142
+ EVIDENCE_INTEGRITY: "EVIDENCE_INTEGRITY";
143
+ GIT: "GIT";
144
+ CONFIGURATION: "CONFIGURATION";
145
+ }>>;
146
+ title: z.ZodString;
147
+ body: z.ZodString;
148
+ evidence: z.ZodString;
149
+ location: z.ZodDiscriminatedUnion<[z.ZodObject<{
150
+ kind: z.ZodLiteral<"local">;
151
+ file: z.ZodString;
152
+ line: z.ZodOptional<z.ZodNumber>;
153
+ endLine: z.ZodOptional<z.ZodNumber>;
154
+ column: z.ZodOptional<z.ZodNumber>;
155
+ endColumn: z.ZodOptional<z.ZodNumber>;
156
+ }, z.core.$strict>, z.ZodObject<{
157
+ kind: z.ZodLiteral<"non_local">;
158
+ label: z.ZodString;
159
+ detail: z.ZodString;
160
+ }, z.core.$strict>], "kind">;
161
+ }, z.core.$strict>>;
162
+ cleanAttestations: z.ZodArray<z.ZodObject<{
163
+ workflowLane: z.ZodString;
164
+ coverageScope: z.ZodString;
165
+ evidence: z.ZodString;
166
+ }, z.core.$strict>>;
167
+ unresolved: z.ZodArray<z.ZodObject<{
168
+ workflowLane: z.ZodString;
169
+ reason: z.ZodEnum<{
170
+ NOT_EXECUTED: "NOT_EXECUTED";
171
+ PARTIAL_OUTPUT: "PARTIAL_OUTPUT";
172
+ CONTRACT_FAILURE: "CONTRACT_FAILURE";
173
+ RESOURCE_LIMIT: "RESOURCE_LIMIT";
174
+ DEADLINE_EXCEEDED: "DEADLINE_EXCEEDED";
175
+ STALE_BINDING: "STALE_BINDING";
176
+ PARENT_CANCELLED: "PARENT_CANCELLED";
177
+ }>;
178
+ detail: z.ZodString;
179
+ }, z.core.$strict>>;
180
+ }, z.core.$strict>;
181
+ export type PrReviewLaneResultEnvelope = z.infer<typeof PrReviewLaneResultEnvelopeSchema>;
182
+ export declare function serializedPrReviewResultReceiptBytes(value: unknown): number;
183
+ export declare function prReviewLaneResultEnvelopeDigest(value: PrReviewLaneResultEnvelope): string;
184
+ export declare const PrReviewResultReceiptSchema: z.ZodObject<{
185
+ schemaVersion: z.ZodLiteral<1>;
186
+ mode: z.ZodEnum<{
187
+ "swarm-pr-review:base": "swarm-pr-review:base";
188
+ "swarm-pr-review:micro": "swarm-pr-review:micro";
189
+ }>;
190
+ workflowInstanceId: z.ZodString;
191
+ workflowRevision: z.ZodNumber;
192
+ batchId: z.ZodString;
193
+ laneId: z.ZodString;
194
+ workflowLane: z.ZodString;
195
+ ownedWorkflowLanes: z.ZodArray<z.ZodString>;
196
+ baseSha: z.ZodString;
197
+ headSha: z.ZodString;
198
+ dispatchRevisionDigest: z.ZodString;
199
+ childSessionId: z.ZodString;
200
+ generation: z.ZodNumber;
201
+ semanticEnvelopeDigest: z.ZodString;
202
+ envelope: z.ZodObject<{
203
+ schemaVersion: z.ZodLiteral<1>;
204
+ outcome: z.ZodEnum<{
205
+ CLEAN: "CLEAN";
206
+ FINDINGS: "FINDINGS";
207
+ INCOMPLETE: "INCOMPLETE";
208
+ }>;
209
+ creditedLanes: z.ZodArray<z.ZodString>;
210
+ findings: z.ZodArray<z.ZodObject<{
211
+ id: z.ZodString;
212
+ workflowLane: z.ZodString;
213
+ severity: z.ZodEnum<{
214
+ CRITICAL: "CRITICAL";
215
+ HIGH: "HIGH";
216
+ MEDIUM: "MEDIUM";
217
+ LOW: "LOW";
218
+ INFO: "INFO";
219
+ }>;
220
+ riskImpact: z.ZodEnum<{
221
+ ORDINARY: "ORDINARY";
222
+ HIGH_IMPACT: "HIGH_IMPACT";
223
+ UNKNOWN: "UNKNOWN";
224
+ }>;
225
+ riskTags: z.ZodArray<z.ZodEnum<{
226
+ SECURITY: "SECURITY";
227
+ AUTH_PERMISSIONS: "AUTH_PERMISSIONS";
228
+ STATE_INTEGRITY: "STATE_INTEGRITY";
229
+ WRITE_PATH: "WRITE_PATH";
230
+ EVIDENCE_INTEGRITY: "EVIDENCE_INTEGRITY";
231
+ GIT: "GIT";
232
+ CONFIGURATION: "CONFIGURATION";
233
+ }>>;
234
+ title: z.ZodString;
235
+ body: z.ZodString;
236
+ evidence: z.ZodString;
237
+ location: z.ZodDiscriminatedUnion<[z.ZodObject<{
238
+ kind: z.ZodLiteral<"local">;
239
+ file: z.ZodString;
240
+ line: z.ZodOptional<z.ZodNumber>;
241
+ endLine: z.ZodOptional<z.ZodNumber>;
242
+ column: z.ZodOptional<z.ZodNumber>;
243
+ endColumn: z.ZodOptional<z.ZodNumber>;
244
+ }, z.core.$strict>, z.ZodObject<{
245
+ kind: z.ZodLiteral<"non_local">;
246
+ label: z.ZodString;
247
+ detail: z.ZodString;
248
+ }, z.core.$strict>], "kind">;
249
+ }, z.core.$strict>>;
250
+ cleanAttestations: z.ZodArray<z.ZodObject<{
251
+ workflowLane: z.ZodString;
252
+ coverageScope: z.ZodString;
253
+ evidence: z.ZodString;
254
+ }, z.core.$strict>>;
255
+ unresolved: z.ZodArray<z.ZodObject<{
256
+ workflowLane: z.ZodString;
257
+ reason: z.ZodEnum<{
258
+ NOT_EXECUTED: "NOT_EXECUTED";
259
+ PARTIAL_OUTPUT: "PARTIAL_OUTPUT";
260
+ CONTRACT_FAILURE: "CONTRACT_FAILURE";
261
+ RESOURCE_LIMIT: "RESOURCE_LIMIT";
262
+ DEADLINE_EXCEEDED: "DEADLINE_EXCEEDED";
263
+ STALE_BINDING: "STALE_BINDING";
264
+ PARENT_CANCELLED: "PARENT_CANCELLED";
265
+ }>;
266
+ detail: z.ZodString;
267
+ }, z.core.$strict>>;
268
+ }, z.core.$strict>;
269
+ }, z.core.$strict>;
270
+ export type PrReviewResultReceipt = z.infer<typeof PrReviewResultReceiptSchema>;
28
271
  export declare const PR_REVIEW_CONTRACT_CARD_HEADER = "[PR-REVIEW CONTRACT CARD]";
29
272
  export declare const PR_REVIEW_FINDINGS_MAX_BYTES: number;
30
273
  export declare const PR_REVIEW_FINDINGS_WRITE_MAX_BYTES: number;
@@ -36,10 +279,10 @@ export declare const PrReviewRunIdSchema: z.ZodString;
36
279
  export declare const PrReviewFindingSchema: z.ZodObject<{
37
280
  finding_id: z.ZodString;
38
281
  status: z.ZodEnum<{
39
- PENDING: "PENDING";
40
282
  CONFIRMED: "CONFIRMED";
41
283
  DISPROVED: "DISPROVED";
42
284
  PRE_EXISTING: "PRE_EXISTING";
285
+ PENDING: "PENDING";
43
286
  }>;
44
287
  file_line: z.ZodString;
45
288
  evidence: z.ZodString;
@@ -135,10 +378,10 @@ export declare const WritePrReviewArtifactArgsSchema: z.ZodDiscriminatedUnion<[z
135
378
  records: z.ZodArray<z.ZodObject<{
136
379
  finding_id: z.ZodString;
137
380
  status: z.ZodEnum<{
138
- PENDING: "PENDING";
139
381
  CONFIRMED: "CONFIRMED";
140
382
  DISPROVED: "DISPROVED";
141
383
  PRE_EXISTING: "PRE_EXISTING";
384
+ PENDING: "PENDING";
142
385
  }>;
143
386
  file_line: z.ZodString;
144
387
  evidence: z.ZodString;
@@ -0,0 +1,13 @@
1
+ export interface ResolvedCommand {
2
+ argv: string[];
3
+ shellCommand: string;
4
+ }
5
+ /**
6
+ * Tokenize a generated command into argv without invoking a shell. Supports
7
+ * single and double quotes for grouping, but never interprets shell
8
+ * metacharacters.
9
+ */
10
+ export declare function tokenizeCommand(command: string): string[];
11
+ /** Resolve a plugin-generated command without invoking a package downloader. */
12
+ export declare function resolveLocalCommand(command: string, workingDir: string, isAvailable: (binary: string) => boolean, platform?: NodeJS.Platform): ResolvedCommand | null;
13
+ export declare function resolveLocalNodeTool(tool: string, args: string[], workingDir: string, platform?: NodeJS.Platform, isAvailable?: (binary: string) => boolean): string[] | null;