opencode-swarm 7.124.0 → 7.125.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/critic-gate/SKILL.md +8 -0
- package/.opencode/skills/swarm/SKILL.md +12 -8
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +245 -171
- package/.opencode/skills/swarm-pr-feedback/references/bot-claim-verification.md +71 -0
- package/.opencode/skills/swarm-pr-feedback/references/operational-gotchas.md +49 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +238 -412
- package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +235 -0
- package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +103 -0
- package/.opencode/skills/writing-tests/SKILL.md +4 -123
- package/.opencode/skills/writing-tests/references/mock-and-seam-inventory.md +43 -0
- package/README.md +3 -1
- package/dist/background/lane-output-store.d.ts +10 -0
- package/dist/background/pending-delegations.d.ts +3 -0
- package/dist/background/workspace-snapshot.d.ts +59 -0
- package/dist/cli/{config-doctor-53mnpeke.js → config-doctor-g3m2q646.js} +2 -2
- package/dist/cli/{curation-policy-ny033330.js → curation-policy-vgbx8530.js} +2 -2
- package/dist/cli/{curator-llm-factory-e0tjz8qq.js → curator-llm-factory-7pvqy94w.js} +15 -14
- package/dist/cli/{curator-nvn1pdq6.js → curator-xk4g1nx2.js} +15 -14
- package/dist/cli/{evidence-summary-service-9hq7n9k9.js → evidence-summary-service-v4h2w487.js} +1 -1
- package/dist/cli/{guardrail-explain-d3dd57nf.js → guardrail-explain-wfk16bpr.js} +16 -15
- package/dist/cli/{guardrail-log-3q2z9axs.js → guardrail-log-5zz9xx6z.js} +3 -3
- package/dist/cli/{hive-promoter-9gbpepgm.js → hive-promoter-njwc5rt0.js} +15 -14
- package/dist/cli/{pending-delegations-e3bcqj77.js → index-0cz1ws47.js} +4 -18
- package/dist/cli/{index-3yyr4ynk.js → index-3k8pg467.js} +1 -1
- package/dist/cli/{index-x2mmnrnx.js → index-83rwq7pb.js} +1 -1
- package/dist/cli/{index-c6crt5rs.js → index-8yvqkbw7.js} +12 -2
- package/dist/cli/{index-z0m4angq.js → index-93cq8t5b.js} +5 -5
- package/dist/cli/{index-8pz0ypxz.js → index-cz6fv84h.js} +17 -16
- package/dist/cli/{index-mkkx1a4f.js → index-dsf1yv4s.js} +1588 -891
- package/dist/cli/{index-4rzzzjtg.js → index-fs02c7tz.js} +277 -16
- package/dist/cli/{index-zjedv2bd.js → index-ghteqdy1.js} +2 -2
- package/dist/cli/{index-13d2g7k9.js → index-kvrk3h8p.js} +1 -1
- package/dist/cli/{index-eeg04r0x.js → index-kws8zn6y.js} +1 -1
- package/dist/cli/index-mg54y5gc.js +564 -0
- package/dist/cli/{index-qd77aft9.js → index-mhhmecsw.js} +2 -2
- package/dist/cli/{index-2x4maxte.js → index-mwdcvh0e.js} +4 -4
- package/dist/cli/{index-e19mxn9f.js → index-pbjenws7.js} +1 -1
- package/dist/cli/{index-wqwpzhv1.js → index-rpg8qqjs.js} +2 -2
- package/dist/cli/{index-tyg0zezw.js → index-tn3shyqj.js} +3 -3
- package/dist/cli/{index-htbjqftb.js → index-txragda9.js} +1 -1
- package/dist/cli/{index-v5ecczts.js → index-z4sc6yxc.js} +1 -1
- package/dist/cli/index.js +15 -14
- package/dist/cli/{knowledge-escalator-r1s01m3z.js → knowledge-escalator-jtyykzqc.js} +3 -3
- package/dist/cli/{knowledge-events-a9hmxvke.js → knowledge-events-qhr97sy9.js} +1 -1
- package/dist/cli/{knowledge-store-jt31br5k.js → knowledge-store-332x3pjv.js} +1 -1
- package/dist/cli/{knowledge-validator-9vrwxr3z.js → knowledge-validator-3t8tgzsz.js} +4 -4
- package/dist/cli/pending-delegations-7j8xqg5f.js +34 -0
- package/dist/cli/{scan-cursor-bkjtsawg.js → scan-cursor-q21c9k9q.js} +2 -2
- package/dist/cli/{schema-y3z416z7.js → schema-y2d7j2jk.js} +1 -1
- package/dist/cli/{skill-generator-794hyndw.js → skill-generator-3gkxx98d.js} +5 -5
- package/dist/cli/workspace-snapshot-c9pxxt9a.js +48 -0
- package/dist/commands/close.d.ts +4 -2
- package/dist/commands/registry.d.ts +1 -1
- package/dist/config/schema.d.ts +4 -0
- package/dist/evidence/documents-retention.d.ts +116 -0
- package/dist/evidence/manager.d.ts +17 -0
- package/dist/hooks/pr-workflow-gate.d.ts +211 -0
- package/dist/hooks/pr-workflow-response-gate.d.ts +23 -0
- package/dist/hooks/pr-workflow-session-resolver.d.ts +14 -0
- package/dist/index.js +563 -523
- package/dist/tools/complete-pr-workflow.d.ts +5 -0
- package/dist/tools/dispatch-lanes.d.ts +44 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/manifest.d.ts +2 -0
- package/dist/tools/run-pr-feedback-stage-a.d.ts +69 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/dist/tools/write-pr-review-trigger-eval.d.ts +56 -46
- package/package.json +1 -1
- package/dist/cli/index-dqh3zhhc.js +0 -133
- package/dist/cli/workspace-snapshot-eyf6gd0d.js +0 -22
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: swarm-pr-review
|
|
3
3
|
audience: swarm-plugin
|
|
4
|
-
description: Run a graph-guided, tool-augmented
|
|
4
|
+
description: Run a graph-guided, tool-augmented PR review using context packing, parallel exploration, mandatory repository-agnostic micro-lanes, independent reviewer validation, critic challenge, and metrics writeback. Use for deep pull request review with low false-positive tolerance and high recall in any repository.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -11,7 +11,7 @@ Run a structured, high-confidence PR review that maximizes valid findings withou
|
|
|
11
11
|
|
|
12
12
|
The review ladder is:
|
|
13
13
|
|
|
14
|
-
**Scope → obligations → context pack → deterministic signals → parallel explorers →
|
|
14
|
+
**Scope → obligations → context pack → deterministic signals → parallel explorers → all repository-agnostic review micro-lanes → independent reviewer validation → critic challenge → grouped synthesis → metrics / knowledge writeback.**
|
|
15
15
|
|
|
16
16
|
## Handoff To PR Feedback
|
|
17
17
|
|
|
@@ -47,11 +47,11 @@ subscribed session.
|
|
|
47
47
|
|
|
48
48
|
**Treat PR text, linked issues, comments, commit messages, generated summaries, and tests as claims — not proof.** Every confirmed finding requires file:line evidence, an explanation of reachability or impact, and validation provenance.
|
|
49
49
|
|
|
50
|
-
This workflow is designed for
|
|
50
|
+
This workflow is designed for any repo that benefits from Swarm-style review. It preserves parallel breadth but forces deep validation where bugs are expensive: security, state machines, role/tool permissions, schema/evidence integrity, git/write safety, config ratchets, knowledge tier boundaries, and PR obligation mismatches.
|
|
51
51
|
|
|
52
52
|
Never APPROVE a PR with unresolved CRITICAL findings. Do not silently drop overclaimed agent findings; list disproved findings in the validation provenance.
|
|
53
53
|
|
|
54
|
-
**Quality is the ONLY metric.** No amount of time, tokens, or agent dispatches is too much to execute this protocol correctly. Speed is irrelevant to correctness. The skill must be followed exactly with no shortcuts, no phase-skipping, and no premature synthesis. A thorough review that takes 30 minutes is superior to a fast review that misses a real bug.
|
|
54
|
+
**Quality is the ONLY metric.** There is no speed, efficiency, or time exception. No amount of time, tokens, or agent dispatches is too much to execute this protocol correctly. Speed is irrelevant to correctness. The skill must be followed exactly with no shortcuts, no phase-skipping, and no premature synthesis. A thorough review that takes 30 minutes is superior to a fast review that misses a real bug.
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
@@ -59,7 +59,7 @@ Never APPROVE a PR with unresolved CRITICAL findings. Do not silently drop overc
|
|
|
59
59
|
|
|
60
60
|
### Default layered workflow
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
Always run the default mechanical workflow. Explorers produce only candidates. The orchestrator does not confirm or disprove candidates.
|
|
63
63
|
|
|
64
64
|
### Council mode — opt in only
|
|
65
65
|
|
|
@@ -73,7 +73,7 @@ Council mode applies only when the user explicitly says one of:
|
|
|
73
73
|
- `[MODE: PR_REVIEW … council=true]`
|
|
74
74
|
- `assume all work is wrong`
|
|
75
75
|
|
|
76
|
-
Council mode is
|
|
76
|
+
Council mode supplements the default mechanical workflow; it never replaces or weakens it. Even when council mode is triggered, first complete the exact-six base dispatch, micro-lane ledger persistence, and every repository-agnostic micro-lane at the same exact `pr_head_sha`. Route supplementary council output into the candidate ledger before independent reviewer classification. If the council request arrives after classification has begun, run the council as an additional candidate pass and dispatch a new structured reviewer batch for those candidates before synthesis.
|
|
77
77
|
|
|
78
78
|
---
|
|
79
79
|
|
|
@@ -85,7 +85,7 @@ The orchestrator may:
|
|
|
85
85
|
|
|
86
86
|
- determine scope,
|
|
87
87
|
- build or request the context pack,
|
|
88
|
-
- launch explorers and
|
|
88
|
+
- launch explorers and every mandatory repository-agnostic micro-lane,
|
|
89
89
|
- extract candidates from lane artifacts via `parse_lane_candidates` or equivalent parser,
|
|
90
90
|
- filter, group, and chunk candidates for reviewer dispatch,
|
|
91
91
|
- route candidates to reviewers,
|
|
@@ -137,7 +137,7 @@ If scope cannot be determined, review the narrowest safe scope available and sta
|
|
|
137
137
|
Before launching explorers (Phase 3), confirm the PR branch refs are available:
|
|
138
138
|
- If `head_ref` is a remote branch that is not checked out locally, fetch it via `git fetch origin <head_ref>`
|
|
139
139
|
- **Check out the head branch locally.** Explorer agents read files from the working tree, not from git history — passing the commit range in the delegation prompt is not sufficient because `Read` / `Glob` / `Grep` tools operate on the filesystem. Without a checkout, explorers silently read the base branch's version of changed files and produce invalid candidates. **Before checking out, verify the working tree is clean (`git status --porcelain`). If uncommitted changes exist, stash them or abort the checkout to prevent data loss.**
|
|
140
|
-
- Explicitly pass the
|
|
140
|
+
- Explicitly pass the verified merge-base range (`base_sha...pr_head_sha`) in every explorer delegation so explorers inspect exactly the controller-bound PR diff. Include `base_ref` only as the live ref used to recompute `base_sha`; do not substitute a two-dot branch-tip range.
|
|
141
141
|
|
|
142
142
|
If refs cannot be fetched or checked out, state the limitation in the context pack.
|
|
143
143
|
|
|
@@ -149,14 +149,37 @@ pre-confirmed findings.
|
|
|
149
149
|
|
|
150
150
|
### PR title and body compliance check
|
|
151
151
|
|
|
152
|
-
Before deeper analysis,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
Before deeper analysis, discover whether the repository defines a PR
|
|
153
|
+
publication contract (for example a local `commit-pr` skill, `CONTRIBUTING`
|
|
154
|
+
guidance, a PR template, or a CI check such as `pr-standards`). If it does,
|
|
155
|
+
verify the PR against that contract and record any gap as an advisory ledger
|
|
156
|
+
item. If it does not, do not invent opencode-swarm-specific title/body
|
|
157
|
+
sections; still verify that the PR text is not misleading about what the diff
|
|
158
|
+
does or proves.
|
|
159
|
+
|
|
160
|
+
At minimum, check:
|
|
161
|
+
|
|
162
|
+
- required title/body/linked-issue structure from the discovered repository
|
|
163
|
+
contract,
|
|
164
|
+
- issue-closing, migration, release-note, invariant, or test-plan claims made
|
|
165
|
+
in the PR text,
|
|
166
|
+
- whether those claims are supported by the actual diff and the current issue
|
|
167
|
+
state.
|
|
168
|
+
|
|
169
|
+
**Issue-closing claim-integrity check:** if the PR body uses an issue-closing
|
|
170
|
+
keyword such as `Closes #<issue-number>`, verify (a) the issue is currently open
|
|
171
|
+
(`gh issue view <N> --json state` when the host is GitHub), and (b) the diff
|
|
172
|
+
addresses the issue's acceptance criteria (read the issue, map each criterion
|
|
173
|
+
to changed files/symbols, and inspect the diff for those areas). If the issue
|
|
174
|
+
is already closed by another merged PR, do NOT re-close it — the duplicate
|
|
175
|
+
closing reference is misleading. If the issue is open but the diff does not
|
|
176
|
+
address the acceptance criteria, mark the claim as `UNVERIFIED — claim
|
|
177
|
+
integrity` in the validation provenance and surface the unresolved gap to the
|
|
178
|
+
user before synthesis.
|
|
179
|
+
|
|
180
|
+
Contract non-compliance is a ledger item (advisory unless the repository
|
|
181
|
+
explicitly makes it blocking). If the PR is from an external contributor, note
|
|
182
|
+
the compliance gap for the maintainer to address before merge.
|
|
160
183
|
|
|
161
184
|
This intake includes:
|
|
162
185
|
|
|
@@ -172,6 +195,11 @@ If GraphQL is unavailable, keep the signal and mark
|
|
|
172
195
|
|
|
173
196
|
### Step 1 — Fetch all PR feedback surfaces
|
|
174
197
|
|
|
198
|
+
The commands below are GitHub examples. On GitLab, Bitbucket, Gerrit, or
|
|
199
|
+
another code host, use the host's API/connector/CLI to enumerate the same full
|
|
200
|
+
surface, including pagination and unresolved-thread state. Host choice never
|
|
201
|
+
reduces the intake ledger.
|
|
202
|
+
|
|
175
203
|
```bash
|
|
176
204
|
# Issue comments (general PR thread)
|
|
177
205
|
gh api --paginate repos/{owner}/{repo}/issues/{PR_NUMBER}/comments
|
|
@@ -230,6 +258,10 @@ feedback handoff artifact.
|
|
|
230
258
|
|
|
231
259
|
### Step 1 — Check merge state
|
|
232
260
|
|
|
261
|
+
The field names and values below are GitHub-specific examples. On another code
|
|
262
|
+
host, record the equivalent mergeability, conflict, required-check, base-drift,
|
|
263
|
+
and stale-head signals and preserve the same read-only behavior.
|
|
264
|
+
|
|
233
265
|
```bash
|
|
234
266
|
gh pr view <PR_NUMBER> --json mergeable,mergeStateStatus
|
|
235
267
|
```
|
|
@@ -562,7 +594,26 @@ Tool candidate rules:
|
|
|
562
594
|
|
|
563
595
|
## Phase 3: Parallel Base Explorer Lanes
|
|
564
596
|
|
|
565
|
-
Launch all base lanes with `dispatch_lanes_async` when available. Pass the six
|
|
597
|
+
Launch all base lanes with `dispatch_lanes_async` when available. Pass the six
|
|
598
|
+
lane specs together, set `mode: "swarm-pr-review:base"`, assign each lane its
|
|
599
|
+
exact `workflow_lane` identifier from the table below, set `max_concurrent` to
|
|
600
|
+
`6`, bind the batch with the exact current `pr_head_sha`, record the returned
|
|
601
|
+
`batch_id`, and pass the exact reviewed merge base and its live base tip/ref as
|
|
602
|
+
`base_sha` and `base_ref`. Every later base retry, micro, council, reviewer, and
|
|
603
|
+
critic dispatch repeats those same exact bindings. The controller recomputes
|
|
604
|
+
`git merge-base -- <base_ref> <pr_head_sha>`, rejects mismatches, and replaces
|
|
605
|
+
caller `scope` text with the complete verified `base_sha...pr_head_sha` PR diff;
|
|
606
|
+
caller scope is retained only as a non-authoritative focus hint. Continue only non-dependent architect
|
|
607
|
+
work: refine the obligation ledger, inspect PR metadata, prepare micro-lane
|
|
608
|
+
trigger checks, and run deterministic read-only local tools. The runtime rejects
|
|
609
|
+
partial, duplicate, mislabelled, or non-explorer base waves. Do not synthesize
|
|
610
|
+
findings from running lanes. Keep each lane `prompt` compact: send the shared
|
|
611
|
+
review context (PR diff, obligation ledger, scope) ONCE via the `common_prompt`
|
|
612
|
+
field, or have lanes read it from a file by absolute path, instead of inlining
|
|
613
|
+
the same large blob into all six prompts — oversized inline prompts produce
|
|
614
|
+
malformed or truncated tool-call JSON and force clumsy file workarounds.
|
|
615
|
+
|
|
616
|
+
This is an exact six-lane gate, not a soft target. If the base wave is launched with fewer than six lanes, the review is BLOCKED until the missing lanes are dispatched and settled; "small PR", "docs-only", "CI-only", and "time-saving" are not exceptions.
|
|
566
617
|
|
|
567
618
|
**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.
|
|
568
619
|
|
|
@@ -570,11 +621,11 @@ Before Phase 4 or synthesis, all base lanes must be settled. `dispatch_lanes_asy
|
|
|
570
621
|
|
|
571
622
|
**COVERAGE GATE — zero tolerance for unclosed gaps.** After `collect_lane_results`, verify every lane produced validated output. Two failure modes exist:
|
|
572
623
|
- **Mode A (empty output):** Lane returns 0 chars, `status: cancelled`, `output_digest` matches SHA-256 of empty string (`e3b0c442...b855`).
|
|
573
|
-
- **Mode B (intermediate reasoning only):** Lane reports `status: completed` with non-empty output, but the output is preliminary reasoning ("Now let me check...") with zero `[CANDIDATE]` rows. The `output_digest` does NOT match the empty-string hash. `parse_lane_candidates` returns 0 candidates. This mode is MORE dangerous — the lane appears successful but produced no findings.
|
|
624
|
+
- **Mode B (intermediate reasoning only):** Lane reports `status: completed` with non-empty output, but the output is preliminary reasoning ("Now let me check...") with zero `[CANDIDATE]` rows and no parseable `[CLEAN] | workflow_lane | coverage_scope | evidence` attestation. The `output_digest` does NOT match the empty-string hash. `parse_lane_candidates` returns 0 candidates. This mode is MORE dangerous — the lane appears successful but produced no findings or clean proof.
|
|
574
625
|
|
|
575
626
|
For ANY lane that failed (either mode):
|
|
576
|
-
1. **Retry** (max 2 attempts) with materially different parameters — different session
|
|
577
|
-
2. If
|
|
627
|
+
1. **Retry** (max 2 attempts) with materially different parameters — different session or prompt decomposition, while preserving the required structured async mode and exact head provenance.
|
|
628
|
+
2. If a base lane fails, retry only the failed `workflow_lane` identifiers with `dispatch_lanes_async`, `mode: "swarm-pr-review:base"`, the same exact `pr_head_sha`, and explorer agents. The durable gate joins successful provenance across the initial wave and retry batches. Blocking `dispatch_lanes` and direct Task dispatch are not equivalent under this workflow because they cannot satisfy the structured provenance gate.
|
|
578
629
|
3. If no equivalent alternative can be verified, **STOP and surface the lane failure to the user as BLOCKED** with the lane id, scope, failure mode, retry attempts, and why equivalence could not be proven. Do not present partial findings, do not issue a review verdict, and do not synthesize from successful lanes. A low-quality partial review is worse than no review.
|
|
579
630
|
|
|
580
631
|
### Candidate extraction via parser
|
|
@@ -598,7 +649,7 @@ rather than preview-text extraction:
|
|
|
598
649
|
4. Stage reviewer-sized chunks, but do not dispatch reviewers yet. Phase 4 must
|
|
599
650
|
complete trigger accounting and settle every launched micro-lane first.
|
|
600
651
|
|
|
601
|
-
If a lane has `output_degraded: true`, `transcript_incomplete: true`, or no usable `output_ref`, apply the COVERAGE GATE
|
|
652
|
+
If a lane has `output_degraded: true`, `transcript_incomplete: true`, or no usable `output_ref`, apply the COVERAGE GATE (Phase 3). Do not use blocking or direct-Task fallbacks, mark affected candidates UNVERIFIED to proceed, or infer candidate absence from a preview.
|
|
602
653
|
|
|
603
654
|
After candidate parsing and before reviewer dispatch, persist the post-explorer
|
|
604
655
|
candidate ledger using the Review Finding Persistence contract. This is the
|
|
@@ -617,16 +668,24 @@ in the same batch unless intentionally replacing that exact lane before dispatch
|
|
|
617
668
|
|
|
618
669
|
Explorers optimize for recall. Over-reporting is expected. Explorers produce candidates only.
|
|
619
670
|
|
|
620
|
-
The six lanes are a fixed **check-type** partition
|
|
621
|
-
|
|
622
|
-
|
|
671
|
+
The six lanes are a fixed **check-type** partition, not an area partition: the
|
|
672
|
+
count is intentionally constant — every PR needs all six review dimensions —
|
|
673
|
+
and the lanes deliberately overlap by file, each receiving the same diff via
|
|
674
|
+
`common_prompt` and viewing it through a different lens. Six is this workflow's
|
|
675
|
+
high-assurance policy floor, not a claim that research proves a universal optimal
|
|
676
|
+
agent count. Repository policy may add scrutiny but may never reduce the six.
|
|
677
|
+
This is the deliberate exception to surface-scaled fan-out. Coverage is
|
|
678
|
+
guaranteed by all six dimensions reading the whole diff, so the disjoint-partition
|
|
679
|
+
rule that governs area-split fan-outs does not apply.
|
|
680
|
+
|
|
681
|
+
| `workflow_lane` | Focus | Required checks |
|
|
623
682
|
|---|---|---|
|
|
624
|
-
|
|
|
625
|
-
|
|
|
626
|
-
|
|
|
627
|
-
|
|
|
628
|
-
|
|
|
629
|
-
|
|
|
683
|
+
| `intent-architecture` | Intent, scope, architecture, and integration | obligation mapping, design fit, callers/consumers, sibling patterns, docs and claimed-vs-actual behavior |
|
|
684
|
+
| `correctness-state` | Functional correctness, data/state flow, edge cases, and failure paths | input domains, nullability, ordering, transactions, error behavior, rollback, backwards behavior |
|
|
685
|
+
| `tests-falsifiability` | Tests, test validity, regressions, and claimed validation | assertion strength, negative paths, isolation, fixtures, deterministic timing, missing proof |
|
|
686
|
+
| `security-trust` | Security, privacy, trust boundaries, unsafe inputs/sinks, and supply chain | authorization, injection, secrets, provenance, dependency risk, data exposure, abuse paths |
|
|
687
|
+
| `reliability-performance` | Reliability, concurrency, retries, resource bounds, and performance | races, retry semantics, timeouts, lifecycle, caching, algorithmic cost, operational failure modes |
|
|
688
|
+
| `compatibility-delivery` | API/schema/config compatibility, maintainability, build/deploy, docs, and release behavior | public contracts, migrations, runtime/platform support, packaging, CI, rollout and recovery guidance |
|
|
630
689
|
|
|
631
690
|
### Explorer context contract
|
|
632
691
|
|
|
@@ -639,7 +698,7 @@ Every explorer must inspect or explicitly mark unavailable:
|
|
|
639
698
|
5. the nearest relevant test or missing-test location,
|
|
640
699
|
6. deterministic signal entries mapped to its files/symbols,
|
|
641
700
|
7. relevant Swarm knowledge/evidence entries, if present.
|
|
642
|
-
8. the
|
|
701
|
+
8. the exact controller-bound range to analyze (`base_sha...pr_head_sha`),
|
|
643
702
|
|
|
644
703
|
### Explorer output format
|
|
645
704
|
|
|
@@ -656,31 +715,57 @@ directly in the lane output as a fallback convention.
|
|
|
656
715
|
|
|
657
716
|
Explorers must not use `CONFIRMED`, `DISPROVED`, or `PRE_EXISTING`.
|
|
658
717
|
|
|
718
|
+
A base lane that finds no surviving candidates must emit exactly one fully
|
|
719
|
+
populated clean row:
|
|
720
|
+
|
|
721
|
+
```text
|
|
722
|
+
[CLEAN] | workflow_lane | coverage_scope | evidence
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
Header-only `[CLEAN]` markers, prose-only "clean" claims, or empty output do
|
|
726
|
+
not settle the lane.
|
|
727
|
+
|
|
659
728
|
---
|
|
660
729
|
|
|
661
|
-
## Phase 4:
|
|
730
|
+
## Phase 4: Mandatory Repository-Agnostic Micro-Lanes
|
|
662
731
|
|
|
663
|
-
After base lanes settle,
|
|
664
|
-
mandatory ledger with one row per
|
|
732
|
+
After base lanes settle, inspect the exact diff/context pack to focus every row
|
|
733
|
+
in the micro-lane map and print a mandatory ledger with one row per map row:
|
|
665
734
|
|
|
666
735
|
```text
|
|
667
|
-
[TRIGGER-EVAL] | trigger_row | MATCHED
|
|
736
|
+
[TRIGGER-EVAL] | trigger_row | MATCHED | focus_evidence
|
|
668
737
|
```
|
|
669
738
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
739
|
+
Focus evidence must name the changed files, manifests, imports/symbols, semantic
|
|
740
|
+
signals, or explicit absence conditions the lane should examine. `MATCHED` means
|
|
741
|
+
the lane is required, not that a keyword heuristic guessed applicability.
|
|
742
|
+
Repository identity, technology stack, PR size, elapsed time, or predicted risk
|
|
743
|
+
never justifies skipping a row.
|
|
744
|
+
|
|
745
|
+
Launch one focused micro-lane for every row, using
|
|
746
|
+
`dispatch_lanes_async` with `mode: "swarm-pr-review:micro"` and each lane's
|
|
747
|
+
`workflow_lane` equal to its trigger ID. Include the complete exact-set
|
|
748
|
+
`trigger_evaluation` ledger and the same exact current `pr_head_sha` in that
|
|
749
|
+
dispatch. Use a separate batch from base
|
|
750
|
+
lanes. Because the dispatcher accepts at most eight lanes per call, split the
|
|
751
|
+
eleven mandatory micro-lanes across bounded async batches. The runtime rejects
|
|
752
|
+
unrelated or duplicate micro-lanes within a batch, and final ledger persistence
|
|
753
|
+
rejects any row whose completed unique provenance is absent.
|
|
754
|
+
Poll incrementally, then settle every launched lane. Persist
|
|
678
755
|
the complete ledger with `write_pr_review_trigger_eval`; its rows use the stable
|
|
679
|
-
trigger IDs below, and every
|
|
680
|
-
`
|
|
756
|
+
trigger IDs below, and every row includes its returned `source_batch_id` and
|
|
757
|
+
`source_lane_id`. Missing, extra, duplicate, `NO-MATCH`, or unprovenanced
|
|
681
758
|
rows make persistence fail and Phase 4 BLOCKED. The tool atomically writes
|
|
682
759
|
`.swarm/pr-review/<run_id>/trigger-eval.json`, separate from `findings.jsonl`;
|
|
683
|
-
|
|
760
|
+
pass the exact reviewed merge-base as `base_sha`, the exact live base branch
|
|
761
|
+
tip/ref used to compute it as `base_ref`, and the same `pr_head_sha` to the
|
|
762
|
+
writer. The writer runs bounded `git merge-base -- <base_ref> <pr_head_sha>` and
|
|
763
|
+
rejects any claimed `base_sha` that is not the exact result. It accepts only the
|
|
764
|
+
exact eleven-row `MATCHED` set backed by
|
|
765
|
+
eleven completed, non-degraded, exact-head artifacts. It never uses keyword
|
|
766
|
+
classification as permission to waive a lane. Any head mismatch makes
|
|
767
|
+
persistence fail.
|
|
768
|
+
Do not add trigger results to the finding-status enum.
|
|
684
769
|
|
|
685
770
|
For each micro `output_ref`, call `parse_lane_candidates` with
|
|
686
771
|
`producer: "swarm-pr-review"`, `expected_family: "micro_lane"`, and
|
|
@@ -697,11 +782,7 @@ errors, zero malformed rows, and a complete, non-degraded source:
|
|
|
697
782
|
[CLEAN] | micro_lane | coverage_scope | evidence
|
|
698
783
|
```
|
|
699
784
|
|
|
700
|
-
Header-only or malformed zero output is `UNATTESTED` and
|
|
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.
|
|
785
|
+
Header-only or malformed zero output is `UNATTESTED`; apply the COVERAGE GATE (Phase 3). 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. Task-derived findings or CLEAN prose cannot satisfy Phase 4.
|
|
705
786
|
|
|
706
787
|
Each micro-lane receives:
|
|
707
788
|
|
|
@@ -714,23 +795,28 @@ Each micro-lane receives:
|
|
|
714
795
|
- structured candidate output (parser-extracted). If the parser is unavailable,
|
|
715
796
|
the micro-lane MAY emit `[CANDIDATE]` rows as a fallback convention.
|
|
716
797
|
|
|
717
|
-
###
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
|
727
|
-
|
|
728
|
-
| `
|
|
729
|
-
| `
|
|
730
|
-
| `
|
|
731
|
-
| `
|
|
732
|
-
| `
|
|
733
|
-
| `
|
|
798
|
+
### Repository-agnostic mandatory micro-lane map
|
|
799
|
+
|
|
800
|
+
Every row runs in every repository. Diff/context analysis focuses each lane but
|
|
801
|
+
cannot waive it: semantic applicability is not reliably decidable from paths or
|
|
802
|
+
keywords, so `NO-MATCH` is invalid. Repository policy may require supplementary
|
|
803
|
+
specialist review outside this canonical ledger, but supplementary work never
|
|
804
|
+
replaces these portable rows. The `unclassified-risk` lane always runs to cover
|
|
805
|
+
novel failure modes and classification gaps.
|
|
806
|
+
|
|
807
|
+
| Trigger ID | Scope | Trigger in diff or context pack | Launch micro-lane | Invariants to check |
|
|
808
|
+
|---|---|---|---|---|
|
|
809
|
+
| `auth-identity-secrets` | universal | authentication, authorization, identity, sessions, permissions, secrets, cryptography | Identity and secret boundaries | least privilege, confused-deputy paths, credential lifecycle, cryptographic misuse, safe defaults |
|
|
810
|
+
| `untrusted-input-boundaries` | universal | parsing, serialization, queries, templates/rendering, file or network input/output | Untrusted input and sink analysis | injection, traversal, SSRF, unsafe deserialization, output escaping, resource limits |
|
|
811
|
+
| `subprocess-platform` | universal | subprocesses, shell commands, filesystem operations, OS/runtime-specific code | Subprocess and platform safety | array argv, bounded execution, path containment, portability, cleanup, non-interactive behavior |
|
|
812
|
+
| `concurrency-state` | universal | queues, caches, retries, transactions, locks, state machines, async coordination | Concurrency and state transitions | races, atomicity, idempotency, retry accounting, rollback, stale state, bounded growth |
|
|
813
|
+
| `dependencies-build-release` | universal | dependency manifests, lockfiles, installers, build scripts, CI, packaging, deployment | Dependency and delivery integrity | provenance, version/lock consistency, install safety, platform matrices, rollback and release completeness |
|
|
814
|
+
| `api-schema-migrations` | universal | public API, wire/schema/config/storage formats, migrations, feature flags | Compatibility and migration safety | backward/forward compatibility, defaults, validation, mixed-version operation, recovery |
|
|
815
|
+
| `test-infrastructure` | universal | tests, mocks, fixtures, harnesses, coverage, CI matrices | Test validity and isolation | meaningful assertions, contamination, determinism, negative paths, cross-platform proof, test theater |
|
|
816
|
+
| `ui-accessibility-i18n` | universal | user interfaces, interaction flows, rendering, accessibility, localization | UI and human-interface quality | keyboard/screen-reader behavior, focus, error states, responsive behavior, locale-safe formatting |
|
|
817
|
+
| `privacy-observability` | universal | telemetry, logs, analytics, traces, retention, diagnostics | Privacy and observability safety | minimization, redaction, consent, retention, stable metrics, non-gameable evidence |
|
|
818
|
+
| `generated-provenance` | universal | generated, vendored, binary, model-produced, codegen or checked-in build artifacts | Generated artifact provenance | reproducibility, source linkage, tamper evidence, reviewable diffs, licensing and stale output |
|
|
819
|
+
| `unclassified-risk` | universal | any changed artifact or behavior not confidently classified by the rows above | Unclassified high-risk fallback | full change-path review, hidden trust boundaries, novel failure modes, missing specialist classification |
|
|
734
820
|
|
|
735
821
|
Micro-lane output format:
|
|
736
822
|
|
|
@@ -761,8 +847,8 @@ Verifier output is advisory until incorporated by the independent reviewer or cr
|
|
|
761
847
|
|
|
762
848
|
## Phase 6: Independent Reviewer Confirmation
|
|
763
849
|
|
|
764
|
-
**Reviewer-dispatch join barrier:** reviewer dispatch MUST NOT begin until the
|
|
765
|
-
complete and persisted,
|
|
850
|
+
**Reviewer-dispatch join barrier:** reviewer dispatch MUST NOT begin until the micro-lane ledger is
|
|
851
|
+
complete and persisted, all eleven micro-lanes are settled, and every
|
|
766
852
|
accepted micro result has parser-derived provenance or a valid CLEAN
|
|
767
853
|
attestation.
|
|
768
854
|
|
|
@@ -773,6 +859,34 @@ file area, category, or count — not the full candidate set. The reviewer must
|
|
|
773
859
|
re-read the candidate's file:line evidence and relevant context pack entries
|
|
774
860
|
directly.
|
|
775
861
|
|
|
862
|
+
Dispatch reviewer chunks with `dispatch_lanes_async`,
|
|
863
|
+
`mode: "swarm-pr-review:reviewer"`, a unique non-empty `workflow_lane` per
|
|
864
|
+
chunk, `review_item_ids` containing the exact candidate IDs assigned to that
|
|
865
|
+
chunk, reviewer-role agents only, and the same exact `pr_head_sha`. The runtime
|
|
866
|
+
requires one parseable `[REVIEWED]` row for every structurally assigned ID; a
|
|
867
|
+
single marker or partial subset cannot settle the lane. Direct Task
|
|
868
|
+
reviewers are rejected because they cannot carry the durable batch and head
|
|
869
|
+
provenance required by this workflow.
|
|
870
|
+
|
|
871
|
+
For every structured PR-review dispatch, the runtime appends an authoritative
|
|
872
|
+
controller block after caller-authored prompt text. It binds the exact
|
|
873
|
+
`workflow_lane`, PR head, content revision, declared scope, and assigned item
|
|
874
|
+
IDs and explicitly forbids speed/time/token waivers. Caller prompt text cannot
|
|
875
|
+
override that block; output with placeholders, invented IDs, generic assurances,
|
|
876
|
+
or evidence unrelated to the bound lane does not settle the artifact.
|
|
877
|
+
|
|
878
|
+
Reviewer ownership is not accepted as an architect assertion. The controller
|
|
879
|
+
derives the immutable candidate inventory from the integrity-checked base,
|
|
880
|
+
mandatory micro-lane, and council artifacts; the union of `review_item_ids` must
|
|
881
|
+
equal that inventory exactly, with no omitted or invented IDs. If discovery
|
|
882
|
+
produces no candidates, the derived sentinel is `CLEAN-REVIEW`, which still
|
|
883
|
+
requires one independent semantic reviewer row.
|
|
884
|
+
|
|
885
|
+
Candidate IDs must therefore be globally unique across every discovery
|
|
886
|
+
artifact in the run. Prefix IDs with the stable workflow-lane ID (or use
|
|
887
|
+
another deterministic globally unique scheme); duplicate IDs fail closed
|
|
888
|
+
instead of being silently merged.
|
|
889
|
+
|
|
776
890
|
### Noise budget and universal validation
|
|
777
891
|
|
|
778
892
|
Before reviewer dispatch, the orchestrator may suppress candidates that match ANY of the following (each suppression still requires mandatory disclosure):
|
|
@@ -823,6 +937,12 @@ Reviewer output format:
|
|
|
823
937
|
[REVIEWED] | candidate_id | classification | evidence_type | final_severity | introduced_by_pr: YES/NO/UNKNOWN | file:line | rationale | falsification_probe | reviewer_id
|
|
824
938
|
```
|
|
825
939
|
|
|
940
|
+
For the mechanically derived `CLEAN-REVIEW` sentinel, use the same exact row
|
|
941
|
+
with `DISPROVED | STRUCTURALLY_PROVEN | NONE | UNKNOWN | N/A` and concrete
|
|
942
|
+
rationale/probe/reviewer fields; the sentinel means the reviewer independently
|
|
943
|
+
found no surviving actionable candidate, not that reviewer validation was
|
|
944
|
+
skipped.
|
|
945
|
+
|
|
826
946
|
Every reviewer response must end with one parseable `[REVIEWED]` row per
|
|
827
947
|
assigned candidate. A malformed `[REVIEWED]` row is not a verdict: re-dispatch
|
|
828
948
|
with the exact contract (max 2), then mark the reviewer dimension BLOCKED if no
|
|
@@ -858,6 +978,31 @@ A finding may still be reported without a runnable command if it is structurally
|
|
|
858
978
|
|
|
859
979
|
Route every reviewer-confirmed HIGH or CRITICAL finding to a critic. Also route borderline MEDIUM findings when they involve security, state machines, write authority, evidence integrity, model/tool permissions, git safety, or config ratchets.
|
|
860
980
|
|
|
981
|
+
The controller conservatively derives critic ownership from semantic reviewer
|
|
982
|
+
rows: every reviewer-confirmed CRITICAL, HIGH, or MEDIUM item is mandatory
|
|
983
|
+
critic inventory. This intentionally over-routes ordinary MEDIUM items because
|
|
984
|
+
machine enforcement cannot safely infer every repository-specific trust
|
|
985
|
+
boundary from prose. Completion is blocked until that exact derived inventory
|
|
986
|
+
has valid critic rows.
|
|
987
|
+
|
|
988
|
+
Reviewer and critic retries cannot be combined as complementary partial verdict
|
|
989
|
+
sets. Each phase requires at least one fully successful exact batch covering its
|
|
990
|
+
entire mechanically assigned inventory on one revision. A later degraded,
|
|
991
|
+
truncated, stale, wrong-identity, or malformed batch cannot replace an earlier
|
|
992
|
+
valid batch or suppress critic routing.
|
|
993
|
+
|
|
994
|
+
Any newer reviewer batch invalidates every older critic batch, even when the
|
|
995
|
+
new reviewer rows happen to be identical. Dispatch a fresh critic wave from the
|
|
996
|
+
latest coherent reviewer batch; critic evidence can never predate the reviewer
|
|
997
|
+
evidence it purports to challenge.
|
|
998
|
+
|
|
999
|
+
Dispatch critic chunks with `dispatch_lanes_async`,
|
|
1000
|
+
`mode: "swarm-pr-review:critic"`, a unique non-empty `workflow_lane` per
|
|
1001
|
+
chunk, `review_item_ids` containing the exact finding IDs assigned to that
|
|
1002
|
+
chunk, critic-role agents only, and the same exact `pr_head_sha`. The runtime
|
|
1003
|
+
requires one parseable `[CRITIC]` row for every structurally assigned ID and
|
|
1004
|
+
requires one coherent fully successful exact reviewer batch before a critic wave.
|
|
1005
|
+
|
|
861
1006
|
The critic must challenge:
|
|
862
1007
|
|
|
863
1008
|
- severity inflation,
|
|
@@ -885,7 +1030,13 @@ The `[CRITIC]` row in the format above is **mandatory contract**, not advisory o
|
|
|
885
1030
|
|
|
886
1031
|
**Re-dispatch trigger:** when a critic lane response is missing the verdict row, the orchestrator must automatically re-dispatch that lane with the explicit instruction: "Your final line MUST be exactly the Phase 8 contract row: `[CRITIC] | finding_id | UPHELD/DOWNGRADED/DISPROVED/NEEDS_MORE_EVIDENCE | final_severity | reason | required_report_change`. A response without that exact row will be treated as a planning message and re-dispatched." Do not synthesize findings from the planning preamble; only from the re-dispatched verdict.
|
|
887
1032
|
|
|
888
|
-
|
|
1033
|
+
`NEEDS_MORE_EVIDENCE` is deliberately non-terminal and never satisfies critic
|
|
1034
|
+
settlement. Re-dispatch a narrower critic/probe lane or report the dimension
|
|
1035
|
+
BLOCKED. Terminal critic rows are cross-field checked: `DISPROVED` requires
|
|
1036
|
+
`NONE`, `UPHELD` requires CRITICAL/HIGH/MEDIUM, and `DOWNGRADED` cannot remain
|
|
1037
|
+
CRITICAL.
|
|
1038
|
+
|
|
1039
|
+
**COVERAGE GATE alignment:** Critic lane failures apply the COVERAGE GATE (Phase 3) using `dispatch_lanes_async` with `mode: "swarm-pr-review:critic"` and the same exact `pr_head_sha`. Do NOT mark findings UNVERIFIED or continue past the gap. The orchestrator NEVER fabricates a critic verdict by parsing prose, by tolerating a planning preamble, by presenting partial findings, or by silently accepting reduced coverage.
|
|
889
1040
|
|
|
890
1041
|
Refuted findings become `DISPROVED` or `ADVISORY`, depending on critic rationale. Downgrades must be listed in the final validation provenance.
|
|
891
1042
|
|
|
@@ -1014,240 +1165,7 @@ Update the verdict only after re-verifying all previously blocking findings.
|
|
|
1014
1165
|
|
|
1015
1166
|
---
|
|
1016
1167
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
This section demonstrates the new parser-based extraction path end-to-end
|
|
1020
|
-
using synthetic data. It is concrete enough to implement the same pattern in
|
|
1021
|
-
another skill.
|
|
1022
|
-
|
|
1023
|
-
### Scenario
|
|
1024
|
-
|
|
1025
|
-
A PR review has dispatched six base explorer lanes via `dispatch_lanes_async`.
|
|
1026
|
-
The batch completed and `collect_lane_results` returned:
|
|
1027
|
-
|
|
1028
|
-
```json
|
|
1029
|
-
{
|
|
1030
|
-
"batch_id": "batch-a1b2c3",
|
|
1031
|
-
"lane_results": [
|
|
1032
|
-
{
|
|
1033
|
-
"lane_id": "pr_review_lane1_correctness",
|
|
1034
|
-
"status": "completed",
|
|
1035
|
-
"output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
1036
|
-
"output_degraded": false
|
|
1037
|
-
},
|
|
1038
|
-
{
|
|
1039
|
-
"lane_id": "pr_review_lane2_security",
|
|
1040
|
-
"status": "completed",
|
|
1041
|
-
"output_ref": "L1:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
1042
|
-
"output_degraded": false
|
|
1043
|
-
}
|
|
1044
|
-
]
|
|
1045
|
-
}
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
### Step 1 — Call the parser
|
|
1049
|
-
|
|
1050
|
-
The orchestrator calls `parse_lane_candidates` for each `output_ref`:
|
|
1051
|
-
|
|
1052
|
-
```json
|
|
1053
|
-
{
|
|
1054
|
-
"tool": "parse_lane_candidates",
|
|
1055
|
-
"arguments": {
|
|
1056
|
-
"output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
1057
|
-
"producer": "swarm-pr-review",
|
|
1058
|
-
"expected_family": "base_explorer"
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
### Step 2 — Structured response
|
|
1064
|
-
|
|
1065
|
-
The parser returns a `ParseResultWithSidecar`. On success, `error` and `error_code` are absent:
|
|
1066
|
-
|
|
1067
|
-
```json
|
|
1068
|
-
{
|
|
1069
|
-
"candidates": [
|
|
1070
|
-
{
|
|
1071
|
-
"record_type": "candidate",
|
|
1072
|
-
"row_format_family": "base_explorer",
|
|
1073
|
-
"row_format_version": 1,
|
|
1074
|
-
"record_version": { "major": 1, "minor": 1 },
|
|
1075
|
-
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
1076
|
-
"source_batch_id": "B-2025-06-22-001",
|
|
1077
|
-
"source_lane_id": "explorer-1",
|
|
1078
|
-
"source_agent": "paid_explorer",
|
|
1079
|
-
"source_digest": "sha256:abc123def456...",
|
|
1080
|
-
"extracted_from_partial_source": false,
|
|
1081
|
-
"sessionId": "ses_01HXYZ...",
|
|
1082
|
-
"parentSessionId": "ses_01HABC...",
|
|
1083
|
-
"producer": "swarm-pr-review",
|
|
1084
|
-
"candidate_id": "C-001",
|
|
1085
|
-
"lane": "Lane 1: Correctness and edge cases",
|
|
1086
|
-
"micro_lane": null,
|
|
1087
|
-
"severity": "HIGH",
|
|
1088
|
-
"category": "null-safety",
|
|
1089
|
-
"file_line": "src/utils/cache.ts:142",
|
|
1090
|
-
"claim": "Uncached getter may return undefined on cold start",
|
|
1091
|
-
"evidence_summary": "The `getCached` function returns `cache[key]` without a fallback when the cache is empty.",
|
|
1092
|
-
"impact_context": "Downstream callers in `src/handlers/*.ts` expect a defined value and call `.toString()` directly.",
|
|
1093
|
-
"invariant_violated": null,
|
|
1094
|
-
"confidence": "HIGH"
|
|
1095
|
-
},
|
|
1096
|
-
{
|
|
1097
|
-
"record_type": "candidate",
|
|
1098
|
-
"row_format_family": "base_explorer",
|
|
1099
|
-
"row_format_version": 1,
|
|
1100
|
-
"record_version": { "major": 1, "minor": 1 },
|
|
1101
|
-
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
1102
|
-
"source_batch_id": "B-2025-06-22-001",
|
|
1103
|
-
"source_lane_id": "explorer-1",
|
|
1104
|
-
"source_agent": "paid_explorer",
|
|
1105
|
-
"source_digest": "sha256:abc123def456...",
|
|
1106
|
-
"extracted_from_partial_source": false,
|
|
1107
|
-
"sessionId": "ses_01HXYZ...",
|
|
1108
|
-
"parentSessionId": "ses_01HABC...",
|
|
1109
|
-
"producer": "swarm-pr-review",
|
|
1110
|
-
"candidate_id": "C-002",
|
|
1111
|
-
"lane": "Lane 1: Correctness and edge cases",
|
|
1112
|
-
"micro_lane": null,
|
|
1113
|
-
"severity": "MEDIUM",
|
|
1114
|
-
"category": "async-ordering",
|
|
1115
|
-
"file_line": "src/services/queue.ts:88",
|
|
1116
|
-
"claim": "Race between `drain` and `processNext` may drop items",
|
|
1117
|
-
"evidence_summary": "`drain` sets `active = false` before awaiting `processNext`, which also checks `active`.",
|
|
1118
|
-
"impact_context": "Items submitted during the drain window are silently dropped.",
|
|
1119
|
-
"invariant_violated": null,
|
|
1120
|
-
"confidence": "MEDIUM"
|
|
1121
|
-
}
|
|
1122
|
-
],
|
|
1123
|
-
"invocation_envelope": {
|
|
1124
|
-
"record_type": "invocation",
|
|
1125
|
-
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
1126
|
-
"source_batch_id": "B-2025-06-22-001",
|
|
1127
|
-
"source_lane_id": "explorer-1",
|
|
1128
|
-
"source_agent": "paid_explorer",
|
|
1129
|
-
"source_digest": "sha256:abc123def456...",
|
|
1130
|
-
"row_format_version": 1,
|
|
1131
|
-
"record_version": { "major": 1, "minor": 1 },
|
|
1132
|
-
"sessionId": "ses_01HXYZ...",
|
|
1133
|
-
"parentSessionId": "ses_01HABC...",
|
|
1134
|
-
"producer": "swarm-pr-review",
|
|
1135
|
-
"produced_at": "2025-06-22T14:30:00.000Z",
|
|
1136
|
-
"format_families_detected": ["base_explorer"],
|
|
1137
|
-
"candidate_count": 2,
|
|
1138
|
-
"parse_errors": 0,
|
|
1139
|
-
"malformed_rows": 0,
|
|
1140
|
-
"clean_attestation_count": 0
|
|
1141
|
-
},
|
|
1142
|
-
"diagnostics": {
|
|
1143
|
-
"candidate_count": 2,
|
|
1144
|
-
"parse_errors": 0,
|
|
1145
|
-
"parse_error_details": [],
|
|
1146
|
-
"malformed_rows": 0,
|
|
1147
|
-
"duplicate_id_count": 0,
|
|
1148
|
-
"duplicate_id_warnings": [],
|
|
1149
|
-
"degraded_source_count": 0,
|
|
1150
|
-
"incomplete_source_count": 0,
|
|
1151
|
-
"format_families_detected": ["base_explorer"],
|
|
1152
|
-
"clean_attestation_count": 0
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
```
|
|
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`.
|
|
1161
|
-
|
|
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:
|
|
1163
|
-
|
|
1164
|
-
```json
|
|
1165
|
-
{
|
|
1166
|
-
"error": "Artifact reference not found in store",
|
|
1167
|
-
"error_code": "ref-not-found",
|
|
1168
|
-
"candidates": [],
|
|
1169
|
-
"invocation_envelope": {
|
|
1170
|
-
"record_type": "invocation",
|
|
1171
|
-
"source_output_ref": "L1:1111111111111111111111111111111111111111111111111111111111111111:2222222222222222222222222222222222222222222222222222222222222222:3333333333333333333333333333333333333333333333333333333333333333",
|
|
1172
|
-
"source_batch_id": "",
|
|
1173
|
-
"source_lane_id": "",
|
|
1174
|
-
"source_agent": "",
|
|
1175
|
-
"source_digest": "",
|
|
1176
|
-
"row_format_version": 1,
|
|
1177
|
-
"record_version": { "major": 1, "minor": 1 },
|
|
1178
|
-
"produced_at": "2025-06-22T14:30:00.000Z",
|
|
1179
|
-
"format_families_detected": [],
|
|
1180
|
-
"candidate_count": 0,
|
|
1181
|
-
"parse_errors": 0,
|
|
1182
|
-
"malformed_rows": 0,
|
|
1183
|
-
"clean_attestation_count": 0
|
|
1184
|
-
},
|
|
1185
|
-
"diagnostics": {
|
|
1186
|
-
"candidate_count": 0,
|
|
1187
|
-
"parse_errors": 0,
|
|
1188
|
-
"parse_error_details": [],
|
|
1189
|
-
"malformed_rows": 0,
|
|
1190
|
-
"duplicate_id_count": 0,
|
|
1191
|
-
"duplicate_id_warnings": [],
|
|
1192
|
-
"degraded_source_count": 0,
|
|
1193
|
-
"incomplete_source_count": 0,
|
|
1194
|
-
"format_families_detected": [],
|
|
1195
|
-
"clean_attestation_count": 0
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
```
|
|
1199
|
-
|
|
1200
|
-
### Step 3 — Filter and group
|
|
1201
|
-
|
|
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
|
|
1203
|
-
the candidates. In this synthetic example, the two candidates above are grouped
|
|
1204
|
-
by file area:
|
|
1205
|
-
|
|
1206
|
-
- **Chunk A — `src/utils/`** (1 candidate): C-001
|
|
1207
|
-
- **Chunk B — `src/services/`** (1 candidate): C-002
|
|
1208
|
-
|
|
1209
|
-
If there were more candidates, the orchestrator would also group by category
|
|
1210
|
-
(e.g., `null-safety`, `async-ordering`) and cap each chunk at 50 candidates.
|
|
1211
|
-
|
|
1212
|
-
### Step 4 — Dispatch reviewer lanes
|
|
1213
|
-
|
|
1214
|
-
The orchestrator dispatches one reviewer lane per chunk:
|
|
1215
|
-
|
|
1216
|
-
```text
|
|
1217
|
-
You are the independent reviewer. Validate only the candidates assigned below.
|
|
1218
|
-
Do not search for new issues except where needed to validate reachability or
|
|
1219
|
-
mitigation. Do not trust explorer severity.
|
|
1220
|
-
|
|
1221
|
-
Context pack summary:
|
|
1222
|
-
- scope: ...
|
|
1223
|
-
- obligations: ...
|
|
1224
|
-
- impact cone: ...
|
|
1225
|
-
- deterministic signals: ...
|
|
1226
|
-
- relevant Swarm artifacts / knowledge: ...
|
|
1227
|
-
- base_ref: <commit SHA of base branch>
|
|
1228
|
-
- head_ref: <commit SHA of PR head branch>
|
|
1229
|
-
|
|
1230
|
-
Candidates (Chunk A — src/utils/):
|
|
1231
|
-
- C-001 | HIGH | null-safety | src/utils/cache.ts:142 | Uncached getter may return undefined on cold start
|
|
1232
|
-
|
|
1233
|
-
For each candidate, return:
|
|
1234
|
-
[REVIEWED] | candidate_id | CONFIRMED/DISPROVED/UNVERIFIED/PRE_EXISTING | evidence_type | final_severity | introduced_by_pr | file:line | rationale | falsification_probe | reviewer_id
|
|
1235
|
-
|
|
1236
|
-
You must check caller context, reachability, schema/middleware/framework mitigations, state-machine constraints, test coverage, PR-introducedness, and severity.
|
|
1237
|
-
|
|
1238
|
-
IMPORTANT: If a finding claims behavior is "new" or "introduced by the PR", you MUST read the equivalent code on the base branch (git show <base_ref>:<file>) to verify it was not present before. A reviewer claim of "this is new" is invalid without base-branch evidence. Do not compare the new code to an idealized baseline — compare it to what actually existed on the base branch at the time of the PR.
|
|
1239
|
-
```
|
|
1240
|
-
|
|
1241
|
-
### Key invariants
|
|
1242
|
-
|
|
1243
|
-
- The parser reads the **full artifact**, not a preview. Truncation in the
|
|
1244
|
-
`dispatch_lanes` preview does not affect candidate extraction.
|
|
1245
|
-
- The orchestrator never classifies candidates — it only filters, groups, and
|
|
1246
|
-
routes them.
|
|
1247
|
-
- Each reviewer receives a bounded chunk. A chunk with more than 50 candidates
|
|
1248
|
-
is split before dispatch.
|
|
1249
|
-
- The `invocation_envelope` in the parser response provides audit provenance
|
|
1250
|
-
for every extracted candidate.
|
|
1168
|
+
For the full parser-based candidate extraction dry-run example, read `references/parser-dry-run.md`.
|
|
1251
1169
|
|
|
1252
1170
|
---
|
|
1253
1171
|
|
|
@@ -1258,11 +1176,11 @@ Council mode is opt-in only and adversarial.
|
|
|
1258
1176
|
When triggered:
|
|
1259
1177
|
|
|
1260
1178
|
1. Build the same context pack as default mode.
|
|
1261
|
-
2.
|
|
1179
|
+
2. After the default exact-six base lanes and required micro-lanes are mechanically covered, launch all supplementary council agents with one `dispatch_lanes_async` call using `mode: "swarm-pr-review:council"`, the same exact `pr_head_sha`, and one unique `workflow_lane` per council member; continue independent context preparation while they run, polling with `collect_lane_results` (without `wait`) to process settled agents incrementally. Use `wait: true` only when no independent work remains and agents are still pending. All agents must be settled and their candidates added to the ledger before reviewer classification; the runtime enforces this join barrier. If structured asynchronous dispatch with exact-head and workflow-lane provenance is unavailable, stop as `BLOCKED`; blocking, sequential, or direct-Task fallback is not equivalent.
|
|
1262
1180
|
3. Each council agent assumes all work is wrong until code evidence proves otherwise.
|
|
1263
1181
|
4. Each agent hunts within its lane only.
|
|
1264
|
-
5. Agents return
|
|
1265
|
-
6. Agents must not return `CONFIRMED`, `DISPROVED`, or final severity.
|
|
1182
|
+
5. Agents return the same mechanically parseable candidate contract as other discovery lanes: one `[CANDIDATE]` row per `EVIDENCE_FOUND` or `SUSPICIOUS` claim, or a fully populated `[CLEAN] | workflow_lane | coverage_scope | evidence` row when no candidate survives. Council prose without one of those markers does not settle the lane.
|
|
1183
|
+
6. Agents must not return `CONFIRMED`, `DISPROVED`, or final severity; candidate severity remains provisional until reviewer classification.
|
|
1266
1184
|
7. The independent reviewer then classifies every council candidate as `CONFIRMED`, `DISPROVED`, `UNVERIFIED`, or `PRE_EXISTING`.
|
|
1267
1185
|
8. Apply critic challenge to reviewer-confirmed HIGH/CRITICAL or borderline findings.
|
|
1268
1186
|
9. Final synthesis distinguishes real blockers, real low-severity issues, accepted caveats, disproved council claims, and follow-up quality work.
|
|
@@ -1319,7 +1237,7 @@ Council findings are supplementary, not authoritative overrides. Do not adopt co
|
|
|
1319
1237
|
11. Obligation precedence is deterministic. Do not skip higher-precedence sources to fill gaps with LLM synthesis.
|
|
1320
1238
|
12. Do not leak secrets from logs, evidence bundles, config files, URLs, or scanner output.
|
|
1321
1239
|
13. Do not recommend destructive git or filesystem actions as fixes unless they are clearly scoped, safe, and necessary.
|
|
1322
|
-
14. If subagents fail, timeout, or return malformed output, retry with corrected parameters (max 2 attempts)
|
|
1240
|
+
14. If subagents fail, timeout, or return malformed output, retry with corrected parameters (max 2 attempts) through the same structured `dispatch_lanes_async` workflow mode and exact `pr_head_sha`. Blocking or direct-Task dispatch cannot preserve the durable provenance contract and is not an equivalent fallback. If structured retries fail, the affected coverage dimension is BLOCKED and must be surfaced to the user before synthesis. Do not fabricate validation results, do not present partial findings, and do not silently mark candidates UNVERIFIED to proceed past the gap.
|
|
1323
1241
|
|
|
1324
1242
|
15. If context pack, repo graph, deterministic signals, or Swarm artifacts are unavailable, retry with alternative access paths. If unavailable after retry, the affected coverage dimension is BLOCKED and must be surfaced to the user. Do not proceed to synthesis with unclosed coverage gaps under a "best available evidence" rationale — the architect is not authorized to produce a degraded review.
|
|
1325
1243
|
|
|
@@ -1338,7 +1256,7 @@ Before writing the final output, print this checklist with filled values. Every
|
|
|
1338
1256
|
[VALIDATION] deterministic lane dispatcher used: YES/NO — ___
|
|
1339
1257
|
[VALIDATION] base explorer lanes dispatched: ___ / 6
|
|
1340
1258
|
[VALIDATION] base explorer lanes returned: ___ / 6
|
|
1341
|
-
[VALIDATION]
|
|
1259
|
+
[VALIDATION] mandatory micro-lanes dispatched and settled: ___ / 11 OR BLOCKED — <missing rows>
|
|
1342
1260
|
[VALIDATION] Swarm verifier routing used: ___
|
|
1343
1261
|
[VALIDATION] raw candidates: ___
|
|
1344
1262
|
[VALIDATION] tool candidates: ___
|
|
@@ -1366,7 +1284,7 @@ If any reviewer lane lacks a parseable `[REVIEWED]` row after bounded
|
|
|
1366
1284
|
re-dispatch, the reviewer dimension is BLOCKED. Do not infer or silently
|
|
1367
1285
|
downgrade a verdict.
|
|
1368
1286
|
|
|
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
|
|
1287
|
+
**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 — apply the COVERAGE GATE (Phase 3). Do not proceed to final output. Surface unclosed gaps with exact failing dimensions and retry/equivalence evidence.
|
|
1370
1288
|
|
|
1371
1289
|
---
|
|
1372
1290
|
|
|
@@ -1474,105 +1392,13 @@ Use this exact continuation prompt format:
|
|
|
1474
1392
|
|
|
1475
1393
|
---
|
|
1476
1394
|
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
Use this template when dispatching reviewer subagents:
|
|
1480
|
-
|
|
1481
|
-
```text
|
|
1482
|
-
You are the independent reviewer. Validate only the candidates assigned below.
|
|
1483
|
-
Do not search for new issues except where needed to validate reachability or mitigation.
|
|
1484
|
-
Do not trust explorer severity.
|
|
1485
|
-
|
|
1486
|
-
Context pack summary:
|
|
1487
|
-
- scope: ...
|
|
1488
|
-
- obligations: ...
|
|
1489
|
-
- impact cone: ...
|
|
1490
|
-
- deterministic signals: ...
|
|
1491
|
-
- relevant Swarm artifacts / knowledge: ...
|
|
1492
|
-
- base_ref: <commit SHA of base branch>
|
|
1493
|
-
- head_ref: <commit SHA of PR head branch>
|
|
1494
|
-
|
|
1495
|
-
Candidates:
|
|
1496
|
-
- ...
|
|
1497
|
-
|
|
1498
|
-
For each candidate, return:
|
|
1499
|
-
[REVIEWED] | candidate_id | CONFIRMED/DISPROVED/UNVERIFIED/PRE_EXISTING | evidence_type | final_severity | introduced_by_pr | file:line | rationale | falsification_probe | reviewer_id
|
|
1500
|
-
|
|
1501
|
-
You must check caller context, reachability, schema/middleware/framework mitigations, state-machine constraints, test coverage, PR-introducedness, and severity.
|
|
1502
|
-
|
|
1503
|
-
IMPORTANT: If a finding claims behavior is "new" or "introduced by the PR", you MUST read the equivalent code on the base branch (git show <base_ref>:<file>) to verify it was not present before. A reviewer claim of "this is new" is invalid without base-branch evidence. Do not compare the new code to an idealized baseline — compare it to what actually existed on the base branch at the time of the PR.
|
|
1504
|
-
```
|
|
1505
|
-
|
|
1506
|
-
---
|
|
1507
|
-
|
|
1508
|
-
# Critic Prompt Template
|
|
1509
|
-
|
|
1510
|
-
Use this template when dispatching critic subagents:
|
|
1511
|
-
|
|
1512
|
-
```text
|
|
1513
|
-
You are the adversarial critic. Challenge only reviewer-confirmed findings assigned below.
|
|
1514
|
-
Your goal is to reduce false positives, severity inflation, and non-actionable reports.
|
|
1515
|
-
|
|
1516
|
-
For each finding, challenge:
|
|
1517
|
-
- whether evidence proves the claim,
|
|
1518
|
-
- whether the path is reachable,
|
|
1519
|
-
- whether mitigations apply,
|
|
1520
|
-
- whether severity is inflated,
|
|
1521
|
-
- whether it is PR-introduced,
|
|
1522
|
-
- whether suggested fixes are safe/actionable,
|
|
1523
|
-
- whether related files were missed,
|
|
1524
|
-
- whether multiple findings should be grouped.
|
|
1525
|
-
|
|
1526
|
-
Return:
|
|
1527
|
-
[CRITIC] | finding_id | UPHELD/DOWNGRADED/DISPROVED/NEEDS_MORE_EVIDENCE | final_severity | reason | required_report_change
|
|
1528
|
-
|
|
1529
|
-
REQUIRED FINAL LINE — your final line MUST be exactly the row above (no variations, no labeled fields, no placeholders):
|
|
1530
|
-
[CRITIC] | finding_id | UPHELD/DOWNGRADED/DISPROVED/NEEDS_MORE_EVIDENCE | final_severity | reason | required_report_change
|
|
1531
|
-
|
|
1532
|
-
A response without this exact row is treated as a planning preamble and re-dispatched. Do not output only a planning or investigation message.
|
|
1533
|
-
```
|
|
1534
|
-
|
|
1535
|
-
---
|
|
1536
|
-
|
|
1537
|
-
# Explorer Prompt Template
|
|
1538
|
-
|
|
1539
|
-
Use this template when dispatching base explorer or micro-lane agents:
|
|
1540
|
-
|
|
1541
|
-
```text
|
|
1542
|
-
You are an explorer. Optimize for recall, not final judgment.
|
|
1543
|
-
Return candidates only. Do not use CONFIRMED, DISPROVED, or PRE_EXISTING.
|
|
1544
|
-
|
|
1545
|
-
Lane:
|
|
1546
|
-
Scope:
|
|
1547
|
-
base_ref:
|
|
1548
|
-
head_ref:
|
|
1549
|
-
Obligations:
|
|
1550
|
-
Changed files/hunks:
|
|
1551
|
-
Impact cone:
|
|
1552
|
-
Relevant deterministic signals:
|
|
1553
|
-
Relevant Swarm artifacts / knowledge:
|
|
1554
|
-
Checklist:
|
|
1555
|
-
|
|
1556
|
-
You must inspect or mark unavailable:
|
|
1557
|
-
1. changed hunk,
|
|
1558
|
-
2. caller/consumer,
|
|
1559
|
-
3. callee/dependency,
|
|
1560
|
-
4. sibling implementation or prior pattern,
|
|
1561
|
-
5. nearest test or missing-test location,
|
|
1562
|
-
6. deterministic signals,
|
|
1563
|
-
7. Swarm artifacts/knowledge,
|
|
1564
|
-
8. the exact `base_ref..head_ref` commit range and both endpoint revisions.
|
|
1565
|
-
|
|
1566
|
-
Return:
|
|
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`.
|
|
1570
|
-
```
|
|
1571
|
-
|
|
1572
|
-
The orchestrator extracts candidates from the full lane artifact via
|
|
1573
|
-
`parse_lane_candidates` as the primary mechanism. The `[CANDIDATE]` row
|
|
1574
|
-
format above is a fallback convention for environments where the parser is
|
|
1575
|
-
unavailable. Explorers should still emit structured records regardless of
|
|
1576
|
-
whether the parser is present.
|
|
1395
|
+
For reviewer, critic, and explorer prompt templates, read `references/prompt-templates.md`.
|
|
1577
1396
|
|
|
1578
|
-
|
|
1397
|
+
After metrics and durable review artifacts are complete, but before emitting the
|
|
1398
|
+
user-facing final report, call `complete_pr_workflow` with mode `PR_REVIEW` and
|
|
1399
|
+
the same exact
|
|
1400
|
+
`pr_head_sha`. The tool refuses to clear the session gate while required base,
|
|
1401
|
+
trigger, declared reviewer/critic, or open-lane obligations remain incomplete.
|
|
1402
|
+
While the gate remains active, the runtime replaces architect final-response
|
|
1403
|
+
text with a mechanical blocked notice and re-wakes an idle parent session. Only
|
|
1404
|
+
emit the final report after the completion tool confirms that the gate cleared.
|