@chllming/wave-orchestration 0.9.13 → 0.9.14

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/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@chllming/wave-orchestration",
3
- "version": "0.9.13",
3
+ "version": "0.9.14",
4
4
  "license": "MIT",
5
5
  "description": "Generic wave-based multi-agent orchestration for repository work.",
6
+ "packageManager": "pnpm@10.23.0",
6
7
  "repository": {
7
8
  "type": "git",
8
9
  "url": "git+https://github.com/chllming/agent-wave-orchestrator.git"
@@ -31,12 +32,6 @@
31
32
  "wave-dashboard": "scripts/wave-dashboard.mjs",
32
33
  "wave-local-executor": "scripts/wave-local-executor.mjs"
33
34
  },
34
- "devDependencies": {
35
- "@mozilla/readability": "^0.6.0",
36
- "jsdom": "^29.0.1",
37
- "pdfjs-dist": "^5.5.207",
38
- "vitest": "3.2.4"
39
- },
40
35
  "scripts": {
41
36
  "context7:api-check": "bash scripts/context7-export-env.sh run bash scripts/context7-api-check.sh",
42
37
  "research:import-agent-context": "node scripts/research/import-agent-context-archive.mjs scripts/research/manifests/agent-context-expanded-2026-03-22.mjs",
@@ -50,5 +45,11 @@
50
45
  "wave:feedback": "node scripts/wave-human-feedback.mjs",
51
46
  "wave:launch": "node scripts/wave-launcher.mjs",
52
47
  "wave:local": "node scripts/wave-local-executor.mjs"
48
+ },
49
+ "devDependencies": {
50
+ "@mozilla/readability": "^0.6.0",
51
+ "jsdom": "^29.0.1",
52
+ "pdfjs-dist": "^5.5.207",
53
+ "vitest": "3.2.4"
53
54
  }
54
- }
55
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -922,8 +922,28 @@ export function validateImplementationSummary(agent, summary) {
922
922
  };
923
923
  }
924
924
 
925
- export function validateDocumentationClosureSummary(agent, summary) {
925
+ export function validateDocumentationClosureSummary(agent, summary, options = {}) {
926
926
  if (!summary?.docClosure) {
927
+ // When the agent had exit-code 0 but produced no structured output (e.g. credential
928
+ // broker collision, empty run), allow a graceful fallback instead of hard-failing
929
+ // the entire wave. The caller (gate-engine) decides whether the surrounding
930
+ // integration/QA state justifies auto-closing documentation.
931
+ const emptyRun = !summary || (
932
+ !summary.proof && !summary.component && !summary.integration &&
933
+ !summary.verdict && !summary.docClosure && !summary.security &&
934
+ (summary.rawSignalCount === 0 || summary.rawSignalCount === undefined)
935
+ );
936
+ if (options.allowFallbackOnEmptyRun && emptyRun) {
937
+ return {
938
+ ok: false,
939
+ statusCode: "missing-doc-closure-empty-run",
940
+ detail: appendTerminationHint(
941
+ `Documentation steward ${agent?.agentId || "A9"} produced no output (empty run). Eligible for fallback auto-closure.`,
942
+ summary,
943
+ ),
944
+ eligibleForFallback: true,
945
+ };
946
+ }
927
947
  return {
928
948
  ok: false,
929
949
  statusCode: "missing-doc-closure",
@@ -922,7 +922,29 @@ export function readWaveDocumentationGate(wave, agentRuns, options = {}) {
922
922
  mode,
923
923
  securityRolePromptPath: options.securityRolePromptPath,
924
924
  });
925
- const validation = validateDocumentationClosureSummary(docRun.agent, summary);
925
+ const validation = validateDocumentationClosureSummary(docRun.agent, summary, {
926
+ allowFallbackOnEmptyRun: true,
927
+ });
928
+ // Fallback: when doc steward had an empty run but integration/QA passed,
929
+ // auto-close instead of blocking the wave.
930
+ if (!validation.ok && validation.eligibleForFallback) {
931
+ const integrationSummary = options.derivedState?.integrationSummary;
932
+ const integrationReady =
933
+ integrationSummary?.recommendation === "ready-for-doc-closure";
934
+ const contQaPassed =
935
+ options.derivedState?.ledger?.contQa?.verdict === "pass" ||
936
+ options.derivedState?.ledger?.contQa?.verdict === "PASS";
937
+ if (integrationReady || contQaPassed) {
938
+ return {
939
+ ok: true,
940
+ agentId: docRun.agent.agentId,
941
+ statusCode: "fallback-auto-closed",
942
+ detail: `Documentation steward ${docRun.agent.agentId} had an empty run. Auto-closed because ${integrationReady ? "integration is ready-for-doc-closure" : "cont-QA passed"}.`,
943
+ logPath: summary?.logPath || path.relative(REPO_ROOT, docRun.logPath),
944
+ docClosureState: "no-change",
945
+ };
946
+ }
947
+ }
926
948
  return {
927
949
  ok: validation.ok,
928
950
  agentId: docRun.agent.agentId,
@@ -1501,7 +1523,30 @@ export function readWaveDocumentationGatePure(wave, agentResults, options = {})
1501
1523
  }
1502
1524
  const summary = agentResults?.[documentationAgentId] || null;
1503
1525
  const agent = { agentId: documentationAgentId };
1504
- const validation = validateDocumentationClosureSummary(agent, summary);
1526
+ const validation = validateDocumentationClosureSummary(agent, summary, {
1527
+ allowFallbackOnEmptyRun: true,
1528
+ });
1529
+ // When the doc steward had an empty run (broker collision, no output) but
1530
+ // integration is already ready-for-doc-closure, auto-close documentation
1531
+ // instead of failing the entire wave.
1532
+ if (!validation.ok && validation.eligibleForFallback) {
1533
+ const integrationSummary = options.derivedState?.integrationSummary;
1534
+ const integrationReady =
1535
+ integrationSummary?.recommendation === "ready-for-doc-closure";
1536
+ const contQaPassed =
1537
+ options.derivedState?.ledger?.contQa?.verdict === "pass" ||
1538
+ options.derivedState?.ledger?.contQa?.verdict === "PASS";
1539
+ if (integrationReady || contQaPassed) {
1540
+ return {
1541
+ ok: true,
1542
+ agentId: documentationAgentId,
1543
+ statusCode: "fallback-auto-closed",
1544
+ detail: `Documentation steward ${documentationAgentId} had an empty run. Auto-closed because ${integrationReady ? "integration is ready-for-doc-closure" : "cont-QA passed"}.`,
1545
+ logPath: summary?.logPath || null,
1546
+ docClosureState: "no-change",
1547
+ };
1548
+ }
1549
+ }
1505
1550
  return { ok: validation.ok, agentId: documentationAgentId, statusCode: validation.statusCode,
1506
1551
  detail: validation.detail, logPath: summary?.logPath || null };
1507
1552
  }
@@ -905,10 +905,19 @@ export function evaluateOwnedSliceProven(task, agentResult, proofBundles = []) {
905
905
  }
906
906
 
907
907
  if (task.taskType === "documentation") {
908
- const validation = validateDocumentationClosureSummary(agent, agentResult);
909
- return validation.ok
910
- ? { proven: true, reason: "Documentation closure satisfied" }
911
- : { proven: false, reason: validation.detail || validation.statusCode };
908
+ const validation = validateDocumentationClosureSummary(agent, agentResult, {
909
+ allowFallbackOnEmptyRun: true,
910
+ });
911
+ if (validation.ok) {
912
+ return { proven: true, reason: "Documentation closure satisfied" };
913
+ }
914
+ // Allow fallback-eligible empty runs to pass at the task level;
915
+ // the gate engine will make the final call on whether surrounding
916
+ // state justifies auto-closure.
917
+ if (validation.eligibleForFallback) {
918
+ return { proven: true, reason: "Documentation closure fallback (empty run, deferred to gate)" };
919
+ }
920
+ return { proven: false, reason: validation.detail || validation.statusCode };
912
921
  }
913
922
 
914
923
  if (task.taskType === "security") {
File without changes
File without changes
package/scripts/wave.mjs CHANGED
File without changes