@erclx/canon 5.21.0 → 5.22.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.
Files changed (74) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +1 -1
  3. package/claude/skills/auto-ship/references/draft-mark.md +8 -6
  4. package/claude/skills/draft-doc/REQUIREMENT.md +45 -0
  5. package/claude/skills/draft-doc/SKILL.md +77 -0
  6. package/claude/skills/draft-doc/references/context.md +31 -0
  7. package/claude/skills/draft-doc/references/docs.md +33 -0
  8. package/claude/skills/draft-doc/references/readme.md +58 -0
  9. package/claude/skills/draft-doc/references/wiki.md +53 -0
  10. package/claude/skills/draft-doc/references/wireframes.md +48 -0
  11. package/claude/skills/draft-figure/REQUIREMENT.md +1 -1
  12. package/claude/skills/draft-figure/SKILL.md +1 -1
  13. package/claude/skills/git-pr/SKILL.md +5 -46
  14. package/claude/skills/git-pr/references/final-command.md +75 -0
  15. package/claude/skills/git-pr/references/labels.md +2 -2
  16. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +76 -0
  17. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -1
  18. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +5 -1
  19. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  20. package/claude/skills/search-craft/SKILL.md +1 -1
  21. package/docs/agents/commands.md +1 -1
  22. package/docs/agents/drift-surfaces.md +20 -9
  23. package/docs/agents/index.md +2 -2
  24. package/docs/agents/install-and-sync.md +3 -3
  25. package/docs/agents/migrate.md +1 -1
  26. package/docs/agents/rule-citations.md +1 -1
  27. package/docs/agents/slides.md +47 -3
  28. package/docs/agents/tasks.md +1 -1
  29. package/docs/target/migrations.md +3 -1
  30. package/docs/target/sync.md +1 -1
  31. package/docs/workflow/skill-map.md +14 -18
  32. package/governance/rules/canon/604-scratch.md +0 -1
  33. package/governance/rules/claude/575-hooks.md +1 -2
  34. package/governance/rules/claude/576-settings.md +1 -2
  35. package/governance/rules/standards/architecture.md +0 -1
  36. package/governance/rules/standards/context.md +0 -1
  37. package/governance/rules/standards/design.md +0 -1
  38. package/governance/rules/standards/diagrams.md +0 -3
  39. package/governance/rules/standards/requirements.md +0 -1
  40. package/governance/rules/standards/wireframes.md +0 -1
  41. package/package.json +1 -1
  42. package/scripts/manage-sandbox.sh +7 -8
  43. package/src/claude/cases/authoring.ts +5 -5
  44. package/src/commands/slides.ts +14 -4
  45. package/src/commands/sync.ts +10 -0
  46. package/src/gov/citations.ts +1 -2
  47. package/src/migrate/skill-names.ts +12 -0
  48. package/src/slides/convert/deck.ts +83 -3
  49. package/src/slides/convert/export.ts +67 -19
  50. package/src/slides/convert/shapes.ts +43 -3
  51. package/src/slides/convert/walk.ts +43 -1
  52. package/src/slides/package/fonts.ts +297 -0
  53. package/src/slides/package/motion.ts +316 -0
  54. package/src/slides/package/test-face.ts +113 -0
  55. package/src/sync/check.ts +9 -0
  56. package/src/sync/layout.ts +27 -1
  57. package/standards/architecture.md +0 -1
  58. package/standards/context.md +0 -1
  59. package/standards/design.md +0 -1
  60. package/standards/diagrams.md +0 -3
  61. package/standards/requirements.md +0 -1
  62. package/standards/rule.md +1 -0
  63. package/standards/wireframes.md +0 -1
  64. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +8 -3
  65. package/claude/skills/draft-context/REQUIREMENT.md +0 -37
  66. package/claude/skills/draft-context/SKILL.md +0 -61
  67. package/claude/skills/draft-docs/REQUIREMENT.md +0 -35
  68. package/claude/skills/draft-docs/SKILL.md +0 -59
  69. package/claude/skills/draft-readme/REQUIREMENT.md +0 -38
  70. package/claude/skills/draft-readme/SKILL.md +0 -73
  71. package/claude/skills/draft-wiki/REQUIREMENT.md +0 -42
  72. package/claude/skills/draft-wiki/SKILL.md +0 -83
  73. package/claude/skills/draft-wireframes/REQUIREMENT.md +0 -38
  74. package/claude/skills/draft-wireframes/SKILL.md +0 -69
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Orchestrator cloud launch
3
+ description: The cloud build shape, being the launch prompt that carries the plan as text and announces over GitHub, the create under a pseudo-terminal with its trust keys, and the readout that fails loudly on a missing session id
4
+ ---
5
+
6
+ # Orchestrator cloud launch
7
+
8
+ Run this once `orchestrator-dispatch.md` has cleared a row and picked cloud for it. The worker runs on a Claude Code cloud VM that clones the repository from GitHub, loads no plugin, and cannot see this machine's `.canon/`.
9
+
10
+ The shape needs a `SessionStart` hook in the repository that, on the VM alone, copies the plugin skills into `.claude/skills/` and puts `canon` on the path. A repository without one cannot take this shape, so fall back to a local worker there. Where the hook exists, the launch prompt calls `/auto-ship` with no `canon:` prefix, since the copied skills list as project skills.
11
+
12
+ ## Check the row is unclaimed
13
+
14
+ A cloud worker never appears in `canon sessions list` and never pushes the derived branch, since the cloud assigns it a `claude/` branch of its own. So the roster and the refs read clear on a row a cloud worker is already building. Run the local check in `orchestrator-dispatch.md` anyway, since a local worker on the same row still collides, then read the two places a cloud worker does show:
15
+
16
+ ```bash
17
+ prs=$(gh api 'repos/{owner}/{repo}/pulls?state=open&per_page=100' --jq '.[] | select(.head.ref | startswith("claude/")) | .number') || { echo 'unreadable: the open pull request list'; exit 1; }
18
+ found=$(printf '%s\n' "$prs" | while IFS= read -r n; do
19
+ [ -n "$n" ] || continue
20
+ bodies=$(gh api "repos/{owner}/{repo}/issues/$n/comments" --jq '.[].body') || { echo "unreadable: the comments on #$n"; exit 1; }
21
+ if printf '%s\n' "$bodies" | grep -qE '^(ANNOUNCE|QUESTION): plan <slug>([^a-z0-9-]|$)'; then echo "claimed: #$n"; fi
22
+ done) || { printf '%s\n' "$found" | grep '^unreadable'; exit 1; }
23
+ printf '%s\n' "${found:-clear}"
24
+ ```
25
+
26
+ The prompt below has the worker open its `ANNOUNCE:` and `QUESTION:` comments with `plan <slug>`, so the comment is where a cloud pull request names its row. A title or body cannot, since `git-pr` writes both from the diff. Ending the match at a character no slug carries keeps `log` from claiming `log-entry`.
27
+
28
+ Branch on the line it prints rather than on the exit, which a shell function wrapping a command can flatten to zero:
29
+
30
+ - `claimed: #<n>`: a cloud worker's pull request names the plan slug. Treat the row as claimed and report each number.
31
+ - `clear`, and this pass's launched record holds no cloud session for the row: the row is clear of cloud workers.
32
+ - `unreadable: <what>`: the list or a comment read failed, so nothing was checked. Treat the candidate as unverified and fall back to the human-launch line, the same as a refused local check in `orchestrator-dispatch.md`. Never read it as clear, since an empty answer from a failed read is the collision this check exists to catch.
33
+
34
+ The launched record covers the minutes before the pull request opens, when nothing on GitHub names the row yet. It is this session's alone, so a second dispatcher sees only the pull request list, which is the window `orchestrator-dispatch.md` already states for local workers under `## Hold what this pass already launched`.
35
+
36
+ ## The prompt
37
+
38
+ Write the prompt to `.canon/tmp/cloud-<slug>/prompt.md` at the main worktree root, with the command at position zero, per `### Position zero` in `orchestrator-launch.md`:
39
+
40
+ ```plaintext
41
+ /auto-ship .canon/plans/feature-<slug>.md
42
+ Before Step 1 reads it, write the plan below verbatim to .canon/plans/feature-<slug>.md, creating the folder. That folder is gitignored, so it stays out of every commit. Stay on the branch this session was given, since a cloud session may push only to its own claude/ branch, so skip the worktree entry and the branch rename, and open the pull request from that branch although its name does not follow the branch convention git-pr checks.
43
+ Your controller cannot receive a message from this session. Announce on GitHub instead, naming the repository <owner>/<repo> in every comment. When the pull request opens, comment on it starting with ANNOUNCE: plan <slug>, then the number, the branch, the head sha, the CI state, and every point you departed from the plan on. If the chain stops after the pull request opens, post that comment anyway and name the stop. If you stop on a question before a pull request exists, push what you have, open a draft pull request through the REST create with draft=true, since the draft mark cannot run here, and comment on it starting with QUESTION: plan <slug>.
44
+ Before you finish, read the pull request's live body and delete every line carrying claude.ai/code/session_, since the label scan fails on one.
45
+ <the plan file, verbatim>
46
+ ```
47
+
48
+ The plan travels as text because the VM has no `.canon/` and the orchestrator alone writes the board, so nothing syncs the record across. `auto-ship` Step 1 then reads it at the path the command names, the same as on a local worker.
49
+
50
+ ## The create
51
+
52
+ `claude --cloud` refuses without a terminal, so the create runs under `script`, which supplies one:
53
+
54
+ ```bash
55
+ dir=.canon/tmp/cloud-<slug>
56
+ timeout 150 script -qec "claude --cloud \"\$(cat $dir/prompt.md)\"" "$dir/create.typescript" < <(sleep 30)
57
+ session=$(grep -A 2 'Created cloud session:' "$dir/create.typescript" | grep -o 'session_[A-Za-z0-9]*' | head -n 1)
58
+ [ -n "$session" ] || { printf 'No cloud session id in %s. Nothing was dispatched.\n' "$dir/create.typescript" >&2; exit 1; }
59
+ printf 'session=%s\n' "$session"
60
+ ```
61
+
62
+ Run it from the main worktree root, since the session targets whichever repository that checkout's `origin` names. That folder is already trusted, so the create screen shows no trust prompt. From a checkout this machine has not trusted, such as a fresh clone of another repository, the screen asks first, and piped keys answer it: replace `<(sleep 30)` with `<(sleep 4; printf '\033[B'; sleep 1; printf '\r'; sleep 30)`. Either way stdin stays open for the create, which is the shape the wrapper was measured in, since an early end of input can reach the terminal before the create screen settles.
63
+
64
+ The readout is the text `Created cloud session: <title>`, unanchored since a terminal capture can open a line with escape codes, followed by a `View:` address carrying the `session_...` id. Anything else is a failed create, including a run that exits zero. Report the typescript's last lines and fall back to the human-launch line in `orchestrator-dispatch.md` rather than recording a session that does not exist. The wrapper is a stopgap: any change to the interactive create screen breaks it, which is why the readout fails loudly instead of guessing.
65
+
66
+ Record `session` beside the row's branch in this pass's launched record. A cloud worker never registers in `canon sessions list`, so that record and the pull request list are the only two readings that know it exists. Report the dispatch the way the local shape does, naming the row, the plan, the repository, and the session id in place of a session name.
67
+
68
+ ## Recognize the pull request
69
+
70
+ A cloud worker cannot message this session and never appears in the roster `watch.ts` reads, so its pull request and its `ANNOUNCE:` comment are the announcement. Start the poll in `orchestrator-poll.md` when the cloud dispatch goes out, rather than at that runbook's thirty-minute fallback. A pull request on a `claude/` head is this row's when one of its commits carries a `Claude-Session:` trailer naming the session id the create recorded:
71
+
72
+ ```bash
73
+ gh api 'repos/{owner}/{repo}/pulls/<number>/commits' --jq '.[].commit.message' | grep -c 'Claude-Session:.*<session>'
74
+ ```
75
+
76
+ A count above zero matches the row. A count of zero is someone else's pull request, whatever its title says. Once it matches, record the number on the row's task yourself with `canon tasks pull-request <number> <task>`, since `git-pr` on the VM has no task file to write, then review it the way step 5 reviews any worker's pull request.
@@ -54,6 +54,10 @@ Reading `claimed` off the record is what keeps this a check rather than a rule a
54
54
 
55
55
  What the ref read cannot see is a branch pushed from another machine since the last fetch, because it reads the remote-tracking ref rather than the remote. Nobody has hit that, and a `git ls-remote` per dispatch costs 0.438s against 0.001s, so the gap is recorded rather than closed.
56
56
 
57
+ ### A cloud worker's claim
58
+
59
+ A cloud worker never appears in the roster and never pushes the derived branch, so run the local check above and then the cloud claim in `${CLAUDE_SKILL_DIR}/references/orchestrator-cloud-launch.md` before a cloud dispatch.
60
+
57
61
  ## Hold what this pass already launched
58
62
 
59
63
  A worker registers with `branch: main` and the main worktree as its `cwd` until `auto-ship` Step 0 moves it, which took several seconds on both measured runs. Neither the roster nor the refs name the candidate during that window, so a second check inside it reads clear.
@@ -82,9 +86,15 @@ A `claude --bg` session inherits the model of whatever launched it rather than r
82
86
 
83
87
  Name `<model>` on the launch, and pick it against the task rather than copying whatever this session happens to run. Sizing the model to the row is the dispatcher's call, the same call it already makes on the branch. A mechanical row moving files under a written plan is not the row that needs the largest model, and one whose plan carries an open judgment is.
84
88
 
89
+ ## Pick local or cloud
90
+
91
+ Dispatch to a cloud worker only on the operator's explicit pick for that dispatch, until three cloud rows have merged. Whether a cloud session is worth its cost is the operator's account to judge, and the review load a cloud pull request adds is unmeasured, so the pick stays a person's until that count gives a reading.
92
+
93
+ A row qualifies for that pick when its plan carries no open question and touches no surface needing local state, such as the sandbox, the records remote, or a browser. A cloud worker cannot reach any of the three, and it cannot ask the operator mid-build except through a draft pull request.
94
+
85
95
  ## Dispatch
86
96
 
87
- Read `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md` once every check above clears, and launch from its build template. It also holds the review-address and planning shapes, which skip the checks above.
97
+ Read `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md` once every check above clears, and launch from its build template. That runbook also holds the review-address and planning shapes, which skip the checks above. A row the operator picked for cloud launches from `${CLAUDE_SKILL_DIR}/references/orchestrator-cloud-launch.md` instead, since the cloud VM shares neither the plugin nor the board with this machine.
88
98
 
89
99
  ## Fall back to the human
90
100
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Orchestrator launch runbook
3
- description: The launch every dispatch kind shares, being the build, review-address, planning, reviewer, and UI reviewer templates, the session name and controller id each carries, why the command sits at position zero, and what the brief may carry
3
+ description: The launch every dispatch kind shares, being the build, cloud build, review-address, planning, reviewer, and UI reviewer templates, the session name and controller id each carries, why the command sits at position zero, and what the brief may carry
4
4
  ---
5
5
 
6
6
  Run this once `orchestrator-dispatch.md` has cleared a row, or from its planning, review-address, or reviewer shape below when that runbook's checks do not bind. The model each template names comes from `## Pick the model` in that runbook.
@@ -49,6 +49,10 @@ The prompt carries pointers and standing context, and stops there. The branch an
49
49
 
50
50
  Report the dispatch as loudly as the human-launch line it replaces: name the branch, the model, the task, and the session name, so a person reading the transcript can follow what fired without watching it happen.
51
51
 
52
+ ## Dispatch to a cloud worker
53
+
54
+ Read `${CLAUDE_SKILL_DIR}/references/orchestrator-cloud-launch.md` when `orchestrator-dispatch.md` picked cloud for the row. It holds the prompt that carries the plan as text and announces over GitHub, the create under `script`, and the readout that refuses to record a missing session id.
55
+
52
56
  ## Dispatch to address a review
53
57
 
54
58
  `review-address` is a single pass, not a chain, so a launch naming it alone reaches no `role-worker` and takes no role, which owes no message either. Reach the role directly on this launch instead of wrapping a second chain around one skill that has none of its own.
@@ -7,7 +7,7 @@ description: Why a session needs a thinking step before an outside search, deriv
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, a session reaching outside the project runs one generic `WebSearch` and takes what ranks highest. Nothing in the toolkit says how to search, and the two procedures that require an outside source, `plan-groundwork` and `draft-wiki`, give no route to one.
10
+ Without this skill, a session reaching outside the project runs one generic `WebSearch` and takes what ranks highest. Nothing in the toolkit says how to search, and the two procedures that require an outside source, `plan-groundwork` and `draft-doc`'s wiki kind, give no route to one.
11
11
 
12
12
  The miss is measured. On 2026-10-02 two queries ran twice each with identical text, once open and once with `allowed_domains` set to authorities the session derived itself with no list to consult.
13
13
 
@@ -30,7 +30,7 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
30
30
  - Prefer a public API over a fetched and summarized page where one exists, since the API returns the dates, authors, and identifiers a citation needs
31
31
  - Carry a dated access note grown only from a failure a session hit, and stop to ask the operator before any paid or logged-in route
32
32
  - Close with the practice skill's excuses, red flags, and closing checklist, answering "the model already knows the good sites" and "one search was enough"
33
- - Be loaded from the sourcing steps of `plan-groundwork` and `draft-wiki`, each reporting when the skill does not resolve
33
+ - Be loaded from the sourcing steps of `plan-groundwork` and `draft-doc`'s wiki kind, each reporting when the skill does not resolve
34
34
 
35
35
  ## Must not
36
36
 
@@ -42,7 +42,7 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
42
42
  ## Out of scope
43
43
 
44
44
  - The form a citation takes: the procedure or standard writing it
45
- - A Claude Code subject: the `claude-code-guide` agent, which `draft-wiki` already routes to
45
+ - A Claude Code subject: the `claude-code-guide` agent, which `draft-doc`'s wiki sourcing step already routes to
46
46
  - Image generation, which makes a picture rather than finding a source
47
47
  - Loading on every web search rather than on a research-shaped request: a hook matching `WebSearch`, planned on its own
48
48
  - Whether a session already scopes searches without the skill, which only a run on a fresh research request without it would show
@@ -54,4 +54,4 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
54
54
  - No `Skill` call fired, so the description did not route a plain research request to the body.
55
55
  - The run searched four times with no domain filter, naming authors and journals from recall, then fetched the papers' own pages. It never named the field, so the scenario's field pattern failed and the arm went red on one of its assertions.
56
56
 
57
- The arm shows the trigger is the gap rather than the body: a session that never loads the skill cannot follow it. The pointers from `plan-groundwork` and `draft-wiki` reach only those procedures, and the hook matching `WebSearch` is the route for every other search. One run on one model shows the miss exists and does not size it.
57
+ The arm shows the trigger is the gap rather than the body: a session that never loads the skill cannot follow it. The pointers from `plan-groundwork` and `draft-doc`'s wiki kind reach only those procedures, and the hook matching `WebSearch` is the route for every other search. One run on one model shows the miss exists and does not size it.
@@ -78,6 +78,6 @@ Each line is a claim measured once, and `${CLAUDE_SKILL_DIR}/REQUIREMENT.md` rec
78
78
  ## What this delegates
79
79
 
80
80
  - The form a citation takes: the surface writing it, such as the standard the procedure writes to
81
- - A Claude Code subject: the `claude-code-guide` agent, which `draft-wiki` routes to
81
+ - A Claude Code subject: the `claude-code-guide` agent, which `draft-doc`'s wiki sourcing step routes to
82
82
  - Generating an image: whatever draws the surface, since making one is not search
83
83
  - Access code a session needs repeatedly: a `canon` verb, never a script in this skill
@@ -130,7 +130,7 @@ Subcommands no other page describes:
130
130
  - `design regen` rewrites this repository's `canon/DESIGN.md` from `src/design/tokens.ts` and `src/design/base.css` from `src/design/neutral.ts`. `design css` emits the tokens and components as CSS on stdout, with `--no-components` for properties alone, and `design render` declares each vendored face the typography table names under `--embed-fonts`.
131
131
  - `slides render` renders a `.claude/SLIDES.md` source into a PowerPoint deck and reports any unrecognized layout name on stderr, and `slides list --json` emits the layout catalog.
132
132
  - `slides render --source <folder>` lays out each `.html` file in filename order in Chromium at 1280 by 720 and rebuilds it as editable shapes. Each element drawn as a picture prints one `✗` line on stderr naming the slide, the selector, and the properties that forced it. A link left out, being a `#slide-N` past the deck's end or any target that is neither that nor an absolute URL, prints one too, and the exit stays 0.
133
- - A deck folder's `deck.json`, its per-slide `<body>` attributes, speaker notes, and charts are described in `slides.md`.
133
+ - A deck folder's `deck.json` and the faces it embeds, its per-slide `<body>` attributes, transitions and entrances, speaker notes, and charts are described in `slides.md`.
134
134
  - `canvas`, with its verbs, content format, and write routes, is described in `canvas.md`.
135
135
  - `labels scan` fails a pull request or a posted review whose title, body, or review comment carries a phase label, a label a code span quotes, a gitignored record path, a session link, a title word no dictionary holds, or a title breaking `standards/pr.md`'s format, casing, or length rule (`--event`, `--body-file`, `--json`).
136
136
  - `repo metadata propose` compares a description, homepage, and topic set computed from the README and `package.json` against what the remote carries, writing nothing, and `repo metadata apply` writes an explicitly supplied set through `gh repo edit` (`--description`, `--homepage`, `--topics`).
@@ -1,19 +1,19 @@
1
1
  ---
2
2
  title: Drift surfaces
3
- description: The six sections canon sync --check reports beside the per-domain scan, being seeds, superseded artifacts, unmigrated domains, new rules and skills, and the reverse walk, with the managed-target gate and what counts toward the exit code
3
+ description: The seven sections canon sync --check reports beside the per-domain scan, being seeds, superseded artifacts, unmigrated domains, surfaces at the old root, new rules and skills, and the reverse walk, with the managed-target gate and what counts toward the exit code
4
4
  ---
5
5
 
6
6
  # Drift surfaces
7
7
 
8
- `canon sync --check` reports six sections outside the per-domain scan that
8
+ `canon sync --check` reports seven sections outside the per-domain scan that
9
9
  `install-and-sync.md` describes, because each names something
10
- that walk cannot see: `seeds`, `superseded`, `unmigrated`, `newSkills`,
11
- `newRules`, and `reverse`. None of them produces a change, and no sync command
12
- applies any of them. The headings below group the first three together and give
13
- `newSkills` its description under `newRules`, which answers the same question
14
- about a different corpus.
10
+ that walk cannot see: `seeds`, `superseded`, `unmigrated`, `unmovedSurfaces`,
11
+ `newSkills`, `newRules`, and `reverse`. None of them produces a change, and no
12
+ sync command applies any of them. The headings below group the first four
13
+ together and give `newSkills` its description under `newRules`, which answers the
14
+ same question about a different corpus.
15
15
 
16
- All six report only against a toolkit-managed target, which is one carrying a
16
+ All seven report only against a toolkit-managed target, which is one carrying a
17
17
  `.claude/` directory, a `CLAUDE.md`, or a domain still at the root layout. The
18
18
  report says so through `managed` in the JSON and routes an unmanaged directory to
19
19
  `canon init`. Seeds are why the gate exists, since they enumerate from the toolkit
@@ -26,7 +26,7 @@ toolkit installed. When `managed` is false every section comes back empty rather
26
26
  than the render alone going quiet, so a consumer reading `--json` never acts on a
27
27
  finding the rendered half withheld.
28
28
 
29
- ## Seeds, superseded artifacts, and unmigrated domains
29
+ ## Seeds, superseded artifacts, unmigrated domains, and old-root surfaces
30
30
 
31
31
  `seeds` classifies every seed the toolkit ships against the target's copy, as
32
32
  `matching`, `stale`, `drifted`, or `missing`. `missing` has no per-domain
@@ -68,6 +68,13 @@ Nothing proposes moving it, and no command relocates the content. Move it
68
68
  yourself. A leftover `snippets/` folder reports under the reverse walk instead,
69
69
  where `docs/target/sync.md` says what to do with it.
70
70
 
71
+ `unmovedSurfaces` names a tracked surface the target still holds at its `.claude/`
72
+ spelling with nothing at the `canon/` one, such as `.claude/REQUIREMENTS.md` or
73
+ `.claude/context/`. Each entry carries `rel` and `movesTo`, and the render names
74
+ `canon migrate surface-roots`, the verb that moves them. Rules glob the `canon/`
75
+ spelling alone, so a target on the old root stops loading the rules scoped to
76
+ those files until it moves. <!-- canon-keep-surface-root -->
77
+
71
78
  ## Rules the target never received
72
79
 
73
80
  `newRules` names a rule the target could receive and its tree does not hold. A
@@ -182,6 +189,10 @@ toolkit shipped and the target renamed goes unmatched, the same limit the
182
189
  is: only the user can move content they wrote, so failing a job on it leaves the
183
190
  job red with no mechanical remedy.
184
191
 
192
+ `unmovedSurfaces` is excluded although `canon migrate surface-roots` closes it.
193
+ The move rewrites citations across the project, so it is a change the project
194
+ schedules, and a job counting it would go red the day a target updated the CLI.
195
+
185
196
  `newRules` is excluded on a different ground, since a command does close it. What
186
197
  excludes it is that installing a rule changes what a project is governed by, so
187
198
  gating on the count would pressure a target into adopting rules nobody chose.
@@ -22,7 +22,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
22
22
  - [Demo](demo.md): Compiling a screencast draft into a runnable plan, driving a served application to a recording and a still, reading numbered frames back out of a recording, the pointer the recording paints, and what each refusal reports
23
23
  - [Design board](design-board.md): Generating a static index over a project's design surfaces, what each panel reads, and which two stay toolkit-checkout-only
24
24
  - [Docs](docs.md): How canon docs resolves the toolkit's own reference surface from an install root, and how a split domain is named
25
- - [Drift surfaces](drift-surfaces.md): The six sections canon sync --check reports beside the per-domain scan, being seeds, superseded artifacts, unmigrated domains, new rules and skills, and the reverse walk, with the managed-target gate and what counts toward the exit code
25
+ - [Drift surfaces](drift-surfaces.md): The seven sections canon sync --check reports beside the per-domain scan, being seeds, superseded artifacts, unmigrated domains, surfaces at the old root, new rules and skills, and the reverse walk, with the managed-target gate and what counts toward the exit code
26
26
  - [Driver](driver.md): Walking a page through named interactions, the probe catalog and the false finding each one carries, why viewport heights are never defaulted, and what each refusal reports
27
27
  - [Merge gate](gate.md): Running the gate this repository verifies a branch with, what the stage table holds and what stays a script, how the changed set scopes three stages, and why a stage that cannot read its input reports rather than passing
28
28
  - [Hooks](hooks.md): Running the post-merge steps through one verb, the order and the child call behind each, the root and working directory each step reads, the skip switches, and the line each record maps to
@@ -55,7 +55,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
55
55
  - [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds, reading which row is the caller, the liveness confidence field, what each session surface can see, and where moving a session to another machine is described
56
56
  - [Skill audit](skills-audit.md): Measuring both skill corpora against the skill standards, the checks it reads, the requirement gate that is the only failing one, and the drift verb that names bodies rewritten since a ref
57
57
  - [Citation reach](skills-reach.md): Reporting the skill bodies that cite a path no target project receives, which corpus the verb reads, the ownership key that decides what counts, the one-word qualifier that marks a citation as decided, and why the verb reports instead of gating
58
- - [Slides](slides.md): What a folder of HTML slides declares for the whole deck in deck.json, what each slide declares on its own body, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
58
+ - [Slides](slides.md): What a folder of HTML slides declares for the whole deck in deck.json, the faces it embeds, what each slide declares on its own body, transitions and entrances, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
59
59
  - [Standard success criteria](standards-audit.md): Reading the corpus against the success-criterion gate, the two headings it accepts, why the check scopes to arrival rather than the whole corpus, and the exit codes it sets
60
60
  - [State-scoped risk](state-scoped-risk.md): Reading committed state rather than an arriving change, the shipped-tree corpus the secret scan reads, what it keys on and how a deliberate value is exempted, the advisory check and its network failure mode, and why one gates while the other reports
61
61
  - [Superseded values](superseded.md): Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the family stem behind a templated citation, the exemption marker, the blind spots it cannot reach, and why it reports rather than gates
@@ -233,9 +233,9 @@ edit and a job counting those stays red with no remedy.
233
233
 
234
234
  ### Surfaces reported beside the domains
235
235
 
236
- Six sections sit outside the per-domain scan, because each names something
237
- that walk cannot see: `seeds`, `superseded`, `unmigrated`, `newSkills`,
238
- `newRules`, and `reverse`. None of them produces a change, and no sync command
236
+ Seven sections sit outside the per-domain scan, because each names something
237
+ that walk cannot see: `seeds`, `superseded`, `unmigrated`, `unmovedSurfaces`,
238
+ `newSkills`, `newRules`, and `reverse`. None of them produces a change, and no sync command
239
239
  applies any of them. What each reports, the managed-target gate they share, and
240
240
  which count toward `--exit-code` are in `drift-surfaces.md`.
241
241
 
@@ -9,7 +9,7 @@ description: What each canon migrate verb moves and rewrites, what it refuses, t
9
9
 
10
10
  `migrate rename` moves a project off the retired `aitk` name. It reports until `--write` is passed, and `--scope target` rewrites the toolkit-owned folders alone, reporting every other citation as one the project owns rather than editing prose somebody wrote. A project installing `canon` fresh never needs it.
11
11
 
12
- `migrate skill-names` moves the plugin skills that carried a `claude-` prefix onto their two-word names and rewrites every citation of one. It carries two plain renames as well, where a skill carried no prefix and changed its name because the old one described a job it no longer does, landing on `ui-checklist` and `context-fold`, and it leaves the pointer answering under the fold skill's old name in place. It shares its engine with `migrate rename` and differs in what it is scanning for: a skill name is a whole name rather than a word stem, so it matches only where the word ends, which is what keeps a longer word that merely opens with a skill name, such as `claude-worktrees`, out of it. It takes no `--scope`, since the skill folders it moves are authored in the toolkit and no target holds a copy of that catalog, which leaves a target's own citations of a renamed skill as the whole of what it rewrites there. The changelog and the eval transcripts are passed over on the argument the other sweep already carries, that each records what shipped or what a session ran under whatever name was current then.
12
+ `migrate skill-names` moves the plugin skills that carried a `claude-` prefix onto their two-word names and rewrites every citation of one. It carries two plain renames as well, where a skill carried no prefix and changed its name because the old one described a job it no longer does, landing on `ui-checklist` and `context-fold`, and one merge, where the five per-kind document drafters land on `draft-doc`. It leaves the pointer answering under the fold skill's old name in place. It shares its engine with `migrate rename` and differs in what it is scanning for: a skill name is a whole name rather than a word stem, so it matches only where the word ends, which is what keeps a longer word that merely opens with a skill name, such as `claude-worktrees`, out of it. It takes no `--scope`, since the skill folders it moves are authored in the toolkit and no target holds a copy of that catalog, which leaves a target's own citations of a renamed skill as the whole of what it rewrites there. The changelog and the eval transcripts are passed over on the argument the other sweep already carries, that each records what shipped or what a session ran under whatever name was current then.
13
13
 
14
14
  `migrate records` moves a project's session records from `.claude/` to `.canon/` and rewrites every tracked file that cites one. It reports until `--write` is passed, and refuses outright when the project does not already ignore `.canon/`, since every folder it relocates is ignored where it stands and landing one under a tracked root commits the memory pen. Take the ignore entry with `canon tooling sync --write` first.
15
15
 
@@ -59,7 +59,7 @@ The extension test is what carries most of the separation, and it costs one real
59
59
 
60
60
  Two classes resolve to nothing and are right to. Both are reported by name rather than dropped, so a reader can see what the verdict declined to judge.
61
61
 
62
- **Governed.** A rule spelling a path in its own frontmatter `paths:` is naming an artifact a target holds rather than a file here. `governance/rules/standards/diagrams.md` declares `.claude/DIAGRAMS.md` and then tells its reader to convert one an older install left behind, so the file is correctly absent from this tree and correctly named in the rule.
62
+ **Governed.** A rule spelling a path in its own frontmatter `paths:` is naming an artifact a target holds rather than a file here, so the file is correctly absent from this tree and correctly named in the rule. No shipped rule declares one today, and the stage's test fixtures carry the instance that keeps the class exercised.
63
63
 
64
64
  Only an exact declaration exempts, never a glob match against one. A glob declares a shape, so a body path sitting inside it is still a citation and a stale one is still a defect. A rule scoped at `docs/**` citing a `docs/agents/renamed.md` that moved is exactly the class this stage exists to catch, and matching the glob would excuse it.
65
65
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Slides
3
- description: What a folder of HTML slides declares for the whole deck in deck.json, what each slide declares on its own body, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
3
+ description: What a folder of HTML slides declares for the whole deck in deck.json, the faces it embeds, what each slide declares on its own body, transitions and entrances, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
4
4
  ---
5
5
 
6
6
  # Slides
@@ -22,13 +22,18 @@ canon slides render --source slides/q3-review
22
22
  | `footer` | on, with the title on the left | a band at the bottom, with the same three slots |
23
23
  | `slideNumbers` | `true` | the number at the right of the footer |
24
24
  | `mark` | none | an image path, relative to the folder, top right |
25
+ | `fonts` | none | faces to embed in the file, described below |
25
26
 
26
27
  ```json
27
28
  {
28
29
  "title": "Q3 review",
29
30
  "header": { "left": "Acme" },
30
31
  "footer": { "center": "Internal" },
31
- "mark": "assets/mark.png"
32
+ "mark": "assets/mark.png",
33
+ "fonts": [
34
+ { "family": "Inter", "path": "fonts/Inter-Regular.ttf" },
35
+ { "family": "Inter", "weight": 700, "path": "fonts/Inter-Bold.ttf" }
36
+ ]
32
37
  }
33
38
  ```
34
39
 
@@ -38,6 +43,17 @@ Slide numbers belong to the footer and hold its right slot. They show only where
38
43
 
39
44
  Prefer a raster mark. An SVG mark lands as a vector, and its fallback for a viewer that cannot draw SVG comes out broken.
40
45
 
46
+ ### Embedded faces
47
+
48
+ Each entry in `fonts` names one TrueType or OpenType file inside the deck folder, and the deck carries it so it renders in its own face on a machine without the font installed.
49
+
50
+ - `family` is required and should match the family the slides set, since that is the name PowerPoint looks the face up by.
51
+ - `weight` defaults to `400`. PowerPoint holds four faces a family, so `600` and above fills the bold slot and anything lighter fills regular.
52
+ - `style` is `normal` or `italic`, defaulting to `normal`.
53
+ - `path` is relative to the folder and has to stay inside it.
54
+
55
+ A face is refused, and the deck still written without it, when its license forbids embedding or allows a bitmap only, when it is a variable font, when it is a `woff` or `woff2` file, or when a second face lands in a slot one already fills. Supply static instances, one per weight, in place of a variable face. For `woff2`, supply the TrueType or OpenType file it was compressed from, which most font downloads ship beside it.
56
+
41
57
  ## What each slide declares
42
58
 
43
59
  A slide sets its own place in the deck through attributes on `<body>`.
@@ -55,6 +71,30 @@ Once any slide opens a section, slides ahead of the first one sit in a section n
55
71
 
56
72
  A slide dropping one band keeps the other from the master. A slide replacing a slot draws its band as its own text, so editing that band once in PowerPoint's master view reaches every slide except the ones that replaced it.
57
73
 
74
+ ## Motion
75
+
76
+ A slide declares how it arrives on `<body>`, and an element declares how it comes in on its own tag.
77
+
78
+ | Attribute | Takes | Effect |
79
+ | -------------------------- | ------------------------------- | -------------------------------------- |
80
+ | `data-transition` | `fade`, `push`, `wipe`, `cover` | the transition into this slide |
81
+ | `data-transition-duration` | `500`, `500ms`, or `0.5s` | rounded to 0.5, 0.75, or 1 second |
82
+ | `data-enter` | `fade`, `fly`, `wipe`, `zoom` | an entrance played on a click |
83
+ | `data-enter-order` | a number | the click it plays on, lowest first |
84
+ | `data-enter-duration` | `500`, `500ms`, or `0.5s` | the entrance length, 500 ms by default |
85
+
86
+ ```html
87
+ <body data-transition="fade">
88
+ <h1>Results</h1>
89
+ <div class="card" data-enter="fly" data-enter-order="1">…</div>
90
+ <div class="card" data-enter="fly" data-enter-order="2">…</div>
91
+ </body>
92
+ ```
93
+
94
+ Each entrance is its own click. Entrances without an order play after the ordered ones, in page order. An entrance brings in every shape drawn from its element and the elements inside it together, so a card's box and its text arrive on one click, and an element drawn as a picture brings in that picture. An element inside it with its own `data-enter` waits for its own click. Fly comes in from the bottom and wipe from the left.
95
+
96
+ A transition length rounds to the nearest of the three speeds PowerPoint's file format names, since a length in milliseconds needs an extension the deck does not write.
97
+
58
98
  ## The master
59
99
 
60
100
  The master takes its colors from the `<html>` element of the first slide as Chromium laid it out with the project's token stylesheet injected, so a theme switched on one slide's `<body>`, such as a dark cover, stays on that slide:
@@ -112,9 +152,13 @@ A `<figure data-chart="...">` holding a `<table>` becomes a native, editable cha
112
152
  | -------------------------------------- | ---------------------------------------------- | ---- |
113
153
  | `deck.json` field malformed or unknown | `✗` naming the file and the field | 1 |
114
154
  | `mark` path missing | `✗` naming the resolved path | 1 |
155
+ | `fonts` path missing or outside folder | `✗` naming the field and the path | 1 |
156
+ | face not embeddable | `✗` naming the path and the reason | 0 |
157
+ | unknown transition or entrance name | `✗` naming the slide, the element, the effect | 0 |
158
+ | entrance on an element that draws none | `✗` naming the slide and the element | 0 |
115
159
  | chart cell not a number | `✗` naming the slide, the figure, and the cell | 0 |
116
160
  | `data-chart` outside the five types | `✗` naming the value | 0 |
117
161
  | token role not declared | `✗` naming the role | 0 |
118
162
  | slide body sets its own `--color-text` | `✗` naming the slides | 0 |
119
163
 
120
- A refused chart is left out and the rest of the deck is written.
164
+ A refused chart, effect, or face is left out and the rest of the deck is written.
@@ -64,7 +64,7 @@ Run from a branch other than `main` or `master`, the verb also drops that branch
64
64
 
65
65
  Exit codes: `0` recorded, `1` refused. The `reason` field carries `no-board`, `no-match`, or `ambiguous`. `git-pr` skips silently on those three, because each is a case where a guessed write would archive the wrong task once the branch merges.
66
66
 
67
- A malformed argument refuses as `bad-input` instead, which sits outside that set on purpose. `git-pr` derives the number by slicing whatever `gh pr create` printed, so a non-numeric value is reachable, and folding it into the swallowed set would lose the number with nothing reporting it.
67
+ A malformed argument refuses as `bad-input` instead, which sits outside that set on purpose. `git-pr` derives the number by slicing the address the create call returned, so a non-numeric value is reachable, and folding it into the swallowed set would lose the number with nothing reporting it.
68
68
 
69
69
  ## Outcome
70
70
 
@@ -62,7 +62,9 @@ The first line reports the plan and the second applies it, relocating each rule
62
62
 
63
63
  Twenty-five plugin skills dropped their `claude-` prefix for two-word names, so `canon:claude-docs` answers as `canon:context-fold` and `canon:claude-tasks` as `canon:task-board`. A project that installed governance or tooling before that release holds files naming the old ones, and the plugin answers to none of them. A later release renamed `docs-fold` to `context-fold`, since the skill folds a session into the context entries and the task board rather than into `docs/`, and the same sweep carries a project across that rename too. The pointer that answered under the old name no longer ships, so a citation the sweep has not reached names nothing. <!-- canon-keep-retired -->
64
64
 
65
- Two of those files run rather than sit there. `.husky/post-merge` runs the `canon hooks post-merge` verb, so a stale copy of the hook calls a binary that may lack it, and `.claude/hooks/pr-create-log.sh` hands a session a message naming a skill, so a stale copy tells someone to invoke something that no longer exists. A rule under `.claude/rules/canon/core/` names skills too, though a rule is read rather than run.
65
+ The same sweep carries the merge of the five per-kind document drafters into `draft-doc`, so a citation of any one of them lands on `canon:draft-doc`.
66
+
67
+ Two of those files run rather than sit there. `.husky/post-merge` runs the `canon hooks post-merge` verb, so a stale copy of the hook calls a binary that may lack it, and `.claude/hooks/pr-create-log.sh` hands a session a message naming a skill, so a stale copy tells someone to invoke something that no longer exists. A copy older than `git-pr`'s move to REST also matches only `gh pr create`, so it stays silent on every pull request `git-pr` opens. A rule under `.claude/rules/canon/core/` names skills too, though a rule is read rather than run.
66
68
 
67
69
  Resync what the toolkit owns, then sweep what the project wrote:
68
70
 
@@ -28,7 +28,7 @@ Each domain holds its own toolkit commit, so syncing governance today does not m
28
28
 
29
29
  A project that has never synced under a toolkit new enough to write a stamp falls back to the toolkit's own git history. Installed content matching any version that history published proves the file untouched, so it reports `stale` naming the commit it came from, and content matching no published version stays `drifted`. That fallback needs the toolkit as a git checkout. Installed from the registry it ships source without history, and the report says attribution was unavailable rather than reading every file as a local edit.
30
30
 
31
- Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and reconciled with `canon:seed-sync`, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.canon/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself.
31
+ Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and reconciled with `canon:seed-sync`, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.canon/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself. A surface still at its `.claude/` spelling with nothing under `canon/`, such as `.claude/REQUIREMENTS.md`, is reported under `unmovedSurfaces`, since rules glob the `canon/` spelling alone, and `canon migrate surface-roots` moves it. <!-- canon-keep-surface-root -->
32
32
 
33
33
  `unmigrated` currently names no domain, since standards and snippets are the two the toolkit ever installed at the project root, standards closed its install channel, and snippets retired outright. A target still holding a root `standards/` folder from an older toolkit is carrying its own authoring surface now, not an unfinished install, and nothing proposes moving it. A leftover `.claude/snippets/` reports under `reverse` below instead.
34
34
 
@@ -118,24 +118,20 @@ This page is the corpus the coverage claim is measured against: every name `cano
118
118
 
119
119
  ## Generate an artifact on demand
120
120
 
121
- | Skill | When to use |
122
- | ------------------------- | ----------------------------------------------------------------------------------------------------------------- |
123
- | `canon:create-rule` | For a project-specific governance rule the toolkit does not ship |
124
- | `canon:create-skill` | For a new `SKILL.md` |
125
- | `canon:create-standard` | For a new authoring convention |
126
- | `canon:draft-docs` | For a brand-new `docs/*.md` page, drafted against `standards/docs.md` |
127
- | `canon:draft-ready` | For finished files a worker should copy, written as a ready folder with its overview, thin plan, and task |
128
- | `canon:draft-context` | For a brand-new `canon/context/<domain>.md` entry, drafted against `standards/context.md` |
129
- | `canon:draft-wireframes` | For a brand-new `canon/wireframes/<surface>.md` file, drafted against `standards/wireframes.md` |
130
- | `canon:draft-wiki` | For a brand-new wiki reference page on a subject owned outside the project, drafted against `standards/wiki.md` |
131
- | `canon:draft-figure` | For a hand-drawn figure inside an existing doc, drafted against `standards/figures.md` in Mermaid or freehand SVG |
132
- | `canon:draft-readme` | For a project's `README.md`, drafted against `standards/readme.md` |
133
- | `canon:bash-cli-script` | For a small non-interactive shell wrapper, stopping at 100 lines in favor of TypeScript on Bun |
134
- | `canon:ci-workflow` | For a GitHub Actions workflow file |
135
- | `canon:draft-slides` | For a deck, drafted as `.claude/SLIDES.md` and rendered to PowerPoint |
136
- | `canon:draft-screencast` | For a recording script with beats and defaults already seeded |
137
- | `canon:record-screencast` | For recording a screencast draft, then composing the take into a finished mp4 when the draft asks for a wrap |
138
- | `canon:draft-identity` | For a project's logo mark and its social card, drafted through `draft-and-pick`'s pick loop |
121
+ | Skill | When to use |
122
+ | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
123
+ | `canon:create-rule` | For a project-specific governance rule the toolkit does not ship |
124
+ | `canon:create-skill` | For a new `SKILL.md` |
125
+ | `canon:create-standard` | For a new authoring convention |
126
+ | `canon:draft-doc` | For a brand-new `docs/` page, context entry, wireframe surface, wiki reference page, or `README.md`, drafted against the standard for its kind |
127
+ | `canon:draft-ready` | For finished files a worker should copy, written as a ready folder with its overview, thin plan, and task |
128
+ | `canon:draft-figure` | For a hand-drawn figure inside an existing doc, drafted against `standards/figures.md` in Mermaid or freehand SVG |
129
+ | `canon:bash-cli-script` | For a small non-interactive shell wrapper, stopping at 100 lines in favor of TypeScript on Bun |
130
+ | `canon:ci-workflow` | For a GitHub Actions workflow file |
131
+ | `canon:draft-slides` | For a deck, drafted as `.claude/SLIDES.md` and rendered to PowerPoint |
132
+ | `canon:draft-screencast` | For a recording script with beats and defaults already seeded |
133
+ | `canon:record-screencast` | For recording a screencast draft, then composing the take into a finished mp4 when the draft asks for a wrap |
134
+ | `canon:draft-identity` | For a project's logo mark and its social card, drafted through `draft-and-pick`'s pick loop |
139
135
 
140
136
  ## Answer a question at any point
141
137
 
@@ -7,4 +7,3 @@ description: Write temporary files to the scratch folder structure
7
7
  ## Temporary files
8
8
 
9
9
  - Write temporary files to `.canon/tmp/<slug>/<file>.md` at the current worktree's root, a nested folder with a kebab-slug tied to the topic rather than a flat `<slug>-<file>.md`. The slug must not take one of the five reserved names `runs`, `hooks`, `handoff`, `pr`, and `render`. A skill that resolves a write at the main root instead states so in its own body.
10
- - Write to `.claude/.tmp/<slug>/` instead in a project that carries no `.canon/` root, and `canon migrate records` moves it to the first spelling. <!-- canon-keep-record-root -->
@@ -1,8 +1,7 @@
1
1
  ---
2
- description: State the hook stdin guard and the silencing rule for .claude/hooks scripts and their seeded copies
2
+ description: State the hook stdin guard and the silencing rule for .claude/hooks scripts
3
3
  paths:
4
4
  - '.claude/hooks/**/*.sh'
5
- - 'tooling/claude/seeds/.claude/hooks/**/*.sh'
6
5
  ---
7
6
 
8
7
  # Hook standards
@@ -1,8 +1,7 @@
1
1
  ---
2
- description: State the autoContinueAtUsageLimit inversion and the autoCompactWindow cap for .claude/settings.json and its seeded copy
2
+ description: State the autoContinueAtUsageLimit inversion and the autoCompactWindow cap for .claude/settings.json
3
3
  paths:
4
4
  - '.claude/settings.json'
5
- - 'tooling/claude/seeds/.claude/settings.json'
6
5
  ---
7
6
 
8
7
  # Settings standards
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for canon/ARCHITECTURE.md
4
4
  paths:
5
5
  - 'canon/ARCHITECTURE.md'
6
- - '.claude/ARCHITECTURE.md'
7
6
  ---
8
7
 
9
8
  # Architecture standards
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for canon/context/<domain>.md entries
4
4
  paths:
5
5
  - 'canon/context/**'
6
- - '.claude/context/**'
7
6
  ---
8
7
 
9
8
  # Context entry standards
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for canon/DESIGN.md
4
4
  paths:
5
5
  - 'canon/DESIGN.md'
6
- - '.claude/DESIGN.md'
7
6
  ---
8
7
 
9
8
  # Design standards
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for .canon/diagrams/<kind>.md files
4
4
  paths:
5
5
  - '.canon/diagrams/**'
6
- - '.claude/DIAGRAMS.md'
7
6
  ---
8
7
 
9
8
  # Diagram standards
@@ -13,5 +12,3 @@ paths:
13
12
  - Follow the diagrams standard for shape and content rules for .canon/diagrams/<kind>.md files. It is the single source. Read it with `canon standards diagrams`.
14
13
  - Layout, budgets, accessibility, labels, and render verification inside the fence are a separate topic. The mermaid standard routes them.
15
14
  - A diagram entry carries structure and flow, not implementation. Read the standard before adding or revising a kind.
16
- - Write a new diagram to `.canon/diagrams/<kind>.md`, never to `.claude/DIAGRAMS.md`
17
- - Convert a `.claude/DIAGRAMS.md` left by an older install into per-kind entries before editing it
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for canon/REQUIREMENTS.md
4
4
  paths:
5
5
  - 'canon/REQUIREMENTS.md'
6
- - '.claude/REQUIREMENTS.md'
7
6
  ---
8
7
 
9
8
  # Requirements standards
@@ -3,7 +3,6 @@
3
3
  description: Shape and content rules for canon/wireframes/<surface>.md files
4
4
  paths:
5
5
  - 'canon/wireframes/**'
6
- - '.claude/wireframes/**'
7
6
  ---
8
7
 
9
8
  # Wireframe standards
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "5.21.0",
4
+ "version": "5.22.0",
5
5
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
6
6
  "license": "MIT",
7
7
  "bin": {