@erclx/canon 4.62.1 → 4.64.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 (41) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/canon-cli/REQUIREMENT.md +7 -3
  3. package/claude/skills/canon-cli/SKILL.md +8 -2
  4. package/claude/skills/canon-record/REQUIREMENT.md +34 -0
  5. package/claude/skills/canon-record/SKILL.md +54 -0
  6. package/claude/skills/canon-screencast/REQUIREMENT.md +1 -1
  7. package/claude/skills/canon-screencast/SKILL.md +3 -3
  8. package/claude/skills/claude-autoship/REQUIREMENT.md +3 -1
  9. package/claude/skills/claude-autoship/SKILL.md +26 -12
  10. package/claude/skills/{context-draft → draft-context}/REQUIREMENT.md +3 -3
  11. package/claude/skills/{context-draft → draft-context}/SKILL.md +1 -1
  12. package/claude/skills/{docs-draft → draft-docs}/REQUIREMENT.md +1 -1
  13. package/claude/skills/{docs-draft → draft-docs}/SKILL.md +1 -1
  14. package/claude/skills/draft-readme/REQUIREMENT.md +36 -0
  15. package/claude/skills/draft-readme/SKILL.md +65 -0
  16. package/claude/skills/{wireframe-draft → draft-wireframes}/REQUIREMENT.md +3 -3
  17. package/claude/skills/{wireframe-draft → draft-wireframes}/SKILL.md +1 -1
  18. package/claude/skills/identity/REQUIREMENT.md +40 -0
  19. package/claude/skills/identity/SKILL.md +86 -0
  20. package/claude/skills/repo-metadata/SKILL.md +6 -5
  21. package/claude/skills/test-first/REQUIREMENT.md +34 -0
  22. package/claude/skills/test-first/SKILL.md +24 -0
  23. package/docs/agents/demo.md +2 -0
  24. package/docs/agents/review-classification.md +2 -2
  25. package/docs/workflow/ai-workflow.md +23 -19
  26. package/docs/workflow/visual-design-workflow.md +1 -0
  27. package/governance/rules/core/070-planning.md +1 -0
  28. package/package.json +3 -1
  29. package/scripts/core/regen-agent-fixture.sh +1 -1
  30. package/src/claude/cases/authoring.ts +7 -3
  31. package/src/claude/cases/claude-workflow.ts +5 -0
  32. package/src/claude/cases/misc.ts +10 -0
  33. package/src/commands/tooling.ts +8 -1
  34. package/src/project-root.ts +34 -0
  35. package/src/shipped/references.ts +45 -15
  36. package/standards/readme.md +2 -0
  37. package/tooling/astro/configs/eslint.config.js +7 -1
  38. package/tooling/astro/reference.md +1 -1
  39. package/tooling/nextjs/configs/eslint.config.js +3 -2
  40. package/tooling/nextjs/reference.md +1 -1
  41. package/tooling/web/configs/eslint.config.js +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "4.62.1",
4
+ "version": "4.64.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: canon-cli
3
- description: Why the overwrite contract is stated before a sync runs, and why the skill reads rather than executes
3
+ description: Why a session is pointed at the verb catalog, the reference docs, and the overwrite contract from one place, and why the skill reads rather than writes
4
4
  ---
5
5
 
6
6
  # Canon cli requirement
@@ -17,17 +17,20 @@ Being reachable is a separate problem from being right. This is a pure reference
17
17
 
18
18
  The two bodies now carrying an inline pointer are `claude-seed-sync` and `canon-operator`, each at the point it runs or prints an overwriting command.
19
19
 
20
+ A third gap sits beside the first two, aimed at a different question. `canon --help` lists every top-level verb and `canon docs` emits the toolkit's own reference corpus, but no reference skill pointed a session at either. The one skill that does, `canon-operator`, is user-invoked only and reaches them as a side effect of its own orientation step. A session guessing at a verb's name, or restating what a doc already answers, is the same missing-fact failure the overwrite gap names.
21
+
20
22
  ## Must
21
23
 
22
24
  - State per surface and per command whether an existing file is overwritten, merged, written once, or left alone
23
25
  - Warn about a destructive run before it happens, naming the surface that will be lost
24
26
  - Name the section-preserving path for a standard or seed the project has customized
25
27
  - Defer to the toolkit's own context docs when they and this summary disagree, since the summary is a copy and they are the source
28
+ - Point to `canon docs agents` for the verb catalog and to `canon docs` for the reference corpus, rather than restating either
26
29
 
27
30
  ## Must not
28
31
 
29
- - Run any `canon` command. The skill is read before acting.
30
- - Restate the full semantics. It is a target-session summary and the detail lives with its owner.
32
+ - Run, or send the session to run, a `canon` command that writes or installs. The skill is read before acting on a sync.
33
+ - Restate the verb catalog or a reference doc's content. Point to `canon docs agents` or `canon docs <topic>` instead. The overwrite table is this skill's one authored exception, and it too is a target-session summary, with the detail living with its owner.
31
34
  - Take a mention in a sibling's requirement file as an inbound route. The three bodies named in the gap above carry the pointer, and adding a fourth means editing that body rather than its requirement.
32
35
 
33
36
  ## Guards
@@ -39,3 +42,4 @@ The two bodies now carrying an inline pointer are `claude-seed-sync` and `canon-
39
42
  - Executing the sync, which the user runs or `canon-operator` routes
40
43
  - Reconciling a customized seed section by section: `claude-seed-sync`
41
44
  - Deciding which stack, rule, or standard a project should install, which the setup skills resolve from live catalogs
45
+ - Diagnosing what a project is behind on, or executing the fix: `canon-operator`
@@ -1,11 +1,17 @@
1
1
  ---
2
2
  name: canon-cli
3
- description: Reference for what canon sync and install commands overwrite, merge, or leave untouched in a target project. Use before running `canon tooling`, `canon standards`, `canon claude sync`, or `canon init`, or when asked "will this overwrite my changes". Do NOT use to run the commands, only to know their effect.
3
+ description: Reference for what a canon verb does before you run it. Run `canon docs agents` for the full command catalog, `canon docs` for any other reference doc, and read this skill's own table for what a sync or install command overwrites, merges, or leaves untouched in a target project. Use when asked "which canon command do I run", "is there a doc for X", "will this overwrite my changes", or before running `canon tooling`, `canon standards`, `canon claude sync`, or `canon init`. Do NOT use to execute a sync, an install, or a docs lookup, only to know which command answers the question.
4
4
  ---
5
5
 
6
6
  # Toolkit CLI contract
7
7
 
8
- What each `canon` sync or install command does to existing files in a target project. Consult before running one, then warn the user about anything destructive. This skill is reference only. It does not run commands.
8
+ Consult before running an unfamiliar `canon` verb, before a sync or install, or when asked "will this overwrite my changes". This skill is reference only. It never runs a sync or an install.
9
+
10
+ ## Verb catalog and reference docs
11
+
12
+ - Run `canon docs agents` for the full command catalog and invocation contract, rather than guessing at a verb from its name.
13
+ - Run `canon docs list` for every other reference doc, then `canon docs <topic>` by name.
14
+ - State neither list here. Both read live off the CLI, and a copy in this body ships on a different cadence than the commands it names.
9
15
 
10
16
  ## Overwrite contract
11
17
 
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: canon-record
3
+ description: Why compiling and running a screencast draft needs a routed skill rather than an operator typing two verbs by hand, and why the unresolved-field refusal cannot be a suggestion
4
+ ---
5
+
6
+ # Canon record requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, `canon-screencast` writes a draft and names `canon demo compile` as the next step, and nothing after that routes a session there or to `canon demo run`. An operator has to know both verbs, type them in order, and read the compile record for unresolved fields by hand. A session that fills one in on its own reproduces the exact failure `canon demo run`'s `plan-unresolved` reason exists to catch, one layer up where nothing enforces it.
11
+
12
+ ## Must
13
+
14
+ - Resolve the default plan path the same way `canon demo compile` does, so a caller passing only the draft path reaches the plan without naming it
15
+ - Skip compiling when a plan already exists at that path, since its timing may be tuned by hand and a draft cannot reproduce that
16
+ - Report every unresolved field from the compile or run record and stop rather than filling one in
17
+ - Report every path a run wrote, video, mp4, gif, still, skipping any the record carries as null
18
+
19
+ ## Must not
20
+
21
+ - Pass `--force` to compile
22
+ - Guess or fill a target, a URL, or any other unresolved field
23
+ - Drive the application through anything other than `canon demo run`
24
+ - Assume this skill's own invocation frequency needs no check. `canon-screencast`'s closing block names it by hand, but whether anything else reaches for it beyond that pointer or an operator typing its name has no answer at creation time, so a review pass some months in should read that back rather than take it on faith.
25
+
26
+ ## Guards
27
+
28
+ - No draft path given: stop rather than guessing what to compile
29
+
30
+ ## Out of scope
31
+
32
+ - Drafting the beats, which `canon-screencast` owns
33
+ - Filling an existing plan's target or URL, which is the operator's own edit
34
+ - Verifying a recording beyond its own caption, which nothing in the toolkit does yet
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: canon-record
3
+ description: Drives a screencast draft through to a recording. Compiles it with `canon demo compile` when no plan exists yet at the default path, skipping compile when one is already there, then runs `canon demo run` once nothing is unresolved. Reports every unresolved field from the compile or run record and stops rather than guessing one. Use when asked to "record the screencast", "run the demo", "compile and record this draft", or right after `canon-screencast` prints its next-step line. Do NOT use to draft the beats, which is `canon-screencast`, or to fill in a plan's target or URL, which is the operator's own edit.
4
+ ---
5
+
6
+ # Canon record
7
+
8
+ ## Guards
9
+
10
+ - If no draft path is given, stop: `❌ No draft path. Pass the path canon-screencast printed.`
11
+ - Never guess or fill an unresolved field, a target, a URL, or anything else the compile or run record names. Report it and stop. Filling one in reproduces the failure `canon demo run`'s `plan-unresolved` reason exists to catch, one layer up where nothing enforces it.
12
+ - Never pass `--force` to compile. A plan already at the default output path may carry timing tuned by hand, and the draft cannot reproduce that, so leave it untouched.
13
+ - Drive the application through `canon demo run` alone. Never open a browser, click through the app, or write to the output paths some other way.
14
+
15
+ ## Step 1: resolve the plan path
16
+
17
+ Derive the default plan path the same way `canon demo compile` does: `<out>/<slug>.json`, where `<out>` defaults to `demos` and `<slug>` defaults to the draft's filename with its extension stripped. `.canon/tmp/screencast/inline-edit.md` resolves to `demos/inline-edit.json`.
18
+
19
+ ## Step 2: compile only when no plan exists yet
20
+
21
+ Check whether the resolved plan path already exists.
22
+
23
+ - **It exists.** A person may have tuned it by hand since compiling. Skip compiling and go to Step 3 with this path.
24
+ - **It does not exist.** Run:
25
+
26
+ ```bash
27
+ canon demo compile <draft> --json
28
+ ```
29
+
30
+ Branch on the record rather than the exit code:
31
+ - `reason: draft-missing` or `reason: draft-unreadable`: report the reason, plus the record's `message` when it carries one, and stop.
32
+ - No `reason` key, meaning the plan was written: read `unresolved` off the record.
33
+ - Non-empty: report the plan path and every field the array names, one per line, and stop. Do not proceed to Step 3.
34
+ - Empty: continue to Step 3 with the record's `plan` path.
35
+
36
+ ## Step 3: run
37
+
38
+ Run:
39
+
40
+ ```bash
41
+ canon demo run <plan> --json
42
+ ```
43
+
44
+ Branch on the record's `reason`:
45
+
46
+ - `plan-unresolved`: report every field in `unresolved`, one per line, and stop. This is the path a pre-existing plan takes, since Step 2 skipped compiling and never read its fields.
47
+ - Any other reason (`plan-missing`, `plan-unreadable`, `no-output-requested`, `cursor-unreadable`, `engine-missing`, `browser-missing`): report the reason, plus the record's `message` or `install` line when it carries one, and stop.
48
+ - No `reason` key, meaning the run wrote its output: continue to Step 4.
49
+
50
+ ## Step 4: output
51
+
52
+ The record carries `video`, `mp4`, `gif`, and `still`, each a path or `null`. Report each one that is not `null`, one per line, skipping the rest.
53
+
54
+ Say so plainly if `canon demo compile` or `canon demo run` is not available, rather than driving the application some other way. Both ship with the CLI and this skill ships with the plugin, so a project carrying one and not the other is a real state.
@@ -33,7 +33,7 @@ A draft that names the recording software, the editing software, or the window m
33
33
 
34
34
  ## Out of scope
35
35
 
36
- - Producing the recording, which stops at the script by design
36
+ - Producing the recording, which `canon-record` owns
37
37
  - Refining an existing draft, which is a direct edit of the file
38
38
  - Slide decks, which `canon-slides-draft` owns
39
39
  - Where the recording ships, which the draft lists and the user decides
@@ -8,7 +8,7 @@ description: Drafts a screencast script with pre-seeded beats, defaults, and dec
8
8
  ## Guards
9
9
 
10
10
  - If no topic is provided, stop: `❌ No screencast topic. Describe what you are recording.`
11
- - Draft, then hand off. Do not edit video or generate captions, and do not drive the application. A recording is another command's job rather than something forbidden: write the draft, name `canon demo compile` as the next step, and stop.
11
+ - Draft, then hand off. Do not edit video or generate captions, and do not drive the application. A recording is another skill's job rather than something forbidden: write the draft, name `canon-record` as the next step, and stop.
12
12
  - Stack-agnostic in the draft. Never name a recording tool, an editing tool, a font, or a window manager. Keep selectors, URLs, wait conditions, and timings out of the beats too, since those four are exactly what the compiler adds in a plan of its own. A beat carrying them stops being a document a person can read and edit down.
13
13
 
14
14
  ## Step 1: read the project context
@@ -159,9 +159,9 @@ Print the file path on its own line and a one-line summary. Do not paraphrase th
159
159
  Draft has 5 beats and pre-seeded defaults. Edit the beats and the resolved decisions.
160
160
 
161
161
  To record it rather than shoot it by hand:
162
- canon demo compile .canon/tmp/screencast/<slug>.md
162
+ canon-record .canon/tmp/screencast/<slug>.md
163
163
  ```
164
164
 
165
- Name the command and stop there. Do not compile the draft, do not run it, and do not generate captions. The operator edits the beats first, and the compiler reports which selectors and URLs they still owe it.
165
+ Name the skill and stop there. Do not compile the draft, do not run it, and do not generate captions. The operator edits the beats first, and the compiler reports which selectors and URLs they still owe it.
166
166
 
167
167
  Say so plainly if `canon demo compile` is not available, rather than driving the application some other way. The command ships with the CLI and the skills ship with the plugin, so a project carrying one and not the other is a real state.
@@ -16,6 +16,7 @@ Review is the step that varies most. It gets skipped on a diff that needed one,
16
16
  - Take the approved plan for the branch as the scope, and implement only what it describes
17
17
  - Give every step a stop condition, and leave the code on the branch and the receipts on disk at each one
18
18
  - Classify the changed-file list by path as well as by extension, so informational prose skips a code review with no signal on it and executable prose still reaches one
19
+ - Check the branch's committed history for a test-order violation between verify and review, and report any finding without gating on it, matching the verb's own contract
19
20
  - Split findings by origin, stopping on a critical or should-fix one the branch inherited and repairing one this run caused
20
21
  - Own the review receipt's lifetime, since this chain writes it, cites it in its own closing block, and is the only body that can read whether the step keeping it is still using it
21
22
  - Delegate the ship sequence to `git-ship` rather than restating it, and name only what this chain adds to it
@@ -34,6 +35,7 @@ Review is the step that varies most. It gets skipped on a diff that needed one,
34
35
  - Run the memory Apply phase. Promoting an entry changes how the agent operates and ships as its own change.
35
36
  - Read an empty changed-file list as prose-only. It satisfies that test vacuously and would route the branch past review instead of through it.
36
37
  - Read a markdown extension as evidence the change only informs. A skill body, a governance rule, and a standard are behavior written in prose.
38
+ - Stop the chain or rewrite a commit over a test-order finding. The verb reports and never gates, and a commit already in history is a different act from the work this run is building.
37
39
 
38
40
  ## Guards
39
41
 
@@ -47,4 +49,4 @@ Review is the step that varies most. It gets skipped on a diff that needed one,
47
49
 
48
50
  - Writing the plan, which `claude-feature` owns. This chain starts from one already approved.
49
51
  - The behavior of each step, owned by the skill invoked. This skill owns the order and the stop conditions.
50
- - The ship sequence and the resume path after a stop, both of which `git-ship` owns. That skill is the tail of this chain, invoked at Step 7 rather than copied into it, so the overlap is one body reached two ways rather than two bodies stating one order.
52
+ - The ship sequence and the resume path after a stop, both of which `git-ship` owns. That skill is the tail of this chain, invoked at Step 8 rather than copied into it, so the overlap is one body reached two ways rather than two bodies stating one order.
@@ -17,7 +17,7 @@ Chain the post-plan pipeline in a single run. Every step has a stop condition. S
17
17
 
18
18
  ## Diff baseline
19
19
 
20
- Step 5 classifies the changed-file list to decide whether review runs. Resolve the base ref once:
20
+ Step 6 classifies the changed-file list to decide whether review runs. Resolve the base ref once:
21
21
 
22
22
  ```bash
23
23
  git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main 2>/dev/null
@@ -27,7 +27,7 @@ Prefer `origin/main` over local `main`. A local `main` trailing the remote pulls
27
27
 
28
28
  The baseline is unusable when no merge base resolves against either ref. Stop: `❌ No diff baseline against main. Fetch origin, then re-run autoship.`
29
29
 
30
- The base equalling HEAD stays usable here, unlike in the four read-only siblings carrying this section. Step 5 runs before anything is committed, since `git-stage` commits at Step 7, so the base equals HEAD on every ordinary run. The classifier diffs the base against the working tree rather than against HEAD, which keeps the uncommitted work in the set at correct scope. Do not port the sibling `base == HEAD` stop into this skill.
30
+ The base equalling HEAD stays usable here, unlike in the four read-only siblings carrying this section. Step 6 runs before anything is committed, since `git-stage` commits at Step 8, so the base equals HEAD on every ordinary run. The classifier diffs the base against the working tree rather than against HEAD, which keeps the uncommitted work in the set at correct scope. Do not port the sibling `base == HEAD` stop into this skill.
31
31
 
32
32
  ## Step 0: take the role, then enter a worktree
33
33
 
@@ -103,7 +103,21 @@ Run the verify commands defined in `CLAUDE.md` (lint, typecheck, tests). On fail
103
103
 
104
104
  Do not loop. Do not bypass hooks.
105
105
 
106
- ## Step 4: UI test (conditional)
106
+ ## Step 4: test order
107
+
108
+ Run `canon gov test-order --json` from the worktree this chain is building in, which is the one tree holding the branch's own commits. The Guards send a `.canon/plans/` and a `.canon/review/` read to the main worktree root and this is not one of those: that checkout sits on the trunk on an ordinary run, so the range closes on itself there and every finding the branch carries reads as clean.
109
+
110
+ The verb reads git history rather than the working tree, so a branch with nothing committed yet reads as clean, and what it catches is a violation that already reached this branch's history in an earlier session or an earlier round of this chain. It reports and never gates, since nothing wires its exit into a push, so branch on the record's `kind` and its `findings` array rather than on the exit, which reads 2 on a finding and 1 on a refusal and which a shell function wrapping `canon` can flatten to zero either way.
111
+
112
+ - `kind: 'measured'`, `findings` empty. Nothing on the branch reached history ahead of its test. Continue to Step 5.
113
+ - `kind: 'measured'`, `findings` non-empty. Report each pair's `subject` and `reason` to the user and continue to Step 5. Do not stop the chain and do not attempt a fix: the commit already reached history, and rewriting it here rewrites what an earlier run shipped rather than what this run is building.
114
+ - `kind: 'unreadable'`. Report the `message` and continue to Step 5. A shallow clone or a repository with no trunk is an ordinary state this check cannot read, not a reason to stop shipping.
115
+
116
+ ### When the verb is absent
117
+
118
+ The verb ships with the CLI and this body ships with the plugin, matching Step 6's own fallback for the classify verb. Report that the check did not run rather than reading a missing subcommand as clean, and continue to Step 5.
119
+
120
+ ## Step 5: UI test (conditional)
107
121
 
108
122
  If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:claude-ui-test`.
109
123
 
@@ -111,7 +125,7 @@ If `claude-ui-test` produces a manual checklist, stop: `❌ UI requires visual v
111
125
 
112
126
  If all UI changes are covered by e2e tests, continue.
113
127
 
114
- ## Step 5: review
128
+ ## Step 6: review
115
129
 
116
130
  Classify the diff first. Take the union of `git diff --name-only <base>` and `git ls-files --others --exclude-standard`, resolving `<base>` per Diff baseline, then hand that set to the verb rather than reading it against the list below yourself:
117
131
 
@@ -121,7 +135,7 @@ canon autoship classify --json <path>...
121
135
 
122
136
  The verb reads names only and touches git not at all, so the set stays the one this step already computed and no second baseline resolves to disagree with the first. Branch on the record's `decision` rather than on the exit code, which a shell function wrapping `canon` can flatten to zero.
123
137
 
124
- - `skip`. Every path reads as prose and none states agent behavior. Skip review entirely and continue to Step 7.
138
+ - `skip`. Every path reads as prose and none states agent behavior. Skip review entirely and continue to Step 8.
125
139
  - `review`. Invoke `canon:claude-review`. The record names the `file` that decided it and the `test` it failed, `extension` for a path that is not prose and `behavior-path` for prose that states what an agent does.
126
140
  - `refused`, carrying reason `no-changes`. The changed set was empty, so take the stop below.
127
141
 
@@ -137,7 +151,7 @@ The verb ships with the CLI and this body ships with the plugin, so a target hol
137
151
 
138
152
  Never read an absent subcommand as a skip. Failing open is the exact defect the verb closes, and a shell that answers `command not found` reaching a body that skips on anything other than a `skip` record would ship every branch unreviewed.
139
153
 
140
- The skip needs both tests to pass: every changed file matches `*.md` or `*.txt`, and no changed file sits under a behavior path. On a pass, skip review entirely and continue to Step 7. Otherwise invoke `canon:claude-review`.
154
+ The skip needs both tests to pass: every changed file matches `*.md` or `*.txt`, and no changed file sits under a behavior path. On a pass, skip review entirely and continue to Step 8. Otherwise invoke `canon:claude-review`.
141
155
 
142
156
  Behavior paths carry two spellings, the one a surface authors at and the one it reaches a session at, so the rule reads the same in a toolkit and in a project that consumed one:
143
157
 
@@ -156,9 +170,9 @@ The list covers this toolkit's authoring layout and the layout it installs, whic
156
170
 
157
171
  The verb reads the same set from `src/autoship/paths.ts`, so a path added here belongs there too and a path added there belongs here. Two copies is what the fallback costs, and it stands until a release retires the written half.
158
172
 
159
- ## Step 6: evaluate findings
173
+ ## Step 7: evaluate findings
160
174
 
161
- Skip this step when Step 5 skipped review. Otherwise read `.canon/review/branch/review-<slug>.md` at the main worktree root. Split every finding by origin before parsing the summary line (`X critical, Y should-fix, Z minor`), since the stop exists for a defect the branch inherited rather than for one this run introduced.
175
+ Skip this step when Step 6 skipped review. Otherwise read `.canon/review/branch/review-<slug>.md` at the main worktree root. Split every finding by origin before parsing the summary line (`X critical, Y should-fix, Z minor`), since the stop exists for a defect the branch inherited rather than for one this run introduced.
162
176
 
163
177
  - **This run caused it, at any severity.** Fix it, re-run the Step 3 verify commands, re-read the fixed file against what the finding claimed, and continue. Do not report it as a stop and do not offer the fix as a choice, which is the same stop wearing a proposal.
164
178
  - **It predates this run, critical or should-fix.** Stop: `❌ Review found non-minor issues that predate this run. See .canon/review/branch/review-<slug>.md. Fix and run /git-ship.`
@@ -168,9 +182,9 @@ Read origin as causation rather than authorship. Staleness this run induced in a
168
182
 
169
183
  Bound the repair at one pass, the way Step 3 bounds verify. When that re-read shows the finding still standing, stop: `❌ A self-introduced finding survived one fix pass. See .canon/review/branch/review-<slug>.md. Fix and run /git-ship.`
170
184
 
171
- This chain owns the receipt's lifetime, which is what makes the Output block's citation resolve on a run that reaches it. `claude-docs` used to delete the current slug's receipt while running under Step 7 below, so the closing line named a file the same run had already removed. That sweep now reaches only reports whose branch is gone, which collects this one a branch later rather than during the run that wrote it. The cost is one receipt per live branch left in `.canon/review/branch/`, bounded by the branch count rather than by the lifetime of the checkout.
185
+ This chain owns the receipt's lifetime, which is what makes the Output block's citation resolve on a run that reaches it. `claude-docs` used to delete the current slug's receipt while running under Step 8 below, so the closing line named a file the same run had already removed. That sweep now reaches only reports whose branch is gone, which collects this one a branch later rather than during the run that wrote it. The cost is one receipt per live branch left in `.canon/review/branch/`, bounded by the branch count rather than by the lifetime of the checkout.
172
186
 
173
- ## Step 7: ship
187
+ ## Step 8: ship
174
188
 
175
189
  Invoke `canon:git-ship`. That body owns the sequence, being the verify gate, memory capture, both doc syncs, staging, the commit grouping, the branch rename, the pull request, the CI watch, and the scoped memory review, along with the reason each step sits where it does. This step used to restate that list and the two drifted apart with nothing comparing them, so read the order there and never here.
176
190
 
@@ -201,11 +215,11 @@ Respond with up to five lines:
201
215
  <Memory proposal at .canon/review/memory/memory-review-<slug>.md>
202
216
  ```
203
217
 
204
- `<state>` is whatever the Step 7 read returned, being `draft` or `ready, unsupervised`, rather than the state the undo asked for. Writing the word `draft` there unconditionally is what this line used to do, and it named a state no step had read.
218
+ `<state>` is whatever the Step 8 read returned, being `draft` or `ready, unsupervised`, rather than the state the undo asked for. Writing the word `draft` there unconditionally is what this line used to do, and it named a state no step had read.
205
219
 
206
220
  Omit the second line if there were no minor findings, and the third if nothing routed. Omit the fourth and fifth if `claude-memory-capture` wrote no memory file this session, since an empty pen means no scoped review and no proposal. A run that routes every fact and writes none is the shape to expect, and it reports three lines.
207
221
 
208
- This block replaces the one `git-ship` closes on rather than following it. The two carry the same three trailing lines and differ on the two above them, since the first names the state the read returned and the second reports the minor findings Step 6 kept, neither of which that body has a counterpart for. Emitting both reports one run twice and buries the state under a `✅ Shipped` that does not name it.
222
+ This block replaces the one `git-ship` closes on rather than following it. The two carry the same three trailing lines and differ on the two above them, since the first names the state the read returned and the second reports the minor findings Step 7 kept, neither of which that body has a counterpart for. Emitting both reports one run twice and buries the state under a `✅ Shipped` that does not name it.
209
223
 
210
224
  ## Failure recovery
211
225
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: context-draft
2
+ name: draft-context
3
3
  description: Why a brand-new .claude/context/<domain>.md entry needs a catalog collision check and a confirm step, not the refresh path claude-docs already owns
4
4
  ---
5
5
 
@@ -32,6 +32,6 @@ Without this skill, a session documenting a domain that has no context entry yet
32
32
  ## Out of scope
33
33
 
34
34
  - Refreshing an existing `.claude/context/<domain>.md` entry against a diff: `claude-docs`
35
- - Drafting a `.claude/wireframes/<surface>.md` file: `wireframe-draft`
36
- - Drafting a `docs/*.md` page: `docs-draft`
35
+ - Drafting a `.claude/wireframes/<surface>.md` file: `draft-wireframes`
36
+ - Drafting a `docs/*.md` page: `draft-docs`
37
37
  - Drafting a standard, a snippet, or a governance rule: `create-standard`, `create-snippet`, `create-rule`
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: context-draft
2
+ name: draft-context
3
3
  description: Drafts a brand-new `.claude/context/<domain>.md` entry against the context standard, checks the catalog for a name-or-topic collision, decides flat-file placement, confirms with the user, then writes. Use when asked to "write a context entry for X", "document the X domain", "add a context entry for X", or "create a .claude/context page for X" where no existing entry covers the domain. Do NOT use to refresh an existing entry against a diff, which is `claude-docs`.
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: docs-draft
2
+ name: draft-docs
3
3
  description: Why a brand-new docs/*.md page needs a placement decision and a confirm step, not the rewrite path docs-sync already owns
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: docs-draft
2
+ name: draft-docs
3
3
  description: Drafts a brand-new `docs/*.md` page against the docs standard, decides its placement in the existing catalog, confirms with the user, then writes. Use when asked to "add a docs page for X", "write a new doc for X", "document X under docs/", or "create a docs page for X" where no existing page covers the topic. Do NOT use to rewrite or sync an existing `docs/*.md` section against a diff, which is `docs-sync`.
4
4
  ---
5
5
 
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: draft-readme
3
+ description: Why a README needs a project-type read and a confirm step, not the rewrite path docs-sync already owns
4
+ ---
5
+
6
+ # Readme draft requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session drafting a README either copies the generic template from memory or reaches for `docs-sync`, which has nothing to diff a nonexistent page against and reports the topic as unrelated to any change. A scaffold-written stub meets the same dead end, since no diff touches it either. Either way the page ships with no read of `standards/readme.md`, no read of what the project actually is, and no badge chosen against its rendered value rather than its service name.
11
+
12
+ A README whose real documentation lives in `.claude/context/` or `docs/` was a second gap the standard itself carried until this build: nothing named a pointer page as complete, so a session drafting one either padded the page or read the required list as unsatisfied.
13
+
14
+ ## Must
15
+
16
+ - Read `standards/readme.md` before drafting, since its `## Voice` section is scoped to a repository-root README and yields to `write-human`'s reference voice everywhere else
17
+ - Detect every project type the standard's `## Content` list applies to, from the manifest and the tree, rather than drafting against the closest single type
18
+ - Treat an existing README with no H1, or with headings that name only the scaffold that wrote it, as unedited generator output to draft over rather than a page to sync section by section
19
+ - Verify a candidate badge by the value it would render rather than by a fetch's status code, since a badge service answers 200 for a query it cannot satisfy
20
+ - Confirm the resolved path, the detected types, the badge candidates, and the full content with the user before writing, since project-type detection and badge selection are judgment calls with no diff to preview them against
21
+
22
+ ## Must not
23
+
24
+ - Rewrite an authored README. One carrying an H1 that names the project refuses toward `docs-sync`.
25
+ - Offer to overwrite an authored README on the refusal path, or propose conforming it to what this skill would have drafted. A target project's own citations into its README are invisible from here, so the refusal reports rather than proposes.
26
+ - Assume this skill's own invocation frequency needs no check. Whether anything reaches for it beyond an author typing its name has no answer at creation time, so a review pass some months in should read that back rather than take the assumption on faith.
27
+
28
+ ## Guards
29
+
30
+ - The target already exists and is authored, carrying an H1 that names the project: stop and point at `docs-sync` instead.
31
+
32
+ ## Out of scope
33
+
34
+ - Rewriting or syncing an existing authored `README.md` against a diff since main: `docs-sync`
35
+ - The consumer-facing reference under `docs/`: `draft-docs`
36
+ - Product scope and goals, and every other surface `standards/readme.md` already scopes out of its own governance
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: draft-readme
3
+ description: Drafts a project's README.md against the readme standard, detecting project type and badge candidates, and confirming with the user before write. Use when asked to "write a README", "draft a README for this project", "add a README", or "create a README.md" where none exists yet or the existing one is unedited scaffold output. Do NOT use to rewrite or resync an existing authored README against a diff, which is `docs-sync`.
4
+ ---
5
+
6
+ # Readme draft
7
+
8
+ Drafts a project's `README.md` end to end: read the standard, detect the project's shape, confirm the draft with the user, then write.
9
+
10
+ Read these files in parallel:
11
+
12
+ - `${CLAUDE_SKILL_DIR}/../../standards/readme.md`: voice, structure, required and optional sections, badge selection, and what to link out to rather than carry. Voice is claimed here for a repository-root README, and `write-human` yields it there while keeping rhythm, density, and the machine-tell catalog everywhere, root README included.
13
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
14
+ - The `write-human` skill: rhythm, density, and sentence construction for all generated text
15
+
16
+ ## Guards
17
+
18
+ - Default the target to `README.md` at the repository root when no path is given. A caller naming a path under a folder, a harness, or an internal tool is drafting a nested README instead, which keeps the reference voice per the standard's `## Voice` section rather than the root voice below.
19
+ - Read the target if it exists.
20
+ - It carries an H1 naming the project: it is authored. Stop: `❌ <path> already exists and covers the project. Run canon:docs-sync instead.`
21
+ - It carries no H1, or its only headings restate the tool that scaffolded it rather than the project: it is unedited generator output. Continue, drafting over it rather than syncing its sections.
22
+ - It does not exist: continue.
23
+ - A hand-authored README opening with a badge block, or a title in some other form the H1 test misses, falls into the no-H1 branch the same as a scaffold page. The Confirm step below is what catches that case before the write happens, so treat it as load-bearing rather than a courtesy: never skip it on the reasoning that the guard already decided.
24
+
25
+ ## Detect
26
+
27
+ - Read the project's manifest (`package.json`, `pyproject.toml`, `Cargo.toml`, or equivalent) for a `bin` field or CLI entry point, an installable package name, and its declared dependencies.
28
+ - Check for a `claude/skills/` or `.claude/skills/` folder, a `plugin.json`, or a marketplace manifest, each naming an agent-facing or marketplace-distributed surface.
29
+ - A project is often several of these at once. Note every type that applies rather than stopping at the first match, since the Draft step covers each one the project actually is.
30
+
31
+ ## Draft
32
+
33
+ - Draft the page against `${CLAUDE_SKILL_DIR}/../../standards/readme.md`: H1, a 2-3 sentence description in plain text, then the required sections, then whichever optional sections and per-type content the Detect step found.
34
+ - Cover every applicable project type from the standard's `## Content` list rather than picking the closest one.
35
+ - Candidate badges: check for a published package (a registry field in the manifest), a CI workflow, and a `LICENSE` file.
36
+ - State each candidate's rendered value in the preview rather than trusting a fetch's status code, since a badge service answers 200 for a query it cannot satisfy.
37
+ - Pin a status badge to the branch the standard names and confirm the workflow actually triggers on that branch before offering it. Zero badges is a correct answer when nothing passes the test.
38
+
39
+ ## Confirm
40
+
41
+ - Show the resolved path, the detected project types, the badge candidates and what backs each one, and the full drafted content before writing.
42
+ - Confirm with the user. This skill waits for that answer rather than treating the tool permission dialog as the gate, since project-type detection and badge selection are judgment calls with no diff to preview them against.
43
+
44
+ ## Write
45
+
46
+ - Write the file at the confirmed path, creating the folder when it is absent.
47
+ - Run `canon markdown audit <path>`.
48
+
49
+ ## Response format
50
+
51
+ ### Preview
52
+
53
+ **Target:** `<path>` (root | nested)
54
+ **Detected:** `<project types>`
55
+ **Badges:** `<candidates, or none>`
56
+
57
+ ```markdown
58
+ <drafted H1 and body>
59
+ ```
60
+
61
+ ### After confirmation
62
+
63
+ ```plaintext
64
+ ✅ Drafted: <path>
65
+ ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: wireframe-draft
2
+ name: draft-wireframes
3
3
  description: Why a brand-new .claude/wireframes/<surface>.md file needs a real draft and a tier-detect step, not the stub the wireframe-sweep already writes
4
4
  ---
5
5
 
@@ -32,7 +32,7 @@ Without this skill, a session drafting a wireframe for a surface with no file ye
32
32
  ## Out of scope
33
33
 
34
34
  - Stubbing a surface a diff touched, or reporting drift in an existing wireframe against a diff: `claude/skills/claude-docs/references/wireframe-sweep.md`
35
- - Drafting a `.claude/context/<domain>.md` entry: `context-draft`
36
- - Drafting a `docs/*.md` page: `docs-draft`
35
+ - Drafting a `.claude/context/<domain>.md` entry: `draft-context`
36
+ - Drafting a `docs/*.md` page: `draft-docs`
37
37
  - Drafting a standard, a snippet, or a governance rule: `create-standard`, `create-snippet`, `create-rule`
38
38
  - Building or wiring an actual tier-1 or tier-2 rendering pipeline: the visual design workflow's own tier guidance, out of reach of a hand-drafting skill
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: wireframe-draft
2
+ name: draft-wireframes
3
3
  description: Drafts a brand-new `.claude/wireframes/<surface>.md` file against the wireframes standard, walks the tree for a name collision, detects an existing higher visual-design tier without building one, confirms with the user, then writes. Use when asked to "draft a wireframe for X", "write the wireframe for this surface", "add a .claude/wireframes entry for X", or "wireframe this screen" where no surface file covers it yet. Do NOT use to fix a stale TODO stub or report wireframe drift against a diff, which is `claude-docs`'s wireframe-sweep step.
4
4
  ---
5
5
 
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: identity
3
+ description: Why the mark and the card are one pick rather than two, and where the size sequence and the write folder come from before either is drafted
4
+ ---
5
+
6
+ # Identity requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session asked for a logo and a social card either invents shapes with nothing behind them, or drafts the mark and the card as two separate decisions that can land on shapes that do not compose, which is the failure the task filing this skill measured by hand on every project it touched. A search across every shipped skill and standard found zero hits for `logo`, `og:image`, `og-image`, or Open Graph, so nothing in the catalog reached either output.
11
+
12
+ A session building this without a shared loop restates `draft-and-pick`'s render, hand-off, pick, and loop mechanics from scratch, which drifts from the shipped one with nothing comparing the two copies. It also guesses at the icon size sequence and the output folder rather than reading what the project already declares, and it produces one raster per size through a separate render call per size, which multiplies capture invocations for no reason `canon capture` cannot already batch.
13
+
14
+ ## Must
15
+
16
+ - Detect the icon size sequence from the project's own HTML head or manifest before falling back to the stated default set
17
+ - Detect the write folder from the project's own static-asset convention before falling back to the project root, and announce which one decided it
18
+ - Draft every arm already composed inside the card frame, so one pick settles the mark's shape and its composition together
19
+ - Follow `draft-and-pick`'s Steps 2 through 5 for the render, hand-off, pick, and loop, rather than restating them
20
+ - Write the final mark as its own SVG source, not baked into a raster only
21
+ - Render every final size and the card in one capture call, by sharing one selector class across pages, each declared at half its target dimension to land on the literal size once the render engine's fixed 2x scale factor is applied
22
+
23
+ ## Must not
24
+
25
+ - Restate `draft-and-pick`'s render, hand-off, pick, or loop mechanics
26
+ - Add a `## Logo` section to `standards/design.md`'s fixed section set. `src/design/parse.ts` reads a fixed key set, and no outcome behind this skill asks for a schema change.
27
+ - Modify `draft-and-pick`, `claude-design-extract`, `canon capture`, or `canon design render`. This skill composes all four and extending any of them is a separate change.
28
+ - Assume this skill's own invocation frequency needs no check. Whether anything reaches for it beyond an operator typing its name has no answer at creation time, so a review pass some months in should read that back rather than take it on faith.
29
+
30
+ ## Guards
31
+
32
+ - `canon` not on PATH: stop, since the render loop and the finalize step both need it
33
+ - Fires on a direct request only. A run offering a logo to a project that never asked for one spends a render nobody wanted.
34
+
35
+ ## Out of scope
36
+
37
+ - Wiring the produced files into a project's own HTML head or manifest, which is a separate edit this skill leaves for the operator to make against their own markup
38
+ - Recording the mark's construction rules in `standards/design.md`, which the task's own constraint keeps out of the fixed section set
39
+ - Mutating an existing logo file directly, which is a direct edit rather than a skill
40
+ - Auditing an implemented UI against its tokens, which `claude-ux-audit` owns