@chllming/wave-orchestration 0.9.2 → 0.9.4
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 +30 -0
- package/README.md +8 -9
- package/docs/README.md +3 -3
- package/docs/guides/recommendations-0.9.3.md +137 -0
- package/docs/guides/recommendations-0.9.4.md +191 -0
- package/docs/guides/sandboxed-environments.md +2 -2
- package/docs/plans/current-state.md +2 -2
- package/docs/plans/migration.md +40 -56
- package/docs/reference/coordination-and-closure.md +2 -2
- package/docs/reference/runtime-config/README.md +2 -2
- package/package.json +1 -1
- package/releases/manifest.json +22 -0
- package/scripts/wave-orchestrator/agent-state.mjs +26 -9
- package/scripts/wave-orchestrator/config.mjs +14 -0
- package/scripts/wave-orchestrator/coordination.mjs +1 -1
- package/scripts/wave-orchestrator/gate-engine.mjs +40 -0
- package/scripts/wave-orchestrator/install.mjs +1 -1
- package/scripts/wave-orchestrator/launcher.mjs +21 -3
- package/scripts/wave-orchestrator/planner.mjs +29 -0
- package/scripts/wave-orchestrator/wave-files.mjs +1 -2
- package/wave.config.json +125 -43
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.9.4 - 2026-04-05
|
|
6
|
+
|
|
7
|
+
- Laddered gate modes: bootstrap/standard/strict per wave number
|
|
8
|
+
- Bootstrap pass: exit 0 + deliverables exist = advance (no QA signals needed)
|
|
9
|
+
- Fix: requireDocumentationStewardFromWave threshold strictly respected
|
|
10
|
+
- New config: gateModeThresholds, bootstrapPassConditions, testCommand
|
|
11
|
+
- evaluateBootstrapGate() and resolveGateMode() functions
|
|
12
|
+
|
|
13
|
+
## 0.9.3 - 2026-03-30
|
|
14
|
+
|
|
15
|
+
### Fixed And Hardened
|
|
16
|
+
|
|
17
|
+
- 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.
|
|
18
|
+
- 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.
|
|
19
|
+
- The cont-QA coordination prompt now documents gap as a valid dimension value alongside pass|concerns|blocked.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- First-time wave launch now auto-triggers wave project setup when no project profile exists, matching existing wave draft behavior. (Contributed by @justanothernate in #54)
|
|
24
|
+
- 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)
|
|
25
|
+
- PromptSession gains a describe(text) method for writing contextual help to stderr during interactive setup flows.
|
|
26
|
+
- parseArgs now passes the loaded config object through to runLauncherCli, avoiding a redundant loadWaveConfig() call.
|
|
27
|
+
|
|
28
|
+
### Testing And Validation
|
|
29
|
+
|
|
30
|
+
- `pnpm exec vitest run --config vitest.config.ts`
|
|
31
|
+
- `node scripts/wave.mjs doctor --json`
|
|
32
|
+
- `node scripts/wave.mjs launch --lane main --dry-run --no-dashboard`
|
|
33
|
+
- `pnpm test -- test/wave-orchestrator/release-surface.test.ts`
|
|
34
|
+
|
|
5
35
|
## 0.9.2 - 2026-03-29
|
|
6
36
|
|
|
7
37
|
### Added
|
package/README.md
CHANGED
|
@@ -107,19 +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.
|
|
111
|
-
- Release tag: [`v0.9.
|
|
110
|
+
- `@chllming/wave-orchestration@0.9.4`
|
|
111
|
+
- Release tag: [`v0.9.4`](https://github.com/chllming/agent-wave-orchestrator/releases/tag/v0.9.4)
|
|
112
112
|
- Public install path: npmjs
|
|
113
113
|
- Authenticated fallback: GitHub Packages
|
|
114
114
|
|
|
115
|
-
Highlights in `0.9.
|
|
115
|
+
Highlights in `0.9.4`:
|
|
116
116
|
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
- Release docs, migration guidance, runtime-config and closure references, Wave Control docs, the new Corridor reference, the manifest, and the tracked install-state fixtures now all point at the `0.9.2` surface.
|
|
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
|
+
- 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
|
+
- `PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows.
|
|
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.4` surface.
|
|
123
122
|
|
|
124
123
|
Requirements:
|
|
125
124
|
|
package/docs/README.md
CHANGED
|
@@ -38,7 +38,7 @@ The useful path is journey-first:
|
|
|
38
38
|
- Setting up multiple projects in one monorepo:
|
|
39
39
|
Read [guides/monorepo-projects.md](./guides/monorepo-projects.md) for `defaultProject`, `projects.<projectId>`, project-scoped state paths, and telemetry defaults.
|
|
40
40
|
- Adding an optional pre-implementation design steward:
|
|
41
|
-
Read [guides/author-and-run-waves.md](./guides/author-and-run-waves.md), then the standing prompt in [agents/wave-design-role.md](./agents/wave-design-role.md). The shipped `0.9.
|
|
41
|
+
Read [guides/author-and-run-waves.md](./guides/author-and-run-waves.md), then the standing prompt in [agents/wave-design-role.md](./agents/wave-design-role.md). The shipped `0.9.3` surface includes `role-design` plus `tui-design`, with docs-first design stewards by default and explicit hybrid design stewards when a wave also gives that same agent code ownership.
|
|
42
42
|
- Running in LEAPclaw, OpenClaw, Nemoshell, Docker, or another short-lived sandbox:
|
|
43
43
|
Read [guides/sandboxed-environments.md](./guides/sandboxed-environments.md) first for the submit or supervise pattern, persistent-state expectations, and dashboard guidance, then use [plans/sandbox-end-state-architecture.md](./plans/sandbox-end-state-architecture.md) for the deeper runtime design.
|
|
44
44
|
- Want signal-driven automation or long-running watcher loops:
|
|
@@ -53,8 +53,8 @@ The useful path is journey-first:
|
|
|
53
53
|
Read [plans/migration.md](./plans/migration.md), then review the release notes in [../CHANGELOG.md](../CHANGELOG.md) before running `pnpm exec wave upgrade`.
|
|
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
|
-
- Want the practical `0.9.
|
|
57
|
-
Read [guides/recommendations-0.9.
|
|
56
|
+
- Want the practical `0.9.3` operating stance:
|
|
57
|
+
Read [guides/recommendations-0.9.4.md](./guides/recommendations-0.9.4.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,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "0.9.3 Recommendations"
|
|
3
|
+
summary: "How to use 0.9.3's softer blocker states, advisory turn budgets, and targeted recovery without weakening proof and closure."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 0.9.3 Recommendations
|
|
7
|
+
|
|
8
|
+
Use this guide when you are adopting `0.9.3` 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.3` 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.3` 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,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
|
+
```
|
|
@@ -8,7 +8,7 @@ Typical examples:
|
|
|
8
8
|
- Nemoshell or similar hosted terminal sandboxes
|
|
9
9
|
- Docker or devcontainer setups where the client process is disposable but the workspace and state volume persist
|
|
10
10
|
|
|
11
|
-
The core rule in `0.9.
|
|
11
|
+
The core rule in `0.9.3` is simple:
|
|
12
12
|
|
|
13
13
|
- clients should be short-lived
|
|
14
14
|
- supervision should be long-lived
|
|
@@ -94,7 +94,7 @@ If the sandbox only gives you short exec windows, `wave autonomous` should not b
|
|
|
94
94
|
|
|
95
95
|
## Docker And Containerized Setups
|
|
96
96
|
|
|
97
|
-
Docker works well with the `0.9.
|
|
97
|
+
Docker works well with the `0.9.3` process-backed runner model, but only if the state directories survive container restarts.
|
|
98
98
|
|
|
99
99
|
Recommended container posture:
|
|
100
100
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Current State
|
|
2
2
|
|
|
3
|
-
- The published package is `0.9.
|
|
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.
|
|
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:
|
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.4` surface.
|
|
4
4
|
|
|
5
5
|
Use it when you are:
|
|
6
6
|
|
|
@@ -12,6 +12,36 @@ 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
|
+
|
|
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.4` surface keeps everything from `0.9.2` and adds two focused improvements with no breaking changes.
|
|
28
|
+
|
|
29
|
+
The practical changes are:
|
|
30
|
+
|
|
31
|
+
- `WAVE_GATE_REGEX` now accepts `gap` alongside `pass|concerns|blocked` for all five gate dimensions (architecture, integration, durability, live, docs), so agents that report a documented gap no longer have their marker rejected entirely
|
|
32
|
+
- `validateContQaSummary` treats `gap` dimension values as a conditional pass (`ok: true`, `statusCode: conditional-pass`) instead of a hard blocker
|
|
33
|
+
- the cont-QA coordination prompt now documents `gap` as a valid dimension value
|
|
34
|
+
- first-time `wave launch` now auto-triggers `wave project setup` when no project profile exists, matching existing `wave draft` behavior
|
|
35
|
+
- `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
|
|
36
|
+
- `PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows
|
|
37
|
+
- `parseArgs` now passes the loaded config object through to `runLauncherCli`, avoiding a redundant `loadWaveConfig()` call
|
|
38
|
+
|
|
39
|
+
There are no breaking changes. Just upgrade with `pnpm up @chllming/wave-orchestration` and run `pnpm exec wave upgrade`.
|
|
40
|
+
|
|
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.
|
|
42
|
+
|
|
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).
|
|
44
|
+
|
|
15
45
|
## What `0.9.2` Changes
|
|
16
46
|
|
|
17
47
|
The current `0.9.2` surface keeps the packaged operator-guidance alignment, monorepo project support, and project-aware default telemetry from `0.9.0`, but adds a more sandbox-friendly execution model and lower-overhead live orchestration.
|
|
@@ -150,10 +180,11 @@ pnpm exec wave coord inbox --lane main --wave 0 --agent A1 --dry-run
|
|
|
150
180
|
|
|
151
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.
|
|
152
182
|
|
|
153
|
-
## `0.9.
|
|
183
|
+
## `0.9.4` Release Model
|
|
154
184
|
|
|
155
|
-
The current `0.9.
|
|
185
|
+
The current `0.9.4` surface combines these strands:
|
|
156
186
|
|
|
187
|
+
- the gap-value wave-gate fix and first-time setup UX improvements released in `0.9.4`
|
|
157
188
|
- the detached process-runner and sandbox supervisor hardening released in `0.9.2`
|
|
158
189
|
- the shipped `0.9.0` monorepo project support and project-aware runtime isolation
|
|
159
190
|
- the shipped `design` worker role and hybrid design-steward flow introduced in `0.8.5`
|
|
@@ -261,7 +292,7 @@ The interactive `wave draft` flow supports `design` as a worker role and scaffol
|
|
|
261
292
|
|
|
262
293
|
## Version-Specific Upgrade Guidance
|
|
263
294
|
|
|
264
|
-
## Upgrading From `0.8.5` To `0.
|
|
295
|
+
## Upgrading From `0.8.5` To `0.9.4`
|
|
265
296
|
|
|
266
297
|
This is the smallest upgrade, but it changes the live wait-loop contract for external automation and intentionally long-running agents.
|
|
267
298
|
|
|
@@ -298,7 +329,7 @@ If the repo copied starter surface, sync:
|
|
|
298
329
|
- if the repo uses long-running watchers, confirm they can write the ack file where the prompt tells them to
|
|
299
330
|
- reroute one targeted feedback or coordination request and confirm the resident signal version changes even when the signal kind stays the same
|
|
300
331
|
|
|
301
|
-
## Upgrading From `0.8.4` To `0.
|
|
332
|
+
## Upgrading From `0.8.4` To `0.9.4`
|
|
302
333
|
|
|
303
334
|
### What changed
|
|
304
335
|
|
|
@@ -336,54 +367,7 @@ If your repo copied starter config defaults, also sync the `designRolePromptPath
|
|
|
336
367
|
- hybrid design stewards rejoin implementation when they explicitly own code
|
|
337
368
|
- long-running prompts receive signal-state and ack paths when the repo uses the new waiting model
|
|
338
369
|
|
|
339
|
-
## Upgrading From `0.8.3` To `0.
|
|
340
|
-
|
|
341
|
-
This is the most common one-step package upgrade path.
|
|
342
|
-
|
|
343
|
-
### What changed across that range
|
|
344
|
-
|
|
345
|
-
- `0.8.4` tightened contradiction replay, component-promotion threshold handling, and projection persistence boundaries
|
|
346
|
-
- `0.8.5` ships the `design` worker role, the `role-design` and `tui-design` starter bundles, and the hybrid design-steward runtime model as part of the published package
|
|
347
|
-
- `0.8.6` adds versioned signal snapshots, `signal-hygiene`, prompt-injected signal ack loops, and the seeded operator wrappers
|
|
348
|
-
- current operator and planner docs now describe the shipped surface directly instead of splitting behavior between a published package and newer `main`-only additions
|
|
349
|
-
|
|
350
|
-
### Required repo changes
|
|
351
|
-
|
|
352
|
-
Usually none if the repo does not copy starter prompts, skills, planning docs, or wrapper scripts.
|
|
353
|
-
|
|
354
|
-
### Strongly recommended sync
|
|
355
|
-
|
|
356
|
-
If the repo copied starter surface, sync:
|
|
357
|
-
|
|
358
|
-
- `docs/agents/wave-design-role.md`
|
|
359
|
-
- `skills/role-design/`
|
|
360
|
-
- `skills/tui-design/`
|
|
361
|
-
- `skills/signal-hygiene/`
|
|
362
|
-
- `scripts/wave-status.sh`
|
|
363
|
-
- `scripts/wave-watch.sh`
|
|
364
|
-
- `docs/guides/author-and-run-waves.md`
|
|
365
|
-
- `docs/guides/signal-wrappers.md`
|
|
366
|
-
- `docs/guides/planner.md`
|
|
367
|
-
- `docs/reference/skills.md`
|
|
368
|
-
- `docs/reference/sample-waves.md`
|
|
369
|
-
- `docs/plans/current-state.md`
|
|
370
|
-
- `docs/plans/wave-orchestrator.md`
|
|
371
|
-
- `docs/plans/end-state-architecture.md`
|
|
372
|
-
|
|
373
|
-
If the repo copied starter `wave.config.json` defaults, also sync:
|
|
374
|
-
|
|
375
|
-
- `roles.designRolePromptPath`
|
|
376
|
-
- `skills.byRole.design`
|
|
377
|
-
- `executors.profiles.design-pass`
|
|
378
|
-
|
|
379
|
-
### Validation focus
|
|
380
|
-
|
|
381
|
-
- confirm contradiction-blocked replay cases still compare cleanly if the repo keeps replay fixtures
|
|
382
|
-
- if the repo uses design stewards, confirm packet-only design waves still block implementation until `ready-for-implementation`
|
|
383
|
-
- if the repo uses hybrid design stewards, confirm the same agent rejoins implementation only when the authored wave explicitly gives it code ownership
|
|
384
|
-
- if the repo uses long-running agents or shell automation, confirm the new wrapper exit contract and ack-loop semantics before relying on an older polling script
|
|
385
|
-
|
|
386
|
-
## Upgrading From `0.8.3` To `0.9.2`
|
|
370
|
+
## Upgrading From `0.8.3` To `0.9.4`
|
|
387
371
|
|
|
388
372
|
Treat this as one move to the current `0.9.2` surface.
|
|
389
373
|
|
|
@@ -418,7 +402,7 @@ If your repo copied starter docs or skills, sync:
|
|
|
418
402
|
- dry-run one design-steward wave if the repo wants the new authored surface
|
|
419
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
|
|
420
404
|
|
|
421
|
-
## Upgrading From `0.6.x` Or `0.7.x` To `0.9.
|
|
405
|
+
## Upgrading From `0.6.x` Or `0.7.x` To `0.9.4`
|
|
422
406
|
|
|
423
407
|
This is the main migration path for older adopted repos.
|
|
424
408
|
|
|
@@ -459,7 +443,7 @@ pnpm exec wave control proof get --lane main --wave 0 --json
|
|
|
459
443
|
|
|
460
444
|
If the repo carries proof-first waves, verify that required proof artifacts still exist locally and not only in historical summaries.
|
|
461
445
|
|
|
462
|
-
## Upgrading From `0.5.x` Or Earlier To `0.9.
|
|
446
|
+
## Upgrading From `0.5.x` Or Earlier To `0.9.4`
|
|
463
447
|
|
|
464
448
|
Do not treat this as a tiny patch bump.
|
|
465
449
|
|
|
@@ -569,4 +553,4 @@ For repos that depend on replay parity, replay at least:
|
|
|
569
553
|
|
|
570
554
|
## Summary
|
|
571
555
|
|
|
572
|
-
The current `0.9.
|
|
556
|
+
The current `0.9.4` 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.
|
|
@@ -428,9 +428,9 @@ The important distinction is:
|
|
|
428
428
|
`cont-QA` must emit:
|
|
429
429
|
|
|
430
430
|
- a final verdict
|
|
431
|
-
- a final `[wave-gate]` marker
|
|
431
|
+
- a final `[wave-gate]` marker with each of the five gate dimensions (architecture, integration, durability, live, docs) set to `pass`, `concerns`, `blocked`, or `gap`
|
|
432
432
|
|
|
433
|
-
Final PASS requires all gate dimensions to pass in the final state.
|
|
433
|
+
Final PASS requires all gate dimensions to be `pass` or `gap` in the final state. A `gap` value means the dimension has a documented gap that is not an actionable blocker; it is treated as a conditional pass (`ok: true`, `statusCode: conditional-pass`) with detail text listing which dimensions have documented gaps.
|
|
434
434
|
|
|
435
435
|
## Why The Closure Model Works
|
|
436
436
|
|
|
@@ -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.
|
|
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
|
|
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.
|
|
206
|
+
Packaged defaults in `@chllming/wave-orchestration@0.9.3`:
|
|
207
207
|
|
|
208
208
|
- `endpoint`: `https://wave-control.up.railway.app/api/v1`
|
|
209
209
|
- `reportMode`: `metadata-only`
|
package/package.json
CHANGED
package/releases/manifest.json
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "@chllming/wave-orchestration",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.9.4",
|
|
7
|
+
"date": "2026-03-30",
|
|
8
|
+
"summary": "Gap-value wave-gate fix and first-time project setup UX improvements.",
|
|
9
|
+
"features": [
|
|
10
|
+
"WAVE_GATE_REGEX now accepts `gap` alongside `pass|concerns|blocked` for all five gate dimensions (architecture, integration, durability, live, docs), so agents reporting a documented gap no longer have their marker rejected entirely.",
|
|
11
|
+
"`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.",
|
|
12
|
+
"The cont-QA coordination prompt now documents `gap` as a valid dimension value alongside `pass|concerns|blocked`.",
|
|
13
|
+
"First-time `wave launch` now auto-triggers `wave project setup` when no project profile exists, matching existing `wave draft` behavior. (Contributed by @justanothernate in #54)",
|
|
14
|
+
"`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
|
+
"`PromptSession` gains a `describe(text)` method for writing contextual help to stderr during interactive setup flows.",
|
|
16
|
+
"`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.4` surface.",
|
|
18
|
+
"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
|
+
],
|
|
20
|
+
"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.4` release surface.",
|
|
22
|
+
"Push the `v0.9.4` 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.4.md` so local guidance matches the packaged release."
|
|
24
|
+
],
|
|
25
|
+
"breaking": false
|
|
26
|
+
},
|
|
5
27
|
{
|
|
6
28
|
"version": "0.9.2",
|
|
7
29
|
"date": "2026-03-29",
|
|
@@ -50,7 +50,7 @@ const WAVE_SECURITY_REGEX =
|
|
|
50
50
|
const WAVE_DESIGN_REGEX =
|
|
51
51
|
/^\[wave-design\]\s*state=(ready-for-implementation|needs-clarification|blocked)\s+decisions=(\d+)\s+assumptions=(\d+)\s+open_questions=(\d+)\s*(?:detail=(.*))?$/gim;
|
|
52
52
|
const WAVE_GATE_REGEX =
|
|
53
|
-
/^\[wave-gate\]\s*architecture=(pass|concerns|blocked)\s+integration=(pass|concerns|blocked)\s+durability=(pass|concerns|blocked)\s+live=(pass|concerns|blocked)\s+docs=(pass|concerns|blocked)\s*(?:detail=(.*))?$/gim;
|
|
53
|
+
/^\[wave-gate\]\s*architecture=(pass|concerns|blocked|gap)\s+integration=(pass|concerns|blocked|gap)\s+durability=(pass|concerns|blocked|gap)\s+live=(pass|concerns|blocked|gap)\s+docs=(pass|concerns|blocked|gap)\s*(?:detail=(.*))?$/gim;
|
|
54
54
|
const WAVE_GAP_REGEX =
|
|
55
55
|
/^\[wave-gap\]\s*kind=(architecture|integration|durability|ops|docs)\s*(?:detail=(.*))?$/gim;
|
|
56
56
|
const WAVE_COMPONENT_REGEX =
|
|
@@ -1268,17 +1268,34 @@ export function validateContQaSummary(agent, summary, options = {}) {
|
|
|
1268
1268
|
detail: summary.verdict.detail || "Verdict read from cont-QA report.",
|
|
1269
1269
|
};
|
|
1270
1270
|
}
|
|
1271
|
+
const hardBlockers = [];
|
|
1272
|
+
const documentedGaps = [];
|
|
1271
1273
|
for (const key of ["architecture", "integration", "durability", "live", "docs"]) {
|
|
1272
|
-
if (summary.gate[key]
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
detail:
|
|
1277
|
-
summary.gate.detail ||
|
|
1278
|
-
`Final cont-QA gate did not pass ${key}; got ${summary.gate[key]}.`,
|
|
1279
|
-
};
|
|
1274
|
+
if (summary.gate[key] === "gap") {
|
|
1275
|
+
documentedGaps.push(key);
|
|
1276
|
+
} else if (summary.gate[key] !== "pass") {
|
|
1277
|
+
hardBlockers.push(key);
|
|
1280
1278
|
}
|
|
1281
1279
|
}
|
|
1280
|
+
if (hardBlockers.length > 0) {
|
|
1281
|
+
const key = hardBlockers[0];
|
|
1282
|
+
return {
|
|
1283
|
+
ok: false,
|
|
1284
|
+
statusCode: `gate-${key}-${summary.gate[key]}`,
|
|
1285
|
+
detail:
|
|
1286
|
+
summary.gate.detail ||
|
|
1287
|
+
`Final cont-QA gate did not pass ${key}; got ${summary.gate[key]}.`,
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
if (documentedGaps.length > 0) {
|
|
1291
|
+
return {
|
|
1292
|
+
ok: true,
|
|
1293
|
+
statusCode: "conditional-pass",
|
|
1294
|
+
detail:
|
|
1295
|
+
summary.gate.detail ||
|
|
1296
|
+
`cont-QA gate passed with documented gaps in: ${documentedGaps.join(", ")}.`,
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1282
1299
|
return {
|
|
1283
1300
|
ok: true,
|
|
1284
1301
|
statusCode: "pass",
|
|
@@ -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
|
|
|
@@ -253,7 +253,7 @@ export function buildExecutionPrompt({
|
|
|
253
253
|
? [
|
|
254
254
|
`- Because you are Agent ${contQaAgentId}, your cont-QA report must end with exactly one standalone line in the form \`Verdict: PASS\`, \`Verdict: CONCERNS\`, or \`Verdict: BLOCKED\`.`,
|
|
255
255
|
"- Also emit one matching structured marker in your terminal output: `[wave-verdict] pass`, `[wave-verdict] concerns`, or `[wave-verdict] blocked`.",
|
|
256
|
-
"- Emit one final structured gate marker: `[wave-gate] architecture=<pass|concerns|blocked> integration=<pass|concerns|blocked> durability=<pass|concerns|blocked> live=<pass|concerns|blocked> docs=<pass|concerns|blocked> detail=<short-note>`.",
|
|
256
|
+
"- Emit one final structured gate marker: `[wave-gate] architecture=<pass|concerns|blocked|gap> integration=<pass|concerns|blocked|gap> durability=<pass|concerns|blocked|gap> live=<pass|concerns|blocked|gap> docs=<pass|concerns|blocked|gap> detail=<short-note>`.",
|
|
257
257
|
"- Only use `Verdict: PASS` when the wave is coherent enough to unblock the next wave.",
|
|
258
258
|
`- Do not declare PASS until the documentation gate is closed: impacted implementation-owned docs must exist, ${sharedPlanDocList} must reflect plan-affecting outcomes, and no unresolved architecture-versus-plans drift remains.`,
|
|
259
259
|
"- If shared-plan reconciliation is still active inside the wave, require the exact remaining doc delta and an explicit `closed` or `no-change` note from the documentation steward or named owner before finalizing. Do not treat ownership handoff alone as the blocker.",
|
|
@@ -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.
|
|
72
|
+
"docs/guides/recommendations-0.9.4.md",
|
|
73
73
|
"docs/guides/sandboxed-environments.md",
|
|
74
74
|
"docs/guides/signal-wrappers.md",
|
|
75
75
|
"docs/guides/terminal-surfaces.md",
|
|
@@ -332,7 +332,7 @@ function parseArgs(argv) {
|
|
|
332
332
|
continue;
|
|
333
333
|
}
|
|
334
334
|
if (arg === "--help" || arg === "-h") {
|
|
335
|
-
return { help: true, lanePaths, options };
|
|
335
|
+
return { help: true, lanePaths, options, config };
|
|
336
336
|
}
|
|
337
337
|
if (arg === "--dry-run") {
|
|
338
338
|
options.dryRun = true;
|
|
@@ -474,7 +474,7 @@ function parseArgs(argv) {
|
|
|
474
474
|
if (!options.dryRun && options.terminalSurface === "none") {
|
|
475
475
|
throw new Error("--terminal-surface none is only supported with --dry-run");
|
|
476
476
|
}
|
|
477
|
-
return { help: false, lanePaths, options };
|
|
477
|
+
return { help: false, lanePaths, options, config };
|
|
478
478
|
}
|
|
479
479
|
|
|
480
480
|
// --- Local wrappers that bind engine calls to launcher scope ---
|
|
@@ -755,7 +755,25 @@ export async function runLauncherCli(argv) {
|
|
|
755
755
|
printUsage(parsed.lanePaths, parsed.options.terminalSurface);
|
|
756
756
|
return;
|
|
757
757
|
}
|
|
758
|
-
const { lanePaths, options } = parsed;
|
|
758
|
+
const { lanePaths, options, config } = parsed;
|
|
759
|
+
|
|
760
|
+
// Auto-run project setup on first launch if no profile exists yet.
|
|
761
|
+
const projectId = options.project || config.defaultProject;
|
|
762
|
+
if (!readProjectProfile({ config, project: projectId })) {
|
|
763
|
+
const { stderr: stderrStream } = await import("node:process");
|
|
764
|
+
stderrStream.write(
|
|
765
|
+
"\n No project profile found — running first-time setup.\n" +
|
|
766
|
+
" You can re-run this later with: wave project setup\n\n",
|
|
767
|
+
);
|
|
768
|
+
const { runPlannerCli } = await import("./planner.mjs");
|
|
769
|
+
await runPlannerCli(["project", "setup", ...(projectId ? ["--project", projectId] : [])]);
|
|
770
|
+
// Re-read the terminal surface from the newly created profile.
|
|
771
|
+
const freshProfile = readProjectProfile({ config, project: projectId });
|
|
772
|
+
if (freshProfile) {
|
|
773
|
+
options.terminalSurface = resolveDefaultTerminalSurface(freshProfile);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
759
777
|
const supervisorRunId = String(process.env.WAVE_SUPERVISOR_RUN_ID || "").trim() || null;
|
|
760
778
|
const launcherProgressPath = launcherProgressPathForRun(lanePaths, supervisorRunId);
|
|
761
779
|
const writeLauncherRunProgress = (patch = {}) => {
|
|
@@ -486,6 +486,10 @@ class PromptSession {
|
|
|
486
486
|
}
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
+
describe(text) {
|
|
490
|
+
stderr.write(` ${text}\n`);
|
|
491
|
+
}
|
|
492
|
+
|
|
489
493
|
async close() {
|
|
490
494
|
this.interface?.close();
|
|
491
495
|
}
|
|
@@ -2925,7 +2929,13 @@ async function runProjectSetupFlow(options = {}) {
|
|
|
2925
2929
|
const laneChoices = Array.from(
|
|
2926
2930
|
new Set([config.defaultLane, ...projectLanes, ...Object.keys(config.lanes || {})].filter(Boolean)),
|
|
2927
2931
|
);
|
|
2932
|
+
stderr.write("\n Wave project setup — answer a few questions so Wave can tailor defaults for this repo.\n Press Enter to accept the default shown in [brackets].\n\n");
|
|
2933
|
+
prompt.describe("Is this a fresh start, or has Wave been used in this repo before?");
|
|
2928
2934
|
const newProject = await prompt.askBoolean("Treat this repository as a new project?", base.newProject);
|
|
2935
|
+
|
|
2936
|
+
prompt.describe("\nShould you review agent progress yourself, or let them run autonomously?");
|
|
2937
|
+
prompt.describe(" oversight — you review progress and approve risky steps (recommended)");
|
|
2938
|
+
prompt.describe(" dark-factory — agents run end-to-end without human checkpoints");
|
|
2929
2939
|
const defaultOversightMode = normalizeOversightMode(
|
|
2930
2940
|
await prompt.askChoice(
|
|
2931
2941
|
"Default execution posture",
|
|
@@ -2933,6 +2943,10 @@ async function runProjectSetupFlow(options = {}) {
|
|
|
2933
2943
|
base.defaultOversightMode,
|
|
2934
2944
|
),
|
|
2935
2945
|
);
|
|
2946
|
+
|
|
2947
|
+
prompt.describe("\nHow do you want to watch agent sessions?");
|
|
2948
|
+
prompt.describe(" vscode — agent sessions appear as VS Code terminal tabs");
|
|
2949
|
+
prompt.describe(" tmux — agent sessions run in tmux panes (terminal-native)");
|
|
2936
2950
|
const defaultTerminalSurface = normalizeTerminalSurface(
|
|
2937
2951
|
await prompt.askChoice(
|
|
2938
2952
|
"Default terminal surface",
|
|
@@ -2940,6 +2954,12 @@ async function runProjectSetupFlow(options = {}) {
|
|
|
2940
2954
|
base.defaultTerminalSurface,
|
|
2941
2955
|
),
|
|
2942
2956
|
);
|
|
2957
|
+
|
|
2958
|
+
prompt.describe("\nWhat kind of work will waves usually do?");
|
|
2959
|
+
prompt.describe(" implementation — building features, fixing bugs, writing code (most common)");
|
|
2960
|
+
prompt.describe(" qa — test coverage, test infrastructure, validation work");
|
|
2961
|
+
prompt.describe(" infra — deployment, CI/CD, infrastructure changes");
|
|
2962
|
+
prompt.describe(" release — versioning, changelog, release coordination");
|
|
2943
2963
|
const template = normalizeDraftTemplate(
|
|
2944
2964
|
await prompt.askChoice(
|
|
2945
2965
|
"Default draft template",
|
|
@@ -2947,11 +2967,20 @@ async function runProjectSetupFlow(options = {}) {
|
|
|
2947
2967
|
base.plannerDefaults.template,
|
|
2948
2968
|
),
|
|
2949
2969
|
);
|
|
2970
|
+
|
|
2971
|
+
prompt.describe("\nWhich lane should new waves go into? A lane is just an ordered sequence of waves.");
|
|
2972
|
+
prompt.describe("'main' is the default and usually fine to start with.");
|
|
2950
2973
|
const lane = await prompt.askChoice(
|
|
2951
2974
|
"Default draft lane",
|
|
2952
2975
|
laneChoices,
|
|
2953
2976
|
base.plannerDefaults.lane,
|
|
2954
2977
|
);
|
|
2978
|
+
|
|
2979
|
+
prompt.describe("\nDo you have deploy environments (e.g. staging, production) you want Wave to know about?");
|
|
2980
|
+
prompt.describe("This helps Wave attach the right deployment skills when agents do infra or release work.");
|
|
2981
|
+
prompt.describe("Supported providers: railway, docker-compose, kubernetes, ssh-manual.");
|
|
2982
|
+
prompt.describe("Use 'custom' for anything else (GitHub Actions, Vercel, Cloudflare, etc.).");
|
|
2983
|
+
prompt.describe("You can skip this now (enter 0) and add them later with 'wave project setup'.");
|
|
2955
2984
|
const deployEnvironmentCount = await prompt.askInteger(
|
|
2956
2985
|
"How many deploy environments should the planner remember?",
|
|
2957
2986
|
base.deployEnvironments.length,
|
|
@@ -1786,8 +1786,7 @@ export function validateWaveDefinition(wave, options = {}) {
|
|
|
1786
1786
|
}
|
|
1787
1787
|
}
|
|
1788
1788
|
const documentationRuleActive =
|
|
1789
|
-
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
72
|
+
"tags": [
|
|
73
|
+
"design",
|
|
74
|
+
"review"
|
|
75
|
+
],
|
|
67
76
|
"budget": {
|
|
68
|
-
"turns": 10,
|
|
69
77
|
"minutes": 30
|
|
70
78
|
},
|
|
71
79
|
"claude": {
|
|
72
|
-
"allowedTools": [
|
|
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": [
|
|
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": [
|
|
104
|
+
"config": [
|
|
105
|
+
"model_reasoning_effort=high"
|
|
106
|
+
]
|
|
87
107
|
}
|
|
88
108
|
},
|
|
89
109
|
"security-review": {
|
|
90
110
|
"id": "claude",
|
|
91
|
-
"tags": [
|
|
111
|
+
"tags": [
|
|
112
|
+
"security",
|
|
113
|
+
"review"
|
|
114
|
+
],
|
|
92
115
|
"budget": {
|
|
93
|
-
"turns": 8,
|
|
94
116
|
"minutes": 20
|
|
95
117
|
},
|
|
96
118
|
"claude": {
|
|
97
|
-
"allowedTools": [
|
|
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": [
|
|
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": [
|
|
156
|
+
"base": [
|
|
157
|
+
"wave-core",
|
|
158
|
+
"repo-coding-rules"
|
|
159
|
+
],
|
|
126
160
|
"byRole": {
|
|
127
|
-
"design": [
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
"
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"
|
|
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": [
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
"
|
|
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": [
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"
|
|
152
|
-
|
|
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": [
|
|
304
|
+
"fallbackExecutorOrder": [
|
|
305
|
+
"claude",
|
|
306
|
+
"opencode",
|
|
307
|
+
"codex"
|
|
308
|
+
]
|
|
227
309
|
}
|
|
228
310
|
}
|
|
229
311
|
}
|
|
230
|
-
}
|
|
312
|
+
}
|