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