Rule catalog
Every check Specline can emit, in one place — 33 rules. The engine andspecline rules read from the same registry, so a finding can never carry arule_id the catalog lacks — and the catalog can never drift from what actually fires.
Severity is the line. error meansintegrity — a fact that's broken regardless of any opinion about good specs; it fails the gate. warning means advisory — a judgment about whether a spec is good (completeness, sizing, mechanics, build-readiness); it's surfaced for the decider and never blocks. Specline runs inone mode: it reports every finding and exits nonzero when any of them is an error. Scope — repo findings consider the whole tree;spec integrity errors quarantine to --changed. Parts 1 and 2 always run. Part 3 runs, and is listed by specline rules, only when specline.yml sets unattended: true.
Part 1 — the spec (9)
| rule_id | severity | scope | fires when |
|---|---|---|---|
STRUCT-MISSING-SPEC | error | spec | a specs/ folder has no spec.md — the constitutive file; the folder is not a spec without it. |
FRONTMATTER-UNPARSEABLE | error | spec | spec.md frontmatter is missing or doesn't parse. |
FRONTMATTER-SLUG-MISMATCH | error | spec | frontmatter slug doesn't match the directory. |
ENUM-INVALID | error | spec | a known enum (type, status, or — when unattended — build/blast_radius/size/target_model) has an invalid value. |
UNKNOWN-FRONTMATTER-KEY | warning | spec | an unrecognized frontmatter key — preserved, not failed (likely a newer canon). |
UNKNOWN-SECTION | warning | spec | an unrecognized body section — preserved, not failed. |
GOAL-MISSING | warning | spec | a spec has no `## Goal` — one falsifiable line, the highest hydration value per character in the format. |
PARENT-HAS-MECHANICS | warning | spec | a type: parent carries Behavior or Acceptance — a parent is a map, not a plan. |
PARENT-NO-SCOPES | warning | spec | a type: parent lists no child scopes (nothing declares part_of: it) — a misfiled scope. |
Part 2 — the record (12)
| rule_id | severity | scope | fires when |
|---|---|---|---|
SLUG-DUPLICATE | error | repo | an active spec's slug collides with knowledge/ or archive/; the graduated knowledge + archive pair is legal. |
RELATION-DANGLING | error | repo | a relations.md edge points to a slug that exists nowhere in specs/, knowledge/, or archive/. |
RELATION-UNPARSEABLE | error | repo | relations.md in a spec or knowledge folder has invalid YAML or field shapes. |
LINK-DANGLING | error | repo | a relative link under docs/ doesn't resolve. |
KNOWLEDGE-HAS-STATUS | error | repo | knowledge/ contains a lifecycle artifact (status.md, open-questions.md). |
ARCHIVE-EDITED | error | repo | an archived spec is modified (adding one is graduation, allowed) — the audit trail is immutable. |
STRUCT-MISSING-RELATIONS | warning | spec | a specs/ folder has no relations.md — an auxiliary file. |
RELATION-CROSS-REPO | warning | repo | a repo:slug edge — validated weakly, warn only. |
RELATION-KILLED | warning | repo | an edge points to a killed slug — warn only. |
OPEN-QUESTION-INCOMPLETE | warning | spec | a building spec's open question is missing a decider or default. |
OPEN-QUESTION-OVERDUE | warning | spec | an active spec has an open question past its deadline. |
CANON-PIN-MISMATCH | warning | repo | the repo's pinned canon (specline.yml, compared at MAJOR.MINOR) differs from the tool's served canon. |
Part 3 — unattended builds (12)
Experimental — in force only when specline.yml setsunattended: true. Off by default; nothing here is checked or listed until you turn it on.
| rule_id | severity | scope | fires when |
|---|---|---|---|
UNATTENDED-INCOMPLETE | warning | spec | build: unattended lacks blast_radius, loop_budget, status.md, or (once active) stale_after. |
STATUS-SCHEMA | warning | spec | status.md is missing or duplicates a required section. |
CORRECTIONS-MALFORMED | warning | spec | a status.md ## Corrections entry doesn't carry the `<what> — <altitude> — <who caught it>` shape. |
LOOP-BUDGET-INVALID | warning | spec | loop_budget is present but not a positive integer (the autonomy grant). |
JUDGEABLE-NO-SECTION | warning | spec | a judgeable acceptance item names no spec section to judge against — not falsifiable. |
CHECK-RUN-MALFORMED | warning | spec | an acceptance item carries `— run:` but not a single backtick-fenced command. Absence of the suffix never fires. |
SCOPE-EXCEEDS-SIZE | warning | spec | size: small but measured size is over suggest_slicing_past — slice it, or declare size: large. |
ACCEPTANCE-UNPARTITIONED | warning | spec | an unattended spec has no `### agent-loopable` acceptance partition — the build loop has no labelled exit condition. |
ARCHIVE-NO-ACCEPTANCE | warning | repo | a shipped, archived spec carries no linked acceptance_results — graduation may have skipped its run. |
STALE-QUARANTINE | warning | spec | a building/blocked spec is past stale_after — flagged for a human. |
DECIDER-OVER-BUDGET | warning | repo | a decider is over the focus_limit for building or active specs. |
COUPLING-CEILING | warning | spec | spec + transitively forced loads exceeds coupling_ceiling% of context_window — too entangled. |
This table mirrors specline rules --format json — that command, not this page, is the authoritative machine-readable catalog. With unattended off, Part 3 is neither listed nor checked. A few canon checks that need git history (specline diff) or aren't built yet (relations-index --fix) are marked planned in the canon.