@erclx/canon 5.38.0 → 5.39.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 +1 -1
- 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 +36 -17
- 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 +7 -4
- 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-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 +62 -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-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/create-report.md +36 -0
- 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 +22 -18
- 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/context-audit-checks.md +19 -1
- package/docs/agents/context-audit.md +2 -2
- package/docs/agents/driver.md +1 -1
- package/docs/agents/hooks.md +21 -1
- package/docs/agents/index.md +10 -14
- package/docs/agents/indexes.md +25 -29
- package/docs/agents/install-and-sync.md +124 -235
- package/docs/agents/markdown-audit-density.md +39 -0
- package/docs/agents/markdown-audit-weight.md +9 -7
- package/docs/agents/markdown-audit.md +18 -14
- 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/routing.md +1 -1
- package/docs/agents/rule-citations.md +1 -1
- package/docs/agents/skills-reach.md +1 -1
- package/docs/agents/targets.md +25 -77
- package/docs/target/migrations.md +1 -1
- package/docs/target/projects.md +2 -2
- package/docs/workflow/ai-workflow.md +2 -2
- package/docs/workflow/parallel-features.md +2 -2
- package/docs/workflow/skill-map.md +1 -1
- package/docs/workflow/visual-design-workflow.md +1 -1
- package/package.json +1 -1
- package/src/commands/claude.ts +1 -1
- package/src/commands/context.ts +106 -7
- package/src/commands/hooks.ts +63 -0
- package/src/commands/markdown.ts +169 -32
- package/src/context/audit.ts +256 -5
- package/src/context/classify/prompts.ts +1 -1
- package/src/context/gate.ts +23 -7
- package/src/context/shape-gated.ts +28 -0
- package/src/design/document.ts +1 -1
- package/src/design/tokens.ts +1 -1
- package/src/gate/measures.ts +15 -190
- package/src/gate/stages.ts +7 -23
- 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 +174 -0
- package/src/markdown/structure.ts +9 -59
- package/src/shipped/references.ts +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/docs/agents/commands.md +0 -154
- package/docs/agents/docs.md +0 -27
- package/docs/agents/drift-surfaces.md +0 -201
- package/docs/agents/gov-detect.md +0 -47
- package/docs/agents/scripting.md +0 -142
- package/src/markdown/growth.ts +0 -43
|
@@ -1,246 +1,135 @@
|
|
|
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
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
+
- It refuses the toolkit root and a missing path
|
|
20
|
+
- `--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.
|
|
21
|
+
|
|
22
|
+
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.
|
|
23
|
+
|
|
24
|
+
## Governance sync
|
|
25
|
+
|
|
26
|
+
`canon gov sync [target]` updates what `.claude/rules/canon/` holds and adds nothing. `.claude/rules/project/` is never read, so put project rules there.
|
|
27
|
+
|
|
28
|
+
- A rule the toolkit no longer ships is deleted, edited or not
|
|
29
|
+
- A rule renamed in `governance/renames.toml` moves, and its local edits are dropped
|
|
30
|
+
- A rule the recorded stack lists and the tree lacks reports as `missing` with no change
|
|
31
|
+
- A retired `.claude/GOV.md` is removed
|
|
32
|
+
- A binary older than the stamp holds every rule it has no source for and asks for an upgrade
|
|
33
|
+
|
|
34
|
+
After a rename the new name shows as `missing` when the stamp records a stack, and `gov install <stack>` adds it.
|
|
35
|
+
|
|
36
|
+
`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.
|
|
37
|
+
|
|
38
|
+
## Rule detection
|
|
39
|
+
|
|
40
|
+
`canon gov detect [target] [--stack <stack>] [--json]` proposes opt-in rules and writes nothing, from `governance/detect.toml` evidence keyed by rule basename.
|
|
41
|
+
|
|
42
|
+
- `deps` match package names in `package.json`, `pyproject.toml`, `go.mod`, and `composer.json`
|
|
43
|
+
- `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>`.
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"target": "",
|
|
48
|
+
"stack": "node",
|
|
49
|
+
"proposals": [
|
|
50
|
+
{
|
|
51
|
+
"rule": "react",
|
|
52
|
+
"evidence": [{ "kind": "dep", "match": "react", "path": "package.json" }]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- `kind` is `dep` or `file`, and `stack` is null without `--stack`, which drops rules that stack resolves
|
|
59
|
+
- 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`
|
|
60
|
+
- It exits 0 on any readable target and 1 for a missing target or an unresolved stack
|
|
61
|
+
|
|
62
|
+
## Tooling
|
|
63
|
+
|
|
64
|
+
- `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference
|
|
65
|
+
- A `--json` refusal answers `{ ok: false, reason, message }`, so branch on the record
|
|
66
|
+
- `withheld` entries are `{ rel, stack, present }`, hold every `.github/` file below the git root, and count toward no exit
|
|
67
|
+
- `present` marks a copy an earlier sync left, which is reported and never deleted
|
|
68
|
+
- `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1.
|
|
69
|
+
|
|
70
|
+
`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.
|
|
71
|
+
|
|
72
|
+
## Design
|
|
73
|
+
|
|
74
|
+
- `canon design install` copies `base.css` to `.claude/design/` and creates no override
|
|
75
|
+
- Project overrides live in `.claude/design/project/`, which `design sync` never touches
|
|
76
|
+
- `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`
|
|
77
|
+
- `fonts list --json` flags a missing or out-of-folder file as a `problem`
|
|
78
|
+
- `canon sync` skips the domain where `design install` never ran
|
|
141
79
|
|
|
142
80
|
## Whole-project sync
|
|
143
81
|
|
|
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`.
|
|
82
|
+
`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
83
|
|
|
225
|
-
##
|
|
84
|
+
## Drift report
|
|
85
|
+
|
|
86
|
+
`canon sync --check` writes nothing and needs no clean tree. `--json` emits the record, `--exit-code` fails CI.
|
|
87
|
+
|
|
88
|
+
| State | Meaning |
|
|
89
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
90
|
+
| `stale` | Still matches what the toolkit installed |
|
|
91
|
+
| `customized` | The project edited it |
|
|
92
|
+
| `stranded` | Sits at a path the toolkit no longer installs to |
|
|
93
|
+
| `orphaned` | The project authored it |
|
|
94
|
+
| `drifted` | No stamp covers it |
|
|
95
|
+
| `missing` | Governance only. The recorded stack lists it and the tree lacks it |
|
|
96
|
+
| `retired` | Governance only. The toolkit no longer ships it |
|
|
97
|
+
| `renamed` | Governance only. The toolkit ships it under a new name |
|
|
98
|
+
|
|
99
|
+
`retired` and `renamed` count toward `--exit-code`. `orphaned` and `missing` do not.
|
|
100
|
+
|
|
101
|
+
- Attribution reads `canon/config/config.json`, then `.claude/canon/config.json`, then the retired `.claude/canon.json`, and moves none
|
|
102
|
+
- 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`.
|
|
103
|
+
- `covers` names the domains the target stamped, and each domain keeps its own anchor
|
|
104
|
+
- Tooling records its stack chain, nearest first, and never counts toward `--exit-code`
|
|
105
|
+
- `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.
|
|
106
|
+
|
|
107
|
+
## Side sections
|
|
108
|
+
|
|
109
|
+
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`.
|
|
110
|
+
|
|
111
|
+
| Section | Reports | Exit |
|
|
112
|
+
| ----------------- | --------------------------------------------------------------------------------------- | ---- |
|
|
113
|
+
| `seeds` | Each seed as `matching`, `stale`, `drifted`, or `missing`. Merge an edited one by hand. | No |
|
|
114
|
+
| `superseded` | A file a newer seed folder replaced, as `replacedBy`. Never deleted. | No |
|
|
115
|
+
| `unmigrated` | A domain at its old root, with `rootPath`, `installPath`, and a count | Yes |
|
|
116
|
+
| `unmovedSurfaces` | A surface at its `.claude/` spelling, as `rel` and `movesTo` | No |
|
|
117
|
+
| `newRules` | A rule the recorded stack lists and the tree lacks | No |
|
|
118
|
+
| `newSkills` | A plugin skill the target has not seen. Needs no command. | No |
|
|
119
|
+
| `reverse` | `unclaimed` folders the toolkit once shipped | No |
|
|
120
|
+
|
|
121
|
+
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`.
|
|
122
|
+
|
|
123
|
+
`newRules` and `newSkills` come back empty on a shallow clone or registry install, which is unmeasured rather than clean.
|
|
124
|
+
|
|
125
|
+
## Version skew
|
|
126
|
+
|
|
127
|
+
`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.
|
|
128
|
+
|
|
129
|
+
| State | Meaning |
|
|
130
|
+
| --------- | ---------------------------------------------------- |
|
|
131
|
+
| `behind` | Names `canon upgrade` as the remedy |
|
|
132
|
+
| `current` | Installed matches published |
|
|
133
|
+
| `unknown` | Carries the reason the registry could not be reached |
|
|
226
134
|
|
|
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.
|
|
135
|
+
`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.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Markdown audit density
|
|
3
|
+
description: The six layout limits the markdown audit measures, what each one counts, which paths take a finding, and how a folder's gate turns on
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Markdown audit density
|
|
7
|
+
|
|
8
|
+
`canon markdown audit` measures six layout limits beside its bans. Each one is a count against a fixed number, so a finding is a fact rather than a judgment, and a gated path fails the run on it.
|
|
9
|
+
|
|
10
|
+
## The limits
|
|
11
|
+
|
|
12
|
+
Six limits report on the paths that take them, under `density` in each `--json` entry.
|
|
13
|
+
|
|
14
|
+
| Limit | Finding |
|
|
15
|
+
| ------------------- | ---------------------------------------------------------- |
|
|
16
|
+
| Paragraph length | a prose paragraph past 350 characters |
|
|
17
|
+
| Paragraphs in a row | more than 2 paragraphs with nothing else between them |
|
|
18
|
+
| Bullet length | a top-level bullet past 200 characters, marker excluded |
|
|
19
|
+
| Bullets in a row | more than 5 plain top-level bullets |
|
|
20
|
+
| Heading depth | any heading past H3 |
|
|
21
|
+
| H3 opening | an H3 whose first block is neither a paragraph nor a table |
|
|
22
|
+
|
|
23
|
+
## What counts as a block
|
|
24
|
+
|
|
25
|
+
A paragraph indented under a list item counts toward that bullet's length and never as a paragraph. A table, a fence, a list, a heading, and a bold section marker each break a paragraph run. Each finding carries `kind`, `line`, `value`, `limit`, and `gating`, and the H3 opening carries `null` for both numbers.
|
|
26
|
+
|
|
27
|
+
## Which paths take a finding
|
|
28
|
+
|
|
29
|
+
Only context entries, docs pages, skill bodies and references, tooling seeds and stack references, the wiki, `README.md`, and `CONTRIBUTING.md` take a finding. A rule, `CLAUDE.md`, a requirement or design record, the changelog, `examples/`, and every `.canon/` record take none, so a plan never reports one.
|
|
30
|
+
|
|
31
|
+
## When a finding gates
|
|
32
|
+
|
|
33
|
+
A finding gates when its path sits under a prefix in `GATED_PATHS` in `src/markdown/scope.ts`, and each rewrite batch adds its folders at zero, or one file per entry where it covers part of a folder. A run of more than 5 plain bullets gates in context, docs, and skills from the start, since it failed the push there before this measure existed.
|
|
34
|
+
|
|
35
|
+
Outside a canon checkout every density finding reports and none gates, since the list describes this repository's own rewrite.
|
|
36
|
+
|
|
37
|
+
## What reads the finding
|
|
38
|
+
|
|
39
|
+
A gating finding sets exit `2`, the same code a ban hit takes, and `markdown-audit.md` carries the full exit contract. The `Markdown` stage of `canon gate run` reads that exit over the whole corpus, and the edit-time hook hands every finding back, gating or not.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Markdown audit weight
|
|
3
|
-
description: The
|
|
3
|
+
description: The advisory sections of the markdown audit, being bullet and paragraph weight, run depth, the two cadence numbers, and the length ceiling, with the samples behind each checkpoint and which of those numbers gate through density
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Markdown audit weight
|
|
7
7
|
|
|
8
8
|
## Bullets, paragraphs, and depth
|
|
9
9
|
|
|
10
|
-
Bullet weight and depth are the checks that moved off `canon context audit`, carrying what they measured at the time. A top-level bullet reports past roughly
|
|
10
|
+
Bullet weight and depth are the checks that moved off `canon context audit`, carrying what they measured at the time. A top-level bullet reports past roughly 200 characters with continuation lines folded in and nested items left out. A run reports past roughly 40 rendered lines, measured at 80 columns, where a heading breaks one and so does a bold section marker taking the whole line at column zero, either ending in a colon, or holding one whole code span at any width, or running to 20 characters or fewer, skipping fenced blocks and exempting a flat peer list averaging under 130 characters a bullet and a run that is entirely table rows. Each file reports its longest run alone, so a second run past the checkpoint in the same file is never named.
|
|
11
11
|
|
|
12
12
|
Every weight and depth measure counts the text a reader is shown. A link reduces to its anchor text and an autolink drops whole, since no reader is shown either destination. A backticked path stays counted, which is where these measures part from the ban scan `markdown-audit.md` describes: that one blanks a code span so a standard quoting its own banned character does not report itself, and discounting the same span here would under-report a paragraph carrying several. One file holds both span sets and each answers its own question.
|
|
13
13
|
|
|
@@ -17,7 +17,7 @@ The paragraph check measures both halves of one rule. `markdown.md` caps a parag
|
|
|
17
17
|
|
|
18
18
|
A sentence boundary closes on terminal punctuation ahead of a capital or a code span. The capital is what keeps a version pin and a decimal from each reading as two sentences, and the code span is admitted beside it because a command name opening a sentence carries no capital to find.
|
|
19
19
|
|
|
20
|
-
The paragraph weight sits at
|
|
20
|
+
The paragraph weight sits at 350 and the bullet weight at 200, the two density lengths in `markdown-audit.md`, so this advisory warning and the density finding that gates read one number. Both shipped at 400 and have moved twice, each time against a sample of its own. They are separate checkpoints in the standard and separate patterns in the parser, so a read that moves one leaves the other where it is.
|
|
21
21
|
|
|
22
22
|
### The sample behind the paragraph number
|
|
23
23
|
|
|
@@ -44,15 +44,17 @@ The sample is thirty-six paragraphs against a reported population in the hundred
|
|
|
44
44
|
|
|
45
45
|
That re-sample ran once the scan stopped counting link syntax as prose. Findings at 604, 633, and 677 characters each read as an ordinary four-sentence paragraph on one topic, density arrived around 760 and was plain by 860, and the move cut the weight half of the report roughly in half while leaving the sentence cap untouched.
|
|
46
46
|
|
|
47
|
+
### The read that moved it to 350
|
|
48
|
+
|
|
49
|
+
The operator read sample rewrites at 400 and 350 side by side and picked 350, the length of the reference sample, in groundwork `154`. The bullet number moved to 200 in the same read, since no rewritten one-fact bullet passed 151. Both now gate as density limits, so the earlier verdict that a long paragraph reads well as written no longer holds.
|
|
50
|
+
|
|
47
51
|
A bullet, a heading, a table row, a blockquote, a blank line, and a fence each end a paragraph, so a heavy bullet is reported by the bullet check alone and never counted twice.
|
|
48
52
|
|
|
49
53
|
## Bullet stacks
|
|
50
54
|
|
|
51
|
-
A run of consecutive top-level bullets reports past 5. A blank line, an indented continuation, and a nested item do not break the run, and a paragraph, a heading, or any other column-zero line does. A fenced line is skipped without breaking it. The count is of items rather than weight, so it catches a catalog of short bullets the
|
|
52
|
-
|
|
53
|
-
Two shapes are exempt. A run whose every item opens with a bold label or a link names its own subject per item and reads as a table of entries, and a numbered list states an order, so numbered items never count. `CHANGELOG.md` is exempt by name. Governance rules and `REQUIREMENT.md` sit outside the gate stage's scope rather than being exempted here, since a rule is one imperative per bullet.
|
|
55
|
+
A run of more than 5 plain bullets is one of the six density limits in `markdown-audit.md`, which reports and gates it. This section keeps what counts as a run. A run of consecutive top-level bullets reports past 5. A blank line, an indented continuation, and a nested item do not break the run, and a paragraph, a heading, or any other column-zero line does. A fenced line is skipped without breaking it. The count is of items rather than weight, so it catches a catalog of short bullets the 200-character checkpoint above passes.
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
Two shapes are exempt. A run whose every item opens with a bold label or a link names its own subject per item and reads as a table of entries, and a numbered list states an order, so numbered items never count. Governance rules and `REQUIREMENT.md` sit outside the density scope rather than being exempted here, since a rule is one imperative per bullet.
|
|
56
58
|
|
|
57
59
|
## Cadence
|
|
58
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Markdown audit
|
|
3
|
-
description: Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why
|
|
3
|
+
description: Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, how a reference page opts into its shape check, and why bans, dead links, and density or reference shape on a gated path fail while the rest reports
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Markdown audit
|
|
@@ -11,13 +11,11 @@ description: Running the audit over any markdown path, where its bans and checkp
|
|
|
11
11
|
canon markdown audit
|
|
12
12
|
canon markdown audit --json
|
|
13
13
|
canon markdown audit .claude/rules governance
|
|
14
|
-
canon markdown audit docs/agents/
|
|
14
|
+
canon markdown audit docs/agents/install-and-sync.md
|
|
15
15
|
canon markdown audit 'docs/**/*.md'
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
| -------- | ---------------------------------------------------------- |
|
|
20
|
-
| `--json` | Add a machine-readable record on stdout, keeping the frame |
|
|
18
|
+
Run `canon markdown audit --help` for every flag.
|
|
21
19
|
|
|
22
20
|
## Scope
|
|
23
21
|
|
|
@@ -65,15 +63,25 @@ The heading-case measure reports a heading or a frontmatter `title` with a capit
|
|
|
65
63
|
|
|
66
64
|
`CHANGELOG.md` is exempt from both, since the release tool writes its headings.
|
|
67
65
|
|
|
66
|
+
### Density
|
|
67
|
+
|
|
68
|
+
The six layout limits, their scope, and their gate are in `markdown-audit-density.md`.
|
|
69
|
+
|
|
70
|
+
### Reference shape
|
|
71
|
+
|
|
72
|
+
A page opts in with `kind: reference` in its frontmatter, and an unmarked page is never measured. On a marked page, outside fences, an H2 other than `Output`, `Refusals`, or `See also` reports, as does one repeated or out of that order, any H3, and a table headed `Flag` or `Option`.
|
|
73
|
+
|
|
74
|
+
Each finding sits under `referenceShape` in the `--json` entry with `kind`, `line`, `text`, and `gating`. It gates under the prefixes density gates on.
|
|
75
|
+
|
|
68
76
|
### Weight, cadence, and length
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
The Bullets, Paragraphs, Cadence, Depth, and Length sections report and never set the exit. The bullet and paragraph numbers gate through the density lengths instead, and depth and cadence stay a judgment a reader settles. What each section measures and the samples behind its checkpoint are in `markdown-audit-weight.md`.
|
|
71
79
|
|
|
72
80
|
## Exit codes
|
|
73
81
|
|
|
74
|
-
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, `2` for a ban hit
|
|
82
|
+
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, `2` for a ban hit, a dead relative link, or a density or reference shape finding marked `gating`, and `3` for a shipped ban set that arrived empty. All three are facts a scan settles rather than a reader judging. Depth weight is a judgment a reader settles, and cadence is a distribution whose healthy range moves with the surface, so both report under every code, as do the advisory Bullets and Paragraphs sections. 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
83
|
|
|
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
|
|
84
|
+
`3` is separate from `1` because the two want different responses from a caller. A refusal means no corpus was built, and the `Markdown` 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
85
|
|
|
78
86
|
`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
87
|
|
|
@@ -83,8 +91,6 @@ Of the five measures a first full reading took, the ban count is the only one a
|
|
|
83
91
|
|
|
84
92
|
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
93
|
|
|
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
94
|
### What a hit asks of an author
|
|
89
95
|
|
|
90
96
|
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.
|
|
@@ -95,7 +101,7 @@ A hit the closed set could not separate from correct prose was the case with no
|
|
|
95
101
|
|
|
96
102
|
### Where the rules are enforced
|
|
97
103
|
|
|
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
|
|
104
|
+
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` 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
105
|
|
|
100
106
|
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
107
|
|
|
@@ -105,7 +111,7 @@ The target push stage excludes `CHANGELOG.md`, unlike every other surface here.
|
|
|
105
111
|
|
|
106
112
|
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
113
|
|
|
108
|
-
It
|
|
114
|
+
It relays every density finding from the same record, gating or not, and the two advisory measures. 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
115
|
|
|
110
116
|
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
117
|
|
|
@@ -122,5 +128,3 @@ The verb reads the `markdown-craft` skill's reference and the `write-human` cade
|
|
|
122
128
|
`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
129
|
|
|
124
130
|
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.
|