@chllming/wave-orchestration 0.9.0 → 0.9.1
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 +28 -0
- package/README.md +119 -18
- package/docs/README.md +7 -3
- package/docs/architecture/README.md +1498 -0
- package/docs/concepts/operating-modes.md +2 -2
- package/docs/guides/author-and-run-waves.md +14 -4
- package/docs/guides/planner.md +2 -2
- package/docs/guides/{recommendations-0.9.0.md → recommendations-0.9.1.md} +8 -7
- package/docs/guides/sandboxed-environments.md +158 -0
- package/docs/guides/terminal-surfaces.md +14 -12
- package/docs/plans/current-state.md +5 -3
- package/docs/plans/end-state-architecture.md +3 -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 +46 -19
- package/docs/plans/sandbox-end-state-architecture.md +153 -0
- package/docs/reference/cli-reference.md +71 -7
- package/docs/reference/coordination-and-closure.md +1 -1
- package/docs/reference/github-packages-setup.md +1 -1
- package/docs/reference/migration-0.2-to-0.5.md +9 -7
- package/docs/reference/npmjs-token-publishing.md +53 -0
- package/docs/reference/npmjs-trusted-publishing.md +4 -50
- package/docs/reference/package-publishing-flow.md +272 -0
- package/docs/reference/runtime-config/README.md +2 -2
- package/docs/reference/sample-waves.md +5 -5
- package/docs/reference/skills.md +1 -1
- package/docs/roadmap.md +43 -201
- package/package.json +1 -1
- package/releases/manifest.json +19 -0
- package/scripts/wave-orchestrator/agent-process-runner.mjs +344 -0
- package/scripts/wave-orchestrator/agent-state.mjs +0 -1
- package/scripts/wave-orchestrator/artifact-schemas.mjs +7 -0
- package/scripts/wave-orchestrator/autonomous.mjs +47 -14
- package/scripts/wave-orchestrator/closure-engine.mjs +138 -17
- package/scripts/wave-orchestrator/control-cli.mjs +42 -5
- package/scripts/wave-orchestrator/dashboard-renderer.mjs +115 -43
- package/scripts/wave-orchestrator/derived-state-engine.mjs +6 -3
- package/scripts/wave-orchestrator/gate-engine.mjs +106 -38
- package/scripts/wave-orchestrator/install.mjs +13 -0
- package/scripts/wave-orchestrator/launcher-progress.mjs +91 -0
- package/scripts/wave-orchestrator/launcher-runtime.mjs +179 -68
- package/scripts/wave-orchestrator/launcher.mjs +201 -53
- package/scripts/wave-orchestrator/ledger.mjs +7 -2
- package/scripts/wave-orchestrator/projection-writer.mjs +13 -1
- package/scripts/wave-orchestrator/reducer-snapshot.mjs +6 -0
- package/scripts/wave-orchestrator/retry-control.mjs +3 -3
- package/scripts/wave-orchestrator/retry-engine.mjs +93 -6
- package/scripts/wave-orchestrator/role-helpers.mjs +30 -0
- package/scripts/wave-orchestrator/session-supervisor.mjs +94 -85
- package/scripts/wave-orchestrator/supervisor-cli.mjs +1306 -0
- package/scripts/wave-orchestrator/terminals.mjs +12 -32
- package/scripts/wave-orchestrator/tmux-adapter.mjs +300 -0
- package/scripts/wave-orchestrator/wave-files.mjs +38 -5
- package/scripts/wave.mjs +13 -0
|
@@ -84,7 +84,13 @@ function readIntegrationContradictionBarrier(derivedState, agentId, logPath) {
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
function
|
|
87
|
+
function isSecurityReviewAgentWithOptions(agent, options = {}) {
|
|
88
|
+
return isSecurityReviewAgent(agent, {
|
|
89
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function resolveRunReportPath(wave, runInfo, options = {}) {
|
|
88
94
|
if (!wave || !runInfo?.agent) {
|
|
89
95
|
return null;
|
|
90
96
|
}
|
|
@@ -94,7 +100,7 @@ function resolveRunReportPath(wave, runInfo) {
|
|
|
94
100
|
if (runInfo.agent.agentId === (wave.contEvalAgentId || "E0") && wave.contEvalReportPath) {
|
|
95
101
|
return path.resolve(REPO_ROOT, wave.contEvalReportPath);
|
|
96
102
|
}
|
|
97
|
-
if (
|
|
103
|
+
if (isSecurityReviewAgentWithOptions(runInfo.agent, options)) {
|
|
98
104
|
const securityReportPath = resolveSecurityReviewReportPath(runInfo.agent);
|
|
99
105
|
return securityReportPath ? path.resolve(REPO_ROOT, securityReportPath) : null;
|
|
100
106
|
}
|
|
@@ -132,12 +138,12 @@ function validateEnvelopeForRun(runInfo, envelope, options = {}) {
|
|
|
132
138
|
};
|
|
133
139
|
}
|
|
134
140
|
|
|
135
|
-
export function materializeAgentExecutionSummaryForRun(wave, runInfo) {
|
|
141
|
+
export function materializeAgentExecutionSummaryForRun(wave, runInfo, options = {}) {
|
|
136
142
|
const statusRecord = readStatusRecordIfPresent(runInfo.statusPath);
|
|
137
143
|
if (!statusRecord) {
|
|
138
144
|
return null;
|
|
139
145
|
}
|
|
140
|
-
const reportPath = resolveRunReportPath(wave, runInfo);
|
|
146
|
+
const reportPath = resolveRunReportPath(wave, runInfo, options);
|
|
141
147
|
const summary = buildAgentExecutionSummary({
|
|
142
148
|
agent: runInfo.agent,
|
|
143
149
|
statusRecord,
|
|
@@ -189,7 +195,7 @@ export function materializeAgentExecutionSummaryForRun(wave, runInfo) {
|
|
|
189
195
|
export function readRunResultEnvelope(runInfo, wave = null, options = {}) {
|
|
190
196
|
const mode = normalizeReadMode(options.mode);
|
|
191
197
|
const statusRecord = runInfo?.statusPath ? readStatusRecordIfPresent(runInfo.statusPath) : null;
|
|
192
|
-
const reportPath = wave ? resolveRunReportPath(wave, runInfo) : null;
|
|
198
|
+
const reportPath = wave ? resolveRunReportPath(wave, runInfo, options) : null;
|
|
193
199
|
const runEnvelopeContext = resolveRunEnvelopeContext(runInfo, wave, { statusRecord });
|
|
194
200
|
const envelopeReadOptions = buildEnvelopeReadOptions(runInfo, wave, statusRecord, reportPath);
|
|
195
201
|
const synthesizeFromSummary = (summary, source) => {
|
|
@@ -285,7 +291,7 @@ export function readRunResultEnvelope(runInfo, wave = null, options = {}) {
|
|
|
285
291
|
runInfo?.logPath &&
|
|
286
292
|
fs.existsSync(runInfo.statusPath)
|
|
287
293
|
) {
|
|
288
|
-
materializeAgentExecutionSummaryForRun(wave, runInfo);
|
|
294
|
+
materializeAgentExecutionSummaryForRun(wave, runInfo, options);
|
|
289
295
|
const envelope =
|
|
290
296
|
readAgentResultEnvelopeForRun(runInfo, wave, { statusRecord }) ||
|
|
291
297
|
readAgentResultEnvelope(runInfo.statusPath);
|
|
@@ -313,9 +319,12 @@ export function readRunExecutionSummary(runInfo, wave = null, options = {}) {
|
|
|
313
319
|
const applyProofRegistry = (summary) =>
|
|
314
320
|
runInfo?.proofRegistry ? augmentSummaryWithProofRegistry(runInfo.agent, summary, runInfo.proofRegistry) : summary;
|
|
315
321
|
const statusRecord = runInfo?.statusPath ? readStatusRecordIfPresent(runInfo.statusPath) : null;
|
|
316
|
-
const reportPath = wave ? resolveRunReportPath(wave, runInfo) : null;
|
|
322
|
+
const reportPath = wave ? resolveRunReportPath(wave, runInfo, options) : null;
|
|
317
323
|
const envelopeReadOptions = buildEnvelopeReadOptions(runInfo, wave, statusRecord, reportPath);
|
|
318
|
-
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
324
|
+
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
325
|
+
mode,
|
|
326
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
327
|
+
});
|
|
319
328
|
if (envelopeResult?.valid && envelopeResult.envelope) {
|
|
320
329
|
return applyProofRegistry(
|
|
321
330
|
projectLegacySummaryFromEnvelope(envelopeResult.envelope, envelopeReadOptions),
|
|
@@ -348,9 +357,12 @@ export function readRunExecutionSummary(runInfo, wave = null, options = {}) {
|
|
|
348
357
|
return null;
|
|
349
358
|
}
|
|
350
359
|
|
|
351
|
-
export function materializeAgentExecutionSummaries(wave, agentRuns) {
|
|
360
|
+
export function materializeAgentExecutionSummaries(wave, agentRuns, options = {}) {
|
|
352
361
|
return Object.fromEntries(
|
|
353
|
-
agentRuns.map((runInfo) => [
|
|
362
|
+
agentRuns.map((runInfo) => [
|
|
363
|
+
runInfo.agent.agentId,
|
|
364
|
+
materializeAgentExecutionSummaryForRun(wave, runInfo, options),
|
|
365
|
+
]),
|
|
354
366
|
);
|
|
355
367
|
}
|
|
356
368
|
|
|
@@ -369,7 +381,10 @@ export function readWaveContQaGate(wave, agentRuns, options = {}) {
|
|
|
369
381
|
logPath: null,
|
|
370
382
|
};
|
|
371
383
|
}
|
|
372
|
-
const envelopeResult = readRunResultEnvelope(contQaRun, wave, {
|
|
384
|
+
const envelopeResult = readRunResultEnvelope(contQaRun, wave, {
|
|
385
|
+
mode,
|
|
386
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
387
|
+
});
|
|
373
388
|
const summary = envelopeResult.valid
|
|
374
389
|
? projectLegacySummaryFromEnvelope(
|
|
375
390
|
envelopeResult.envelope,
|
|
@@ -377,10 +392,13 @@ export function readWaveContQaGate(wave, agentRuns, options = {}) {
|
|
|
377
392
|
contQaRun,
|
|
378
393
|
wave,
|
|
379
394
|
contQaRun?.statusPath ? readStatusRecordIfPresent(contQaRun.statusPath) : null,
|
|
380
|
-
resolveRunReportPath(wave, contQaRun),
|
|
395
|
+
resolveRunReportPath(wave, contQaRun, options),
|
|
381
396
|
),
|
|
382
397
|
)
|
|
383
|
-
: readRunExecutionSummary(contQaRun, wave, {
|
|
398
|
+
: readRunExecutionSummary(contQaRun, wave, {
|
|
399
|
+
mode,
|
|
400
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
401
|
+
});
|
|
384
402
|
if (summary) {
|
|
385
403
|
const validation = validateContQaSummary(contQaRun.agent, summary, { mode });
|
|
386
404
|
return {
|
|
@@ -461,7 +479,10 @@ export function readWaveContEvalGate(wave, agentRuns, options = {}) {
|
|
|
461
479
|
logPath: null,
|
|
462
480
|
};
|
|
463
481
|
}
|
|
464
|
-
const envelopeResult = readRunResultEnvelope(contEvalRun, wave, {
|
|
482
|
+
const envelopeResult = readRunResultEnvelope(contEvalRun, wave, {
|
|
483
|
+
mode,
|
|
484
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
485
|
+
});
|
|
465
486
|
const summary = envelopeResult.valid
|
|
466
487
|
? projectLegacySummaryFromEnvelope(
|
|
467
488
|
envelopeResult.envelope,
|
|
@@ -469,10 +490,13 @@ export function readWaveContEvalGate(wave, agentRuns, options = {}) {
|
|
|
469
490
|
contEvalRun,
|
|
470
491
|
wave,
|
|
471
492
|
contEvalRun?.statusPath ? readStatusRecordIfPresent(contEvalRun.statusPath) : null,
|
|
472
|
-
resolveRunReportPath(wave, contEvalRun),
|
|
493
|
+
resolveRunReportPath(wave, contEvalRun, options),
|
|
473
494
|
),
|
|
474
495
|
)
|
|
475
|
-
: readRunExecutionSummary(contEvalRun, wave, {
|
|
496
|
+
: readRunExecutionSummary(contEvalRun, wave, {
|
|
497
|
+
mode,
|
|
498
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
499
|
+
});
|
|
476
500
|
if (summary) {
|
|
477
501
|
const validation = validateContEvalSummary(contEvalRun.agent, summary, {
|
|
478
502
|
mode,
|
|
@@ -522,11 +546,14 @@ export function readWaveImplementationGate(wave, agentRuns, options = {}) {
|
|
|
522
546
|
[contQaAgentId, integrationAgentId, documentationAgentId].includes(runInfo.agent.agentId) ||
|
|
523
547
|
isContEvalReportOnlyAgent(runInfo.agent, { contEvalAgentId }) ||
|
|
524
548
|
isDocsOnlyDesignAgent(runInfo.agent) ||
|
|
525
|
-
|
|
549
|
+
isSecurityReviewAgentWithOptions(runInfo.agent, options)
|
|
526
550
|
) {
|
|
527
551
|
continue;
|
|
528
552
|
}
|
|
529
|
-
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
553
|
+
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
554
|
+
mode,
|
|
555
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
556
|
+
});
|
|
530
557
|
if (mode === "live" && !envelopeResult.valid) {
|
|
531
558
|
return {
|
|
532
559
|
ok: false,
|
|
@@ -548,10 +575,13 @@ export function readWaveImplementationGate(wave, agentRuns, options = {}) {
|
|
|
548
575
|
runInfo,
|
|
549
576
|
wave,
|
|
550
577
|
runInfo?.statusPath ? readStatusRecordIfPresent(runInfo.statusPath) : null,
|
|
551
|
-
resolveRunReportPath(wave, runInfo),
|
|
578
|
+
resolveRunReportPath(wave, runInfo, options),
|
|
552
579
|
),
|
|
553
580
|
)
|
|
554
|
-
: readRunExecutionSummary(runInfo, wave, {
|
|
581
|
+
: readRunExecutionSummary(runInfo, wave, {
|
|
582
|
+
mode,
|
|
583
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
584
|
+
});
|
|
555
585
|
const validation = validateImplementationSummary(runInfo.agent, summary);
|
|
556
586
|
if (!validation.ok) {
|
|
557
587
|
return {
|
|
@@ -585,7 +615,10 @@ export function readWaveDesignGate(wave, agentRuns, options = {}) {
|
|
|
585
615
|
};
|
|
586
616
|
}
|
|
587
617
|
for (const runInfo of designRuns) {
|
|
588
|
-
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
618
|
+
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
619
|
+
mode,
|
|
620
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
621
|
+
});
|
|
589
622
|
if (mode === "live" && !envelopeResult.valid) {
|
|
590
623
|
return {
|
|
591
624
|
ok: false,
|
|
@@ -607,10 +640,13 @@ export function readWaveDesignGate(wave, agentRuns, options = {}) {
|
|
|
607
640
|
runInfo,
|
|
608
641
|
wave,
|
|
609
642
|
runInfo?.statusPath ? readStatusRecordIfPresent(runInfo.statusPath) : null,
|
|
610
|
-
resolveRunReportPath(wave, runInfo),
|
|
643
|
+
resolveRunReportPath(wave, runInfo, options),
|
|
611
644
|
),
|
|
612
645
|
)
|
|
613
|
-
: readRunExecutionSummary(runInfo, wave, {
|
|
646
|
+
: readRunExecutionSummary(runInfo, wave, {
|
|
647
|
+
mode,
|
|
648
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
649
|
+
});
|
|
614
650
|
const validation = validateDesignSummary(runInfo.agent, summary);
|
|
615
651
|
if (!validation.ok) {
|
|
616
652
|
return {
|
|
@@ -709,7 +745,10 @@ export function readWaveComponentGate(wave, agentRuns, options = {}) {
|
|
|
709
745
|
const summariesByAgentId = Object.fromEntries(
|
|
710
746
|
agentRuns.map((runInfo) => [
|
|
711
747
|
runInfo.agent.agentId,
|
|
712
|
-
readRunExecutionSummary(runInfo, wave, {
|
|
748
|
+
readRunExecutionSummary(runInfo, wave, {
|
|
749
|
+
mode,
|
|
750
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
751
|
+
}),
|
|
713
752
|
]),
|
|
714
753
|
);
|
|
715
754
|
const validation = validateWaveComponentPromotions(wave, summariesByAgentId, options);
|
|
@@ -793,7 +832,10 @@ export function readWaveDocumentationGate(wave, agentRuns, options = {}) {
|
|
|
793
832
|
logPath: null,
|
|
794
833
|
};
|
|
795
834
|
}
|
|
796
|
-
const envelopeResult = readRunResultEnvelope(docRun, wave, {
|
|
835
|
+
const envelopeResult = readRunResultEnvelope(docRun, wave, {
|
|
836
|
+
mode,
|
|
837
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
838
|
+
});
|
|
797
839
|
if (mode === "live" && !envelopeResult.valid) {
|
|
798
840
|
return {
|
|
799
841
|
ok: false,
|
|
@@ -815,10 +857,13 @@ export function readWaveDocumentationGate(wave, agentRuns, options = {}) {
|
|
|
815
857
|
docRun,
|
|
816
858
|
wave,
|
|
817
859
|
docRun?.statusPath ? readStatusRecordIfPresent(docRun.statusPath) : null,
|
|
818
|
-
resolveRunReportPath(wave, docRun),
|
|
860
|
+
resolveRunReportPath(wave, docRun, options),
|
|
819
861
|
),
|
|
820
862
|
)
|
|
821
|
-
: readRunExecutionSummary(docRun, wave, {
|
|
863
|
+
: readRunExecutionSummary(docRun, wave, {
|
|
864
|
+
mode,
|
|
865
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
866
|
+
});
|
|
822
867
|
const validation = validateDocumentationClosureSummary(docRun.agent, summary);
|
|
823
868
|
return {
|
|
824
869
|
ok: validation.ok,
|
|
@@ -831,7 +876,9 @@ export function readWaveDocumentationGate(wave, agentRuns, options = {}) {
|
|
|
831
876
|
|
|
832
877
|
export function readWaveSecurityGate(wave, agentRuns, options = {}) {
|
|
833
878
|
const mode = normalizeReadMode(options.mode || "live");
|
|
834
|
-
const securityRuns = (agentRuns || []).filter((run) =>
|
|
879
|
+
const securityRuns = (agentRuns || []).filter((run) =>
|
|
880
|
+
isSecurityReviewAgentWithOptions(run.agent, options),
|
|
881
|
+
);
|
|
835
882
|
if (securityRuns.length === 0) {
|
|
836
883
|
return {
|
|
837
884
|
ok: true,
|
|
@@ -843,7 +890,10 @@ export function readWaveSecurityGate(wave, agentRuns, options = {}) {
|
|
|
843
890
|
}
|
|
844
891
|
const concernAgentIds = [];
|
|
845
892
|
for (const runInfo of securityRuns) {
|
|
846
|
-
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
893
|
+
const envelopeResult = readRunResultEnvelope(runInfo, wave, {
|
|
894
|
+
mode,
|
|
895
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
896
|
+
});
|
|
847
897
|
if (mode === "live" && !envelopeResult.valid) {
|
|
848
898
|
return {
|
|
849
899
|
ok: false,
|
|
@@ -865,10 +915,13 @@ export function readWaveSecurityGate(wave, agentRuns, options = {}) {
|
|
|
865
915
|
runInfo,
|
|
866
916
|
wave,
|
|
867
917
|
runInfo?.statusPath ? readStatusRecordIfPresent(runInfo.statusPath) : null,
|
|
868
|
-
resolveRunReportPath(wave, runInfo),
|
|
918
|
+
resolveRunReportPath(wave, runInfo, options),
|
|
869
919
|
),
|
|
870
920
|
)
|
|
871
|
-
: readRunExecutionSummary(runInfo, wave, {
|
|
921
|
+
: readRunExecutionSummary(runInfo, wave, {
|
|
922
|
+
mode,
|
|
923
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
924
|
+
});
|
|
872
925
|
const validation = validateSecuritySummary(runInfo.agent, summary);
|
|
873
926
|
if (!validation.ok) {
|
|
874
927
|
return {
|
|
@@ -923,7 +976,10 @@ export function readWaveIntegrationGate(wave, agentRuns, options = {}) {
|
|
|
923
976
|
logPath: null,
|
|
924
977
|
};
|
|
925
978
|
}
|
|
926
|
-
const envelopeResult = readRunResultEnvelope(integrationRun, wave, {
|
|
979
|
+
const envelopeResult = readRunResultEnvelope(integrationRun, wave, {
|
|
980
|
+
mode,
|
|
981
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
982
|
+
});
|
|
927
983
|
if (mode === "live" && !envelopeResult.valid) {
|
|
928
984
|
return {
|
|
929
985
|
ok: false,
|
|
@@ -945,10 +1001,13 @@ export function readWaveIntegrationGate(wave, agentRuns, options = {}) {
|
|
|
945
1001
|
integrationRun,
|
|
946
1002
|
wave,
|
|
947
1003
|
integrationRun?.statusPath ? readStatusRecordIfPresent(integrationRun.statusPath) : null,
|
|
948
|
-
resolveRunReportPath(wave, integrationRun),
|
|
1004
|
+
resolveRunReportPath(wave, integrationRun, options),
|
|
949
1005
|
),
|
|
950
1006
|
)
|
|
951
|
-
: readRunExecutionSummary(integrationRun, wave, {
|
|
1007
|
+
: readRunExecutionSummary(integrationRun, wave, {
|
|
1008
|
+
mode,
|
|
1009
|
+
securityRolePromptPath: options.securityRolePromptPath,
|
|
1010
|
+
});
|
|
952
1011
|
const validation = validateIntegrationSummary(integrationRun.agent, summary);
|
|
953
1012
|
return {
|
|
954
1013
|
ok: validation.ok,
|
|
@@ -1105,7 +1164,10 @@ export function buildGateSnapshot({
|
|
|
1105
1164
|
(agentRuns || [])
|
|
1106
1165
|
.map((runInfo) => [
|
|
1107
1166
|
runInfo.agent.agentId,
|
|
1108
|
-
readRunExecutionSummary(runInfo, wave, {
|
|
1167
|
+
readRunExecutionSummary(runInfo, wave, {
|
|
1168
|
+
mode: validationMode,
|
|
1169
|
+
securityRolePromptPath: lanePaths?.securityRolePromptPath,
|
|
1170
|
+
}),
|
|
1109
1171
|
])
|
|
1110
1172
|
.filter(([, summary]) => Boolean(summary)),
|
|
1111
1173
|
);
|
|
@@ -1127,6 +1189,7 @@ export function buildGateSnapshot({
|
|
|
1127
1189
|
contEvalAgentId: lanePaths?.contEvalAgentId,
|
|
1128
1190
|
integrationAgentId: lanePaths?.integrationAgentId,
|
|
1129
1191
|
documentationAgentId: lanePaths?.documentationAgentId,
|
|
1192
|
+
securityRolePromptPath: lanePaths?.securityRolePromptPath,
|
|
1130
1193
|
requireIntegrationStewardFromWave: lanePaths?.requireIntegrationStewardFromWave,
|
|
1131
1194
|
laneProfile: lanePaths?.laneProfile,
|
|
1132
1195
|
benchmarkCatalogPath: lanePaths?.laneProfile?.paths?.benchmarkCatalogPath,
|
|
@@ -1157,7 +1220,7 @@ export function readWaveImplementationGatePure(wave, agentResults, options = {})
|
|
|
1157
1220
|
[contQaAgentId, integrationAgentId, documentationAgentId].includes(agent.agentId) ||
|
|
1158
1221
|
isContEvalReportOnlyAgent(agent, { contEvalAgentId }) ||
|
|
1159
1222
|
isDocsOnlyDesignAgent(agent) ||
|
|
1160
|
-
|
|
1223
|
+
isSecurityReviewAgentWithOptions(agent, options)
|
|
1161
1224
|
) {
|
|
1162
1225
|
continue;
|
|
1163
1226
|
}
|
|
@@ -1348,7 +1411,9 @@ export function readWaveDocumentationGatePure(wave, agentResults, options = {})
|
|
|
1348
1411
|
|
|
1349
1412
|
export function readWaveSecurityGatePure(wave, agentResults, options = {}) {
|
|
1350
1413
|
const agents = Array.isArray(wave.agents) ? wave.agents : [];
|
|
1351
|
-
const securityAgents = agents.filter((agent) =>
|
|
1414
|
+
const securityAgents = agents.filter((agent) =>
|
|
1415
|
+
isSecurityReviewAgentWithOptions(agent, options),
|
|
1416
|
+
);
|
|
1352
1417
|
if (securityAgents.length === 0) {
|
|
1353
1418
|
return { ok: true, agentId: null, statusCode: "pass",
|
|
1354
1419
|
detail: "No security reviewer declared for this wave.", logPath: null };
|
|
@@ -1419,6 +1484,7 @@ export function buildGateSnapshotPure({ wave, agentResults, derivedState, valida
|
|
|
1419
1484
|
const implementationGate = readWaveImplementationGatePure(wave, agentResults, {
|
|
1420
1485
|
contQaAgentId: laneConfig.contQaAgentId, contEvalAgentId: laneConfig.contEvalAgentId,
|
|
1421
1486
|
integrationAgentId: laneConfig.integrationAgentId, documentationAgentId: laneConfig.documentationAgentId,
|
|
1487
|
+
securityRolePromptPath: laneConfig.securityRolePromptPath,
|
|
1422
1488
|
});
|
|
1423
1489
|
const componentGate = readWaveComponentGatePure(wave, agentResults, { laneProfile: laneConfig.laneProfile });
|
|
1424
1490
|
const integrationMarkerGate = readWaveIntegrationGatePure(wave, agentResults, {
|
|
@@ -1459,7 +1525,9 @@ export function buildGateSnapshotPure({ wave, agentResults, derivedState, valida
|
|
|
1459
1525
|
const contEvalGate = readWaveContEvalGatePure(wave, agentResults, {
|
|
1460
1526
|
contEvalAgentId: laneConfig.contEvalAgentId, mode: validationMode,
|
|
1461
1527
|
evalTargets: wave.evalTargets, benchmarkCatalogPath: laneConfig.benchmarkCatalogPath });
|
|
1462
|
-
const securityGate = readWaveSecurityGatePure(wave, agentResults
|
|
1528
|
+
const securityGate = readWaveSecurityGatePure(wave, agentResults, {
|
|
1529
|
+
securityRolePromptPath: laneConfig.securityRolePromptPath,
|
|
1530
|
+
});
|
|
1463
1531
|
const contQaGate = readWaveContQaGatePure(wave, agentResults, {
|
|
1464
1532
|
contQaAgentId: laneConfig.contQaAgentId, mode: validationMode });
|
|
1465
1533
|
const infraGate = readWaveInfraGatePure(wave, agentResults);
|
|
@@ -26,6 +26,7 @@ export const UPGRADE_HISTORY_DIR = path.join(REPO_ROOT, INSTALL_STATE_DIR, "upgr
|
|
|
26
26
|
export const CHANGELOG_MANIFEST_PATH = path.join(PACKAGE_ROOT, "releases", "manifest.json");
|
|
27
27
|
export const WORKSPACE_PACKAGE_JSON_PATH = path.join(REPO_ROOT, "package.json");
|
|
28
28
|
export const STARTER_TEMPLATE_PATHS = [
|
|
29
|
+
"CHANGELOG.md",
|
|
29
30
|
"wave.config.json",
|
|
30
31
|
"scripts/wave-status.sh",
|
|
31
32
|
"scripts/wave-watch.sh",
|
|
@@ -61,18 +62,30 @@ export const STARTER_TEMPLATE_PATHS = [
|
|
|
61
62
|
"docs/evals/cases/wave-contradiction-conflict.json",
|
|
62
63
|
"docs/evals/cases/wave-simultaneous-lockstep.json",
|
|
63
64
|
"docs/evals/cases/wave-expert-routing-preservation.json",
|
|
65
|
+
"docs/guides/author-and-run-waves.md",
|
|
66
|
+
"docs/guides/monorepo-projects.md",
|
|
64
67
|
"docs/guides/planner.md",
|
|
68
|
+
"docs/guides/recommendations-0.9.1.md",
|
|
69
|
+
"docs/guides/sandboxed-environments.md",
|
|
70
|
+
"docs/guides/signal-wrappers.md",
|
|
65
71
|
"docs/guides/terminal-surfaces.md",
|
|
72
|
+
"docs/plans/architecture-hardening-migration.md",
|
|
66
73
|
"docs/plans/component-cutover-matrix.json",
|
|
67
74
|
"docs/plans/component-cutover-matrix.md",
|
|
68
75
|
"docs/plans/context7-wave-orchestrator.md",
|
|
69
76
|
"docs/plans/current-state.md",
|
|
77
|
+
"docs/plans/end-state-architecture.md",
|
|
70
78
|
"docs/plans/examples/wave-example-live-proof.md",
|
|
71
79
|
"docs/plans/master-plan.md",
|
|
72
80
|
"docs/plans/migration.md",
|
|
81
|
+
"docs/plans/sandbox-end-state-architecture.md",
|
|
73
82
|
"docs/plans/wave-orchestrator.md",
|
|
74
83
|
"docs/plans/waves/wave-0.md",
|
|
84
|
+
"docs/reference/cli-reference.md",
|
|
75
85
|
"docs/reference/live-proof-waves.md",
|
|
86
|
+
"docs/reference/npmjs-token-publishing.md",
|
|
87
|
+
"docs/reference/npmjs-trusted-publishing.md",
|
|
88
|
+
"docs/reference/package-publishing-flow.md",
|
|
76
89
|
"docs/reference/repository-guidance.md",
|
|
77
90
|
"docs/reference/sample-waves.md",
|
|
78
91
|
"docs/reference/skills.md",
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
ensureDirectory,
|
|
5
|
+
readJsonOrNull,
|
|
6
|
+
toIsoTimestamp,
|
|
7
|
+
writeJsonAtomic,
|
|
8
|
+
} from "./shared.mjs";
|
|
9
|
+
|
|
10
|
+
function normalizeStringArray(values) {
|
|
11
|
+
return Array.from(
|
|
12
|
+
new Set(
|
|
13
|
+
(Array.isArray(values) ? values : [])
|
|
14
|
+
.map((value) => String(value || "").trim())
|
|
15
|
+
.filter(Boolean),
|
|
16
|
+
),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function launcherProgressPathForRun(lanePaths, runId) {
|
|
21
|
+
if (!lanePaths?.controlDir || !runId) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return path.join(lanePaths.controlDir, "supervisor", "runs", runId, "launcher-progress.json");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function normalizeLauncherProgress(payload, defaults = {}) {
|
|
28
|
+
const source = payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
29
|
+
return {
|
|
30
|
+
runId: String(source.runId || defaults.runId || "").trim() || null,
|
|
31
|
+
waveNumber: Number.isFinite(Number(source.waveNumber))
|
|
32
|
+
? Number(source.waveNumber)
|
|
33
|
+
: Number.isFinite(Number(defaults.waveNumber))
|
|
34
|
+
? Number(defaults.waveNumber)
|
|
35
|
+
: null,
|
|
36
|
+
attemptNumber: Number.isFinite(Number(source.attemptNumber))
|
|
37
|
+
? Number(source.attemptNumber)
|
|
38
|
+
: Number.isFinite(Number(defaults.attemptNumber))
|
|
39
|
+
? Number(defaults.attemptNumber)
|
|
40
|
+
: null,
|
|
41
|
+
phase: String(source.phase || defaults.phase || "").trim() || null,
|
|
42
|
+
selectedAgentIds: normalizeStringArray(source.selectedAgentIds),
|
|
43
|
+
launchedAgentIds: normalizeStringArray(source.launchedAgentIds),
|
|
44
|
+
completedAgentIds: normalizeStringArray(source.completedAgentIds),
|
|
45
|
+
resumeFromPhase: String(source.resumeFromPhase || defaults.resumeFromPhase || "").trim() || null,
|
|
46
|
+
forwardedClosureGaps: Array.isArray(source.forwardedClosureGaps)
|
|
47
|
+
? JSON.parse(JSON.stringify(source.forwardedClosureGaps))
|
|
48
|
+
: [],
|
|
49
|
+
gateSnapshotSummary:
|
|
50
|
+
source.gateSnapshotSummary && typeof source.gateSnapshotSummary === "object"
|
|
51
|
+
? JSON.parse(JSON.stringify(source.gateSnapshotSummary))
|
|
52
|
+
: null,
|
|
53
|
+
finalized: source.finalized === true,
|
|
54
|
+
finalDisposition: String(source.finalDisposition || defaults.finalDisposition || "").trim() || null,
|
|
55
|
+
exitCode: Number.isInteger(source.exitCode) ? source.exitCode : null,
|
|
56
|
+
updatedAt: String(source.updatedAt || defaults.updatedAt || "").trim() || toIsoTimestamp(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function readLauncherProgress(filePath, defaults = {}) {
|
|
61
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return normalizeLauncherProgress(readJsonOrNull(filePath), defaults);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function writeLauncherProgress(filePath, payload, defaults = {}) {
|
|
68
|
+
if (!filePath) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
ensureDirectory(path.dirname(filePath));
|
|
72
|
+
const normalized = normalizeLauncherProgress(payload, defaults);
|
|
73
|
+
writeJsonAtomic(filePath, normalized);
|
|
74
|
+
return normalized;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function updateLauncherProgress(filePath, patch, defaults = {}) {
|
|
78
|
+
if (!filePath) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const current = readLauncherProgress(filePath, defaults) || normalizeLauncherProgress({}, defaults);
|
|
82
|
+
return writeLauncherProgress(
|
|
83
|
+
filePath,
|
|
84
|
+
{
|
|
85
|
+
...current,
|
|
86
|
+
...patch,
|
|
87
|
+
updatedAt: toIsoTimestamp(),
|
|
88
|
+
},
|
|
89
|
+
defaults,
|
|
90
|
+
);
|
|
91
|
+
}
|