@chllming/wave-orchestration 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.9.5 - 2026-04-05
6
+
7
+ ### Fixed
8
+ - Pass `lanePaths` to `reconcileFailuresAgainstSharedComponentState` to fix `ReferenceError` crash on repos without Integration Steward (A8).
9
+
10
+ ## 0.9.4 - 2026-04-05
11
+
12
+ - Laddered gate modes: bootstrap/standard/strict per wave number
13
+ - Bootstrap pass: exit 0 + deliverables exist = advance (no QA signals needed)
14
+ - Fix: requireDocumentationStewardFromWave threshold strictly respected
15
+ - New config: gateModeThresholds, bootstrapPassConditions, testCommand
16
+ - evaluateBootstrapGate() and resolveGateMode() functions
17
+
5
18
  ## 0.9.3 - 2026-03-30
6
19
 
7
20
  ### Fixed And Hardened
package/README.md CHANGED
@@ -107,18 +107,18 @@ Wave is built to mitigate those failures with a canonical authority set, generat
107
107
 
108
108
  Current release:
109
109
 
110
- - `@chllming/wave-orchestration@0.9.3`
111
- - Release tag: [`v0.9.3`](https://github.com/chllming/agent-wave-orchestrator/releases/tag/v0.9.3)
110
+ - `@chllming/wave-orchestration@0.9.5`
111
+ - Release tag: [`v0.9.5`](https://github.com/chllming/agent-wave-orchestrator/releases/tag/v0.9.5)
112
112
  - Public install path: npmjs
113
113
  - Authenticated fallback: GitHub Packages
114
114
 
115
- Highlights in `0.9.3`:
115
+ Highlights in `0.9.4`:
116
116
 
117
117
  - Wave-gate markers now accept `gap` alongside `pass`, `concerns`, and `blocked` for all five gate dimensions. Agents that report a documented gap (e.g. `live=gap` for an infrastructure topology constraint) no longer have their marker rejected entirely, and `cont-QA` treats gap values as a conditional pass instead of a hard blocker.
118
118
  - First-time `wave launch` now auto-triggers `wave project setup` when no project profile exists, matching existing `wave draft` behavior. The interactive setup flow now shows descriptive help text, explains all template and posture options inline, and adds whitespace between question groups for readability.
119
119
  - `PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows.
120
120
  - `parseArgs` now passes the loaded config object through to `runLauncherCli`, avoiding a redundant `loadWaveConfig()` call.
121
- - Release docs, migration guidance, runtime-config and closure references, the manifest, and the tracked install-state fixtures now all point at the `0.9.3` surface.
121
+ - Release docs, migration guidance, runtime-config and closure references, the manifest, and the tracked install-state fixtures now all point at the `0.9.4` surface.
122
122
 
123
123
  Requirements:
124
124
 
package/docs/README.md CHANGED
@@ -54,7 +54,7 @@ The useful path is journey-first:
54
54
  - Publishing the package:
55
55
  Read [reference/package-publishing-flow.md](./reference/package-publishing-flow.md) for the end-to-end release path, the GitHub publish workflows, the lifecycle scripts, and the verification or repair flow.
56
56
  - Want the practical `0.9.3` operating stance:
57
- Read [guides/recommendations-0.9.3.md](./guides/recommendations-0.9.3.md) for the recommended default around relaxed blocker states, advisory turn budgets, and targeted recovery.
57
+ Read [guides/recommendations-0.9.5.md](./guides/recommendations-0.9.5.md) for the recommended default around relaxed blocker states, advisory turn budgets, and targeted recovery.
58
58
  - Want the concrete runtime module map:
59
59
  Read [plans/end-state-architecture.md](./plans/end-state-architecture.md) for the engine-by-engine architecture and artifact ownership model.
60
60
  - Want the CLI surface map:
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: "0.9.4 Recommendations"
3
+ summary: "How to use 0.9.4's softer blocker states, advisory turn budgets, and targeted recovery without weakening proof and closure."
4
+ ---
5
+
6
+ # 0.9.4 Recommendations
7
+
8
+ Use this guide when you are adopting `0.9.4` and want one practical operating stance for the softer blocker states, advisory turn-budget behavior, and targeted recovery flow that the current package line ships.
9
+
10
+ ## Recommended Default
11
+
12
+ For most repos, the safest `0.9.4` default is:
13
+
14
+ - bound work with `budget.minutes`
15
+ - leave generic `budget.turns` as advisory metadata
16
+ - author non-proof follow-up as `soft`, `stale`, or `advisory` instead of silently treating every open record as a hard blocker
17
+ - use `resolve-policy` when the answer already exists in repo policy or shipped docs
18
+ - prefer targeted rerun or resume after timeout, max-turn, rate-limit, or missing-status outcomes instead of relaunching the whole wave
19
+ - in short-lived sandboxes, prefer `wave submit`, `wave supervise`, `wave status`, and `wave wait` instead of binding the full run to one client shell
20
+ - when a wave-gate dimension has a documented gap that is not an actionable blocker, use `gap` instead of `pass` or `blocked` — the runtime treats it as a conditional pass
21
+
22
+ That recommendation matches the runtime:
23
+
24
+ - executor launch metadata only emits hard turn-limit flags from `claude.maxTurns` or `opencode.steps`
25
+ - open `stale` and `advisory` coordination records stay visible without reopening the active blocking edge
26
+ - recoverable launcher failures queue targeted retry state instead of immediately escalating to broad terminal wave failure
27
+
28
+ ## 1. Budgets
29
+
30
+ Treat the two budget knobs differently:
31
+
32
+ - `budget.minutes` is the primary attempt budget
33
+ - generic `budget.turns` is only a planning hint
34
+ - `claude.maxTurns` or `opencode.steps` are the hard runtime ceilings when you actually want deterministic turn stopping
35
+
36
+ Recommended pattern for synthesis-heavy implementation or closure work:
37
+
38
+ ```json
39
+ {
40
+ "executors": {
41
+ "profiles": {
42
+ "implementation-default": {
43
+ "id": "claude",
44
+ "model": "claude-sonnet-4-6",
45
+ "budget": {
46
+ "minutes": 35,
47
+ "turns": 12
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ In that pattern, `35` minutes is real policy. `12` turns is only guidance for planning and preview metadata.
56
+
57
+ Only set a hard runtime ceiling when you deliberately want the runtime itself to stop:
58
+
59
+ ```json
60
+ {
61
+ "executors": {
62
+ "profiles": {
63
+ "bounded-closure": {
64
+ "id": "claude",
65
+ "model": "claude-sonnet-4-6",
66
+ "budget": {
67
+ "minutes": 20
68
+ },
69
+ "claude": {
70
+ "maxTurns": 6
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## 2. Softer Coordination States
79
+
80
+ `0.9.2` keeps “still visible” separate from “still blocking”.
81
+
82
+ Use these states intentionally:
83
+
84
+ | State | Use it for | What the runtime does |
85
+ | --- | --- | --- |
86
+ | `soft` | follow-up that still matters but should not be treated like proof failure | remains visible and may still drive repair or retry targeting |
87
+ | `stale` | outdated clarification or blocker context kept for history | visible in control state, but does not reopen blocking by itself |
88
+ | `advisory` | known issue, note, or human context that should stay visible without blocking closure | visible in control state, but does not own the active blocking edge |
89
+
90
+ Practical command paths:
91
+
92
+ ```bash
93
+ pnpm exec wave control task act defer --lane main --wave 10 --id blocker-doc-follow-up
94
+ pnpm exec wave control task act mark-stale --lane main --wave 10 --id clarify-a7-rollout
95
+ pnpm exec wave control task act mark-advisory --lane main --wave 10 --id request-clarify-a7-rollout
96
+ pnpm exec wave control task act resolve-policy --lane main --wave 10 --id clarify-a7-rollout --detail "Policy already covered in the rollout guide."
97
+ ```
98
+
99
+ Use them when the repo already knows the answer, the remaining item is informational, or the follow-up should stay visible for the next wave without holding the current wave hostage.
100
+
101
+ ## 3. What Should Stay Hard
102
+
103
+ Do not relax everything.
104
+
105
+ Keep these hard or closure-critical unless you are intentionally changing wave policy:
106
+
107
+ - missing proof or required deliverables
108
+ - failed integration, documentation, or cont-QA closure gates
109
+ - real human-feedback or escalation requirements that block safe continuation
110
+ - requests or clarifications that still represent unresolved ownership or policy ambiguity for the current wave
111
+
112
+ Use `gap` in wave-gate markers when a dimension has a documented gap that is not actionable in the current wave. For example, `live=gap` is appropriate when an infrastructure topology constraint prevents full live validation but the constraint is known, documented, and does not represent a regression. Do not use `gap` to hide actual failures or unreviewed work.
113
+
114
+ If the current wave cannot truthfully close without the answer, keep it blocking.
115
+
116
+ ## 4. Recovery Recommendation
117
+
118
+ My recommendation after reviewing the current `0.9.4` code path is:
119
+
120
+ - let timeout, max-turn, rate-limit, and missing-status failures go through the built-in targeted recovery path first
121
+ - inspect the queued rerun or resume request before manually relaunching the whole wave
122
+ - preserve reusable proof from successful sibling owners whenever the reducer already identified it as reusable
123
+
124
+ That is the shape the launcher now prefers. It only broadens failure when the remaining blockers are still proof-critical or otherwise non-recoverable.
125
+
126
+ ## 5. Suggested Operator Policy
127
+
128
+ For most repo-owned runbooks:
129
+
130
+ - teach authors to use `budget.minutes` first
131
+ - teach operators to downgrade only non-proof follow-up
132
+ - treat `resolve-policy` as the preferred path when the answer already exists in docs or repo policy
133
+ - escalate to a full-wave rerun only after targeted recovery proves insufficient
134
+
135
+ If you want a single sentence policy:
136
+
137
+ > Keep proof and closure strict, keep generic turns advisory, and keep non-proof context visible without letting it accidentally own wave closure.
138
+
139
+
140
+ ## Laddered Gate Modes (new in 0.9.4)
141
+
142
+ Waves now have three gate strictness tiers based on wave number:
143
+
144
+ | Mode | Default waves | What's required to advance |
145
+ |------|--------------|---------------------------|
146
+ | **bootstrap** | 0-3 | Implementation agents exit 0 + deliverables exist |
147
+ | **standard** | 4-9 | + A0 verdict required, doc closure recommended |
148
+ | **strict** | 10+ | Full ceremony: all signals, all stewards, all proof |
149
+
150
+ ### Configuration
151
+
152
+ ```json
153
+ {
154
+ "validation": {
155
+ "gateModeThresholds": {
156
+ "bootstrap": 0,
157
+ "standard": 4,
158
+ "strict": 10
159
+ },
160
+ "bootstrapPassConditions": {
161
+ "requireTestsPass": true,
162
+ "requireDeliverablesExist": true,
163
+ "requireExitCodeZero": true
164
+ },
165
+ "testCommand": "pnpm test:repo"
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Steward threshold fix
171
+
172
+ `requireDocumentationStewardFromWave` and `requireIntegrationStewardFromWave`
173
+ are now strictly respected. Previously, the documentation steward was required
174
+ whenever component promotions were active, regardless of the threshold setting.
175
+
176
+ ### Migration from 0.9.3
177
+
178
+ No breaking changes. Existing repos get bootstrap mode for waves 0-3 by default.
179
+ To keep the old strict behavior for all waves, set:
180
+
181
+ ```json
182
+ {
183
+ "validation": {
184
+ "gateModeThresholds": {
185
+ "bootstrap": 0,
186
+ "standard": 0,
187
+ "strict": 0
188
+ }
189
+ }
190
+ }
191
+ ```
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: "0.9.4 Recommendations"
3
+ summary: "How to use 0.9.4's softer blocker states, advisory turn budgets, and targeted recovery without weakening proof and closure."
4
+ ---
5
+
6
+ # 0.9.4 Recommendations
7
+
8
+ Use this guide when you are adopting `0.9.4` and want one practical operating stance for the softer blocker states, advisory turn-budget behavior, and targeted recovery flow that the current package line ships.
9
+
10
+ ## Recommended Default
11
+
12
+ For most repos, the safest `0.9.4` default is:
13
+
14
+ - bound work with `budget.minutes`
15
+ - leave generic `budget.turns` as advisory metadata
16
+ - author non-proof follow-up as `soft`, `stale`, or `advisory` instead of silently treating every open record as a hard blocker
17
+ - use `resolve-policy` when the answer already exists in repo policy or shipped docs
18
+ - prefer targeted rerun or resume after timeout, max-turn, rate-limit, or missing-status outcomes instead of relaunching the whole wave
19
+ - in short-lived sandboxes, prefer `wave submit`, `wave supervise`, `wave status`, and `wave wait` instead of binding the full run to one client shell
20
+ - when a wave-gate dimension has a documented gap that is not an actionable blocker, use `gap` instead of `pass` or `blocked` — the runtime treats it as a conditional pass
21
+
22
+ That recommendation matches the runtime:
23
+
24
+ - executor launch metadata only emits hard turn-limit flags from `claude.maxTurns` or `opencode.steps`
25
+ - open `stale` and `advisory` coordination records stay visible without reopening the active blocking edge
26
+ - recoverable launcher failures queue targeted retry state instead of immediately escalating to broad terminal wave failure
27
+
28
+ ## 1. Budgets
29
+
30
+ Treat the two budget knobs differently:
31
+
32
+ - `budget.minutes` is the primary attempt budget
33
+ - generic `budget.turns` is only a planning hint
34
+ - `claude.maxTurns` or `opencode.steps` are the hard runtime ceilings when you actually want deterministic turn stopping
35
+
36
+ Recommended pattern for synthesis-heavy implementation or closure work:
37
+
38
+ ```json
39
+ {
40
+ "executors": {
41
+ "profiles": {
42
+ "implementation-default": {
43
+ "id": "claude",
44
+ "model": "claude-sonnet-4-6",
45
+ "budget": {
46
+ "minutes": 35,
47
+ "turns": 12
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ In that pattern, `35` minutes is real policy. `12` turns is only guidance for planning and preview metadata.
56
+
57
+ Only set a hard runtime ceiling when you deliberately want the runtime itself to stop:
58
+
59
+ ```json
60
+ {
61
+ "executors": {
62
+ "profiles": {
63
+ "bounded-closure": {
64
+ "id": "claude",
65
+ "model": "claude-sonnet-4-6",
66
+ "budget": {
67
+ "minutes": 20
68
+ },
69
+ "claude": {
70
+ "maxTurns": 6
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## 2. Softer Coordination States
79
+
80
+ `0.9.2` keeps “still visible” separate from “still blocking”.
81
+
82
+ Use these states intentionally:
83
+
84
+ | State | Use it for | What the runtime does |
85
+ | --- | --- | --- |
86
+ | `soft` | follow-up that still matters but should not be treated like proof failure | remains visible and may still drive repair or retry targeting |
87
+ | `stale` | outdated clarification or blocker context kept for history | visible in control state, but does not reopen blocking by itself |
88
+ | `advisory` | known issue, note, or human context that should stay visible without blocking closure | visible in control state, but does not own the active blocking edge |
89
+
90
+ Practical command paths:
91
+
92
+ ```bash
93
+ pnpm exec wave control task act defer --lane main --wave 10 --id blocker-doc-follow-up
94
+ pnpm exec wave control task act mark-stale --lane main --wave 10 --id clarify-a7-rollout
95
+ pnpm exec wave control task act mark-advisory --lane main --wave 10 --id request-clarify-a7-rollout
96
+ pnpm exec wave control task act resolve-policy --lane main --wave 10 --id clarify-a7-rollout --detail "Policy already covered in the rollout guide."
97
+ ```
98
+
99
+ Use them when the repo already knows the answer, the remaining item is informational, or the follow-up should stay visible for the next wave without holding the current wave hostage.
100
+
101
+ ## 3. What Should Stay Hard
102
+
103
+ Do not relax everything.
104
+
105
+ Keep these hard or closure-critical unless you are intentionally changing wave policy:
106
+
107
+ - missing proof or required deliverables
108
+ - failed integration, documentation, or cont-QA closure gates
109
+ - real human-feedback or escalation requirements that block safe continuation
110
+ - requests or clarifications that still represent unresolved ownership or policy ambiguity for the current wave
111
+
112
+ Use `gap` in wave-gate markers when a dimension has a documented gap that is not actionable in the current wave. For example, `live=gap` is appropriate when an infrastructure topology constraint prevents full live validation but the constraint is known, documented, and does not represent a regression. Do not use `gap` to hide actual failures or unreviewed work.
113
+
114
+ If the current wave cannot truthfully close without the answer, keep it blocking.
115
+
116
+ ## 4. Recovery Recommendation
117
+
118
+ My recommendation after reviewing the current `0.9.4` code path is:
119
+
120
+ - let timeout, max-turn, rate-limit, and missing-status failures go through the built-in targeted recovery path first
121
+ - inspect the queued rerun or resume request before manually relaunching the whole wave
122
+ - preserve reusable proof from successful sibling owners whenever the reducer already identified it as reusable
123
+
124
+ That is the shape the launcher now prefers. It only broadens failure when the remaining blockers are still proof-critical or otherwise non-recoverable.
125
+
126
+ ## 5. Suggested Operator Policy
127
+
128
+ For most repo-owned runbooks:
129
+
130
+ - teach authors to use `budget.minutes` first
131
+ - teach operators to downgrade only non-proof follow-up
132
+ - treat `resolve-policy` as the preferred path when the answer already exists in docs or repo policy
133
+ - escalate to a full-wave rerun only after targeted recovery proves insufficient
134
+
135
+ If you want a single sentence policy:
136
+
137
+ > Keep proof and closure strict, keep generic turns advisory, and keep non-proof context visible without letting it accidentally own wave closure.
138
+
139
+
140
+ ## Laddered Gate Modes (new in 0.9.4)
141
+
142
+ Waves now have three gate strictness tiers based on wave number:
143
+
144
+ | Mode | Default waves | What's required to advance |
145
+ |------|--------------|---------------------------|
146
+ | **bootstrap** | 0-3 | Implementation agents exit 0 + deliverables exist |
147
+ | **standard** | 4-9 | + A0 verdict required, doc closure recommended |
148
+ | **strict** | 10+ | Full ceremony: all signals, all stewards, all proof |
149
+
150
+ ### Configuration
151
+
152
+ ```json
153
+ {
154
+ "validation": {
155
+ "gateModeThresholds": {
156
+ "bootstrap": 0,
157
+ "standard": 4,
158
+ "strict": 10
159
+ },
160
+ "bootstrapPassConditions": {
161
+ "requireTestsPass": true,
162
+ "requireDeliverablesExist": true,
163
+ "requireExitCodeZero": true
164
+ },
165
+ "testCommand": "pnpm test:repo"
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Steward threshold fix
171
+
172
+ `requireDocumentationStewardFromWave` and `requireIntegrationStewardFromWave`
173
+ are now strictly respected. Previously, the documentation steward was required
174
+ whenever component promotions were active, regardless of the threshold setting.
175
+
176
+ ### Migration from 0.9.3
177
+
178
+ No breaking changes. Existing repos get bootstrap mode for waves 0-3 by default.
179
+ To keep the old strict behavior for all waves, set:
180
+
181
+ ```json
182
+ {
183
+ "validation": {
184
+ "gateModeThresholds": {
185
+ "bootstrap": 0,
186
+ "standard": 0,
187
+ "strict": 0
188
+ }
189
+ }
190
+ }
191
+ ```
@@ -1,10 +1,10 @@
1
1
  # Current State
2
2
 
3
- - The published package is `0.9.3`; that release keeps the shipped monorepo, design-role, signal-hygiene, detached process-runner, and sandbox supervisor surfaces, and now also accepts `gap` as a valid wave-gate dimension value (alongside `pass`, `concerns`, and `blocked`) so that agents reporting a documented gap no longer trigger missing-wave-gate failures. First-time `wave launch` now auto-triggers `wave project setup` when no project profile exists, and the interactive setup flow shows descriptive help text and inline option explanations. The current authenticated Wave Control plus Corridor-backed security surface continues to ship in this repo.
3
+ - The published package is `0.9.4`; that release keeps the shipped monorepo, design-role, signal-hygiene, detached process-runner, and sandbox supervisor surfaces, and now also accepts `gap` as a valid wave-gate dimension value (alongside `pass`, `concerns`, and `blocked`) so that agents reporting a documented gap no longer trigger missing-wave-gate failures. First-time `wave launch` now auto-triggers `wave project setup` when no project profile exists, and the interactive setup flow shows descriptive help text and inline option explanations. The current authenticated Wave Control plus Corridor-backed security surface continues to ship in this repo.
4
4
  - The canonical shipped runtime architecture is documented in `docs/plans/end-state-architecture.md`; the sandbox-runtime companion is `docs/plans/sandbox-end-state-architecture.md`; historical cutover notes remain in `docs/plans/architecture-hardening-migration.md`.
5
5
  - The repository contains the published `@chllming/wave-orchestration` package plus the starter scaffold used by `wave init`.
6
6
  - The runtime is package-first and non-destructive for adopting repos: `wave init --adopt-existing` records existing repo-owned plans, waves, prompts, and config without overwriting them, and `wave upgrade` writes only `.wave/install-state.json` plus `.wave/upgrade-history/`.
7
- - The recommended `0.9.3` operating stance is documented in `docs/guides/recommendations-0.9.3.md`: keep proof and closure strict, keep generic `budget.turns` advisory, and use softer coordination states only for non-proof follow-up.
7
+ - The recommended `0.9.4` operating stance is documented in `docs/guides/recommendations-0.9.4.md`: keep proof and closure strict, keep generic `budget.turns` advisory, and use softer coordination states only for non-proof follow-up.
8
8
  - Sandbox-safe setup guidance now ships in `docs/guides/sandboxed-environments.md`: use `wave submit/supervise/status/wait/attach` for short-lived clients, keep `tmux` optional and dashboard-only, and preserve `.tmp/` plus `.wave/` when running inside Nemoshell or Docker.
9
9
  - Runtime launch entrypoints now perform a best-effort npmjs version check, cache the result under `.wave/package-update-check.json`, and point operators at `pnpm exec wave self-update` when a newer published package exists.
10
10
  - The companion control plane now ships in two packages:
@@ -1,6 +1,6 @@
1
1
  # Migration
2
2
 
3
- This page is the practical repo-upgrade guide for the current `0.9.3` surface.
3
+ This page is the practical repo-upgrade guide for the current `0.9.5` surface.
4
4
 
5
5
  Use it when you are:
6
6
 
@@ -12,9 +12,19 @@ For the completed internal architecture cutover record, see [architecture-harden
12
12
 
13
13
  For the sandbox-specific long-running execution target, including async `submit/status/wait` semantics and daemon ownership goals, see [sandbox-end-state-architecture.md](./sandbox-end-state-architecture.md).
14
14
 
15
- ## What `0.9.3` Changes
16
15
 
17
- The current `0.9.3` surface keeps everything from `0.9.2` and adds two focused improvements with no breaking changes.
16
+ ## What `0.9.4` Changes
17
+
18
+ The `0.9.4` surface adds laddered gate modes and fixes the steward threshold enforcement.
19
+
20
+ - **Laddered gate modes**: bootstrap (waves 0-3), standard (4-9), strict (10+). Bootstrap mode requires only implementation agent exit 0 and deliverables exist — no formal QA signals needed.
21
+ - **Steward threshold fix**: `requireDocumentationStewardFromWave` is now strictly respected. Previously it was OR'd with `componentPromotionRuleActive`.
22
+ - **New config fields**: `gateModeThresholds`, `bootstrapPassConditions`, `testCommand`, `testCommandTimeout`.
23
+ - **No breaking changes**: existing repos get bootstrap mode for waves 0-3 by default.
24
+
25
+ ## What `0.9.4` Changes
26
+
27
+ The current `0.9.5` surface keeps everything from `0.9.2` and adds two focused improvements with no breaking changes.
18
28
 
19
29
  The practical changes are:
20
30
 
@@ -30,7 +40,7 @@ There are no breaking changes. Just upgrade with `pnpm up @chllming/wave-orchest
30
40
 
31
41
  If your repo uses wave-gate markers, you can now use `gap` for dimensions where the gap is documented and not an actionable blocker.
32
42
 
33
- For the practical `0.9.3` operating stance after the upgrade, read [../guides/recommendations-0.9.3.md](../guides/recommendations-0.9.3.md).
43
+ For the practical `0.9.4` operating stance after the upgrade, read [../guides/recommendations-0.9.4.md](../guides/recommendations-0.9.4.md).
34
44
 
35
45
  ## What `0.9.2` Changes
36
46
 
@@ -170,11 +180,11 @@ pnpm exec wave coord inbox --lane main --wave 0 --agent A1 --dry-run
170
180
 
171
181
  Use `pnpm exec wave dashboard --lane <lane> --attach current` or `--attach global` when you need to reattach to a tmux-backed dashboard after the upgrade.
172
182
 
173
- ## `0.9.3` Release Model
183
+ ## `0.9.4` Release Model
174
184
 
175
- The current `0.9.3` surface combines these strands:
185
+ The current `0.9.5` surface combines these strands:
176
186
 
177
- - the gap-value wave-gate fix and first-time setup UX improvements released in `0.9.3`
187
+ - the gap-value wave-gate fix and first-time setup UX improvements released in `0.9.4`
178
188
  - the detached process-runner and sandbox supervisor hardening released in `0.9.2`
179
189
  - the shipped `0.9.0` monorepo project support and project-aware runtime isolation
180
190
  - the shipped `design` worker role and hybrid design-steward flow introduced in `0.8.5`
@@ -282,7 +292,7 @@ The interactive `wave draft` flow supports `design` as a worker role and scaffol
282
292
 
283
293
  ## Version-Specific Upgrade Guidance
284
294
 
285
- ## Upgrading From `0.8.5` To `0.9.3`
295
+ ## Upgrading From `0.8.5` To `0.9.4`
286
296
 
287
297
  This is the smallest upgrade, but it changes the live wait-loop contract for external automation and intentionally long-running agents.
288
298
 
@@ -319,7 +329,7 @@ If the repo copied starter surface, sync:
319
329
  - if the repo uses long-running watchers, confirm they can write the ack file where the prompt tells them to
320
330
  - reroute one targeted feedback or coordination request and confirm the resident signal version changes even when the signal kind stays the same
321
331
 
322
- ## Upgrading From `0.8.4` To `0.9.3`
332
+ ## Upgrading From `0.8.4` To `0.9.4`
323
333
 
324
334
  ### What changed
325
335
 
@@ -357,7 +367,7 @@ If your repo copied starter config defaults, also sync the `designRolePromptPath
357
367
  - hybrid design stewards rejoin implementation when they explicitly own code
358
368
  - long-running prompts receive signal-state and ack paths when the repo uses the new waiting model
359
369
 
360
- ## Upgrading From `0.8.3` To `0.9.3`
370
+ ## Upgrading From `0.8.3` To `0.9.5`
361
371
 
362
372
  Treat this as one move to the current `0.9.2` surface.
363
373
 
@@ -392,7 +402,7 @@ If your repo copied starter docs or skills, sync:
392
402
  - dry-run one design-steward wave if the repo wants the new authored surface
393
403
  - if the repo uses long-running watcher agents or shell automation, validate `scripts/wave-status.sh` and `scripts/wave-watch.sh` against a live or staged lane
394
404
 
395
- ## Upgrading From `0.6.x` Or `0.7.x` To `0.9.3`
405
+ ## Upgrading From `0.6.x` Or `0.7.x` To `0.9.5`
396
406
 
397
407
  This is the main migration path for older adopted repos.
398
408
 
@@ -433,7 +443,7 @@ pnpm exec wave control proof get --lane main --wave 0 --json
433
443
 
434
444
  If the repo carries proof-first waves, verify that required proof artifacts still exist locally and not only in historical summaries.
435
445
 
436
- ## Upgrading From `0.5.x` Or Earlier To `0.9.3`
446
+ ## Upgrading From `0.5.x` Or Earlier To `0.9.4`
437
447
 
438
448
  Do not treat this as a tiny patch bump.
439
449
 
@@ -543,4 +553,4 @@ For repos that depend on replay parity, replay at least:
543
553
 
544
554
  ## Summary
545
555
 
546
- The current `0.9.3` surface keeps the same authority-set and phase-engine architecture, ships both the design-role starter surface and the signal-driven long-running-agent starter surface, keeps the `0.8.7` policy and routing hardening, and now also packages the practical operator recommendations guide inside the release line. For most repos already on `0.8.x`, the upgrade is package bump plus validation. For older adopted repos, the real work is syncing repo-owned prompts, skills, planner corpus, wrapper scripts, and runbooks so they describe the runtime the package now ships.
556
+ The current `0.9.5` surface keeps the same authority-set and phase-engine architecture, ships both the design-role starter surface and the signal-driven long-running-agent starter surface, keeps the `0.8.7` policy and routing hardening, and now also packages the practical operator recommendations guide inside the release line. For most repos already on `0.8.x`, the upgrade is package bump plus validation. For older adopted repos, the real work is syncing repo-owned prompts, skills, planner corpus, wrapper scripts, and runbooks so they describe the runtime the package now ships.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chllming/wave-orchestration",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "license": "MIT",
5
5
  "description": "Generic wave-based multi-agent orchestration for repository work.",
6
6
  "repository": {
@@ -3,7 +3,18 @@
3
3
  "packageName": "@chllming/wave-orchestration",
4
4
  "releases": [
5
5
  {
6
- "version": "0.9.3",
6
+ "version": "0.9.5",
7
+ "date": "2026-04-05",
8
+ "summary": "Hotfix: pass lanePaths to reconcileFailuresAgainstSharedComponentState, fixing launcher crash on repos without Integration Steward.",
9
+ "features": [
10
+ "Fixed ReferenceError where `lanePaths` was used as a free variable in `reconcileFailuresAgainstSharedComponentState` instead of being passed as a parameter.",
11
+ "planner-agentic bundle placeholder remains available for adopted repos."
12
+ ],
13
+ "manualSteps": [],
14
+ "breaking": false
15
+ },
16
+ {
17
+ "version": "0.9.4",
7
18
  "date": "2026-03-30",
8
19
  "summary": "Gap-value wave-gate fix and first-time project setup UX improvements.",
9
20
  "features": [
@@ -14,13 +25,13 @@
14
25
  "`wave project setup` now shows descriptive help text before each prompt, explains all template and posture options inline, and adds whitespace between question groups for readability. (Contributed by @justanothernate in #54)",
15
26
  "`PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows.",
16
27
  "`parseArgs` now passes the loaded config object through to `runLauncherCli`, avoiding a redundant `loadWaveConfig()` call.",
17
- "Release docs, migration guidance, runtime-config and closure references, the manifest, and the tracked install-state fixtures now all point at the `0.9.3` surface.",
28
+ "Release docs, migration guidance, runtime-config and closure references, the manifest, and the tracked install-state fixtures now all point at the `0.9.4` surface.",
18
29
  "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."
19
30
  ],
20
31
  "manualSteps": [
21
- "Run `pnpm exec wave doctor` and `pnpm exec wave launch --lane main --dry-run --no-dashboard` after upgrading so the repo validates against the `0.9.3` release surface.",
22
- "Push the `v0.9.3` tag after the release commit so the GitHub publish workflow can publish the matching npm package version.",
23
- "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`, and `docs/guides/recommendations-0.9.3.md` so local guidance matches the packaged release."
32
+ "Run `pnpm exec wave doctor` and `pnpm exec wave launch --lane main --dry-run --no-dashboard` after upgrading so the repo validates against the `0.9.4` release surface.",
33
+ "Push the `v0.9.4` tag after the release commit so the GitHub publish workflow can publish the matching npm package version.",
34
+ "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`, and `docs/guides/recommendations-0.9.4.md` so local guidance matches the packaged release."
24
35
  ],
25
36
  "breaking": false
26
37
  },
@@ -556,4 +567,4 @@
556
567
  "breaking": false
557
568
  }
558
569
  ]
559
- }
570
+ }
@@ -531,6 +531,20 @@ function normalizeValidation(rawValidation = {}) {
531
531
  rawValidation.requireAgentComponentsFromWave,
532
532
  0,
533
533
  ),
534
+ gateModeThresholds: {
535
+ bootstrap: rawValidation.gateModeThresholds?.bootstrap ?? 0,
536
+ standard: rawValidation.gateModeThresholds?.standard ?? 4,
537
+ strict: rawValidation.gateModeThresholds?.strict ?? 10,
538
+ },
539
+ bootstrapPassConditions: {
540
+ requireA0Verdict: rawValidation.bootstrapPassConditions?.requireA0Verdict ?? false,
541
+ requireProofSignals: rawValidation.bootstrapPassConditions?.requireProofSignals ?? false,
542
+ requireTestsPass: rawValidation.bootstrapPassConditions?.requireTestsPass ?? true,
543
+ requireDeliverablesExist: rawValidation.bootstrapPassConditions?.requireDeliverablesExist ?? true,
544
+ requireExitCodeZero: rawValidation.bootstrapPassConditions?.requireExitCodeZero ?? true,
545
+ },
546
+ testCommand: typeof rawValidation.testCommand === "string" ? rawValidation.testCommand : null,
547
+ testCommandTimeout: typeof rawValidation.testCommandTimeout === "number" ? rawValidation.testCommandTimeout : 120,
534
548
  };
535
549
  }
536
550
 
@@ -138,6 +138,46 @@ function validateEnvelopeForRun(runInfo, envelope, options = {}) {
138
138
  };
139
139
  }
140
140
 
141
+
142
+ // --- Laddered gate modes (0.9.4) ---
143
+ export function resolveGateMode(waveNumber, thresholds) {
144
+ if (!thresholds) return "strict";
145
+ if (waveNumber < (thresholds.standard ?? 4)) return "bootstrap";
146
+ if (waveNumber < (thresholds.strict ?? 10)) return "standard";
147
+ return "strict";
148
+ }
149
+
150
+ export function evaluateBootstrapGate(wave, agentRuns, options = {}) {
151
+ const conditions = options.bootstrapPassConditions ?? {};
152
+ const summaries = options.summaries ?? new Map();
153
+
154
+ // Check implementation agents (non-A0, non-A8, non-A9)
155
+ const implAgents = agentRuns.filter(a =>
156
+ !["A0", "E0", "A8", "A9"].includes(a.agentId)
157
+ );
158
+
159
+ for (const agent of implAgents) {
160
+ const summary = summaries.get(agent.agentId);
161
+ if (!summary) continue;
162
+
163
+ // Must have exit code 0
164
+ if (conditions.requireExitCodeZero !== false && summary.exitCode !== 0) {
165
+ return { ok: false, statusCode: "blocked", detail: `${agent.agentId} exit code ${summary.exitCode}` };
166
+ }
167
+
168
+ // Check deliverables exist
169
+ if (conditions.requireDeliverablesExist !== false && summary.deliverables) {
170
+ const missing = summary.deliverables.filter(d => !d.exists);
171
+ if (missing.length > 0) {
172
+ return { ok: false, statusCode: "concerns", detail: `${agent.agentId} missing deliverables: ${missing.map(d=>d.path).join(", ")}` };
173
+ }
174
+ }
175
+ }
176
+
177
+ return { ok: true, statusCode: "pass", detail: "bootstrap-pass: impl agents completed with deliverables" };
178
+ }
179
+ // --- End laddered gate modes ---
180
+
141
181
  export function materializeAgentExecutionSummaryForRun(wave, runInfo, options = {}) {
142
182
  const statusRecord = readStatusRecordIfPresent(runInfo.statusPath);
143
183
  if (!statusRecord) {
@@ -69,7 +69,7 @@ export const STARTER_TEMPLATE_PATHS = [
69
69
  "docs/guides/author-and-run-waves.md",
70
70
  "docs/guides/monorepo-projects.md",
71
71
  "docs/guides/planner.md",
72
- "docs/guides/recommendations-0.9.3.md",
72
+ "docs/guides/recommendations-0.9.5.md",
73
73
  "docs/guides/sandboxed-environments.md",
74
74
  "docs/guides/signal-wrappers.md",
75
75
  "docs/guides/terminal-surfaces.md",
@@ -1787,7 +1787,7 @@ export async function runLauncherCli(argv) {
1787
1787
  syncWaveSignals();
1788
1788
  lastLiveCoordinationRefreshAt = Date.now();
1789
1789
  emitCoordinationAlertEvents(derivedState);
1790
- failures = reconcileFailuresAgainstSharedComponentState(wave, agentRuns, failures);
1790
+ failures = reconcileFailuresAgainstSharedComponentState(wave, agentRuns, failures, lanePaths);
1791
1791
  for (const failure of failures) {
1792
1792
  if (failure.statusCode === "shared-component-sibling-pending") {
1793
1793
  applySharedComponentWaitStateToDashboard(failure, dashboardState);
@@ -276,7 +276,7 @@ export function applySharedComponentWaitStateToDashboard(componentGate, dashboar
276
276
  }
277
277
  }
278
278
 
279
- export function reconcileFailuresAgainstSharedComponentState(wave, agentRuns, failures) {
279
+ export function reconcileFailuresAgainstSharedComponentState(wave, agentRuns, failures, lanePaths) {
280
280
  if (!Array.isArray(failures) || failures.length === 0) {
281
281
  return failures;
282
282
  }
@@ -1786,8 +1786,7 @@ export function validateWaveDefinition(wave, options = {}) {
1786
1786
  }
1787
1787
  }
1788
1788
  const documentationRuleActive =
1789
- (documentationThreshold !== null && wave.wave >= documentationThreshold) ||
1790
- componentPromotionRuleActive;
1789
+ documentationThreshold !== null && wave.wave >= documentationThreshold;
1791
1790
  if (documentationRuleActive) {
1792
1791
  const documentationStewards = wave.agents.filter((agent) =>
1793
1792
  agent.rolePromptPaths?.includes(laneProfile.roles.documentationRolePromptPath),
package/wave.config.json CHANGED
@@ -31,51 +31,69 @@
31
31
  "profiles": {
32
32
  "implement-fast": {
33
33
  "id": "codex",
34
- "tags": ["implementation"],
34
+ "tags": [
35
+ "implementation"
36
+ ],
35
37
  "budget": {
36
- "turns": 12,
37
38
  "minutes": 45
38
39
  }
39
40
  },
40
41
  "deep-review": {
41
42
  "id": "claude",
42
- "tags": ["integration", "review"],
43
+ "tags": [
44
+ "integration",
45
+ "review"
46
+ ],
43
47
  "budget": {
44
- "turns": 10,
45
48
  "minutes": 30
46
49
  }
47
50
  },
48
51
  "eval-tuning": {
49
52
  "id": "codex",
50
- "tags": ["eval", "tuning"],
53
+ "tags": [
54
+ "eval",
55
+ "tuning"
56
+ ],
51
57
  "budget": {
52
- "turns": 14,
53
58
  "minutes": 45
54
59
  }
55
60
  },
56
61
  "docs-pass": {
57
62
  "id": "claude",
58
- "tags": ["documentation"],
63
+ "tags": [
64
+ "documentation"
65
+ ],
59
66
  "budget": {
60
- "turns": 8,
61
67
  "minutes": 20
62
68
  }
63
69
  },
64
70
  "design-pass": {
65
71
  "id": "claude",
66
- "tags": ["design", "review"],
72
+ "tags": [
73
+ "design",
74
+ "review"
75
+ ],
67
76
  "budget": {
68
- "turns": 10,
69
77
  "minutes": 30
70
78
  },
71
79
  "claude": {
72
- "allowedTools": ["Read", "Edit", "Write", "Bash", "Grep", "Glob"]
80
+ "allowedTools": [
81
+ "Read",
82
+ "Edit",
83
+ "Write",
84
+ "Bash",
85
+ "Grep",
86
+ "Glob"
87
+ ]
73
88
  }
74
89
  },
75
90
  "planning-readonly": {
76
91
  "id": "codex",
77
92
  "model": "gpt-5-codex",
78
- "tags": ["planning", "review"],
93
+ "tags": [
94
+ "planning",
95
+ "review"
96
+ ],
79
97
  "budget": {
80
98
  "minutes": 30
81
99
  },
@@ -83,25 +101,38 @@
83
101
  "search": true,
84
102
  "json": true,
85
103
  "sandbox": "read-only",
86
- "config": ["model_reasoning_effort=high"]
104
+ "config": [
105
+ "model_reasoning_effort=high"
106
+ ]
87
107
  }
88
108
  },
89
109
  "security-review": {
90
110
  "id": "claude",
91
- "tags": ["security", "review"],
111
+ "tags": [
112
+ "security",
113
+ "review"
114
+ ],
92
115
  "budget": {
93
- "turns": 8,
94
116
  "minutes": 20
95
117
  },
96
118
  "claude": {
97
- "allowedTools": ["Read", "Edit", "Write", "Bash", "Grep", "Glob"]
119
+ "allowedTools": [
120
+ "Read",
121
+ "Edit",
122
+ "Write",
123
+ "Bash",
124
+ "Grep",
125
+ "Glob"
126
+ ]
98
127
  }
99
128
  },
100
129
  "ops-triage": {
101
130
  "id": "opencode",
102
- "tags": ["ops", "research"],
131
+ "tags": [
132
+ "ops",
133
+ "research"
134
+ ],
103
135
  "budget": {
104
- "turns": 8,
105
136
  "minutes": 20
106
137
  }
107
138
  }
@@ -122,34 +153,81 @@
122
153
  },
123
154
  "skills": {
124
155
  "dir": "skills",
125
- "base": ["wave-core", "repo-coding-rules"],
156
+ "base": [
157
+ "wave-core",
158
+ "repo-coding-rules"
159
+ ],
126
160
  "byRole": {
127
- "design": ["role-design"],
128
- "implementation": ["role-implementation"],
129
- "integration": ["role-integration"],
130
- "documentation": ["role-documentation"],
131
- "cont-qa": ["role-cont-qa"],
132
- "cont-eval": ["role-cont-eval"],
133
- "security": ["role-security"],
134
- "infra": ["role-infra"],
135
- "deploy": ["role-deploy"],
136
- "research": ["role-research"]
161
+ "design": [
162
+ "role-design"
163
+ ],
164
+ "implementation": [
165
+ "role-implementation"
166
+ ],
167
+ "integration": [
168
+ "role-integration"
169
+ ],
170
+ "documentation": [
171
+ "role-documentation"
172
+ ],
173
+ "cont-qa": [
174
+ "role-cont-qa"
175
+ ],
176
+ "cont-eval": [
177
+ "role-cont-eval"
178
+ ],
179
+ "security": [
180
+ "role-security"
181
+ ],
182
+ "infra": [
183
+ "role-infra"
184
+ ],
185
+ "deploy": [
186
+ "role-deploy"
187
+ ],
188
+ "research": [
189
+ "role-research"
190
+ ]
137
191
  },
138
192
  "byRuntime": {
139
- "codex": ["runtime-codex"],
140
- "claude": ["runtime-claude"],
141
- "opencode": ["runtime-opencode"],
142
- "local": ["runtime-local"]
193
+ "codex": [
194
+ "runtime-codex"
195
+ ],
196
+ "claude": [
197
+ "runtime-claude"
198
+ ],
199
+ "opencode": [
200
+ "runtime-opencode"
201
+ ],
202
+ "local": [
203
+ "runtime-local"
204
+ ]
143
205
  },
144
206
  "byDeployKind": {
145
- "railway-cli": ["provider-railway"],
146
- "railway-mcp": ["provider-railway"],
147
- "docker-compose": ["provider-docker-compose"],
148
- "kubernetes": ["provider-kubernetes"],
149
- "aws": ["provider-aws"],
150
- "github-release": ["provider-github-release"],
151
- "ssh-manual": ["provider-ssh-manual"],
152
- "custom": ["provider-custom-deploy"]
207
+ "railway-cli": [
208
+ "provider-railway"
209
+ ],
210
+ "railway-mcp": [
211
+ "provider-railway"
212
+ ],
213
+ "docker-compose": [
214
+ "provider-docker-compose"
215
+ ],
216
+ "kubernetes": [
217
+ "provider-kubernetes"
218
+ ],
219
+ "aws": [
220
+ "provider-aws"
221
+ ],
222
+ "github-release": [
223
+ "provider-github-release"
224
+ ],
225
+ "ssh-manual": [
226
+ "provider-ssh-manual"
227
+ ],
228
+ "custom": [
229
+ "provider-custom-deploy"
230
+ ]
153
231
  }
154
232
  },
155
233
  "planner": {
@@ -223,8 +301,12 @@
223
301
  "infra": "opencode",
224
302
  "deploy": "opencode"
225
303
  },
226
- "fallbackExecutorOrder": ["claude", "opencode", "codex"]
304
+ "fallbackExecutorOrder": [
305
+ "claude",
306
+ "opencode",
307
+ "codex"
308
+ ]
227
309
  }
228
310
  }
229
311
  }
230
- }
312
+ }