@chllming/wave-orchestration 0.6.2 → 0.7.0
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 +64 -1
- package/README.md +44 -8
- package/docs/agents/wave-orchestrator-role.md +50 -0
- package/docs/agents/wave-planner-role.md +39 -0
- package/docs/context7/bundles.json +9 -0
- package/docs/context7/planner-agent/README.md +25 -0
- package/docs/context7/planner-agent/manifest.json +83 -0
- package/docs/context7/planner-agent/papers/cooperbench-why-coding-agents-cannot-be-your-teammates-yet.md +3283 -0
- package/docs/context7/planner-agent/papers/dova-deliberation-first-multi-agent-orchestration-for-autonomous-research-automation.md +1699 -0
- package/docs/context7/planner-agent/papers/dpbench-large-language-models-struggle-with-simultaneous-coordination.md +2251 -0
- package/docs/context7/planner-agent/papers/incremental-planning-to-control-a-blackboard-based-problem-solver.md +1729 -0
- package/docs/context7/planner-agent/papers/silo-bench-a-scalable-environment-for-evaluating-distributed-coordination-in-multi-agent-llm-systems.md +3747 -0
- package/docs/context7/planner-agent/papers/todoevolve-learning-to-architect-agent-planning-systems.md +1675 -0
- package/docs/context7/planner-agent/papers/verified-multi-agent-orchestration-a-plan-execute-verify-replan-framework-for-complex-query-resolution.md +1173 -0
- package/docs/context7/planner-agent/papers/why-do-multi-agent-llm-systems-fail.md +5211 -0
- package/docs/context7/planner-agent/topics/planning-and-orchestration.md +24 -0
- package/docs/evals/README.md +96 -1
- package/docs/evals/arm-templates/README.md +13 -0
- package/docs/evals/arm-templates/full-wave.json +15 -0
- package/docs/evals/arm-templates/single-agent.json +15 -0
- package/docs/evals/benchmark-catalog.json +7 -0
- package/docs/evals/cases/README.md +47 -0
- package/docs/evals/cases/wave-blackboard-inbox-targeting.json +73 -0
- package/docs/evals/cases/wave-contradiction-conflict.json +104 -0
- package/docs/evals/cases/wave-expert-routing-preservation.json +69 -0
- package/docs/evals/cases/wave-hidden-profile-private-evidence.json +81 -0
- package/docs/evals/cases/wave-premature-closure-guard.json +71 -0
- package/docs/evals/cases/wave-silo-cross-agent-state.json +77 -0
- package/docs/evals/cases/wave-simultaneous-lockstep.json +92 -0
- package/docs/evals/cooperbench/real-world-mitigation.md +341 -0
- package/docs/evals/external-benchmarks.json +85 -0
- package/docs/evals/external-command-config.sample.json +9 -0
- package/docs/evals/external-command-config.swe-bench-pro.json +8 -0
- package/docs/evals/pilots/README.md +47 -0
- package/docs/evals/pilots/swe-bench-pro-public-full-wave-review-10.json +64 -0
- package/docs/evals/pilots/swe-bench-pro-public-pilot.json +111 -0
- package/docs/evals/wave-benchmark-program.md +302 -0
- package/docs/guides/planner.md +48 -11
- package/docs/plans/context7-wave-orchestrator.md +20 -0
- package/docs/plans/current-state.md +9 -1
- package/docs/plans/examples/wave-benchmark-improvement.md +108 -0
- package/docs/plans/examples/wave-example-live-proof.md +1 -1
- package/docs/plans/examples/wave-example-rollout-fidelity.md +340 -0
- package/docs/plans/wave-orchestrator.md +73 -11
- package/docs/plans/waves/reviews/wave-1-benchmark-operator.md +118 -0
- package/docs/reference/coordination-and-closure.md +436 -0
- package/docs/reference/live-proof-waves.md +25 -3
- package/docs/reference/npmjs-trusted-publishing.md +3 -3
- package/docs/reference/proof-metrics.md +90 -0
- package/docs/reference/runtime-config/README.md +61 -0
- package/docs/reference/sample-waves.md +29 -18
- package/docs/reference/wave-control.md +164 -0
- package/docs/reference/wave-planning-lessons.md +131 -0
- package/package.json +5 -4
- package/releases/manifest.json +33 -0
- package/scripts/research/agent-context-archive.mjs +18 -0
- package/scripts/research/manifests/agent-context-expanded-2026-03-22.mjs +17 -0
- package/scripts/research/sync-planner-context7-bundle.mjs +133 -0
- package/scripts/wave-autonomous.mjs +2 -4
- package/scripts/wave-orchestrator/adhoc.mjs +32 -11
- package/scripts/wave-orchestrator/artifact-schemas.mjs +232 -0
- package/scripts/wave-orchestrator/autonomous.mjs +27 -6
- package/scripts/wave-orchestrator/benchmark-cases.mjs +374 -0
- package/scripts/wave-orchestrator/benchmark-external.mjs +1384 -0
- package/scripts/wave-orchestrator/benchmark.mjs +972 -0
- package/scripts/wave-orchestrator/clarification-triage.mjs +78 -12
- package/scripts/wave-orchestrator/config.mjs +175 -0
- package/scripts/wave-orchestrator/control-cli.mjs +1123 -0
- package/scripts/wave-orchestrator/control-plane.mjs +697 -0
- package/scripts/wave-orchestrator/coord-cli.mjs +360 -2
- package/scripts/wave-orchestrator/coordination-store.mjs +211 -9
- package/scripts/wave-orchestrator/coordination.mjs +84 -0
- package/scripts/wave-orchestrator/dashboard-renderer.mjs +38 -3
- package/scripts/wave-orchestrator/dashboard-state.mjs +22 -0
- package/scripts/wave-orchestrator/evals.mjs +23 -0
- package/scripts/wave-orchestrator/executors.mjs +3 -2
- package/scripts/wave-orchestrator/feedback.mjs +55 -0
- package/scripts/wave-orchestrator/install.mjs +253 -26
- package/scripts/wave-orchestrator/launcher-closure.mjs +4 -1
- package/scripts/wave-orchestrator/launcher-runtime.mjs +24 -21
- package/scripts/wave-orchestrator/launcher.mjs +800 -35
- package/scripts/wave-orchestrator/package-update-notice.mjs +230 -0
- package/scripts/wave-orchestrator/package-version.mjs +32 -0
- package/scripts/wave-orchestrator/planner-context.mjs +75 -0
- package/scripts/wave-orchestrator/planner.mjs +2270 -136
- package/scripts/wave-orchestrator/proof-cli.mjs +195 -0
- package/scripts/wave-orchestrator/proof-registry.mjs +317 -0
- package/scripts/wave-orchestrator/replay.mjs +10 -4
- package/scripts/wave-orchestrator/retry-cli.mjs +184 -0
- package/scripts/wave-orchestrator/retry-control.mjs +225 -0
- package/scripts/wave-orchestrator/shared.mjs +26 -0
- package/scripts/wave-orchestrator/swe-bench-pro-task.mjs +1004 -0
- package/scripts/wave-orchestrator/traces.mjs +157 -2
- package/scripts/wave-orchestrator/wave-control-client.mjs +532 -0
- package/scripts/wave-orchestrator/wave-control-schema.mjs +309 -0
- package/scripts/wave-orchestrator/wave-files.mjs +17 -5
- package/scripts/wave.mjs +39 -2
- package/skills/repo-coding-rules/SKILL.md +1 -0
- package/skills/role-cont-eval/SKILL.md +1 -0
- package/skills/role-cont-qa/SKILL.md +13 -6
- package/skills/role-deploy/SKILL.md +1 -0
- package/skills/role-documentation/SKILL.md +4 -0
- package/skills/role-implementation/SKILL.md +4 -0
- package/skills/role-infra/SKILL.md +2 -1
- package/skills/role-integration/SKILL.md +15 -8
- package/skills/role-planner/SKILL.md +39 -0
- package/skills/role-planner/skill.json +21 -0
- package/skills/role-research/SKILL.md +1 -0
- package/skills/role-security/SKILL.md +2 -2
- package/skills/runtime-claude/SKILL.md +2 -1
- package/skills/runtime-codex/SKILL.md +1 -0
- package/skills/runtime-local/SKILL.md +2 -0
- package/skills/runtime-opencode/SKILL.md +1 -0
- package/skills/wave-core/SKILL.md +25 -6
- package/skills/wave-core/references/marker-syntax.md +16 -8
- package/wave.config.json +45 -0
|
@@ -5,9 +5,7 @@ import { bootstrapWaveArgs } from "./wave-cli-bootstrap.mjs";
|
|
|
5
5
|
const argv = bootstrapWaveArgs(process.argv.slice(2));
|
|
6
6
|
const { runAutonomousCli } = await import("./wave-orchestrator/autonomous.mjs");
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
runAutonomousCli(argv);
|
|
10
|
-
} catch (error) {
|
|
8
|
+
runAutonomousCli(argv).catch((error) => {
|
|
11
9
|
console.error(`[wave-autonomous] ${error instanceof Error ? error.message : String(error)}`);
|
|
12
10
|
process.exit(1);
|
|
13
|
-
}
|
|
11
|
+
});
|
|
@@ -8,6 +8,10 @@ import {
|
|
|
8
8
|
buildDefaultProjectProfile,
|
|
9
9
|
readProjectProfile,
|
|
10
10
|
} from "./project-profile.mjs";
|
|
11
|
+
import {
|
|
12
|
+
maybeAnnouncePackageUpdate,
|
|
13
|
+
WAVE_SUPPRESS_UPDATE_NOTICE_ENV,
|
|
14
|
+
} from "./package-update-notice.mjs";
|
|
11
15
|
import { runLauncherCli } from "./launcher.mjs";
|
|
12
16
|
import { renderWaveMarkdown } from "./planner.mjs";
|
|
13
17
|
import {
|
|
@@ -187,6 +191,20 @@ function buildAdhocRunId() {
|
|
|
187
191
|
return sanitizeAdhocRunId(`adhoc-${stamp}-${random}`);
|
|
188
192
|
}
|
|
189
193
|
|
|
194
|
+
async function withSuppressedNestedUpdateNotice(fn) {
|
|
195
|
+
const previousValue = process.env[WAVE_SUPPRESS_UPDATE_NOTICE_ENV];
|
|
196
|
+
process.env[WAVE_SUPPRESS_UPDATE_NOTICE_ENV] = "1";
|
|
197
|
+
try {
|
|
198
|
+
return await fn();
|
|
199
|
+
} finally {
|
|
200
|
+
if (previousValue === undefined) {
|
|
201
|
+
delete process.env[WAVE_SUPPRESS_UPDATE_NOTICE_ENV];
|
|
202
|
+
} else {
|
|
203
|
+
process.env[WAVE_SUPPRESS_UPDATE_NOTICE_ENV] = previousValue;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
190
208
|
function readEffectiveProjectProfile(config) {
|
|
191
209
|
return readProjectProfile({ config }) || buildDefaultProjectProfile(config);
|
|
192
210
|
}
|
|
@@ -1135,6 +1153,7 @@ export async function runAdhocCli(argv) {
|
|
|
1135
1153
|
if (options.tasks.length === 0) {
|
|
1136
1154
|
throw new Error("At least one --task is required for `wave adhoc run`.");
|
|
1137
1155
|
}
|
|
1156
|
+
await maybeAnnouncePackageUpdate();
|
|
1138
1157
|
const stored = createStoredRun({ config, options });
|
|
1139
1158
|
const summary = summarizePlan(stored.spec, stored.lanePaths);
|
|
1140
1159
|
if (options.json) {
|
|
@@ -1157,17 +1176,19 @@ export async function runAdhocCli(argv) {
|
|
|
1157
1176
|
writeJsonAtomic(stored.lanePaths.adhocResultPath, runningResult);
|
|
1158
1177
|
upsertAdhocIndexEntry(stored.lanePaths.adhocIndexPath, runningResult);
|
|
1159
1178
|
try {
|
|
1160
|
-
await
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1179
|
+
await withSuppressedNestedUpdateNotice(() =>
|
|
1180
|
+
runLauncherCli([
|
|
1181
|
+
"--lane",
|
|
1182
|
+
stored.lanePaths.lane,
|
|
1183
|
+
"--adhoc-run",
|
|
1184
|
+
stored.lanePaths.runId,
|
|
1185
|
+
"--start-wave",
|
|
1186
|
+
String(ADHOC_WAVE_NUMBER),
|
|
1187
|
+
"--end-wave",
|
|
1188
|
+
String(ADHOC_WAVE_NUMBER),
|
|
1189
|
+
...options.launcherArgs,
|
|
1190
|
+
]),
|
|
1191
|
+
);
|
|
1171
1192
|
const completedResult = buildResultRecord(
|
|
1172
1193
|
stored.lanePaths,
|
|
1173
1194
|
stored.request,
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import { readJsonOrNull, toIsoTimestamp, writeJsonAtomic } from "./shared.mjs";
|
|
2
|
+
import {
|
|
3
|
+
normalizeWaveControlReportMode,
|
|
4
|
+
normalizeWaveControlRunKind,
|
|
5
|
+
} from "./wave-control-schema.mjs";
|
|
2
6
|
|
|
3
7
|
export const MANIFEST_SCHEMA_VERSION = 1;
|
|
4
8
|
export const GLOBAL_DASHBOARD_SCHEMA_VERSION = 1;
|
|
5
9
|
export const WAVE_DASHBOARD_SCHEMA_VERSION = 1;
|
|
6
10
|
export const RELAUNCH_PLAN_SCHEMA_VERSION = 1;
|
|
11
|
+
export const RETRY_OVERRIDE_SCHEMA_VERSION = 1;
|
|
7
12
|
export const ASSIGNMENT_SNAPSHOT_SCHEMA_VERSION = 1;
|
|
8
13
|
export const DEPENDENCY_SNAPSHOT_SCHEMA_VERSION = 1;
|
|
14
|
+
export const PROOF_REGISTRY_SCHEMA_VERSION = 1;
|
|
9
15
|
export const RUN_STATE_SCHEMA_VERSION = 2;
|
|
16
|
+
export const WAVE_CONTROL_DELIVERY_STATE_SCHEMA_VERSION = 1;
|
|
10
17
|
|
|
11
18
|
export const MANIFEST_KIND = "wave-manifest";
|
|
12
19
|
export const GLOBAL_DASHBOARD_KIND = "global-dashboard";
|
|
13
20
|
export const WAVE_DASHBOARD_KIND = "wave-dashboard";
|
|
14
21
|
export const RELAUNCH_PLAN_KIND = "wave-relaunch-plan";
|
|
22
|
+
export const RETRY_OVERRIDE_KIND = "wave-retry-override";
|
|
15
23
|
export const ASSIGNMENT_SNAPSHOT_KIND = "wave-assignment-snapshot";
|
|
16
24
|
export const DEPENDENCY_SNAPSHOT_KIND = "wave-dependency-snapshot";
|
|
25
|
+
export const PROOF_REGISTRY_KIND = "wave-proof-registry";
|
|
17
26
|
export const RUN_STATE_KIND = "wave-run-state";
|
|
27
|
+
export const WAVE_CONTROL_DELIVERY_STATE_KIND = "wave-control-delivery-state";
|
|
18
28
|
|
|
19
29
|
function isPlainObject(value) {
|
|
20
30
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -25,6 +35,11 @@ function normalizeInteger(value, fallback = null) {
|
|
|
25
35
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
26
36
|
}
|
|
27
37
|
|
|
38
|
+
function normalizeNonNegativeInteger(value, fallback = 0) {
|
|
39
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
40
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
function normalizeText(value, fallback = null) {
|
|
29
44
|
const normalized = String(value ?? "").trim();
|
|
30
45
|
return normalized || fallback;
|
|
@@ -34,6 +49,19 @@ function cloneJson(value) {
|
|
|
34
49
|
return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
|
|
35
50
|
}
|
|
36
51
|
|
|
52
|
+
function normalizeStringArray(values) {
|
|
53
|
+
if (!Array.isArray(values)) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
return Array.from(
|
|
57
|
+
new Set(
|
|
58
|
+
values
|
|
59
|
+
.map((value) => normalizeText(value, null))
|
|
60
|
+
.filter(Boolean),
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
37
65
|
export function normalizeManifest(payload) {
|
|
38
66
|
const source = isPlainObject(payload) ? payload : {};
|
|
39
67
|
return {
|
|
@@ -94,6 +122,42 @@ export function writeRelaunchPlan(filePath, payload, defaults = {}) {
|
|
|
94
122
|
return normalized;
|
|
95
123
|
}
|
|
96
124
|
|
|
125
|
+
export function normalizeRetryOverride(payload, defaults = {}) {
|
|
126
|
+
const source = isPlainObject(payload) ? payload : {};
|
|
127
|
+
return {
|
|
128
|
+
schemaVersion: RETRY_OVERRIDE_SCHEMA_VERSION,
|
|
129
|
+
kind: RETRY_OVERRIDE_KIND,
|
|
130
|
+
lane: normalizeText(source.lane, normalizeText(defaults.lane, null)),
|
|
131
|
+
wave: normalizeInteger(source.wave, normalizeInteger(defaults.wave, null)),
|
|
132
|
+
selectedAgentIds: normalizeStringArray(source.selectedAgentIds),
|
|
133
|
+
reuseAttemptIds: normalizeStringArray(source.reuseAttemptIds),
|
|
134
|
+
reuseProofBundleIds: normalizeStringArray(source.reuseProofBundleIds),
|
|
135
|
+
reuseDerivedSummaries: source.reuseDerivedSummaries !== false,
|
|
136
|
+
invalidateComponentIds: normalizeStringArray(source.invalidateComponentIds),
|
|
137
|
+
clearReusableAgentIds: normalizeStringArray(source.clearReusableAgentIds),
|
|
138
|
+
preserveReusableAgentIds: normalizeStringArray(source.preserveReusableAgentIds),
|
|
139
|
+
resumePhase: normalizeText(source.resumePhase, null),
|
|
140
|
+
requestedBy: normalizeText(source.requestedBy, normalizeText(defaults.requestedBy, null)),
|
|
141
|
+
reason: normalizeText(source.reason, null),
|
|
142
|
+
applyOnce: source.applyOnce !== false,
|
|
143
|
+
createdAt: normalizeText(source.createdAt, toIsoTimestamp()),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function readRetryOverride(filePath, defaults = {}) {
|
|
148
|
+
const payload = readJsonOrNull(filePath);
|
|
149
|
+
if (!payload) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return normalizeRetryOverride(payload, defaults);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function writeRetryOverride(filePath, payload, defaults = {}) {
|
|
156
|
+
const normalized = normalizeRetryOverride(payload, defaults);
|
|
157
|
+
writeJsonAtomic(filePath, normalized);
|
|
158
|
+
return normalized;
|
|
159
|
+
}
|
|
160
|
+
|
|
97
161
|
export function normalizeAssignmentSnapshot(payload, defaults = {}) {
|
|
98
162
|
if (Array.isArray(payload)) {
|
|
99
163
|
return {
|
|
@@ -168,6 +232,174 @@ export function writeDependencySnapshot(filePath, payload, defaults = {}) {
|
|
|
168
232
|
return normalized;
|
|
169
233
|
}
|
|
170
234
|
|
|
235
|
+
function normalizeProofArtifactEntry(entry) {
|
|
236
|
+
const source = isPlainObject(entry) ? entry : {};
|
|
237
|
+
return {
|
|
238
|
+
path: normalizeText(source.path, null),
|
|
239
|
+
kind: normalizeText(source.kind, null),
|
|
240
|
+
requiredFor: normalizeStringArray(source.requiredFor),
|
|
241
|
+
exists: source.exists === true,
|
|
242
|
+
sha256: normalizeText(source.sha256, null),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function normalizeProofComponentEntry(entry) {
|
|
247
|
+
const source = isPlainObject(entry) ? entry : {};
|
|
248
|
+
return {
|
|
249
|
+
componentId: normalizeText(source.componentId, null),
|
|
250
|
+
level: normalizeText(source.level, null),
|
|
251
|
+
state: normalizeText(source.state, null),
|
|
252
|
+
detail: normalizeText(source.detail, null),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function normalizeProofSummaryEntry(entry) {
|
|
257
|
+
const source = isPlainObject(entry) ? entry : {};
|
|
258
|
+
const state = normalizeText(source.state, null);
|
|
259
|
+
const completion = normalizeText(source.completion, null);
|
|
260
|
+
const durability = normalizeText(source.durability, null);
|
|
261
|
+
const proof = normalizeText(source.proof, null);
|
|
262
|
+
if (!state && !completion && !durability && !proof) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
state,
|
|
267
|
+
completion,
|
|
268
|
+
durability,
|
|
269
|
+
proof,
|
|
270
|
+
detail: normalizeText(source.detail, null),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function normalizeDocDeltaEntry(entry) {
|
|
275
|
+
const source = isPlainObject(entry) ? entry : {};
|
|
276
|
+
const state = normalizeText(source.state, null);
|
|
277
|
+
if (!state) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
state,
|
|
282
|
+
detail: normalizeText(source.detail, null),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function normalizeProofRegistryEntry(entry) {
|
|
287
|
+
const source = isPlainObject(entry) ? entry : {};
|
|
288
|
+
return {
|
|
289
|
+
id: normalizeText(source.id, null),
|
|
290
|
+
agentId: normalizeText(source.agentId, null),
|
|
291
|
+
state: normalizeText(source.state, null),
|
|
292
|
+
authoritative: source.authoritative === true,
|
|
293
|
+
recordedAt: normalizeText(source.recordedAt, toIsoTimestamp()),
|
|
294
|
+
recordedBy: normalizeText(source.recordedBy, null),
|
|
295
|
+
detail: normalizeText(source.detail, null),
|
|
296
|
+
summary: normalizeText(source.summary, null),
|
|
297
|
+
satisfyOwnedComponents: source.satisfyOwnedComponents === true,
|
|
298
|
+
proof: normalizeProofSummaryEntry(source.proof),
|
|
299
|
+
docDelta: normalizeDocDeltaEntry(source.docDelta),
|
|
300
|
+
components: (Array.isArray(source.components) ? source.components : [])
|
|
301
|
+
.map((item) => normalizeProofComponentEntry(item))
|
|
302
|
+
.filter((item) => item.componentId),
|
|
303
|
+
artifacts: (Array.isArray(source.artifacts) ? source.artifacts : [])
|
|
304
|
+
.map((item) => normalizeProofArtifactEntry(item))
|
|
305
|
+
.filter((item) => item.path),
|
|
306
|
+
scope: normalizeText(source.scope, null),
|
|
307
|
+
attestation: isPlainObject(source.attestation) ? cloneJson(source.attestation) : null,
|
|
308
|
+
satisfies: normalizeStringArray(source.satisfies),
|
|
309
|
+
supersedes: normalizeText(source.supersedes, null),
|
|
310
|
+
supersededBy: normalizeText(source.supersededBy, null),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function normalizeProofRegistry(payload, defaults = {}) {
|
|
315
|
+
const source = isPlainObject(payload) ? payload : {};
|
|
316
|
+
return {
|
|
317
|
+
schemaVersion: PROOF_REGISTRY_SCHEMA_VERSION,
|
|
318
|
+
kind: PROOF_REGISTRY_KIND,
|
|
319
|
+
lane: normalizeText(source.lane, normalizeText(defaults.lane, null)),
|
|
320
|
+
wave: normalizeInteger(source.wave, normalizeInteger(defaults.wave, null)),
|
|
321
|
+
updatedAt: normalizeText(source.updatedAt, toIsoTimestamp()),
|
|
322
|
+
entries: (Array.isArray(source.entries) ? source.entries : [])
|
|
323
|
+
.map((entry) => normalizeProofRegistryEntry(entry))
|
|
324
|
+
.filter((entry) => entry.id && entry.agentId),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function readProofRegistry(filePath, defaults = {}) {
|
|
329
|
+
const payload = readJsonOrNull(filePath);
|
|
330
|
+
if (!payload) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
return normalizeProofRegistry(payload, defaults);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function writeProofRegistry(filePath, payload, defaults = {}) {
|
|
337
|
+
const normalized = normalizeProofRegistry(payload, defaults);
|
|
338
|
+
writeJsonAtomic(filePath, normalized);
|
|
339
|
+
return normalized;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function normalizeWaveControlDeliveryState(payload, defaults = {}) {
|
|
343
|
+
const source = isPlainObject(payload) ? payload : {};
|
|
344
|
+
return {
|
|
345
|
+
schemaVersion: WAVE_CONTROL_DELIVERY_STATE_SCHEMA_VERSION,
|
|
346
|
+
kind: WAVE_CONTROL_DELIVERY_STATE_KIND,
|
|
347
|
+
workspaceId: normalizeText(source.workspaceId, normalizeText(defaults.workspaceId, null)),
|
|
348
|
+
lane: normalizeText(source.lane, normalizeText(defaults.lane, null)),
|
|
349
|
+
runId: normalizeText(source.runId, normalizeText(defaults.runId, null)),
|
|
350
|
+
runKind: normalizeWaveControlRunKind(
|
|
351
|
+
source.runKind,
|
|
352
|
+
"waveControlDeliveryState.runKind",
|
|
353
|
+
normalizeText(defaults.runKind, "unknown"),
|
|
354
|
+
),
|
|
355
|
+
reportMode: normalizeWaveControlReportMode(
|
|
356
|
+
source.reportMode,
|
|
357
|
+
"waveControlDeliveryState.reportMode",
|
|
358
|
+
normalizeText(defaults.reportMode, "metadata-plus-selected"),
|
|
359
|
+
),
|
|
360
|
+
endpoint: normalizeText(source.endpoint, normalizeText(defaults.endpoint, null)),
|
|
361
|
+
queuePath: normalizeText(source.queuePath, normalizeText(defaults.queuePath, null)),
|
|
362
|
+
eventsPath: normalizeText(source.eventsPath, normalizeText(defaults.eventsPath, null)),
|
|
363
|
+
pendingCount: normalizeNonNegativeInteger(
|
|
364
|
+
source.pendingCount,
|
|
365
|
+
normalizeNonNegativeInteger(defaults.pendingCount, 0),
|
|
366
|
+
),
|
|
367
|
+
sentCount: normalizeNonNegativeInteger(
|
|
368
|
+
source.sentCount,
|
|
369
|
+
normalizeNonNegativeInteger(defaults.sentCount, 0),
|
|
370
|
+
),
|
|
371
|
+
failedCount: normalizeNonNegativeInteger(
|
|
372
|
+
source.failedCount,
|
|
373
|
+
normalizeNonNegativeInteger(defaults.failedCount, 0),
|
|
374
|
+
),
|
|
375
|
+
lastEnqueuedAt: normalizeText(source.lastEnqueuedAt, normalizeText(defaults.lastEnqueuedAt, null)),
|
|
376
|
+
lastFlushAt: normalizeText(source.lastFlushAt, normalizeText(defaults.lastFlushAt, null)),
|
|
377
|
+
lastSuccessAt: normalizeText(source.lastSuccessAt, normalizeText(defaults.lastSuccessAt, null)),
|
|
378
|
+
lastError:
|
|
379
|
+
source.lastError === undefined
|
|
380
|
+
? defaults.lastError ?? null
|
|
381
|
+
: isPlainObject(source.lastError)
|
|
382
|
+
? source.lastError
|
|
383
|
+
: normalizeText(source.lastError, null),
|
|
384
|
+
recentEventIds: normalizeStringArray(source.recentEventIds ?? defaults.recentEventIds),
|
|
385
|
+
updatedAt: normalizeText(source.updatedAt, normalizeText(defaults.updatedAt, toIsoTimestamp())),
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function readWaveControlDeliveryState(filePath, defaults = {}) {
|
|
390
|
+
const payload = readJsonOrNull(filePath);
|
|
391
|
+
if (!payload) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
return normalizeWaveControlDeliveryState(payload, defaults);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export function writeWaveControlDeliveryState(filePath, payload, defaults = {}) {
|
|
398
|
+
const normalized = normalizeWaveControlDeliveryState(payload, defaults);
|
|
399
|
+
writeJsonAtomic(filePath, normalized);
|
|
400
|
+
return normalized;
|
|
401
|
+
}
|
|
402
|
+
|
|
171
403
|
export function cloneArtifactPayload(value) {
|
|
172
404
|
return cloneJson(value);
|
|
173
405
|
}
|
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
DEFAULT_CODEX_SANDBOX_MODE,
|
|
22
22
|
normalizeCodexSandboxMode,
|
|
23
23
|
} from "./launcher.mjs";
|
|
24
|
+
import {
|
|
25
|
+
maybeAnnouncePackageUpdate,
|
|
26
|
+
WAVE_SUPPRESS_UPDATE_NOTICE_ENV,
|
|
27
|
+
} from "./package-update-notice.mjs";
|
|
24
28
|
import { readRunState } from "./wave-files.mjs";
|
|
25
29
|
import { readDependencyTickets } from "./coordination-store.mjs";
|
|
26
30
|
import { readWaveLedger } from "./ledger.mjs";
|
|
@@ -41,6 +45,7 @@ Options:
|
|
|
41
45
|
Max backoff delay for 429 retries (default: ${DEFAULT_AGENT_RATE_LIMIT_MAX_DELAY_SECONDS})
|
|
42
46
|
--agent-launch-stagger-ms <n> Delay between agent launches (default: ${DEFAULT_AGENT_LAUNCH_STAGGER_MS})
|
|
43
47
|
--orchestrator-id <id> Orchestrator ID for coordination board
|
|
48
|
+
--resident-orchestrator Launch a resident orchestrator session for each live wave
|
|
44
49
|
--executor <mode> Default executor passed to launcher: ${SUPPORTED_EXECUTOR_MODES.join(" | ")} (default: lane config)
|
|
45
50
|
--codex-sandbox <mode> Default Codex sandbox mode passed to launcher (default: ${DEFAULT_CODEX_SANDBOX_MODE})
|
|
46
51
|
--dashboard Enable dashboards (default: disabled)
|
|
@@ -60,6 +65,7 @@ export function parseArgs(argv) {
|
|
|
60
65
|
agentRateLimitMaxDelaySeconds: DEFAULT_AGENT_RATE_LIMIT_MAX_DELAY_SECONDS,
|
|
61
66
|
agentLaunchStaggerMs: DEFAULT_AGENT_LAUNCH_STAGGER_MS,
|
|
62
67
|
orchestratorId: null,
|
|
68
|
+
residentOrchestrator: false,
|
|
63
69
|
executorMode: DEFAULT_EXECUTOR_MODE,
|
|
64
70
|
codexSandboxMode: DEFAULT_CODEX_SANDBOX_MODE,
|
|
65
71
|
noDashboard: true,
|
|
@@ -99,6 +105,8 @@ export function parseArgs(argv) {
|
|
|
99
105
|
options.agentLaunchStaggerMs = parseNonNegativeInt(argv[++i], "--agent-launch-stagger-ms");
|
|
100
106
|
} else if (arg === "--orchestrator-id") {
|
|
101
107
|
options.orchestratorId = String(argv[++i] || "").trim();
|
|
108
|
+
} else if (arg === "--resident-orchestrator") {
|
|
109
|
+
options.residentOrchestrator = true;
|
|
102
110
|
} else if (arg === "--executor") {
|
|
103
111
|
options.executorMode = normalizeExecutorMode(argv[++i], "--executor");
|
|
104
112
|
executorProvided = true;
|
|
@@ -155,21 +163,30 @@ export function nextIncompleteWave(allWaves, completed) {
|
|
|
155
163
|
return null;
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
function runCommand(args) {
|
|
166
|
+
function runCommand(args, envOverrides = {}) {
|
|
159
167
|
const result = spawnSync("node", args, {
|
|
160
168
|
cwd: REPO_ROOT,
|
|
161
169
|
stdio: "inherit",
|
|
162
|
-
env:
|
|
170
|
+
env: {
|
|
171
|
+
...process.env,
|
|
172
|
+
...envOverrides,
|
|
173
|
+
},
|
|
163
174
|
});
|
|
164
175
|
return Number.isInteger(result.status) ? result.status : 1;
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
function reconcile(lane) {
|
|
168
|
-
return runCommand(
|
|
179
|
+
return runCommand(
|
|
180
|
+
[path.join(PACKAGE_ROOT, "scripts", "wave-launcher.mjs"), "--lane", lane, "--reconcile-status"],
|
|
181
|
+
{ [WAVE_SUPPRESS_UPDATE_NOTICE_ENV]: "1" },
|
|
182
|
+
);
|
|
169
183
|
}
|
|
170
184
|
|
|
171
185
|
function dryRun(lane) {
|
|
172
|
-
return runCommand(
|
|
186
|
+
return runCommand(
|
|
187
|
+
[path.join(PACKAGE_ROOT, "scripts", "wave-launcher.mjs"), "--lane", lane, "--dry-run", "--no-dashboard"],
|
|
188
|
+
{ [WAVE_SUPPRESS_UPDATE_NOTICE_ENV]: "1" },
|
|
189
|
+
);
|
|
173
190
|
}
|
|
174
191
|
|
|
175
192
|
function listPendingFeedback(lane) {
|
|
@@ -215,7 +232,10 @@ function launchSingleWave(params) {
|
|
|
215
232
|
if (params.keepTerminals) {
|
|
216
233
|
args.push("--keep-terminals");
|
|
217
234
|
}
|
|
218
|
-
|
|
235
|
+
if (params.residentOrchestrator) {
|
|
236
|
+
args.push("--resident-orchestrator");
|
|
237
|
+
}
|
|
238
|
+
return runCommand(args, { [WAVE_SUPPRESS_UPDATE_NOTICE_ENV]: "1" });
|
|
219
239
|
}
|
|
220
240
|
|
|
221
241
|
function requiredInboundDependenciesOpen(lanePaths, lane) {
|
|
@@ -291,12 +311,13 @@ export function readAutonomousBarrier(lanePaths, lane, wave = null) {
|
|
|
291
311
|
return null;
|
|
292
312
|
}
|
|
293
313
|
|
|
294
|
-
export function runAutonomousCli(argv) {
|
|
314
|
+
export async function runAutonomousCli(argv) {
|
|
295
315
|
const parsed = parseArgs(argv);
|
|
296
316
|
if (parsed.help) {
|
|
297
317
|
printUsage();
|
|
298
318
|
return;
|
|
299
319
|
}
|
|
320
|
+
await maybeAnnouncePackageUpdate();
|
|
300
321
|
const options = parsed.options;
|
|
301
322
|
const allWaves = getWaveNumbers(options.lane);
|
|
302
323
|
console.log(`[autonomous] lane=${options.lane} orchestrator=${options.orchestratorId}`);
|