@erclx/canon 5.34.0 → 5.36.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 +15 -17
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/REQUIREMENT.md +1 -1
- package/claude/skills/auto-ship/references/draft-mark.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +12 -12
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +2 -2
- package/claude/skills/canvas-board/references/design.md +53 -36
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -1
- package/claude/skills/codebase-layout/SKILL.md +2 -2
- package/claude/skills/create-rule/REQUIREMENT.md +6 -8
- package/claude/skills/create-rule/SKILL.md +8 -8
- package/claude/skills/create-rule/references/rule.md +11 -23
- package/claude/skills/create-skill/SKILL.md +2 -1
- package/claude/skills/create-skill/references/skill-paths.md +12 -15
- package/{standards/standard.md → claude/skills/create-skill/references/skill-reference.md} +50 -45
- package/claude/skills/create-skill/references/skill.md +9 -3
- package/claude/skills/design-taste/REQUIREMENT.md +6 -6
- package/claude/skills/design-taste/SKILL.md +2 -2
- package/claude/skills/design-taste/references/craft.md +1 -1
- package/claude/skills/design-taste/references/preflight.md +2 -2
- package/claude/skills/design-taste/references/tells.md +1 -1
- package/claude/skills/draft-and-pick/SKILL.md +1 -1
- package/claude/skills/draft-identity/SKILL.md +3 -2
- package/claude/skills/git-commit/references/versioning.md +13 -13
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/markdown-craft/references/markdown.md +3 -2
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/review-address/REQUIREMENT.md +1 -1
- package/claude/skills/review-address/SKILL.md +2 -2
- package/claude/skills/review-craft/references/ui.md +1 -1
- package/claude/skills/review-pr/SKILL.md +3 -3
- package/claude/skills/review-pr/references/post.md +1 -1
- package/claude/skills/review-ui/REQUIREMENT.md +1 -1
- package/claude/skills/review-ui/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +2 -2
- package/claude/skills/role-orchestrator/SKILL.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +3 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -8
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +10 -4
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +12 -15
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +6 -4
- package/claude/skills/role-orchestrator/scripts/poll.ts +50 -1
- package/claude/skills/role-reviewer/REQUIREMENT.md +17 -7
- package/claude/skills/role-reviewer/SKILL.md +17 -10
- package/claude/skills/role-worker/REQUIREMENT.md +1 -1
- package/claude/skills/role-worker/SKILL.md +6 -6
- package/claude/skills/session-compact/references/handoff-note.md +1 -1
- package/claude/skills/target-setup/SKILL.md +2 -2
- package/claude/skills/target-setup/references/detect.md +3 -3
- package/claude/skills/test-craft/SKILL.md +2 -2
- package/claude/skills/ux-audit/REQUIREMENT.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +2 -2
- package/claude/skills/ux-measure/REQUIREMENT.md +1 -1
- package/claude/skills/write-human/references/machine-tells.md +12 -0
- package/docs/agents/audits.md +1 -1
- package/docs/agents/commands.md +14 -13
- package/docs/agents/comments.md +1 -1
- package/docs/agents/counts.md +5 -6
- package/docs/agents/drift-surfaces.md +15 -19
- package/docs/agents/gov-detect.md +1 -1
- package/docs/agents/index.md +2 -3
- package/docs/agents/install-and-sync.md +10 -34
- package/docs/agents/markdown-audit.md +22 -12
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/output-shape.md +1 -1
- package/docs/agents/overview.md +2 -2
- package/docs/agents/records-stale.md +1 -1
- package/docs/agents/records-validate.md +11 -23
- package/docs/agents/records.md +1 -1
- package/docs/agents/routing.md +1 -1
- package/docs/agents/rule-citations.md +9 -17
- package/docs/agents/scripting.md +2 -20
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/tasks-validate.md +1 -1
- package/docs/agents/teach.md +1 -1
- package/docs/target/index.md +1 -0
- package/docs/target/migrations.md +4 -0
- package/docs/target/projects.md +10 -10
- package/docs/target/scenarios.md +5 -6
- package/docs/target/standards-moved.md +32 -0
- package/docs/target/sync.md +5 -5
- package/docs/workflow/ai-workflow.md +1 -1
- package/docs/workflow/operating-model.md +16 -18
- package/docs/workflow/skill-map.md +1 -1
- package/docs/workflow/visual-design-workflow.md +3 -3
- package/governance/detect.toml +32 -36
- package/governance/renames.toml +44 -1
- package/governance/rules/lib/{305-e2e-reliability.md → e2e-reliability.md} +1 -1
- package/governance/rules/lib/{306-test-scope.md → test-scope.md} +2 -2
- package/governance/rules/ui/{410-a11y.md → a11y.md} +1 -1
- package/governance/rules/ui/{440-surface-capture.md → surface-capture.md} +3 -3
- package/governance/stacks/base.toml +15 -8
- package/governance/stacks/go.toml +2 -0
- package/governance/stacks/node.toml +1 -1
- package/governance/stacks/php.toml +2 -0
- package/governance/stacks/python.toml +1 -1
- package/package.json +1 -4
- package/scripts/core/install-check.sh +4 -10
- package/src/audits/catalog.ts +0 -9
- package/src/capture/frame-values.ts +3 -6
- package/src/claude/routing.ts +1 -1
- package/src/claude/skills-reach.ts +4 -6
- package/src/cli/help-all.ts +96 -0
- package/src/cli/help.ts +29 -29
- package/src/cli.ts +8 -3
- package/src/commands/claude.ts +29 -0
- package/src/commands/design.ts +22 -1
- package/src/commands/gov.ts +29 -11
- package/src/commands/init.ts +10 -1
- package/src/commands/labels.ts +4 -44
- package/src/commands/markdown.ts +96 -3
- package/src/commands/migrate.ts +1 -1
- package/src/commands/records.ts +5 -21
- package/src/commands/sync.ts +11 -0
- package/src/commands/tooling.ts +10 -4
- package/src/counts/catalogs.ts +0 -6
- package/src/design/budget.ts +14 -10
- package/src/design/document.ts +5 -5
- package/src/design/parse.ts +21 -4
- package/src/design/render.ts +3 -3
- package/src/gate/boundaries.ts +2 -2
- package/src/gate/measures.ts +7 -29
- package/src/gate/sequencer.ts +51 -2
- package/src/gate/stages.ts +0 -18
- package/src/gov/citations.ts +16 -71
- package/src/gov/stacks.ts +3 -3
- package/src/inventory/subjects.ts +1 -1
- package/src/markdown/bans.ts +1 -1
- package/src/markdown/ceiling.ts +6 -1
- package/src/markdown/colons.ts +86 -0
- package/src/markdown/gate.ts +15 -0
- package/src/markdown/heading-case.ts +74 -0
- package/src/migrate/scratch-evidence.ts +2 -2
- package/src/records/validate.ts +6 -194
- package/src/sandbox/provision.ts +0 -5
- package/src/secrets/shipped.ts +1 -2
- package/src/serve/static.ts +1 -2
- package/src/shipped/references.ts +42 -93
- package/src/sync/check.ts +18 -14
- package/src/sync/copy.ts +4 -5
- package/src/tooling/inject.ts +6 -37
- package/src/tooling/read.ts +2 -3
- package/src/tooling/scan.ts +4 -17
- package/src/tooling/subfolder.ts +2 -66
- package/tooling/astro/manifest.toml +0 -1
- package/tooling/astro/reference.md +0 -8
- package/tooling/base/configs/scripts/verify.json +1 -1
- package/tooling/base/configs/scripts/verify.ts +22 -17
- package/tooling/base/manifest.toml +7 -7
- package/tooling/base/reference.md +19 -32
- package/tooling/base/seeds/.github/workflows/verify.yml +0 -9
- package/tooling/base/seeds/.lintstagedrc +2 -4
- package/tooling/base/seeds/canon/context/ci.md +4 -6
- package/tooling/base/seeds/canon/context/development.md +2 -2
- package/tooling/claude/reference.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +13 -1
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +1 -1
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +27 -2
- package/tooling/claude/seeds/CLAUDE.md +1 -1
- package/tooling/claude/seeds/canon/DESIGN.md +24 -37
- package/tooling/go/reference.md +1 -1
- package/tooling/php/reference.md +1 -1
- package/tooling/python/reference.md +2 -2
- package/tooling/shell/configs/.github/workflows/shell.yml +30 -0
- package/tooling/shell/manifest.toml +12 -0
- package/tooling/shell/reference.md +46 -0
- package/tooling/vite-react/manifest.toml +0 -1
- package/tooling/vite-react/reference.md +0 -8
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +3 -5
- package/tooling/web/configs/.github/workflows/verify.yml +0 -9
- package/tooling/web/manifest.toml +1 -2
- package/tooling/web/reference.md +4 -6
- package/docs/agents/standards-audit.md +0 -40
- package/governance/rules/tooling/765-spelling.md +0 -19
- package/governance/stacks/astro.toml +0 -2
- package/governance/stacks/nextjs.toml +0 -2
- package/governance/stacks/node-server.toml +0 -2
- package/governance/stacks/python-fastapi.toml +0 -2
- package/governance/stacks/react.toml +0 -2
- package/src/commands/standards.ts +0 -278
- package/src/labels/spelling.ts +0 -120
- package/src/standards/audit.ts +0 -146
- package/src/standards/list.ts +0 -33
- package/src/standards/read.ts +0 -177
- package/src/standards/scope.ts +0 -56
- package/standards/index.md +0 -10
- package/tooling/base/configs/.vscode/extensions.json +0 -9
- package/tooling/base/configs/.vscode/settings.json +0 -3
- package/tooling/base/configs/scripts/verify.sh +0 -2
- package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +0 -25
- package/tooling/base/seeds/cspell.json +0 -20
- package/tooling/go/seeds/.cspell/tech-stack.txt +0 -16
- package/tooling/nextjs/seeds/.cspell/tech-stack.txt +0 -3
- package/tooling/php/seeds/.cspell/tech-stack.txt +0 -5
- package/tooling/python/seeds/.cspell/tech-stack.txt +0 -18
- package/tooling/vite-react/seeds/.cspell/project-terms.txt +0 -1
- package/tooling/vite-react/seeds/.cspell/tech-stack.txt +0 -2
- package/tooling/web/configs/.vscode/extensions.json +0 -13
- package/tooling/web/configs/.vscode/settings.json +0 -10
- package/tooling/web/seeds/.cspell/tech-stack.txt +0 -21
- /package/governance/rules/canon/{606-git.md → git.md} +0 -0
- /package/governance/rules/canon/{611-indexes.md → indexes.md} +0 -0
- /package/governance/rules/canon/{604-scratch.md → scratch.md} +0 -0
- /package/governance/rules/canon/{602-tasks.md → task-scope.md} +0 -0
- /package/governance/rules/canon/{605-worktrees.md → worktrees.md} +0 -0
- /package/governance/rules/claude/{566-output.md → output.md} +0 -0
- /package/governance/rules/code/{000-code.md → routing.md} +0 -0
- /package/governance/rules/code/{010-testing.md → testing.md} +0 -0
- /package/governance/rules/framework/{210-astro.md → astro.md} +0 -0
- /package/governance/rules/framework/{220-fastapi.md → fastapi.md} +0 -0
- /package/governance/rules/framework/{230-nextjs.md → nextjs.md} +0 -0
- /package/governance/rules/framework/{200-react.md → react.md} +0 -0
- /package/governance/rules/framework/{260-shadcn.md → shadcn.md} +0 -0
- /package/governance/rules/framework/{250-tailwind.md → tailwind.md} +0 -0
- /package/governance/rules/lang/{130-go.md → go.md} +0 -0
- /package/governance/rules/lang/{140-php.md → php.md} +0 -0
- /package/governance/rules/lang/{110-python.md → python.md} +0 -0
- /package/governance/rules/lang/{100-typescript.md → typescript.md} +0 -0
- /package/governance/rules/lib/{370-database.md → database.md} +0 -0
- /package/governance/rules/lib/{340-pydantic.md → pydantic.md} +0 -0
- /package/governance/rules/lib/{360-security-server.md → security-server.md} +0 -0
- /package/governance/rules/lib/{350-security-web.md → security-web.md} +0 -0
- /package/governance/rules/lib/{320-tanstack-query.md → tanstack-query.md} +0 -0
- /package/governance/rules/lib/{335-testing-go.md → testing-go.md} +0 -0
- /package/governance/rules/lib/{336-testing-php.md → testing-php.md} +0 -0
- /package/governance/rules/lib/{330-testing-py.md → testing-py.md} +0 -0
- /package/governance/rules/lib/{300-testing-ts.md → testing-ts.md} +0 -0
- /package/governance/rules/lib/{310-zod.md → zod.md} +0 -0
- /package/governance/rules/tooling/{700-ci-workflow.md → ci-workflow.md} +0 -0
- /package/governance/rules/tooling/{790-code-comments.md → code-comments.md} +0 -0
- /package/governance/rules/tooling/{780-config-comments.md → config-comments.md} +0 -0
- /package/governance/rules/tooling/{775-dependencies.md → dependencies.md} +0 -0
- /package/governance/rules/ui/{480-canvas.md → canvas.md} +0 -0
- /package/governance/rules/ui/{400-ui.md → copy.md} +0 -0
- /package/governance/rules/ui/{460-design-taste.md → design-taste.md} +0 -0
- /package/governance/rules/ui/{420-forms.md → forms.md} +0 -0
- /package/governance/rules/ui/{465-interface-casing.md → interface-casing.md} +0 -0
- /package/governance/rules/ui/{450-link-behavior.md → link-behavior.md} +0 -0
- /package/governance/rules/ui/{470-motion.md → motion.md} +0 -0
- /package/governance/rules/ui/{430-ux-completeness.md → ux-completeness.md} +0 -0
- /package/tooling/{base → shell}/configs/.editorconfig +0 -0
- /package/tooling/{base → shell}/configs/.shellcheckrc +0 -0
|
@@ -5,14 +5,14 @@ description: Running the audit over any markdown path, where its bans and checkp
|
|
|
5
5
|
|
|
6
6
|
# Markdown audit
|
|
7
7
|
|
|
8
|
-
`canon markdown audit [path...]` reports any markdown file against the
|
|
8
|
+
`canon markdown audit [path...]` reports any markdown file against the `markdown-craft` skill's `markdown.md` reference. That reference governs a file rather than a folder, so this resolves no folder and requires no `index.md`, which is what puts `.claude/rules/` and `governance/` in reach. Folder-shaped findings stay in `canon context audit`, described in `context-audit.md`.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
canon markdown audit
|
|
12
12
|
canon markdown audit --json
|
|
13
13
|
canon markdown audit .claude/rules governance
|
|
14
14
|
canon markdown audit docs/agents/commands.md
|
|
15
|
-
canon markdown audit '
|
|
15
|
+
canon markdown audit 'docs/**/*.md'
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
| Option | Behavior |
|
|
@@ -27,29 +27,27 @@ A bare run measures every markdown file git lists, tracked plus untracked-and-no
|
|
|
27
27
|
|
|
28
28
|
## Where the rules come from
|
|
29
29
|
|
|
30
|
-
The ban set and all ten checkpoints ship with the `canon` package as data, in `src/markdown/bans.ts` and `src/markdown/structure.ts`. Every project is measured against the same set whether or not it installed
|
|
30
|
+
The ban set and all ten checkpoints ship with the `canon` package as data, in `src/markdown/bans.ts` and `src/markdown/structure.ts`. Every project is measured against the same set whether or not it installed the plugin, and no file has to resolve for a run to mean something.
|
|
31
31
|
|
|
32
32
|
Seven of the ten are stated in `markdown.md` and the three cadence numbers are stated in the `write-human` skill. That split is the content boundary rather than an accident: `markdown.md` carries the enforced rules a scan can decide, and the skill carries the rhythm rules a ban list cannot express. A cadence number moved in the skill and left in the code drifts the same way, so move both.
|
|
33
33
|
|
|
34
|
-
Reading them out of the
|
|
34
|
+
Reading them out of the reference per run was the original design. It put a parser contract on a document authored for people, and the reference had to carry a paragraph of its own warning an author that a one-word backticked example in a `- Do not use ` bullet would be lifted into a literal ban set and ban that word everywhere. A rule existing to protect a parser from the prose it parses is the argument for separating them.
|
|
35
35
|
|
|
36
36
|
`markdown.md` still states every ban and every checkpoint, and a reader follows it rather than the code. Nothing compares the two, so a number moved in one place and left in the other drifts silently. Move both in the same change.
|
|
37
37
|
|
|
38
|
-
The set is closed rather than extensible, so a project cannot add a term by editing a file. It holds the two characters alone, since a character is the one class a literal match settles. The set once carried 13 words and 6 British spellings as well. The words moved to the `write-human` skill as guidance, because a word ban catches the token and misses the habit, and `just`, `allows`, and `very` carry honest uses no literal match separates. Spelling
|
|
38
|
+
The set is closed rather than extensible, so a project cannot add a term by editing a file. It holds the two characters alone, since a character is the one class a literal match settles. The set once carried 13 words and 6 British spellings as well. The words moved to the `write-human` skill as guidance, because a word ban catches the token and misses the habit, and `just`, `allows`, and `very` carry honest uses no literal match separates. Spelling is left to the author, with American spelling carried as guidance in `markdown-craft`.
|
|
39
39
|
|
|
40
40
|
A set shipped empty is reported rather than passed. It finds nothing and would exit clean, which reports a corpus nobody checked as a corpus carrying no violation, so the run names the empty set and exits `3`. The set ships with the package, so a defect in the build is the only cause left.
|
|
41
41
|
|
|
42
|
-
`canon standards <name>` still resolves a standard at the authoring root, then the package corpus, and prints it, so the human catalog reads without a project copy on disk.
|
|
43
|
-
|
|
44
42
|
## What each check reports
|
|
45
43
|
|
|
46
44
|
### Bans
|
|
47
45
|
|
|
48
46
|
One closed set reports a hit: the characters `markdown.md` bans under `## Punctuation`.
|
|
49
47
|
|
|
50
|
-
Frontmatter, fenced blocks, inline code spans, and link destinations are excluded. Without the code-span exclusion each
|
|
48
|
+
Frontmatter, fenced blocks, inline code spans, and link destinations are excluded. Without the code-span exclusion each reference would report its own backticked examples, and without the link exclusion a semicolon in a query string would report as prose no rewrite can fix.
|
|
51
49
|
|
|
52
|
-
Word choice stays unmeasured and the report says so on every run. Single words travel in the `write-human` skill as guidance a reader applies. A multi-word ban escapes the harvest by width, whether it carries a placeholder standing in for the rest of the sentence or spells the phrase out in full, and every rule under `## Voice` is a judgment. The bans `## Language` states over what a sentence may claim are patterns of the multi-word kind by construction, since a literal match over a pattern reports the compliant text and reaches none of the violations. A report listing hits without naming those would read as a verdict on the whole
|
|
50
|
+
Word choice stays unmeasured and the report says so on every run. Single words travel in the `write-human` skill as guidance a reader applies. A multi-word ban escapes the harvest by width, whether it carries a placeholder standing in for the rest of the sentence or spells the phrase out in full, and every rule under `## Voice` is a judgment. The bans `## Language` states over what a sentence may claim are patterns of the multi-word kind by construction, since a literal match over a pattern reports the compliant text and reaches none of the violations. A report listing hits without naming those would read as a verdict on the whole reference.
|
|
53
51
|
|
|
54
52
|
### Links
|
|
55
53
|
|
|
@@ -57,6 +55,16 @@ A relative link's destination resolves against the filesystem, over the same cor
|
|
|
57
55
|
|
|
58
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.
|
|
59
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
|
+
|
|
60
68
|
### Weight, cadence, and length
|
|
61
69
|
|
|
62
70
|
Bullet and paragraph weight, 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`.
|
|
@@ -97,20 +105,22 @@ The target push stage excludes `CHANGELOG.md`, unlike every other surface here.
|
|
|
97
105
|
|
|
98
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.
|
|
99
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
|
+
|
|
100
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.
|
|
101
111
|
|
|
102
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.
|
|
103
113
|
|
|
104
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.
|
|
105
115
|
|
|
106
|
-
The stage measures the whole corpus rather than the changed files. A `Do not use` bullet added to a
|
|
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.
|
|
107
117
|
|
|
108
118
|
## What it does not cover
|
|
109
119
|
|
|
110
|
-
The verb reads the
|
|
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.
|
|
111
121
|
|
|
112
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.
|
|
113
123
|
|
|
114
|
-
That
|
|
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.
|
|
115
125
|
|
|
116
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.
|
package/docs/agents/migrate.md
CHANGED
|
@@ -25,7 +25,7 @@ Every citation in scope is reported with its file, its line number, and the line
|
|
|
25
25
|
|
|
26
26
|
`migrate rule-layout` moves a target still on the flat installed-rule layout onto the `canon/`-wrapped one. It classifies each flat file against the target's own recorded stamp: an unchanged hash is clean, a changed one is edited, and a name neither the stamp nor the current rule catalog can vouch for is unclaimed and left in place. Clean and edited files both relocate with their content untouched, since moving a rule is a different decision from re-syncing it. The one renumbered rule reads its destination from a table rather than from its own current name, so it never lands as a second copy under the retired number.
|
|
27
27
|
|
|
28
|
-
`migrate scratch-evidence` moves a folder out of `.tmp/` for good rather than repointing a citation in place. A promoted folder is one a durable record, live or archived, cites as its evidence, and no source file under `claude/`, `scripts/`, `src/`,
|
|
28
|
+
`migrate scratch-evidence` moves a folder out of `.tmp/` for good rather than repointing a citation in place. A promoted folder is one a durable record, live or archived, cites as its evidence, and no source file under `claude/`, `scripts/`, `src/`, or `governance/` names by path, which is what a script still writing into it fails. It walks every `canon records push` folder rather than the live ones alone, since most of what it repoints sits in `tasks/archive/`, `plans/archive/`, and `groundwork/`. A destination already occupied is a refusal, and a second run rewriting nothing is the same idempotence check `migrate record-tree` uses.
|
|
29
29
|
|
|
30
30
|
A destination that already holds the same bytes marks the flat file a duplicate, which `--write` deletes rather than moves. One holding different bytes is a real collision: neither file is touched, it is reported by name, and every other planned move still applies independently. Run this before `canon gov install` or `canon gov sync` against a target still on the flat layout, since neither bootstrap verb detects or clears it on its own.
|
|
31
31
|
|
|
@@ -40,7 +40,7 @@ Rules:
|
|
|
40
40
|
└
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Help skips the banner. The `Usage:` line sits directly on `├`. Help writes to stdout because `--help` is documentation, not runtime UI.
|
|
43
|
+
Help skips the banner. The `Usage:` line sits directly on `├`. Help writes to stdout because `--help` is documentation, not runtime UI. `--help --all` on a command prints each block unframed, one after another, and a help request naming an unknown subcommand, under a group that takes no operand of its own, writes its refusal to stderr and exits 1.
|
|
44
44
|
|
|
45
45
|
## JSON and `--names` modes
|
|
46
46
|
|
package/docs/agents/overview.md
CHANGED
|
@@ -11,7 +11,7 @@ This folder is an index of what an agent can run and how to run it cleanly from
|
|
|
11
11
|
|
|
12
12
|
## Invocation rules
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
`output-shape.md` holds the stream and exit contract. It applies to every command in this folder.
|
|
15
15
|
|
|
16
16
|
## Where to start
|
|
17
17
|
|
|
@@ -21,6 +21,6 @@ See `CLAUDE.md` design principles. They apply to every command in this folder.
|
|
|
21
21
|
|
|
22
22
|
## Related
|
|
23
23
|
|
|
24
|
-
- `CLAUDE.md`: project behaviors
|
|
24
|
+
- `CLAUDE.md`: project behaviors
|
|
25
25
|
- `.claude/skills/internal-*`: domain-scoped guidance for editing work, in the toolkit checkout only
|
|
26
26
|
- `docs/index.md`: full docs directory
|
|
@@ -25,7 +25,7 @@ It reports and never writes, matching `validate` and `size`.
|
|
|
25
25
|
|
|
26
26
|
`canonical` reads `REQUIREMENTS.md` at whichever surface root carries it, `canon/` ahead of `.claude/`, and omits it when the project does not hold one. It is tracked, so `--root` defaults to the worktree the caller stands in rather than the main one, and a stamp a branch just wrote reads back from that branch.
|
|
27
27
|
|
|
28
|
-
The review point is an optional `reviewed: YYYY-MM-DD` frontmatter field, set by whoever finishes a review, per `
|
|
28
|
+
The review point is an optional `reviewed: YYYY-MM-DD` frontmatter field, set by whoever finishes a review, per `claude/skills/draft-doc/references/requirements.md`. It is a date rather than a commit, since a commit written on a feature branch never reaches a trunk that squash-merges. The field is read off the raw frontmatter block rather than a parsed value, since a YAML parser resolves a bare date to a date object on one schema and a string on another. A value that is not a calendar date reads as never reviewed, and the record carries the raw value as `invalidReviewed` so a review can see it rather than the verb throwing over one hand edit.
|
|
29
29
|
|
|
30
30
|
The count is every release tag merged into `HEAD` whose creator date falls after the reviewed day. A release tag ends in a dotted version, bare as `v5.25.0` or behind a component prefix as `canon-v2.1.0`, so an eval, deploy, or snapshot tag on the trunk never inflates it. A lightweight tag's creator date is its commit's date and an annotated tag's is the tagging date, so a project mixing both counts by two clocks.
|
|
31
31
|
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Records validate
|
|
3
|
-
description: Validating the session records
|
|
3
|
+
description: Validating the session records, the per-kind checks, which root they default to, the exit codes, and the refusal reasons
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Records validate
|
|
7
7
|
|
|
8
|
-
`canon records validate <kind>` reports where a file and the standard governing it disagree. Four kinds
|
|
8
|
+
`canon records validate <kind>` reports where a file and the standard governing it disagree. Four kinds exist, each a gitignored folder under the record root resolved at `.canon/` first: `plans`, `groundwork`, `intake`, and `teach`.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
canon records validate plans
|
|
12
|
-
canon records validate standards
|
|
13
12
|
canon records validate intake --json
|
|
14
13
|
```
|
|
15
14
|
|
|
16
|
-
| Option | Behavior
|
|
17
|
-
| --------------- |
|
|
18
|
-
| `--json` | Add a machine-readable record on stdout
|
|
19
|
-
| `--root <path>` | Project root, defaulting to the main worktree
|
|
15
|
+
| Option | Behavior |
|
|
16
|
+
| --------------- | --------------------------------------------- |
|
|
17
|
+
| `--json` | Add a machine-readable record on stdout |
|
|
18
|
+
| `--root <path>` | Project root, defaulting to the main worktree |
|
|
20
19
|
|
|
21
|
-
It reads and never writes
|
|
20
|
+
It reads and never writes. A session record is per-machine scratch with no history behind it, so a repair that guessed wrong could not be undone.
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Nothing fires it automatically. The four record folders are gitignored, so the standards-audit hook exits early on them and any check reading changed files from git never lists one. The corpus is tracked and still unreached, since the markdown audit reads content across the files git lists and rules on no filename. The verb runs at the moment a session claims the record is finished, which is the same placement `canon tasks validate` takes over the board.
|
|
22
|
+
Nothing fires it automatically. The four record folders are gitignored, so the standards-audit hook exits early on them and any check reading changed files from git never lists one. The verb runs at the moment a session claims the record is finished, which is the same placement `canon tasks validate` takes over the board.
|
|
26
23
|
|
|
27
24
|
The two record roots every kind resolves at are in `records.md`.
|
|
28
25
|
|
|
@@ -33,37 +30,28 @@ The two record roots every kind resolves at are in `records.md`.
|
|
|
33
30
|
| `plans` | A filename that is not `feature-<slug>.md`, a missing `# Feature:` heading, a missing required section, a files-to-touch entry naming no file or saying nothing about one, a question carrying no suggestion or no answer slot, and a batch still staged with a `**Batch N**` sub-heading inside the one file rather than split into its own plan |
|
|
34
31
|
| `groundwork` | A track with no `README.md` or no `01-current-state.md`, a file missing `title` or `description`, a `README.md` with no `date` as `YYYY-MM-DD`, an unnumbered file, and a track holding a decision without its handoff or the reverse |
|
|
35
32
|
| `intake` | A dump with no `00-overview.md`, the same frontmatter and numbering checks, an item missing any of `Problem`, `Fix`, `Worth it`, or `You`, and an item carrying `Open` with no `Suggested` |
|
|
36
|
-
| `standards` | A standard missing `title` or `description`, an absent `## Scope` section, a scope section carrying no `Does not govern:` list, a statement anchoring nothing, and a filename naming no part of the path the statement governs |
|
|
37
33
|
| `teach` | A workspace folder carrying no two-digit ordinal, an absent `MISSION.md`, `RESOURCES.md`, or `GLOSSARY.md`, a file missing `title` or `description`, a mission with no `date` as `YYYY-MM-DD` or no `## Success looks like` section, an unnumbered learning record, and a reference page opening with an ordinal |
|
|
38
34
|
|
|
39
35
|
The half-closed track is the groundwork check a reader cannot run by eye. A folder holding `06` without `07` reads as closed to anyone scanning filenames while the file a returning session actually opens is absent.
|
|
40
36
|
|
|
41
37
|
The item check skips `00-overview.md` and `99-next-session.md`, since neither holds items and running it over the handoff would report every heading it carries.
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
The scope statement is read exactly as `canon standards list` reads it for the catalog's `appliesTo` field: backticked spans in the first sentence alone, with an attribute standard resolving where that sentence backticks nothing and the statement says it governs an attribute. One sentence read two ways would let a standard pass the check while publishing a different jurisdiction to every consumer of the catalog. An attribute standard is exempt from the filename derivation because it governs no path to derive from, and a statement that anchors nothing and claims no attribute is reported as `scope-unanchored` rather than passed, since silence there would let the backticks be removed to disable the check.
|
|
46
|
-
|
|
47
|
-
An absent `## Scope` section suppresses the filename finding. The name derives from the statement, so a missing section leaves nothing to derive against, and reporting both would name one defect twice and point the fix at the wrong file. The walk skips `index.md`, which is generated from its siblings rather than authored.
|
|
48
|
-
|
|
49
|
-
A plan section opens as a bold label or as an H2 and the check counts both, naming the standard's spelling when it reports one missing. The corpus splits roughly four to one between the two forms, so failing the variant would report nearly every plan on a rule that costs a reader nothing.
|
|
39
|
+
A plan section opens as a bold label or as an H2 and the check counts both, naming the reference's spelling when it reports one missing. Plans split roughly four to one between the two forms, so failing the variant would report nearly every plan on a rule that costs a reader nothing.
|
|
50
40
|
|
|
51
41
|
A section runs to the next marker-shaped line whatever it names, so a plan carrying a label of its own closes the section above it rather than collecting into it. Fenced blocks are dropped before any of this, since a plan showing the shape it writes puts real-looking bullets and headings inside a fence.
|
|
52
42
|
|
|
53
43
|
## Exit codes and refusals
|
|
54
44
|
|
|
55
|
-
Exit codes: `0` every check passed, `1` refused, `2` at least one record carries a finding. A `reason` field carries which gate fired: `no-folder` when none of the kind's directories exist, and `unknown-kind` when the argument names no published kind. A `no-folder` message names every candidate, so a
|
|
45
|
+
Exit codes: `0` every check passed, `1` refused, `2` at least one record carries a finding. A `reason` field carries which gate fired: `no-folder` when none of the kind's directories exist, and `unknown-kind` when the argument names no published kind. A `no-folder` message names every candidate, so a refusal names both record roots.
|
|
56
46
|
|
|
57
47
|
An exit code says nothing about a call made from a session, since a shell profile may wrap the binary in a function taking its status from a later command. Read the record's `findings` array and its `reason` rather than the exit when a skill consumes this.
|
|
58
48
|
|
|
59
49
|
The four record folders are shared scratch at the main worktree root, so `--root` defaults to the first entry of `git worktree list` rather than the working directory. A linked worktree validates the same records every other session reads.
|
|
60
50
|
|
|
61
|
-
`standards` takes the other default, the root of the checkout the caller stands in. The corpus is tracked, so a linked worktree holds its own edited copy, and resolving the main root there would report on a tree the session never touched while saying nothing about which one it read. A session that adds or renames a standard inside a worktree is the case, and it is the one the check exists for.
|
|
62
|
-
|
|
63
51
|
Skills branch on the findings rather than on the exit code:
|
|
64
52
|
|
|
65
53
|
```bash
|
|
66
54
|
canon records validate plans --json | jq -r '.findings[] | "\(.kind): \(.subject)"'
|
|
67
55
|
```
|
|
68
56
|
|
|
69
|
-
For the shapes each check enforces, see `claude/skills/plan-feature/references/plan.md`, `claude/skills/plan-groundwork/references/groundwork.md`, `claude/skills/plan-intake/references/intake.md
|
|
57
|
+
For the shapes each check enforces, see `claude/skills/plan-feature/references/plan.md`, `claude/skills/plan-groundwork/references/groundwork.md`, and `claude/skills/plan-intake/references/intake.md`.
|
package/docs/agents/records.md
CHANGED
|
@@ -17,7 +17,7 @@ A refusal names every root it looked at, so a message reading `no-folder` says w
|
|
|
17
17
|
|
|
18
18
|
## Validate
|
|
19
19
|
|
|
20
|
-
`canon records validate <kind>` reports where a record folder
|
|
20
|
+
`canon records validate <kind>` reports where a record folder disagrees with the standard governing it. Its flags, the per-kind checks, and the refusals are in `records-validate.md`.
|
|
21
21
|
|
|
22
22
|
## Ordinal
|
|
23
23
|
|
package/docs/agents/routing.md
CHANGED
|
@@ -32,7 +32,7 @@ Three things are read past. A nested bullet belongs to the one above it rather t
|
|
|
32
32
|
|
|
33
33
|
A bullet is path-scoped here when it names a path. That is evidence for the tier judgment rather than the judgment itself, and the gap runs both ways: a bullet naming a folder can still apply every session, and one firing on a path it never spells is invisible to the count. Read a section's number as a place to look rather than as a verdict on it.
|
|
34
34
|
|
|
35
|
-
A backticked token counts when it carries a separator or an alphabetic extension, which admits `src/cli.ts` and `
|
|
35
|
+
A backticked token counts when it carries a separator or an alphabetic extension, which admits `src/cli.ts` and `tsconfig.json` while leaving a flag, a bare word, and a version string out.
|
|
36
36
|
|
|
37
37
|
A shape counts as the folder above its placeholder. `canon/context/<domain>.md` names `canon/context/` and nothing narrower, so dropping the token whole would report the section carrying it as naming no path at all. A placeholder opening the first segment has no openable prefix and is dropped.
|
|
38
38
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Rule citations
|
|
3
|
-
description: Resolving every path a governance rule cites and every frontmatter glob the internal corpus declares, the
|
|
3
|
+
description: Resolving every path a governance rule cites and every frontmatter glob the internal corpus declares, the one form a citation is written in, the shapes that look like citations and are not, the two classes where an absent path is correct, why the glob half reads one corpus, and why this one gates
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Rule citations
|
|
@@ -28,32 +28,24 @@ Under `--json` the record holds stdout alone and the frame still renders on stde
|
|
|
28
28
|
|
|
29
29
|
Two files agreeing is what a drift check measures. Whether either one is right about the tree is a different question, and this is the stage that asks it.
|
|
30
30
|
|
|
31
|
-
## The
|
|
31
|
+
## The one form
|
|
32
32
|
|
|
33
|
-
A citation reaches a reader
|
|
33
|
+
A citation reaches a reader as a backticked path, reported under the form `path`, and it resolves against the root. A bare filename is never a citation, since with no folder around it nothing tells a rule from a convention such as `index.md`. A rule pointing at another rule writes its repository path.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
| ---------- | ------------------------ | ---------------------------------- |
|
|
37
|
-
| `standard` | `canon standards <name>` | `standards/<name>.md` |
|
|
38
|
-
| `path` | a backticked path | the root |
|
|
39
|
-
| `sibling` | a bare `<nnn>-<slug>.md` | the folder the citing rule sits in |
|
|
35
|
+
A call to the retired standards verb is no form here. A rule holding one fails the shipped-references stage of `canon gate run`, which reads every shipped file for it.
|
|
40
36
|
|
|
41
|
-
`
|
|
42
|
-
|
|
43
|
-
A standard name resolves against the authoring root and nowhere else, matching `standardRoots` in `src/standards/read.ts`, which reads `standards/` at the working root and then the package corpus. The stage refuses a tree holding no rule corpus, so it runs only where those two roots are one directory. `internal/standards/` is deliberately not tried: `canon standards <name>` never reaches it, so admitting it would pass a citation that refuses for the session opening it, which is a gate failing open.
|
|
44
|
-
|
|
45
|
-
A `path` is anchored on the whole backticked span rather than on a trailing pattern inside it. Cutting `standards/tooling-reference.md` out of `internal/standards/tooling-reference.md` and resolving that against the standards root reports a file that exists as missing, which is a mistake made by hand while measuring this corpus before the stage was written.
|
|
37
|
+
A `path` is anchored on the whole backticked span rather than on a trailing pattern inside it. Cutting `tooling-reference.md` out of `internal/standards/tooling-reference.md` and resolving that against the root alone reports a file that exists as missing, which is a mistake made by hand while measuring this corpus before the stage was written.
|
|
46
38
|
|
|
47
39
|
## What is not a citation
|
|
48
40
|
|
|
49
41
|
A rule body is full of backticked spans carrying a slash, and almost none of them names a file in this tree. The stage declines four shapes outright.
|
|
50
42
|
|
|
51
|
-
- A placeholder or glob segment describes a shape rather than naming a file: `canon/context/<domain>.md`, `
|
|
52
|
-
- A bare filename names a convention: `route.ts`, `manifest.toml`, `components.json`, `playwright.config.ts`.
|
|
43
|
+
- A placeholder or glob segment describes a shape rather than naming a file: `canon/context/<domain>.md`, `app/**/route.ts`, `${CLAUDE_SKILL_DIR}/../references/<name>.md`.
|
|
44
|
+
- A bare filename names a convention: `route.ts`, `manifest.toml`, `components.json`, `playwright.config.ts`.
|
|
53
45
|
- A span carrying no file extension is a folder or a module specifier: `src/pages/`, `next/font`, `try/except`, `react-hooks/set-state-in-effect`, `oven-sh/setup-bun@v2`, `@/lib/utils`.
|
|
54
46
|
- A fenced block displays a path rather than pointing at one.
|
|
55
47
|
|
|
56
|
-
The extension test is what carries most of the separation, and it costs
|
|
48
|
+
The extension test is what carries most of the separation, and it costs the real paths that name a folder or a symlink, which this stage declines to check because nothing in the span says it is a file. Declining is the right direction for a gate, where a guess that goes wrong fails a push over prose.
|
|
57
49
|
|
|
58
50
|
## Where an absent path is correct
|
|
59
51
|
|
|
@@ -73,7 +65,7 @@ A rule under `governance/rules/` installs into a target, and its `paths:` entrie
|
|
|
73
65
|
|
|
74
66
|
`internal/rules/` ships nowhere. The tree it governs is the tree present, which makes the question answerable, and all 14 of its globs across 7 rules match at the commit this shipped on.
|
|
75
67
|
|
|
76
|
-
What that leaves unreached is a glob that matches real files and still reaches none of the work it was scoped at. `governance/rules/lib/
|
|
68
|
+
What that leaves unreached is a glob that matches real files and still reaches none of the work it was scoped at. `governance/rules/lib/e2e-reliability.md` scoped itself at `e2e/*.ts` and `e2e/**/*.ts` and now reads `**/e2e/**/*.ts`. No probe in this repository is written under `e2e/`, so the rule asking a session to watch a new guard fail never fired for the session writing guards. Resolution is mechanical and reach is a judgment about where the work happens, so only the first is here.
|
|
77
69
|
|
|
78
70
|
## The exemption marker
|
|
79
71
|
|
package/docs/agents/scripting.md
CHANGED
|
@@ -14,7 +14,6 @@ Use these to discover what's available instead of hardcoding names.
|
|
|
14
14
|
| Command | Returns |
|
|
15
15
|
| --------------------------------- | ---------------------------------------------------------------- |
|
|
16
16
|
| `canon tooling list --json` | Stacks, extends chain, dep and script counts |
|
|
17
|
-
| `canon standards list --json` | Standards docs and the paths each governs |
|
|
18
17
|
| `canon gov list --json` | Governance stacks, rule sets, evidence, and unreferenced rules |
|
|
19
18
|
| `canon gov detect --json` | Opt-in rules a target's dependencies and paths propose |
|
|
20
19
|
| `canon claude seeds list --json` | Seed doc sources with content |
|
|
@@ -28,20 +27,6 @@ Every catalog serializes through `JSON.stringify`, so a name carrying a quote
|
|
|
28
27
|
emits valid JSON. `canon tooling list` previously built
|
|
29
28
|
its output with `printf` and no escaping.
|
|
30
29
|
|
|
31
|
-
`canon standards list` carries `appliesTo` per standard, the paths that standard's
|
|
32
|
-
`## Scope` statement declares. It holds the backticked paths from the first
|
|
33
|
-
sentence of the statement, the single entry `*` for a standard governing an
|
|
34
|
-
attribute rather than a document type, and an empty array when the statement
|
|
35
|
-
declares nothing a parser can read. A consumer mapping a file to its governing
|
|
36
|
-
standards reads this rather than holding a table of its own, and reports an empty
|
|
37
|
-
array rather than skipping the standard behind it.
|
|
38
|
-
|
|
39
|
-
Each standard also carries `source`, the labeled path of the copy `canon standards
|
|
40
|
-
<name>` would read: `standards/<name>.md` for the working root and
|
|
41
|
-
`<canon>/standards/<name>.md` for the package corpus. A project's own standard
|
|
42
|
-
lists beside the package's, and one sharing a package name lists once, as the
|
|
43
|
-
project's copy.
|
|
44
|
-
|
|
45
30
|
`canon claude seeds list` reads the same plan `canon claude init` applies, so the
|
|
46
31
|
listing and the install cannot disagree. It now reports
|
|
47
32
|
`canon/context/index.md`, which `init` has always installed and the listing
|
|
@@ -94,7 +79,7 @@ CANON_NON_INTERACTIVE=1 canon tooling diff astro /path/to/project
|
|
|
94
79
|
CANON_NON_INTERACTIVE=1 canon tooling sync astro /path/to/project --write
|
|
95
80
|
|
|
96
81
|
# Install a governance stack (the stack argument is required headlessly)
|
|
97
|
-
CANON_NON_INTERACTIVE=1 canon gov install
|
|
82
|
+
CANON_NON_INTERACTIVE=1 canon gov install node --add astro,shadcn /path/to/project
|
|
98
83
|
|
|
99
84
|
# Update installed governance rules, dropping a retired .claude/GOV.md
|
|
100
85
|
CANON_NON_INTERACTIVE=1 canon gov sync /path/to/project
|
|
@@ -116,11 +101,8 @@ canon tooling inject base /path/to/project --configs --seeds
|
|
|
116
101
|
# Prints the number removed on stdout, diagnostics on stderr
|
|
117
102
|
canon tooling prune-gitignore base /path/to/project
|
|
118
103
|
|
|
119
|
-
# Print one standard. Nothing installs the corpus, so this is how a target reads one
|
|
120
|
-
CANON_NON_INTERACTIVE=1 canon standards slug >slug.md
|
|
121
|
-
|
|
122
104
|
# Bootstrap a project. Any flag suppresses the confirmation prompt
|
|
123
|
-
CANON_NON_INTERACTIVE=1 canon init --stack
|
|
105
|
+
CANON_NON_INTERACTIVE=1 canon init --stack node --skip wiki /path/to/project
|
|
124
106
|
|
|
125
107
|
# Run every domain sync. The git workflow is refused headlessly, so nothing is pushed
|
|
126
108
|
CANON_NON_INTERACTIVE=1 canon sync /path/to/project
|
|
@@ -24,7 +24,7 @@ canon secrets scan ../my-app
|
|
|
24
24
|
|
|
25
25
|
The corpus is the package's own `files` field rather than a list the check keeps. That field is the single statement of which trees leave this repository, so a second list beside it would answer the same question and drift. It also carries the negations the publish already makes, which is what puts the eval tree and every test file out of scope by the rule that keeps them out of the tarball rather than by an exclusion this check invented. The sandbox tree sits under no `files` entry at all, so the same field leaves it out without a negation.
|
|
26
26
|
|
|
27
|
-
The plugin reaches a target by a different route, loading live from `claude/` rather than from a tarball. That folder is a `files` entry too,
|
|
27
|
+
The plugin reaches a target by a different route, loading live from `claude/` rather than from a tarball. That folder is a `files` entry too, so both routes land inside the same corpus.
|
|
28
28
|
|
|
29
29
|
Three root files are read whether or not the field names them, being `package.json`, the readme, and the license, since npm packs those on every publish. A negation still removes one, because a field that excludes a file outranks the default that included it.
|
|
30
30
|
|
|
@@ -130,4 +130,4 @@ Skills branch on the findings rather than on the exit code:
|
|
|
130
130
|
canon tasks validate --json | jq -r '.findings[] | "\(.kind): \(.subject)"'
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
The `task-board` skill's `board.md` and `tasks.md` references carry the board format, the `Pull request:` line, and the archive rules.
|
package/docs/agents/teach.md
CHANGED
|
@@ -81,7 +81,7 @@ canon teach resource regular-expressions \
|
|
|
81
81
|
| `--json` | Emit a machine-readable record on stdout |
|
|
82
82
|
| `--root <path>` | Teach root, defaulting to the main worktree |
|
|
83
83
|
|
|
84
|
-
The pair splits on the first `=`, so a URL carrying its own separator survives intact. Say in the title which claims rest on the source, since the entry is the only place a later session reads that from. Which sources qualify is the source ladder in `
|
|
84
|
+
The pair splits on the first `=`, so a URL carrying its own separator survives intact. Say in the title which claims rest on the source, since the entry is the only place a later session reads that from. Which sources qualify is the source ladder in `claude/skills/teach-workspace/references/teach.md`, and a source below its first two rungs also names why no higher one covers the claim.
|
|
85
85
|
|
|
86
86
|
A URL either heading already lists is refused rather than written twice. Two entries for one source split what rests on it across two lines, and a reader checking a claim then finds half of the answer. The exception is a `--read` URL already under `## Leads`, which moves to `## Read` under the title the call carries, since opening a lead is how it becomes read. A `--read` URL already under `## Read`, and any `--lead` URL already listed, stays refused, and a refusal leaves the whole batch unwritten.
|
|
87
87
|
|
package/docs/target/index.md
CHANGED
|
@@ -13,4 +13,5 @@ Scaffold, sync, and migrate a toolkit-managed project, with worked setups for th
|
|
|
13
13
|
- [Target migrations](migrations.md): One-time moves a project scaffolded under an older toolkit runs before its next sync
|
|
14
14
|
- [Target projects](projects.md): Scaffold, add domains later, and sync upstream drift in a toolkit-managed project
|
|
15
15
|
- [Target scenarios](scenarios.md): Worked setups for a markdown-heavy project, a web application, and a monorepo
|
|
16
|
+
- [Target standards moved](standards-moved.md): Which skill owns each standard the retired standards verb used to serve, for a project that still calls it
|
|
16
17
|
- [Target sync](sync.md): Check what drifted in a toolkit-managed project and pull it in, per domain or all at once
|
|
@@ -124,6 +124,10 @@ The walk checks both `.claude/snippets` and a root `snippets/`, since a toolkit
|
|
|
124
124
|
|
|
125
125
|
The walk reads the toolkit's own history, so it needs a cloned toolkit. Installed from the registry it reports `historyUnavailable` and names nothing, so check for `.claude/snippets/` and a root `snippets/` by hand there, and treat what you find as `unattributed`.
|
|
126
126
|
|
|
127
|
+
## Stop calling the standards verb, once
|
|
128
|
+
|
|
129
|
+
`canon standards` is gone. Replace each call with a skill reference from [target standards moved](standards-moved.md). <!-- canon-allow-reference: verb retired -->
|
|
130
|
+
|
|
127
131
|
## Keep or delete the wireframes folder, your call
|
|
128
132
|
|
|
129
133
|
The toolkit retired the wireframes record. Its standard, its generated rule, its seeded folder, and the `@canon/wireframes/index.md` import in the seed `CLAUDE.md` no longer ship, and no skill reads or writes `canon/wireframes/` any more. The canvas holds visual direction instead.
|
package/docs/target/projects.md
CHANGED
|
@@ -38,7 +38,7 @@ The `canon` CLI is separate. Twenty skills invoke it in a command position, and
|
|
|
38
38
|
bun install --global @erclx/canon
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
The package ships the catalogs the CLI reads, not only `src/`, so `canon init` resolves governance, tooling, and the seeds from wherever the package landed
|
|
41
|
+
The package ships the catalogs the CLI reads, not only `src/`, so `canon init` resolves governance, tooling, and the seeds from wherever the package landed.
|
|
42
42
|
|
|
43
43
|
Pointing Claude Code at a checkout stays the development path, where a local skill edit overrides the installed copy for that session.
|
|
44
44
|
|
|
@@ -72,7 +72,7 @@ Keep the `## Scripts` table in `canon/context/development.md` current as scripts
|
|
|
72
72
|
Scaffold installs tooling and seeds. It does not fill the planning docs or the design system. Complete those before the first feature session:
|
|
73
73
|
|
|
74
74
|
1. Fill `canon/REQUIREMENTS.md`. The seed asks for the problem in one line, then goals and non-goals, and the scope is yours to write. The seed states its own cap of 600 words, and `canon context audit` gates on it. Edit the number in the record to loosen it. A decision about how the project is built goes in the `canon/context/` entry of the domain it constrains.
|
|
75
|
-
2. For a UI project, write `canon/DESIGN.md` from the seed template, or work the direction out with `canon:canvas-board` and carry the pick in. Skip for non-UI projects.
|
|
75
|
+
2. For a UI project, write `canon/DESIGN.md` from the seed template and name the project's stylesheet in its lead, or work the direction out with `canon:canvas-board` and carry the pick in. Skip for non-UI projects.
|
|
76
76
|
3. Optionally invoke `canon:draft-figure` naming an architecture view, such as system context or components, and the document it belongs in. It draws the view from the context index, the folder layout, and the requirements and renders it to verify the layout, which downloads the Mermaid CLI on first use and takes about 15 seconds.
|
|
77
77
|
4. Start the feature loop. See [AI workflow](../workflow/ai-workflow.md) for the per-feature sequence.
|
|
78
78
|
|
|
@@ -82,25 +82,25 @@ Nothing watches a figure once it is drawn. Run `canon:draft-figure` again when t
|
|
|
82
82
|
|
|
83
83
|
### Stack decision
|
|
84
84
|
|
|
85
|
-
The default path is `base`. `canon init` on `base` installs base tooling configs, Claude seeds, and the
|
|
85
|
+
The default path is `base`. `canon init` on `base` installs base tooling configs, Claude seeds, and the ten `base` governance rules, and scaffolds an empty `.claude/wiki/`. Most projects need nothing more.
|
|
86
86
|
|
|
87
|
-
Escalate
|
|
87
|
+
Escalate for a project writing code. The `target-setup` skill reads `package.json` and the framework configs, then picks the matching tooling stack (`canon tooling list --json` names the current set) and the governance stack for the root's language (`node`, `python`, `go`, `php`). Framework rules arrive as extras `canon gov detect` proposes from the manifest, so a Next.js app lands on `node` with the App Router rule proposed, and a Vite React app gets no such proposal.
|
|
88
88
|
|
|
89
89
|
In a monorepo the skill reads each folder holding a `package.json`, `pyproject.toml`, `go.mod`, `composer.json`, or `Cargo.toml` to depth two, skipping what git ignores. Each of those folders gets its own tooling stack and a `canon tooling sync <stack> <folder> --skip base` in the preview. Governance still installs once at the root, since a rule's `paths:` globs reach every subfolder, so a subfolder's language rules join the root install through `--add`.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
The server-side security and persistence rules belong to no stack. `canon gov detect` proposes both from a server framework or database client in the manifest, which you confirm in the preview, or add them by hand with `--add security-server,database`.
|
|
92
92
|
|
|
93
93
|
Markdown-heavy projects, CLI tools, docs sites, research notebooks, and scripting repos stay on `base`. Escalation is a ceiling move, not a default.
|
|
94
94
|
|
|
95
|
-
A project the toolkit ships no stack for lands on `base` the same way, and the skill marks that resolution as a fallback in its preview rather than reporting it as a match. Configs, seeds, and gitignore entries land either way, and the JavaScript development dependencies, scripts, and hook activation land only where a `package.json` exists to carry them. A project outside that ecosystem declines at the preview and takes `canon:target-setup gov` for the governance layer alone, which is language-neutral. Go and PHP ship
|
|
95
|
+
A project the toolkit ships no stack for lands on `base` the same way, and the skill marks that resolution as a fallback in its preview rather than reporting it as a match. Configs, seeds, and gitignore entries land either way, and the JavaScript development dependencies, scripts, and hook activation land only where a `package.json` exists to carry them. A project outside that ecosystem declines at the preview and takes `canon:target-setup gov` for the governance layer alone, which is language-neutral. Go and PHP ship a governance stack beside their tooling stack, so a project in either takes `go` or `php` for both.
|
|
96
96
|
|
|
97
97
|
Run `canon tooling list --json` and `canon gov list --json` to see the current catalogs. Never hardcode stack names.
|
|
98
98
|
|
|
99
99
|
### Core domains and skips
|
|
100
100
|
|
|
101
|
-
`canon init` installs base tooling, Claude workflow, and governance, and scaffolds `.claude/wiki/`. Governance defaults to the `base` stack, so a bare init carries the rules that route a project. Pass `--stack <name>` to install a
|
|
101
|
+
`canon init` installs base tooling, Claude workflow, and governance, and scaffolds `.claude/wiki/`. Governance defaults to the `base` stack, so a bare init carries the rules that route a project. Pass `--stack <name>` to install a language stack instead.
|
|
102
102
|
|
|
103
|
-
No
|
|
103
|
+
No reference corpus is written into the project. Each governance rule carries its operative lines inline and names the plugin skill that owns the rest, and every toolkit skill reads the references in its own plugin root. A target that installs governance without the plugin gets the inline lines alone, since no verb answers for a skill's reference there. `canon markdown audit` needs no reference at all, its ban set and checkpoints shipping with the package as data.
|
|
104
104
|
|
|
105
105
|
`governance` and `wiki` are skippable:
|
|
106
106
|
|
|
@@ -117,7 +117,7 @@ When a new need appears after scaffold, install the one domain without re-runnin
|
|
|
117
117
|
- Project-specific rule the toolkit does not ship: invoke `canon:create-rule`. It scaffolds a rule into `.claude/rules/project/` with a non-colliding number, and `canon gov sync` leaves it untouched. A rule placed under `.claude/rules/canon/` instead is deleted on the next sync, since that folder belongs to the toolkit.
|
|
118
118
|
- Index.md system for a markdown-heavy folder that emerged: invoke `canon:target-setup indexes`
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
Skill references are not on that list, and there is nothing to add for them. They install into no project, by default or by flag, and a session reads one from the plugin that loaded the skill rather than from a project copy. A project holding a `standards` folder under `.claude/` from an older toolkit is carrying a stale artifact nothing reads, and deleting it is safe. The toolkit retired snippets entirely, and [target migrations](migrations.md) covers the `.claude/snippets/` folder an older one left behind.
|
|
121
121
|
|
|
122
122
|
Per-domain mechanics live in the corresponding `docs/<domain>.md`. The skill body in `claude/skills/<skill>/SKILL.md` covers detection and preview.
|
|
123
123
|
|
|
@@ -134,5 +134,5 @@ When the toolkit updates, a target pulls changes per domain. A project scaffolde
|
|
|
134
134
|
- [agents](../agents/index.md): CLI flags, exit codes, and JSON output shapes
|
|
135
135
|
- [target migrations](migrations.md), [target sync](sync.md), [target scenarios](scenarios.md): the one-time moves, the recurring sync, and worked setups
|
|
136
136
|
- [AI workflow](../workflow/ai-workflow.md): feature-development loop inside a toolkit-managed project
|
|
137
|
-
- [tooling](../../canon/context/tooling/index.md), [governance](../../canon/context/governance/index.md), [claude plugin](../../canon/context/claude-plugin/index.md), [indexes](../../canon/context/context-model/indexes.md), [
|
|
137
|
+
- [tooling](../../canon/context/tooling/index.md), [governance](../../canon/context/governance/index.md), [claude plugin](../../canon/context/claude-plugin/index.md), [indexes](../../canon/context/context-model/indexes.md), [skill references](../../canon/context/claude-plugin/skill-references/index.md): per-domain mechanics
|
|
138
138
|
- [sandbox](../../canon/context/sandbox/index.md): scenario catalog for verifying domain flows
|
package/docs/target/scenarios.md
CHANGED
|
@@ -26,7 +26,7 @@ bun create vite my-app && cd my-app
|
|
|
26
26
|
claude
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Invoke `canon:target-setup`. The skill reads `package.json` and the Vite config, resolves tooling to `vite-react` and governance to `
|
|
29
|
+
Invoke `canon:target-setup`. The skill reads `package.json` and the Vite config, resolves tooling to `vite-react` and governance to `node`, proposes `react` and the other rules its manifest matches as extras, and runs `canon init` with the resolved flags.
|
|
30
30
|
|
|
31
31
|
Ongoing maintenance:
|
|
32
32
|
|
|
@@ -34,23 +34,22 @@ Ongoing maintenance:
|
|
|
34
34
|
- Seed drift: merge by hand against the toolkit copy
|
|
35
35
|
- Catch-all sync: `canon sync .`
|
|
36
36
|
- Governance rule refresh only: `canon gov sync .`
|
|
37
|
-
- Layer a new rule on top, for example `
|
|
37
|
+
- Layer a new rule on top, for example `shadcn` after adopting shadcn: `canon gov install node --add shadcn .`
|
|
38
38
|
|
|
39
39
|
## Monorepo with multiple language roots
|
|
40
40
|
|
|
41
41
|
The repo root owns the shared `base` layer, and each language lives in its own subfolder.
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
canon init --stack react .
|
|
44
|
+
canon init --stack node --add react .
|
|
45
45
|
canon tooling sync vite-react ./frontend --skip base --write
|
|
46
46
|
canon tooling sync python ./backend --skip base --write
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
`--skip base` drops the `base` layer from each subtree sync, so husky, prettier,
|
|
49
|
+
`--skip base` drops the `base` layer from each subtree sync, so husky, prettier, commitlint, and CI stay single at the repo root. The one exception is base's verify runner, `scripts/verify.ts` and `scripts/verify.json`, which every subtree still receives so it can verify on its own. Without it, every subtree re-drops husky, and since git honors only one `core.hooksPath` the extra hook dirs silently break. Each subtree still gets its own framework configs (eslint, vitest, tsconfig, vite), and its own stack reference reads through `canon tooling reference <stack>`.
|
|
50
50
|
|
|
51
51
|
A sync whose target sits below the git root knows it is writing into a subfolder:
|
|
52
52
|
|
|
53
53
|
- It withholds `.github/`, since GitHub reads workflows only at the repository root, and names each withheld file. Run the subtree from a job in the root workflow instead, with `working-directory` set to the subtree path the sync prints, such as `working-directory: frontend`.
|
|
54
|
-
- It writes a nested `cspell.json` that registers the subtree's word lists, so a root `cspell '**'` reads them for files under that folder. It leaves a spell config the subtree already has alone.
|
|
55
54
|
- It installs no dependencies and adds no scripts to a subtree without a `package.json`. It names what it skipped and ends on `run 'bun init' in <path>, then sync again`.
|
|
56
|
-
- The subtree carries no `check` script, since that lives in the root's base layer, so run
|
|
55
|
+
- The subtree carries no `check` script, since that lives in the root's base layer, so run `bun scripts/verify.ts` there. It skips the format phases a subtree does not declare, since the root runs them, and still fails on a missing lint, typecheck, or test script, the phases its stack's `scripts/verify.json` requires.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Target standards moved
|
|
3
|
+
description: Which skill owns each standard the retired standards verb used to serve, for a project that still calls it
|
|
4
|
+
category: Agent surface
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Target standards moved
|
|
8
|
+
|
|
9
|
+
`canon standards <name>` is gone, and with it the name map that sent an old call to a new home. A rule, skill, or `CLAUDE.md` of your own that still runs it now gets commander's too-many-arguments error and no content, so search the project for the call and replace it. The surrounding step is in [target migrations](migrations.md). <!-- canon-allow-reference: says the verb is gone -->
|
|
10
|
+
|
|
11
|
+
Each standard now lives at `references/<name>.md` in the skill that owns it. Load that skill and read the reference it names:
|
|
12
|
+
|
|
13
|
+
- `task-board`: `board`, `tasks`, `tasks-decline`
|
|
14
|
+
- `context-fold`: `context`
|
|
15
|
+
- `canvas-board`: `canvas`, `design`
|
|
16
|
+
- `docs-sync`: `docs`, `readme`
|
|
17
|
+
- `draft-figure`: `figures`, `mermaid`
|
|
18
|
+
- `create-rule`: `rule`
|
|
19
|
+
- `create-skill`: `skill`, `skill-paths`, `skill-practice`, `skill-requirement`
|
|
20
|
+
- `git-branch`: `branch`, `slug`
|
|
21
|
+
- `git-commit`: `commit`, `versioning`
|
|
22
|
+
- `git-pr`: `pr`, `publish`
|
|
23
|
+
- `markdown-craft`: `markdown`
|
|
24
|
+
- `teach-workspace`: `glossary`, `teach`
|
|
25
|
+
- `plan-groundwork`: `groundwork`, `groundwork-spikes`
|
|
26
|
+
- `plan-intake`: `intake`
|
|
27
|
+
- `plan-feature`: `plan`, `plan-lifecycle`
|
|
28
|
+
- `draft-ready`: `ready`
|
|
29
|
+
- `draft-doc`: `requirements`, `wiki`
|
|
30
|
+
- `session-map`: `session`
|
|
31
|
+
|
|
32
|
+
One name moved under a new filename. `standard`, the shape of a standard itself, became `skill-reference.md` in `create-skill`, since the toolkit no longer ships a standards folder to hold one.
|