@chllming/wave-orchestration 0.8.2 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -2
- package/README.md +47 -11
- package/docs/README.md +6 -2
- package/docs/concepts/what-is-a-wave.md +1 -1
- package/docs/plans/architecture-hardening-migration.md +8 -1
- package/docs/plans/current-state.md +17 -7
- package/docs/plans/end-state-architecture.md +82 -69
- package/docs/plans/examples/wave-example-live-proof.md +1 -1
- package/docs/plans/migration.md +235 -61
- package/docs/plans/wave-orchestrator.md +37 -11
- package/docs/reference/cli-reference.md +39 -15
- package/docs/reference/coordination-and-closure.md +30 -6
- package/docs/reference/npmjs-trusted-publishing.md +5 -4
- package/docs/reference/sample-waves.md +4 -4
- package/package.json +1 -1
- package/releases/manifest.json +39 -0
- package/scripts/wave-orchestrator/agent-state.mjs +0 -491
- package/scripts/wave-orchestrator/autonomous.mjs +10 -6
- package/scripts/wave-orchestrator/{launcher-closure.mjs → closure-engine.mjs} +190 -74
- package/scripts/wave-orchestrator/control-cli.mjs +8 -0
- package/scripts/wave-orchestrator/coord-cli.mjs +8 -0
- package/scripts/wave-orchestrator/{launcher-derived-state.mjs → derived-state-engine.mjs} +34 -146
- package/scripts/wave-orchestrator/feedback.mjs +11 -1
- package/scripts/wave-orchestrator/{launcher-gates.mjs → gate-engine.mjs} +395 -139
- package/scripts/wave-orchestrator/human-input-resolution.mjs +348 -0
- package/scripts/wave-orchestrator/human-input-workflow.mjs +104 -0
- package/scripts/wave-orchestrator/implementation-engine.mjs +120 -0
- package/scripts/wave-orchestrator/launcher-runtime.mjs +5 -6
- package/scripts/wave-orchestrator/launcher.mjs +271 -724
- package/scripts/wave-orchestrator/projection-writer.mjs +256 -0
- package/scripts/wave-orchestrator/reconcile-format.mjs +32 -0
- package/scripts/wave-orchestrator/reducer-snapshot.mjs +297 -0
- package/scripts/wave-orchestrator/replay.mjs +3 -1
- package/scripts/wave-orchestrator/result-envelope.mjs +589 -0
- package/scripts/wave-orchestrator/retry-control.mjs +5 -0
- package/scripts/wave-orchestrator/{launcher-retry.mjs → retry-engine.mjs} +267 -18
- package/scripts/wave-orchestrator/role-helpers.mjs +51 -0
- package/scripts/wave-orchestrator/{launcher-supervisor.mjs → session-supervisor.mjs} +178 -103
- package/scripts/wave-orchestrator/shared.mjs +1 -0
- package/scripts/wave-orchestrator/traces.mjs +10 -1
- package/scripts/wave-orchestrator/wave-files.mjs +11 -9
- package/scripts/wave-orchestrator/wave-state-reducer.mjs +52 -5
|
@@ -1180,494 +1180,3 @@ export function validateContQaSummary(agent, summary, options = {}) {
|
|
|
1180
1180
|
detail: summary.verdict.detail || summary.gate.detail || "cont-QA gate passed.",
|
|
1181
1181
|
};
|
|
1182
1182
|
}
|
|
1183
|
-
|
|
1184
|
-
// ---------------------------------------------------------------------------
|
|
1185
|
-
// Agent Result Envelope — P1-6 End-State (schemaVersion 2)
|
|
1186
|
-
// ---------------------------------------------------------------------------
|
|
1187
|
-
|
|
1188
|
-
import { toIsoTimestamp } from "./shared.mjs";
|
|
1189
|
-
|
|
1190
|
-
/**
|
|
1191
|
-
* Valid roles for the agent result envelope.
|
|
1192
|
-
*/
|
|
1193
|
-
export const ENVELOPE_VALID_ROLES = [
|
|
1194
|
-
"implementation",
|
|
1195
|
-
"integration",
|
|
1196
|
-
"documentation",
|
|
1197
|
-
"cont-qa",
|
|
1198
|
-
"cont-eval",
|
|
1199
|
-
"security",
|
|
1200
|
-
"deploy",
|
|
1201
|
-
];
|
|
1202
|
-
|
|
1203
|
-
function inferEnvelopeRole(agent, summary) {
|
|
1204
|
-
const candidate = String(agent?.role || summary?.role || "").trim().toLowerCase();
|
|
1205
|
-
if (candidate && ENVELOPE_VALID_ROLES.includes(candidate)) {
|
|
1206
|
-
return candidate;
|
|
1207
|
-
}
|
|
1208
|
-
if (summary?.integration) {
|
|
1209
|
-
return "integration";
|
|
1210
|
-
}
|
|
1211
|
-
if (summary?.docClosure) {
|
|
1212
|
-
return "documentation";
|
|
1213
|
-
}
|
|
1214
|
-
if (summary?.eval) {
|
|
1215
|
-
return "cont-eval";
|
|
1216
|
-
}
|
|
1217
|
-
if (summary?.security) {
|
|
1218
|
-
return "security";
|
|
1219
|
-
}
|
|
1220
|
-
if (summary?.gate || summary?.verdict) {
|
|
1221
|
-
return "cont-qa";
|
|
1222
|
-
}
|
|
1223
|
-
if (summary?.deploy) {
|
|
1224
|
-
return "deploy";
|
|
1225
|
-
}
|
|
1226
|
-
if (summary?.proof || summary?.docDelta || Array.isArray(summary?.components)) {
|
|
1227
|
-
return "implementation";
|
|
1228
|
-
}
|
|
1229
|
-
return null;
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
function toSummaryRelativePath(filePath) {
|
|
1233
|
-
const normalized = String(filePath || "").trim();
|
|
1234
|
-
if (!normalized) {
|
|
1235
|
-
return null;
|
|
1236
|
-
}
|
|
1237
|
-
return path.isAbsolute(normalized) ? path.relative(REPO_ROOT, normalized) : normalized;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
function toLegacyProofState(state) {
|
|
1241
|
-
if (state === "satisfied") {
|
|
1242
|
-
return "met";
|
|
1243
|
-
}
|
|
1244
|
-
if (state === "partial") {
|
|
1245
|
-
return "gap";
|
|
1246
|
-
}
|
|
1247
|
-
if (state === "failed") {
|
|
1248
|
-
return "failed";
|
|
1249
|
-
}
|
|
1250
|
-
return "not_applicable";
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
/**
|
|
1254
|
-
* Compute the attempt-scoped canonical envelope path.
|
|
1255
|
-
*
|
|
1256
|
-
* End-state path: .tmp/<lane>/results/wave-<N>/attempt-<A>/<agentId>.json
|
|
1257
|
-
*
|
|
1258
|
-
* @param {object} options - { lane, waveNumber, attempt, agentId }
|
|
1259
|
-
* @returns {string} The envelope file path
|
|
1260
|
-
*/
|
|
1261
|
-
export function agentEnvelopePath({ lane, waveNumber, attempt, agentId }) {
|
|
1262
|
-
const safeLane = lane || "main";
|
|
1263
|
-
const safeWave = waveNumber ?? 0;
|
|
1264
|
-
const safeAttempt = attempt ?? 1;
|
|
1265
|
-
const safeAgent = agentId || "unknown";
|
|
1266
|
-
return `.tmp/${safeLane}-wave-launcher/results/wave-${safeWave}/attempt-${safeAttempt}/${safeAgent}.json`;
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
/**
|
|
1270
|
-
* Legacy path derivation from status path.
|
|
1271
|
-
* Retained for backward compatibility during migration.
|
|
1272
|
-
*
|
|
1273
|
-
* @param {string} statusPath - Path to the .status or .summary file
|
|
1274
|
-
* @returns {string} The envelope file path
|
|
1275
|
-
*/
|
|
1276
|
-
export function agentEnvelopePathFromStatusPath(statusPath) {
|
|
1277
|
-
if (statusPath.endsWith(".summary.json")) {
|
|
1278
|
-
return statusPath.replace(/\.summary\.json$/i, ".envelope.json");
|
|
1279
|
-
}
|
|
1280
|
-
if (statusPath.endsWith(".status")) {
|
|
1281
|
-
return statusPath.replace(/\.status$/i, ".envelope.json");
|
|
1282
|
-
}
|
|
1283
|
-
return `${statusPath}.envelope.json`;
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
/**
|
|
1287
|
-
* Build a structured result envelope from an already-parsed execution summary.
|
|
1288
|
-
* Pure function — the envelope is a normalized projection of the summary.
|
|
1289
|
-
*
|
|
1290
|
-
* End-state P1-6: common header + role-specific typed optional payloads.
|
|
1291
|
-
* Absent role sections are NOT included (not null, not empty object).
|
|
1292
|
-
*
|
|
1293
|
-
* @param {object} agent - Agent definition from wave (must include .role)
|
|
1294
|
-
* @param {object} summary - Execution summary from buildAgentExecutionSummary
|
|
1295
|
-
* @param {object} [options] - { waveNumber, attempt, exitCode }
|
|
1296
|
-
* @returns {object} AgentResultEnvelope (schemaVersion 2)
|
|
1297
|
-
*/
|
|
1298
|
-
export function buildAgentResultEnvelope(agent, summary, options = {}) {
|
|
1299
|
-
const safeAgent = agent || {};
|
|
1300
|
-
const safeSummary = summary || {};
|
|
1301
|
-
const safeOptions = options || {};
|
|
1302
|
-
|
|
1303
|
-
const agentId = safeAgent.agentId || safeSummary.agentId || null;
|
|
1304
|
-
const role = inferEnvelopeRole(safeAgent, safeSummary);
|
|
1305
|
-
|
|
1306
|
-
// --- Common header ---
|
|
1307
|
-
const proof = safeSummary.proof || {};
|
|
1308
|
-
const proofSection = {
|
|
1309
|
-
state: proof.state === "met" ? "satisfied"
|
|
1310
|
-
: proof.state === "gap" ? "partial"
|
|
1311
|
-
: proof.state === "failed" ? "failed"
|
|
1312
|
-
: "not_applicable",
|
|
1313
|
-
completion: proof.completion || null,
|
|
1314
|
-
durability: proof.durability || null,
|
|
1315
|
-
proofLevel: proof.proof || null,
|
|
1316
|
-
detail: proof.detail || null,
|
|
1317
|
-
};
|
|
1318
|
-
|
|
1319
|
-
// Deliverables — with sha256
|
|
1320
|
-
const deliverables = Array.isArray(safeSummary.deliverables)
|
|
1321
|
-
? safeSummary.deliverables.map((d) => ({
|
|
1322
|
-
path: d.path || null,
|
|
1323
|
-
exists: d.exists === true,
|
|
1324
|
-
sha256: d.sha256 || null,
|
|
1325
|
-
}))
|
|
1326
|
-
: [];
|
|
1327
|
-
|
|
1328
|
-
// Proof artifacts — with sha256 and requiredFor
|
|
1329
|
-
const proofArtifacts = Array.isArray(safeSummary.proofArtifacts)
|
|
1330
|
-
? safeSummary.proofArtifacts.map((artifact) => ({
|
|
1331
|
-
path: artifact.path || null,
|
|
1332
|
-
kind: artifact.kind || null,
|
|
1333
|
-
exists: artifact.exists === true,
|
|
1334
|
-
sha256: artifact.sha256 || null,
|
|
1335
|
-
requiredFor: artifact.requiredFor || null,
|
|
1336
|
-
}))
|
|
1337
|
-
: [];
|
|
1338
|
-
|
|
1339
|
-
// Gaps
|
|
1340
|
-
const gaps = Array.isArray(safeSummary.gaps)
|
|
1341
|
-
? safeSummary.gaps.map((g) => ({
|
|
1342
|
-
kind: g.kind || null,
|
|
1343
|
-
detail: g.detail || null,
|
|
1344
|
-
}))
|
|
1345
|
-
: [];
|
|
1346
|
-
|
|
1347
|
-
// Unresolved blockers
|
|
1348
|
-
const unresolvedBlockers = Array.isArray(safeSummary.unresolvedBlockers)
|
|
1349
|
-
? safeSummary.unresolvedBlockers.map((b) =>
|
|
1350
|
-
typeof b === "object" ? { kind: b.kind || null, detail: b.detail || null, blocking: b.blocking || null } : { kind: null, detail: String(b), blocking: null },
|
|
1351
|
-
)
|
|
1352
|
-
: [];
|
|
1353
|
-
|
|
1354
|
-
// Risk notes
|
|
1355
|
-
const riskNotes = Array.isArray(safeSummary.riskNotes) ? safeSummary.riskNotes : [];
|
|
1356
|
-
|
|
1357
|
-
// Facts
|
|
1358
|
-
const facts = Array.isArray(safeSummary.facts)
|
|
1359
|
-
? safeSummary.facts.map((f) => ({
|
|
1360
|
-
factId: f.factId || null,
|
|
1361
|
-
kind: f.kind || null,
|
|
1362
|
-
content: f.content || null,
|
|
1363
|
-
}))
|
|
1364
|
-
: [];
|
|
1365
|
-
|
|
1366
|
-
const envelope = {
|
|
1367
|
-
schemaVersion: 2,
|
|
1368
|
-
agentId,
|
|
1369
|
-
waveNumber: safeOptions.waveNumber ?? safeSummary.waveNumber ?? null,
|
|
1370
|
-
attempt: safeOptions.attempt ?? safeSummary.attempt ?? null,
|
|
1371
|
-
completedAt: safeOptions.completedAt || toIsoTimestamp(),
|
|
1372
|
-
exitCode: typeof safeOptions.exitCode === "number" ? safeOptions.exitCode : (typeof safeSummary.exitCode === "number" ? safeSummary.exitCode : 0),
|
|
1373
|
-
role,
|
|
1374
|
-
proof: proofSection,
|
|
1375
|
-
deliverables,
|
|
1376
|
-
proofArtifacts,
|
|
1377
|
-
gaps,
|
|
1378
|
-
unresolvedBlockers,
|
|
1379
|
-
riskNotes,
|
|
1380
|
-
facts,
|
|
1381
|
-
};
|
|
1382
|
-
|
|
1383
|
-
// --- Role-specific typed payloads (absent when not applicable) ---
|
|
1384
|
-
|
|
1385
|
-
if (role === "implementation") {
|
|
1386
|
-
const docDelta = safeSummary.docDelta || {};
|
|
1387
|
-
const components = Array.isArray(safeSummary.components)
|
|
1388
|
-
? safeSummary.components.map((c) => ({
|
|
1389
|
-
componentId: c.componentId || null,
|
|
1390
|
-
level: c.level || null,
|
|
1391
|
-
state: c.state || null,
|
|
1392
|
-
detail: c.detail || null,
|
|
1393
|
-
}))
|
|
1394
|
-
: [];
|
|
1395
|
-
envelope.implementation = {
|
|
1396
|
-
docDelta: {
|
|
1397
|
-
state: docDelta.state || "none",
|
|
1398
|
-
paths: Array.isArray(docDelta.paths) ? docDelta.paths : [],
|
|
1399
|
-
detail: docDelta.detail || null,
|
|
1400
|
-
},
|
|
1401
|
-
components,
|
|
1402
|
-
};
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
if (role === "integration") {
|
|
1406
|
-
const integ = safeSummary.integration || {};
|
|
1407
|
-
envelope.integration = {
|
|
1408
|
-
state: integ.state || null,
|
|
1409
|
-
claims: integ.claims || 0,
|
|
1410
|
-
conflicts: integ.conflicts || 0,
|
|
1411
|
-
blockers: integ.blockers || 0,
|
|
1412
|
-
detail: integ.detail || null,
|
|
1413
|
-
};
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
if (role === "documentation") {
|
|
1417
|
-
const docDelta = safeSummary.docDelta || safeSummary.docClosure || {};
|
|
1418
|
-
envelope.documentation = {
|
|
1419
|
-
docClosure: {
|
|
1420
|
-
state: docDelta.state || "no-change",
|
|
1421
|
-
paths: Array.isArray(docDelta.paths) ? docDelta.paths : [],
|
|
1422
|
-
detail: docDelta.detail || null,
|
|
1423
|
-
},
|
|
1424
|
-
};
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
if (role === "cont-qa") {
|
|
1428
|
-
const verdict = safeSummary.verdict || {};
|
|
1429
|
-
const gate = safeSummary.gate || {};
|
|
1430
|
-
envelope.contQa = {
|
|
1431
|
-
verdict: {
|
|
1432
|
-
verdict: verdict.verdict || null,
|
|
1433
|
-
detail: verdict.detail || null,
|
|
1434
|
-
},
|
|
1435
|
-
gateClaims: {
|
|
1436
|
-
architecture: gate.architecture || null,
|
|
1437
|
-
integration: gate.integration || null,
|
|
1438
|
-
durability: gate.durability || null,
|
|
1439
|
-
live: gate.live || null,
|
|
1440
|
-
docs: gate.docs || null,
|
|
1441
|
-
},
|
|
1442
|
-
};
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
if (role === "cont-eval") {
|
|
1446
|
-
const evalSection = safeSummary.eval || {};
|
|
1447
|
-
envelope.contEval = {
|
|
1448
|
-
state: evalSection.state || null,
|
|
1449
|
-
targets: evalSection.targets || 0,
|
|
1450
|
-
benchmarks: evalSection.benchmarks || 0,
|
|
1451
|
-
regressions: evalSection.regressions || 0,
|
|
1452
|
-
targetIds: Array.isArray(evalSection.targetIds) ? evalSection.targetIds : [],
|
|
1453
|
-
benchmarkIds: Array.isArray(evalSection.benchmarkIds) ? evalSection.benchmarkIds : [],
|
|
1454
|
-
detail: evalSection.detail || null,
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
if (role === "security") {
|
|
1459
|
-
const sec = safeSummary.security || {};
|
|
1460
|
-
envelope.security = {
|
|
1461
|
-
state: sec.state || null,
|
|
1462
|
-
findings: sec.findings || 0,
|
|
1463
|
-
approvals: sec.approvals || 0,
|
|
1464
|
-
detail: sec.detail || null,
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
if (role === "deploy") {
|
|
1469
|
-
const dep = safeSummary.deploy || {};
|
|
1470
|
-
envelope.deploy = {
|
|
1471
|
-
state: dep.state || "not_applicable",
|
|
1472
|
-
environment: dep.environment || null,
|
|
1473
|
-
healthCheck: dep.healthCheck || null,
|
|
1474
|
-
rolloutArtifact: dep.rolloutArtifact || null,
|
|
1475
|
-
detail: dep.detail || null,
|
|
1476
|
-
};
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
|
-
return envelope;
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
/**
|
|
1483
|
-
* Build a v2 envelope from legacy parsed log markers.
|
|
1484
|
-
* Migration adapter: synthesizes the end-state envelope shape from the
|
|
1485
|
-
* output of buildAgentExecutionSummary (which parses log markers).
|
|
1486
|
-
*
|
|
1487
|
-
* This exists so the gate engine always sees a consistent v2 shape,
|
|
1488
|
-
* even when the agent emitted legacy log markers rather than a structured envelope.
|
|
1489
|
-
*
|
|
1490
|
-
* @param {object} agent - Agent definition (must include .agentId, .role)
|
|
1491
|
-
* @param {object} legacySummary - Result from buildAgentExecutionSummary
|
|
1492
|
-
* @param {object} [options] - { waveNumber, attempt, exitCode }
|
|
1493
|
-
* @returns {object} AgentResultEnvelope (schemaVersion 2)
|
|
1494
|
-
*/
|
|
1495
|
-
export function buildEnvelopeFromLegacySignals(agent, legacySummary, options = {}) {
|
|
1496
|
-
const envelope = buildAgentResultEnvelope(agent, legacySummary, options);
|
|
1497
|
-
envelope._synthesizedFromLegacy = true;
|
|
1498
|
-
return envelope;
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
export function buildExecutionSummaryFromEnvelope(envelope, options = {}) {
|
|
1502
|
-
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
1503
|
-
return null;
|
|
1504
|
-
}
|
|
1505
|
-
const role = inferEnvelopeRole(options.agent || {}, envelope);
|
|
1506
|
-
const proof = envelope.proof && typeof envelope.proof === "object"
|
|
1507
|
-
? {
|
|
1508
|
-
state: toLegacyProofState(envelope.proof.state),
|
|
1509
|
-
completion: envelope.proof.completion || null,
|
|
1510
|
-
durability: envelope.proof.durability || null,
|
|
1511
|
-
proof: envelope.proof.proofLevel || null,
|
|
1512
|
-
detail: envelope.proof.detail || null,
|
|
1513
|
-
}
|
|
1514
|
-
: null;
|
|
1515
|
-
const summary = {
|
|
1516
|
-
agentId: envelope.agentId || options.agent?.agentId || null,
|
|
1517
|
-
role,
|
|
1518
|
-
waveNumber: envelope.waveNumber ?? options.waveNumber ?? null,
|
|
1519
|
-
attempt: envelope.attempt ?? options.attempt ?? null,
|
|
1520
|
-
completedAt: envelope.completedAt || null,
|
|
1521
|
-
exitCode: typeof envelope.exitCode === "number" ? envelope.exitCode : 0,
|
|
1522
|
-
logPath: toSummaryRelativePath(options.logPath),
|
|
1523
|
-
reportPath: toSummaryRelativePath(options.reportPath),
|
|
1524
|
-
proof,
|
|
1525
|
-
deliverables: Array.isArray(envelope.deliverables)
|
|
1526
|
-
? envelope.deliverables.map((deliverable) => ({
|
|
1527
|
-
path: deliverable.path || null,
|
|
1528
|
-
exists: deliverable.exists === true,
|
|
1529
|
-
sha256: deliverable.sha256 || null,
|
|
1530
|
-
}))
|
|
1531
|
-
: [],
|
|
1532
|
-
proofArtifacts: Array.isArray(envelope.proofArtifacts)
|
|
1533
|
-
? envelope.proofArtifacts.map((artifact) => ({
|
|
1534
|
-
path: artifact.path || null,
|
|
1535
|
-
kind: artifact.kind || null,
|
|
1536
|
-
exists: artifact.exists === true,
|
|
1537
|
-
sha256: artifact.sha256 || null,
|
|
1538
|
-
requiredFor: artifact.requiredFor || null,
|
|
1539
|
-
}))
|
|
1540
|
-
: [],
|
|
1541
|
-
gaps: Array.isArray(envelope.gaps)
|
|
1542
|
-
? envelope.gaps.map((gap) => ({
|
|
1543
|
-
kind: gap.kind || null,
|
|
1544
|
-
detail: gap.detail || null,
|
|
1545
|
-
}))
|
|
1546
|
-
: [],
|
|
1547
|
-
unresolvedBlockers: Array.isArray(envelope.unresolvedBlockers)
|
|
1548
|
-
? envelope.unresolvedBlockers.map((blocker) => ({
|
|
1549
|
-
kind: blocker.kind || null,
|
|
1550
|
-
detail: blocker.detail || null,
|
|
1551
|
-
blocking: blocker.blocking ?? null,
|
|
1552
|
-
}))
|
|
1553
|
-
: [],
|
|
1554
|
-
riskNotes: Array.isArray(envelope.riskNotes) ? envelope.riskNotes.slice() : [],
|
|
1555
|
-
facts: Array.isArray(envelope.facts)
|
|
1556
|
-
? envelope.facts.map((fact) => ({
|
|
1557
|
-
factId: fact.factId || null,
|
|
1558
|
-
kind: fact.kind || null,
|
|
1559
|
-
content: fact.content || null,
|
|
1560
|
-
}))
|
|
1561
|
-
: [],
|
|
1562
|
-
};
|
|
1563
|
-
|
|
1564
|
-
if (envelope.implementation) {
|
|
1565
|
-
summary.docDelta = {
|
|
1566
|
-
state: envelope.implementation.docDelta?.state || "none",
|
|
1567
|
-
paths: Array.isArray(envelope.implementation.docDelta?.paths)
|
|
1568
|
-
? envelope.implementation.docDelta.paths
|
|
1569
|
-
: [],
|
|
1570
|
-
detail: envelope.implementation.docDelta?.detail || null,
|
|
1571
|
-
};
|
|
1572
|
-
summary.components = Array.isArray(envelope.implementation.components)
|
|
1573
|
-
? envelope.implementation.components.map((component) => ({
|
|
1574
|
-
componentId: component.componentId || null,
|
|
1575
|
-
level: component.level || null,
|
|
1576
|
-
state: component.state || null,
|
|
1577
|
-
detail: component.detail || null,
|
|
1578
|
-
}))
|
|
1579
|
-
: [];
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
if (envelope.documentation?.docClosure) {
|
|
1583
|
-
summary.docClosure = {
|
|
1584
|
-
state: envelope.documentation.docClosure.state || "no-change",
|
|
1585
|
-
paths: Array.isArray(envelope.documentation.docClosure.paths)
|
|
1586
|
-
? envelope.documentation.docClosure.paths
|
|
1587
|
-
: [],
|
|
1588
|
-
detail: envelope.documentation.docClosure.detail || null,
|
|
1589
|
-
};
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
if (envelope.integration) {
|
|
1593
|
-
summary.integration = {
|
|
1594
|
-
state: envelope.integration.state || null,
|
|
1595
|
-
claims: envelope.integration.claims || 0,
|
|
1596
|
-
conflicts: envelope.integration.conflicts || 0,
|
|
1597
|
-
blockers: envelope.integration.blockers || 0,
|
|
1598
|
-
detail: envelope.integration.detail || null,
|
|
1599
|
-
};
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
if (envelope.contEval) {
|
|
1603
|
-
summary.eval = {
|
|
1604
|
-
state: envelope.contEval.state || null,
|
|
1605
|
-
targets: envelope.contEval.targets || 0,
|
|
1606
|
-
benchmarks: envelope.contEval.benchmarks || 0,
|
|
1607
|
-
regressions: envelope.contEval.regressions || 0,
|
|
1608
|
-
targetIds: Array.isArray(envelope.contEval.targetIds) ? envelope.contEval.targetIds : [],
|
|
1609
|
-
benchmarkIds: Array.isArray(envelope.contEval.benchmarkIds) ? envelope.contEval.benchmarkIds : [],
|
|
1610
|
-
detail: envelope.contEval.detail || null,
|
|
1611
|
-
};
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
if (envelope.contQa) {
|
|
1615
|
-
summary.gate = {
|
|
1616
|
-
architecture: envelope.contQa.gateClaims?.architecture || null,
|
|
1617
|
-
integration: envelope.contQa.gateClaims?.integration || null,
|
|
1618
|
-
durability: envelope.contQa.gateClaims?.durability || null,
|
|
1619
|
-
live: envelope.contQa.gateClaims?.live || null,
|
|
1620
|
-
docs: envelope.contQa.gateClaims?.docs || null,
|
|
1621
|
-
detail: envelope.contQa.gateClaims?.detail || null,
|
|
1622
|
-
};
|
|
1623
|
-
summary.verdict = {
|
|
1624
|
-
verdict: envelope.contQa.verdict?.verdict || null,
|
|
1625
|
-
detail: envelope.contQa.verdict?.detail || null,
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
|
-
if (envelope.security) {
|
|
1630
|
-
summary.security = {
|
|
1631
|
-
state: envelope.security.state || null,
|
|
1632
|
-
findings: envelope.security.findings || 0,
|
|
1633
|
-
approvals: envelope.security.approvals || 0,
|
|
1634
|
-
detail: envelope.security.detail || null,
|
|
1635
|
-
};
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
if (envelope.deploy) {
|
|
1639
|
-
summary.deploy = {
|
|
1640
|
-
state: envelope.deploy.state || "not_applicable",
|
|
1641
|
-
environment: envelope.deploy.environment || null,
|
|
1642
|
-
healthCheck: envelope.deploy.healthCheck || null,
|
|
1643
|
-
rolloutArtifact: envelope.deploy.rolloutArtifact || null,
|
|
1644
|
-
detail: envelope.deploy.detail || null,
|
|
1645
|
-
};
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
return summary;
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
|
-
/**
|
|
1652
|
-
* Write an agent result envelope alongside the summary file.
|
|
1653
|
-
*
|
|
1654
|
-
* @param {string} statusPath - Path to the .status file
|
|
1655
|
-
* @param {object} envelope - Result from buildAgentResultEnvelope
|
|
1656
|
-
*/
|
|
1657
|
-
export function writeAgentResultEnvelope(statusPath, envelope) {
|
|
1658
|
-
const envelopePath = agentEnvelopePathFromStatusPath(statusPath);
|
|
1659
|
-
writeJsonAtomic(envelopePath, envelope);
|
|
1660
|
-
return envelopePath;
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
|
-
/**
|
|
1664
|
-
* Read an agent result envelope if it exists.
|
|
1665
|
-
*
|
|
1666
|
-
* @param {string} statusPath - Path to the .status file
|
|
1667
|
-
* @returns {object|null} The envelope or null
|
|
1668
|
-
*/
|
|
1669
|
-
export function readAgentResultEnvelope(statusPath) {
|
|
1670
|
-
const envelopePath = agentEnvelopePathFromStatusPath(statusPath);
|
|
1671
|
-
const payload = readJsonOrNull(envelopePath);
|
|
1672
|
-
return payload && typeof payload === "object" ? payload : null;
|
|
1673
|
-
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_CODEX_SANDBOX_MODE,
|
|
6
|
+
DEFAULT_EXECUTOR_MODE,
|
|
7
|
+
normalizeCodexSandboxMode,
|
|
8
|
+
normalizeExecutorMode,
|
|
9
|
+
SUPPORTED_EXECUTOR_MODES,
|
|
10
|
+
} from "./config.mjs";
|
|
5
11
|
import {
|
|
6
12
|
DEFAULT_AGENT_LAUNCH_STAGGER_MS,
|
|
7
13
|
DEFAULT_AGENT_RATE_LIMIT_BASE_DELAY_SECONDS,
|
|
@@ -17,10 +23,6 @@ import {
|
|
|
17
23
|
parsePositiveInt,
|
|
18
24
|
sanitizeLaneName,
|
|
19
25
|
} from "./shared.mjs";
|
|
20
|
-
import {
|
|
21
|
-
DEFAULT_CODEX_SANDBOX_MODE,
|
|
22
|
-
normalizeCodexSandboxMode,
|
|
23
|
-
} from "./launcher.mjs";
|
|
24
26
|
import {
|
|
25
27
|
maybeAnnouncePackageUpdate,
|
|
26
28
|
WAVE_SUPPRESS_UPDATE_NOTICE_ENV,
|
|
@@ -29,6 +31,8 @@ import { readRunState } from "./wave-files.mjs";
|
|
|
29
31
|
import { readDependencyTickets } from "./coordination-store.mjs";
|
|
30
32
|
import { readWaveLedger } from "./ledger.mjs";
|
|
31
33
|
|
|
34
|
+
const AUTONOMOUS_EXECUTOR_MODES = SUPPORTED_EXECUTOR_MODES.filter((mode) => mode !== "local");
|
|
35
|
+
|
|
32
36
|
function printUsage() {
|
|
33
37
|
console.log(`Usage: pnpm exec wave autonomous [options]
|
|
34
38
|
|
|
@@ -46,7 +50,7 @@ Options:
|
|
|
46
50
|
--agent-launch-stagger-ms <n> Delay between agent launches (default: ${DEFAULT_AGENT_LAUNCH_STAGGER_MS})
|
|
47
51
|
--orchestrator-id <id> Orchestrator ID for coordination board
|
|
48
52
|
--resident-orchestrator Launch a resident orchestrator session for each live wave
|
|
49
|
-
--executor <mode> Default executor passed to launcher: ${
|
|
53
|
+
--executor <mode> Default executor passed to launcher: ${AUTONOMOUS_EXECUTOR_MODES.join(" | ")} (default: lane config)
|
|
50
54
|
--codex-sandbox <mode> Default Codex sandbox mode passed to launcher (default: ${DEFAULT_CODEX_SANDBOX_MODE})
|
|
51
55
|
--dashboard Enable dashboards (default: disabled)
|
|
52
56
|
--keep-sessions Keep tmux sessions between waves
|