@erclx/canon 5.42.0 → 5.44.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 (195) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +3 -3
  3. package/claude/skills/backlog-triage/references/apply.md +6 -6
  4. package/claude/skills/canon-cli/SKILL.md +4 -4
  5. package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
  6. package/claude/skills/canvas-board/SKILL.md +1 -1
  7. package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
  8. package/claude/skills/ci-workflow/SKILL.md +12 -2
  9. package/claude/skills/ci-workflow/references/workflows.md +12 -9
  10. package/claude/skills/context-fold/references/context.md +1 -1
  11. package/claude/skills/create-rule/SKILL.md +1 -0
  12. package/claude/skills/create-skill/REQUIREMENT.md +1 -1
  13. package/claude/skills/create-skill/SKILL.md +2 -2
  14. package/claude/skills/create-skill/references/skill-requirement.md +68 -9
  15. package/claude/skills/create-skill/references/skill.md +1 -1
  16. package/claude/skills/decision-escalate/SKILL.md +1 -2
  17. package/claude/skills/design-identity/REQUIREMENT.md +40 -0
  18. package/claude/skills/design-identity/SKILL.md +138 -0
  19. package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
  20. package/claude/skills/design-taste/REQUIREMENT.md +4 -4
  21. package/claude/skills/design-taste/SKILL.md +2 -2
  22. package/claude/skills/design-taste/references/kinds.md +1 -1
  23. package/claude/skills/design-taste/references/preflight.md +1 -1
  24. package/claude/skills/document-health/references/axes.md +2 -1
  25. package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
  26. package/claude/skills/draft-and-pick/SKILL.md +3 -153
  27. package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
  28. package/claude/skills/draft-doc/SKILL.md +4 -76
  29. package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
  30. package/claude/skills/draft-figure/SKILL.md +3 -77
  31. package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
  32. package/claude/skills/draft-identity/SKILL.md +3 -130
  33. package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
  34. package/claude/skills/draft-ready/SKILL.md +3 -128
  35. package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
  36. package/claude/skills/draft-screencast/SKILL.md +3 -62
  37. package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
  38. package/claude/skills/draft-slides/SKILL.md +3 -72
  39. package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
  40. package/claude/skills/draw-figure/SKILL.md +85 -0
  41. package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
  42. package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
  43. package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
  44. package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
  45. package/claude/skills/git-commit/references/commit.md +1 -5
  46. package/claude/skills/git-pr/references/pr.md +1 -0
  47. package/claude/skills/make-deck/REQUIREMENT.md +44 -0
  48. package/claude/skills/make-deck/SKILL.md +80 -0
  49. package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
  50. package/claude/skills/markdown-craft/SKILL.md +2 -2
  51. package/claude/skills/pick-by-eye/REQUIREMENT.md +86 -0
  52. package/claude/skills/pick-by-eye/SKILL.md +161 -0
  53. package/claude/skills/plan-feature/SKILL.md +3 -2
  54. package/claude/skills/plan-feature/references/plan.md +25 -11
  55. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  56. package/claude/skills/plan-intake/SKILL.md +1 -1
  57. package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
  58. package/claude/skills/plan-ready/SKILL.md +136 -0
  59. package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
  60. package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
  61. package/claude/skills/pr-evidence/references/evidence.md +1 -1
  62. package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
  63. package/claude/skills/record-screencast/SKILL.md +2 -2
  64. package/claude/skills/role-orchestrator/REQUIREMENT.md +1 -1
  65. package/claude/skills/role-orchestrator/SKILL.md +2 -0
  66. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
  67. package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -0
  68. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
  69. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
  70. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  71. package/claude/skills/role-planner/SKILL.md +5 -4
  72. package/claude/skills/role-worker/REQUIREMENT.md +2 -0
  73. package/claude/skills/role-worker/SKILL.md +35 -2
  74. package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
  75. package/claude/skills/script-screencast/SKILL.md +70 -0
  76. package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
  77. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  78. package/claude/skills/search-craft/SKILL.md +2 -2
  79. package/claude/skills/target-setup/SKILL.md +1 -0
  80. package/claude/skills/task-board/SKILL.md +11 -9
  81. package/claude/skills/task-board/references/board.md +15 -12
  82. package/claude/skills/teach-workspace/SKILL.md +1 -1
  83. package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
  84. package/claude/skills/ui-checklist/SKILL.md +2 -0
  85. package/claude/skills/write-doc/REQUIREMENT.md +46 -0
  86. package/claude/skills/write-doc/SKILL.md +83 -0
  87. package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
  88. package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
  89. package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
  90. package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +4 -4
  91. package/claude/skills/{draft-doc → write-doc}/references/wiki.md +1 -1
  92. package/docs/agents/audits.md +1 -0
  93. package/docs/agents/markdown-audit.md +4 -2
  94. package/docs/agents/migrate.md +13 -10
  95. package/docs/target/migrations.md +28 -4
  96. package/docs/target/projects.md +1 -1
  97. package/docs/workflow/parallel-features.md +3 -2
  98. package/docs/workflow/skill-map-on-request.md +18 -12
  99. package/docs/workflow/skill-map.md +13 -12
  100. package/docs/workflow/visual-design-workflow.md +2 -2
  101. package/governance/detect.toml +4 -0
  102. package/governance/ledger/framework/astro.md +73 -0
  103. package/governance/ledger/framework/fastapi.md +76 -0
  104. package/governance/ledger/framework/nextjs.md +86 -0
  105. package/governance/ledger/framework/react.md +83 -0
  106. package/governance/ledger/framework/shadcn.md +60 -0
  107. package/governance/ledger/framework/tailwind.md +55 -0
  108. package/governance/rules/canon/context.md +2 -1
  109. package/governance/rules/canon/plan.md +3 -5
  110. package/governance/rules/canon/scratch.md +3 -1
  111. package/governance/rules/canon/task-scope.md +2 -1
  112. package/governance/rules/canon/tasks.md +2 -1
  113. package/governance/rules/canon/worktrees.md +5 -2
  114. package/governance/rules/claude/output.md +7 -4
  115. package/governance/rules/claude/skill.md +6 -4
  116. package/governance/rules/framework/astro.md +12 -14
  117. package/governance/rules/framework/fastapi.md +20 -24
  118. package/governance/rules/framework/nextjs.md +19 -27
  119. package/governance/rules/framework/react.md +22 -33
  120. package/governance/rules/framework/shadcn.md +11 -15
  121. package/governance/rules/framework/tailwind.md +12 -14
  122. package/governance/rules/tooling/ci-workflow.md +6 -39
  123. package/governance/rules/ui/design-reference.md +37 -0
  124. package/governance/rules/writing/markdown.md +3 -2
  125. package/package.json +6 -6
  126. package/src/audits/catalog.ts +42 -0
  127. package/src/claude/cases/authoring.ts +15 -3
  128. package/src/claude/cases/misc.ts +12 -0
  129. package/src/claude/cases/workflow.ts +19 -1
  130. package/src/claude/settings.ts +8 -4
  131. package/src/claude/skills-audit.ts +113 -1
  132. package/src/commands/claude.ts +45 -12
  133. package/src/commands/demo.ts +1 -1
  134. package/src/commands/gov.ts +198 -0
  135. package/src/commands/markdown.ts +1 -1
  136. package/src/commands/migrate.ts +125 -2
  137. package/src/commands/pr.ts +34 -83
  138. package/src/commands/tasks.ts +383 -2
  139. package/src/commands/tooling.ts +3 -3
  140. package/src/commands/worktrees.ts +49 -0
  141. package/src/context/audit.ts +1 -1
  142. package/src/demo/beats.ts +1 -1
  143. package/src/gate/stages.ts +15 -0
  144. package/src/gov/audit.ts +441 -0
  145. package/src/listeners/belongs.ts +21 -0
  146. package/src/listeners/machine.ts +93 -0
  147. package/src/listeners/parse.ts +41 -0
  148. package/src/markdown/scope.ts +45 -35
  149. package/src/migrate/record-layout.ts +1 -1
  150. package/src/migrate/session-defaults.ts +138 -0
  151. package/src/migrate/skill-names.ts +68 -21
  152. package/src/pr/frames.ts +14 -3
  153. package/src/pr/local.ts +4 -69
  154. package/src/records/validate.ts +31 -0
  155. package/src/sync/check.ts +15 -0
  156. package/src/tasks/board.ts +854 -0
  157. package/src/tasks/record.ts +20 -1
  158. package/src/tasks/validate.ts +206 -9
  159. package/src/tooling/stamp.ts +56 -12
  160. package/src/worktrees/stop.ts +92 -0
  161. package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
  162. package/tooling/astro/reference.md +2 -2
  163. package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
  164. package/tooling/base/configs/commitlint.config.js +0 -20
  165. package/tooling/base/reference.md +1 -1
  166. package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
  167. package/tooling/claude/reference.md +13 -7
  168. package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
  169. package/tooling/claude/seeds/.claude/settings.json +8 -0
  170. package/tooling/claude/user/settings.template.json +0 -4
  171. package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
  172. package/tooling/public/configs/.github/dependabot.yml +12 -0
  173. package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
  174. package/tooling/public/manifest.toml +8 -0
  175. package/tooling/public/reference.md +53 -0
  176. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
  177. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
  178. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
  179. package/tooling/public/seeds/.release-please-manifest.json +3 -0
  180. package/tooling/public/seeds/CONTRIBUTING.md +50 -0
  181. package/tooling/public/seeds/LICENSE +21 -0
  182. package/tooling/public/seeds/SECURITY.md +13 -0
  183. package/tooling/public/seeds/release-please-config.json +12 -0
  184. package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
  185. package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
  186. package/tooling/web/configs/.github/workflows/verify.yml +15 -12
  187. /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
  188. /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
  189. /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
  190. /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
  191. /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
  192. /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
  193. /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
  194. /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
  195. /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
4
- "version": "5.42.0",
4
+ "version": "5.44.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -65,9 +65,9 @@ If neither form is present, stop: `❌ <path> carries no plan sections. A plan l
65
65
 
66
66
  ### Unanswered questions
67
67
 
68
- The plan's sections and answer contract are fixed by `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`. A blank `- Answer:` accepts the `- Suggested:` line above it, so an unanswered question is a decision this run executes rather than a reason to stop.
68
+ Read `## The suggested-and-answer contract` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md` before acting on a question, for what it resolves to and the form an override takes. A question left open is a decision this run executes rather than a reason to stop.
69
69
 
70
- When this run decides against a suggestion, rewrite its line as `overridden at execution to <pick>,` plus the measurement, leaving `- Answer:` blank. Put the same deviation in one line under the open task's `## Findings`, opening with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
70
+ Open the task's `## Findings` line for an override with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
71
71
 
72
72
  ## Step 2: implement
73
73
 
@@ -107,7 +107,7 @@ When the plan's `**Constraints:**` carry a `Fan-in member of` bullet, push the b
107
107
 
108
108
  If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
109
109
 
110
- When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file.
110
+ When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file. A diff passing this test also owes the preview server `role-worker` states, started before Step 6.
111
111
 
112
112
  ## Step 6: ship
113
113
 
@@ -25,12 +25,12 @@ An item already applied, by the test in the skill's Step 1, is skipped silently,
25
25
 
26
26
  Take the task stem from the item heading. Every verdict leaves the folder slug on its task, which is how Step 1 and `task-board`'s unlinked-origin scan both see the folder as acted on.
27
27
 
28
- | Verdict | Command and board write |
29
- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
- | decline | `canon tasks decline <stem> --reason "<reason>, backlog triage <slug> item <cluster>#<n>" --json`, which clears the backlog line |
31
- | archive | `canon tasks outcome <stem> --close <p> ... --json` for the named positions, then `canon tasks archive <stem> --json` |
32
- | keep | Append the `## Findings` line naming what reproduced, leaving the backlog line |
33
- | promote | Move the backlog line to the bottom of `## Needs a plan` in `.canon/tasks/priority.md`, its `Waiting on` cell stating what cleared and ending in `last` |
28
+ | Verdict | Command and board write |
29
+ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
30
+ | decline | `canon tasks decline <stem> --reason "<reason>, backlog triage <slug> item <cluster>#<n>" --json`, which clears the backlog line |
31
+ | archive | `canon tasks outcome <stem> --close <p> ... --json` for the named positions, then `canon tasks archive <stem> --json` |
32
+ | keep | Append the `## Findings` line naming what reproduced, leaving the backlog line |
33
+ | promote | `canon tasks place <stem> --group needs-a-plan --bottom --waiting "<what cleared>. Last" --json`, which clears the backlog line |
34
34
 
35
35
  ### Archive and missing files
36
36
 
@@ -43,11 +43,11 @@ Each verb here has a skill that owns the job. Load the skill rather than driving
43
43
 
44
44
  | Job | Verb | Skill |
45
45
  | -------------------------------------------- | ------------------- | --------------------------- |
46
- | Render the design system | `canon design` | `canon:draft-figure` |
47
- | Render a slide deck | `canon slides` | `canon:draft-slides` |
48
- | Render an HTML source to a PNG | `canon capture` | `canon:draft-identity` |
46
+ | Render the design system | `canon design` | `canon:draw-figure` |
47
+ | Render a slide deck | `canon slides` | `canon:make-deck` |
48
+ | Render an HTML source to a PNG | `canon capture` | `canon:design-identity` |
49
49
  | Serve a directory and print the link | `canon serve` | none |
50
- | Record a running app | `canon demo` | `canon:draft-screencast` |
50
+ | Record a running app | `canon demo` | `canon:script-screencast` |
51
51
  | Report one computed property across routes | `canon inventory` | `canon:target-check` |
52
52
  | Walk a page through interactions and measure | `canon drive` | `canon:ux-measure` |
53
53
  | Fetch a YouTube transcript | `canon transcripts` | `canon:youtube-transcripts` |
@@ -43,6 +43,6 @@ When the operator picks a frame, the session leaves the decision on the canvas a
43
43
 
44
44
  - What the canvas verbs do internally, which is the CLI's own contract
45
45
  - The content format a frame and a layout take, which the canvas standard fixes
46
- - Drafting candidates for a taste decision and taking the pick, which `draft-and-pick` runs on this canvas through the same verbs
46
+ - Drafting candidates for a taste decision and taking the pick, which `pick-by-eye` runs on this canvas through the same verbs
47
47
  - Tracing reference images into design values or writing the design document from code, which no skill owns now
48
48
  - Backing up the canvas folder off one disk
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: canvas-board
3
- description: Drives the local design canvas, where pages hold HTML frames the operator sees, drags, selects, and edits in the browser. Starts the canvas when it is not running, confirms the live shell loads, makes pages and frames, edits a frame through its file, reads what the operator selected or restyled, captures finished frames, and carries a picked direction into the project's design document. Use when asked to "open the canvas", "put this on the canvas", "draw a frame for X", "change the one I selected", "what did I pick", "capture this frame", or "move that frame on the canvas". Do NOT use to draft candidates for a taste decision, which is `draft-and-pick`.
3
+ description: Drives the local design canvas, where pages hold HTML frames the operator sees, drags, selects, and edits in the browser. Starts the canvas when it is not running, confirms the live shell loads, makes pages and frames, edits a frame through its file, reads what the operator selected or restyled, captures finished frames, and carries a picked direction into the project's design document. Use when asked to "open the canvas", "put this on the canvas", "draw a frame for X", "change the one I selected", "what did I pick", "capture this frame", or "move that frame on the canvas". Do NOT use to draft candidates for a taste decision, which is `pick-by-eye`.
4
4
  metadata:
5
5
  family: decide
6
6
  ---
@@ -21,7 +21,8 @@ A cache keyed on a static string serves a stale browser or toolchain after a ver
21
21
  - Start the checks that share setup in one job and split them only once a run log puts the gate past roughly two minutes
22
22
  - Pin every action to a tag that cannot cross a major version
23
23
  - Key a cache on the version string of the thing it caches
24
- - Give every workflow a manual trigger beside its primary one
24
+ - Give every workflow a manual trigger beside its primary one, except one that commits back, where a manual run has no branch to land on
25
+ - Default the token to read-only and grant a write scope only on the job that needs it
25
26
  - Bound artifact upload to failures and set an expiry on it
26
27
 
27
28
  ## Must not
@@ -17,7 +17,8 @@ Generate GitHub Actions workflow files for CI pipelines. Enforce parallel job ex
17
17
 
18
18
  ## Workflow setup
19
19
 
20
- - Include `workflow_dispatch` on every workflow alongside the primary trigger.
20
+ - Include `workflow_dispatch` alongside the primary trigger, except on a commit-back workflow, where a manual run has no branch to commit onto and would pass while doing nothing.
21
+ - Set `permissions: contents: read` at the top level, and grant a write scope only on the job that needs it.
21
22
  - Pin all actions to major version tags (`@v4`, never `@latest` or `@main`).
22
23
  - Use `runs-on: ubuntu-latest` for all jobs.
23
24
 
@@ -50,6 +51,14 @@ Generate GitHub Actions workflow files for CI pipelines. Enforce parallel job ex
50
51
  - Install with `bun install --frozen-lockfile`.
51
52
  - Cache Playwright browsers keyed on the Playwright version string, never a static key.
52
53
 
54
+ ## Commit-back
55
+
56
+ A workflow that pushes a regenerated file onto the pull request branch takes these on top of the setup above.
57
+
58
+ - Set the concurrency group on the ref so a newer push cancels the run committing onto a stale head.
59
+ - Set `HUSKY: 0` on the commit step when the runner lacks a tool a hook shells out to.
60
+ - Fail a template's first step while a path list still holds its placeholder, so an unfinished install fails loudly rather than never firing.
61
+
53
62
  ## Template
54
63
 
55
64
  Load `${CLAUDE_SKILL_DIR}/references/workflows.md` for the base workflow template. Adapt it to the project's stack, test commands, and build output. Add or remove jobs as needed. The template already carries the folded shape, and the split beside it applies once the granularity rule above calls for it.
@@ -58,7 +67,8 @@ Load `${CLAUDE_SKILL_DIR}/references/workflows.md` for the base workflow templat
58
67
 
59
68
  Before responding, verify:
60
69
 
61
- - `workflow_dispatch` is present alongside the primary trigger.
70
+ - `workflow_dispatch` is present alongside the primary trigger, and absent from a commit-back workflow.
71
+ - The top-level `permissions` reads `contents: read`, and every write scope sits on a job.
62
72
  - All actions pinned to major version tags, no `@latest` or `@main`.
63
73
  - A new pipeline folds static, unit, and build into one job, and a gate a run log put past two minutes gives them no `needs` so they run in parallel.
64
74
  - Every name in a `needs` matches a job declared in the same file. E2E names the artifact producer, release and deploy name E2E.
@@ -12,12 +12,15 @@ on:
12
12
  branches: [main]
13
13
  workflow_dispatch:
14
14
 
15
+ permissions:
16
+ contents: read
17
+
15
18
  jobs:
16
19
  checks:
17
20
  name: '🛡️ Checks'
18
21
  runs-on: ubuntu-latest
19
22
  steps:
20
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v7
21
24
  - uses: oven-sh/setup-bun@v2
22
25
  with:
23
26
  bun-version: latest
@@ -25,7 +28,7 @@ jobs:
25
28
  - run: bun run check
26
29
  - run: bun run test
27
30
  - run: bun run build
28
- - uses: actions/upload-artifact@v4
31
+ - uses: actions/upload-artifact@v7
29
32
  with:
30
33
  name: build-output
31
34
  path: dist/
@@ -35,17 +38,17 @@ jobs:
35
38
  needs: checks
36
39
  runs-on: ubuntu-latest
37
40
  steps:
38
- - uses: actions/checkout@v4
41
+ - uses: actions/checkout@v7
39
42
  - uses: oven-sh/setup-bun@v2
40
43
  with:
41
44
  bun-version: latest
42
45
  - run: bun install --frozen-lockfile
43
- - uses: actions/download-artifact@v4
46
+ - uses: actions/download-artifact@v8
44
47
  with:
45
48
  name: build-output
46
49
  path: dist/
47
50
  - run: bun run test:e2e
48
- - uses: actions/upload-artifact@v4
51
+ - uses: actions/upload-artifact@v7
49
52
  if: failure()
50
53
  with:
51
54
  name: e2e-results
@@ -63,7 +66,7 @@ jobs:
63
66
  name: '🛡️ Static Checks'
64
67
  runs-on: ubuntu-latest
65
68
  steps:
66
- - uses: actions/checkout@v4
69
+ - uses: actions/checkout@v7
67
70
  - uses: oven-sh/setup-bun@v2
68
71
  with:
69
72
  bun-version: latest
@@ -74,7 +77,7 @@ jobs:
74
77
  name: '🧪 Unit Tests'
75
78
  runs-on: ubuntu-latest
76
79
  steps:
77
- - uses: actions/checkout@v4
80
+ - uses: actions/checkout@v7
78
81
  - uses: oven-sh/setup-bun@v2
79
82
  with:
80
83
  bun-version: latest
@@ -85,13 +88,13 @@ jobs:
85
88
  name: '📦 Build Check'
86
89
  runs-on: ubuntu-latest
87
90
  steps:
88
- - uses: actions/checkout@v4
91
+ - uses: actions/checkout@v7
89
92
  - uses: oven-sh/setup-bun@v2
90
93
  with:
91
94
  bun-version: latest
92
95
  - run: bun install --frozen-lockfile
93
96
  - run: bun run build
94
- - uses: actions/upload-artifact@v4
97
+ - uses: actions/upload-artifact@v7
95
98
  with:
96
99
  name: build-output
97
100
  path: dist/
@@ -28,7 +28,7 @@ Does not govern:
28
28
 
29
29
  - Product scope, goals, and non-goals: `requirements.md`
30
30
  - Path-scoped coding rules: `rule.md`
31
- - Figures and architecture views, which answer structure questions an entry hands off: the `draft-figure` skill
31
+ - Figures and architecture views, which answer structure questions an entry hands off: the `draw-figure` skill
32
32
  - The consumer-facing reference under `docs/`, whose reader is operating the project without the source open: `docs.md`
33
33
 
34
34
  ## Organizing principle
@@ -80,6 +80,7 @@ Title casing is sentence case, with proper nouns keeping their own casing (`# Ty
80
80
  Read `${CLAUDE_SKILL_DIR}/references/checklist.md` and run every bullet of the written rule through it, along with the shape limits and the content test in `rule.md`.
81
81
 
82
82
  - Rewrite a bullet marked revise and cut one marked drop, then run the checklist again over what changed
83
+ - Run `canon gov audit .claude/rules/project/<subdir>/<slug>.md` and fix every finding it reports, since the shape limits are counts the verb takes rather than a judgment
83
84
  - Report the verdict counts with the path, and name any bullet kept against a criterion with the reason
84
85
 
85
86
  ## After writing
@@ -24,7 +24,7 @@ A fifth failure is the confirmation itself. A worker running a plan that adds a
24
24
  - Draft the sibling `REQUIREMENT.md` beside the body, from what the skill is for rather than from the drafted body
25
25
  - Confirm the name and both files with the user before writing, where a person is present to answer. The name is the routing key and a folder that disagrees with its frontmatter fails silently. Where nobody is present, record the three answers and both paths in the output and write.
26
26
  - Write to the conventional skills path, so discovery finds it without configuration. That is `.claude/skills/` in a target project. In the toolkit's own checkout, which the project root's `claude/.claude-plugin/plugin.json` marks, an `internal-*` skill goes under `.claude/skills/` and a plugin skill under `claude/skills/`
27
- - Leave the skills audit's dated-provenance check clean for the new folder before reporting it, with each incident moved to the requirement's `Gap`
27
+ - Leave the skills audit's dated-provenance check clean for the new folder before reporting it, with each incident cut and left to git
28
28
 
29
29
  ## Must not
30
30
 
@@ -38,7 +38,7 @@ Read these in the same pass:
38
38
  - Does the body carry a procedure a session would get wrong from first principles? A one-line wrapper around a single command needs no skill.
39
39
  - Will anything invoke it other than the author typing its name? Carry this one into the drafted `REQUIREMENT.md`'s `Must not` section as a review criterion instead, since nothing can answer it before the skill has run.
40
40
  - Tell the user and stop when the first answer is yes or the second is no. A non-interactive run stops on both too, reporting which question failed and writing no folder.
41
- 2. Draft the full `SKILL.md` from the user's description, stating the current rule alone. An incident and the date it happened belong in the requirement's `Gap`, not in the body or a reference.
41
+ 2. Draft the full `SKILL.md` from the user's description, stating the current rule alone. An incident and the date it happened stay in git, never in the body, a reference, or the requirement.
42
42
  3. Draft the sibling `REQUIREMENT.md` from what the skill is for, in the shape the requirement standard states.
43
43
  - Write the gaps from the user's description rather than from the drafted body, since a requirement derived from the body records whatever the draft overfitted to.
44
44
  4. Confirm the skill name and both files with the user before writing, when a person can answer.
@@ -53,7 +53,7 @@ Steps 5 to 7 write the folder and check what landed before the run reports.
53
53
  - The root is `.claude/skills/` in a target project.
54
54
  - Where the project root holds `claude/.claude-plugin/plugin.json`, which is the toolkit's own checkout, an `internal-*` skill goes under `.claude/skills/` and every other skill under `claude/skills/`, since the plugin ships that tree.
55
55
  6. Run `canon claude skills audit --json` and read `findings.datedProvenance` for rows under `<root>/<name>/`.
56
- - Move each row's incident into `REQUIREMENT.md` under `Gap`, cut the date from the file the row names, and re-run until no row names the folder.
56
+ - Cut each row's date and incident from the file the row names, leaving them to git, and re-run until no row names the folder.
57
57
  - When `canon` does not resolve or its record carries no `datedProvenance` key, say the check did not run rather than reporting the skill clean.
58
58
  7. Run `canon markdown audit <root>/<name>/` over the new body and any references, and fix every ban and density finding it reports.
59
59
  - Re-run it until it reports none, since every file in the folder is this run's draft.
@@ -35,12 +35,36 @@ A requirement that leaves any of the three open is non-conforming regardless of
35
35
  - Write the gaps from what the skill is for, then compare the body against them
36
36
  - A requirement derived from the body records the body's accidents as the requirement, and misinforms a reader who reads it in place of the body
37
37
 
38
+ ## Sections
39
+
40
+ The file carries these H2s in this order and no others. `canon claude skills audit` reports a missing Gap or Must and a Guards heading.
41
+
42
+ | Section | When | Holds |
43
+ | -------------- | ----------------------------------------- | ------------------------------------------------------------- |
44
+ | `Gap` | Always | The failures a session hits today without the skill, as prose |
45
+ | `Must` | Always | The outcomes that close those failures, one per bullet |
46
+ | `Must not` | When a behavior closes a gap and is wrong | That behavior, one per bullet |
47
+ | `Out of scope` | When a sibling owns an adjacent behavior | The behavior and the skill that owns it |
48
+
49
+ `Guards` is retired. A refusal condition is a `Must not` bullet, and the message it prints belongs to the body.
50
+
51
+ ## Caps
52
+
53
+ The audit reports each cap it finds breached, and a rewrite batch turns the report into a gate for the files it brings under.
54
+
55
+ - Each list holds at most 5 bullets. A sixth `Must` is a sign the skill does two jobs or the list restates its steps.
56
+ - The file holds at most 400 words of body, frontmatter excluded
57
+ - Gap carries no `YYYY-MM-DD` date and no `#NNN` issue or pull request number outside a code span
58
+
38
59
  ## Content
39
60
 
40
- - State each gap as an observed failure, not an intent. "Without this skill a session invents its own filename" can be shown wrong. "This skill helps manage tasks" cannot fail, so it constrains nothing.
41
- - Trace everything under `## Must` to a stated gap. A `Must` with no gap behind it is the padding the file exists to prevent.
42
- - Keep it high level. A requirement that outgrows one file has stopped being a requirement, and `references/` already holds detail.
43
- - Use `name` and `description` frontmatter, matching `SKILL.md` so the pair is consistent.
61
+ - State each gap as a failure a session hits today, in the present tense. "Without this skill a session invents its own filename" can be shown wrong.
62
+ - Never state a gap as an intent. "This skill helps manage tasks" cannot fail, so it constrains nothing.
63
+ - Keep history out of Gap. The incident, its date, and the pull request that earned a rule stay in git, where `git log` on the file finds them.
64
+ - Write each `Must` as an outcome a reader can check against the body, never as a step the body takes. "The committed set is exactly the staged set" is an outcome.
65
+ - Trace every `Must` to a stated gap. A `Must` with no gap behind it is the padding the file exists to prevent.
66
+
67
+ The frontmatter carries `name` and `description`, matching `SKILL.md` so the pair is consistent.
44
68
 
45
69
  ## Template
46
70
 
@@ -54,21 +78,56 @@ description: <one line, distinct from the SKILL.md description>
54
78
 
55
79
  ## Gap
56
80
 
57
- Without this skill, a session <observed failure>, <observed failure>.
81
+ Without this skill, a session <failure it hits today>. <A second failure, when there is one>.
58
82
 
59
83
  ## Must
60
84
 
61
- - <behavior that closes a named gap>
85
+ - <outcome that closes a named failure>
62
86
 
63
87
  ## Must not
64
88
 
65
89
  - <behavior that would be wrong even though it closes a gap>
66
90
 
67
- ## Guards
91
+ ## Out of scope
92
+
93
+ - <adjacent behavior>, which `<sibling-skill>` owns
94
+ ```
95
+
96
+ ### Worked example
97
+
98
+ `git-commit`'s requirement in this shape, at 167 words as the audit counts them.
99
+
100
+ ```markdown
101
+ ---
102
+ name: git-commit
103
+ description: What commit generation is for, the gaps it closes, and where the family boundary sits
104
+ ---
105
+
106
+ # Git commit requirement
107
+
108
+ ## Gap
109
+
110
+ Without this skill, a commit message takes whatever shape the session picks. The type and scope drift from the history's convention, the subject runs past the log's width, and a lockfile diff crowds out the change the message should describe.
111
+
112
+ A plain request to commit also reaches the grouping sibling, which restages whole files, so a hunk-level selection ships wider than the user reviewed.
113
+
114
+ ## Must
115
+
116
+ - The message follows the commit format and versioning references
117
+ - The message describes the staged diff with lockfiles excluded
118
+ - The user sees the message and its length before the commit runs
119
+ - The committed set is exactly the staged set
120
+ - The description claims single-concern and hunk-level staged sets, and names `git-stage` for a mixed one
121
+
122
+ ## Must not
68
123
 
69
- - <the refusal condition and its message>
124
+ - Stage or unstage anything
125
+ - Commit when nothing is staged
126
+ - Emit anything after the result line
70
127
 
71
128
  ## Out of scope
72
129
 
73
- - <the adjacent thing this deliberately does not cover, and what covers it>
130
+ - Splitting a mixed diff into several commits, which `git-stage` owns
131
+ - Naming a branch, which `git-branch` owns
132
+ - Pushing or opening a pull request, which `git-pr` owns
74
133
  ```
@@ -132,7 +132,7 @@ A body holds behavioral rules and pointers to reference docs, front-loading the
132
132
 
133
133
  ### Current rule and grouping
134
134
 
135
- State the current rule only, in the body and in every file under `references/`. The incident and the date that earned a rule go in `REQUIREMENT.md` under `Gap`, or stay in git, and a date inside a fence or a code span is example data and stays.
135
+ State the current rule only, in the body and in every file under `references/`. The incident and the date that earned a rule stay in git, and a date inside a fence or a code span is example data and stays.
136
136
 
137
137
  - Cut any rule that resists crisp one-line phrasing. Vague guidance is worse than none.
138
138
  - Group bullets under H2 headings by concern, keeping dos and don'ts together rather than in flat rules and constraints sections
@@ -70,8 +70,7 @@ Restate each pick in one line, then continue the work.
70
70
 
71
71
  A pick that changes a written artifact goes into it under the rule its own standard sets, and a pick that settles nothing written stays in the session.
72
72
 
73
- - An answer to an open plan question rewrites its `- Suggested:` line to the pick, naming the operator as source, per `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`
74
- - Leave the `- Answer:` slot blank, since the standard bars a session from filling it, and the blank resolves to the rewritten suggestion
73
+ - Record an answer to an open plan question per `### Overrides and settled questions` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`
75
74
 
76
75
  Output after the answers land:
77
76
 
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: design-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
+ # Design 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 `pick-by-eye`'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 `pick-by-eye`'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 `pick-by-eye`'s render, hand-off, pick, or loop mechanics
26
+ - Add a `## Logo` section to `claude/skills/canvas-board/references/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 `pick-by-eye`, `canon capture`, or `canon design render`. This skill composes all three 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 `claude/skills/canvas-board/references/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 `ux-audit` owns
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: design-identity
3
+ description: Drafts a project's logo mark through pick-by-eye's render-and-pick loop, then composes the picked mark into an icon sequence and a 1200x630 social card. Use when asked to "make a logo", "design a logo mark", "create a favicon", "build the icon set", "generate a social card", "make an og:image", or "draft the logo and social card together". Do NOT use to mutate an existing logo file directly, which is a plain edit, or to record the mark's construction rules in DESIGN.md, which is out of scope.
4
+ metadata:
5
+ family: generate
6
+ ---
7
+
8
+ # Design identity
9
+
10
+ One identity rendered twice: the same mark sized down to an icon sequence and composed with type into the social card sized up. Drafting both from one pick keeps the mark and its card composition from settling on shapes that do not match.
11
+
12
+ ## Guards
13
+
14
+ - If `canon` is not on PATH, stop: `❌ canon CLI not found.`
15
+ - Draft no candidate for a mark the operator has not asked to make. This skill fires on a direct request, never on the model's own read that a project could use one.
16
+
17
+ ## Step 1: read signal
18
+
19
+ Read these in parallel, skipping any that do not exist:
20
+
21
+ - `canon/DESIGN.md`: the `## Overview` paragraph and the role intents under `## Colors` and `## Typography`, read as `## Personality` and `## Color` in an older record
22
+ - The stylesheet `canon/DESIGN.md`'s lead names: the color and type values behind those roles
23
+ - `canon/REQUIREMENTS.md`: the `## Personality` paragraph, when `canon/DESIGN.md` carries none
24
+ - `CLAUDE.md`: the project's stated voice, when neither file above carries a personality signal
25
+
26
+ No signal from any of these is not a stop. Draft against a neutral default, and mark each guessed color and type value with a `/* ? verify */` comment beside its declaration in the `.mark` and `.card` markup, since the design document carries no value to tag.
27
+
28
+ ## Step 2: detect the icon size sequence
29
+
30
+ Check the project's HTML entry points (`index.html`, `public/index.html`, `src/index.html`) for a `<link rel="icon">` or `<link rel="apple-touch-icon">` tag carrying a `sizes` attribute, and any `manifest.json` or `site.webmanifest` for an `icons` array. Take the union of every size found.
31
+
32
+ Fall back to the stated default when nothing is detected, since no `tooling/` stack scaffolds a `public/` folder, a favicon reference, or an `og:image` meta tag:
33
+
34
+ - `16x16`, `32x32`, `48x48`
35
+ - `180x180`
36
+ - `192x192`, `512x512`
37
+
38
+ This default set is raster-only, and Step 6 writes the vector source at `favicon.svg` on either branch. Announce which of the two decided the sequence.
39
+
40
+ ## Step 3: detect the write folder
41
+
42
+ A root-only check misses a site kept in a subfolder, and a Next project keeps its favicon under the App Router with no `public/` at all. Both would fall through to the root while the announcement reads as detected, so walk one level down and know that convention.
43
+
44
+ Read both, from the project root:
45
+
46
+ ```bash
47
+ find . -maxdepth 3 \( -name node_modules -o -name .git -o -name dist -o -name .astro \) -prune -o -type d \( -name public -o -name static \) -print | sort
48
+ find . -maxdepth 4 \( -name node_modules -o -name .git \) -prune -o -type d -path '*/src/app' -print | sort
49
+ ```
50
+
51
+ Take the first tier that answers:
52
+
53
+ 1. A root `public/` or `static/`.
54
+ 2. A `public/` or `static/` one level down, such as `web/public/`. Of several, take the shallowest, then the one whose parent holds the project's framework config.
55
+ 3. A `src/app/` folder, at the root or one level down, which is the Next App Router convention. Take the folder itself, not a `public/` beside it.
56
+ 4. A stack-declared asset folder, where the project's own config names one.
57
+ 5. The project root, which is the fallback rather than a detection.
58
+
59
+ Announce which tier decided, naming the tier rather than the path alone, so the operator can move the files where the project's convention differs. On tier 5 say the detection found nothing and the root is a fallback.
60
+
61
+ ## Step 4: name the decision and the arms
62
+
63
+ Follow `${CLAUDE_SKILL_DIR}/../pick-by-eye/SKILL.md` Step 1, with the decision fixed rather than derived: "the project's logo mark and its composition into the social card." Vary the mark's shape or style across arms, keeping the card's type and layout fixed, per that skill's one-property rule.
64
+
65
+ - Draft each arm inside the full 1200x630 card frame, mark and type together, and add its canvas frame at `--width 1200 --height 630`, so one pick settles shape and composition
66
+ - Arm 0 is the current mark when the Step 3 folder already holds a logo file (`favicon.svg`, `favicon.ico`, `logo.svg`, or similar). Arms start at 1 otherwise.
67
+ - Structure every arm as a `.mark` element, the inline SVG alone, nested inside a `.card` element, the full composition, so Step 6 can address either
68
+
69
+ ## Step 5: draft, render, pick, and loop
70
+
71
+ Follow `${CLAUDE_SKILL_DIR}/../pick-by-eye/SKILL.md` Steps 2 through 5 against the arms from Step 4: draft the arms as frames on a canvas page, render and hand off, take the pick, and loop on it.
72
+
73
+ The final icon and card renders below are not arms, so they stay off the canvas. Call the folder they render from `<dest>`, being `.canon/tmp/<slug>/` under the slug `pick-by-eye` Step 1 derived, which is where this project puts every temporary write.
74
+
75
+ ## Step 6: finalize the mark and the icons
76
+
77
+ This step and Step 7 replace `pick-by-eye`'s own Step 6 items 1 and 2, since the pick here produces several final files rather than one applied surface. Its archive capture, its page delete, and its server stop still run, after Step 7.
78
+
79
+ 1. Extract the picked arm's `.mark` markup as the final vector source. Write it to `<write-folder>/favicon.svg`.
80
+ 2. Under `<dest>/render/`, write one `icon-<w>x<h>.html` page per Step 2 size, carrying the picked `.mark` markup in an element with the shared class `.render`.
81
+ 3. Declare each `.render` element at `<w>/2` by `<h>/2`, since `canon capture` screenshots at a fixed 2x scale and the PNG then lands on the target size.
82
+ 4. Declare no font on them. Each holds the mark alone, and `canon capture` skips the font check on an element with no text, where `system-ui` would be refused.
83
+ 5. Render the batch:
84
+
85
+ ```bash
86
+ canon capture <dest>/render --selector .render --out <write-folder>
87
+ ```
88
+
89
+ 6. Report each written file's path and the dimensions `canon capture` printed, confirming each equals its Step 2 target rather than half of it.
90
+
91
+ The card leaves this batch and takes Step 7 instead. An icon is the mark alone and a scratch page renders it faithfully, where the card composes the mark with the project's own type and color, which a scratch page can only copy.
92
+
93
+ ## Step 7: write the card as a route and capture it through the server
94
+
95
+ A card captured from a page this run deletes leaves a PNG and nothing that produced it, so renaming the project means another pick loop to move one string. Write the composition into a route the project keeps, and capture it through a running server so it reads the real stylesheet, tokens, and fonts.
96
+
97
+ This is Astro-shaped for now, because Astro is the one web stack whose config gives a route a structural build exclusion. A project already holding the card route scaffold takes the route path, and everything else takes the page path. Say which one decided, since the two leave the project different things.
98
+
99
+ ### The route path
100
+
101
+ Read `${CLAUDE_SKILL_DIR}/references/card-route.md` on reaching this path, for the scaffold check, the message to give when it is missing, and the write, serve, and capture sequence. A project with no scaffold skips it.
102
+
103
+ ### The page path
104
+
105
+ Where the project holds no route to write into, write `og-image.html` into `<dest>/render/` with its `.render` wrapper sized 600x315, then capture that one page:
106
+
107
+ ```bash
108
+ canon capture <dest>/render/og-image.html --selector .render --out <write-folder>
109
+ ```
110
+
111
+ It takes its own call because Step 6's batch is already captured by the time this step picks a path. Say that the card shipped as a PNG with no source, and that the project gains one when it grows a route to hold the composition.
112
+
113
+ ### Closing the scratch folder and the canvas
114
+
115
+ Delete `<dest>` once both captures land, then close the canvas through `pick-by-eye` Step 6 items 3 to 8, which archive every arm and delete the pages the run added. The route is not a leftover variant, since it holds the arm the operator picked.
116
+
117
+ A project whose card was generated before this route existed keeps its PNG. Say so rather than regenerating it, since the pick loop spends attention on a file nobody complained about, and the next real edit picks up the route.
118
+
119
+ ## Response format
120
+
121
+ ```plaintext
122
+ 📝 Wrote <write-folder>/favicon.svg
123
+ 📝 Wrote <write-folder>/icon-16x16.png (16x16)
124
+ 📝 Wrote card-src/pages/og-card.astro (route path only)
125
+ 📝 Wrote <write-folder>/og-image.png (1200x630)
126
+
127
+ Write folder: <tier that decided>. Move the files if this project's own convention differs.
128
+ Card source: <the route, captured through the card server|a scratch page, since this project holds no card route>.
129
+ ```
130
+
131
+ ## What this delegates
132
+
133
+ Cite these rather than restating them.
134
+
135
+ - `pick-by-eye` owns Steps 1 through 5 of the render-and-pick loop, cited above
136
+ - `canon:canvas-board` carries a picked direction into `canon/DESIGN.md`. This skill only reads it.
137
+ - `canon capture` owns the render mechanics, its font refusal, its fixed 2x scale, and its reported dimensions. It reads an `http(s)://` source, where `--out` names the PNG.
138
+ - The `astro` tooling stack owns the card route's scaffold, its second config, and the exclusion check, read with `canon tooling reference astro`. This skill writes into the route and never reshapes it.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Card route path
3
- description: How draft-identity writes the picked card composition into a project's existing Astro card route and captures it through the card server
3
+ description: How design-identity writes the picked card composition into a project's existing Astro card route and captures it through the card server
4
4
  ---
5
5
 
6
6
  # Card route path
7
7
 
8
- Applies to Step 7 of `draft-identity` when the project already holds the card route scaffold. A project without it takes the page path in the skill body instead.
8
+ Applies to Step 7 of `design-identity` when the project already holds the card route scaffold. A project without it takes the page path in the skill body instead.
9
9
 
10
10
  ## The scaffold
11
11