From 272638aec1aeee63700234dae5fd66ee46696e00 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Mon, 4 May 2026 07:43:50 +0200 Subject: [PATCH] feat(ultraplan-local): parallelize Phase 9 review with inline dedup Strengthen single-message reinforcement for plan-critic + scope-guardian parallel dispatch in commands/ultraplan-local.md Phase 9 and mirror in agents/planning-orchestrator.md Phase 6. Reviewers now write structured JSON to /tmp/{plan-critic,scope-guardian}-out.json which is merged via the lib/review/plan-review-dedup.mjs CLI shim from S8. The merged set lets us revise the plan once for duplicate findings instead of twice. Source: research/05 R1 + R2. Pin in tests/lib/doc-consistency.test.mjs locks both files against single-message + dedup-helper regressions. --- .../agents/planning-orchestrator.md | 12 ++++++++- .../commands/ultraplan-local.md | 26 ++++++++++++++++--- .../tests/lib/doc-consistency.test.mjs | 23 ++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/plugins/ultraplan-local/agents/planning-orchestrator.md b/plugins/ultraplan-local/agents/planning-orchestrator.md index 2e88029..6473ac0 100644 --- a/plugins/ultraplan-local/agents/planning-orchestrator.md +++ b/plugins/ultraplan-local/agents/planning-orchestrator.md @@ -401,16 +401,26 @@ Create parent directories if needed. ### Phase 6 — Adversarial review -Launch two review agents **in parallel**: +Launch two review agents **in parallel — emit both Agent tool calls in a +single assistant message turn** (same pattern as Phase 5 exploration). They +have zero data dependencies; serializing them wastes 30–60 seconds per run. - `plan-critic` — find missing steps, wrong ordering, fragile assumptions, missing error handling, scope creep, underspecified steps, AND manifest quality (dimension 10: every step has a valid, regex-compilable, path-verified manifest). Missing or invalid manifest = **major** finding. + Write structured JSON to `/tmp/plan-critic-out.json`. - `scope-guardian` — verify plan matches the brief's requirements, find scope creep (plan does more than the brief specifies) and scope gaps (plan misses brief requirements), validate file/function references. Confirm every Success Criterion in the brief is covered by the plan's Verification section. + Write structured JSON to `/tmp/scope-guardian-out.json`. + +After both complete, run an inline dedup pass via +`node ${CLAUDE_PLUGIN_ROOT}/lib/review/plan-review-dedup.mjs --plan-critic /tmp/plan-critic-out.json --scope-guardian /tmp/scope-guardian-out.json > /tmp/plan-review-merged.json`. +The merged array attributes each finding to `[plan-critic, scope-guardian]` +if both reviewers raised it. Revise the plan once for the merged set, not +twice for the duplicates. Source: research/05 R1 + R2. After both complete: - Address all blockers and major issues by revising the plan diff --git a/plugins/ultraplan-local/commands/ultraplan-local.md b/plugins/ultraplan-local/commands/ultraplan-local.md index 8cc0f56..00a77bf 100644 --- a/plugins/ultraplan-local/commands/ultraplan-local.md +++ b/plugins/ultraplan-local/commands/ultraplan-local.md @@ -675,13 +675,17 @@ Create the parent directory if it does not exist. ## Phase 9 — Adversarial review -Launch two review agents **in parallel**: +Launch two review agents **in parallel — emit both Agent tool calls in a +single assistant message turn** (same pattern as Phase 5 exploration). They +have zero data dependencies; serializing them wastes 30–60 seconds per run. **plan-critic** — adversarial review of the plan. Prompt: "Review this implementation plan for the task: {task}. Plan file: {plan path}. Read it and find every problem — missing steps, wrong ordering, fragile assumptions, missing error handling, scope creep, -underspecified steps. Rate each finding as blocker, major, or minor." +underspecified steps. Rate each finding as blocker, major, or minor. +Write the structured JSON output to `/tmp/plan-critic-out.json` so the +dedup helper can merge with scope-guardian's findings." **scope-guardian** — scope alignment check. Prompt: "Check this implementation plan against the brief. @@ -689,7 +693,23 @@ Task: {task}. Brief file: {brief_path}. Plan file: {plan path}. Find scope creep (plan does more than the brief requires) and scope gaps (plan misses brief requirements). Check that referenced files and functions exist. Verify that every Success Criterion in the brief is covered by the -plan's Verification section." +plan's Verification section. Write structured JSON output to +`/tmp/scope-guardian-out.json`." + +After both complete, run an inline dedup pass: + +```bash +node ${CLAUDE_PLUGIN_ROOT}/lib/review/plan-review-dedup.mjs \ + --plan-critic /tmp/plan-critic-out.json \ + --scope-guardian /tmp/scope-guardian-out.json \ + > /tmp/plan-review-merged.json +``` + +The merged array attributes each finding to `[plan-critic, scope-guardian]` +when both reviewers raised the same issue (exact match on +`file:line:rule_key`, or Jaccard ≥ 0.7 on text tokens). Revise the plan +once for the merged set, not twice for the duplicates. Source: research/05 +R1 + R2. After both complete: - If **blockers** are found: revise the plan to address them. Add a "Revisions" diff --git a/plugins/ultraplan-local/tests/lib/doc-consistency.test.mjs b/plugins/ultraplan-local/tests/lib/doc-consistency.test.mjs index c976b7b..bf8d56f 100644 --- a/plugins/ultraplan-local/tests/lib/doc-consistency.test.mjs +++ b/plugins/ultraplan-local/tests/lib/doc-consistency.test.mjs @@ -158,6 +158,29 @@ test('rule-catalogue has exactly 12 entries', async () => { ); }); +test('Phase 9 prose mandates parallel single-message dispatch + inline dedup', () => { + const cmd = read('commands/ultraplan-local.md'); + const orch = read('agents/planning-orchestrator.md'); + // Single-message reinforcement appears in both (command + orchestrator) + assert.ok( + cmd.includes('single assistant message turn'), + 'commands/ultraplan-local.md Phase 9 should reinforce single-message parallel dispatch', + ); + assert.ok( + orch.includes('single assistant message turn'), + 'agents/planning-orchestrator.md Phase 6 should mirror the single-message parallel-dispatch contract', + ); + // Dedup CLI shim is wired in both + assert.ok( + cmd.includes('plan-review-dedup.mjs'), + 'commands/ultraplan-local.md Phase 9 should call lib/review/plan-review-dedup.mjs after both reviewers complete', + ); + assert.ok( + orch.includes('plan-review-dedup.mjs'), + 'agents/planning-orchestrator.md Phase 6 should reference the dedup helper', + ); +}); + test('commands/ultraplan-local.md Phase 8 seals Opus-4.7 schema-drift defense', () => { const cmd = read('commands/ultraplan-local.md'); // Locate Phase 8 section