canon-kit
Spec discipline for agent-authored components: one canonical spec per component, deltas as short-lived amendment files, and a star topology across the prose surfaces — every fact has exactly one owning surface, and every other surface cites it rather than restating it. Gates hold the copy-shaped failure modes; the irreducibly semantic judgment stays a review tripwire, not a gate.
Why: when a coding agent authors the specs, design rationale gets re-derived under build pressure unless it is captured up front, and a parallel copy of any gated fact is an un-gateable second source that drifts silently. The remedy is a lifecycle (amendments authored up front, merged and deleted at build) plus gates over the mechanically-decidable copy failures — a doubled Definition-of-Done, a banned-heading code dump, a fenced block that verbatim-copies a source file, a glossary definition restated on another surface, a feature task with no amendment. See SPEC.md for the full contracts.
Install
Vendor the kit beside gate-sdk (required); the queue-facing gate reads the tag syntax queue-kit defines.
-
Register the gates — add to your
gates.list, each where its surface exists:check-amendment-queue # needs a task queue check-amendment-update-target # every update target cites a delta the amendment defines check-spec-dod-singleton # needs canonical specs check-spec-derivable-section # needs canonical specs check-spec-embedded-source # needs canonical specs + tracked source check-surface-duplication # needs a glossary (exits 2 without one) check-comment-tier # classifies comments on shell/config sources check-spec-pointer # resolves spec:/contract: pointer targets check-todo-task-liveness # resolves TODO(task:) slugs against the queue check-docs-cmd # invoked paths + kit knobs in docs resolve check-knob-citation # knob values stated only in the owning SPEC check-knob-default-coupling # source knob defaults agree with the owning SPEC check-manifest-count # no bare cardinal over a governed collection check-measured-claim # needs a measured-claim oracle (marked claims re-measured) check-unmarked-claim # needs a claim-class roster (a declared class carries a marker) check-manifest-temporal # no temporal narration in manifest prose check-tracking-claim # a path's tracking status in prose agrees with git check-prose-enum # partial enumeration of a governed set check-md-refs # internal markdown links resolve check-install-claim # one declared primary install transport, led with everywhere check-payload-claim # one declared payload-disclosure class, asserted nowhere else check-spec-fence-balance # even fence counts, parsers never desync check-docs-link-convention # needs a docs site (cite-downward links) check-prose-tells # needs prose surfaces (mechanical AI-prose tells) check-deprecation-task # needs a deprecation-marker vocabularyThey resolve through gate-sdk’s registry path (your gates dir first, then each kit’s
checks/), and their# graph:manifests put the precommit-tier ones in the generated hook:bash gate-sdk/bin/gen-pre-commit.sh --write. -
Adopt the amendment lifecycle — copy
templates/SPEC-amendment.mdwhen a designed-but-unimplemented change needs a home. Name it after the feature (SPEC-<feature>.md), place it in the owning component’s directory (a governance ruling with no component lives at the repo root), and pair it with a queue entry tagged[spec: SPEC-<feature>.md]. Merge it into the canonical spec and delete it when the work completes. -
Optional — reshape the config: copy
templates/canon-config.shinto your gates dir and override the spec/amendment names, section set, the Definition-of-Done mode (exactly-one/at-most-one), the banned-heading set and density budget, the embedded-source language map, or the glossary surface list. Defaults are this repo’s layout.
Use
The lifecycle is prose discipline the gates enforce; there is no runtime tool. Author a spec so it (1) owns semantics, (2) names every contract and couples it to code by a gate, and (3) never copies a structural definition — reference the code instead. Author amendments up front; merge and delete them at build.
Test
bash gate-sdk/bin/run-gate-tests.sh canon-kit/gate-tests canon-kit/checks