@chllming/wave-orchestration 0.9.10 → 0.9.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +7 -8
  3. package/docs/README.md +4 -10
  4. package/docs/architecture/README.md +12 -4
  5. package/docs/concepts/operating-modes.md +1 -1
  6. package/docs/guides/author-and-run-waves.md +3 -2
  7. package/docs/guides/planner.md +3 -3
  8. package/docs/guides/recommendations-0.9.11.md +44 -0
  9. package/docs/guides/recommendations-0.9.12.md +49 -0
  10. package/docs/guides/sandboxed-environments.md +2 -2
  11. package/docs/guides/terminal-surfaces.md +1 -1
  12. package/docs/plans/current-state.md +3 -3
  13. package/docs/plans/end-state-architecture.md +1 -1
  14. package/docs/plans/examples/wave-example-design-handoff.md +1 -1
  15. package/docs/plans/examples/wave-example-live-proof.md +1 -1
  16. package/docs/plans/migration.md +32 -28
  17. package/docs/plans/wave-orchestrator.md +1 -1
  18. package/docs/reference/cli-reference.md +2 -2
  19. package/docs/reference/coordination-and-closure.md +1 -1
  20. package/docs/reference/npmjs-token-publishing.md +2 -2
  21. package/docs/reference/package-publishing-flow.md +12 -12
  22. package/docs/reference/runtime-config/README.md +2 -2
  23. package/docs/reference/sample-waves.md +5 -5
  24. package/docs/reference/skills.md +1 -1
  25. package/docs/reference/wave-control.md +3 -1
  26. package/docs/roadmap.md +3 -3
  27. package/package.json +1 -1
  28. package/releases/manifest.json +32 -0
  29. package/scripts/wave-orchestrator/agent-state.mjs +3 -1
  30. package/scripts/wave-orchestrator/autonomous.mjs +2 -2
  31. package/scripts/wave-orchestrator/closure-engine.mjs +103 -6
  32. package/scripts/wave-orchestrator/closure-policy.mjs +319 -0
  33. package/scripts/wave-orchestrator/config.mjs +15 -0
  34. package/scripts/wave-orchestrator/derived-state-engine.mjs +52 -4
  35. package/scripts/wave-orchestrator/gate-engine.mjs +72 -4
  36. package/scripts/wave-orchestrator/install.mjs +1 -1
  37. package/scripts/wave-orchestrator/launcher.mjs +14 -4
  38. package/scripts/wave-orchestrator/planner.mjs +4 -3
  39. package/scripts/wave-orchestrator/shared.mjs +11 -12
  40. package/scripts/wave-orchestrator/swe-bench-pro-task.mjs +1 -1
  41. package/scripts/wave-orchestrator/traces.mjs +22 -1
  42. package/wave.config.json +13 -2
@@ -2,7 +2,7 @@
2
2
 
3
3
  This repo now includes a dedicated npmjs publish workflow at [publish-npm.yml](../../.github/workflows/publish-npm.yml).
4
4
 
5
- The current `0.9.2` release procedure publishes through a repository Actions secret named `NPM_TOKEN`.
5
+ The current `0.9.12` release procedure publishes through a repository Actions secret named `NPM_TOKEN`.
6
6
 
7
7
  ## What This Repo Already Does
8
8
 
@@ -48,6 +48,6 @@ If this repo later needs private npm dependencies during CI, consider a separate
48
48
  2. Confirm `NPM_TOKEN` exists in the GitHub repo secrets.
49
49
  3. Confirm the package version has been bumped and committed.
50
50
  4. Confirm `README.md`, `CHANGELOG.md`, `releases/manifest.json`, and `docs/plans/migration.md` all describe the same release surface.
51
- 5. Push the release commit and release tag, for example `v0.9.2`.
51
+ 5. Push the release commit and release tag, for example `v0.9.12`.
52
52
  6. Verify both `publish-npm.yml` and `publish-package.yml` start from the tag push.
53
53
  7. Verify the npmjs publish completes successfully for the tagged source.
@@ -15,7 +15,7 @@ Release preparation happens in the repository itself:
15
15
  - update release-surface docs and fixtures
16
16
  - validate the repo
17
17
  - merge the release changes to `main`
18
- - push a version tag such as `v0.9.2`
18
+ - push a version tag such as `v0.9.12`
19
19
 
20
20
  Registry publishing happens in GitHub Actions after the tag push:
21
21
 
@@ -122,14 +122,14 @@ In this source repo, `.wave/install-state.json` and tracked `.wave/upgrade-histo
122
122
 
123
123
  ### 2. Merge the release change to `main`
124
124
 
125
- This repository protects `main`, so release changes must land through a pull request rather than a direct push.
125
+ This repository normally protects `main`, so release changes should land through a pull request unless the repo policy has been intentionally relaxed for a one-off release cut.
126
126
 
127
127
  Typical git flow:
128
128
 
129
129
  ```bash
130
- git checkout -b release/0.9.2
131
- git push -u origin release/0.9.2
132
- gh pr create --base main --head release/0.9.2
130
+ git checkout -b release/0.9.12
131
+ git push -u origin release/0.9.12
132
+ gh pr create --base main --head release/0.9.12
133
133
  gh pr merge <pr-number> --merge --delete-branch
134
134
  ```
135
135
 
@@ -138,13 +138,13 @@ gh pr merge <pr-number> --merge --delete-branch
138
138
  After the release commit is on `main`, push the version tag:
139
139
 
140
140
  ```bash
141
- git tag v0.9.2
142
- git push origin v0.9.2
141
+ git tag v0.9.12
142
+ git push origin v0.9.12
143
143
  ```
144
144
 
145
145
  That tag push is the event that starts both publishing workflows.
146
146
 
147
- The tag must match the checked-in package version exactly. Example: if `package.json.version` is `0.9.2`, the pushed tag must be `v0.9.2`.
147
+ The tag must match the checked-in package version exactly. Example: if `package.json.version` is `0.9.12`, the pushed tag must be `v0.9.12`.
148
148
 
149
149
  ## GitHub Actions Workflows
150
150
 
@@ -212,9 +212,9 @@ Expected result after a successful publish:
212
212
 
213
213
  ```json
214
214
  {
215
- "version": "0.9.2",
215
+ "version": "0.9.12",
216
216
  "dist-tags": {
217
- "latest": "0.9.2"
217
+ "latest": "0.9.12"
218
218
  }
219
219
  }
220
220
  ```
@@ -231,8 +231,8 @@ If a tag-triggered publish fails before the package is actually published, the f
231
231
  Example:
232
232
 
233
233
  ```bash
234
- git tag -f v0.9.2 <fixed-commit>
235
- git push origin refs/tags/v0.9.2 --force
234
+ git tag -f v0.9.12 <fixed-commit>
235
+ git push origin refs/tags/v0.9.12 --force
236
236
  ```
237
237
 
238
238
  Use that only before the package is live on npmjs. Once npmjs has accepted a version, do not try to republish the same version; cut a new version instead.
@@ -191,7 +191,7 @@ Practical guidance:
191
191
  - prefer `budget.minutes` for normal synthesis, integration, and closure work
192
192
  - use generic `budget.turns` as a planning hint, not a hard failure trigger
193
193
  - only set `claude.maxTurns` or `opencode.steps` when you deliberately want a hard ceiling for that runtime
194
- - see [../../guides/recommendations-0.9.3.md](../../guides/recommendations-0.9.3.md) for the recommended `0.9.3` operating stance that combines advisory turn budgets with softer non-proof coordination states
194
+ - see [../../guides/recommendations-0.9.12.md](../../guides/recommendations-0.9.12.md) for the recommended `0.9.12` operating stance that combines advisory turn budgets with softer non-proof coordination states, targeted recovery, and optional TMUX operator surfaces
195
195
 
196
196
  ## Runtime Pages
197
197
 
@@ -203,7 +203,7 @@ Practical guidance:
203
203
 
204
204
  `wave.config.json` may also declare a `waveControl` block for local-first telemetry delivery.
205
205
 
206
- Packaged defaults in `@chllming/wave-orchestration@0.9.3`:
206
+ Packaged defaults in `@chllming/wave-orchestration@0.9.12`:
207
207
 
208
208
  - `endpoint`: `https://wave-control.up.railway.app/api/v1`
209
209
  - `reportMode`: `metadata-only`
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: "Sample Waves"
3
- summary: "Showcase-first sample waves that demonstrate the shipped 0.9.2 authored surface, including the optional design-role path."
3
+ summary: "Showcase-first sample waves that demonstrate the shipped 0.9.12 authored surface, including the optional design-role path."
4
4
  ---
5
5
 
6
6
  # Sample Waves
7
7
 
8
- This guide points to showcase-first sample waves that demonstrate the shipped `0.9.2` authored Wave surface.
8
+ This guide points to showcase-first sample waves that demonstrate the shipped `0.9.12` authored Wave surface.
9
9
 
10
10
  The examples are intentionally denser than typical production waves. Their job is to teach the current authoring and runtime surface quickly, not to be the smallest possible launch-ready files.
11
11
 
@@ -17,7 +17,7 @@ All example `.tmp/main-wave-launcher/...` paths assume the implicit default proj
17
17
  Shows what a good `repo-landed` outcome looks like when one promoted component only closes honestly if desired-state records, reconcile-loop substrate, and cluster-view surfaces land together. It emphasizes maturity discipline, explicit deliverables, and shared-plan closure without drifting into `pilot-live` claims.
18
18
 
19
19
  - [Full modern sample wave](../plans/examples/wave-example-live-proof.md)
20
- Shows the combined `0.9.2` authored surface in one file: closure roles, `E0`, optional security review, delegated and pinned benchmark targets, richer executor config, `### Skills`, `### Capabilities`, `### Deliverables`, `### Exit contract`, `### Proof artifacts`, sticky retry, deploy environments, and proof-first live-wave structure.
20
+ Shows the combined `0.9.12` authored surface in one file: closure roles, `E0`, optional security review, delegated and pinned benchmark targets, richer executor config, `### Skills`, `### Capabilities`, `### Deliverables`, `### Exit contract`, `### Proof artifacts`, sticky retry, deploy environments, and proof-first live-wave structure.
21
21
 
22
22
  - [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md)
23
23
  Shows the shipped design-role surface: one pre-implementation design steward publishes a design packet, downstream implementation owners read that packet before coding, and normal closure roles still decide final completion. For terminal or operator-surface work, pair that shape with explicit `tui-design` in the design steward's `### Skills`. For the hybrid variant, explicitly give that same design agent implementation-owned paths and the normal implementation contract sections.
@@ -46,7 +46,7 @@ All example `.tmp/main-wave-launcher/...` paths assume the implicit default proj
46
46
 
47
47
  ## Feature Coverage Map
48
48
 
49
- Together these samples cover the main surfaces added or hardened through `0.9.2`:
49
+ Together these samples cover the main surfaces added or hardened through `0.9.12`:
50
50
 
51
51
  - repo-landed maturity discipline and anti-overclaim framing
52
52
  - explicit shared-plan closure for future-wave safety
@@ -184,7 +184,7 @@ Adapt more aggressively when:
184
184
  ## Suggested Reading Order
185
185
 
186
186
  1. Start with [High-fidelity repo-landed rollout wave](../plans/examples/wave-example-rollout-fidelity.md) if you want the clearest example of good closure-ready wave fidelity for a repo-only outcome.
187
- 2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy `0.9.2` surface.
187
+ 2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy `0.9.12` surface.
188
188
  3. Read [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md) if the task needs a design packet before implementation fan-out.
189
189
  4. Read [docs/evals/README.md](../evals/README.md) if you want more background on benchmark target selection.
190
190
  5. Read [docs/reference/live-proof-waves.md](./live-proof-waves.md) if you want more detail on proof-first `pilot-live` authoring.
@@ -124,7 +124,7 @@ Top-level and lane-local skill attachment use the same shape:
124
124
 
125
125
  Lane-local `lanes.<lane>.skills` extends the global config instead of replacing it.
126
126
 
127
- Optional design workers in the shipped `0.9.2` surface normally attach `role-design`. That bundle is intended for docs/spec-first design packets and explicit implementation handoff work before implementation starts. When the design packet covers terminal UX, dashboards, or other operator surfaces, add `tui-design` explicitly in the wave's `### Skills`.
127
+ Optional design workers in the shipped `0.9.12` surface normally attach `role-design`. That bundle is intended for docs/spec-first design packets and explicit implementation handoff work before implementation starts. When the design packet covers terminal UX, dashboards, or other operator surfaces, add `tui-design` explicitly in the wave's `### Skills`.
128
128
 
129
129
  Long-running agents that should stay resident and react only to orchestrator signal changes can add `signal-hygiene` explicitly in `### Skills`. That bundle is not auto-attached and is not meant for normal one-shot implementation agents.
130
130
 
@@ -23,7 +23,7 @@ That packaged endpoint is for the default metadata-reporting surface. The owned-
23
23
 
24
24
  ### Packaged Default Endpoint
25
25
 
26
- This is the release default in `@chllming/wave-orchestration@0.9.2`.
26
+ This is the release default in `@chllming/wave-orchestration@0.9.12`.
27
27
 
28
28
  - receives local-first telemetry uploads
29
29
  - supports normal run and benchmark query surfaces
@@ -44,6 +44,8 @@ An owned deployment can add:
44
44
  - broker routes for Context7 and Corridor
45
45
  - provider env leasing for deployment-owned OpenAI and Anthropic credentials
46
46
 
47
+ The packaged browser UI now defaults to a dashboard-first information architecture with `Dashboard`, `Operations`, `Access`, and `Account` views. The goal is to put operator triage first, then let deeper run, benchmark, token, and access-management screens hang off that navigation instead of treating every surface as a flat peer tab.
48
+
47
49
  ## What Gets Reported
48
50
 
49
51
  Wave Control normalizes these entity types:
package/docs/roadmap.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  This roadmap is intentionally short and current. The older planner-foundation and ad-hoc-run phase list has been removed because that work no longer describes the actual shipping direction for this package.
4
4
 
5
- ## Current Release: 0.9.2
5
+ ## Current Release: 0.9.12
6
6
 
7
- `0.9.2` is the current packaged surface.
7
+ `0.9.12` is the current packaged surface.
8
8
 
9
9
  It includes:
10
10
 
@@ -56,6 +56,6 @@ That line is expected to carry:
56
56
 
57
57
  For this repository, the practical sequence is:
58
58
 
59
- 1. Ship `0.9.2` with the sandbox/runtime hardening and aligned docs.
59
+ 1. Ship `0.9.12` with the closure, operator-surface, and release-doc alignment fixes.
60
60
  2. Maintain this Node package for bug fixes, compatibility, operational hardening, and release-surface sync rather than a broad new feature wave.
61
61
  3. Move long-term execution investment to the LEAPclaw + Go + Temporal architecture and the Rust standalone runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chllming/wave-orchestration",
3
- "version": "0.9.10",
3
+ "version": "0.9.12",
4
4
  "license": "MIT",
5
5
  "description": "Generic wave-based multi-agent orchestration for repository work.",
6
6
  "repository": {
@@ -2,6 +2,38 @@
2
2
  "schemaVersion": 1,
3
3
  "packageName": "@chllming/wave-orchestration",
4
4
  "releases": [
5
+ {
6
+ "version": "0.9.12",
7
+ "date": "2026-04-08",
8
+ "summary": "Hybrid closure fast-path fixes, optional-TMUX release-surface cleanup, and a dashboard-first Wave Control UI refresh.",
9
+ "features": [
10
+ "Bootstrap closure now keeps the low-entropy fast path only for genuinely lightweight closure attempts; missing `cont-QA` runs are no longer silently skipped after semantic closure work already ran.",
11
+ "`closureModeThresholds.bootstrap` now participates in runtime mode resolution, and derived closure-complexity metadata now includes clarification, dependency, helper-assignment, and contradiction barriers.",
12
+ "Planner setup, launcher help, autonomous help, runbooks, and canned commands now describe TMUX consistently as an optional dashboard/projection layer instead of a required execution backend.",
13
+ "The `wave-control-web` browser surface now uses dashboard-first navigation with clearer `Dashboard`, `Operations`, `Access`, and `Account` views plus richer run and benchmark analytics summaries.",
14
+ "The shipped versioned operating guide is now `docs/guides/recommendations-0.9.12.md`, and release docs, migration guidance, runtime-config docs, package-publishing docs, tracked install-state fixtures, and the release manifest now all point at the same `0.9.12` surface.",
15
+ "Planner migration guidance and the `planner-agentic` bundle placeholder remain part of the shipped current-surface docs so adopted repos still have one aligned upgrade target."
16
+ ],
17
+ "manualSteps": [
18
+ "Run `pnpm exec wave doctor --json` and `pnpm exec wave launch --lane main --dry-run --no-dashboard` after upgrading so the repo validates against the `0.9.12` release surface.",
19
+ "If your repo copied starter docs or runbooks, sync `README.md`, `docs/README.md`, `docs/plans/current-state.md`, `docs/plans/migration.md`, `docs/reference/coordination-and-closure.md`, `docs/reference/runtime-config/README.md`, `docs/reference/wave-control.md`, `docs/reference/package-publishing-flow.md`, and `docs/guides/recommendations-0.9.12.md` so local guidance matches the packaged release.",
20
+ "If your repo copied terminal-surface guidance or shell helpers, update any local wording that still treats TMUX as mandatory for live execution."
21
+ ],
22
+ "breaking": false
23
+ },
24
+ {
25
+ "version": "0.9.11",
26
+ "date": "2026-04-07",
27
+ "summary": "Cont-QA verdict parsing fix, log-first verdict authority, and sticky integration closure.",
28
+ "features": [
29
+ "`parseVerdictFromText()` now returns the first regex match instead of the last, fixing retry loops caused by stale `Verdict: BLOCKED` lines lingering in append-only cont-QA reports.",
30
+ "`buildAgentExecutionSummary()` now prefers the log-based `[wave-verdict]` marker over the report-file `Verdict:` line when both are present.",
31
+ "Integration closure now respects an explicit A8 `ready-for-doc-closure` sign-off with zero blockers instead of re-injecting synthesized proof/doc gaps on the next derived-state refresh.",
32
+ "Planner migration guidance and the `planner-agentic` bundle placeholder remain part of the shipped current-surface docs so adopted repos still have one aligned upgrade target."
33
+ ],
34
+ "manualSteps": [],
35
+ "breaking": false
36
+ },
5
37
  {
6
38
  "version": "0.9.10",
7
39
  "date": "2026-04-07",
@@ -509,7 +509,9 @@ export function buildAgentExecutionSummary({ agent, statusRecord, logPath, repor
509
509
  : "";
510
510
  const reportVerdict = parseVerdictFromText(reportText, REPORT_VERDICT_REGEX);
511
511
  const logVerdict = parseVerdictFromText(signalText, WAVE_VERDICT_REGEX);
512
- const verdict = reportVerdict.verdict ? reportVerdict : logVerdict;
512
+ // Prefer log verdict (authoritative for the current run) over report verdict
513
+ // (may accumulate stale entries across retries in append-only report files).
514
+ const verdict = logVerdict.verdict ? logVerdict : reportVerdict;
513
515
  const termination = detectTermination(agent, logText, statusRecord);
514
516
  return {
515
517
  agentId: agent?.agentId || null,
@@ -62,8 +62,8 @@ Options:
62
62
  --resident-orchestrator Launch a resident orchestrator session for each live wave
63
63
  --executor <mode> Default executor passed to launcher: ${AUTONOMOUS_EXECUTOR_MODES.join(" | ")} (default: lane config)
64
64
  --codex-sandbox <mode> Codex sandbox mode override passed to launcher (default: lane config)
65
- --dashboard Enable dashboards (default: disabled)
66
- --keep-sessions Keep tmux sessions between waves
65
+ --dashboard Enable dashboard projection sessions (default: disabled)
66
+ --keep-sessions Keep tmux dashboard/projection sessions between waves
67
67
  --keep-terminals Keep temporary terminal entries between waves
68
68
  `);
69
69
  }
@@ -24,6 +24,10 @@ import {
24
24
  resolveWaveRoleBindings,
25
25
  } from "./role-helpers.mjs";
26
26
  import { summarizeResolvedSkills } from "./skills.mjs";
27
+ import {
28
+ resolveClosureMode as resolveClosurePolicyMode,
29
+ resolveClosurePolicyConfig,
30
+ } from "./closure-policy.mjs";
27
31
 
28
32
  function failureResultFromGate(gate, fallbackLogPath) {
29
33
  return {
@@ -134,6 +138,30 @@ function missingClosureRunGate(stage) {
134
138
  };
135
139
  }
136
140
 
141
+ function shouldEvaluateStageBeforeLaunch(stage) {
142
+ return stage.key === "integration" || stage.key === "documentation";
143
+ }
144
+
145
+ function shouldSkipContQaStage({
146
+ stage,
147
+ wave,
148
+ lanePaths,
149
+ semanticClosureStagesRan,
150
+ }) {
151
+ if (stage.key !== "cont-qa" || semanticClosureStagesRan) {
152
+ return false;
153
+ }
154
+ const closurePolicy = resolveClosurePolicyConfig(lanePaths);
155
+ if (!closurePolicy.autoClosure.allowSkipContQaInBootstrap) {
156
+ return false;
157
+ }
158
+ const closureMode = resolveClosurePolicyMode(
159
+ wave.wave,
160
+ closurePolicy.closureModeThresholds,
161
+ );
162
+ return closureMode === "bootstrap";
163
+ }
164
+
137
165
  export async function runClosureSweepPhase({
138
166
  lanePaths,
139
167
  wave,
@@ -195,9 +223,58 @@ export async function runClosureSweepPhase({
195
223
  resolveWaveRoleBindings(wave, lanePaths);
196
224
  const _gateThresholds = lanePaths?.gateModeThresholds || lanePaths?.validation?.gateModeThresholds || options?.gateModeThresholds || null;
197
225
  const _resolvedGateMode = resolveGateMode(wave.wave, _gateThresholds);
226
+ let semanticClosureStagesRan = false;
198
227
  for (const [stageIndex, stage] of stagedRuns.entries()) {
228
+ const currentDerivedState = refreshDerivedState?.(dashboardState?.attempt || 0) || null;
229
+ if (shouldEvaluateStageBeforeLaunch(stage)) {
230
+ const preLaunchGate = evaluateClosureStage({
231
+ stage,
232
+ wave,
233
+ closureRuns,
234
+ lanePaths,
235
+ dashboardState,
236
+ derivedState: currentDerivedState,
237
+ refreshDerivedState,
238
+ readWaveContEvalGateFn: readContEvalGate,
239
+ readWaveSecurityGateFn: readSecurityGate,
240
+ readWaveIntegrationBarrierFn: readIntegrationBarrier,
241
+ readWaveDocumentationGateFn: readDocumentationGate,
242
+ readWaveComponentMatrixGateFn: readComponentMatrixGate,
243
+ readWaveContQaGateFn: readContQaGate,
244
+ contEvalAgentId,
245
+ integrationAgentId,
246
+ documentationAgentId,
247
+ contQaAgentId,
248
+ });
249
+ const autoSatisfiedStage =
250
+ preLaunchGate.ok &&
251
+ !preLaunchGate.agentId &&
252
+ (preLaunchGate.integrationState || preLaunchGate.docClosureState);
253
+ if (autoSatisfiedStage) {
254
+ recordCombinedEvent({
255
+ agentId: stage.agentId || null,
256
+ message: `${stage.label} already satisfied before launch: ${preLaunchGate.detail}`,
257
+ });
258
+ continue;
259
+ }
260
+ }
261
+ if (
262
+ shouldSkipContQaStage({
263
+ stage,
264
+ wave,
265
+ lanePaths,
266
+ semanticClosureStagesRan,
267
+ })
268
+ ) {
269
+ recordCombinedEvent({
270
+ agentId: stage.agentId || null,
271
+ message:
272
+ "cont-QA gate skipped in bootstrap because closure remained on the low-entropy fast path.",
273
+ });
274
+ continue;
275
+ }
199
276
  if (stage.runs.length === 0) {
200
- if (_resolvedGateMode === "bootstrap") {
277
+ if (_resolvedGateMode === "bootstrap" && stage.key !== "cont-qa") {
201
278
  continue;
202
279
  }
203
280
  if (stageRequiresRun(stage, wave, lanePaths)) {
@@ -215,6 +292,9 @@ export async function runClosureSweepPhase({
215
292
  }
216
293
  continue;
217
294
  }
295
+ if (stage.key !== "cont-qa") {
296
+ semanticClosureStagesRan = true;
297
+ }
218
298
  for (const runInfo of stage.runs) {
219
299
  const existing = dashboardState.agents.find((entry) => entry.agentId === runInfo.agent.agentId);
220
300
  setWaveDashboardAgent(dashboardState, runInfo.agent.agentId, {
@@ -311,6 +391,7 @@ export async function runClosureSweepPhase({
311
391
  closureRuns,
312
392
  lanePaths,
313
393
  dashboardState,
394
+ derivedState: refreshDerivedState?.(dashboardState?.attempt || 0) || currentDerivedState,
314
395
  refreshDerivedState,
315
396
  readWaveContEvalGateFn: readContEvalGate,
316
397
  readWaveSecurityGateFn: readSecurityGate,
@@ -435,6 +516,7 @@ function evaluateClosureStage({
435
516
  closureRuns,
436
517
  lanePaths,
437
518
  dashboardState,
519
+ derivedState,
438
520
  refreshDerivedState,
439
521
  readWaveContEvalGateFn,
440
522
  readWaveSecurityGateFn,
@@ -464,24 +546,39 @@ function evaluateClosureStage({
464
546
  return readWaveIntegrationBarrierFn(
465
547
  wave,
466
548
  closureRuns,
467
- refreshDerivedState?.(dashboardState?.attempt || 0),
549
+ derivedState || refreshDerivedState?.(dashboardState?.attempt || 0),
468
550
  {
469
551
  integrationAgentId,
470
552
  mode: "live",
471
553
  requireIntegrationStewardFromWave: lanePaths.requireIntegrationStewardFromWave,
554
+ laneProfile: lanePaths.laneProfile,
555
+ autoClosure: lanePaths.autoClosure,
472
556
  },
473
557
  );
474
558
  case "documentation": {
559
+ const componentMatrixGate = readWaveComponentMatrixGateFn(wave, closureRuns, {
560
+ laneProfile: lanePaths.laneProfile,
561
+ documentationAgentId,
562
+ });
475
563
  const documentationGate = readWaveDocumentationGateFn(wave, closureRuns, {
476
564
  mode: "live",
565
+ derivedState: derivedState || refreshDerivedState?.(dashboardState?.attempt || 0),
566
+ documentationAgentId,
567
+ laneProfile: lanePaths.laneProfile,
568
+ autoClosure: lanePaths.autoClosure,
569
+ componentMatrixGate,
477
570
  });
478
571
  if (!documentationGate.ok) {
479
572
  return documentationGate;
480
573
  }
481
- return readWaveComponentMatrixGateFn(wave, closureRuns, {
482
- laneProfile: lanePaths.laneProfile,
483
- documentationAgentId,
484
- });
574
+ return {
575
+ ...componentMatrixGate,
576
+ docClosureState: documentationGate.docClosureState || null,
577
+ detail:
578
+ documentationGate.docClosureState && componentMatrixGate.ok
579
+ ? documentationGate.detail
580
+ : componentMatrixGate.detail,
581
+ };
485
582
  }
486
583
  case "cont-qa":
487
584
  return readWaveContQaGateFn(wave, closureRuns, {