@chllming/wave-orchestration 0.9.10 → 0.9.11
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 +10 -0
- package/docs/guides/recommendations-0.9.11.md +44 -0
- package/package.json +9 -8
- package/scripts/context7-api-check.sh +0 -0
- package/scripts/context7-export-env.sh +0 -0
- package/scripts/wave-autonomous.mjs +0 -0
- package/scripts/wave-dashboard.mjs +0 -0
- package/scripts/wave-human-feedback.mjs +0 -0
- package/scripts/wave-launcher.mjs +0 -0
- package/scripts/wave-local-executor.mjs +0 -0
- package/scripts/wave-orchestrator/agent-state.mjs +3 -1
- package/scripts/wave-orchestrator/derived-state-engine.mjs +7 -2
- package/scripts/wave-orchestrator/shared.mjs +9 -9
- package/scripts/wave-status.sh +0 -0
- package/scripts/wave-watch.sh +0 -0
- package/scripts/wave.mjs +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.11 - 2026-04-07
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Verdict parsing: first-match-wins** — `parseVerdictFromText()` now returns the **first** regex match instead of the last. In append-only cont-QA report files, stale `Verdict: BLOCKED` entries from earlier attempts would linger at the bottom of the file while newer `Verdict: PASS` entries were written above them. The last-match-wins behavior caused the cont-QA gate to read the stale blocked verdict, creating an infinite retry loop. This was the root cause of 17 blocked waves in React Word Editor (DOCX W20+).
|
|
7
|
+
- **Log verdict priority over report verdict** — `buildAgentExecutionSummary()` now prefers the log-based `[wave-verdict]` marker over the report file `Verdict:` line. The log is authoritative for the current run, while report files may accumulate conflicting entries across retry attempts.
|
|
8
|
+
- **Integration steward closure is now sticky** — When the integration steward (A8) explicitly reports `state=ready-for-doc-closure` with zero blockers, synthesized proof gaps and doc gaps from implementation agent validation are cleared from the integration summary. Previously, `buildWaveIntegrationSummary()` would re-inject gaps derived from agent summaries on every `refreshDerivedState()` call, overriding the steward's explicit sign-off and causing unnecessary retry cycles (observed as 15+ loops in DOCX W20).
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Test suite for `parseVerdictFromText` covering first-match behavior, null/empty inputs, multi-verdict report files, and `[wave-verdict]` marker parsing.
|
|
12
|
+
|
|
3
13
|
## 0.9.10 - 2026-04-07
|
|
4
14
|
|
|
5
15
|
### Fixed
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Recommendations for 0.9.11
|
|
2
|
+
|
|
3
|
+
## Upgrade
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
wave self-update
|
|
7
|
+
# or: npm install -g @chllming/wave-orchestration@0.9.11
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## What changed
|
|
11
|
+
|
|
12
|
+
### Verdict parsing (P0 fix)
|
|
13
|
+
|
|
14
|
+
The `parseVerdictFromText()` function now returns the **first** regex match instead of the last. This fixes a critical bug where append-only cont-QA report files accumulated `Verdict:` lines across retries, and the stale `Verdict: BLOCKED` at the bottom would override newer `Verdict: PASS` entries above it.
|
|
15
|
+
|
|
16
|
+
**If you have waves stuck in cont-QA retry loops**, upgrading to 0.9.11 should unblock them on the next attempt. No manual intervention needed — the runner will re-evaluate the gate with the fixed parser.
|
|
17
|
+
|
|
18
|
+
**For ongoing work**: the log-based `[wave-verdict]` marker is now preferred over the report file `Verdict:` line. Both still work, but if both are present, the log marker wins. This is more reliable because the log is per-run while report files persist across attempts.
|
|
19
|
+
|
|
20
|
+
### Log verdict priority
|
|
21
|
+
|
|
22
|
+
`buildAgentExecutionSummary()` now reads verdicts in this order:
|
|
23
|
+
1. `[wave-verdict]` from the agent's log (authoritative per-run)
|
|
24
|
+
2. `Verdict:` from the cont-QA report file (fallback)
|
|
25
|
+
|
|
26
|
+
Previously the report file took priority. If your cont-QA role prompt instructs the agent to write `Verdict: PASS/BLOCKED` in the report, that still works — it just won't override a contradicting `[wave-verdict]` marker in the same run's log.
|
|
27
|
+
|
|
28
|
+
### Integration steward sticky closure
|
|
29
|
+
|
|
30
|
+
When A8 (integration steward) explicitly reports `state=ready-for-doc-closure` with zero blockers, the orchestrator no longer re-injects synthesized proof/doc gaps on the next `refreshDerivedState()` cycle. This prevents the pattern where:
|
|
31
|
+
|
|
32
|
+
1. A8 closes all gaps → integration summary says "ready-for-doc-closure"
|
|
33
|
+
2. Launcher calls `refreshDerivedState()` on next attempt
|
|
34
|
+
3. `buildIntegrationEvidence()` re-derives gaps from agent summaries
|
|
35
|
+
4. Integration summary regresses to "needs-more-work"
|
|
36
|
+
5. Retry → goto 1
|
|
37
|
+
|
|
38
|
+
**No action required** — the fix is automatic. If your waves were stuck in integration retry loops, they should resolve on the next attempt.
|
|
39
|
+
|
|
40
|
+
## Recommendations
|
|
41
|
+
|
|
42
|
+
- **Stuck cont-QA waves**: Just upgrade and let the runner retry. The fixed verdict parser will read the correct verdict.
|
|
43
|
+
- **Stuck integration loops**: Same — upgrade and let the runner retry.
|
|
44
|
+
- **Report file hygiene**: Consider having your cont-QA role prompt write verdicts with a clear section header (e.g., `## Final Verdict`) to make the file structure unambiguous. The first-match-wins behavior rewards putting the definitive verdict early in the file.
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chllming/wave-orchestration",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.11",
|
|
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
|
|
@@ -509,7 +509,9 @@ export function buildAgentExecutionSummary({ agent, statusRecord, logPath, repor
|
|
|
509
509
|
: "";
|
|
510
510
|
const reportVerdict = parseVerdictFromText(reportText, REPORT_VERDICT_REGEX);
|
|
511
511
|
const logVerdict = parseVerdictFromText(signalText, WAVE_VERDICT_REGEX);
|
|
512
|
-
|
|
512
|
+
// Prefer log verdict (authoritative for the current run) over report verdict
|
|
513
|
+
// (may accumulate stale entries across retries in append-only report files).
|
|
514
|
+
const verdict = logVerdict.verdict ? logVerdict : reportVerdict;
|
|
513
515
|
const termination = detectTermination(agent, logText, statusRecord);
|
|
514
516
|
return {
|
|
515
517
|
agentId: agent?.agentId || null,
|
|
@@ -573,6 +573,11 @@ export function buildWaveIntegrationSummary({
|
|
|
573
573
|
securitySummary,
|
|
574
574
|
});
|
|
575
575
|
if (explicitIntegration) {
|
|
576
|
+
// When the integration steward explicitly asserts ready-for-doc-closure,
|
|
577
|
+
// clear synthesized proof/doc gaps — the steward has signed off on them.
|
|
578
|
+
const stewardClearedGaps =
|
|
579
|
+
explicitIntegration.state === "ready-for-doc-closure" &&
|
|
580
|
+
(explicitIntegration.blockers || 0) === 0;
|
|
576
581
|
return {
|
|
577
582
|
wave: wave.wave,
|
|
578
583
|
lane: lanePaths.lane,
|
|
@@ -595,8 +600,8 @@ export function buildWaveIntegrationSummary({
|
|
|
595
600
|
),
|
|
596
601
|
changedInterfaces: evidence.changedInterfaces,
|
|
597
602
|
crossComponentImpacts: evidence.crossComponentImpacts,
|
|
598
|
-
proofGaps: evidence.proofGaps,
|
|
599
|
-
docGaps: evidence.docGaps,
|
|
603
|
+
proofGaps: stewardClearedGaps ? [] : evidence.proofGaps,
|
|
604
|
+
docGaps: stewardClearedGaps ? [] : evidence.docGaps,
|
|
600
605
|
deployRisks: evidence.deployRisks,
|
|
601
606
|
securityState: evidence.securityState,
|
|
602
607
|
securityFindings: evidence.securityFindings,
|
|
@@ -443,16 +443,16 @@ export function parseVerdictFromText(text, regex) {
|
|
|
443
443
|
}
|
|
444
444
|
regex.lastIndex = 0;
|
|
445
445
|
let match = regex.exec(text);
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
while (match !== null) {
|
|
449
|
-
verdict = normalizeWaveVerdict(match[1]);
|
|
450
|
-
detail = String(match[2] || "")
|
|
451
|
-
.trim()
|
|
452
|
-
.replace(/^detail=/i, "")
|
|
453
|
-
.trim();
|
|
454
|
-
match = regex.exec(text);
|
|
446
|
+
if (!match) {
|
|
447
|
+
return { verdict: null, detail: "" };
|
|
455
448
|
}
|
|
449
|
+
// Use the first match — in append-only reports the latest verdict is written
|
|
450
|
+
// at the top of the newest section, while stale entries linger at the bottom.
|
|
451
|
+
const verdict = normalizeWaveVerdict(match[1]);
|
|
452
|
+
const detail = String(match[2] || "")
|
|
453
|
+
.trim()
|
|
454
|
+
.replace(/^detail=/i, "")
|
|
455
|
+
.trim();
|
|
456
456
|
return { verdict, detail };
|
|
457
457
|
}
|
|
458
458
|
|
package/scripts/wave-status.sh
CHANGED
|
File without changes
|
package/scripts/wave-watch.sh
CHANGED
|
File without changes
|
package/scripts/wave.mjs
CHANGED
|
File without changes
|