opencode-swarm 7.79.6 → 7.80.0
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/brainstorm/SKILL.md +1 -1
- package/.opencode/skills/codebase-review-swarm/SKILL.md +6 -0
- package/.opencode/skills/codebase-review-swarm/references/review-protocol-v8.2.md +5 -5
- package/.opencode/skills/council/SKILL.md +10 -3
- package/.opencode/skills/deep-dive/SKILL.md +4 -2
- package/.opencode/skills/deep-research/SKILL.md +13 -5
- package/.opencode/skills/plan/SKILL.md +1 -1
- package/.opencode/skills/specify/SKILL.md +1 -1
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +18 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +5 -5
- package/dist/background/completion-observer.d.ts +5 -5
- package/dist/background/pending-delegations.d.ts +58 -17
- package/dist/background/task-envelope.d.ts +5 -0
- package/dist/cli/index.js +187 -18
- package/dist/config/schema.d.ts +2 -0
- package/dist/hooks/knowledge-curator.d.ts +2 -0
- package/dist/hooks/knowledge-types.d.ts +1 -0
- package/dist/index.js +889 -69
- package/dist/memory/schema.d.ts +4 -4
- package/dist/tools/dispatch-lanes.d.ts +118 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/manifest.d.ts +2 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/package.json +1 -1
|
@@ -76,7 +76,7 @@ Present the eleven gates with their defaults (DEFAULT_QA_GATES), parallel coder
|
|
|
76
76
|
- final_council (default: OFF) -- when enabled, after all phases complete the architect dispatches the full 5-member council (critic, reviewer, sme, test_engineer, explorer) -- NOT the General Council -- at project scope, collects `CouncilMemberVerdict` objects, and calls `write_final_council_evidence`. This does not require `council.general.enabled`.
|
|
77
77
|
|
|
78
78
|
Additionally, present these two sub-items as part of the same exchange:
|
|
79
|
-
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel.
|
|
79
|
+
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel. Parallel coders each run in an isolated git worktree (separate working dir + branch) and merge back automatically, so they never overwrite each other's files -- safe and faster, but only for tasks whose file scopes do NOT overlap. The per-task file scopes that determine a safe parallel count are not known until the plan is finalized, so default to 1 (serial) here; the precise recommendation is made at plan time once the tasks and their scopes exist.
|
|
80
80
|
- Commit frequency (default: phase-level only) -- optional per-task checkpoint commit after each task completion.
|
|
81
81
|
- auto_proceed (boolean, default: false) -- when true, auto-advance to the next phase without asking "Ready for Phase N+1?"; runtime toggle via /swarm auto-proceed on|off.
|
|
82
82
|
|
|
@@ -63,3 +63,9 @@ Use these baselines unless repository policy explicitly requires stricter or old
|
|
|
63
63
|
6. Run inline critic for CRITICAL/HIGH defects, enhancement critic for all kept enhancements, and final whole-report critic.
|
|
64
64
|
7. Write `review-report.md` only after coverage closure and final critic PASS.
|
|
65
65
|
8. Final response reports only the run path, selected tracks, counts summary, highest-risk items, coverage limitations, and confirmation that no source files were modified.
|
|
66
|
+
|
|
67
|
+
## Async advisory lanes
|
|
68
|
+
|
|
69
|
+
When selected-track inventory or candidate generation decomposes into independent read-only units, launch those units with `dispatch_lanes_async` when available. Record each returned `batch_id`, then continue architect-owned deterministic work that does not depend on lane output: update the coverage ledger shell, run safe local tools, prepare validation shards, and document unresolved coverage units. Do not mark coverage `REVIEWED`, promote candidates to findings, or write the final report from running lanes.
|
|
70
|
+
|
|
71
|
+
At every coverage, validation, and synthesis boundary, call `collect_lane_results` with `wait: true` for all open batches. Missing, stale, cancelled, or failed lanes are explicit coverage gaps and must become `BLOCKED` or `SKIPPED_WITH_REASON`; they cannot be silently ignored. If `dispatch_lanes_async` is unavailable, use the existing blocking dispatch pattern and record that async advisory lanes were unavailable.
|
|
@@ -126,9 +126,9 @@ Before writing under `.swarm/`, verify `.swarm/` is ignored or locally excluded.
|
|
|
126
126
|
## Phase 0 safe ordering
|
|
127
127
|
|
|
128
128
|
1. Run 0A alone.
|
|
129
|
-
2. After 0A, run 0B and 0C
|
|
130
|
-
3. After 0B, run 0D and 0E
|
|
131
|
-
4. Preferred batch order: batch 1 = 0F and 0G; batch 2 = 0H and 0I. Never exceed two Phase 0 agents.
|
|
129
|
+
2. After 0A, run 0B and 0C through `dispatch_lanes_async` only if the repository is large enough to benefit. While those lanes run, the Architect continues deterministic inventory work that does not depend on their results.
|
|
130
|
+
3. After 0B, run 0D and 0E through `dispatch_lanes_async` only if 0E can leave `linked_claims` blank for Architect linking in 0J. Otherwise run 0D before 0E.
|
|
131
|
+
4. Preferred async batch order: batch 1 = 0F and 0G; batch 2 = 0H and 0I. Never exceed two Phase 0 agents.
|
|
132
132
|
5. Run 0F after 0E when possible.
|
|
133
133
|
6. Run 0G after 0B and 0C.
|
|
134
134
|
7. Run 0H and 0I after 0B and 0C.
|
|
@@ -136,7 +136,7 @@ Before writing under `.swarm/`, verify `.swarm/` is ignored or locally excluded.
|
|
|
136
136
|
9. Run 0K after 0J. Stop for user track selection unless preselected.
|
|
137
137
|
10. Run 0L after track selection and before Phase 1 candidate generation. 0L is the last Phase 0 step before Phase 1.
|
|
138
138
|
|
|
139
|
-
Do not run dependent inventory passes merely to keep agents busy. Missing dependency context is `unknown`, not guessed.
|
|
139
|
+
Collect every async batch with `collect_lane_results` before consuming its ledger output or advancing to a dependent step. If `dispatch_lanes_async` or `collect_lane_results` is unavailable, fall back to blocking `dispatch_lanes`; if deterministic dispatch is unavailable, run isolated local passes and record that fallback. Do not run dependent inventory passes merely to keep agents busy. Missing dependency context is `unknown`, not guessed.
|
|
140
140
|
|
|
141
141
|
## Phase 0 inventory
|
|
142
142
|
|
|
@@ -205,7 +205,7 @@ Rules:
|
|
|
205
205
|
|
|
206
206
|
## Phase 1 — Candidate generation
|
|
207
207
|
|
|
208
|
-
Every dispatch includes selected track(s), exact file list or surface IDs, source-of-truth packet, repository-context packet, relevant ledgers, the applicable `TRACK_DEPTH_PLAN`, candidate format, `out_of_scope_note` rule, and anti-cursory/non-dilution reminder.
|
|
208
|
+
Every dispatch includes selected track(s), exact file list or surface IDs, source-of-truth packet, repository-context packet, relevant ledgers, the applicable `TRACK_DEPTH_PLAN`, candidate format, `out_of_scope_note` rule, and anti-cursory/non-dilution reminder. Prefer `dispatch_lanes_async` for independent candidate-generation coverage units so the Architect can continue building the review ledger, coverage map, and validation routing while lanes inspect subsystems. Call `collect_lane_results` before Phase 2 reviewer validation; no candidate may be routed, counted, or synthesized until its async batch has settled or been explicitly marked blocked/skipped.
|
|
209
209
|
|
|
210
210
|
File-size rule: no more than 15 files per deep pass; no more than 8 dense files per deep pass. Dense = >300 logical lines, multiple unrelated responsibilities, or interleaved UI/state/network/security logic. No sampling inside assigned scope. Large selections require more deep passes, not larger batches or lower depth.
|
|
211
211
|
|
|
@@ -87,8 +87,12 @@ RESEARCH CONTEXT
|
|
|
87
87
|
|
|
88
88
|
3. Dispatch `the active swarm's council_generalist agent`,
|
|
89
89
|
`the active swarm's council_skeptic agent`, and
|
|
90
|
-
`the active swarm's council_domain_expert agent`
|
|
91
|
-
|
|
90
|
+
`the active swarm's council_domain_expert agent` with `dispatch_lanes_async`
|
|
91
|
+
when available -- one lane per agent. Record the returned `batch_id`, then
|
|
92
|
+
continue only non-dependent architect work: prepare the synthesis outline,
|
|
93
|
+
normalize the RESEARCH CONTEXT citations, and draft disagreement categories.
|
|
94
|
+
Do not call `convene_general_council` or present conclusions from running
|
|
95
|
+
lanes. Each dispatch message must
|
|
92
96
|
include:
|
|
93
97
|
- The question
|
|
94
98
|
- Round number: 1
|
|
@@ -99,7 +103,10 @@ RESEARCH CONTEXT
|
|
|
99
103
|
|
|
100
104
|
Do NOT share other agents' responses at this stage.
|
|
101
105
|
|
|
102
|
-
4.
|
|
106
|
+
4. Call `collect_lane_results` with `wait: true` for the Round 1 batch and collect
|
|
107
|
+
all three JSON responses. If `dispatch_lanes_async` is unavailable, use
|
|
108
|
+
blocking parallel dispatch and record that async advisory lanes were
|
|
109
|
+
unavailable. The `round1Responses` array will contain
|
|
103
110
|
entries with `memberId` of `council_generalist`, `council_skeptic`, and
|
|
104
111
|
`council_domain_expert` and `role` of `generalist`, `skeptic`, and
|
|
105
112
|
`domain_expert` respectively. These come from the agents' JSON output; no
|
|
@@ -45,7 +45,7 @@ Produce a SCOPE MAP: list of files, modules, and interfaces within the audit bou
|
|
|
45
45
|
|
|
46
46
|
## Step 3 — Explorer Missions (Parallel Waves)
|
|
47
47
|
|
|
48
|
-
Dispatch explorer waves
|
|
48
|
+
Dispatch explorer waves with `dispatch_lanes_async` when available. Each wave contains up to `max_explorers` missions.
|
|
49
49
|
|
|
50
50
|
**File caps per mission:**
|
|
51
51
|
- 8 files maximum per mission
|
|
@@ -71,7 +71,9 @@ Each explorer mission receives:
|
|
|
71
71
|
- The scope map context from Step 2
|
|
72
72
|
- Instruction: "You are performing a [LANE] audit. Report findings as candidate observations with severity (INFO/LOW/MEDIUM/HIGH/CRITICAL), location, and evidence."
|
|
73
73
|
|
|
74
|
-
Explorer missions are dispatched in parallel waves.
|
|
74
|
+
Explorer missions are dispatched in parallel waves. Launch the wave, record the returned `batch_id`, then continue deterministic architect work that does not depend on lane output: refine the scope map, build the candidate ledger shell, inspect local evidence with read-only tools, and prepare reviewer shard structure. Do not synthesize findings from running lanes.
|
|
75
|
+
|
|
76
|
+
At the Step 4 boundary, call `collect_lane_results` with `wait: true` for every open wave batch. Treat missing, stale, cancelled, or failed lanes as explicit coverage gaps; do not silently proceed past a required lane. If `dispatch_lanes_async` is unavailable, use blocking `dispatch_lanes` or parallel Task calls and record that async advisory lanes were unavailable.
|
|
75
77
|
|
|
76
78
|
Explorers generate CANDIDATE FINDINGS only — they do NOT make verdicts. All findings are unverified until Step 5.
|
|
77
79
|
|
|
@@ -97,8 +97,12 @@ RESEARCH CONTEXT — <subtopic>
|
|
|
97
97
|
|
|
98
98
|
## Step 4 — Parallel Synthesis Workers
|
|
99
99
|
|
|
100
|
-
Dispatch up to `max_researchers` `the active swarm's sme agent` calls
|
|
101
|
-
— one per subtopic
|
|
100
|
+
Dispatch up to `max_researchers` `the active swarm's sme agent` calls with
|
|
101
|
+
`dispatch_lanes_async` when available — one per subtopic. Record the returned
|
|
102
|
+
`batch_id`, then continue architect-owned retrieval quality work that does not
|
|
103
|
+
depend on worker output: tighten the evidence ledger, check source authority,
|
|
104
|
+
prepare reviewer shard structure, and identify unresolved gaps. Do not write final
|
|
105
|
+
claims from running lanes. Each sme dispatch must
|
|
102
106
|
include:
|
|
103
107
|
- `DOMAIN`: the subtopic
|
|
104
108
|
- `TASK`: "Synthesize an evidence-grounded answer for this subtopic. Cite each
|
|
@@ -109,9 +113,13 @@ include:
|
|
|
109
113
|
- `OUTPUT`: claims with evidence refs, contradictions noted, confidence (0–1)
|
|
110
114
|
- `SKILLS: none`
|
|
111
115
|
|
|
112
|
-
The sme synthesizes only from the provided evidence — it does not fetch.
|
|
113
|
-
|
|
114
|
-
|
|
116
|
+
The sme synthesizes only from the provided evidence — it does not fetch. Before
|
|
117
|
+
Step 5, call `collect_lane_results` with `wait: true` for every open synthesis
|
|
118
|
+
batch. Collect all completed worker responses into a candidate findings set, each
|
|
119
|
+
finding tagged with its subtopic, evidence refs, and the worker's confidence.
|
|
120
|
+
Treat missing, stale, cancelled, or failed lanes as explicit coverage gaps. If
|
|
121
|
+
`dispatch_lanes_async` is unavailable, use blocking parallel dispatch and record
|
|
122
|
+
that async advisory lanes were unavailable.
|
|
115
123
|
|
|
116
124
|
## Step 5 — Dual-Reviewer Claim Verification
|
|
117
125
|
|
|
@@ -214,7 +214,7 @@ After `save_plan` succeeds, read `.swarm/context.md`:
|
|
|
214
214
|
- drift_check (default: ON) - mandatory per-phase drift verification at PHASE-WRAP
|
|
215
215
|
- final_council (default: OFF) - when enabled, after all phases complete the architect dispatches the full 5-member council (critic, reviewer, sme, test_engineer, explorer) -- NOT the General Council -- at project scope, collects `CouncilMemberVerdict` objects, and calls `write_final_council_evidence`. This does not require `council.general.enabled`.
|
|
216
216
|
Additionally, present these two sub-items as part of the same exchange:
|
|
217
|
-
- Parallel coders (default: 1, range: 1-4) - how many coders should run in parallel.
|
|
217
|
+
- Parallel coders (default: 1, range: 1-4) - how many coders should run in parallel. Parallel coders each run in an isolated git worktree (separate working dir + branch) and merge back automatically, so they never overwrite each other's files - safe and faster, but only for tasks whose file scopes do NOT overlap. Inspect the plan and recommend a count equal to the number of dependency-ready, file-disjoint task groups (clamped 1-4); recommend 1 (serial) when scopes overlap or are unknown. State your recommendation and reasoning when you ask.
|
|
218
218
|
- Commit frequency (default: phase-level only) - optional per-task checkpoint commit after each task completion.
|
|
219
219
|
The user answers all three (gates, parallel coders, commit frequency) in one exchange. Wait for the user's response.
|
|
220
220
|
If the user says parallel coders > 1, write a `## Pending Parallelization Config` section to `.swarm/context.md` alongside the gate selection:
|
|
@@ -47,7 +47,7 @@ Present the eleven gates with their defaults (DEFAULT_QA_GATES), parallel coder
|
|
|
47
47
|
- final_council (default: OFF) -- when enabled, after all phases complete the architect dispatches the full 5-member council (critic, reviewer, sme, test_engineer, explorer) -- NOT the General Council -- at project scope, collects `CouncilMemberVerdict` objects, and calls `write_final_council_evidence`. This does not require `council.general.enabled`.
|
|
48
48
|
|
|
49
49
|
Additionally, present these three sub-items as part of the same exchange:
|
|
50
|
-
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel.
|
|
50
|
+
- Parallel coders (default: 1, range: 1-4) -- how many coders should run in parallel. Parallel coders each run in an isolated git worktree (separate working dir + branch) and merge back automatically, so they never overwrite each other's files -- safe and faster, but only for tasks whose file scopes do NOT overlap. The per-task file scopes that determine a safe parallel count are not known until the plan is finalized, so default to 1 (serial) here; the precise recommendation is made at plan time once the tasks and their scopes exist.
|
|
51
51
|
- Commit frequency (default: phase-level only) -- optional per-task checkpoint commit after each task completion.
|
|
52
52
|
- auto_proceed (boolean, default: false) -- when true, auto-advance to the next phase without asking "Ready for Phase N+1?"; runtime toggle via /swarm auto-proceed on|off.
|
|
53
53
|
|
|
@@ -142,6 +142,24 @@ Build a complete feedback ledger before editing. Include every available source:
|
|
|
142
142
|
If a source is unavailable, record that limitation. Do not treat missing access as
|
|
143
143
|
evidence that no feedback exists.
|
|
144
144
|
|
|
145
|
+
### Async advisory verification lanes
|
|
146
|
+
|
|
147
|
+
After the complete feedback ledger exists and before editing, use
|
|
148
|
+
`dispatch_lanes_async` when available for independent read-only verification lanes:
|
|
149
|
+
comment classification, CI/log root-cause inspection, test impact mapping,
|
|
150
|
+
release/docs claim checks, and stale-branch/conflict analysis. Record each
|
|
151
|
+
returned `batch_id`, then continue only ledger-safe architect work: normalize
|
|
152
|
+
feedback IDs, gather deterministic PR metadata, prepare reproduction commands,
|
|
153
|
+
and plan likely fix groups. Do not edit, close items, or mark feedback resolved
|
|
154
|
+
from running lanes.
|
|
155
|
+
|
|
156
|
+
Before the Verification step can mark any item `RESOLVED`, `DISPROVED`,
|
|
157
|
+
`PRE_EXISTING`, `NEEDS_MORE_EVIDENCE`, or `NEEDS_USER_DECISION`, call
|
|
158
|
+
`collect_lane_results` with `wait: true` for every open verification batch.
|
|
159
|
+
Missing, stale, cancelled, or failed lanes remain explicit ledger limitations.
|
|
160
|
+
If `dispatch_lanes_async` is unavailable, use blocking verification and record
|
|
161
|
+
that async advisory lanes were unavailable.
|
|
162
|
+
|
|
145
163
|
### CI matrix cascade check (do this before fixing)
|
|
146
164
|
|
|
147
165
|
When the PR's `unit` job is a matrix across multiple OSes and downstream jobs
|
|
@@ -468,11 +468,11 @@ Tool candidate rules:
|
|
|
468
468
|
|
|
469
469
|
## Phase 3: Parallel Base Explorer Lanes
|
|
470
470
|
|
|
471
|
-
Launch all base lanes with
|
|
471
|
+
Launch all base lanes with `dispatch_lanes_async` when available. Pass the six lane specs together, set `max_concurrent` to `6`, record the returned `batch_id`, and continue only non-dependent architect work: refine the obligation ledger, inspect PR metadata, prepare micro-lane trigger checks, and run deterministic read-only local tools. Do not synthesize findings from running lanes.
|
|
472
472
|
|
|
473
|
-
If `
|
|
473
|
+
Before Phase 4 or synthesis, call `collect_lane_results` with `wait: true` for the base-lane batch and treat the collected `lane_results` as the join barrier. Missing, stale, cancelled, or failed base lanes are explicit review coverage gaps. If `dispatch_lanes_async` is unavailable, use blocking `dispatch_lanes`; if that is also unavailable, simulate isolated passes. Do not let one lane's conclusions bias another lane, and record unavailable deterministic dispatch in the validation gate.
|
|
474
474
|
|
|
475
|
-
**lane id uniqueness for parallel dispatches:** When re-dispatching failed or re-running explorer lanes, every `dispatch_lanes` lane `id` MUST be unique within that dispatch batch and should include lane and attempt suffixes (e.g. `pr_review_explore_lane1_attempt2`). Never reuse an id in the same batch unless intentionally replacing that exact lane before dispatch.
|
|
475
|
+
**lane id uniqueness for parallel dispatches:** When re-dispatching failed or re-running explorer lanes, every `dispatch_lanes_async` or `dispatch_lanes` lane `id` MUST be unique within that dispatch batch and should include lane and attempt suffixes (e.g. `pr_review_explore_lane1_attempt2`). Never reuse an id in the same batch unless intentionally replacing that exact lane before dispatch.
|
|
476
476
|
|
|
477
477
|
Explorers optimize for recall. Over-reporting is expected. Explorers produce candidates only.
|
|
478
478
|
|
|
@@ -510,7 +510,7 @@ Explorers must not use `CONFIRMED`, `DISPROVED`, or `PRE_EXISTING`.
|
|
|
510
510
|
|
|
511
511
|
## Phase 4: Triggered Swarm Plugin Micro-Lanes
|
|
512
512
|
|
|
513
|
-
After `
|
|
513
|
+
After `collect_lane_results` returns for base lanes, inspect the context pack risk triggers. Launch focused micro-lanes for triggered categories only, using `dispatch_lanes_async` again when more than one read-only micro-lane is needed. Collect every micro-lane batch with `wait: true` before reviewer classification. Do not launch irrelevant micro-lanes.
|
|
514
514
|
|
|
515
515
|
Each micro-lane receives:
|
|
516
516
|
|
|
@@ -793,7 +793,7 @@ Council mode is opt-in only and adversarial.
|
|
|
793
793
|
When triggered:
|
|
794
794
|
|
|
795
795
|
1. Build the same context pack as default mode.
|
|
796
|
-
2. Launch all council agents with one `
|
|
796
|
+
2. Launch all council agents with one `dispatch_lanes_async` call when available; continue only non-dependent context preparation while they run, then use `collect_lane_results` with `wait: true` as the join barrier before reviewer classification. Fall back to blocking `dispatch_lanes` when async launch is unavailable.
|
|
797
797
|
3. Each council agent assumes all work is wrong until code evidence proves otherwise.
|
|
798
798
|
4. Each agent hunts within its lane only.
|
|
799
799
|
5. Agents return evidence states only: `EVIDENCE_FOUND`, `SUSPICIOUS`, or `CLEAN`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Background subagent completion
|
|
2
|
+
* Background subagent completion observer/ingester.
|
|
3
3
|
*
|
|
4
4
|
* Registers as a swarm `event` hook to watch for the upstream background-completion signal:
|
|
5
5
|
* a message part with `synthetic === true` whose text is a task envelope with
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* background-delegation record, it is logged (debug-gated) as the empirical confirmation
|
|
8
8
|
* instrument operators use to verify the runtime signal in a real environment.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* PR1 async advisory lanes ingest trusted terminal completions into the durable
|
|
11
|
+
* background-delegation ledger only. This still NEVER advances workflow gates or records
|
|
12
|
+
* gate evidence; gate-bearing execution is intentionally outside this advisory path.
|
|
13
13
|
*
|
|
14
14
|
* The `synthetic` flag is the trust gate (set by OpenCode, not the model/user). Non-synthetic
|
|
15
15
|
* text that merely looks like an envelope is ignored. The observer is fail-open: any error is
|
|
@@ -19,7 +19,7 @@ interface ObserverConfig {
|
|
|
19
19
|
enabled: boolean;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Build the
|
|
22
|
+
* Build the background completion observer. Returns an `event` handler suitable for the
|
|
23
23
|
* OpenCode plugin `event` hook. No-op (cheap early return) when the feature is disabled.
|
|
24
24
|
*/
|
|
25
25
|
export declare function createBackgroundCompletionObserver(opts: {
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Append-only JSONL event log under project-root `.swarm/background-delegations.jsonl`.
|
|
5
5
|
* Each line is a full record snapshot; readers fold to the latest snapshot per
|
|
6
|
-
* `correlationId`. This tracks background
|
|
7
|
-
* trusted
|
|
8
|
-
* number of permanently-running
|
|
9
|
-
* the folded in-memory view stays bounded by distinct correlationIds.
|
|
10
|
-
* log itself is append-only and is NOT compacted
|
|
11
|
-
* fixed number of lines
|
|
6
|
+
* `correlationId`. This tracks native background `Task` dispatches and deterministic
|
|
7
|
+
* async advisory lanes so trusted completions can be correlated to a real dispatch.
|
|
8
|
+
* The stale sweep bounds the number of permanently-running entries by transitioning
|
|
9
|
+
* them to `stale`, so the folded in-memory view stays bounded by distinct correlationIds.
|
|
10
|
+
* The on-disk log itself is append-only and is NOT compacted; each dispatch leaves a
|
|
11
|
+
* small, fixed number of lines.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Scope: dispatch records `pending`/`running` snapshots, collection or trusted synthetic
|
|
14
|
+
* completions record terminal snapshots, and the stale sweep records `stale` snapshots.
|
|
15
|
+
* This store still has NO gate advancement and NO gate evidence side effect; it is an
|
|
16
|
+
* advisory result ledger only.
|
|
17
17
|
*
|
|
18
18
|
* Concurrency: all writes (append, sweep) run under a single project-scoped lock via
|
|
19
19
|
* `withEvidenceLock`, so concurrent dispatches/sweeps cannot interleave appends. Reads are
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
* `.swarm/` (Invariant 4).
|
|
24
24
|
*/
|
|
25
25
|
export declare const BACKGROUND_DELEGATIONS_FILE = "background-delegations.jsonl";
|
|
26
|
-
export type BackgroundDelegationStatus = 'pending' | 'completed' | 'error' | 'stale';
|
|
26
|
+
export type BackgroundDelegationStatus = 'pending' | 'running' | 'completed' | 'error' | 'cancelled' | 'stale' | 'consumed';
|
|
27
27
|
export interface BackgroundDelegationRecord {
|
|
28
|
-
schemaVersion: 1;
|
|
28
|
+
schemaVersion: 1 | 2;
|
|
29
29
|
/** Subagent session id from the dispatch envelope — the correlation key. */
|
|
30
30
|
correlationId: string;
|
|
31
31
|
/** Structured jobId from dispatch metadata when available, else null. */
|
|
@@ -46,6 +46,33 @@ export interface BackgroundDelegationRecord {
|
|
|
46
46
|
status: BackgroundDelegationStatus;
|
|
47
47
|
createdAt: number;
|
|
48
48
|
updatedAt: number;
|
|
49
|
+
/** Async advisory lane batch id. Present for dispatch_lanes_async records. */
|
|
50
|
+
batchId?: string;
|
|
51
|
+
/** Stable lane id within batchId. */
|
|
52
|
+
laneId?: string;
|
|
53
|
+
/** Advisory workflow/mode that launched the lane. */
|
|
54
|
+
mode?: string;
|
|
55
|
+
/** Canonical hash of prompt/provenance inputs captured at dispatch time. */
|
|
56
|
+
promptHash?: string;
|
|
57
|
+
/** Project/root provenance captured at dispatch time. */
|
|
58
|
+
workspace?: BackgroundWorkspaceSnapshot;
|
|
59
|
+
generation?: number;
|
|
60
|
+
result?: BackgroundDelegationResult;
|
|
61
|
+
completedAt?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface BackgroundWorkspaceSnapshot {
|
|
64
|
+
directory: string;
|
|
65
|
+
gitHead: string | null;
|
|
66
|
+
dirtyHash: string | null;
|
|
67
|
+
prHeadSha: string | null;
|
|
68
|
+
scope: string | null;
|
|
69
|
+
}
|
|
70
|
+
export interface BackgroundDelegationResult {
|
|
71
|
+
text?: string;
|
|
72
|
+
error?: string;
|
|
73
|
+
chars: number;
|
|
74
|
+
truncated: boolean;
|
|
75
|
+
digest: string;
|
|
49
76
|
}
|
|
50
77
|
/**
|
|
51
78
|
* Read and fold the store to the latest snapshot per correlationId. Lock-free and
|
|
@@ -53,10 +80,8 @@ export interface BackgroundDelegationRecord {
|
|
|
53
80
|
* (never throws). Records are returned in first-seen correlationId order.
|
|
54
81
|
*
|
|
55
82
|
* Cost: O(lines on disk) per call — a full read + parse + fold with no in-memory cache.
|
|
56
|
-
* This is intentionally simple and acceptable at
|
|
57
|
-
* background delegations, and the on-disk log is small).
|
|
58
|
-
* background load ever makes this hot, a future stage should add a stat-invalidated in-memory
|
|
59
|
-
* cache and/or JSONL compaction (the same future-compaction work noted in the module header).
|
|
83
|
+
* This is intentionally simple and acceptable at advisory-lane volumes (a swarm has few
|
|
84
|
+
* concurrent background delegations, and the on-disk log is small).
|
|
60
85
|
*/
|
|
61
86
|
export declare function readDelegations(directory: string): BackgroundDelegationRecord[];
|
|
62
87
|
/** Returns the folded record for a correlationId, or null. Lock-free read. */
|
|
@@ -71,16 +96,32 @@ export interface RecordPendingInput {
|
|
|
71
96
|
swarmPrefixedAgent: string;
|
|
72
97
|
planTaskId: string | null;
|
|
73
98
|
evidenceTaskId: string | null;
|
|
99
|
+
batchId?: string;
|
|
100
|
+
laneId?: string;
|
|
101
|
+
mode?: string;
|
|
102
|
+
promptHash?: string;
|
|
103
|
+
workspace?: BackgroundWorkspaceSnapshot;
|
|
104
|
+
generation?: number;
|
|
74
105
|
}
|
|
75
106
|
/**
|
|
76
107
|
* Record a `pending` background delegation. Runs the stale sweep first (lazy maintenance,
|
|
77
108
|
* no plugin-init cost), then appends the pending snapshot — all under one lock acquisition
|
|
78
109
|
* so concurrent dispatches cannot interleave. Best-effort: returns null on lock timeout or
|
|
79
|
-
* write failure
|
|
110
|
+
* write failure. Async advisory launchers must treat null as a launch failure so they do
|
|
111
|
+
* not create untracked background work.
|
|
80
112
|
*/
|
|
81
113
|
export declare function recordPendingDelegation(directory: string, input: RecordPendingInput, options?: {
|
|
82
114
|
staleTimeoutMs?: number;
|
|
83
115
|
}): Promise<BackgroundDelegationRecord | null>;
|
|
116
|
+
export declare function appendDelegationTransition(directory: string, correlationId: string, transition: {
|
|
117
|
+
status: BackgroundDelegationStatus;
|
|
118
|
+
result?: BackgroundDelegationResult;
|
|
119
|
+
completedAt?: number;
|
|
120
|
+
}): Promise<BackgroundDelegationRecord | null>;
|
|
121
|
+
export declare function findByBatchId(directory: string, batchId: string, opts?: {
|
|
122
|
+
parentSessionId?: string;
|
|
123
|
+
}): BackgroundDelegationRecord[];
|
|
124
|
+
export declare function findOpenAsyncLaneBatches(directory: string): BackgroundDelegationRecord[];
|
|
84
125
|
/**
|
|
85
126
|
* Public stale sweep: acquires the store lock and marks overdue pendings as `stale`.
|
|
86
127
|
* Best-effort; returns the number swept (0 on lock timeout / error).
|
|
@@ -21,6 +21,11 @@ export interface TaskEnvelope {
|
|
|
21
21
|
/** The subagent session id from `<task id="...">` — the cross-event correlation key. */
|
|
22
22
|
sessionId: string;
|
|
23
23
|
state: TaskEnvelopeState;
|
|
24
|
+
summary?: string;
|
|
25
|
+
resultText?: string;
|
|
26
|
+
errorText?: string;
|
|
27
|
+
resultChars?: number;
|
|
28
|
+
resultTruncated?: boolean;
|
|
24
29
|
}
|
|
25
30
|
/**
|
|
26
31
|
* Parse a task envelope from arbitrary text. Returns null when the text does not contain
|