speq-plan-review · git:20260726.8209a10 · 2026-07-26 · sha256 e1d6703d314201e5
speq-plan-review git:20260726.8209a10A
Immutable. This exact content is served forever at /api/v1/blob/e1d6703d314201e5.
--- name: speq-plan-review description: Adversarial plan-review method and challenge taxonomy — premortem framing, multi-axis challenge taxonomy, severity discipline, and findings output format. Triggered by plan-reviewer. --- # Adversarial Plan Review Build the case against approval, not for it. A plan that survives review should survive because it's actually sound, not because the reviewer was polite. ## Method **Premortem first.** Before scoring anything, write: "six months from now this plan failed catastrophically — why?" Produce 2-3 concrete failure stories. Route each one into the taxonomy below; a failure story with no matching category means the taxonomy is missing a category, not that it doesn't count. **No silent pass.** For every axis below, either raise a finding or write one line certifying "no objection — axis checked" with the evidence checked. Never skip an axis silently — that's how a defect slides through unreviewed. **Round 2 (if applicable):** re-check every round-1 BLOCKER against the revised artifacts and the `[plan-review]` entries in `decision-log.md` first — confirm each is actually resolved, not reworded — before doing a fresh pass for new ones. **Non-goal:** do not re-litigate decisions the user already made in the clarifying interview. Challenge how the plan *operationalizes* those decisions, not the decisions themselves. If the user said "use approach X" and the plan uses approach X, that's settled — check whether X is executed soundly, not whether X was the right call. A deviation the brief notes as authorized by an active project hook is settled the same way — don't raise it as a finding. ## Challenge Taxonomy Tag every finding, group findings by axis in the output. ### Intent fidelity — does the plan match what the user actually asked for? - `[INTENT_DRIFT]` — the plan quietly reinterprets or substitutes a different problem than the one asked. *Quote the original request; quote the plan line that diverges.* - `[SCOPE_CREEP]` — work with no traceable user need: gold-plating, speculative flexibility, "while we're here" extras. - `[SCOPE_REDUCTION]` — part of the ask silently dropped, deferred, or reframed as out-of-scope without the user agreeing. ### Feasibility — can this actually be built as described? - `[EFFORT_MISESTIMATION]` — a task line hides more work than it states (planning fallacy); which task is secretly three tasks? - `[HIDDEN_DEPENDENCY]` — an unmodeled prerequisite, external system, or ordering constraint the plan doesn't surface. - `[UNSTATED_ASSUMPTION]` — a load-bearing belief the plan never states or validates; what happens if it's false? - `[NFR_IGNORED]` — security, performance, migration/rollback, or concurrency left untouched where the change plainly touches them. ### Requirement quality — are the spec deltas complete and unambiguous? - `[AMBIGUOUS_REQUIREMENT]` — not testable as written; you can't write a concrete pass/fail test from it right now. - `[COMPLETENESS_GAP]` — missing edge case, error path, empty/boundary input for a described behavior. - `[REQUIREMENT_CONFLICT]` — contradicts another delta in this plan, or an existing recorded spec (check via `/speq-cli`). ### Task breakdown — is the WBS correct and appropriately scoped? - `[TRACEABILITY_GAP]` — a spec delta with no implementing task, or a task that implements nothing in scope. - `[TASK_GRANULARITY]` — a task too large to verify as one unit, or a parallelization claim two "independent" tasks actually violate. ### Design Depth — does the plan manage complexity well? (per `/speq-design-philosophy`) - `[SHALLOW_DESIGN]` — a planned module/interface is shallow relative to the complexity it should hide. - `[INFORMATION_LEAKAGE]` — a design decision (format, protocol, temporal split) reflected across multiple planned modules. - `[TACTICAL_SHORTCUT]` — the plan takes a tactical shortcut with no scheduled strategic follow-up. - `[BOUNDARY_VIOLATION]` — planned business logic depends directly on a delivery mechanism, storage engine, or framework. ### Prose quality — does the writing meet `/speq-writing-guardrails`? - `[PROSE_BLOAT]` — prose not required to make the point: filler, repetition, unneeded hedging or preamble. Violates BLUF/terseness. - `[PROSE_UNCLEAR]` — a sentence that's ambiguous, jargon-laden, or not understandable on one read. Prose findings default to **ADVISORY** — they're style, not correctness. Escalate a `[PROSE_UNCLEAR]` to **BLOCKER** only when the unclear prose makes a requirement non-actionable; tag that finding `[AMBIGUOUS_REQUIREMENT]` too, since it's the same defect from two angles. ## Severity - **BLOCKER** — violates user intent, or the plan is infeasible/untestable as written. Gates the plan; the orchestrator loops it back to `planner-agent`. - **ADVISORY** — a real risk, tolerable if the human acknowledges it. Never blocks; surfaced in the orchestrator's final report only. ## Output Format Write the findings document to `specs/_plans/<plan-name>/review/round-<N>.md` per `references/review-findings-template.md`, creating the `review/` directory if absent. Then return exactly one line and nothing else: ``` PLAN REVIEW round <N>: BLOCKERS: <n>, ADVISORY: <n>, INTENT: <n> — specs/_plans/<plan-name>/review/round-<N>.md ``` `INTENT` counts the Intent Fidelity BLOCKERs alone — a subset of `BLOCKERS`, matching the document's Summary block per the template's rules. Never return the findings themselves as response text. `planner-agent` reads them from the file. Every finding needs a location and a concrete `Fix:` imperative — vague objections aren't actionable for the revision loop. On round 2, confirm-or-refute each round-1 BLOCKER by name before raising anything new.