@erclx/canon 5.26.0 → 5.28.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 (320) hide show
  1. package/README.md +2 -2
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/api-design/SKILL.md +2 -0
  4. package/claude/skills/auto-ship/SKILL.md +3 -11
  5. package/claude/skills/auto-ship/references/review-findings.md +20 -0
  6. package/claude/skills/backlog-triage/SKILL.md +2 -0
  7. package/claude/skills/bash-cli-script/SKILL.md +2 -0
  8. package/claude/skills/build-in-slices/SKILL.md +2 -0
  9. package/claude/skills/canon-cli/SKILL.md +2 -0
  10. package/claude/skills/canon-feedback/SKILL.md +2 -0
  11. package/claude/skills/canon-feedback-triage/SKILL.md +2 -0
  12. package/claude/skills/canon-operator/SKILL.md +2 -0
  13. package/claude/skills/canon-rollout/SKILL.md +3 -11
  14. package/claude/skills/canon-rollout/references/failure-recovery.md +20 -0
  15. package/claude/skills/canvas/SKILL.md +13 -0
  16. package/claude/skills/ci-workflow/SKILL.md +2 -0
  17. package/claude/skills/code-craft/SKILL.md +2 -0
  18. package/claude/skills/codebase-layout/SKILL.md +2 -0
  19. package/claude/skills/context-fold/SKILL.md +3 -17
  20. package/claude/skills/context-fold/references/completion-report.md +26 -0
  21. package/claude/skills/create-rule/SKILL.md +2 -0
  22. package/claude/skills/create-skill/SKILL.md +2 -0
  23. package/claude/skills/create-standard/SKILL.md +2 -0
  24. package/claude/skills/decision-escalate/SKILL.md +2 -0
  25. package/claude/skills/deploy-app/SKILL.md +2 -0
  26. package/claude/skills/deprecation-migration/SKILL.md +2 -0
  27. package/claude/skills/design-extract/SKILL.md +2 -0
  28. package/claude/skills/design-taste/SKILL.md +2 -0
  29. package/claude/skills/docs-sync/SKILL.md +2 -0
  30. package/claude/skills/document-health/SKILL.md +2 -0
  31. package/claude/skills/draft-and-pick/SKILL.md +2 -0
  32. package/claude/skills/draft-doc/SKILL.md +2 -0
  33. package/claude/skills/draft-doc/references/wiki.md +1 -1
  34. package/claude/skills/draft-figure/SKILL.md +2 -0
  35. package/claude/skills/draft-identity/SKILL.md +2 -0
  36. package/claude/skills/draft-ready/SKILL.md +5 -1
  37. package/claude/skills/draft-screencast/SKILL.md +2 -0
  38. package/claude/skills/draft-slides/SKILL.md +2 -0
  39. package/claude/skills/git-branch/SKILL.md +2 -0
  40. package/claude/skills/git-commit/SKILL.md +2 -0
  41. package/claude/skills/git-followup/SKILL.md +2 -0
  42. package/claude/skills/git-issue/SKILL.md +2 -0
  43. package/claude/skills/git-pr/SKILL.md +2 -0
  44. package/claude/skills/git-pr/references/evidence.md +7 -7
  45. package/claude/skills/git-ship/SKILL.md +2 -0
  46. package/claude/skills/git-split/SKILL.md +2 -0
  47. package/claude/skills/git-stage/SKILL.md +2 -0
  48. package/claude/skills/git-worktree/SKILL.md +2 -0
  49. package/claude/skills/index-lookup/SKILL.md +2 -0
  50. package/claude/skills/markdown-propose/SKILL.md +2 -0
  51. package/claude/skills/memory-capture/SKILL.md +2 -0
  52. package/claude/skills/memory-review/SKILL.md +2 -0
  53. package/claude/skills/plan-feature/SKILL.md +2 -0
  54. package/claude/skills/plan-groundwork/SKILL.md +2 -0
  55. package/claude/skills/plan-intake/SKILL.md +2 -0
  56. package/claude/skills/plan-intake-answer/SKILL.md +2 -0
  57. package/claude/skills/project-commands/SKILL.md +2 -0
  58. package/claude/skills/read-frames/SKILL.md +2 -0
  59. package/claude/skills/record-screencast/SKILL.md +2 -0
  60. package/claude/skills/repo-metadata/SKILL.md +2 -0
  61. package/claude/skills/restate-plainly/SKILL.md +2 -0
  62. package/claude/skills/review-address/REQUIREMENT.md +4 -2
  63. package/claude/skills/review-address/SKILL.md +19 -14
  64. package/claude/skills/review-address/references/post-review-findings.md +16 -0
  65. package/claude/skills/review-address/references/rebase-conflicts.md +4 -2
  66. package/claude/skills/review-branch/SKILL.md +2 -0
  67. package/claude/skills/review-craft/SKILL.md +2 -0
  68. package/claude/skills/review-craft/references/ui.md +6 -6
  69. package/claude/skills/review-pr/SKILL.md +4 -8
  70. package/claude/skills/review-pr/references/body-variants.md +52 -0
  71. package/claude/skills/review-pr/references/key-changes.md +16 -0
  72. package/claude/skills/review-pr/references/post.md +15 -43
  73. package/claude/skills/review-ui/REQUIREMENT.md +2 -2
  74. package/claude/skills/review-ui/SKILL.md +16 -12
  75. package/claude/skills/review-ui/references/driving.md +8 -8
  76. package/claude/skills/review-ui/references/post.md +13 -3
  77. package/claude/skills/review-ui/references/tick.md +22 -0
  78. package/claude/skills/role-orchestrator/REQUIREMENT.md +15 -15
  79. package/claude/skills/role-orchestrator/SKILL.md +31 -42
  80. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +18 -16
  81. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +13 -3
  82. package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +23 -0
  83. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +6 -34
  84. package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -4
  85. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +5 -5
  86. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +12 -23
  87. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +6 -6
  88. package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +1 -1
  89. package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +38 -0
  90. package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +2 -2
  91. package/claude/skills/role-orchestrator/references/orchestrator-watch.md +26 -0
  92. package/claude/skills/role-orchestrator/scripts/poll.ts +304 -10
  93. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  94. package/claude/skills/role-planner/SKILL.md +4 -2
  95. package/claude/skills/role-reviewer/REQUIREMENT.md +1 -1
  96. package/claude/skills/role-reviewer/SKILL.md +3 -1
  97. package/claude/skills/role-worker/SKILL.md +5 -2
  98. package/claude/skills/search-craft/SKILL.md +2 -0
  99. package/claude/skills/seed-sync/SKILL.md +2 -0
  100. package/claude/skills/session-compact/SKILL.md +2 -0
  101. package/claude/skills/session-map/SKILL.md +2 -0
  102. package/claude/skills/session-relay/SKILL.md +2 -0
  103. package/claude/skills/session-resume/SKILL.md +2 -0
  104. package/claude/skills/session-worktree/SKILL.md +3 -11
  105. package/claude/skills/session-worktree/references/install-command.md +20 -0
  106. package/claude/skills/sketch-design/SKILL.md +2 -0
  107. package/claude/skills/systematic-debugging/SKILL.md +2 -0
  108. package/claude/skills/target-check/SKILL.md +2 -0
  109. package/claude/skills/target-setup/SKILL.md +2 -0
  110. package/claude/skills/task-board/SKILL.md +2 -0
  111. package/claude/skills/teach-workspace/SKILL.md +5 -15
  112. package/claude/skills/teach-workspace/references/lesson-build.md +75 -0
  113. package/claude/skills/teach-workspace/references/lesson-craft.md +13 -69
  114. package/claude/skills/teach-workspace/references/revisit.md +22 -0
  115. package/claude/skills/test-craft/SKILL.md +2 -0
  116. package/claude/skills/test-first/SKILL.md +2 -0
  117. package/claude/skills/ui-checklist/SKILL.md +3 -1
  118. package/claude/skills/ux-audit/SKILL.md +2 -0
  119. package/claude/skills/ux-measure/SKILL.md +2 -0
  120. package/claude/skills/ux-walkthrough/SKILL.md +2 -0
  121. package/claude/skills/video-craft/SKILL.md +2 -0
  122. package/claude/skills/write-human/SKILL.md +2 -0
  123. package/claude/skills/youtube-transcripts/SKILL.md +2 -0
  124. package/docs/agents/canvas.md +24 -8
  125. package/docs/agents/capture.md +5 -5
  126. package/docs/agents/commands.md +2 -2
  127. package/docs/agents/gate.md +3 -1
  128. package/docs/agents/index.md +5 -4
  129. package/docs/agents/install-and-sync.md +7 -0
  130. package/docs/agents/key-changes.md +1 -1
  131. package/docs/agents/pr-evidence.md +47 -23
  132. package/docs/agents/pr-local.md +19 -13
  133. package/docs/agents/pr-preview.md +44 -21
  134. package/docs/agents/pr-tick.md +72 -0
  135. package/docs/agents/sandbox.md +30 -6
  136. package/docs/agents/scripting.md +8 -1
  137. package/docs/agents/skills-audit.md +2 -1
  138. package/docs/agents/tasks-plans.md +1 -1
  139. package/docs/agents/tasks-validate.md +18 -18
  140. package/docs/agents/tasks.md +1 -1
  141. package/docs/workflow/operating-model.md +15 -21
  142. package/docs/workflow/parallel-features.md +24 -3
  143. package/docs/workflow/skill-map.md +3 -1
  144. package/docs/workflow/zshrc-aliases.md +1 -1
  145. package/package.json +1 -1
  146. package/scripts/core/regen-hero.ts +1 -1
  147. package/scripts/lib/sandbox-path.sh +6 -162
  148. package/src/audits/baseline.ts +1 -1
  149. package/src/audits/run.ts +2 -2
  150. package/src/canvas/address.ts +12 -3
  151. package/src/canvas/capture.ts +1 -1
  152. package/src/canvas/client/inspector/align-grid.tsx +162 -0
  153. package/src/canvas/client/inspector/color-field.tsx +201 -171
  154. package/src/canvas/client/inspector/color-inputs.tsx +139 -0
  155. package/src/canvas/client/inspector/color-picker.tsx +668 -0
  156. package/src/canvas/client/inspector/color-space.ts +240 -0
  157. package/src/canvas/client/inspector/field.tsx +66 -3
  158. package/src/canvas/client/inspector/fields.css +473 -6
  159. package/src/canvas/client/inspector/size-field.tsx +69 -0
  160. package/src/canvas/client/inspector/token-select.tsx +109 -0
  161. package/src/canvas/client/inspector/values.ts +117 -3
  162. package/src/canvas/client/inspector.tsx +311 -15
  163. package/src/canvas/client/keys.ts +54 -0
  164. package/src/canvas/client/selection.tsx +199 -0
  165. package/src/canvas/client/shell.css +210 -12
  166. package/src/canvas/client/state.ts +165 -14
  167. package/src/canvas/client/surface.tsx +341 -39
  168. package/src/canvas/client/tools.tsx +64 -0
  169. package/src/canvas/content.ts +51 -2
  170. package/src/canvas/edit.ts +49 -6
  171. package/src/canvas/editing.ts +203 -0
  172. package/src/canvas/global.d.ts +15 -0
  173. package/src/canvas/server.ts +149 -12
  174. package/src/canvas/tokens.ts +60 -18
  175. package/src/census/count.ts +1 -1
  176. package/src/claude/seeds.ts +3 -3
  177. package/src/claude/skills-audit.ts +28 -0
  178. package/src/claude/skills-drift.ts +1 -1
  179. package/src/claude/skills-families.ts +36 -0
  180. package/src/claude/skills-list.ts +76 -15
  181. package/src/claude/skills-reach.ts +1 -1
  182. package/src/commands/audits.ts +2 -2
  183. package/src/commands/canvas.ts +180 -3
  184. package/src/commands/claude.ts +70 -12
  185. package/src/commands/design.ts +145 -5
  186. package/src/commands/docs.ts +1 -1
  187. package/src/commands/feedback.ts +2 -2
  188. package/src/commands/gate.ts +9 -2
  189. package/src/commands/gov.ts +3 -3
  190. package/src/commands/hooks.ts +1 -1
  191. package/src/commands/indexes.ts +1 -1
  192. package/src/commands/init.ts +2 -2
  193. package/src/commands/intake.ts +1 -1
  194. package/src/commands/migrate.ts +2 -2
  195. package/src/commands/pr.ts +288 -65
  196. package/src/commands/records.ts +1 -1
  197. package/src/commands/repo.ts +1 -1
  198. package/src/commands/sandbox.ts +64 -15
  199. package/src/commands/sessions.ts +1 -1
  200. package/src/commands/slides.ts +1 -1
  201. package/src/commands/sync.ts +2 -2
  202. package/src/commands/tasks.ts +21 -4
  203. package/src/commands/teach.ts +1 -1
  204. package/src/commands/tooling.ts +1 -1
  205. package/src/commands/transcripts.ts +2 -2
  206. package/src/commands/upgrade.ts +1 -1
  207. package/src/commands/wiki.ts +1 -1
  208. package/src/commands/worktrees.ts +1 -1
  209. package/src/comments/scan.ts +1 -1
  210. package/src/comments/trend.ts +1 -1
  211. package/src/context/architecture.ts +1 -1
  212. package/src/context/citations.ts +3 -3
  213. package/src/context/classify/extract.ts +3 -3
  214. package/src/context/folders.ts +2 -2
  215. package/src/context/requirements.ts +1 -1
  216. package/src/design/project-fonts.ts +392 -0
  217. package/src/docs/read.ts +1 -1
  218. package/src/exec.ts +1 -1
  219. package/src/feedback/github.ts +2 -2
  220. package/src/gate/measures.ts +48 -10
  221. package/src/gate/sequencer.ts +56 -4
  222. package/src/gate/stages.ts +17 -0
  223. package/src/gate/suite-lock.ts +214 -0
  224. package/src/{git-files.ts → git/files.ts} +2 -2
  225. package/src/{git-ignore.ts → git/ignore.ts} +1 -1
  226. package/src/{worktree.ts → git/worktree.ts} +1 -1
  227. package/src/gov/citations.ts +1 -1
  228. package/src/gov/install.ts +1 -1
  229. package/src/gov/superseded.ts +1 -1
  230. package/src/gov/test-order.ts +2 -2
  231. package/src/help.ts +1 -1
  232. package/src/hooks/post-merge.ts +1 -1
  233. package/src/indexes/walk.ts +1 -1
  234. package/src/intake/folder.ts +1 -1
  235. package/src/labels/audit.ts +1 -1
  236. package/src/labels/map.ts +1 -1
  237. package/src/labels/phase.ts +3 -3
  238. package/src/markdown/files.ts +1 -1
  239. package/src/migrate/apply.ts +1 -1
  240. package/src/migrate/record-layout.ts +1 -1
  241. package/src/migrate/records.ts +11 -11
  242. package/src/migrate/scratch-evidence.ts +1 -1
  243. package/src/migrate/surface-roots.ts +6 -6
  244. package/src/pr/bijection.ts +1 -1
  245. package/src/pr/evidence.ts +250 -59
  246. package/src/pr/local.ts +16 -10
  247. package/src/pr/preview.ts +78 -2
  248. package/src/pr/tick.ts +56 -0
  249. package/src/process/harness.ts +1 -1
  250. package/src/records/backup.ts +2 -2
  251. package/src/records/ordinal.ts +1 -1
  252. package/src/records/prune.ts +1 -1
  253. package/src/records/size.ts +1 -1
  254. package/src/records/stale-canonical.ts +2 -2
  255. package/src/records/stale.ts +1 -1
  256. package/src/records/validate.ts +2 -2
  257. package/src/{project-root.ts → roots/project.ts} +1 -1
  258. package/src/{record-root.ts → roots/record.ts} +1 -1
  259. package/src/sandbox/coverage.ts +11 -12
  260. package/src/sandbox/equivalence.ts +57 -26
  261. package/src/sandbox/headless/dispatch.ts +264 -0
  262. package/src/sandbox/headless/run.ts +653 -0
  263. package/src/sandbox/headless/watch.ts +145 -0
  264. package/src/sandbox/hooks.ts +1 -1
  265. package/src/sandbox/provision.ts +90 -29
  266. package/src/sandbox/scenario.ts +588 -0
  267. package/src/sandbox/tree.ts +4 -8
  268. package/src/secrets/scan.ts +1 -1
  269. package/src/sessions/claim.ts +1 -1
  270. package/src/sessions/live.ts +4 -1
  271. package/src/sessions/resolve.ts +1 -1
  272. package/src/sessions/transfer/bundle.ts +2 -2
  273. package/src/slides/decks.ts +1 -1
  274. package/src/slides/package/fonts.ts +6 -2
  275. package/src/standards/audit.ts +2 -2
  276. package/src/standards/read.ts +1 -1
  277. package/src/sync/check.ts +2 -2
  278. package/src/sync/engine.ts +3 -3
  279. package/src/sync/git.ts +1 -1
  280. package/src/sync/history.ts +1 -1
  281. package/src/sync/layout.ts +2 -2
  282. package/src/sync/reverse.ts +1 -1
  283. package/src/sync/stamp.ts +1 -1
  284. package/src/sync/target.ts +1 -1
  285. package/src/sync/workflow.ts +1 -1
  286. package/src/targets/pulls.ts +2 -2
  287. package/src/targets/sweep.ts +2 -2
  288. package/src/{target.ts → targets/validate.ts} +1 -1
  289. package/src/tasks/answers.ts +1 -1
  290. package/src/tasks/archive.ts +1 -1
  291. package/src/tasks/label.ts +1 -1
  292. package/src/tasks/reach.ts +2 -2
  293. package/src/tasks/trunk.ts +1 -1
  294. package/src/tasks/validate.ts +38 -14
  295. package/src/teach/nav.ts +1 -1
  296. package/src/teach/workspace.ts +1 -1
  297. package/src/tooling/inject.ts +2 -2
  298. package/src/tooling/read.ts +1 -1
  299. package/src/tooling/scan.ts +1 -1
  300. package/src/tooling/subfolder.ts +1 -1
  301. package/src/version/installed.ts +1 -1
  302. package/src/version/skew.ts +1 -1
  303. package/src/web/readme-citations.ts +1 -1
  304. package/src/worktrees/bare-flag.ts +1 -1
  305. package/src/worktrees/reclaim.ts +2 -2
  306. package/src/worktrees/remove.ts +1 -1
  307. package/standards/board.md +3 -3
  308. package/standards/canvas.md +2 -1
  309. package/standards/plan.md +13 -7
  310. package/standards/skill.md +1 -0
  311. package/standards/wiki.md +12 -3
  312. package/tooling/base/configs/.github/workflows/pr-local-preview.yml +2 -2
  313. package/tsconfig.json +1 -1
  314. package/scripts/lib/sandbox-dispatch.sh +0 -190
  315. /package/src/{client-commands.ts → gate/client-commands.ts} +0 -0
  316. /package/src/{git-base.ts → git/base.ts} +0 -0
  317. /package/src/{git-env.ts → git/env.ts} +0 -0
  318. /package/src/{legacy-path.ts → roots/legacy.ts} +0 -0
  319. /package/src/{surface-root.ts → roots/surface.ts} +0 -0
  320. /package/src/{copy.ts → sync/copy.ts} +0 -0
@@ -0,0 +1,20 @@
1
+ ---
2
+ title: Install command
3
+ description: Which install command session-worktree Step 6 names when a Node worktree has no dependencies, read off the lockfile beside the manifest in a fixed order
4
+ ---
5
+
6
+ # Name the install command
7
+
8
+ Part of Step 6 of `session-worktree`. The session reads this file when the Node check reports dependencies not installed, to fill `<install>` in that line.
9
+
10
+ Take `<install>` from the lockfile beside the manifest, checked in this order, first match wins:
11
+
12
+ | Lockfile | Install command |
13
+ | ------------------------- | --------------- |
14
+ | `bun.lock` or `bun.lockb` | `bun install` |
15
+ | `pnpm-lock.yaml` | `pnpm install` |
16
+ | `yarn.lock` | `yarn install` |
17
+ | `package-lock.json` | `npm install` |
18
+ | none of the above | `bun install` |
19
+
20
+ The order matters only when more than one lockfile sits beside the manifest, such as a project mid-migration between package managers. It is fixed rather than derived from anything about the project, so a reader hitting that rare case checks which manager the project actually uses rather than trusting the row the table picked first.
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: sketch-design
3
3
  description: Runs a reference-and-pick loop against operator-supplied images and URLs, then writes the picked reference's traced color, type, and spacing values to a handoff file `design-extract` reads. Use when asked to "sketch a design direction", "compare these reference sites", "pick a look before we build DESIGN.md", "show me a few design directions", or as the first move on `design-extract`'s greenfield path when nothing has been rendered yet. Do NOT use when a value is already anchored to running code or a stylesheet, which is `design-extract`'s source path, or to draft the design system document itself, which stays `design-extract`'s job.
4
+ metadata:
5
+ family: setup
4
6
  ---
5
7
 
6
8
  # Sketch design
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: systematic-debugging
3
3
  description: Forces root-cause investigation before any fix when a test fails, a bug surfaces, or unexpected behavior appears. Auto-triggers on "test is failing", "it's broken", "why does X happen", "this isn't working". Do NOT use for trivial typo fixes or when the cause is already agreed on.
4
+ metadata:
5
+ family: build
4
6
  ---
5
7
 
6
8
  # Systematic debugging
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: target-check
3
3
  description: Reports what a target project holds against what the toolkit currently ships, one section per domain, reading through `canon` verbs rather than inspecting files. Use when asked to "check this target", "what has this project fallen behind on", "is this project current with the toolkit", "run the target check", or as the first thing a rollout worker runs after entering a target. Do NOT use to repair a finding, which the owning command or skill does, and do NOT use in the toolkit repository itself.
4
+ metadata:
5
+ family: upkeep
4
6
  ---
5
7
 
6
8
  # Target check
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: target-setup
3
3
  description: Gets a project onto the toolkit. Detects the stack, resolves per-domain arguments, previews the chain, runs `canon init`, then verifies at a stated depth and bootstraps the `index.md` system. Use when asked to "set up this project", "init this project", "bootstrap the toolkit", "install governance", "install gov rules", "set up indexes", "verify the scaffold", "run the smoke tests", or "one-shot install". Assumes the `canon` CLI is on PATH. Do NOT use on a project that already carries the toolkit, which is `canon-operator`, or to report per-domain drift without repairing it, which is `target-check`.
4
+ metadata:
5
+ family: setup
4
6
  ---
5
7
 
6
8
  # Setup
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: task-board
3
3
  description: Creates a task file in `.canon/tasks/` with the filename, phase label, and frontmatter the standard requires, and archives a shipped one out of the folder. Use when asked to "add a task", "create a task", "queue this", "put this on the board", "archive that task", or "close out a shipped task". Do NOT use to mark an outcome `[x]`. That is `context-fold`.
4
+ metadata:
5
+ family: decide
4
6
  ---
5
7
 
6
8
  # Task board
@@ -3,13 +3,15 @@ name: teach-workspace
3
3
  description: Opens and runs a learning workspace on one subject, holding a mission, resources, numbered lessons, reference pages, a glossary, and learning records that survive across sessions, and proposes where a durable page from one belongs once it outgrows the workspace. Use when asked to "teach me X", "open a learning workspace", "I want to learn X", "quiz me on this", "continue the lesson", "resume my workspace on X", or "promote this reference page". Do NOT use to write project documentation, which belongs to the surface owning that document, and do NOT use to answer one question, which is an ordinary reply.
4
4
  disable-model-invocation: true
5
5
  argument-hint: <subject to learn, or the topic of a workspace to resume or promote>
6
+ metadata:
7
+ family: answer
6
8
  ---
7
9
 
8
10
  # Teach workspace
9
11
 
10
12
  Run a learning workspace on one subject across sessions. The workspace holds what the learner has been through, so a session weeks later resumes from the folder rather than from the conversation.
11
13
 
12
- The shape of the workspace is fixed by `${CLAUDE_SKILL_DIR}/../../standards/teach.md`. Read it before writing anything into the folder. The glossary answers to `${CLAUDE_SKILL_DIR}/../../standards/glossary.md` wherever it lands. The pedagogy sits in `${CLAUDE_SKILL_DIR}/references/pedagogy.md`, the lesson craft in `${CLAUDE_SKILL_DIR}/references/lesson-craft.md`, and the promotion routing in `${CLAUDE_SKILL_DIR}/references/promotion.md`.
14
+ The shape of the workspace is fixed by `${CLAUDE_SKILL_DIR}/../../standards/teach.md`. Read it before writing anything into the folder. The glossary answers to `${CLAUDE_SKILL_DIR}/../../standards/glossary.md` wherever it lands. The pedagogy sits in `${CLAUDE_SKILL_DIR}/references/pedagogy.md`, the lesson craft and its build in `${CLAUDE_SKILL_DIR}/references/lesson-craft.md` and `lesson-build.md`, the record's revisit schedule in `revisit.md`, and the promotion routing in `${CLAUDE_SKILL_DIR}/references/promotion.md`.
13
15
 
14
16
  ## Guards
15
17
 
@@ -105,7 +107,7 @@ Write the correct option first, then present the options in the order `order` re
105
107
 
106
108
  ### The quiz, the teach-back block, and the lesson body
107
109
 
108
- Read `${CLAUDE_SKILL_DIR}/references/lesson-craft.md` before writing the lesson. `## Quiz construction` and `## Teach back` there fix the markup `canon teach nav`'s stepper gates on, so a quiz in any other shape shows every question at once and nothing reports it. `## Building the lesson body` carries the four marker pairs, the render, nav, stylesheet, and glossary verbs, and the rule against composing any of them by hand when a verb does not resolve. Keep every quiz answer the same length, so formatting leaks no clue about which one is correct. Decide the figure first, by `## Diagrams` there.
110
+ Read `${CLAUDE_SKILL_DIR}/references/lesson-craft.md` before writing the lesson. `## Quiz construction` and `## Teach back` there fix the markup `canon teach nav`'s stepper gates on, so a quiz in any other shape shows every question at once and nothing reports it. Then read `${CLAUDE_SKILL_DIR}/references/lesson-build.md` for the block list, the four marker pairs, the render, nav, stylesheet, and glossary verbs, and the rule against hand-composing any of them. Keep every quiz answer the same length, so formatting leaks no clue about which one is correct. Decide the figure first, by `## Diagrams` in `lesson-craft.md`.
109
111
 
110
112
  ### Hand over a link, never a path
111
113
 
@@ -129,19 +131,7 @@ Record the wrong answer rather than the count. The next session places the learn
129
131
 
130
132
  Record what the teach-back left out under what the learner got wrong, naming the concept and where the explanation broke. A produced answer and a selected one are both retrieval failures the next session places from, so a second heading would split one input across two sections.
131
133
 
132
- Then write `## Revisit`, one bullet per item, in the shape `${CLAUDE_SKILL_DIR}/../../standards/teach.md` fixes:
133
-
134
- ```markdown
135
- ## Revisit
136
-
137
- - **<what comes back up>**: due <YYYY-MM-DD>, rung <n>
138
- ```
139
-
140
- Take both the date and the rung from the `due` entry Step 1 already read, copying `hit` for an item the learner retrieved unaided and `miss` for one they did not, with the rung stepped the same way. Do not compute a date from the ladder. A session told to widen a gap still picks the number by judgment, which is the reason the verb reports both dates at all.
141
-
142
- An item the records have never scheduled has no `due` entry to copy from. Open it at rung 1, dated the day after this session, which is the ladder's floor and the one number this body states. Every later date for it comes from the verb.
143
-
144
- An entry outside this shape schedules nothing and nothing reports that it was skipped, so write the shape exactly. A later record naming the same item supersedes an earlier entry, so revise a schedule by writing the new bullet rather than editing the record it was set in.
134
+ Then write `## Revisit`. Read `${CLAUDE_SKILL_DIR}/references/revisit.md` before writing it, for the bullet shape, where each date and rung is copied from, and the first schedule for an item no record has set.
145
135
 
146
136
  Then restate the mission's success lines with what is now met, reading them from the `success` the lesson verb already reported rather than from `MISSION.md` by eye. Report each line as met or not met, and name what the learner did that meets it. A mission whose lines are all met is finished, and saying so is what closes a workspace.
147
137
 
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: Lesson build reference
3
+ description: The block list canon teach render takes and the verbs that build the lesson body, being render, nav, stylesheet, and glossary
4
+ ---
5
+
6
+ # Lesson build reference
7
+
8
+ Mechanics rather than judgment. `lesson-craft.md` covers what a lesson should be, and this file covers how its body reaches the page through the verbs.
9
+
10
+ ## The block list
11
+
12
+ `canon teach render` takes a JSON array of blocks and renders it through the same components a lesson body composes. Six types, and every structural body composes from them:
13
+
14
+ - `{"type":"heading","level":1|2,"text":"<text>"}`: an `<h1>` or `<h2>`.
15
+ - `{"type":"paragraph","text":"<text>","lede":true,"cites":[1]}`: a `<p>`, marked `lede` for the dek that opens the lesson. `cites` adds a footnote marker per reference number after the text, and a lede takes none.
16
+ - `{"type":"list","items":["<text>", ...],"ordered":true}`: a `<ul>` or, with `ordered`, an `<ol>`.
17
+ - `{"type":"refs","items":[{"title":"<name>","url":"<https URL>","note":"<text>"}, ...]}`: the lesson's one reference list, numbered from 1 in item order. `url` and `note` are optional, and a `url` must be http or https.
18
+ - `{"type":"code","lang":"ts","text":"<source>"}`: a code sample, highlighted at render time with no script. `lang` is optional and takes a highlight.js name or alias. One the renderer does not register renders as plain escaped code.
19
+ - `{"type":"raw","html":"<markup>"}`: the escape hatch, passed through unescaped.
20
+
21
+ Code never travels through `raw`. A hand-written `<pre><code>` renders with no color, and `nav` never highlights markup already in a lesson body, so a sample written that way stays plain for good. A fenced block in a reference page's markdown is highlighted by `nav` on its own.
22
+
23
+ The quiz and the teach-back block in `lesson-craft.md` are the one case `raw` is always needed for, since their fixed contract is not a components concern. Give them the array's last `raw` entry, followed only by `refs`, rather than reaching for `raw` anywhere the other types could carry the content instead.
24
+
25
+ A claim resting on a source carries a `cites` number, and the source goes in the lesson's one `refs` block rather than into the sentence. Draw every reference from what `canon teach resource --read` recorded, never from a lead, since a lead is a source nobody opened. Render refuses a cite no reference resolves, so number the list before citing into it.
26
+
27
+ ## Building the lesson body
28
+
29
+ Step 4 of `teach-workspace` reads this section before writing a lesson, after the lesson verb has resolved its path and quiz order. Write the chrome as four empty marker pairs rather than composing it by hand: `<!-- canon:teach:style -->`/`<!-- /canon:teach:style -->` inside `<head>`, and `<!-- canon:teach:header -->`, `<!-- canon:teach:footnav -->`, and `<!-- canon:teach:scripts -->` each with its own close marker, in that order in `<body>`.
30
+
31
+ Build the authored `<h1>`, lede, body, and quiz as a JSON array of blocks rather than composing markup by hand, and render it through the verb rather than through a component import:
32
+
33
+ ```bash
34
+ echo '[
35
+ {"type":"heading","level":1,"text":"<title>"},
36
+ {"type":"paragraph","lede":true,"text":"<the dek>"},
37
+ {"type":"paragraph","text":"<a body paragraph>"},
38
+ {"type":"paragraph","text":"<a claim resting on a source>","cites":[1]},
39
+ {"type":"list","ordered":true,"items":["<step one>","<step two>"]},
40
+ {"type":"raw","html":"<the quiz and teach-back block composed per lesson-craft.md>"},
41
+ {"type":"refs","items":[{"title":"<source name>","url":"<https URL>"}]}
42
+ ]' | canon teach render --json
43
+ ```
44
+
45
+ `## The block list` above states each type and where `raw` belongs. Take the call's `html` field and write it between the header's close marker and the footnav's open marker, and nothing else anywhere in the file.
46
+
47
+ Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it, and never compose the lesson body by hand as a fallback. That is the state this section exists to end, and a target holds this skill body before it holds the verb, since a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes.
48
+
49
+ Then run:
50
+
51
+ ```bash
52
+ canon teach nav <topic> --json
53
+ ```
54
+
55
+ It fills every marker pair from what the workspace holds on disk: the embedded stylesheet, the header with its breadcrumb and jump menus, the prev/next footer nav, and the behavior scripts, and it rewrites the workspace's contents page and the teach-root listing in the same run. It refuses a lesson missing one of the four marker pairs by name rather than guessing at the boundary, so a marker dropped while writing the lesson is caught here rather than read back later as a lesson nothing links to. Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it, and never compose the chrome by hand as a fallback.
56
+
57
+ Seed the stylesheet through the verb rather than authoring a palette, on the first lesson in a workspace:
58
+
59
+ ```bash
60
+ canon teach stylesheet <topic> --json
61
+ ```
62
+
63
+ It writes the design tokens as custom properties and the components built on them, from the one source every other rendered surface reads. Add lesson rules under the seed and reach a value through its property rather than restating the hex, which is what let each workspace fork the palette from every other. It refuses to overwrite, so running it again on a workspace that has grown its own rules is safe and reports `written` as false.
64
+
65
+ Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it. Do not fall back to writing a palette by hand.
66
+
67
+ Add every term the lesson defines to `GLOSSARY.md` through the verb, which places the entries alphabetically in the shape the standard fixes:
68
+
69
+ ```bash
70
+ canon teach glossary <topic> --json \
71
+ --term "<term>=<definition, written without using the term>" \
72
+ --first-seen <the lesson or reference page this batch comes from>
73
+ ```
74
+
75
+ `--term` repeats and one call writes the file once, which is what keeps a batch of terms from racing on it. A term already defined is refused, since a definition the subject has moved under is a revision of the entry rather than a second one.
@@ -1,11 +1,22 @@
1
1
  ---
2
2
  title: Lesson craft reference
3
- description: Typography, restraint, quiz construction, what makes a lesson worth returning to, and the verbs that build the lesson body
3
+ description: Typography, restraint, quiz construction, and what makes a lesson worth returning to
4
4
  ---
5
5
 
6
6
  # Lesson craft reference
7
7
 
8
- Judgment rather than shape. The workspace standard fixes where a lesson sits and what it is named, and this file covers what makes one worth opening twice.
8
+ Judgment rather than shape. The workspace standard fixes where a lesson sits and what it is named, and this file covers what makes one worth opening twice. The block list and the verbs that build the lesson body sit in `lesson-build.md`.
9
+
10
+ ## Contents
11
+
12
+ - [One course, not a pile of pages](#one-course-not-a-pile-of-pages)
13
+ - [Typography](#typography)
14
+ - [Restraint](#restraint)
15
+ - [Diagrams](#diagrams)
16
+ - [Quiz construction](#quiz-construction)
17
+ - [Teach back](#teach-back)
18
+ - [Tokens travel with the course](#tokens-travel-with-the-course)
19
+ - [What makes a lesson worth returning to](#what-makes-a-lesson-worth-returning-to)
9
20
 
10
21
  ## One course, not a pile of pages
11
22
 
@@ -79,23 +90,6 @@ The quiz shape is a contract rather than a convention. `canon teach nav` splices
79
90
 
80
91
  The stepper hides and shows and sets nothing else, so how a selected option looks, and whether a wrong one is marked as wrong, is the workspace stylesheet's to grow. Name the correct option in the feedback text for that reason: it is what a learner reads to find out whether they were right.
81
92
 
82
- ## The block list
83
-
84
- `canon teach render` takes a JSON array of blocks and renders it through the same components a lesson body composes. Six types, and every structural body composes from them:
85
-
86
- - `{"type":"heading","level":1|2,"text":"<text>"}`: an `<h1>` or `<h2>`.
87
- - `{"type":"paragraph","text":"<text>","lede":true,"cites":[1]}`: a `<p>`, marked `lede` for the dek that opens the lesson. `cites` adds a footnote marker per reference number after the text, and a lede takes none.
88
- - `{"type":"list","items":["<text>", ...],"ordered":true}`: a `<ul>` or, with `ordered`, an `<ol>`.
89
- - `{"type":"refs","items":[{"title":"<name>","url":"<https URL>","note":"<text>"}, ...]}`: the lesson's one reference list, numbered from 1 in item order. `url` and `note` are optional, and a `url` must be http or https.
90
- - `{"type":"code","lang":"ts","text":"<source>"}`: a code sample, highlighted at render time with no script. `lang` is optional and takes a highlight.js name or alias. One the renderer does not register renders as plain escaped code.
91
- - `{"type":"raw","html":"<markup>"}`: the escape hatch, passed through unescaped.
92
-
93
- Code never travels through `raw`. A hand-written `<pre><code>` renders with no color, and `nav` never highlights markup already in a lesson body, so a sample written that way stays plain for good. A fenced block in a reference page's markdown is highlighted by `nav` on its own.
94
-
95
- The quiz and the teach-back block above are the one case `raw` is always needed for, since their fixed contract is not a components concern. Give them the array's last `raw` entry, followed only by `refs`, rather than reaching for `raw` anywhere the other types could carry the content instead.
96
-
97
- A claim resting on a source carries a `cites` number, and the source goes in the lesson's one `refs` block rather than into the sentence. Draw every reference from what `canon teach resource --read` recorded, never from a lead, since a lead is a source nobody opened. Render refuses a cite no reference resolves, so number the list before citing into it.
98
-
99
93
  ## Teach back
100
94
 
101
95
  A quiz is recognition and a teach-back is production, which is the form retrieval practice prefers. Carry both: the quiz places the learner against options someone could hold, and the teach-back is where the learner finds out what they cannot say without help.
@@ -131,53 +125,3 @@ Pick values the material needs rather than values the project happens to hold. I
131
125
  - The lesson states what it assumes. A returning reader can tell in one line whether they are in the right place.
132
126
  - The hard part is named as the hard part. Material that flattens everything to one difficulty gives a returning reader nothing to navigate by.
133
127
  - Nothing depends on the session it was written in. A lesson referring to what was discussed is unreadable a week later.
134
-
135
- ## Building the lesson body
136
-
137
- Step 4 of `teach-workspace` reads this section before writing a lesson, after the lesson verb has resolved its path and quiz order. Write the chrome as four empty marker pairs rather than composing it by hand: `<!-- canon:teach:style -->`/`<!-- /canon:teach:style -->` inside `<head>`, and `<!-- canon:teach:header -->`, `<!-- canon:teach:footnav -->`, and `<!-- canon:teach:scripts -->` each with its own close marker, in that order in `<body>`.
138
-
139
- Build the authored `<h1>`, lede, body, and quiz as a JSON array of blocks rather than composing markup by hand, and render it through the verb rather than through a component import:
140
-
141
- ```bash
142
- echo '[
143
- {"type":"heading","level":1,"text":"<title>"},
144
- {"type":"paragraph","lede":true,"text":"<the dek>"},
145
- {"type":"paragraph","text":"<a body paragraph>"},
146
- {"type":"paragraph","text":"<a claim resting on a source>","cites":[1]},
147
- {"type":"list","ordered":true,"items":["<step one>","<step two>"]},
148
- {"type":"raw","html":"<the quiz and teach-back block composed above>"},
149
- {"type":"refs","items":[{"title":"<source name>","url":"<https URL>"}]}
150
- ]' | canon teach render --json
151
- ```
152
-
153
- `## The block list` above states each type and where `raw` belongs. Take the call's `html` field and write it between the header's close marker and the footnav's open marker, and nothing else anywhere in the file.
154
-
155
- Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it, and never compose the lesson body by hand as a fallback. That is the state this section exists to end, and a target holds this skill body before it holds the verb, since a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes.
156
-
157
- Then run:
158
-
159
- ```bash
160
- canon teach nav <topic> --json
161
- ```
162
-
163
- It fills every marker pair from what the workspace holds on disk: the embedded stylesheet, the header with its breadcrumb and jump menus, the prev/next footer nav, and the behavior scripts, and it rewrites the workspace's contents page and the teach-root listing in the same run. It refuses a lesson missing one of the four marker pairs by name rather than guessing at the boundary, so a marker dropped while writing the lesson is caught here rather than read back later as a lesson nothing links to. Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it, and never compose the chrome by hand as a fallback.
164
-
165
- Seed the stylesheet through the verb rather than authoring a palette, on the first lesson in a workspace:
166
-
167
- ```bash
168
- canon teach stylesheet <topic> --json
169
- ```
170
-
171
- It writes the design tokens as custom properties and the components built on them, from the one source every other rendered surface reads. Add lesson rules under the seed and reach a value through its property rather than restating the hex, which is what let each workspace fork the palette from every other. It refuses to overwrite, so running it again on a workspace that has grown its own rules is safe and reports `written` as false.
172
-
173
- Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it. Do not fall back to writing a palette by hand.
174
-
175
- Add every term the lesson defines to `GLOSSARY.md` through the verb, which places the entries alphabetically in the shape the standard fixes:
176
-
177
- ```bash
178
- canon teach glossary <topic> --json \
179
- --term "<term>=<definition, written without using the term>" \
180
- --first-seen <the lesson or reference page this batch comes from>
181
- ```
182
-
183
- `--term` repeats and one call writes the file once, which is what keeps a batch of terms from racing on it. A term already defined is refused, since a definition the subject has moved under is a revision of the entry rather than a second one.
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Revisit schedule
3
+ description: How teach-workspace Step 5 writes a learning record's Revisit section, being the bullet shape, where each date and rung is copied from, the first schedule for a new item, and how a later record revises one
4
+ ---
5
+
6
+ # Write the Revisit section
7
+
8
+ Part of Step 5 of `teach-workspace`. The session reads this file once the record's lessons, retrievals, and wrong answers are written, before restating the mission's success lines.
9
+
10
+ Then write `## Revisit`, one bullet per item, in the shape `${CLAUDE_SKILL_DIR}/../../standards/teach.md` fixes:
11
+
12
+ ```markdown
13
+ ## Revisit
14
+
15
+ - **<what comes back up>**: due <YYYY-MM-DD>, rung <n>
16
+ ```
17
+
18
+ Take both the date and the rung from the `due` entry Step 1 already read, copying `hit` for an item the learner retrieved unaided and `miss` for one they did not, with the rung stepped the same way. Do not compute a date from the ladder. A session told to widen a gap still picks the number by judgment, which is the reason the verb reports both dates at all.
19
+
20
+ An item the records have never scheduled has no `due` entry to copy from. Open it at rung 1, dated the day after this session, which is the ladder's floor and the one number this body states. Every later date for it comes from the verb.
21
+
22
+ An entry outside this shape schedules nothing and nothing reports that it was skipped, so write the shape exactly. A later record naming the same item supersedes an earlier entry, so revise a schedule by writing the new bullet rather than editing the record it was set in.
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: test-craft
3
3
  description: Carries the rule that decides which layer a test belongs at, the question each one opens with, the end to end budget, and the final filter a session runs over what it wrote. Use when writing, changing, or judging a test, after implementing as well as before, when adding a regression guard, when choosing between unit, component, or end to end, or when asked "where should this test go", "is this a good test", "should this be an e2e test", or "why is our e2e suite so slow". Do NOT use for the red, green, refactor procedure, which is `test-first`, or for a bug nobody has explained yet, which is `systematic-debugging`.
4
+ metadata:
5
+ family: build
4
6
  ---
5
7
 
6
8
  # Test craft
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: test-first
3
3
  description: Write the failing test for a behavior before writing the code that satisfies it, confirm it fails for the right reason, implement the smallest change that turns it green, then refactor with the suite green. Auto-triggers before implementing a planned feature, adding a function or an endpoint, or extending existing behavior whose new shape is already decided. Do NOT use for a failure with no known cause, which is canon:systematic-debugging, or when the test for the behavior already exists and already passes.
4
+ metadata:
5
+ family: build
4
6
  ---
5
7
 
6
8
  # Test first
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: ui-checklist
3
3
  description: Writes the visual checklist a reviewer reads beside the evidence screenshots, and names each changed behavior shipping with no test so `test-craft` can place one. Use after implementing UI changes, or when asked "what should I look at", "what do I verify", or "give me a visual checklist". Do NOT use in empty sessions with no implementation context, and do NOT use to write the tests themselves.
4
+ metadata:
5
+ family: build
4
6
  ---
5
7
 
6
8
  # UI checklist
@@ -39,7 +41,7 @@ Write each box so a session driving the running app can run it without guessing:
39
41
  - **Taste.** End the line with `(taste)` when the result is a judgment of look or feel rather than a fact a driver can observe. A driver reports such a box as needing a person's eyes instead of passing it.
40
42
  - **Setup.** A box needing a state the page does not open in states the setup inline. When a hosted preview cannot reach that state, such as a stopped service or a seeded record, end the line with `(local only)` instead.
41
43
 
42
- The checkbox stays `- [ ]` followed by the action and the result, since the evidence comment carries ticked boxes forward by that shape.
44
+ The checkbox stays `- [ ]` followed by the action and the result, since the evidence comment reads boxes by that shape. Only the UI reviewer ticks a box, stamping it with the commit it passed at, and the comment carries that tick forward only while the head it names is current.
43
45
 
44
46
  ## The missing-test list
45
47
 
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: ux-audit
3
3
  description: Audits the current UI for incomplete, inconsistent, or confusing patterns. Reads DESIGN.md and canon/wireframes/ for intent, scans UI files, and outputs observations grouped by surface. Use when asked "audit the UX", "audit the UI", "UX audit", or "find UI roughness". Do NOT use for new feature planning or code changes, and do NOT use to measure what a running interface costs to paint, which is `ux-measure`.
4
+ metadata:
5
+ family: check
4
6
  ---
5
7
 
6
8
  # UX audit
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: ux-measure
3
3
  description: Measures paint, processor, and layout cost against a running interface and reports numbers against published thresholds. Detects the project's existing browser harness rather than requiring one. Use when asked "how fast is this page", "measure the UI", "what does this cost to render", "check Core Web Vitals", or "profile the interface". Do NOT use to judge UI quality by reading source, which is `ux-audit`.
4
+ metadata:
5
+ family: check
4
6
  ---
5
7
 
6
8
  # UX measure
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: ux-walkthrough
3
3
  description: Runs an inspection walkthrough over a running app with the operator. Measures each finding off the built page, drafts arms as served HTML pages lifted from the app's own markup and stylesheet, hands over the localhost link before every pick question, records findings and picks with the arms they beat in one walkthrough file, and relays picks only in batches the operator calls. Use when asked to "run a first-use walkthrough", "do an operator walkthrough", "go through my findings one by one", "inspection walkthrough over the app", or "walk through everything I listed with me". Do NOT use for one decision on its own, which is `draft-and-pick`, to read source for roughness, which is `ux-audit`, or to build a pick, which is `plan-feature` and a worker.
4
+ metadata:
5
+ family: check
4
6
  ---
5
7
 
6
8
  # UX walkthrough
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: video-craft
3
3
  description: Carries what makes a composed video of software read as designed rather than generic, being captions that name only what the frame shows, which moment earns a zoom and how fast it lands, how a real pointer behaves on a real interface, music or silence and how far under a voice the music sits, and reading a frame before dismissing a checker finding. Every number traces to a source. Use before composing or judging any video, whether a product demo, an explainer, a pull request walkthrough, or a launch clip, when a render reads generic or slow, or when asked "make this video look designed", "is this zoom too slow", "what should this caption say", "should this have music", or "the checker flagged a frame, is it real". Do NOT use for general motion such as easing, speed variety, and click timing, which HyperFrames' `hyperframes-animation` and `hyperframes-creative` carry, to fetch or generate a media file, which is `media-use`, or to record the take, which is `record-screencast`.
4
+ metadata:
5
+ family: build
4
6
  ---
5
7
 
6
8
  # Video craft
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: write-human
3
3
  description: Carries the voice, word choice, rhythm, sentence construction, and information density rules a banned-character scan cannot express, plus the catalog of machine tells that survive a clean ban scan. Use when writing or revising prose a person will read, when a passage reads flat or uniform, or when asked to "make this read like a person", "fix the cadence", "this reads like AI wrote it", "vary the sentences", or "tighten this without gutting it". Do NOT use for banned characters, which `markdown.md` states and `canon markdown audit` gates, and do NOT use to restate text that already exists in plainer words, which is `restate-plainly`, whose body loads these rules from here.
4
+ metadata:
5
+ family: answer
4
6
  ---
5
7
 
6
8
  # Write human
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: youtube-transcripts
3
3
  description: Fetches a YouTube video transcript with metadata frontmatter into the current repo via `canon transcripts`. Use when the user pastes a YouTube URL and asks to "grab the transcript", pull captions, or save a transcript for context. Do NOT use for downloading the video file, summarizing a transcript that already exists, or non-YouTube links.
4
+ metadata:
5
+ family: answer
4
6
  ---
5
7
 
6
8
  # YouTube transcripts
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Canvas
3
- description: The canvas server, its content format, and the verbs that list, arrange, select, edit, and capture frames
3
+ description: The canvas server, its content format, and the verbs that list, arrange, select, edit, mark, and capture frames
4
4
  ---
5
5
 
6
6
  # Canvas
@@ -11,7 +11,9 @@ description: The canvas server, its content format, and the verbs that list, arr
11
11
 
12
12
  `canvas serve` serves the canvas on `127.0.0.1`, walks ports like `canon serve`, refuses a `Host` other than loopback on its own port, and runs until interrupted. Each frame gets the project's token stylesheet injected, being this toolkit's tokens in its own checkout, else `.claude/design/base.css` plus anything under `.claude/design/project/`, else none with a notice. An open canvas reloads a frame whose file changes.
13
13
 
14
- The toolkit's own tokens arrive with the font faces they name embedded, so a frame renders in them on a machine that never installed them. An installed base owns its fonts and gets no faces added.
14
+ The toolkit's own tokens arrive with the font faces they name embedded, so a frame renders in them on a machine that never installed them. An installed base gets the same treatment: each vendored face its sheets name is embedded, unless a project rule declares that family itself.
15
+
16
+ A project's own `@font-face` rules under `.claude/design/project/` have each `url()` inlined as a `data:` URI. A rule whose file is missing, or whose path leads out of `.claude/design/project/` after links resolve, is dropped and the frame still renders. `canvas serve` warns once per dropped rule and names each under `tokens.dropped` in its `--json` record. The confinement check reads each `url()` after percent-decoding it. `canon design fonts add` writes those rules.
15
17
 
16
18
  Before it binds a port, `canvas serve` checks that `preact` and `@preact/signals` resolve from the package the CLI runs from, never from the served project. When either is missing it refuses with reason `missing-client-deps` and names `bun install` in the detail, rather than serving a shell that loads as a blank page.
17
19
 
@@ -25,28 +27,42 @@ The write routes the shell posts to also refuse a request carrying an `Origin` o
25
27
 
26
28
  `frame move <page> <name> --x <px> --y <px>` rewrites one frame's position in `layout.json` and keeps its size. An omitted axis stays where the frame is. It refuses a frame or page that does not exist and a layout that does not parse.
27
29
 
28
- The shell writes through the same writer when the operator drags a frame. Both take a lock file beside the layout, read it, merge their change, and replace it, so a drag released while a verb writes loses neither position. A writer that cannot get the lock within two seconds refuses with reason `busy`.
30
+ `frame resize <page> <name> --width <px> --height <px>` rewrites one frame's whole box in one write, and `--x` and `--y` move it at the same time. An omitted flag keeps the frame's current value. It refuses a width or height that is not a positive number as `invalid-size`, a position that is not a number as `invalid-position`, and a missing frame, a missing page, or a layout that does not parse as `frame move` does.
31
+
32
+ The shell writes through the same writer when the operator drags a frame or one of its corner handles. Both take a lock file beside the layout, read it, merge their change, and replace it, so a drag released while a verb writes loses neither position. A writer that cannot get the lock within two seconds refuses with reason `busy`.
29
33
 
30
34
  `canvas selection --json` emits `{ ok, selection }` with the page, frame, file, box, and path of the frame the operator selected, or `selection: null` when nothing is selected or the selected frame has since been removed. Read it when the operator says "this one".
31
35
 
32
36
  The operator can also pick one element inside a frame, by clicking it on the surface or in the frame's layers tree. The selection then carries `element`, recording the `index` in document order, `tag`, `classes`, and `text` excerpt as they were at the pick. An edit to the frame since can shift that index onto another element, so `stale` turns true once the file's content no longer matches what the pick was made against. Check it before acting on the index.
33
37
 
34
- A pick is refused as `address-mismatch` when the browser builds elements the file never states, such as a `tbody` a table leaves out or the document wrapper around a fragment. The shell sends its own element count beside the index, so a frame the two sides count differently is reported rather than recorded against the wrong element. A pick is refused as `stale-address` when the frame file changed between the frame being served and the pick arriving, since every served frame carries the hash of its file and the shell sends that hash back.
38
+ A pick is refused as `address-mismatch` when the browser builds elements the file never states, such as a `tbody` a table leaves out or a `body` after a `head` the file states. A fragment is picked like a whole document, since the server writes the missing `html`, `head`, and `body` into the served frame and the shell leaves them out of its count. The shell sends its own element count beside the index, so a frame the two sides count differently is reported rather than recorded against the wrong element. A pick is refused as `stale-address` when the frame file changed between the frame being served and the pick arriving, since every served frame carries the hash of its file and the shell sends that hash back.
35
39
 
36
40
  ## Edit
37
41
 
38
- `canvas edit <page>/<frame> --element <index> --set <property>=<value>` sets one property of the element at that index, the same index `canvas selection` reports. The properties are `text`, `color`, `background-color`, `font-size`, `font-weight`, `width`, `height`, `padding`, `gap`, and `flex-direction`. A style property is written into the element's inline `style`, replacing that property and leaving the others as they were, and an empty value drops it.
42
+ `canvas edit <page>/<frame> --element <index> --set <property>=<value>` sets one property of the element at that index, the same index `canvas selection` reports. The properties are `text`, `color`, `background-color`, `font-size`, `font-weight`, `font-family`, `line-height`, `letter-spacing`, `text-align`, `width`, `height`, `padding`, `gap`, `display`, `flex-direction`, `justify-content`, `align-items`, `flex-wrap`, `opacity`, `border-radius`, `border-top-left-radius`, `border-top-right-radius`, `border-bottom-right-radius`, and `border-bottom-left-radius`. A style property is written into the element's inline `style`, replacing that property and leaving the others as they were, and an empty value drops it. Writing `border-radius` or `padding` also drops that shorthand's longhands from the same `style`, so no corner or side left over overrides the new value. Writing a longhand leaves its shorthand in place, since the longhand comes later and wins.
39
43
 
40
44
  `text` replaces the text of an element holding text alone and refuses one holding other elements as `not-text-only`. Every byte outside the element stays as it was. `--json` emits the page, frame, file, path, and the file's new `hash`.
41
45
 
42
- The operator edits the same set from the inspector, which posts to the same writer with the hash the frame was served with. An edit made against a version of the file Claude has since rewritten is refused as `stale-address` and the shell reloads the frame, so nothing lands on a shifted element. Both writers take the frame file's lock, and an edit that keeps the selected element where it was keeps the selection fresh.
46
+ The operator edits the same set from the inspector, which posts to the same writer with the hash the frame was served with. Dragging a selected element's corner handle writes `width` and then `height` in pixels through that writer, the second edit carrying the hash the first answered. An edit made against a version of the file Claude has since rewritten is refused as `stale-address` and the shell reloads the frame, so nothing lands on a shifted element. Both writers take the frame file's lock, and an edit that keeps the selected element where it was keeps the selection fresh.
43
47
 
44
- A color picked from the project's tokens is written as `var(--<name>)`, and below full opacity as a `color-mix()` of that `var()` with `transparent` at the opacity percent, so it keeps following the theme. A browser older than 2023 drops a `color-mix()` value, which leaves the property unset there. A hex is written as six digits, or eight below full opacity.
48
+ Size, padding, opacity, radius, and the type properties show in the inspector for every element. Family and font size list the sheet's `font-family` and `font-size` token groups first and write a pick as `var(--<name>)`, the same as a color. The flex fields show only on a flex container, a grid container gets none, and the inspector sets `display` only to `flex`, so any other `display` change goes through the verb.
45
49
 
46
- Inline style beats a class, so an operator's edit masks a class change Claude makes later. Read a frame's inline styles before restyling it, and remove one the change should replace. The inspector marks a color or background set inline with the word `raw` when its value names no `var()` and is not `currentColor` or a CSS-wide keyword, since that value stays fixed when the theme changes. A property outside the set, or a value carrying `;`, `{`, `}`, `<`, `>`, or a line break, is refused as `invalid-edit`.
50
+ A color picked from the project's tokens is written as `var(--<name>)`, and below full opacity as a `color-mix()` of that `var()` with `transparent` at the opacity percent, so it keeps following the theme. A browser older than 2023 drops a `color-mix()` value, which leaves the property unset there. A hex is written as six digits, or eight below full opacity. The inspector's full color picker writes a hex for any color it sets, so the field marks the value raw, and only its alpha keeps a token through the `color-mix()` form.
51
+
52
+ Inline style beats a class, so an operator's edit masks a class change Claude makes later. Read a frame's inline styles before restyling it, and remove one the change should replace. The inspector marks a color, a background, or a family or font size the sheet has tokens for, set inline, with the word `raw` when its value names no `var()` and is not `currentColor` or a CSS-wide keyword, since that value stays fixed when the theme changes. A property outside the set, or a value carrying `;`, `{`, `}`, `<`, `>`, or a line break, is refused as `invalid-edit`.
47
53
 
48
54
  The Theme tab in the shell lists what the token stylesheet defines, grouped as color, spacing, radius, font family, font size, and other. The page record at `/api/pages` carries the same list as `tokens.groups`.
49
55
 
56
+ ## Mark a frame being edited
57
+
58
+ `canvas editing <page>/<frame>` marks a frame as being edited, so an open canvas shows who is working on it before the write lands. The shell draws the mark as `<by> editing` on that frame's label with a dashed outline around it, and drops it on the reread after `--done` or at the mark's `until` with no reread. Run it before writing a frame and again with `--done` once the edits are written. A bare `canvas editing` lists the live marks, and `--json` emits `{ ok, editing }` after each of the three, with each mark carrying `page`, `frame`, `by`, `since`, and `until`.
59
+
60
+ The label is `--by <name>` when given. Without it, the verb reads the caller's name off the session roster, and falls back to `a session` when the environment names no session or the roster holds none matching it.
61
+
62
+ The marks live in `.canon/canvas/editing.json`, keyed by `<page>/<frame>`. Each write takes the record's lock and merges its one key, so two sessions marking two frames both keep their marks. A mark lapses five minutes after it was written, and marking the frame again renews it, so a session that never clears its mark misleads the operator for five minutes at most. A read leaves out a lapsed mark and a mark on a frame since removed, and a record that does not parse reads as holding none and is replaced by the next mark.
63
+
64
+ A mark refuses `no-page` or `no-frame` for a target not on disk, and `invalid-name` for a target that is not `<page>/<frame>` or for `--done` with no target. `--done` on a frame holding no mark succeeds and writes nothing. The mark gates no write, so an inspector edit to a marked frame still lands, and the hash check still refuses one made against a file the session rewrote. The page record at `/api/pages` carries the live marks as `editing`, each with `page`, `frame`, `by`, and `until`.
65
+
50
66
  ## Capture
51
67
 
52
68
  `canvas capture <page>/<frame>` renders one frame as a PNG, and `canvas capture <page>` renders every frame on the page. Each goes through a server started for the call, so the injected tokens are in the image, and renders at the frame's own width from the layout, so a media query resolves there. It never captures the file on disk.
@@ -5,11 +5,11 @@ description: Rendering HTML sources to PNG, what the command asserts about fonts
5
5
 
6
6
  # Capture
7
7
 
8
- `canon capture [source] --selector <sel>` renders HTML sources to PNG, which is how a generated documentation image is rebuilt from the markup it was generated out of. The source defaults to `assets/`, where a directory expands to every `.html` directly inside it, so adding a capture means dropping a file beside the first one and running the same command. That default is a generic starting point rather than a convention every target shares, and it stays because a missing folder still refuses loud, naming the argument, rather than failing silently. This repository no longer takes it: its own sources moved to `assets/captures/` and its images moved to `assets/evidence/`, so a run here names the source explicitly and sends the output where that run wants it, `--out assets/evidence` to rebuild the committed images and somewhere disposable to preview them.
8
+ `canon capture [source] --selector <sel>` renders HTML sources to PNG, which is how a generated documentation image is rebuilt from the markup it was generated out of. The source defaults to `assets/`, where a directory expands to every `.html` directly inside it, so adding a capture means dropping a file beside the first one and running the same command. That default is a generic starting point rather than a convention every target shares, and it stays because a missing folder still refuses loud, naming the argument, rather than failing silently. This repository no longer takes it: its own sources moved to `assets/captures/` and its images moved to `assets/frames/`, so a run here names the source explicitly and sends the output where that run wants it, `--out assets/frames` to rebuild the committed images and somewhere disposable to preview them.
9
9
 
10
10
  ```bash
11
11
  canon capture --selector .window
12
- canon capture assets/captures/install.html --selector .window --out assets/evidence
12
+ canon capture assets/captures/install.html --selector .window --out assets/frames
13
13
  canon capture assets/captures --selector .window --out .canon/review/captures
14
14
  canon capture https://example.com --selector .window --out preview.png
15
15
  ```
@@ -18,9 +18,9 @@ canon capture https://example.com --selector .window --out preview.png
18
18
 
19
19
  ## What this repository captures
20
20
 
21
- A capture set here spans two folders. `assets/captures/` holds three sources and the two templates they are written from, and `assets/evidence/` holds their images and the built-page capture a document points at with the stamp answering for each, under the segment `canon pr evidence` compares. One run over the source folder rebuilds every image, and it takes `--out assets/evidence` to put each PNG where its document points rather than beside the markup it rendered. None of the sources is edited by hand. `scripts/core/regen-hero.ts` writes each `.html` from the template beside it, filling one shared value map into all of them. A branch commits none of them for a moved count or token, since the refresh workflow regenerates them from `main` and opens one pull request, and `bun run check` runs the script with `--check`, which fills every template into a temp folder and fails when the regeneration cannot run.
21
+ A capture set here spans two folders. `assets/captures/` holds three sources and the two templates they are written from, and `assets/frames/` holds their images and the built-page capture a document points at with the stamp answering for each, outside the `evidence` segment `canon pr evidence` compares. The folder name is this repository's own layout, and a target picks its own `--out`. One run over the source folder rebuilds every image, and it takes `--out assets/frames` to put each PNG where its document points rather than beside the markup it rendered. None of the sources is edited by hand. `scripts/core/regen-hero.ts` writes each `.html` from the template beside it, filling one shared value map into all of them. A branch commits none of them for a moved count or token, since the refresh workflow regenerates them from `main` and opens one pull request, and `bun run check` runs the script with `--check`, which fills every template into a temp folder and fails when the regeneration cannot run.
22
22
 
23
- The `hero` template takes catalog data, so a stack gaining a rule moves the frame on the next run. `install.html` is the exception, since it holds terminal text from a real run in its template rather than derived from a live catalog at build time. `assets/evidence/arrival.png` is the one image with no source here: it is the built page's `.fold` element captured in dark mode against a local `web/` preview, since `canon capture` takes no color scheme and the page follows the browser's default of light, so it is retaken by hand when the page's first screen changes.
23
+ The `hero` template takes catalog data, so a stack gaining a rule moves the frame on the next run. `install.html` is the exception, since it holds terminal text from a real run in its template rather than derived from a live catalog at build time. `assets/frames/arrival.png` is the one image with no source here: it is the built page's `.fold` element captured in dark mode against a local `web/` preview, since `canon capture` takes no color scheme and the page follows the browser's default of light, so it is retaken by hand when the page's first screen changes.
24
24
 
25
25
  The README shows each still in two themes through `<picture>`, so a frame is a pair named `<name>` and `<name>-light`. `install` takes the light half from its template, which `regen-hero.ts` fills a second time with the plain color roles pointed at the light ones, and each half is its own capture set with its own stamp. `arrival-light.png` is the same `.fold` capture of the same address taken without forcing dark, so it is retaken by hand alongside `arrival.png`, and nothing catches one drifting from the other.
26
26
 
@@ -28,7 +28,7 @@ A stamp for a URL source digests the address string rather than the page it serv
28
28
 
29
29
  `assets/captures/` is read flat and never descends, by the regeneration script and by this command alike. A source nested a further folder down is skipped by both with nothing reported, so a new frame is a template dropped directly in rather than a folder of its own. The split is what retired the name prefix the flat layout used to need: a frame is named for itself now, since `assets/captures/` no longer mixes markup in with the images.
30
30
 
31
- A branch is not asked whether the HTML is current. The PNG is a chromium render whose bytes move with the browser version, so the refresh workflow rebuilds it with `canon capture assets/captures --selector .window --out assets/evidence` only when the regenerated HTML changed.
31
+ A branch is not asked whether the HTML is current. The PNG is a chromium render whose bytes move with the browser version, so the refresh workflow rebuilds it with `canon capture assets/captures --selector .window --out assets/frames` only when the regenerated HTML changed.
32
32
 
33
33
  Every render writes a stamp beside its PNG, `hero.png` next to `hero.stamp`, holding the source filename, a `source-sha256` over the markup bytes it read, and an `image-sha256` over the image bytes it wrote. Both digests are what `bun run check` compares, so a markup edit committed without a capture and a PNG swapped under unchanged markup each fail. The stamp is tracked and commits alongside the pair. A capture that cannot write it reports that source as failed and exits 1, so an image whose stamp never landed is reported rather than passed over.
34
34
 
@@ -91,12 +91,12 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
91
91
  - `wiki`, in `scripting.md`: `init`
92
92
  - `indexes`, in `indexes.md`: `regen`, `list`
93
93
  - `docs`, in `docs.md`: `list`, `<topic>`
94
- - `design`, in `install-and-sync.md` for `install` and `sync`, and described below for the rest: `render`, `regen`, `css`, `install`, `sync`
94
+ - `design`, in `install-and-sync.md` for `install`, `sync`, and `fonts`, and below for the rest: `render`, `regen`, `css`, `install`, `sync`, `fonts`
95
95
  - `slides`, described below: `render`, `list`
96
96
  - `demo`, in `demo.md`: `compile`, `run`, `frames`
97
97
  - `inventory`, described above: `run`
98
98
  - `teach`, in `teach.md`: `list`, `open`, `resource`, `glossary`, `lesson`, `stylesheet`, `nav`, `render`
99
- - `canvas`, described below: `serve`, `list`, `page add`, `page rename`, `frame add`, `frame move`, `selection`, `edit`, `capture`
99
+ - `canvas`, described below: `serve`, `list`, `page add`, `page rename`, `frame add`, `frame move`, `frame resize`, `selection`, `edit`, `editing`, `capture`
100
100
  - `sandbox`, in `sandbox.md`: `reset`, `clean`, `check`, `coverage`
101
101
  - `tasks`, in `tasks.md`: `next-label`, `archive`, `decline`, `plan-citations`, `plan-answers`, `plan-branch`, `plan-reach`, `plan-link`, `pull-request`, `outcome`, `list`, `validate`
102
102
  - `intake`, in `intake.md`: `list`, `answer`
@@ -86,4 +86,6 @@ One code for a failure, which is what a `bun run` caller and a git hook both rea
86
86
 
87
87
  A failing stage carries its remedy in `failure`, and the same line goes to stderr so a caller reading neither the record nor the frame is still told what to fix.
88
88
 
89
- `ms` carries the wall time each stage's checks took, including every process spawn, and the top-level `ms` sums them. Neither reading changes what a stage measures. Both exist so a slow run is attributable to a stage rather than read off a stopwatch held against the whole thing.
89
+ `ms` carries the wall time each stage took, including every process spawn, and the top-level `ms` sums them. Neither reading changes what a stage measures. Both exist so a slow run is attributable to a stage rather than read off a stopwatch held against the whole thing.
90
+
91
+ The Tests stage holds a machine lock so one box runs one suite at a time, and its `ms` includes any time it queued behind another worktree's suite. A stage that queued carries `queuedMs`, the part of `ms` spent waiting, which is how to separate a queue from a slow suite. The field is absent on a stage that never waited. The wait is also announced on stderr when it starts, naming the holder's pid and worktree, in every mode.