Skip to content

vt-c-spec-check

Spec-clarity birth gate. Runs three layers over a spec.md — deterministic ambiguity/terminology findings plus an LLM planner-readiness assessment (misdirection risk + wrong-turns + anchor-gaps, all quote-anchored) — and prints one soft report. Never blocks. Use at spec birth (auto-hooked into /vt-c-spec-from-requirements) or standalone on any spec.md, including hand-written specs that skip the workflow.

Plugin: core-standards
Category: Other
Command: /vt-c-spec-check


/vt-c-spec-check — Spec-Clarity Birth Gate

A soft clarity gate for a spec.md. It answers one question: could a downstream planning agent take a wrong turn on this spec? It warns, grades, and explains — it never blocks and always exits 0. Runs at spec birth or standalone on any spec.

When to Use

  • Automatically, at the end of /vt-c-spec-from-requirements, right after a spec is written (auto-hook — US-1).
  • Standalone, on any spec.md — including hand-written specs that never entered the workflow (US-2). This is the way to check a spec that skipped /vt-c-2-plan.

Prerequisites

  • python3 for the deterministic layers (Layers 1+2).
  • The shared gray-area-heuristic.py (reused unchanged). PyYAML is optional — if it is missing the heuristic degrades gracefully (EC-3) and the other layers still run.

Execution

Step 1 — Resolve the target spec

Determine which spec.md to check, in this order:

  1. Path argument given → use it (/vt-c-spec-check specs/155-.../spec.md).
  2. No path → derive the active spec: parse the current git branch (feature/spec-NNN-*SPEC-NNN), or read .active-spec, then resolve the spec's dir from .design-state.yaml and use <dir>/spec.md.
  3. Neither a path nor an active spec (EC-4) → print exactly: kein Spec gefunden — Pfad angeben oder /vt-c-activate ausführen. and stop (still exit 0 — soft).

Step 2 — Layers 1 + 2 (deterministic)

Run the scan wrapper and show its findings:

python3 plugins/core-standards/skills/spec-check/scripts/spec-clarity-scan.py <path/to/spec.md>

It emits JSON with: - Layer 1 — structural/lexical findings from gray-area-heuristic.py (missing sections, TBD/fork/hedge/vague), with wrapper-owned suppression of Given/When/Then user_story_no_ac false-negatives and meta-TBD references. - Layer 2terminology findings: underspecified nouns from the watchlist (assets/ambiguity-watchlist.txt) not defined in a ## Begriffe block. Code fences and blockquotes are exempt (EC-2); a ## Begriffe definition suppresses the term everywhere (EC-5).

If recommend_begriffe is non-empty, recommend the author add a ## Begriffe block defining those terms, and name them (FR-9).

Step 3 — Layer 3: Planner-Readiness (LLM assessment — the core)

Read the full spec and assess whether a downstream planning agent could be misled. Produce a quote-anchored assessment — never a blanket judgment.

Emit three things:

  1. Misdirection risk — one of LOW / MEDIUM / HIGH.
  2. Planner-ready verdict — one of READY / READY-WITH-CAVEATS / NOT-READY.
  3. Two finding lists (either may be empty):

Wrong-turns (ambiguous meaning). Each entry names three things (FR-5): - the quote (with line) — the ambiguous place, cited verbatim; - the assumption a planner would silently have to make; - the wrong direction that assumption could send them.

Anchor-gaps (missing implementation anchors — FR-11). Each entry names: - the quote (with line) where the spec operates at implementation level; - what anchor is missing — target repo/module, class/component, named data fields/entities, or a precondition; - why the spec's own detail level requires it, and where its absence would misdirect the planner.

Rules — non-negotiable: - Quote-anchored: every wrong-turn and anchor-gap MUST cite the triggering spec line. No citation → do not emit it — this prevents hallucinated criticism (NFR). - Proportional: raise an anchor-gap ONLY where the spec's own detail level implies concrete implementation. A deliberately abstract, concept-level spec is NOT forced to name a class or repo — flagging it would be a false alarm (proportionality-gated-guidance-mapping; FR-11). When in doubt at concept level, do not flag.

Calibration: the verdict scale is calibrated against the labeled corpus at tests/fixtures/spec-155/calibration/ (HARD gate, adjacent-level tolerance). Keep the rubric wording in this file in sync with that corpus.

Step 4 — Print the soft report

Spec-Clarity Report: <spec path>
────────────────────────────────────────────────
Layer 1+2 (deterministic): <N> finding(s)
  - <type> [line X]: <detail>
  ...
  Recommend a ## Begriffe block for: <terms>   (if any)

Layer 3 (planner-readiness):
  Misdirection risk: <LOW|MEDIUM|HIGH>
  Verdict:           <READY|READY-WITH-CAVEATS|NOT-READY>

  Wrong-turns:
    1. "<quote>" [line X]
       Assumption: <...>
       Wrong direction: <...>
  Anchor-gaps:
    1. "<quote>" [line X]
       Missing: <repo/class/field/precondition>
       Why needed here: <...>
       Would misdirect: <...>
────────────────────────────────────────────────
Soft gate — nothing is blocked. The author decides.

A precise, sufficiently anchored spec yields LOW / READY with empty lists.

Edge Cases

ID Case Behavior
EC-1 Non-toolkit / free-format spec (e.g. VisiTerminal # Spec E0x) Layers 1+2 report missing required sections; Layer 3 still assesses content. No block.
EC-2 Watchlist word inside a code fence or blockquote No Layer-2 finding.
EC-3 PyYAML missing Heuristic degrades (one sub-check off); other layers run.
EC-4 Standalone call, no path and no active spec Print the "kein Spec gefunden" message; exit 0.
EC-5 Term defined in ## Begriffe, used elsewhere too Not reported — the definition covers the whole spec.
EC-6 Layer 3 (LLM) unavailable or fails Print Layers 1+2 anyway; mark planner-readiness „nicht bewertet" (not assessed).

Error Handling

  • The gate is soft: it prints findings and a verdict and never blocks; the scan script always exits 0. Never fail the caller — a birth-time linter that breaks the write flow would train authors to bypass it.
  • Fork-safety: this skill is report-only. NEVER use AskUserQuestion or any interactive prompt — under context: fork the question is swallowed and the sub-agent dies silently, so an interactive gate would hang the caller.

Integration Points

  • /vt-c-spec-from-requirements auto-invokes this skill before its Completion Summary (US-1), showing the report inline without blocking.
  • gray-area-heuristic.py (workflow-2-plan/scripts/) is reused unchanged as Layer 1 — suppression lives in this skill's wrapper, never in the shared script.
  • Relationship to deeper agents: Layer 3 is canonical only for the narrow, fast, fork-safe question "would a planner be misled at spec birth?". It does NOT replace spec-flow-analyzer (exhaustive flow/permutation analysis) or strategic-mentor (strategic viability during planning); it does not dispatch them.

Anti-patterns

  • Do NOT block, fail, or refuse "ready" — the gate is deliberately soft; hard-blocking belongs to no gate here (Out of Scope).
  • Do NOT emit a wrong-turn or anchor-gap without a cited quote — unanchored criticism is hallucination and erodes trust in the verdict.
  • Do NOT flag anchor-gaps on deliberately abstract specs — that is a false alarm and punishes correct high-altitude specs.
  • Do NOT edit gray-area-heuristic.py to fix Layer-1 noise — it is shared with the plan gate; suppress in the wrapper instead (regression risk).

Success Criteria

  • Prints deterministic findings + a planner-readiness verdict; always exit 0 (SC-1).
  • "Upload" without a ## Begriffe entry → one Layer-2 finding; adding the entry removes it (SC-2).
  • A deliberately ambiguous spec → HIGH / NOT-READY with ≥1 quote-anchored wrong-turn; a precise spec → LOW / READY with empty lists (SC-3).
  • Every wrong-turn and anchor-gap is quote-anchored (SC-4).
  • Runs cleanly on a hand-written non-toolkit spec, reporting missing sections (SC-6).
  • If Layer 3 fails, Layers 1+2 still print; readiness marked „nicht bewertet" (SC-7).
  • A "write to the invoice table" spec with no repo/entity/field named → an anchor-gap; an abstract concept-level spec is NOT flagged for it (SC-8).