@chllming/wave-orchestration 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/LICENSE.md +21 -0
  3. package/README.md +18 -6
  4. package/docs/README.md +8 -4
  5. package/docs/agents/wave-security-role.md +1 -0
  6. package/docs/architecture/README.md +1 -1
  7. package/docs/concepts/operating-modes.md +1 -1
  8. package/docs/guides/author-and-run-waves.md +1 -1
  9. package/docs/guides/planner.md +2 -2
  10. package/docs/guides/{recommendations-0.9.1.md → recommendations-0.9.2.md} +7 -7
  11. package/docs/guides/sandboxed-environments.md +2 -2
  12. package/docs/plans/current-state.md +8 -2
  13. package/docs/plans/end-state-architecture.md +1 -1
  14. package/docs/plans/examples/wave-example-design-handoff.md +1 -1
  15. package/docs/plans/examples/wave-example-live-proof.md +1 -1
  16. package/docs/plans/migration.md +42 -18
  17. package/docs/reference/cli-reference.md +1 -1
  18. package/docs/reference/coordination-and-closure.md +18 -1
  19. package/docs/reference/corridor.md +225 -0
  20. package/docs/reference/npmjs-token-publishing.md +2 -2
  21. package/docs/reference/package-publishing-flow.md +11 -11
  22. package/docs/reference/runtime-config/README.md +61 -3
  23. package/docs/reference/sample-waves.md +5 -5
  24. package/docs/reference/skills.md +1 -1
  25. package/docs/reference/wave-control.md +358 -27
  26. package/docs/roadmap.md +12 -19
  27. package/package.json +1 -1
  28. package/releases/manifest.json +22 -3
  29. package/scripts/wave-cli-bootstrap.mjs +52 -1
  30. package/scripts/wave-orchestrator/config.mjs +199 -3
  31. package/scripts/wave-orchestrator/context7.mjs +231 -29
  32. package/scripts/wave-orchestrator/coordination.mjs +14 -0
  33. package/scripts/wave-orchestrator/corridor.mjs +363 -0
  34. package/scripts/wave-orchestrator/derived-state-engine.mjs +38 -1
  35. package/scripts/wave-orchestrator/gate-engine.mjs +20 -0
  36. package/scripts/wave-orchestrator/install.mjs +34 -1
  37. package/scripts/wave-orchestrator/launcher-runtime.mjs +111 -7
  38. package/scripts/wave-orchestrator/planner.mjs +1 -0
  39. package/scripts/wave-orchestrator/projection-writer.mjs +23 -0
  40. package/scripts/wave-orchestrator/provider-runtime.mjs +104 -0
  41. package/scripts/wave-orchestrator/shared.mjs +1 -0
  42. package/scripts/wave-orchestrator/traces.mjs +25 -0
  43. package/scripts/wave-orchestrator/wave-control-client.mjs +14 -1
@@ -1,17 +1,48 @@
1
1
  ---
2
2
  title: "Wave Control"
3
- summary: "Canonical telemetry, artifact upload policy, and the local-first reporting contract for the Railway-hosted Wave control plane."
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 telemetry and analysis plane for Wave runs.
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 markdown remain projections over typed local state
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` **and** the artifact kind is allowed by `waveControl.uploadArtifactKinds`
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": "WAVE_CONTROL_AUTH_TOKEN",
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
- This package is distributed with the author's personal Wave Control endpoint enabled by default. Repos that do not want telemetry delivered there must explicitly opt out.
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
- The service package lives under `services/wave-control/`.
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
- For durable telemetry retention, attach Railway Postgres to `wave-control` so the
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.1
5
+ ## Current Release: 0.9.2
6
6
 
7
- `0.9.1` is the runtime-hardening release.
7
+ `0.9.2` is the current packaged surface.
8
8
 
9
- It focuses on:
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
- ## Next Release: Final Planned Feature Release On This Line
19
+ ## Near-Term Direction On This Node Line
18
20
 
19
- The next planned release after `0.9.1`, aside from bug fixes and release-surface maintenance, is the final feature release for this standalone Node-based line.
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
- After the Wave Control auth release, the main execution roadmap moves away from expanding this Node runtime and toward the LEAPclaw execution model.
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.1` with the sandbox/runtime hardening and aligned docs.
66
- 2. Ship the Wave Control token/web auth release as the last planned feature release on this Node line.
67
- 3. Keep this package maintained for bug fixes, compatibility, and release-surface sync.
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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chllming/wave-orchestration",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "license": "MIT",
5
5
  "description": "Generic wave-based multi-agent orchestration for repository work.",
6
6
  "repository": {
@@ -2,22 +2,41 @@
2
2
  "schemaVersion": 1,
3
3
  "packageName": "@chllming/wave-orchestration",
4
4
  "releases": [
5
+ {
6
+ "version": "0.9.2",
7
+ "date": "2026-03-29",
8
+ "summary": "0.9.2 release cut for the documented Corridor and Wave Control surface, plus aligned publish artifacts.",
9
+ "features": [
10
+ "The packaged version now advances to `0.9.2` so the documented Corridor, Wave Control auth, and security surfaces can be tagged and published without colliding with the existing `0.9.1` npm release and git tag.",
11
+ "Release docs, migration guidance, runtime-config docs, coordination docs, Wave Control docs, package publishing docs, tracked install-state fixtures, and the release manifest now all point at the same `0.9.2` surface.",
12
+ "The shipped versioned operating guide is now `docs/guides/recommendations-0.9.2.md`, and starter install seeding plus install regression coverage now use that exact path.",
13
+ "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."
14
+ ],
15
+ "manualSteps": [
16
+ "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.2` release surface.",
17
+ "Push the `v0.9.2` tag after the release commit so the GitHub publish workflow can publish the matching npm package version.",
18
+ "If your repo copied starter docs or runbooks, sync `README.md`, `docs/README.md`, `docs/plans/current-state.md`, `docs/plans/migration.md`, `docs/reference/coordination-and-closure.md`, `docs/reference/runtime-config/README.md`, `docs/reference/corridor.md`, `docs/reference/wave-control.md`, and `docs/guides/recommendations-0.9.2.md` so local guidance matches the packaged release."
19
+ ],
20
+ "breaking": false
21
+ },
5
22
  {
6
23
  "version": "0.9.1",
7
24
  "date": "2026-03-29",
8
- "summary": "Detached process-backed agent execution, sandbox-safe supervisor hardening, lower memory pressure, and 0.9.1 release-surface alignment.",
25
+ "summary": "Detached process-backed agent execution, authenticated Wave Control, Corridor-backed security context, and 0.9.1 release-surface alignment.",
9
26
  "features": [
10
27
  "Live agent execution now uses detached process runners by default instead of per-agent tmux execution sessions, which reduces tmux churn and lowers memory use during wide orchestration bursts while keeping tmux as an optional dashboard projection layer.",
11
28
  "The sandbox-facing path is now `wave submit`, `wave supervise`, `wave status`, `wave wait`, and `wave attach`, with exact-context lookup, read-side launcher-status reconciliation, progress journaling, degraded-run handling, and log-follow attach behavior suited to LEAPclaw, OpenClaw, Nemoshell, and similar short-lived exec environments.",
12
29
  "Supervisor recovery now relies on run-owned terminal artifacts and finalized progress instead of lane-global completion history, preserving the correct remaining wave range and final active wave during multi-wave reruns and launcher-loss recovery.",
13
30
  "Ordinary runs, closure runs, and resident orchestrator runs now all preserve process-runtime metadata for timeout and cleanup, while process-backed resident orchestrators terminate cleanly and rate-limit retry detection stays scoped to the current attempt output.",
31
+ "Owned `wave-control` deployments now expose the shipped auth surface: Stack-backed browser access, Wave-managed approval states and provider grants, PATs, dedicated service tokens, encrypted per-user credential storage, runtime env leasing, and the separate `services/wave-control-web` frontend.",
32
+ "Corridor is now documented as a first-class security input with `direct`, `broker`, and `hybrid` runtime modes, normalized per-wave security artifacts, owned-path matching rules, and closure gating that can fail before integration on fetch failures or matched blocking findings.",
14
33
  "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.",
15
- "A dedicated setup guide now ships for sandboxed and containerized operation, including Nemoshell and Docker guidance, while README, migration docs, terminal-surface docs, runtime-config docs, coordination docs, and the renamed recommendations guide `docs/guides/recommendations-0.9.1.md` now describe the same sandbox-safe release surface."
34
+ "A dedicated setup guide now ships for sandboxed and containerized operation, and README, migration docs, terminal-surface docs, runtime-config docs, coordination docs, Wave Control docs, the new Corridor reference, and the renamed recommendations guide `docs/guides/recommendations-0.9.1.md` now describe the same current release surface."
16
35
  ],
17
36
  "manualSteps": [
18
37
  "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.1` release surface.",
19
38
  "If your repo runs Wave inside LEAPclaw, OpenClaw, Nemoshell, Docker, or another short-lived exec sandbox, move long-running orchestration to `wave supervise`, use `wave submit/status/wait/attach` from disposable clients, and set Codex sandbox defaults in `wave.config.json` instead of relying on per-command overrides.",
20
- "If your repo copied starter docs or runbooks, sync `README.md`, `docs/README.md`, `docs/plans/current-state.md`, `docs/plans/migration.md`, `docs/reference/coordination-and-closure.md`, `docs/reference/runtime-config/README.md`, `docs/guides/sandboxed-environments.md`, `docs/guides/terminal-surfaces.md`, and `docs/guides/recommendations-0.9.1.md` so local guidance matches the packaged release."
39
+ "If your repo copied starter docs or runbooks, sync `README.md`, `docs/README.md`, `docs/plans/current-state.md`, `docs/plans/migration.md`, `docs/reference/coordination-and-closure.md`, `docs/reference/runtime-config/README.md`, `docs/reference/corridor.md`, `docs/reference/wave-control.md`, `docs/guides/sandboxed-environments.md`, `docs/guides/terminal-surfaces.md`, and `docs/guides/recommendations-0.9.1.md` so local guidance matches the packaged release."
21
40
  ],
22
41
  "breaking": false
23
42
  },
@@ -1,4 +1,13 @@
1
1
  import path from "node:path";
2
+ import fs from "node:fs";
3
+
4
+ const ALLOWLISTED_ENV_FILE_KEYS = new Set([
5
+ "CONTEXT7_API_KEY",
6
+ "CORRIDOR_API_TOKEN",
7
+ "CORRIDOR_API_KEY",
8
+ "WAVE_API_TOKEN",
9
+ "WAVE_CONTROL_AUTH_TOKEN",
10
+ ]);
2
11
 
3
12
  function stripRepoRootArg(argv) {
4
13
  const normalizedArgs = [];
@@ -22,6 +31,48 @@ function stripRepoRootArg(argv) {
22
31
  return normalizedArgs;
23
32
  }
24
33
 
34
+ function parseEnvLine(line) {
35
+ const trimmed = String(line || "").trim();
36
+ if (!trimmed || trimmed.startsWith("#")) {
37
+ return null;
38
+ }
39
+ const exportPrefix = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trim() : trimmed;
40
+ const equalsIndex = exportPrefix.indexOf("=");
41
+ if (equalsIndex <= 0) {
42
+ return null;
43
+ }
44
+ const key = exportPrefix.slice(0, equalsIndex).trim();
45
+ let value = exportPrefix.slice(equalsIndex + 1).trim();
46
+ if (!ALLOWLISTED_ENV_FILE_KEYS.has(key)) {
47
+ return null;
48
+ }
49
+ if (
50
+ (value.startsWith("\"") && value.endsWith("\"")) ||
51
+ (value.startsWith("'") && value.endsWith("'"))
52
+ ) {
53
+ value = value.slice(1, -1);
54
+ }
55
+ return { key, value };
56
+ }
57
+
58
+ function loadRepoLocalEnv() {
59
+ const repoRoot = path.resolve(process.env.WAVE_REPO_ROOT || process.cwd());
60
+ const envPath = path.join(repoRoot, ".env.local");
61
+ if (!fs.existsSync(envPath)) {
62
+ return;
63
+ }
64
+ const lines = fs.readFileSync(envPath, "utf8").split(/\r?\n/);
65
+ for (const line of lines) {
66
+ const entry = parseEnvLine(line);
67
+ if (!entry || process.env[entry.key]) {
68
+ continue;
69
+ }
70
+ process.env[entry.key] = entry.value;
71
+ }
72
+ }
73
+
25
74
  export function bootstrapWaveArgs(argv) {
26
- return stripRepoRootArg(Array.isArray(argv) ? argv : []);
75
+ const normalizedArgs = stripRepoRootArg(Array.isArray(argv) ? argv : []);
76
+ loadRepoLocalEnv();
77
+ return normalizedArgs;
27
78
  }