@erclx/canon 5.38.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/SKILL.md +12 -9
- package/claude/skills/auto-ship/SKILL.md +43 -23
- package/claude/skills/backlog-triage/SKILL.md +62 -53
- package/claude/skills/backlog-triage/references/apply.md +69 -0
- package/claude/skills/build-in-slices/SKILL.md +8 -4
- package/claude/skills/canon-cli/SKILL.md +5 -1
- package/claude/skills/canon-feedback/SKILL.md +18 -8
- package/claude/skills/canon-feedback-triage/SKILL.md +10 -3
- package/claude/skills/canvas-board/SKILL.md +37 -18
- package/claude/skills/ci-workflow/SKILL.md +5 -4
- package/claude/skills/code-craft/SKILL.md +10 -6
- package/claude/skills/codebase-layout/SKILL.md +3 -5
- package/claude/skills/context-fold/REQUIREMENT.md +4 -4
- package/claude/skills/context-fold/SKILL.md +42 -23
- package/claude/skills/context-fold/references/context-refresh.md +4 -3
- package/claude/skills/context-fold/references/context.md +79 -64
- package/claude/skills/create-rule/SKILL.md +7 -3
- package/claude/skills/create-skill/SKILL.md +27 -7
- package/claude/skills/create-skill/references/skill-reference.md +41 -17
- package/claude/skills/decision-escalate/SKILL.md +8 -5
- package/claude/skills/deploy-app/SKILL.md +1 -1
- package/claude/skills/deprecation-migration/SKILL.md +12 -4
- package/claude/skills/design-taste/SKILL.md +17 -11
- package/claude/skills/docs-sync/REQUIREMENT.md +1 -0
- package/claude/skills/docs-sync/SKILL.md +17 -6
- package/claude/skills/docs-sync/references/docs.md +54 -21
- package/claude/skills/docs-sync/references/readme.md +32 -8
- package/claude/skills/document-health/SKILL.md +3 -4
- package/claude/skills/draft-and-pick/SKILL.md +73 -47
- package/claude/skills/draft-doc/SKILL.md +9 -4
- package/claude/skills/draft-doc/references/context.md +4 -4
- package/claude/skills/draft-doc/references/docs.md +1 -0
- package/claude/skills/draft-doc/references/wiki.md +3 -2
- package/claude/skills/draft-figure/SKILL.md +9 -7
- package/claude/skills/draft-identity/SKILL.md +24 -52
- package/claude/skills/draft-identity/references/card-route.md +46 -0
- package/claude/skills/draft-ready/SKILL.md +19 -7
- package/claude/skills/draft-screencast/SKILL.md +6 -112
- package/claude/skills/draft-screencast/references/beats-template.md +119 -0
- package/claude/skills/draft-slides/SKILL.md +9 -7
- package/claude/skills/draft-slides/references/deck.md +183 -0
- package/claude/skills/git-branch/SKILL.md +3 -3
- package/claude/skills/git-commit/SKILL.md +5 -3
- package/claude/skills/git-followup/SKILL.md +16 -9
- package/claude/skills/git-issue/SKILL.md +6 -5
- package/claude/skills/git-pr/SKILL.md +56 -44
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-pr/references/final-command.md +1 -1
- package/claude/skills/git-pr/references/labels.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/git-ship/SKILL.md +43 -34
- package/claude/skills/git-ship/references/ci-watch.md +31 -0
- package/claude/skills/git-split/SKILL.md +28 -100
- package/claude/skills/git-split/references/independent.md +40 -0
- package/claude/skills/git-split/references/stacked.md +73 -0
- package/claude/skills/git-stage/SKILL.md +9 -7
- package/claude/skills/git-worktree/SKILL.md +27 -49
- package/claude/skills/git-worktree/references/cleanup.md +55 -0
- package/claude/skills/markdown-craft/SKILL.md +2 -2
- package/claude/skills/markdown-craft/references/markdown.md +82 -53
- package/claude/skills/plan-feature/SKILL.md +52 -46
- package/claude/skills/plan-feature/references/batches.md +46 -0
- package/claude/skills/plan-groundwork/SKILL.md +60 -74
- package/claude/skills/plan-groundwork/references/output.md +48 -0
- package/claude/skills/plan-intake/SKILL.md +28 -21
- package/claude/skills/plan-intake-answer/SKILL.md +14 -13
- package/claude/skills/read-frames/SKILL.md +2 -0
- package/claude/skills/record-screencast/SKILL.md +31 -11
- package/claude/skills/review-address/SKILL.md +76 -158
- package/claude/skills/review-address/references/rebase-only.md +34 -0
- package/claude/skills/review-craft/SKILL.md +27 -11
- package/claude/skills/review-pr/SKILL.md +91 -40
- package/claude/skills/review-ui/SKILL.md +63 -37
- package/claude/skills/review-ui/references/hosted-preview.md +30 -0
- package/claude/skills/role-orchestrator/SKILL.md +105 -74
- package/claude/skills/role-orchestrator/references/orchestrator-filing.md +26 -0
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +1 -1
- package/claude/skills/role-planner/SKILL.md +66 -64
- package/claude/skills/role-reviewer/SKILL.md +57 -46
- package/claude/skills/role-worker/SKILL.md +68 -63
- package/claude/skills/search-craft/SKILL.md +7 -5
- package/claude/skills/session-compact/SKILL.md +16 -11
- package/claude/skills/session-map/SKILL.md +31 -10
- package/claude/skills/session-relay/SKILL.md +32 -65
- package/claude/skills/session-resume/SKILL.md +18 -13
- package/claude/skills/session-worktree/SKILL.md +70 -42
- package/claude/skills/systematic-debugging/SKILL.md +6 -1
- package/claude/skills/target-check/SKILL.md +13 -6
- package/claude/skills/target-setup/SKILL.md +39 -27
- package/claude/skills/task-board/SKILL.md +68 -60
- package/claude/skills/task-board/references/board.md +1 -1
- package/claude/skills/task-board/references/create-report.md +36 -0
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/task-complete/SKILL.md +20 -18
- package/claude/skills/teach-workspace/SKILL.md +61 -33
- package/claude/skills/test-craft/SKILL.md +2 -1
- package/claude/skills/test-first/SKILL.md +15 -9
- package/claude/skills/ui-checklist/SKILL.md +18 -16
- package/claude/skills/ux-audit/SKILL.md +9 -10
- package/claude/skills/ux-measure/SKILL.md +23 -19
- package/claude/skills/video-craft/SKILL.md +15 -7
- package/claude/skills/write-human/SKILL.md +9 -1
- package/claude/skills/youtube-transcripts/SKILL.md +2 -1
- package/docs/agents/audits.md +61 -60
- package/docs/agents/context-audit.md +40 -58
- package/docs/agents/index.md +11 -61
- package/docs/agents/indexes.md +25 -29
- package/docs/agents/install-and-sync.md +125 -235
- package/docs/agents/markdown-audit.md +54 -96
- package/docs/agents/migrate.md +41 -16
- package/docs/agents/output-shape.md +60 -45
- package/docs/agents/overview.md +36 -12
- package/docs/agents/records.md +37 -79
- package/docs/agents/sessions-transfer.md +26 -70
- package/docs/agents/targets.md +25 -77
- package/docs/target/index.md +0 -1
- package/docs/target/migrations.md +57 -66
- package/docs/target/projects.md +36 -78
- package/docs/target/scenarios.md +9 -19
- package/docs/target/sync.md +27 -68
- package/docs/workflow/ai-workflow.md +22 -68
- package/docs/workflow/operating-model.md +32 -186
- package/docs/workflow/parallel-features.md +29 -66
- package/docs/workflow/skill-map-on-request.md +22 -24
- package/docs/workflow/skill-map.md +72 -76
- package/docs/workflow/visual-design-workflow.md +25 -118
- package/docs/workflow/zshrc-aliases.md +18 -37
- package/package.json +1 -1
- package/src/canvas/client/inspector/fields.css +4 -0
- package/src/canvas/index.html +6 -0
- package/src/claude/skills-reach.ts +2 -2
- package/src/cli/ui.ts +3 -1
- package/src/commands/canvas.ts +23 -0
- package/src/commands/capture.ts +14 -0
- package/src/commands/claude.ts +14 -1
- package/src/commands/context.ts +106 -7
- package/src/commands/demo.ts +22 -0
- package/src/commands/deps.ts +6 -0
- package/src/commands/driver.ts +28 -2
- package/src/commands/gov.ts +52 -18
- package/src/commands/hooks.ts +63 -0
- package/src/commands/intake.ts +17 -0
- package/src/commands/labels.ts +38 -5
- package/src/commands/markdown.ts +169 -32
- package/src/commands/pr.ts +160 -43
- package/src/commands/records.ts +8 -0
- package/src/commands/secrets.ts +6 -0
- package/src/commands/sessions.ts +8 -0
- package/src/commands/tasks.ts +52 -0
- package/src/commands/teach.ts +13 -0
- package/src/commands/upstream.ts +25 -1
- package/src/commands/worktrees.ts +5 -0
- package/src/context/audit.ts +274 -5
- package/src/context/classify/prompts.ts +1 -1
- package/src/context/folders.ts +1 -1
- package/src/context/gate.ts +23 -7
- package/src/context/shape-gated.ts +30 -0
- package/src/counts/scan.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/tokens.ts +1 -1
- package/src/gate/boundaries.ts +4 -1
- package/src/gate/measures.ts +16 -191
- package/src/gate/stages.ts +14 -30
- package/src/git/env.ts +6 -0
- package/src/hooks/reply-links.ts +110 -0
- package/src/markdown/density.ts +258 -0
- package/src/markdown/gate.ts +57 -18
- package/src/markdown/reference-shape.ts +103 -0
- package/src/markdown/scope.ts +162 -0
- package/src/markdown/structure.ts +9 -59
- package/src/pr/lift.ts +153 -19
- package/src/pr/painted.ts +87 -0
- package/src/roots/record.ts +18 -1
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/headless/run.ts +3 -2
- package/src/sandbox/headless/watch.ts +3 -4
- package/src/shipped/references.ts +1 -1
- package/src/slides/convert/master.ts +3 -0
- package/src/sync/format.ts +46 -0
- package/src/sync/stamp.ts +6 -0
- package/tooling/astro/reference.md +2 -2
- package/tooling/base/reference.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/reply-links.sh +72 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +22 -1
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- package/tooling/go/reference.md +1 -1
- package/tooling/nextjs/reference.md +1 -1
- package/tooling/php/reference.md +1 -1
- package/tooling/python/reference.md +1 -1
- package/tooling/vite-react/reference.md +1 -1
- package/tooling/web/reference.md +1 -1
- package/docs/agents/canvas.md +0 -86
- package/docs/agents/capture.md +0 -65
- package/docs/agents/census.md +0 -23
- package/docs/agents/commands.md +0 -154
- package/docs/agents/comments.md +0 -34
- package/docs/agents/context-audit-checks.md +0 -90
- package/docs/agents/context-classify.md +0 -101
- package/docs/agents/counts.md +0 -74
- package/docs/agents/demo.md +0 -140
- package/docs/agents/docs.md +0 -27
- package/docs/agents/drift-surfaces.md +0 -201
- package/docs/agents/driver.md +0 -103
- package/docs/agents/gate.md +0 -90
- package/docs/agents/gov-detect.md +0 -47
- package/docs/agents/hooks.md +0 -58
- package/docs/agents/intake.md +0 -81
- package/docs/agents/key-changes.md +0 -116
- package/docs/agents/label-coverage.md +0 -86
- package/docs/agents/markdown-audit-weight.md +0 -81
- package/docs/agents/pr-evidence-layout.md +0 -70
- package/docs/agents/pr-evidence.md +0 -273
- package/docs/agents/pr-frames.md +0 -131
- package/docs/agents/pr-lift.md +0 -132
- package/docs/agents/pr-local.md +0 -111
- package/docs/agents/pr-preview.md +0 -155
- package/docs/agents/pr-reads.md +0 -111
- package/docs/agents/pr-tick.md +0 -72
- package/docs/agents/records-push.md +0 -61
- package/docs/agents/records-stale.md +0 -40
- package/docs/agents/records-validate.md +0 -57
- package/docs/agents/restated.md +0 -83
- package/docs/agents/routing.md +0 -61
- package/docs/agents/rule-citations.md +0 -90
- package/docs/agents/sandbox.md +0 -126
- package/docs/agents/scripting.md +0 -142
- package/docs/agents/sessions.md +0 -128
- package/docs/agents/skills-audit.md +0 -120
- package/docs/agents/skills-reach.md +0 -64
- package/docs/agents/slides.md +0 -176
- package/docs/agents/state-scoped-risk.md +0 -105
- package/docs/agents/superseded.md +0 -85
- package/docs/agents/tasks-archive.md +0 -83
- package/docs/agents/tasks-plans.md +0 -152
- package/docs/agents/tasks-validate.md +0 -133
- package/docs/agents/tasks.md +0 -123
- package/docs/agents/teach-authoring.md +0 -118
- package/docs/agents/teach.md +0 -157
- package/docs/agents/test-order.md +0 -58
- package/docs/agents/upstream.md +0 -94
- package/docs/agents/worktrees.md +0 -118
- package/docs/target/standards-moved.md +0 -34
- package/src/markdown/growth.ts +0 -43
|
@@ -1,246 +1,136 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Install and sync
|
|
3
|
-
description: What each install and sync verb writes, refuses, or leaves alone, and
|
|
3
|
+
description: What each install and sync verb writes, refuses, or leaves alone, the drift report and its seven side sections, the rule detection record, and version skew states
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Install and sync
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
`canon
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`canon gov install`
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
A rule
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
the `
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
A
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`canon
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
When the target's install recorded a stack, `canon gov sync` also reports a
|
|
81
|
-
rule that stack lists and `.claude/rules/canon/` does not hold, as a `missing`
|
|
82
|
-
entry carrying no change. This is what makes a target whose recorded sync point
|
|
83
|
-
postdates a rule joining its stack still see that rule: the report reads the
|
|
84
|
-
target's current entitlement against its current tree rather than diffing
|
|
85
|
-
from an anchor a later sync could advance past the rule's own commit. A
|
|
86
|
-
target whose install predates the recorded chain falls back to the same
|
|
87
|
-
rule-folder-inference `newRules` uses in `canon sync --check`.
|
|
88
|
-
|
|
89
|
-
## Tooling diff and sync
|
|
90
|
-
|
|
91
|
-
`canon tooling diff <stack> [target]` is the read-only comparison, and a session asking what differs reaches for it by default. It writes nothing and exits 1 when anything differs and 0 when nothing does, so it gates CI. `--json` adds the scan record on stdout with `ok: true`, and the frame goes to stderr. A refusal such as an unknown stack, an excluded stack, or a toolkit-root target still exits 1 and answers `{ ok: false, reason, message }`, so a caller branches on the record and reads a typo'd stack name as a refusal rather than as drift.
|
|
92
|
-
|
|
93
|
-
The record carries a `withheld` array beside `configs`, each entry `{ rel, stack, present }`. It fills only when the target sits below its git root: every `.github/` config or seed moves there rather than into `configs` or `seeds`, and none of them counts toward the exit, since GitHub never reads a workflow outside the root. `present` marks a copy an earlier sync already left in the subfolder, which the sync reports and never deletes. At a root, and for a target outside any repository, `withheld` is empty.
|
|
94
|
-
|
|
95
|
-
`canon tooling sync <stack> [target] --check` reports the same list and always exits 0. It stays for scripts that already call it. `sync` itself writes only under `--write`, and a headless run with neither flag reports and exits 1.
|
|
96
|
-
|
|
97
|
-
## Install guards
|
|
98
|
-
|
|
99
|
-
`canon gov install` requires its first argument under
|
|
100
|
-
`CANON_NON_INTERACTIVE=1`. It used to fall back to an interactive picker that
|
|
101
|
-
resolved to its first option headlessly, so a call with no stack installed
|
|
102
|
-
whichever stack sorted first. It now reports the valid names on stderr and
|
|
103
|
-
exits 1.
|
|
104
|
-
|
|
105
|
-
Every documented agent path already passes the argument, including
|
|
106
|
-
`canon init`. The confirm-then-apply prompt after it still resolves to `Yes`
|
|
107
|
-
headlessly, so a call that names its stack is unchanged.
|
|
108
|
-
|
|
109
|
-
`--add` with no stack installs the named rules into the one positional, or the
|
|
110
|
-
current directory, and keeps the recorded chain. Pass `./node` to force a target
|
|
111
|
-
named like a stack. [Rule detection](gov-detect.md) proposes the names.
|
|
112
|
-
|
|
113
|
-
`canon gov install` also refuses the toolkit root as a target. It resolves the
|
|
114
|
-
target before anything else, so a path that does not exist fails rather than
|
|
115
|
-
being scaffolded.
|
|
116
|
-
|
|
117
|
-
A target still on the flat installed-rule layout from an older release reports
|
|
118
|
-
"No governance surfaces found in target" from `canon gov sync` and exits 0,
|
|
119
|
-
since sync reads only the current wrapped destination. `canon gov install`
|
|
120
|
-
against that same target writes a second, wrapped copy beside the flat one
|
|
121
|
-
rather than reading or clearing it, so the target ends up holding both, and
|
|
122
|
-
Claude Code loads both copies of an edited rule at session start. Run `canon
|
|
123
|
-
migrate rule-layout` first to move a target off the flat layout, which reports
|
|
124
|
-
what it would move and applies it under `--write`.
|
|
125
|
-
|
|
126
|
-
## Governance regen
|
|
127
|
-
|
|
128
|
-
`canon gov regen` is the one governance verb that runs against the toolkit root,
|
|
129
|
-
because the `.claude/rules/` it writes there is produced output rather than an
|
|
130
|
-
operator's working copy. It reads the stack recorded in `internal/governance.toml`
|
|
131
|
-
into `.claude/rules/canon/`, installs anything under `internal/rules/` into a
|
|
132
|
-
separate `.claude/rules/internal/`, and clears both destinations first so a
|
|
133
|
-
rule the record stopped naming disappears. `internal/` is what this repository
|
|
134
|
-
alone carries: no `canon gov install` or `canon gov sync` target ever writes it,
|
|
135
|
-
since a target has no rule source of its own that ships nowhere.
|
|
136
|
-
|
|
137
|
-
It takes `--root <path>` and defaults to the toolkit root, prints nothing on success, and
|
|
138
|
-
reports the reason on stderr with exit 1 when the record names a stack or rule
|
|
139
|
-
that does not resolve. The Consumed copies stage of `bun run check` calls it and
|
|
140
|
-
asserts both the generated rule folders and the consumed copy are committed.
|
|
8
|
+
What each verb writes, refuses, and leaves alone. `canon --help` lists flags.
|
|
9
|
+
|
|
10
|
+
## Bootstrap
|
|
11
|
+
|
|
12
|
+
`canon init [path]` installs up to five core domains and reports each independently. A failed domain does not abort the run, which finishes the rest and exits 1 naming the failures.
|
|
13
|
+
|
|
14
|
+
Any flag skips the confirmation prompt, but the `base` default of `--stack` does not count, so a bare `canon init` still prompts. `--skip` takes `wiki`, `governance`, and `records`, and warns on any other value.
|
|
15
|
+
|
|
16
|
+
## Governance install
|
|
17
|
+
|
|
18
|
+
- `canon gov install <stack> [target]` needs the stack under `CANON_NON_INTERACTIVE=1`, else lists the valid names on stderr and exits 1
|
|
19
|
+
- `--yes` answers the install confirm with no TTY and no env var. Without it, a headless call refuses and the message names `--yes`. It does not pick a stack.
|
|
20
|
+
- It refuses the toolkit root and a missing path
|
|
21
|
+
- `--add <rules>` with no stack installs into the one positional, or the current directory, keeping the recorded chain. Pass `./node` for a target named like a stack.
|
|
22
|
+
|
|
23
|
+
A flat installed-rule layout makes `gov sync` report "No governance surfaces found in target" and exit 0, and `gov install` write a second, wrapped copy. Run `canon migrate rule-layout` first.
|
|
24
|
+
|
|
25
|
+
## Governance sync
|
|
26
|
+
|
|
27
|
+
`canon gov sync [target]` updates what `.claude/rules/canon/` holds and adds nothing. `.claude/rules/project/` is never read, so put project rules there.
|
|
28
|
+
|
|
29
|
+
- A rule the toolkit no longer ships is deleted, edited or not
|
|
30
|
+
- A rule renamed in `governance/renames.toml` moves, and its local edits are dropped
|
|
31
|
+
- A rule the recorded stack lists and the tree lacks reports as `missing` with no change
|
|
32
|
+
- A retired `.claude/GOV.md` is removed
|
|
33
|
+
- A binary older than the stamp holds every rule it has no source for and asks for an upgrade
|
|
34
|
+
|
|
35
|
+
After a rename the new name shows as `missing` when the stamp records a stack, and `gov install <stack>` adds it.
|
|
36
|
+
|
|
37
|
+
`canon gov regen [--root <path>]` runs against the toolkit root alone. It rewrites `.claude/rules/canon/` and `.claude/rules/internal/` from `internal/`, and exits 1 when the record names something that does not resolve.
|
|
38
|
+
|
|
39
|
+
## Rule detection
|
|
40
|
+
|
|
41
|
+
`canon gov detect [target] [--stack <stack>] [--json]` proposes opt-in rules and writes nothing, from `governance/detect.toml` evidence keyed by rule basename.
|
|
42
|
+
|
|
43
|
+
- `deps` match package names in `package.json`, `pyproject.toml`, `go.mod`, and `composer.json`
|
|
44
|
+
- `files` are globs matched against git-listed paths and their folders, to depth two. Install what the operator keeps with `canon gov install --add <rules> <target>`.
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"target": "",
|
|
49
|
+
"stack": "node",
|
|
50
|
+
"proposals": [
|
|
51
|
+
{
|
|
52
|
+
"rule": "react",
|
|
53
|
+
"evidence": [{ "kind": "dep", "match": "react", "path": "package.json" }]
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `kind` is `dep` or `file`, and `stack` is null without `--stack`, which drops rules that stack resolves
|
|
60
|
+
- A glob without a wildcard is also tested on disk, an unparseable manifest contributes nothing, and outside git the walk skips `.git`, `node_modules`, `vendor`, and `.venv`
|
|
61
|
+
- It exits 0 on any readable target and 1 for a missing target or an unresolved stack
|
|
62
|
+
|
|
63
|
+
## Tooling
|
|
64
|
+
|
|
65
|
+
- `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference
|
|
66
|
+
- A `--json` refusal answers `{ ok: false, reason, message }`, so branch on the record
|
|
67
|
+
- `withheld` entries are `{ rel, stack, present }`, hold every `.github/` file below the git root, and count toward no exit
|
|
68
|
+
- `present` marks a copy an earlier sync left, which is reported and never deleted
|
|
69
|
+
- `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1.
|
|
70
|
+
|
|
71
|
+
`canon tooling inject` and `prune-gitignore` apply one stack with no scan or prompt, and the latter prints the number removed on stdout. Use `sync` unless scripting provisioning, and pass `--nested` inside an open frame.
|
|
72
|
+
|
|
73
|
+
## Design
|
|
74
|
+
|
|
75
|
+
- `canon design install` copies `base.css` to `.claude/design/` and creates no override
|
|
76
|
+
- Project overrides live in `.claude/design/project/`, which `design sync` never touches
|
|
77
|
+
- `canon design fonts add <file> --family <name>` copies a `woff2`, `woff`, `ttf`, or `otf` face into `project/fonts/` with its `fonts.css` rule, and refuses mismatched bytes as `invalid-font`
|
|
78
|
+
- `fonts list --json` flags a missing or out-of-folder file as a `problem`
|
|
79
|
+
- `canon sync` skips the domain where `design install` never ran
|
|
141
80
|
|
|
142
81
|
## Whole-project sync
|
|
143
82
|
|
|
144
|
-
`canon sync` runs every installed domain sync, then offers
|
|
145
|
-
and open a pull request. Under `CANON_NON_INTERACTIVE=1` it applies the domain
|
|
146
|
-
syncs and then refuses the git workflow, reporting the branch and commit it
|
|
147
|
-
would have created and exiting 0. Nothing is staged, committed, or pushed
|
|
148
|
-
headlessly.
|
|
149
|
-
|
|
150
|
-
Run it interactively to reach the commit and pull request options.
|
|
151
|
-
It also refuses a target whose working tree is dirty, so commit or stash first.
|
|
152
|
-
|
|
153
|
-
## Drift reporting
|
|
154
|
-
|
|
155
|
-
`canon sync --check` reports drift and writes nothing, so it needs no clean tree
|
|
156
|
-
and is safe to run at any time. Each file is classified as `stale` when it still
|
|
157
|
-
matches what the toolkit installed, `customized` when the project edited it,
|
|
158
|
-
`stranded` when it sits at a path the toolkit no longer installs to, `orphaned`
|
|
159
|
-
when the project authored it, or `drifted` when no stamp covers it. Governance
|
|
160
|
-
also reports `missing`, for a rule the target's recorded stack lists that its
|
|
161
|
-
tree does not hold at all, `retired`, for a rule under
|
|
162
|
-
`.claude/rules/canon/` the toolkit no longer ships, which the next sync
|
|
163
|
-
deletes, and `renamed`, for one the toolkit ships under a new name, which the
|
|
164
|
-
next sync moves. A `retired` or `renamed` file counts toward `--exit-code`,
|
|
165
|
-
since one sync clears it.
|
|
166
|
-
|
|
167
|
-
Use `--json` for the machine-readable report and `--exit-code` to fail a CI job. Orphaned
|
|
168
|
-
and missing files are both excluded from that exit code: a project-authored
|
|
169
|
-
rule never converges, and a sync that added a missing one silently changes
|
|
170
|
-
what the project is governed by, which stays a separate command an operator
|
|
171
|
-
chooses to run. Attribution reads `canon/config/config.json` first, which every
|
|
172
|
-
install and sync now writes, and falls back to `.claude/canon/config.json` for
|
|
173
|
-
a target that has not moved.
|
|
174
|
-
|
|
175
|
-
A target installed before stamping shipped has no such file, and neither does
|
|
176
|
-
that fallback do anything to migrate it. A target stamped before the file
|
|
177
|
-
moved into `.claude/canon/` still carries it at the retired
|
|
178
|
-
`.claude/canon.json`, and `canon sync --check` reads that path when the current
|
|
179
|
-
one is absent, reporting it rather than moving it. Only a target carrying
|
|
180
|
-
neither path falls back to the toolkit's own git history.
|
|
181
|
-
Installed content matching any
|
|
182
|
-
version that history ever published proves the file is untouched, so it reports
|
|
183
|
-
`stale` naming the commit it came from, and content matching no published
|
|
184
|
-
version stays `drifted`. A toolkit reached outside a git clone, which is what a
|
|
185
|
-
registry install is, cannot run that fallback and reports
|
|
186
|
-
`historyUnavailable` alongside the unattributed files.
|
|
187
|
-
|
|
188
|
-
Each domain carries its own toolkit anchor in that file, so syncing one domain
|
|
189
|
-
never advances the revision another measures from, and each reports the upstream
|
|
190
|
-
commits touching its own source path. The `covers` field names the domains a
|
|
191
|
-
target has actually stamped, so a domain that was never stamped is legible
|
|
192
|
-
rather than reading as a clean one.
|
|
193
|
-
|
|
194
|
-
### Tooling
|
|
195
|
-
|
|
196
|
-
Tooling records the stack chain an install resolved rather than per-file hashes,
|
|
197
|
-
since `src/tooling/` runs its own inject machinery and has no walk to attribute.
|
|
198
|
-
The chain is ordered nearest stack first, which is what a `--skip` run needs:
|
|
199
|
-
recording the leaf alone would send the next report measuring against a layer the
|
|
200
|
-
target deliberately does not carry. The report loads exactly those stacks, scans
|
|
201
|
-
them the way `canon tooling diff` would, and counts what differs per category
|
|
202
|
-
under `tooling.counts`.
|
|
203
|
-
|
|
204
|
-
`measured` is the field the section exists for. A target carrying no chain
|
|
205
|
-
reports `measured: false`, which separates tooling nobody has ever looked at from
|
|
206
|
-
tooling that is current. Both produce zero changes otherwise. Every target
|
|
207
|
-
installed before the record shipped starts unmeasured and leaves on its next
|
|
208
|
-
`canon tooling sync`, since backfilling would mean inferring the chain from
|
|
209
|
-
installed files, which is the guess the record replaces.
|
|
210
|
-
|
|
211
|
-
A workspace root records nothing, because each package resolves its own chain and
|
|
212
|
-
one written at the root would be that same guess. Run the check against a package
|
|
213
|
-
to measure it. Tooling never counts toward `--exit-code`, on the grounds seeds
|
|
214
|
-
are already excluded on, since it reports golden configs a project is expected to
|
|
215
|
-
edit and a job counting those stays red with no remedy.
|
|
216
|
-
|
|
217
|
-
### Surfaces reported beside the domains
|
|
218
|
-
|
|
219
|
-
Seven sections sit outside the per-domain scan, because each names something
|
|
220
|
-
that walk cannot see: `seeds`, `superseded`, `unmigrated`, `unmovedSurfaces`,
|
|
221
|
-
`newSkills`, `newRules`, and `reverse`. None of them produces a change, and no sync command
|
|
222
|
-
applies any of them. What each reports, the managed-target gate they share, and
|
|
223
|
-
which count toward `--exit-code` are in `drift-surfaces.md`.
|
|
83
|
+
`canon sync [path]` runs every installed domain sync, then offers a commit and pull request. Headlessly it applies the syncs, refuses the git workflow, reports what it would have made, and exits 0. It refuses a dirty working tree.
|
|
224
84
|
|
|
225
|
-
##
|
|
85
|
+
## Drift report
|
|
86
|
+
|
|
87
|
+
`canon sync --check` writes nothing and needs no clean tree. `--json` emits the record, `--exit-code` fails CI.
|
|
88
|
+
|
|
89
|
+
| State | Meaning |
|
|
90
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
91
|
+
| `stale` | Still matches what the toolkit installed |
|
|
92
|
+
| `customized` | The project edited it |
|
|
93
|
+
| `stranded` | Sits at a path the toolkit no longer installs to |
|
|
94
|
+
| `orphaned` | The project authored it |
|
|
95
|
+
| `drifted` | No stamp covers it |
|
|
96
|
+
| `missing` | Governance only. The recorded stack lists it and the tree lacks it |
|
|
97
|
+
| `retired` | Governance only. The toolkit no longer ships it |
|
|
98
|
+
| `renamed` | Governance only. The toolkit ships it under a new name |
|
|
99
|
+
|
|
100
|
+
`retired` and `renamed` count toward `--exit-code`. `orphaned` and `missing` do not.
|
|
101
|
+
|
|
102
|
+
- Attribution reads `canon/config/config.json`, then `.claude/canon/config.json`, then the retired `.claude/canon.json`, and moves none
|
|
103
|
+
- With none it matches the toolkit's git history, where a published version is `stale` and anything else `drifted`. A registry install has none and reports `historyUnavailable`.
|
|
104
|
+
- `covers` names the domains the target stamped, and each domain keeps its own anchor
|
|
105
|
+
- Tooling records its stack chain, nearest first, and never counts toward `--exit-code`
|
|
106
|
+
- `tooling.measured: false` means none was recorded. It clears on the next `canon tooling sync`. A workspace root records nothing, so run the check against a package.
|
|
107
|
+
|
|
108
|
+
## Side sections
|
|
109
|
+
|
|
110
|
+
Seven sections sit outside the per-domain scan, and no sync applies them. Each returns empty when `managed` is false. A managed target holds `.claude/`, a `CLAUDE.md`, or a root-layout domain, and an unmanaged one is routed to `canon init`.
|
|
111
|
+
|
|
112
|
+
| Section | Reports | Exit |
|
|
113
|
+
| ----------------- | --------------------------------------------------------------------------------------- | ---- |
|
|
114
|
+
| `seeds` | Each seed as `matching`, `stale`, `drifted`, or `missing`. Merge an edited one by hand. | No |
|
|
115
|
+
| `superseded` | A file a newer seed folder replaced, as `replacedBy`. Never deleted. | No |
|
|
116
|
+
| `unmigrated` | A domain at its old root, with `rootPath`, `installPath`, and a count | Yes |
|
|
117
|
+
| `unmovedSurfaces` | A surface at its `.claude/` spelling, as `rel` and `movesTo` | No |
|
|
118
|
+
| `newRules` | A rule the recorded stack lists and the tree lacks | No |
|
|
119
|
+
| `newSkills` | A plugin skill the target has not seen. Needs no command. | No |
|
|
120
|
+
| `reverse` | `unclaimed` folders the toolkit once shipped | No |
|
|
121
|
+
|
|
122
|
+
The Exit column marks what counts toward `--exit-code`. `canon migrate surface-roots` closes `unmovedSurfaces`, and `canon gov install` closes `newRules`. A `reverse` entry is attributed `dropped`, `project`, or `unattributed`.
|
|
123
|
+
|
|
124
|
+
`newRules` and `newSkills` come back empty on a shallow clone or registry install, which is unmeasured rather than clean.
|
|
125
|
+
|
|
126
|
+
## Version skew
|
|
127
|
+
|
|
128
|
+
`canon sync --check` and `canon claude skills drift` report the installed version against the newest published one in `skew.state`. The report never changes an exit code, so branch on the field.
|
|
129
|
+
|
|
130
|
+
| State | Meaning |
|
|
131
|
+
| --------- | ---------------------------------------------------- |
|
|
132
|
+
| `behind` | Names `canon upgrade` as the remedy |
|
|
133
|
+
| `current` | Installed matches published |
|
|
134
|
+
| `unknown` | Carries the reason the registry could not be reached |
|
|
226
135
|
|
|
227
|
-
`canon
|
|
228
|
-
domain that fails does not abort the run, so the command finishes the rest and
|
|
229
|
-
exits 1 naming the failures. Passing any flag skips the confirmation prompt,
|
|
230
|
-
which is what makes it scriptable.
|
|
231
|
-
|
|
232
|
-
`--stack` defaults to `base`, and the default
|
|
233
|
-
does not read as a passed flag, so a bare `canon init` installs governance and
|
|
234
|
-
still prompts. `--skip` takes `wiki`, `governance`, and `records`, and warns
|
|
235
|
-
without aborting on any other value. Records has nothing to run non-interactively,
|
|
236
|
-
since the private backup repository does not exist yet at scaffold time, so its
|
|
237
|
-
step only prints the one-time setup reminder and `--skip records` silences it.
|
|
238
|
-
|
|
239
|
-
## Unguarded tooling primitives
|
|
240
|
-
|
|
241
|
-
`canon tooling inject` and `canon tooling prune-gitignore` are the unguarded
|
|
242
|
-
primitives beneath `sync`. They apply one stack with no scan and no prompt, and
|
|
243
|
-
they deliberately skip the check that rejects `claude`, which is how `canon
|
|
244
|
-
claude` drives its own stack through them. Use `sync` unless you are scripting
|
|
245
|
-
provisioning. Both frame their own output, so pass `--nested` when calling from
|
|
246
|
-
inside an already-open frame.
|
|
136
|
+
`canon upgrade --json` adds `pending`, where the checkout holds a release npm does not serve yet. `checkout` names it, `message` starts `CLI stays at`, and the exit is 0.
|
|
@@ -1,126 +1,84 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Markdown audit
|
|
3
|
-
description: Running the audit over any
|
|
3
|
+
description: Running the markdown audit over any path, each finding it reports with whether it gates, the six density limits, the advisory measures, the exit codes, and where the audit runs
|
|
4
|
+
kind: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Markdown audit
|
|
7
8
|
|
|
8
|
-
`canon markdown audit [path...]` reports any markdown file against the `markdown-craft` skill's `markdown.md
|
|
9
|
+
`canon markdown audit [path...]` reports any markdown file against the `markdown-craft` skill's `markdown.md`. It resolves no folder and needs no `index.md`, so `.claude/rules/` and `governance/` are in reach. Folder-shaped findings belong to `canon context audit`, in `context-audit.md`.
|
|
9
10
|
|
|
10
11
|
```bash
|
|
11
12
|
canon markdown audit
|
|
12
13
|
canon markdown audit --json
|
|
13
14
|
canon markdown audit .claude/rules governance
|
|
14
|
-
canon markdown audit docs/agents/
|
|
15
|
+
canon markdown audit docs/agents/install-and-sync.md
|
|
15
16
|
canon markdown audit 'docs/**/*.md'
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
| -------- | ---------------------------------------------------------- |
|
|
20
|
-
| `--json` | Add a machine-readable record on stdout, keeping the frame |
|
|
19
|
+
An argument is a file, a directory, or a glob, taken against the corpus git lists. A bare run measures every tracked or untracked-and-not-ignored file. An explicit file is taken as given, so a gitignored draft can be measured, and an argument matching nothing is named on the scope line.
|
|
21
20
|
|
|
22
|
-
##
|
|
21
|
+
## Output
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
The ban set and checkpoints ship in `src/markdown/bans.ts` and `src/markdown/structure.ts`. `markdown.md` states each rule and the `write-human` skill states the cadence numbers, so move a number in both places in one change.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
| Finding | Reports | Gates |
|
|
26
|
+
| --------------- | ------------------------------------------------------------------------------------ | ------------------------- |
|
|
27
|
+
| Bans | The two characters `markdown.md` bans, outside frontmatter, fences, spans, and links | Always |
|
|
28
|
+
| Links | A relative link resolving to nothing on disk | Always |
|
|
29
|
+
| Density | The six limits below, under `density` | On a `GATED_PATHS` prefix |
|
|
30
|
+
| Reference shape | A `kind: reference` page breaking its shape, under `referenceShape` | On a `GATED_PATHS` prefix |
|
|
31
|
+
| Colons | A colon followed by more text in a prose line, under `colons` | Never |
|
|
32
|
+
| Heading case | A capital after the first word of a heading or `title`, under `headingCase` | Never |
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
A page marked `kind: reference` holds its opening, then `Output`, `Refusals`, and `See also` as H2s, each at most once and in that order. It takes no H3 and no table headed `Flag` or `Option`. An unmarked page is never measured.
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
| Density limit | Finding |
|
|
37
|
+
| ------------------- | ---------------------------------------------------------- |
|
|
38
|
+
| Paragraph length | A prose paragraph past 350 characters |
|
|
39
|
+
| Paragraphs in a row | More than 2 paragraphs with nothing else between them |
|
|
40
|
+
| Bullet length | A top-level bullet past 200 characters |
|
|
41
|
+
| Bullets in a row | More than 5 plain top-level bullets |
|
|
42
|
+
| Heading depth | Any heading past H3 |
|
|
43
|
+
| H3 opening | An H3 whose first block is neither a paragraph nor a table |
|
|
31
44
|
|
|
32
|
-
|
|
45
|
+
- A paragraph under a list item counts toward that bullet, never as a paragraph
|
|
46
|
+
- A table, fence, list, heading, or bold section marker ends a run of paragraphs
|
|
47
|
+
- A run whose every item opens with a bold label or a link is exempt, and numbered items never count
|
|
48
|
+
- Only context entries, docs, skill bodies and references, tooling seeds and stack references, the wiki, `README.md`, and `CONTRIBUTING.md` take a finding
|
|
49
|
+
- A bullet run gates everywhere those paths sit, and the rest gates under `GATED_PATHS` in `src/markdown/scope.ts`. Outside a canon checkout nothing gates.
|
|
33
50
|
|
|
34
|
-
|
|
51
|
+
Five measures report and never set the exit code on their own.
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
| Measure | Reports | Gate or report |
|
|
54
|
+
| ---------- | ------------------------------------------------------------------------------------ | -------------------------------------- |
|
|
55
|
+
| Bullets | A bullet past 200 characters | Gates through the density length |
|
|
56
|
+
| Paragraphs | A paragraph past 4 sentences or 350 characters | Gates through the density length |
|
|
57
|
+
| Cadence | 3 or more sentences with a spread of 5 words or under, or a word opening more than 2 | Reports |
|
|
58
|
+
| Depth | A run past about 40 rendered lines at 80 columns | Reports |
|
|
59
|
+
| Length | A document past 300 rendered lines, unless it carries `canon-length-exempt` | Reports, and the gate owns the verdict |
|
|
37
60
|
|
|
38
|
-
|
|
61
|
+
| Code | Meaning |
|
|
62
|
+
| ---- | ------------------------------------------------------------------ |
|
|
63
|
+
| `0` | No gating finding |
|
|
64
|
+
| `1` | Refused, with the reason on stderr |
|
|
65
|
+
| `2` | A ban, a dead link, or a gating density or reference shape finding |
|
|
66
|
+
| `3` | The shipped ban set is empty, so nothing was measured |
|
|
39
67
|
|
|
40
|
-
|
|
68
|
+
Rewrite the sentence on a ban hit rather than swapping the token. A code span clears the report only where the token is an identifier under discussion.
|
|
41
69
|
|
|
42
|
-
|
|
70
|
+
The audit runs in four places:
|
|
43
71
|
|
|
44
|
-
|
|
72
|
+
- `.claude/hooks/standards-audit.sh` after each markdown edit, handing back every finding
|
|
73
|
+
- The `Markdown` stage of `canon gate run`, over the whole corpus
|
|
74
|
+
- `scripts/verify.ts` in a scaffolded project, excluding `CHANGELOG.md` and skipping with a logged line when no `canon` is on `PATH`
|
|
75
|
+
- The seeded hook in a target
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
## Refusals
|
|
47
78
|
|
|
48
|
-
|
|
79
|
+
- `no-git` or `no-markdown`: no corpus can be built, and the gate reads it as unmeasured
|
|
49
80
|
|
|
50
|
-
|
|
81
|
+
## See also
|
|
51
82
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
A relative link's destination resolves against the filesystem, over the same corpus the ban scan reads. A destination is skipped rather than resolved when it is empty, opens with a URL scheme, opens with `#` as a same-file anchor, opens with `/` as a root-absolute reference, or carries `<` as a template placeholder such as `<slug>` or `<name>`. What remains is split on its first `#`, decoded, and resolved against the linking file's own folder, and a destination resolving to nothing on disk reports.
|
|
55
|
-
|
|
56
|
-
The placeholder exemption is the one live case the corpus needs. Every current instance is a genuine illustration rather than a literal path, and a marker-based override is available for the day a real one needs an exception instead.
|
|
57
|
-
|
|
58
|
-
### Colons and heading case
|
|
59
|
-
|
|
60
|
-
Two advisory measures report beside the bans and never fail a run.
|
|
61
|
-
|
|
62
|
-
The colon measure reports a colon followed by more text in a prose line, outside the label position. A list item's first colon, a bold or code span label, a line-final colon, a time, a URL, and anything inside a code span or a link are left alone. A heading, a table row, and a fenced line are skipped. Each finding carries the line, the column, the line's text, and the word before the colon as `lead` under `colons` in the `--json` entry.
|
|
63
|
-
|
|
64
|
-
The heading-case measure reports a heading or a frontmatter `title` with a capitalized word after its first, outside code spans and all-caps tokens, under `headingCase`. A proper noun reports as well and is left as it is.
|
|
65
|
-
|
|
66
|
-
`CHANGELOG.md` is exempt from both, since the release tool writes its headings.
|
|
67
|
-
|
|
68
|
-
### Weight, cadence, and length
|
|
69
|
-
|
|
70
|
-
Bullet and paragraph weight, bullet stacks, run depth, the two cadence numbers, and the document length ceiling are each a judgment a reader settles rather than a fact a scan settles. What each measures, the samples behind its checkpoint, and why none of them gates are in `markdown-audit-weight.md`.
|
|
71
|
-
|
|
72
|
-
## Exit codes
|
|
73
|
-
|
|
74
|
-
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, `2` for a ban hit or a dead relative link, and `3` for a shipped ban set that arrived empty. A banned character and a relative link resolving to nothing on disk each fail the run, both facts a scan settles rather than a reader judging. Bullet, paragraph, and depth weight are judgments a reader settles, and cadence is a distribution whose healthy range moves with the surface, so all four report under every code. A bullet stack, a run of more than 5 plain bullets, reports the same way, and the `bullet-stacks` stage in `canon gate run` owns its verdict. Length reports the same way, since the audit also runs on a plan kept out of version control, and the Document ceiling stage in `canon gate run` owns that verdict instead.
|
|
75
|
-
|
|
76
|
-
`3` is separate from `1` because the two want different responses from a caller. A refusal means no corpus was built, and the `Markdown bans` stage in `canon gate run` is right to report it as unmeasured rather than as a pass. An empty set means the corpus was walked and nothing was looked for, so that stage fails the push on `3` rather than skipping.
|
|
77
|
-
|
|
78
|
-
`2` rather than `1` for the gate keeps a measurement that succeeded and found something distinct from the audit declining to measure at all. A caller reading one as the other sends a reader hunting a defect that does not exist, which is the distinction `canon context audit` and the gate's own seed stage already draw between the same two codes.
|
|
79
|
-
|
|
80
|
-
A banned character is a fact rather than a judgment, which is the test that admits it to a gate. What held it back was that gating on day one against a corpus never checked mechanically fails loudly on work nobody has had a chance to fix. The order was to land the verb reporting, measure the corpus once, fix what it finds, and turn the gate on as its own change, and the gate is the last of the four.
|
|
81
|
-
|
|
82
|
-
Of the five measures a first full reading took, the ban count is the only one a gate should ever read.
|
|
83
|
-
|
|
84
|
-
The ban half reached zero, which was the precondition the gate waited on, and it was re-measured against the same corpus at the moment the gate landed. Three sweep slices then took the structural half, and the corpus reports 1 heavy bullet and 22 heavy paragraphs across 6 files on 2026-08-06, every one on a ground the triage record holds as exempt.
|
|
85
|
-
|
|
86
|
-
Depth is the one measure no slice triaged, so its figure moved with the sweep rather than with the corpus. The break rule widened to bold section markers on 2026-08-28 and again to the colon-less ones the same day, and each drop came with no edit to any file, so the 41 above reads against a rule the command no longer runs. Read all four structural counts from a run rather than from this paragraph.
|
|
87
|
-
|
|
88
|
-
### What a hit asks of an author
|
|
89
|
-
|
|
90
|
-
Rewrite the sentence rather than swapping the banned token for a near-synonym. The rule is about the sense the token carries, so a swap that keeps the sense clears the report without clearing the violation.
|
|
91
|
-
|
|
92
|
-
A code span clears the report too, since the ban scan walks around one, and it is the answer only where the token is genuinely an identifier under discussion. `## Code and identifiers` in `markdown.md` reserves the span for commands, API names, file paths, and identifiers, so backticking a quoted utterance spends one rule to satisfy another and leaves the corpus no cleaner.
|
|
93
|
-
|
|
94
|
-
A hit the closed set could not separate from correct prose was the case with no third option while the set still carried words. The temporal `just` reported as the vague qualifier it happened to spell, and rewriting the sentence is what the toolkit settled on over building an exemption path, since an exemption landing in the verb and not the edit hook leaves the line failing where an author actually meets it. That class is part of why the words left the gate.
|
|
95
|
-
|
|
96
|
-
### Where the rules are enforced
|
|
97
|
-
|
|
98
|
-
Four surfaces apply the ban set and all four go through this verb. `.claude/hooks/standards-audit.sh` runs it against a single file after each markdown edit, the seed copy a project installs does the same, the `Markdown bans` stage in `canon gate run` runs it across the whole corpus before this repository's own push, and the same-named stage in the one verify runner every stack shares, `scripts/verify.ts`, runs it across a scaffolded project's tracked markdown before its own push. Each hook parsed its own copy of the word bans in awk before that, which left a British spelling passing at edit time and failing the push with nothing in between explaining the difference.
|
|
99
|
-
|
|
100
|
-
The seed copy moved onto the verb when the sets became data, since its awk had nothing left to parse. It resolves one runner where the toolkit copy resolves two, looking for no checkout source, and a machine carrying no `canon` gets a report naming the binary to install rather than a silent pass. The Seed independence stage of `bun run check` scopes its walk to markdown and leaves the seed hooks outside it, which its own comment records as deliberate.
|
|
101
|
-
|
|
102
|
-
The target push stage reads the same exit codes `canon gate run`'s own stage reads: 0 passes, 1 is a refusal logged as a skip, 2 is a finding, and 3 is a shipped-empty ban set. It skips and logs rather than failing when no `canon` binary is on the machine's PATH, since a scaffolded project is not guaranteed the toolkit is installed, and its skip line names the install command.
|
|
103
|
-
|
|
104
|
-
The target push stage excludes `CHANGELOG.md`, unlike every other surface here. A changelog a generator builds from commit subjects carries prose nobody wrote against the ban set, where this repository's own passes only because `release-please` builds it from subjects sessions already wrote to the rule. The stage passes an explicit file list rather than the bare invocation the other surfaces use, so a corpus with no file left once the changelog is set aside reads as a pass rather than falling back to the whole tree.
|
|
105
|
-
|
|
106
|
-
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies. It reads `bans.emptySets` out of the same record, so a set the verb shipped empty reaches the author as a check narrowed to what it could measure rather than as a clean pass.
|
|
107
|
-
|
|
108
|
-
It also relays the two advisory measures from the same record. A heading finding reports for the whole file, and a colon finding reports only where the word before the colon and the colon appear in the text the write carried, so an edit is never asked to answer for a colon it left untouched.
|
|
109
|
-
|
|
110
|
-
That field replaced `bans.missingStandards`, which answered a standard resolving under none of three roots. The set ships with the package now, so the state it named cannot occur and the narrowed check has one cause left, a defect in the build. The hook keeps reading a field either way, since a reader cannot tell a narrowed check from a clean one without it.
|
|
111
|
-
|
|
112
|
-
Both hooks answer an absent record as well. A completed run always writes the record and a refusal writes none, so an empty one means the verb declined to measure rather than measured and found nothing. The verb needs a git repository to build its corpus and refuses without one, which is a project the seeded hook can be installed into, and reading the findings alone reported that as a clean file.
|
|
113
|
-
|
|
114
|
-
A machine with neither runner still blocks no edit, and it says so rather than exiting clean. The push stage holds either way. An edit nobody checked and an edit carrying no violation are one silence to a reader, so the enforcement a machine lacks is reported rather than inferred.
|
|
115
|
-
|
|
116
|
-
The stage measures the whole corpus rather than the changed files. A `Do not use` bullet added to a reference bans a token retroactively, and no file in the push that adds the bullet was edited.
|
|
117
|
-
|
|
118
|
-
## What it does not cover
|
|
119
|
-
|
|
120
|
-
The verb reads the `markdown-craft` skill's reference and the `write-human` cadence numbers and nothing else. The references the `git-pr`, `git-branch`, and `git-commit` skills own, `publish.md`, `slug.md`, and `versioning.md`, govern an attribute of other artifacts, and none of them is implemented here.
|
|
121
|
-
|
|
122
|
-
`publish.md` describes a scan applying the same punctuation bans to finished text on its way out. No code implemented that scan before this command, so nothing is duplicated, and a later surface should call this verb rather than build a second one.
|
|
123
|
-
|
|
124
|
-
That reference's cross-reference rule is out of reach rather than merely unimplemented. It resolves by destination, bare where the destination auto-links a pull request or issue number and backticked where it does not, so this verb sees only the half where the backticked form is correct. A check here would report every compliant reference in the tree and reach none of the published text that goes wrong, which is why the rule holds on reading alone.
|
|
125
|
-
|
|
126
|
-
The list-density rule at `claude/skills/markdown-craft/references/markdown.md` is out of scope on purpose, since it carries no number and what a density figure should measure is still open.
|
|
83
|
+
- `context-audit.md`: the folder-shaped findings
|
|
84
|
+
- `audits.md`: the aggregate that runs this audit
|