| name | add-canon-lint |
| description | Install deterministic consistency linting into a fleet's shared canon repo — seeds tools/canon-lint/ (stdlib-only Python, no LLM), lint/rules.yaml (severity config), a GitHub Actions workflow that lints every push/PR, and the "Lintable structure" section of CONVENTIONS.md defining the two-zone folder schema (facts.yaml = purely lintable claims, docs/ = prose with a linted envelope). Runs the first lint, offers migration seeding for pre-schema folders, and optionally makes the lint a required PR status check. Targets the canon repo itself, not an agent — run once per fleet; the per-agent gate ships with add-canon ≥1.4 runtime skills (/canon-publish lints before pushing, /canon-doctor verifies the linter). |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion |
| user-invocable | true |
| metadata | {"version":"1.0","created":"2026-07-29T00:00:00.000Z","author":"Ability.ai","changelog":["1.0: Initial version — deterministic canon linter (9 rules: envelope, fact-schema, key-grammar, one-home-per-key, ownership, staleness, source-resolution, reachability, layout warn) seeded into the canon repo as tools/canon-lint/canon_lint.py + lint/rules.yaml + .github/workflows/canon-lint.yml + CONVENTIONS.md two-zone schema section; strict vs migration (report-only) presets; first-run report; sanctioned migration seeding for pre-schema folders; optional required-status-check branch protection; delivery via direct push or PR"]} |
Add Canon Lint
ℹ️ First, set expectations: before anything else, print one short line with this skill's version and its most recent change — the top entry of metadata.changelog above — e.g. add-canon-lint vX.Y — recent: <summary>. Then proceed.
Make the fleet's canon repo mechanically self-consistent: a deterministic linter — plain Python, zero dependencies, zero LLM — that runs on every push and enforces the two-zone folder schema (facts.yaml structured claims + enveloped prose in docs/), catches cross-folder fact conflicts, stale canon, ownership violations, and unreachable docs before they become drift disputes.
Division of labor (the design): the linter on every push = internal consistency — grammar, ownership, one-home-per-key, staleness bounds. Each agent's scheduled /canon-reconcile = external truth — does the fact still match reality? The linter deliberately never judges content; reconcile deliberately never re-derives what the linter already proved.
Where the gates sit (own-folder writes are direct pushes, so CI alone cannot block them):
| Gate | When | Blocks? |
|---|
/canon-publish local lint (add-canon ≥1.4 runtime skills) | before every push | yes — the real gate for agent writes |
.github/workflows/canon-lint.yml | every push + PR | red X; backstop for human edits and drift |
| Required status check (optional, Step 6) | PRs to protected branches | yes — for protocols/ + cross-folder PRs |
This skill targets the canon repo, not an agent — run it once per fleet, from the orchestrator, any enrolled agent, or inside the canon repo itself. /add-canon installs the layer; this installs its law.
Process
Step 1: Preflight — locate the canon repo
Resolve the target, first match wins:
- Run from an enrolled agent —
template.yaml has x-canon: → target is the clone at clone_path (default canon/); if the clone is missing, self-heal it exactly as Step 1 does (auth-aware).