@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.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/SKILL.md +1 -1
- package/claude/skills/auto-ship/references/draft-mark.md +8 -6
- package/claude/skills/draft-doc/REQUIREMENT.md +45 -0
- package/claude/skills/draft-doc/SKILL.md +77 -0
- package/claude/skills/draft-doc/references/context.md +31 -0
- package/claude/skills/draft-doc/references/docs.md +33 -0
- package/claude/skills/draft-doc/references/readme.md +58 -0
- package/claude/skills/draft-doc/references/wiki.md +53 -0
- package/claude/skills/draft-doc/references/wireframes.md +48 -0
- package/claude/skills/draft-figure/REQUIREMENT.md +1 -1
- package/claude/skills/draft-figure/SKILL.md +1 -1
- package/claude/skills/git-pr/SKILL.md +5 -46
- package/claude/skills/git-pr/references/final-command.md +75 -0
- package/claude/skills/git-pr/references/labels.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +76 -0
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -1
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +5 -1
- package/claude/skills/search-craft/REQUIREMENT.md +4 -4
- package/claude/skills/search-craft/SKILL.md +1 -1
- package/docs/agents/commands.md +1 -1
- package/docs/agents/drift-surfaces.md +20 -9
- package/docs/agents/index.md +2 -2
- package/docs/agents/install-and-sync.md +3 -3
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/rule-citations.md +1 -1
- package/docs/agents/slides.md +47 -3
- package/docs/agents/tasks.md +1 -1
- package/docs/target/migrations.md +3 -1
- package/docs/target/sync.md +1 -1
- package/docs/workflow/skill-map.md +14 -18
- package/governance/rules/canon/604-scratch.md +0 -1
- package/governance/rules/claude/575-hooks.md +1 -2
- package/governance/rules/claude/576-settings.md +1 -2
- package/governance/rules/standards/architecture.md +0 -1
- package/governance/rules/standards/context.md +0 -1
- package/governance/rules/standards/design.md +0 -1
- package/governance/rules/standards/diagrams.md +0 -3
- package/governance/rules/standards/requirements.md +0 -1
- package/governance/rules/standards/wireframes.md +0 -1
- package/package.json +1 -1
- package/scripts/manage-sandbox.sh +7 -8
- package/src/claude/cases/authoring.ts +5 -5
- package/src/commands/slides.ts +14 -4
- package/src/commands/sync.ts +10 -0
- package/src/gov/citations.ts +1 -2
- package/src/migrate/skill-names.ts +12 -0
- package/src/slides/convert/deck.ts +83 -3
- package/src/slides/convert/export.ts +67 -19
- package/src/slides/convert/shapes.ts +43 -3
- package/src/slides/convert/walk.ts +43 -1
- package/src/slides/package/fonts.ts +297 -0
- package/src/slides/package/motion.ts +316 -0
- package/src/slides/package/test-face.ts +113 -0
- package/src/sync/check.ts +9 -0
- package/src/sync/layout.ts +27 -1
- package/standards/architecture.md +0 -1
- package/standards/context.md +0 -1
- package/standards/design.md +0 -1
- package/standards/diagrams.md +0 -3
- package/standards/requirements.md +0 -1
- package/standards/rule.md +1 -0
- package/standards/wireframes.md +0 -1
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +8 -3
- package/claude/skills/draft-context/REQUIREMENT.md +0 -37
- package/claude/skills/draft-context/SKILL.md +0 -61
- package/claude/skills/draft-docs/REQUIREMENT.md +0 -35
- package/claude/skills/draft-docs/SKILL.md +0 -59
- package/claude/skills/draft-readme/REQUIREMENT.md +0 -38
- package/claude/skills/draft-readme/SKILL.md +0 -73
- package/claude/skills/draft-wiki/REQUIREMENT.md +0 -42
- package/claude/skills/draft-wiki/SKILL.md +0 -83
- package/claude/skills/draft-wireframes/REQUIREMENT.md +0 -38
- 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.
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
package/docs/agents/commands.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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`, `
|
|
11
|
-
`newRules`, and `reverse`. None of them produces a change, and no
|
|
12
|
-
applies any of them. The headings below group the first
|
|
13
|
-
`newSkills` its description under `newRules`, which answers the
|
|
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
|
|
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
|
|
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.
|
package/docs/agents/index.md
CHANGED
|
@@ -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
|
|
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
|
-
|
|
237
|
-
that walk cannot see: `seeds`, `superseded`, `unmigrated`, `
|
|
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
|
|
package/docs/agents/migrate.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
package/docs/agents/slides.md
CHANGED
|
@@ -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.
|
package/docs/agents/tasks.md
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
package/docs/target/sync.md
CHANGED
|
@@ -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-
|
|
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-
|
|
129
|
-
| `canon:
|
|
130
|
-
| `canon:
|
|
131
|
-
| `canon:draft-
|
|
132
|
-
| `canon:draft-
|
|
133
|
-
| `canon:
|
|
134
|
-
| `canon:
|
|
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
|
|
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
|
|
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/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
|