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¶
python3for 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:
- Path argument given → use it (
/vt-c-spec-check specs/155-.../spec.md). - No path → derive the active spec: parse the current git branch
(
feature/spec-NNN-*→SPEC-NNN), or read.active-spec, then resolve the spec'sdirfrom.design-state.yamland use<dir>/spec.md. - 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:
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 2 — terminology 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:
- Misdirection risk — one of
LOW/MEDIUM/HIGH. - Planner-ready verdict — one of
READY/READY-WITH-CAVEATS/NOT-READY. - 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
AskUserQuestionor any interactive prompt — undercontext: forkthe question is swallowed and the sub-agent dies silently, so an interactive gate would hang the caller.
Integration Points¶
/vt-c-spec-from-requirementsauto-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) orstrategic-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.pyto 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
## Begriffeentry → 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).