@chllming/wave-orchestration 0.9.1 → 0.9.3
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 +52 -1
- package/LICENSE.md +21 -0
- package/README.md +20 -9
- package/docs/README.md +8 -4
- package/docs/agents/wave-security-role.md +1 -0
- package/docs/architecture/README.md +1 -1
- package/docs/concepts/operating-modes.md +1 -1
- package/docs/guides/author-and-run-waves.md +1 -1
- package/docs/guides/planner.md +2 -2
- package/docs/guides/{recommendations-0.9.1.md → recommendations-0.9.2.md} +7 -7
- package/docs/guides/recommendations-0.9.3.md +137 -0
- package/docs/guides/sandboxed-environments.md +2 -2
- package/docs/plans/current-state.md +8 -2
- package/docs/plans/end-state-architecture.md +1 -1
- package/docs/plans/examples/wave-example-design-handoff.md +1 -1
- package/docs/plans/examples/wave-example-live-proof.md +1 -1
- package/docs/plans/migration.md +65 -67
- package/docs/reference/cli-reference.md +1 -1
- package/docs/reference/coordination-and-closure.md +20 -3
- package/docs/reference/corridor.md +225 -0
- package/docs/reference/npmjs-token-publishing.md +2 -2
- package/docs/reference/package-publishing-flow.md +11 -11
- package/docs/reference/runtime-config/README.md +61 -3
- package/docs/reference/sample-waves.md +5 -5
- package/docs/reference/skills.md +1 -1
- package/docs/reference/wave-control.md +358 -27
- package/docs/roadmap.md +12 -19
- package/package.json +1 -1
- package/releases/manifest.json +44 -3
- package/scripts/wave-cli-bootstrap.mjs +52 -1
- package/scripts/wave-orchestrator/agent-state.mjs +26 -9
- package/scripts/wave-orchestrator/config.mjs +199 -3
- package/scripts/wave-orchestrator/context7.mjs +231 -29
- package/scripts/wave-orchestrator/coordination.mjs +15 -1
- package/scripts/wave-orchestrator/corridor.mjs +363 -0
- package/scripts/wave-orchestrator/derived-state-engine.mjs +38 -1
- package/scripts/wave-orchestrator/gate-engine.mjs +20 -0
- package/scripts/wave-orchestrator/install.mjs +34 -1
- package/scripts/wave-orchestrator/launcher-runtime.mjs +111 -7
- package/scripts/wave-orchestrator/launcher.mjs +21 -3
- package/scripts/wave-orchestrator/planner.mjs +30 -0
- package/scripts/wave-orchestrator/projection-writer.mjs +23 -0
- package/scripts/wave-orchestrator/provider-runtime.mjs +104 -0
- package/scripts/wave-orchestrator/shared.mjs +1 -0
- package/scripts/wave-orchestrator/traces.mjs +25 -0
- package/scripts/wave-orchestrator/wave-control-client.mjs +14 -1
|
@@ -8,6 +8,7 @@ Use it when you need the full supported surface for:
|
|
|
8
8
|
- `defaultProject` and `projects.<projectId>`
|
|
9
9
|
- `lanes.<lane>.executors`
|
|
10
10
|
- `waveControl`
|
|
11
|
+
- `externalProviders`
|
|
11
12
|
- `executors.profiles.<profile>`
|
|
12
13
|
- per-agent `### Executor` blocks inside a wave file
|
|
13
14
|
|
|
@@ -190,7 +191,7 @@ Practical guidance:
|
|
|
190
191
|
- prefer `budget.minutes` for normal synthesis, integration, and closure work
|
|
191
192
|
- use generic `budget.turns` as a planning hint, not a hard failure trigger
|
|
192
193
|
- only set `claude.maxTurns` or `opencode.steps` when you deliberately want a hard ceiling for that runtime
|
|
193
|
-
- 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
|
|
194
195
|
|
|
195
196
|
## Runtime Pages
|
|
196
197
|
|
|
@@ -202,7 +203,7 @@ Practical guidance:
|
|
|
202
203
|
|
|
203
204
|
`wave.config.json` may also declare a `waveControl` block for local-first telemetry delivery.
|
|
204
205
|
|
|
205
|
-
Packaged defaults in `@chllming/wave-orchestration@0.9.
|
|
206
|
+
Packaged defaults in `@chllming/wave-orchestration@0.9.3`:
|
|
206
207
|
|
|
207
208
|
- `endpoint`: `https://wave-control.up.railway.app/api/v1`
|
|
208
209
|
- `reportMode`: `metadata-only`
|
|
@@ -219,7 +220,10 @@ Supported top-level fields:
|
|
|
219
220
|
| `endpoint` | string | `https://wave-control.up.railway.app/api/v1` | Base URL for the Railway-hosted `services/wave-control` API |
|
|
220
221
|
| `workspaceId` | string | derived from repo path | Stable workspace identity used across runs |
|
|
221
222
|
| `projectId` | string | resolved project id | Stable project identity used for cross-workspace reporting and filtering |
|
|
222
|
-
| `authTokenEnvVar` | string | `
|
|
223
|
+
| `authTokenEnvVar` | string | `WAVE_API_TOKEN` | Primary environment variable name holding the bearer token |
|
|
224
|
+
| `authTokenEnvVars` | string[] | `["WAVE_API_TOKEN", "WAVE_CONTROL_AUTH_TOKEN"]` | Ordered fallback env var list consulted when Wave resolves a bearer token for owned Wave Control routes |
|
|
225
|
+
| `credentialProviders` | string[] | `[]` | Allowlisted runtime credential leases requested from an owned Wave Control deployment before executor launch. Supported values: `openai`, `anthropic` |
|
|
226
|
+
| `credentials` | `{ id, envVar }[]` | `[]` | Arbitrary per-user credential leases requested from an owned Wave Control deployment before executor launch |
|
|
223
227
|
| `reportMode` | string | `metadata-only` | `disabled`, `metadata-only`, `metadata-plus-selected`, or `full-artifact-upload` |
|
|
224
228
|
| `uploadArtifactKinds` | string[] | selected proof/trace/benchmark kinds | Artifact classes eligible for body upload when an artifact's upload policy requests a body |
|
|
225
229
|
| `requestTimeoutMs` | integer | `5000` | Per-batch network timeout |
|
|
@@ -232,6 +236,8 @@ Supported top-level fields:
|
|
|
232
236
|
|
|
233
237
|
Lane overrides may refine the same keys under `lanes.<lane>.waveControl` or `projects.<projectId>.lanes.<lane>.waveControl`.
|
|
234
238
|
|
|
239
|
+
Wave resolves the Wave Control bearer token from `authTokenEnvVars` when that list is present. Otherwise it resolves `authTokenEnvVar` first and keeps `WAVE_CONTROL_AUTH_TOKEN` as a compatibility fallback.
|
|
240
|
+
|
|
235
241
|
One-run override:
|
|
236
242
|
|
|
237
243
|
- `wave launch --no-telemetry` disables Wave Control queueing and remote delivery for that launcher invocation without changing the repo config.
|
|
@@ -246,6 +252,8 @@ Example:
|
|
|
246
252
|
"endpoint": "https://wave-control.up.railway.app/api/v1",
|
|
247
253
|
"workspaceId": "wave-main",
|
|
248
254
|
"projectId": "app",
|
|
255
|
+
"credentialProviders": ["openai"],
|
|
256
|
+
"credentials": [{ "id": "github_pat", "envVar": "GITHUB_TOKEN" }],
|
|
249
257
|
"reportMode": "metadata-only",
|
|
250
258
|
"uploadArtifactKinds": [
|
|
251
259
|
"trace-run-metadata",
|
|
@@ -261,6 +269,56 @@ Runtime-emitted Wave Control events also attach:
|
|
|
261
269
|
- `orchestratorId` from the active launcher or resident orchestrator
|
|
262
270
|
- `runtimeVersion` from the installed Wave package metadata
|
|
263
271
|
|
|
272
|
+
## External Providers
|
|
273
|
+
|
|
274
|
+
Wave can resolve third-party auth directly in the repo runtime or through an owned Wave Control broker.
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"externalProviders": {
|
|
279
|
+
"context7": {
|
|
280
|
+
"mode": "direct",
|
|
281
|
+
"apiKeyEnvVar": "CONTEXT7_API_KEY"
|
|
282
|
+
},
|
|
283
|
+
"corridor": {
|
|
284
|
+
"enabled": false,
|
|
285
|
+
"mode": "direct",
|
|
286
|
+
"baseUrl": "https://app.corridor.dev/api",
|
|
287
|
+
"apiTokenEnvVar": "CORRIDOR_API_TOKEN",
|
|
288
|
+
"apiKeyFallbackEnvVar": "CORRIDOR_API_KEY",
|
|
289
|
+
"teamId": "team-id-for-direct-mode",
|
|
290
|
+
"projectId": "project-id-for-direct-mode",
|
|
291
|
+
"severityThreshold": "critical",
|
|
292
|
+
"findingStates": ["open", "potential"],
|
|
293
|
+
"requiredAtClosure": true
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
- `direct`: use repo/runtime env vars directly
|
|
300
|
+
- `broker`: use the owned Wave Control endpoint with `WAVE_API_TOKEN`
|
|
301
|
+
- `hybrid`: try the broker first, then fall back to direct auth if broker setup fails or a broker request fails at runtime
|
|
302
|
+
- direct Corridor mode requires both `teamId` and `projectId` in config; broker mode instead requires a matching `WAVE_BROKER_CORRIDOR_PROJECT_MAP` entry on the owned Wave Control deployment
|
|
303
|
+
- Wave auto-loads an allowlisted repo-root `.env.local` for `CONTEXT7_API_KEY`, `CORRIDOR_API_TOKEN`, `CORRIDOR_API_KEY`, `WAVE_API_TOKEN`, and `WAVE_CONTROL_AUTH_TOKEN`
|
|
304
|
+
- `wave doctor` now warns or fails early when brokered providers target the packaged default endpoint or no Wave Control auth token is available
|
|
305
|
+
- Context7 remains fail-open
|
|
306
|
+
- Corridor writes `.tmp/<lane>-wave-launcher/security/wave-<n>-corridor.json`, filters findings down to the wave's implementation-owned non-doc, non-`.tmp/`, non-markdown paths, and can fail closure when the fetch fails or matched findings meet the configured threshold
|
|
307
|
+
- Broker mode is intended for self-hosted or team-owned Wave Control only; the packaged default endpoint is rejected as a provider-secret proxy
|
|
308
|
+
- if `findingStates` is omitted or set to `[]`, Wave does not apply a state filter and the provider may return all states
|
|
309
|
+
- for the full Corridor lifecycle, including broker mapping, generated artifact shape, and gate semantics, see [../corridor.md](../corridor.md)
|
|
310
|
+
|
|
311
|
+
`waveControl.credentialProviders` is related but separate from `externalProviders`:
|
|
312
|
+
|
|
313
|
+
- use `externalProviders.context7` and `externalProviders.corridor` for brokered or direct API access during planning / closure flows
|
|
314
|
+
- use `waveControl.credentialProviders` only when an executor needs env vars leased into its runtime
|
|
315
|
+
- use `waveControl.credentials` when an executor needs arbitrary user-owned secrets leased into env vars such as `GITHUB_TOKEN` or `NPM_TOKEN`
|
|
316
|
+
- only `openai` and `anthropic` are valid leased providers today
|
|
317
|
+
- `context7` and `corridor` remain broker-only and are never returned as raw env secrets
|
|
318
|
+
- `waveControl.credentials[*].id` must match `/^[a-z0-9][a-z0-9._-]*$/`
|
|
319
|
+
- `waveControl.credentials[*].envVar` must match `/^[A-Z_][A-Z0-9_]*$/`
|
|
320
|
+
- when provider or arbitrary credentials are leased, Wave injects them into the live executor environment and redacts those keys in `launch-preview.json`
|
|
321
|
+
|
|
264
322
|
Those fields are queryable in the `wave-control` service alongside `workspaceId`,
|
|
265
323
|
`projectId`, `runKind`, `runId`, `lane`, and benchmark ids.
|
|
266
324
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Sample Waves"
|
|
3
|
-
summary: "Showcase-first sample waves that demonstrate the shipped 0.9.
|
|
3
|
+
summary: "Showcase-first sample waves that demonstrate the shipped 0.9.2 authored surface, including the optional design-role path."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Sample Waves
|
|
7
7
|
|
|
8
|
-
This guide points to showcase-first sample waves that demonstrate the shipped `0.9.
|
|
8
|
+
This guide points to showcase-first sample waves that demonstrate the shipped `0.9.2` authored Wave surface.
|
|
9
9
|
|
|
10
10
|
The examples are intentionally denser than typical production waves. Their job is to teach the current authoring and runtime surface quickly, not to be the smallest possible launch-ready files.
|
|
11
11
|
|
|
@@ -17,7 +17,7 @@ All example `.tmp/main-wave-launcher/...` paths assume the implicit default proj
|
|
|
17
17
|
Shows what a good `repo-landed` outcome looks like when one promoted component only closes honestly if desired-state records, reconcile-loop substrate, and cluster-view surfaces land together. It emphasizes maturity discipline, explicit deliverables, and shared-plan closure without drifting into `pilot-live` claims.
|
|
18
18
|
|
|
19
19
|
- [Full modern sample wave](../plans/examples/wave-example-live-proof.md)
|
|
20
|
-
Shows the combined `0.9.
|
|
20
|
+
Shows the combined `0.9.2` authored surface in one file: closure roles, `E0`, optional security review, delegated and pinned benchmark targets, richer executor config, `### Skills`, `### Capabilities`, `### Deliverables`, `### Exit contract`, `### Proof artifacts`, sticky retry, deploy environments, and proof-first live-wave structure.
|
|
21
21
|
|
|
22
22
|
- [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md)
|
|
23
23
|
Shows the shipped design-role surface: one pre-implementation design steward publishes a design packet, downstream implementation owners read that packet before coding, and normal closure roles still decide final completion. For terminal or operator-surface work, pair that shape with explicit `tui-design` in the design steward's `### Skills`. For the hybrid variant, explicitly give that same design agent implementation-owned paths and the normal implementation contract sections.
|
|
@@ -46,7 +46,7 @@ All example `.tmp/main-wave-launcher/...` paths assume the implicit default proj
|
|
|
46
46
|
|
|
47
47
|
## Feature Coverage Map
|
|
48
48
|
|
|
49
|
-
Together these samples cover the main surfaces added or hardened through `0.9.
|
|
49
|
+
Together these samples cover the main surfaces added or hardened through `0.9.2`:
|
|
50
50
|
|
|
51
51
|
- repo-landed maturity discipline and anti-overclaim framing
|
|
52
52
|
- explicit shared-plan closure for future-wave safety
|
|
@@ -184,7 +184,7 @@ Adapt more aggressively when:
|
|
|
184
184
|
## Suggested Reading Order
|
|
185
185
|
|
|
186
186
|
1. Start with [High-fidelity repo-landed rollout wave](../plans/examples/wave-example-rollout-fidelity.md) if you want the clearest example of good closure-ready wave fidelity for a repo-only outcome.
|
|
187
|
-
2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy `0.9.
|
|
187
|
+
2. Read [Full modern sample wave](../plans/examples/wave-example-live-proof.md) if you want the denser proof-first and eval-heavy `0.9.2` surface.
|
|
188
188
|
3. Read [Optional design-steward handoff wave](../plans/examples/wave-example-design-handoff.md) if the task needs a design packet before implementation fan-out.
|
|
189
189
|
4. Read [docs/evals/README.md](../evals/README.md) if you want more background on benchmark target selection.
|
|
190
190
|
5. Read [docs/reference/live-proof-waves.md](./live-proof-waves.md) if you want more detail on proof-first `pilot-live` authoring.
|
package/docs/reference/skills.md
CHANGED
|
@@ -124,7 +124,7 @@ Top-level and lane-local skill attachment use the same shape:
|
|
|
124
124
|
|
|
125
125
|
Lane-local `lanes.<lane>.skills` extends the global config instead of replacing it.
|
|
126
126
|
|
|
127
|
-
Optional design workers in the shipped `0.9.
|
|
127
|
+
Optional design workers in the shipped `0.9.2` surface normally attach `role-design`. That bundle is intended for docs/spec-first design packets and explicit implementation handoff work before implementation starts. When the design packet covers terminal UX, dashboards, or other operator surfaces, add `tui-design` explicitly in the wave's `### Skills`.
|
|
128
128
|
|
|
129
129
|
Long-running agents that should stay resident and react only to orchestrator signal changes can add `signal-hygiene` explicitly in `### Skills`. That bundle is not auto-attached and is not meant for normal one-shot implementation agents.
|
|
130
130
|
|
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Wave Control"
|
|
3
|
-
summary: "Canonical telemetry,
|
|
3
|
+
summary: "Canonical telemetry, owned deployment auth, broker routes, credential leasing, and the local-first reporting contract for the Wave control plane."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Wave Control
|
|
7
7
|
|
|
8
|
-
Wave Control is the
|
|
8
|
+
Wave Control is the control and observability plane for Wave runs.
|
|
9
9
|
|
|
10
10
|
The design rule is:
|
|
11
11
|
|
|
12
12
|
- local canonical state stays authoritative
|
|
13
13
|
- remote reporting is best-effort
|
|
14
|
-
- dashboards and
|
|
14
|
+
- dashboards, summaries, and the browser UI remain projections over typed local or persisted state
|
|
15
|
+
|
|
16
|
+
The packaged default endpoint is:
|
|
17
|
+
|
|
18
|
+
- `https://wave-control.up.railway.app/api/v1`
|
|
19
|
+
|
|
20
|
+
That packaged endpoint is for the default metadata-reporting surface. The owned-deployment features described below, such as provider brokering and runtime credential leasing, are intentionally meant for self-hosted or team-owned `wave-control` deployments.
|
|
21
|
+
|
|
22
|
+
## Deployment Profiles
|
|
23
|
+
|
|
24
|
+
### Packaged Default Endpoint
|
|
25
|
+
|
|
26
|
+
This is the release default in `@chllming/wave-orchestration@0.9.2`.
|
|
27
|
+
|
|
28
|
+
- receives local-first telemetry uploads
|
|
29
|
+
- supports normal run and benchmark query surfaces
|
|
30
|
+
- uses `reportMode: "metadata-only"` by default
|
|
31
|
+
- does not act as a provider-secret broker for Corridor, Context7, or leased runtime credentials
|
|
32
|
+
|
|
33
|
+
### Owned Deployment
|
|
34
|
+
|
|
35
|
+
This is the full control-plane model backed by `services/wave-control/` and, optionally, `services/wave-control-web/`.
|
|
36
|
+
|
|
37
|
+
An owned deployment can add:
|
|
38
|
+
|
|
39
|
+
- Stack-authenticated browser access
|
|
40
|
+
- Wave-managed app-user approval states and provider grants
|
|
41
|
+
- personal access tokens for repo runtimes and API clients
|
|
42
|
+
- dedicated service tokens for machine-admin workflows
|
|
43
|
+
- encrypted per-user stored credentials with owner-scoped runtime leasing
|
|
44
|
+
- broker routes for Context7 and Corridor
|
|
45
|
+
- provider env leasing for deployment-owned OpenAI and Anthropic credentials
|
|
15
46
|
|
|
16
47
|
## What Gets Reported
|
|
17
48
|
|
|
@@ -90,24 +121,10 @@ Signals to preserve:
|
|
|
90
121
|
- expert routing:
|
|
91
122
|
targeted assignments, reroutes, and final recommendation ownership should remain visible
|
|
92
123
|
- premature closure prevention:
|
|
93
|
-
gate snapshots, proof completeness, block reasons, reruns, and cont-QA reversal should be durable
|
|
124
|
+
gate snapshots, proof completeness, block reasons, reruns, and `cont-QA` reversal should be durable
|
|
94
125
|
- benchmark trust:
|
|
95
126
|
every benchmark item should distinguish capability from validity
|
|
96
127
|
|
|
97
|
-
## Blocker And Recovery Metadata
|
|
98
|
-
|
|
99
|
-
Wave Control should preserve the softer runtime policy, not flatten it away.
|
|
100
|
-
|
|
101
|
-
In practice that means `coordination_record`, `task`, `gate`, `wave_run`, and `rerun_request` payloads should keep fields such as:
|
|
102
|
-
|
|
103
|
-
- `blocking`
|
|
104
|
-
- `blockerSeverity`
|
|
105
|
-
- `recoverable`
|
|
106
|
-
- `recoveryReason`
|
|
107
|
-
- queued rerun request ids or resume targets
|
|
108
|
-
|
|
109
|
-
That distinction matters because a wave that is `blocked` by a proof-critical gate is different from a wave that is `blocked` only long enough to surface a targeted recovery after timeout, max-turn, rate-limit, or missing-status failure. The control plane should let operators ask which barriers still stop closure outright and which ones were intentionally downgraded to advisory or stale context.
|
|
110
|
-
|
|
111
128
|
## Artifact Contract
|
|
112
129
|
|
|
113
130
|
Selected artifacts are described with typed descriptors:
|
|
@@ -129,10 +146,10 @@ Upload policy meanings:
|
|
|
129
146
|
|
|
130
147
|
- `local-only`: keep only the descriptor remotely
|
|
131
148
|
- `metadata-only`: report path, hash, size, and presence only
|
|
132
|
-
- `selected`: upload metadata plus the artifact body when the runtime is in `metadata-plus-selected` or `full-artifact-upload`
|
|
149
|
+
- `selected`: upload metadata plus the artifact body when the runtime is in `metadata-plus-selected` or `full-artifact-upload` and the artifact kind is allowed by `waveControl.uploadArtifactKinds`
|
|
133
150
|
- `full`: upload the artifact body in `full-artifact-upload` flows; if `uploadArtifactKinds` is set, keep the kind allowlist aligned with that policy
|
|
134
151
|
|
|
135
|
-
## Runtime Config
|
|
152
|
+
## Repo Runtime Config
|
|
136
153
|
|
|
137
154
|
`wave.config.json` can declare:
|
|
138
155
|
|
|
@@ -142,7 +159,9 @@ Upload policy meanings:
|
|
|
142
159
|
"endpoint": "https://wave-control.up.railway.app/api/v1",
|
|
143
160
|
"workspaceId": "my-workspace",
|
|
144
161
|
"projectId": "app",
|
|
145
|
-
"authTokenEnvVar": "
|
|
162
|
+
"authTokenEnvVar": "WAVE_API_TOKEN",
|
|
163
|
+
"credentialProviders": ["openai"],
|
|
164
|
+
"credentials": [{ "id": "github_pat", "envVar": "GITHUB_TOKEN" }],
|
|
146
165
|
"reportMode": "metadata-only",
|
|
147
166
|
"uploadArtifactKinds": [
|
|
148
167
|
"trace-run-metadata",
|
|
@@ -159,8 +178,8 @@ Packaged defaults:
|
|
|
159
178
|
- enabled: `true`
|
|
160
179
|
- report mode: `metadata-only`
|
|
161
180
|
- identity defaults to the resolved project, lane, wave, run kind, and run id
|
|
162
|
-
|
|
163
|
-
|
|
181
|
+
- primary auth token env var: `WAVE_API_TOKEN`
|
|
182
|
+
- compatibility fallback auth token env var: `WAVE_CONTROL_AUTH_TOKEN`
|
|
164
183
|
|
|
165
184
|
Lane overrides may refine the same surface under `lanes.<lane>.waveControl` or `projects.<projectId>.lanes.<lane>.waveControl`.
|
|
166
185
|
|
|
@@ -182,6 +201,316 @@ Repo or project config may also opt out with:
|
|
|
182
201
|
|
|
183
202
|
That suppresses the local telemetry spool and remote delivery for that invocation, while leaving the canonical runtime artifacts and local control-plane state intact.
|
|
184
203
|
|
|
204
|
+
## API Surfaces
|
|
205
|
+
|
|
206
|
+
Wave Control exposes five main route families.
|
|
207
|
+
|
|
208
|
+
### Public
|
|
209
|
+
|
|
210
|
+
- `GET /api/v1/health`
|
|
211
|
+
- `GET /`
|
|
212
|
+
|
|
213
|
+
### Ingest And Query
|
|
214
|
+
|
|
215
|
+
- `POST /api/v1/ingest/batches`
|
|
216
|
+
- `GET /api/v1/runs`
|
|
217
|
+
- `GET /api/v1/run`
|
|
218
|
+
- `GET /api/v1/benchmarks`
|
|
219
|
+
- `GET /api/v1/benchmark`
|
|
220
|
+
- `GET /api/v1/analytics/overview`
|
|
221
|
+
- `GET /api/v1/artifact`
|
|
222
|
+
- `POST /api/v1/artifacts/signed-upload`
|
|
223
|
+
|
|
224
|
+
### Browser-App Routes
|
|
225
|
+
|
|
226
|
+
- `GET /api/v1/app/session`
|
|
227
|
+
- `POST /api/v1/app/access-request`
|
|
228
|
+
- `GET /api/v1/app/me`
|
|
229
|
+
- `GET /api/v1/app/overview`
|
|
230
|
+
- `GET /api/v1/app/runs`
|
|
231
|
+
- `GET /api/v1/app/run`
|
|
232
|
+
- `GET /api/v1/app/benchmarks`
|
|
233
|
+
- `GET /api/v1/app/benchmark`
|
|
234
|
+
- `GET /api/v1/app/tokens`
|
|
235
|
+
- `POST /api/v1/app/tokens`
|
|
236
|
+
- `POST /api/v1/app/tokens/:id/revoke`
|
|
237
|
+
- `GET /api/v1/app/admin/users`
|
|
238
|
+
- `POST /api/v1/app/admin/users`
|
|
239
|
+
- `POST /api/v1/app/admin/users/:id/state`
|
|
240
|
+
- `POST /api/v1/app/admin/users/:id/role`
|
|
241
|
+
- `POST /api/v1/app/admin/users/:id/providers`
|
|
242
|
+
- `GET /api/v1/app/admin/users/:id/credentials`
|
|
243
|
+
- `PUT /api/v1/app/admin/users/:id/credentials/:credentialId`
|
|
244
|
+
- `DELETE /api/v1/app/admin/users/:id/credentials/:credentialId`
|
|
245
|
+
|
|
246
|
+
### Provider And Runtime Lease Routes
|
|
247
|
+
|
|
248
|
+
- `GET /api/v1/providers/context7/search`
|
|
249
|
+
- `GET /api/v1/providers/context7/context`
|
|
250
|
+
- `POST /api/v1/providers/corridor/context`
|
|
251
|
+
- `POST /api/v1/runtime/provider-env`
|
|
252
|
+
- `POST /api/v1/runtime/credential-env`
|
|
253
|
+
|
|
254
|
+
### Service-Token Machine Routes
|
|
255
|
+
|
|
256
|
+
- `GET /api/v1/service/session`
|
|
257
|
+
- `GET /api/v1/service/users`
|
|
258
|
+
- `POST /api/v1/service/users`
|
|
259
|
+
- `POST /api/v1/service/users/:id/state`
|
|
260
|
+
- `POST /api/v1/service/users/:id/role`
|
|
261
|
+
- `POST /api/v1/service/users/:id/providers`
|
|
262
|
+
- `GET /api/v1/service/users/:id/credentials`
|
|
263
|
+
- `PUT /api/v1/service/users/:id/credentials/:credentialId`
|
|
264
|
+
- `DELETE /api/v1/service/users/:id/credentials/:credentialId`
|
|
265
|
+
- `POST /api/v1/service/users/:id/tokens`
|
|
266
|
+
- `POST /api/v1/service/tokens/:id/revoke`
|
|
267
|
+
|
|
268
|
+
## Access Model
|
|
269
|
+
|
|
270
|
+
Route access depends on both principal type and scope.
|
|
271
|
+
|
|
272
|
+
| Principal | How it authenticates | Main routes | Notes |
|
|
273
|
+
| --- | --- | --- | --- |
|
|
274
|
+
| Static env token | `WAVE_CONTROL_API_TOKEN(S)` or `WAVE_API_TOKEN(S)` | ingest, query, provider brokers, provider env leasing | trusted service-to-service path; bypasses provider-grant checks; does not use browser-app or service-token routes |
|
|
275
|
+
| Stack user | `x-stack-access-token` plus internal-team membership | `/api/v1/app/*`; approved users may also call runtime lease routes | Stack proves identity first; Wave Control then applies `pending`, `approved`, `rejected`, or `revoked` plus `member`/`superuser` |
|
|
276
|
+
| PAT | `Authorization: Bearer wave_pat_*` | ingest, provider brokers, provider env leasing, owner-scoped credential leasing | PAT scopes and provider grants are both enforced; owner approval state is re-checked on every request |
|
|
277
|
+
| Service token | `WAVE_CONTROL_SERVICE_TOKENS_JSON` | `/api/v1/service/*` | machine-admin only; cannot use owner-scoped credential leasing |
|
|
278
|
+
|
|
279
|
+
Two rules matter:
|
|
280
|
+
|
|
281
|
+
1. scopes and provider grants are separate
|
|
282
|
+
2. browser users do not receive `broker:read`
|
|
283
|
+
|
|
284
|
+
That means:
|
|
285
|
+
|
|
286
|
+
- a PAT needs `broker:read` plus the matching provider grant to use Corridor or Context7 broker routes
|
|
287
|
+
- a PAT or approved browser user needs `credential:read` plus the matching provider grant to use `POST /api/v1/runtime/provider-env`
|
|
288
|
+
- `POST /api/v1/runtime/credential-env` is owner-scoped and only works for an approved browser user or the owner's PAT
|
|
289
|
+
- static env tokens can still use ingest, query, broker, and provider-env routes as trusted deployment credentials
|
|
290
|
+
|
|
291
|
+
If `WAVE_CONTROL_REQUIRE_AUTH_FOR_READS=false`, the read/query routes may be public. Auth requirements for app, broker, lease, and service routes do not change.
|
|
292
|
+
|
|
293
|
+
## Stack App-User Model
|
|
294
|
+
|
|
295
|
+
Wave Control uses Stack as the browser login system, but it keeps its own authorization state on top of that identity.
|
|
296
|
+
|
|
297
|
+
Required backend env for browser auth:
|
|
298
|
+
|
|
299
|
+
- `WAVE_CONTROL_STACK_ENABLED=true`
|
|
300
|
+
- `WAVE_CONTROL_STACK_PROJECT_ID`
|
|
301
|
+
- `WAVE_CONTROL_STACK_PUBLISHABLE_CLIENT_KEY`
|
|
302
|
+
- `STACK_SECRET_SERVER_KEY`
|
|
303
|
+
- `WAVE_CONTROL_STACK_INTERNAL_TEAM_IDS`
|
|
304
|
+
|
|
305
|
+
Flow:
|
|
306
|
+
|
|
307
|
+
1. Stack authenticates the browser user.
|
|
308
|
+
2. Wave Control verifies the user is a confirmed member of `WAVE_CONTROL_STACK_INTERNAL_TEAM_IDS`.
|
|
309
|
+
3. Wave Control resolves or creates its own internal app-user record.
|
|
310
|
+
4. That app-user record carries:
|
|
311
|
+
- `accessState`: `pending`, `approved`, `rejected`, or `revoked`
|
|
312
|
+
- `role`: `member` or `superuser`
|
|
313
|
+
- `providerGrants`: allowlisted provider ids such as `context7`, `corridor`, `openai`, or `anthropic`
|
|
314
|
+
|
|
315
|
+
Bootstrap behavior:
|
|
316
|
+
|
|
317
|
+
- `WAVE_CONTROL_BOOTSTRAP_SUPERUSER_EMAILS` auto-provisions approved superusers on first sign-in for listed emails
|
|
318
|
+
- superusers automatically receive all provider grants
|
|
319
|
+
- members receive only the grants explicitly assigned to them
|
|
320
|
+
|
|
321
|
+
Important distinction:
|
|
322
|
+
|
|
323
|
+
- Stack identity decides who is a real internal user
|
|
324
|
+
- Wave Control app-user state decides who is approved and what they may do
|
|
325
|
+
|
|
326
|
+
## Personal Access Tokens
|
|
327
|
+
|
|
328
|
+
Wave Control PATs are opaque `wave_pat_*` tokens.
|
|
329
|
+
|
|
330
|
+
The service stores:
|
|
331
|
+
|
|
332
|
+
- only a SHA-256 hash of the token
|
|
333
|
+
- metadata such as owner, scopes, creation time, last-used time, and revocation time
|
|
334
|
+
|
|
335
|
+
The plaintext token is shown once at creation time.
|
|
336
|
+
|
|
337
|
+
PAT rules:
|
|
338
|
+
|
|
339
|
+
- allowlisted scopes: `broker:read`, `credential:read`, `ingest:write`
|
|
340
|
+
- members may issue PATs for themselves
|
|
341
|
+
- superusers may issue or revoke PATs for any approved user
|
|
342
|
+
- unsupported scopes, including `*`, are rejected
|
|
343
|
+
- PAT owners must be bound to a Stack user
|
|
344
|
+
- PAT requests are clamped to the owner's current approval state and provider grants every time the token is used
|
|
345
|
+
|
|
346
|
+
PATs are the intended token type for repo runtimes that need broker access or runtime env leasing without using a long-lived deployment-wide env token.
|
|
347
|
+
|
|
348
|
+
## Service Tokens
|
|
349
|
+
|
|
350
|
+
`WAVE_CONTROL_SERVICE_TOKENS_JSON` defines dedicated machine-admin tokens with `service:*` scopes.
|
|
351
|
+
|
|
352
|
+
Example:
|
|
353
|
+
|
|
354
|
+
```json
|
|
355
|
+
[
|
|
356
|
+
{
|
|
357
|
+
"label": "ops-bot",
|
|
358
|
+
"token": "replace-me",
|
|
359
|
+
"scopes": ["service:read", "service:user:write", "service:credential:write", "service:token:write"]
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Service tokens are intentionally separate from PATs:
|
|
365
|
+
|
|
366
|
+
- they access `/api/v1/service/*`
|
|
367
|
+
- they can manage users, provider grants, credentials, and PAT issuance for bound users
|
|
368
|
+
- they cannot impersonate a browser user
|
|
369
|
+
- they cannot use the owner-scoped `POST /api/v1/runtime/credential-env` route
|
|
370
|
+
|
|
371
|
+
## Credential Leasing
|
|
372
|
+
|
|
373
|
+
Wave Control supports two different leasing models.
|
|
374
|
+
|
|
375
|
+
### Provider Env Leasing
|
|
376
|
+
|
|
377
|
+
`POST /api/v1/runtime/provider-env` returns deployment-owned provider secrets as runtime env vars.
|
|
378
|
+
|
|
379
|
+
Current supported providers:
|
|
380
|
+
|
|
381
|
+
- `openai` -> `OPENAI_API_KEY`
|
|
382
|
+
- `anthropic` -> `ANTHROPIC_API_KEY`
|
|
383
|
+
|
|
384
|
+
Requirements:
|
|
385
|
+
|
|
386
|
+
- owned deployment only
|
|
387
|
+
- provider is enabled on the deployment
|
|
388
|
+
- caller has `credential:read`
|
|
389
|
+
- caller holds the matching provider grant unless it is a trusted env token
|
|
390
|
+
|
|
391
|
+
### Arbitrary Per-User Credential Leasing
|
|
392
|
+
|
|
393
|
+
`POST /api/v1/runtime/credential-env` leases user-owned stored credentials under requested env var names.
|
|
394
|
+
|
|
395
|
+
Example request:
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"credentials": [
|
|
400
|
+
{ "id": "github_pat", "envVar": "GITHUB_TOKEN" }
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Requirements:
|
|
406
|
+
|
|
407
|
+
- `WAVE_CONTROL_SECRET_ENCRYPTION_KEY` must be configured as a base64-encoded 32-byte AES-256-GCM key
|
|
408
|
+
- the caller must be the approved browser user or that user's PAT
|
|
409
|
+
- service tokens and env tokens are rejected
|
|
410
|
+
- the requested credential id must already exist for that owner
|
|
411
|
+
|
|
412
|
+
Stored credentials are:
|
|
413
|
+
|
|
414
|
+
- write-only through the admin and service management APIs
|
|
415
|
+
- encrypted at rest
|
|
416
|
+
- never returned through list endpoints
|
|
417
|
+
- only revealed through explicit lease responses
|
|
418
|
+
|
|
419
|
+
## Provider Brokers
|
|
420
|
+
|
|
421
|
+
Broker routes are intended for owned deployments only.
|
|
422
|
+
|
|
423
|
+
### Context7
|
|
424
|
+
|
|
425
|
+
- `GET /api/v1/providers/context7/search`
|
|
426
|
+
- `GET /api/v1/providers/context7/context`
|
|
427
|
+
|
|
428
|
+
Requirements:
|
|
429
|
+
|
|
430
|
+
- `WAVE_BROKER_OWNED_DEPLOYMENT=true`
|
|
431
|
+
- `WAVE_BROKER_ENABLE_CONTEXT7=true`
|
|
432
|
+
- `WAVE_BROKER_CONTEXT7_API_KEY`
|
|
433
|
+
- PAT or env token with `broker:read`
|
|
434
|
+
- matching `context7` provider grant for PAT callers
|
|
435
|
+
|
|
436
|
+
### Corridor
|
|
437
|
+
|
|
438
|
+
- `POST /api/v1/providers/corridor/context`
|
|
439
|
+
|
|
440
|
+
Requirements:
|
|
441
|
+
|
|
442
|
+
- `WAVE_BROKER_OWNED_DEPLOYMENT=true`
|
|
443
|
+
- `WAVE_BROKER_ENABLE_CORRIDOR=true`
|
|
444
|
+
- `WAVE_BROKER_CORRIDOR_API_TOKEN`
|
|
445
|
+
- `WAVE_BROKER_CORRIDOR_PROJECT_MAP`
|
|
446
|
+
- PAT or env token with `broker:read`
|
|
447
|
+
- matching `corridor` provider grant for PAT callers
|
|
448
|
+
|
|
449
|
+
Example project map:
|
|
450
|
+
|
|
451
|
+
```json
|
|
452
|
+
{
|
|
453
|
+
"app": {
|
|
454
|
+
"teamId": "team-uuid",
|
|
455
|
+
"projectId": "corridor-project-uuid"
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Example request:
|
|
461
|
+
|
|
462
|
+
```json
|
|
463
|
+
{
|
|
464
|
+
"projectId": "app",
|
|
465
|
+
"ownedPaths": ["src/auth", "src/session"],
|
|
466
|
+
"severityThreshold": "critical",
|
|
467
|
+
"findingStates": ["open", "potential"]
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Broker semantics:
|
|
472
|
+
|
|
473
|
+
- if `findingStates` is omitted, the service defaults to `open` and `potential`
|
|
474
|
+
- if the caller sends `findingStates: []`, the service queries all states
|
|
475
|
+
- the service returns a normalized summary with `guardrails`, `matchedFindings`, `blockingFindings`, `blocking`, and `error`
|
|
476
|
+
- upstream provider secrets never leave the owned deployment
|
|
477
|
+
|
|
478
|
+
For the runtime-side lifecycle, owned-path matching, and closure semantics, see [corridor.md](./corridor.md).
|
|
479
|
+
|
|
480
|
+
## Browser App
|
|
481
|
+
|
|
482
|
+
The frontend package lives at `services/wave-control-web/`.
|
|
483
|
+
|
|
484
|
+
It is a Vite/Lit app with Stack browser auth and a static shell.
|
|
485
|
+
|
|
486
|
+
Frontend env:
|
|
487
|
+
|
|
488
|
+
- `VITE_WAVE_CONTROL_API_BASE_URL`
|
|
489
|
+
- `VITE_STACK_PROJECT_ID`
|
|
490
|
+
- `VITE_STACK_PUBLISHABLE_CLIENT_KEY`
|
|
491
|
+
- `WAVE_CONTROL_WEB_BASE_PATH` for non-root deploy paths
|
|
492
|
+
|
|
493
|
+
Compatibility fallbacks:
|
|
494
|
+
|
|
495
|
+
- `NEXT_PUBLIC_STACK_PROJECT_ID`
|
|
496
|
+
- `NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY`
|
|
497
|
+
|
|
498
|
+
`VITE_WAVE_CONTROL_API_BASE_URL` may point at either:
|
|
499
|
+
|
|
500
|
+
- the Wave Control origin, such as `https://control.example.test`
|
|
501
|
+
- or the full `/api/v1` base
|
|
502
|
+
|
|
503
|
+
The frontend normalizes either form before appending route paths.
|
|
504
|
+
|
|
505
|
+
Runtime behavior:
|
|
506
|
+
|
|
507
|
+
- persists the Stack browser session across reloads
|
|
508
|
+
- completes OAuth and magic-link callbacks on the same app path
|
|
509
|
+
- only renders sign-in methods enabled in the Stack project
|
|
510
|
+
- loads `/api/v1/app/session` first after sign-in
|
|
511
|
+
- shows the request-access flow for internal users who are not yet approved
|
|
512
|
+
- exposes a superuser-only Users tab for approvals, role changes, provider grants, and write-only user credential rotation
|
|
513
|
+
|
|
185
514
|
## Delivery Model
|
|
186
515
|
|
|
187
516
|
Wave Control reporting should:
|
|
@@ -195,8 +524,10 @@ Wave Control reporting should:
|
|
|
195
524
|
|
|
196
525
|
The Railway-hosted `services/wave-control` service is an analysis surface, not the scheduler of record.
|
|
197
526
|
|
|
198
|
-
|
|
527
|
+
## Storage And Durability
|
|
528
|
+
|
|
529
|
+
For durable telemetry retention, attach Railway Postgres to `wave-control` so the service receives `DATABASE_URL`.
|
|
530
|
+
|
|
531
|
+
Without that variable, the service falls back to the in-memory store and only keeps data until the process restarts.
|
|
199
532
|
|
|
200
|
-
|
|
201
|
-
service receives `DATABASE_URL`. Without that variable, the service falls back to the
|
|
202
|
-
in-memory store and only keeps data until the process restarts.
|
|
533
|
+
Optional object storage may be configured through the `WAVE_CONTROL_BUCKET_*` variables for larger inline artifact bodies and signed-download URLs.
|
package/docs/roadmap.md
CHANGED
|
@@ -2,39 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
This roadmap is intentionally short and current. The older planner-foundation and ad-hoc-run phase list has been removed because that work no longer describes the actual shipping direction for this package.
|
|
4
4
|
|
|
5
|
-
## Current Release: 0.9.
|
|
5
|
+
## Current Release: 0.9.2
|
|
6
6
|
|
|
7
|
-
`0.9.
|
|
7
|
+
`0.9.2` is the current packaged surface.
|
|
8
8
|
|
|
9
|
-
It
|
|
9
|
+
It includes:
|
|
10
10
|
|
|
11
11
|
- detached process-backed agent execution instead of tmux-heavy live execution
|
|
12
12
|
- lower steady-state memory pressure and less terminal churn during long runs
|
|
13
13
|
- better behavior in constrained sandboxes such as LEAPclaw, OpenClaw, Nemoshell, and Docker-based operator environments
|
|
14
14
|
- a safer `submit -> supervise -> status/wait -> attach` control path for long-running agentic orchestration
|
|
15
15
|
- tighter supervisor recovery, progress journaling, and closure/retry correctness
|
|
16
|
+
- the current protected Wave Control model: Stack-authenticated browser access, Wave-managed approval states and provider grants, PATs, service tokens, encrypted per-user credentials, and runtime env leasing
|
|
17
|
+
- owned Context7 and Corridor broker routes plus the Corridor-backed security context that can gate closure before integration
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## Near-Term Direction On This Node Line
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
That release is focused on Wave Control authentication:
|
|
22
|
-
|
|
23
|
-
- token-based auth for `wave-control`
|
|
24
|
-
- web auth for the Wave Control operator surface
|
|
25
|
-
- a cleaner control-plane boundary between the local orchestrator runtime and authenticated operator access
|
|
26
|
-
- documentation and setup guidance for protected control surfaces in local, containerized, and hosted environments
|
|
27
|
-
|
|
28
|
-
After that release, this package should move into maintenance mode:
|
|
21
|
+
This standalone Node line should now be treated as maintenance-oriented:
|
|
29
22
|
|
|
30
23
|
- bug fixes
|
|
31
24
|
- compatibility updates
|
|
25
|
+
- operational hardening
|
|
32
26
|
- documentation updates
|
|
33
27
|
- release-surface alignment work
|
|
34
28
|
|
|
35
29
|
## Strategic Direction: LEAPclaw Execution Model
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
With the authenticated Wave Control surface now present, the main execution roadmap moves away from expanding this Node runtime and toward the LEAPclaw execution model.
|
|
38
32
|
|
|
39
33
|
The target shape is:
|
|
40
34
|
|
|
@@ -62,7 +56,6 @@ That line is expected to carry:
|
|
|
62
56
|
|
|
63
57
|
For this repository, the practical sequence is:
|
|
64
58
|
|
|
65
|
-
1. Ship `0.9.
|
|
66
|
-
2.
|
|
67
|
-
3.
|
|
68
|
-
4. Move long-term execution investment to the LEAPclaw + Go + Temporal architecture and the Rust standalone runtime.
|
|
59
|
+
1. Ship `0.9.2` with the sandbox/runtime hardening and aligned docs.
|
|
60
|
+
2. Maintain this Node package for bug fixes, compatibility, operational hardening, and release-surface sync rather than a broad new feature wave.
|
|
61
|
+
3. Move long-term execution investment to the LEAPclaw + Go + Temporal architecture and the Rust standalone runtime.
|