@chllming/wave-orchestration 0.9.7 → 0.9.9
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 +54 -26
- package/docs/README.md +5 -1
- package/docs/guides/recommendations-0.9.8.md +137 -0
- package/docs/guides/recommendations-0.9.9.md +137 -0
- package/docs/plans/migration.md +10 -6
- package/package.json +1 -1
- package/releases/manifest.json +12 -1
- package/scripts/wave-orchestrator/config.mjs +1 -1
- package/scripts/wave-orchestrator/executors.mjs +0 -1
- package/scripts/wave-orchestrator/gate-engine.mjs +30 -3
- package/scripts/wave-orchestrator/wave-state-reducer.mjs +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,52 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.9.9 - 2026-04-07
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Helper assignment barrier is now advisory (non-blocking) in bootstrap gate mode. Previously, open helper assignments blocked wave closure even when the assigned agent completed successfully with exit 0, causing unnecessary retries. In bootstrap mode, assigned-but-open helper requests are downgraded to advisory warnings with statusCode `helper-assignment-open-advisory`. Unresolved assignments (no assignee) remain blocking in all gate modes.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## 0.9.8 - 2026-04-06
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- `wave self-update` command for in-place package upgrades with release notes display.
|
|
13
|
+
- Upgrade history tracking in `.wave/upgrade-history/` with per-upgrade reports including workspace impact analysis and follow-up actions.
|
|
14
|
+
- Bootstrap advisory gates: in bootstrap mode (waves 0–3), doc-closure, cont-QA, integration, and component gates are advisory (non-blocking) while implementation gates remain required. Advisory failures are tracked in the gate snapshot for visibility.
|
|
15
|
+
- `docs/guides/recommendations-0.9.8.md` recommendations guide.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- Integration barrier now short-circuits when no A8 steward is declared (`agentId: null`), fixing `missing-integration-summary` failures on waves without an integration agent.
|
|
19
|
+
- Default `claude.permissionMode` to `bypassPermissions` (fixes Docker container environments where interactive permission prompts hang).
|
|
20
|
+
- Removed `--search` flag from codex exec invocations (unsupported by `codex exec`).
|
|
21
|
+
- Relaxed release-surface test version checks while keeping changelog checks strict (#64).
|
|
22
|
+
- Updated executor test — `--search` not supported in codex exec (#63).
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- `wave upgrade` now records install-state transitions and generates upgrade reports.
|
|
4
26
|
|
|
5
27
|
## 0.9.7 - 2026-04-06
|
|
6
28
|
|
|
7
29
|
### Fixed
|
|
8
|
-
- Closure engine now skips missing-closure-run failures
|
|
9
|
-
- `gateModeThresholds` is now exposed on the `lanePaths` object
|
|
30
|
+
- Closure engine now skips missing-closure-run failures when the resolved gate mode is `bootstrap`, allowing waves to pass when agents complete but tmux status reconciliation fails.
|
|
31
|
+
- `gateModeThresholds` is now exposed on the `lanePaths` object so downstream consumers (closure engine, derived state) can resolve the active gate mode.
|
|
10
32
|
|
|
11
33
|
## 0.9.6 - 2026-04-05
|
|
12
34
|
|
|
13
35
|
### Fixed
|
|
14
|
-
- Closure engine now respects `requireIntegrationStewardFromWave` and `requireDocumentationStewardFromWave` thresholds instead of unconditionally requiring integration/documentation
|
|
36
|
+
- Closure engine now respects `requireIntegrationStewardFromWave` and `requireDocumentationStewardFromWave` thresholds instead of unconditionally requiring integration/documentation steward runs for waves that don't declare them. When set to `null`, the stage is only required if the wave declares the corresponding agent.
|
|
15
37
|
|
|
16
38
|
## 0.9.5 - 2026-04-05
|
|
17
39
|
|
|
18
40
|
### Fixed
|
|
19
|
-
- Pass `lanePaths` to `reconcileFailuresAgainstSharedComponentState
|
|
41
|
+
- Pass `lanePaths` to `reconcileFailuresAgainstSharedComponentState`, fixing `ReferenceError` crash on repos without Integration Steward (A8).
|
|
20
42
|
|
|
21
43
|
## 0.9.4 - 2026-04-05
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- New config: gateModeThresholds
|
|
27
|
-
- evaluateBootstrapGate() and resolveGateMode() functions
|
|
45
|
+
### Added
|
|
46
|
+
- Laddered gate modes: `bootstrap` (waves 0–3), `standard` (waves 4–9), `strict` (waves 10+) per wave number via `gateModeThresholds` config.
|
|
47
|
+
- Bootstrap pass conditions: `exit 0 + deliverables exist = advance` — no QA signals required in early waves.
|
|
48
|
+
- New config fields: `gateModeThresholds`, `bootstrapPassConditions`, `testCommand`.
|
|
49
|
+
- `evaluateBootstrapGate()` and `resolveGateMode()` functions for gate-mode resolution.
|
|
50
|
+
- `docs/guides/recommendations-0.9.4.md` recommendations guide.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
- `requireDocumentationStewardFromWave` threshold now strictly respected during validation. Was previously OR'd with `componentPromotionRuleActive`, ignoring the threshold.
|
|
28
54
|
|
|
29
55
|
## 0.9.3 - 2026-03-30
|
|
30
56
|
|
|
31
57
|
### Fixed And Hardened
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
58
|
+
- `WAVE_GATE_REGEX` now accepts `gap` alongside `pass|concerns|blocked` for all five gate dimensions (architecture, integration, durability, live, docs). Previously, agents that reported a documented gap (e.g. `live=gap` for an infrastructure topology constraint) had their marker rejected entirely, causing missing-wave-gate failures that prevented wave closure.
|
|
59
|
+
- `validateContQaSummary` now treats gap dimension values as a conditional pass (`ok: true`, `statusCode: conditional-pass`) instead of a hard blocker, with detail text listing which dimensions have documented gaps.
|
|
60
|
+
- The cont-QA coordination prompt now documents `gap` as a valid dimension value alongside `pass|concerns|blocked`.
|
|
61
|
+
- Migration sections aligned and install seeding updated to target 0.9.3 correctly.
|
|
62
|
+
- Planner-agentic note added to 0.9.3 manifest entry.
|
|
36
63
|
|
|
37
64
|
### Added
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- parseArgs now passes the loaded config object through to runLauncherCli, avoiding a redundant loadWaveConfig() call.
|
|
43
|
-
|
|
44
|
-
### Testing And Validation
|
|
45
|
-
|
|
46
|
-
- `pnpm exec vitest run --config vitest.config.ts`
|
|
47
|
-
- `node scripts/wave.mjs doctor --json`
|
|
48
|
-
- `node scripts/wave.mjs launch --lane main --dry-run --no-dashboard`
|
|
49
|
-
- `pnpm test -- test/wave-orchestrator/release-surface.test.ts`
|
|
65
|
+
- First-time wave launch now auto-triggers `wave project setup` when no project profile exists, matching existing `wave draft` behavior.
|
|
66
|
+
- `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.
|
|
67
|
+
- `PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows.
|
|
68
|
+
- `parseArgs` now passes the loaded config object through to `runLauncherCli`, avoiding a redundant `loadWaveConfig()` call.
|
|
50
69
|
|
|
51
70
|
## 0.9.2 - 2026-03-29
|
|
52
71
|
|
|
@@ -552,3 +571,12 @@
|
|
|
552
571
|
|
|
553
572
|
- Initial generic wave orchestrator runtime.
|
|
554
573
|
- Added Context7 bundle resolution and multi-executor support for Codex, Claude Code, and OpenCode.
|
|
574
|
+
|
|
575
|
+
## 0.9.8 - 2026-04-06
|
|
576
|
+
|
|
577
|
+
### Fixed
|
|
578
|
+
- Gate engine: bootstrap mode treats doc-closure, cont-QA, integration, and component gates as advisory (non-blocking) while impl gates remain required
|
|
579
|
+
- Gate engine: integration barrier short-circuits when no steward declared
|
|
580
|
+
- Claude executor defaults permissionMode to bypassPermissions (fixes Docker containers)
|
|
581
|
+
- Removed --search from codex exec invocations (unsupported by codex exec)
|
|
582
|
+
- Advisory failures tracked in gate snapshot for operator visibility
|
package/docs/README.md
CHANGED
|
@@ -54,7 +54,11 @@ 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.7
|
|
57
|
+
Read [guides/recommendations-0.9.7
|
|
58
|
+
- [0.9.8 Operating Recommendations](guides/recommendations-0.9.8.md
|
|
59
|
+
- [0.9.9 Recommendations](guides/recommendations-0.9.9.md)).md](./guides/recommendations-0.9.7
|
|
60
|
+
- [0.9.8 Operating Recommendations](guides/recommendations-0.9.8.md
|
|
61
|
+
- [0.9.9 Recommendations](guides/recommendations-0.9.9.md)).md) for the recommended default around relaxed blocker states, advisory turn budgets, and targeted recovery.
|
|
58
62
|
- Want the concrete runtime module map:
|
|
59
63
|
Read [plans/end-state-architecture.md](./plans/end-state-architecture.md) for the engine-by-engine architecture and artifact ownership model.
|
|
60
64
|
- Want the CLI surface map:
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "0.9.8 Recommendations"
|
|
3
|
+
summary: "How to use 0.9.8's softer blocker states, advisory turn budgets, and targeted recovery without weakening proof and closure."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.9.8 Recommendations
|
|
7
|
+
|
|
8
|
+
Use this guide when you are adopting `0.9.8` 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.8` 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.8` 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.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "0.9.9 Recommendations"
|
|
3
|
+
summary: "How to use 0.9.9's softer blocker states, advisory turn budgets, and targeted recovery without weakening proof and closure."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.9.9 Recommendations
|
|
7
|
+
|
|
8
|
+
Use this guide when you are adopting `0.9.9` 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.9` 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.9` 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.
|
package/docs/plans/migration.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Migration
|
|
2
2
|
|
|
3
|
-
This page is the practical repo-upgrade guide for the current `0.9.
|
|
3
|
+
This page is the practical repo-upgrade guide for the current `0.9.9` surface.
|
|
4
4
|
|
|
5
5
|
Use it when you are:
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ The `0.9.4` surface adds laddered gate modes and fixes the steward threshold enf
|
|
|
24
24
|
|
|
25
25
|
## What `0.9.4` Changes
|
|
26
26
|
|
|
27
|
-
The current `0.9.
|
|
27
|
+
The current `0.9.9` surface keeps everything from `0.9.2` and adds two focused improvements with no breaking changes.
|
|
28
28
|
|
|
29
29
|
The practical changes are:
|
|
30
30
|
|
|
@@ -182,7 +182,7 @@ Use `pnpm exec wave dashboard --lane <lane> --attach current` or `--attach globa
|
|
|
182
182
|
|
|
183
183
|
## `0.9.4` Release Model
|
|
184
184
|
|
|
185
|
-
The current `0.9.
|
|
185
|
+
The current `0.9.9` surface combines these strands:
|
|
186
186
|
|
|
187
187
|
- the gap-value wave-gate fix and first-time setup UX improvements released in `0.9.4`
|
|
188
188
|
- the detached process-runner and sandbox supervisor hardening released in `0.9.2`
|
|
@@ -367,7 +367,11 @@ If your repo copied starter config defaults, also sync the `designRolePromptPath
|
|
|
367
367
|
- hybrid design stewards rejoin implementation when they explicitly own code
|
|
368
368
|
- long-running prompts receive signal-state and ack paths when the repo uses the new waiting model
|
|
369
369
|
|
|
370
|
-
## Upgrading From `0.8
|
|
370
|
+
## Upgrading From `0.9.8` To `0.9.9`
|
|
371
|
+
|
|
372
|
+
Helper assignment barriers are now advisory in bootstrap gate mode. No config changes needed.
|
|
373
|
+
|
|
374
|
+
## Upgrading From `0.8.3` To `0.9.9`
|
|
371
375
|
|
|
372
376
|
Treat this as one move to the current `0.9.2` surface.
|
|
373
377
|
|
|
@@ -402,7 +406,7 @@ If your repo copied starter docs or skills, sync:
|
|
|
402
406
|
- dry-run one design-steward wave if the repo wants the new authored surface
|
|
403
407
|
- 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
|
|
404
408
|
|
|
405
|
-
## Upgrading From `0.6.x` Or `0.7.x` To `0.9.
|
|
409
|
+
## Upgrading From `0.6.x` Or `0.7.x` To `0.9.9`
|
|
406
410
|
|
|
407
411
|
This is the main migration path for older adopted repos.
|
|
408
412
|
|
|
@@ -553,4 +557,4 @@ For repos that depend on replay parity, replay at least:
|
|
|
553
557
|
|
|
554
558
|
## Summary
|
|
555
559
|
|
|
556
|
-
The current `0.9.
|
|
560
|
+
The current `0.9.9` 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
package/releases/manifest.json
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "@chllming/wave-orchestration",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.9.9",
|
|
7
|
+
"date": "2026-04-07",
|
|
8
|
+
"summary": "Helper assignment barrier is advisory in bootstrap gate mode; planner-agentic bundle remains available.",
|
|
9
|
+
"features": [
|
|
10
|
+
"Helper assignment barrier is now advisory (non-blocking) in bootstrap gate mode, preventing unnecessary retries when assigned agents complete successfully.",
|
|
11
|
+
"planner-agentic bundle placeholder remains available for adopted repos."
|
|
12
|
+
],
|
|
13
|
+
"manualSteps": [],
|
|
14
|
+
"breaking": false
|
|
15
|
+
},
|
|
5
16
|
{
|
|
6
17
|
"version": "0.9.7",
|
|
7
18
|
"date": "2026-04-06",
|
|
@@ -590,4 +601,4 @@
|
|
|
590
601
|
"breaking": false
|
|
591
602
|
}
|
|
592
603
|
]
|
|
593
|
-
}
|
|
604
|
+
}
|
|
@@ -1080,7 +1080,7 @@ function normalizeExecutors(rawExecutors = {}) {
|
|
|
1080
1080
|
appendSystemPromptMode: normalizeClaudePromptMode(
|
|
1081
1081
|
executors.claude?.appendSystemPromptMode,
|
|
1082
1082
|
),
|
|
1083
|
-
permissionMode: normalizeOptionalString(executors.claude?.permissionMode,
|
|
1083
|
+
permissionMode: normalizeOptionalString(executors.claude?.permissionMode, "bypassPermissions"),
|
|
1084
1084
|
permissionPromptTool: normalizeOptionalString(
|
|
1085
1085
|
executors.claude?.permissionPromptTool,
|
|
1086
1086
|
null,
|
|
@@ -193,7 +193,6 @@ export function buildCodexExecInvocation(
|
|
|
193
193
|
appendSingleValueFlag(tokens, "--model", options.model);
|
|
194
194
|
appendSingleValueFlag(tokens, "--profile", options.profileName);
|
|
195
195
|
appendRepeatedFlag(tokens, "-c", options.config);
|
|
196
|
-
appendBooleanFlag(tokens, "--search", options.search);
|
|
197
196
|
appendRepeatedFlag(tokens, "--image", options.images);
|
|
198
197
|
appendRepeatedFlag(tokens, "--add-dir", options.addDirs);
|
|
199
198
|
appendBooleanFlag(tokens, "--json", options.json);
|
|
@@ -1138,7 +1138,8 @@ export function readClarificationBarrier(derivedState) {
|
|
|
1138
1138
|
};
|
|
1139
1139
|
}
|
|
1140
1140
|
|
|
1141
|
-
export function readWaveAssignmentBarrier(derivedState) {
|
|
1141
|
+
export function readWaveAssignmentBarrier(derivedState, options) {
|
|
1142
|
+
const gateMode = options?.gateMode || null;
|
|
1142
1143
|
const blockingAssignments = (derivedState?.capabilityAssignments || []).filter(
|
|
1143
1144
|
(assignment) => assignment.blocking,
|
|
1144
1145
|
);
|
|
@@ -1157,6 +1158,13 @@ export function readWaveAssignmentBarrier(derivedState) {
|
|
|
1157
1158
|
detail: `Helper assignments remain unresolved (${unresolvedAssignments.map((assignment) => assignment.requestId).join(", ")}).`,
|
|
1158
1159
|
};
|
|
1159
1160
|
}
|
|
1161
|
+
if (gateMode === "bootstrap") {
|
|
1162
|
+
return {
|
|
1163
|
+
ok: true,
|
|
1164
|
+
statusCode: "helper-assignment-open-advisory",
|
|
1165
|
+
detail: `Helper assignments remain open but are advisory in bootstrap gate mode (${blockingAssignments.map((assignment) => assignment.requestId).join(", ")}).`,
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1160
1168
|
return {
|
|
1161
1169
|
ok: false,
|
|
1162
1170
|
statusCode: "helper-assignment-open",
|
|
@@ -1552,6 +1560,8 @@ export function buildGateSnapshotPure({ wave, agentResults, derivedState, valida
|
|
|
1552
1560
|
});
|
|
1553
1561
|
const integrationBarrier = (() => {
|
|
1554
1562
|
if (!integrationMarkerGate.ok) { return integrationMarkerGate; }
|
|
1563
|
+
// Short-circuit: no integration steward declared and not required
|
|
1564
|
+
if (!integrationMarkerGate.agentId) { return integrationMarkerGate; }
|
|
1555
1565
|
const integrationSummary = derivedState?.integrationSummary || null;
|
|
1556
1566
|
if (!integrationSummary) {
|
|
1557
1567
|
return { ok: false, agentId: integrationMarkerGate.agentId,
|
|
@@ -1602,16 +1612,33 @@ export function buildGateSnapshotPure({ wave, agentResults, derivedState, valida
|
|
|
1602
1612
|
["componentMatrixGate", componentMatrixGate], ["contQaGate", contQaGate],
|
|
1603
1613
|
["infraGate", infraGate], ["clarificationBarrier", clarificationBarrier],
|
|
1604
1614
|
];
|
|
1605
|
-
const
|
|
1615
|
+
const gateMode = laneConfig.gateMode || "strict";
|
|
1616
|
+
// In bootstrap mode, these gates are advisory (non-blocking)
|
|
1617
|
+
const bootstrapAdvisoryGates = new Set([
|
|
1618
|
+
"documentationGate", "contQaGate", "integrationBarrier",
|
|
1619
|
+
"componentMatrixGate", "componentGate",
|
|
1620
|
+
]);
|
|
1621
|
+
const firstFailure = orderedGates.find(([name, gate]) => {
|
|
1622
|
+
if (!gate || gate.ok !== false) return false;
|
|
1623
|
+
if (gateMode === "bootstrap" && bootstrapAdvisoryGates.has(name)) return false;
|
|
1624
|
+
return true;
|
|
1625
|
+
});
|
|
1626
|
+
const advisoryFailures = gateMode === "bootstrap"
|
|
1627
|
+
? orderedGates.filter(([name, gate]) => gate?.ok === false && bootstrapAdvisoryGates.has(name))
|
|
1628
|
+
: [];
|
|
1606
1629
|
return {
|
|
1607
1630
|
designGate, implementationGate, componentGate, integrationGate: integrationMarkerGate,
|
|
1608
1631
|
integrationBarrier, documentationGate, componentMatrixGate,
|
|
1609
1632
|
contEvalGate, securityGate, contQaGate, infraGate,
|
|
1610
1633
|
clarificationBarrier, helperAssignmentBarrier, dependencyBarrier,
|
|
1634
|
+
gateMode,
|
|
1635
|
+
advisoryFailures: advisoryFailures.map(([name, gate]) => ({ gate: name, ...gate })),
|
|
1611
1636
|
overall: firstFailure
|
|
1612
1637
|
? { ok: false, gate: firstFailure[0], statusCode: firstFailure[1].statusCode,
|
|
1613
1638
|
detail: firstFailure[1].detail, agentId: firstFailure[1].agentId || null }
|
|
1614
1639
|
: { ok: true, gate: "pass", statusCode: "pass",
|
|
1615
|
-
detail:
|
|
1640
|
+
detail: gateMode === "bootstrap"
|
|
1641
|
+
? `Bootstrap pass: impl gates passed (${advisoryFailures.length} advisory).`
|
|
1642
|
+
: "All replayed wave gates passed.", agentId: null },
|
|
1616
1643
|
};
|
|
1617
1644
|
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
buildGateSnapshotPure,
|
|
20
20
|
readClarificationBarrier,
|
|
21
21
|
readWaveAssignmentBarrier,
|
|
22
|
+
resolveGateMode,
|
|
22
23
|
} from "./gate-engine.mjs";
|
|
23
24
|
import { buildHumanInputRequests } from "./human-input-workflow.mjs";
|
|
24
25
|
import { projectLegacySummaryFromEnvelope } from "./result-envelope.mjs";
|
|
@@ -713,7 +714,9 @@ export function reduceWaveState({
|
|
|
713
714
|
Array.isArray(waveDefinition?.agents) ? waveDefinition.agents : [],
|
|
714
715
|
laneConfig.capabilityRouting || {},
|
|
715
716
|
);
|
|
716
|
-
const
|
|
717
|
+
const _reducerGateThresholds = laneConfig?.gateModeThresholds || laneConfig?.validation?.gateModeThresholds || null;
|
|
718
|
+
const _reducerGateMode = resolveGateMode(waveDefinition?.wave || 0, _reducerGateThresholds);
|
|
719
|
+
const helperAssignmentBarrier = readWaveAssignmentBarrier({ capabilityAssignments }, { gateMode: _reducerGateMode });
|
|
717
720
|
const dependencyBarrier = (() => {
|
|
718
721
|
if (!dependencyTickets) {
|
|
719
722
|
return { ok: true, statusCode: "pass", detail: "" };
|