@erclx/canon 5.53.0 → 5.55.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 (127) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +10 -9
  3. package/claude/.claude-plugin/plugin.json +1 -1
  4. package/claude/skills/canon-cli/SKILL.md +5 -5
  5. package/claude/skills/create-skill/SKILL.md +1 -1
  6. package/claude/skills/design-identity/REQUIREMENT.md +2 -2
  7. package/claude/skills/design-identity/SKILL.md +6 -6
  8. package/claude/skills/design-record/REQUIREMENT.md +2 -2
  9. package/claude/skills/design-record/SKILL.md +4 -4
  10. package/claude/skills/design-record/references/folder.md +1 -1
  11. package/claude/skills/design-taste/REQUIREMENT.md +1 -1
  12. package/claude/skills/document-health/SKILL.md +6 -6
  13. package/claude/skills/document-repair/SKILL.md +5 -5
  14. package/claude/skills/draw-figure/REQUIREMENT.md +1 -1
  15. package/claude/skills/draw-figure/SKILL.md +1 -1
  16. package/claude/skills/pick-by-eye/REQUIREMENT.md +4 -4
  17. package/claude/skills/pick-by-eye/SKILL.md +34 -41
  18. package/claude/skills/pick-by-eye/references/board.md +42 -0
  19. package/claude/skills/pick-by-eye/references/live-arms.md +3 -3
  20. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  21. package/claude/skills/target-check/SKILL.md +6 -8
  22. package/claude/skills/target-check/references/domains.md +1 -4
  23. package/claude/skills/target-setup/SKILL.md +8 -8
  24. package/claude/skills/target-update/SKILL.md +5 -5
  25. package/claude/skills/teach-craft/REQUIREMENT.md +1 -1
  26. package/claude/skills/teach-craft/SKILL.md +32 -1
  27. package/claude/skills/teach-craft/references/adopted.md +113 -0
  28. package/claude/skills/teach-craft/references/lesson-craft.md +10 -2
  29. package/claude/skills/teach-craft/references/pedagogy.md +29 -2
  30. package/docs/agents/install-and-sync.md +2 -10
  31. package/docs/agents/output-shape.md +11 -10
  32. package/docs/target/migrations.md +8 -3
  33. package/docs/target/projects.md +1 -1
  34. package/docs/target/sync.md +1 -1
  35. package/docs/workflow/skill-map.md +0 -1
  36. package/docs/workflow/visual-design-workflow.md +1 -4
  37. package/governance/detect.toml +1 -6
  38. package/governance/renames.toml +0 -1
  39. package/package.json +2 -5
  40. package/scripts/core/install-check.sh +1 -1
  41. package/scripts/lib/ui.sh +12 -65
  42. package/src/audits/run.ts +1 -1
  43. package/src/claude/cases/misc.ts +0 -5
  44. package/src/claude/routing.ts +1 -1
  45. package/src/claude/skills-audit.ts +1 -0
  46. package/src/cli/help.ts +0 -3
  47. package/src/cli/run.ts +5 -6
  48. package/src/cli/ui.ts +87 -28
  49. package/src/cli.ts +6 -2
  50. package/src/commands/claude.ts +2 -3
  51. package/src/commands/design.ts +20 -324
  52. package/src/commands/gate.ts +5 -3
  53. package/src/commands/gov.ts +11 -21
  54. package/src/commands/labels.ts +1 -1
  55. package/src/commands/pr.ts +1 -1
  56. package/src/commands/sync.ts +5 -6
  57. package/src/commands/tooling.ts +5 -8
  58. package/src/commands/transcripts.ts +6 -11
  59. package/src/design/regen.ts +5 -32
  60. package/src/design/render.ts +1 -1
  61. package/src/design/tokens.ts +3 -2
  62. package/src/gate/sequencer.ts +1 -1
  63. package/src/gate/stages.ts +4 -20
  64. package/src/gov/audit.ts +1 -6
  65. package/src/hooks/post-merge.ts +2 -5
  66. package/src/markdown/scope.ts +2 -4
  67. package/src/process/harness.ts +3 -4
  68. package/src/sandbox/equivalence.ts +0 -1
  69. package/src/sandbox/provision.ts +8 -13
  70. package/src/sandbox/scenario.ts +6 -12
  71. package/src/shipped/references.ts +1 -2
  72. package/src/sync/check.ts +4 -29
  73. package/src/sync/engine.ts +3 -8
  74. package/src/sync/stamp.ts +6 -6
  75. package/src/sync/target.ts +1 -4
  76. package/src/sync/workflow.ts +3 -5
  77. package/src/tooling/verify-stack.ts +1 -1
  78. package/tooling/base/configs/.husky/post-merge +6 -10
  79. package/tooling/claude/reference.md +1 -1
  80. package/tooling/claude/seeds/canon/DESIGN.md +1 -1
  81. package/claude/skills/canvas-board/REQUIREMENT.md +0 -35
  82. package/claude/skills/canvas-board/SKILL.md +0 -143
  83. package/claude/skills/canvas-board/references/canvas.md +0 -170
  84. package/governance/rules/ui/canvas.md +0 -13
  85. package/scripts/core/check-color-source.sh +0 -51
  86. package/src/canvas/address.ts +0 -227
  87. package/src/canvas/arrange.ts +0 -66
  88. package/src/canvas/capture.ts +0 -391
  89. package/src/canvas/client/app.tsx +0 -188
  90. package/src/canvas/client/inspector/align-grid.tsx +0 -162
  91. package/src/canvas/client/inspector/color-field.tsx +0 -398
  92. package/src/canvas/client/inspector/color-inputs.tsx +0 -139
  93. package/src/canvas/client/inspector/color-picker.tsx +0 -668
  94. package/src/canvas/client/inspector/color-space.ts +0 -240
  95. package/src/canvas/client/inspector/field.tsx +0 -263
  96. package/src/canvas/client/inspector/fields.css +0 -763
  97. package/src/canvas/client/inspector/section.tsx +0 -27
  98. package/src/canvas/client/inspector/size-field.tsx +0 -69
  99. package/src/canvas/client/inspector/token-select.tsx +0 -109
  100. package/src/canvas/client/inspector/values.ts +0 -297
  101. package/src/canvas/client/inspector.tsx +0 -692
  102. package/src/canvas/client/keys.ts +0 -71
  103. package/src/canvas/client/layers.tsx +0 -118
  104. package/src/canvas/client/main.tsx +0 -71
  105. package/src/canvas/client/pages-panel.tsx +0 -212
  106. package/src/canvas/client/panel-handle.tsx +0 -90
  107. package/src/canvas/client/selection.tsx +0 -199
  108. package/src/canvas/client/shell.css +0 -762
  109. package/src/canvas/client/state.ts +0 -792
  110. package/src/canvas/client/surface.tsx +0 -803
  111. package/src/canvas/client/theme-panel.tsx +0 -55
  112. package/src/canvas/client/tools.tsx +0 -153
  113. package/src/canvas/content.ts +0 -781
  114. package/src/canvas/edit.ts +0 -575
  115. package/src/canvas/editing.ts +0 -203
  116. package/src/canvas/fit.ts +0 -238
  117. package/src/canvas/global.d.ts +0 -15
  118. package/src/canvas/history.ts +0 -116
  119. package/src/canvas/index.html +0 -20
  120. package/src/canvas/server.ts +0 -766
  121. package/src/canvas/tokens.ts +0 -221
  122. package/src/commands/canvas.ts +0 -1097
  123. package/src/design/adapter.ts +0 -59
  124. package/src/design/base.css +0 -203
  125. package/src/design/brand-favicon.ts +0 -18
  126. package/src/design/neutral.ts +0 -127
  127. package/src/design/project-fonts.ts +0 -392
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.55.0](https://github.com/erclx/canon/compare/v5.54.0...v5.55.0) (2026-10-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * **cli:** decide headless from a missing terminal on stdin ([#2600](https://github.com/erclx/canon/issues/2600)) ([63e9af6](https://github.com/erclx/canon/commit/63e9af6fcd2b23c1aa4abe45e0fb818519b0e314))
9
+ * **cli:** quiet stderr on --json runs and drop the frame off a terminal ([#2599](https://github.com/erclx/canon/issues/2599)) ([824861b](https://github.com/erclx/canon/commit/824861b55ce9a1c92227b3b8c96f541684d2da8b))
10
+
11
+ ## [5.54.0](https://github.com/erclx/canon/compare/v5.53.0...v5.54.0) (2026-10-21)
12
+
13
+
14
+ ### Features
15
+
16
+ * **canvas:** move the design board to Frameboard and retire the canvas ([#2593](https://github.com/erclx/canon/issues/2593)) ([19e0d4f](https://github.com/erclx/canon/commit/19e0d4f4c0022f02bdc94253a743ef757ec44bcc))
17
+ * **ci:** prove canon on macOS with the stock bash ([#2591](https://github.com/erclx/canon/issues/2591)) ([0220169](https://github.com/erclx/canon/commit/0220169cf6f10fb45ff07ffba7fb58a708ade5e2))
18
+ * **design:** retire the canvas-only design verbs and sync domain ([#2598](https://github.com/erclx/canon/issues/2598)) ([ed15567](https://github.com/erclx/canon/commit/ed1556768df49a015b8c9a921df41382e2d19e89))
19
+ * **skills:** give teach-craft a cited source ledger ([#2592](https://github.com/erclx/canon/issues/2592)) ([d67d18c](https://github.com/erclx/canon/commit/d67d18ccf6de3a04963fc20c0ff0624ea7b479f4))
20
+
3
21
  ## [5.53.0](https://github.com/erclx/canon/compare/v5.52.0...v5.53.0) (2026-10-21)
4
22
 
5
23
 
package/README.md CHANGED
@@ -66,15 +66,16 @@ Each domain has a canonical source in this repo and a thin install or sync CLI o
66
66
 
67
67
  ### Domain catalog
68
68
 
69
- | Domain | What it is | How it reaches you |
70
- | -------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
71
- | Plugin skills | Skills that plan a feature, review a diff, sync the planning docs, and run the ship chain | Loaded live from the plugin, never copied |
72
- | Governance | Coding and authoring rules that load into a Claude session when a matching path is edited | Installed per project by `canon gov install`, refreshed by sync |
73
- | Tooling stacks | Golden configs, seeds, and a reference per framework | Laid down by `canon init`, reconciled by `canon tooling sync` |
74
- | Design system | Ships a `DESIGN.md` intent format pointing at your stylesheet for values, a skill that drafts one, and a render command | `canon design render` |
75
- | Canvas | Pages of HTML frames on a local pan and zoom surface, each frame drawn with the project's tokens | `canon canvas serve` |
76
- | Transcripts | A YouTube transcript with metadata frontmatter | `canon transcripts <url>` writes it into any repo |
77
- | Sandbox | Scenario scaffolds that provision an isolated project state for verifying each domain flow | `canon sandbox` |
69
+ | Domain | What it is | How it reaches you |
70
+ | -------------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
71
+ | Plugin skills | Skills that plan a feature, review a diff, sync the planning docs, and run the ship chain | Loaded live from the plugin, never copied |
72
+ | Governance | Coding and authoring rules that load into a Claude session when a matching path is edited | Installed per project by `canon gov install`, refreshed by sync |
73
+ | Tooling stacks | Golden configs, seeds, and a reference per framework | Laid down by `canon init`, reconciled by `canon tooling sync` |
74
+ | Design system | Ships a `DESIGN.md` intent format pointing at your stylesheet for values, and a skill that drafts one | `canon:design-record` drafts it in your repo |
75
+ | Transcripts | A YouTube transcript with metadata frontmatter | `canon transcripts <url>` writes it into any repo |
76
+ | Sandbox | Scenario scaffolds that provision an isolated project state for verifying each domain flow | `canon sandbox` |
77
+
78
+ The design board lives outside canon in [Frameboard](https://www.npmjs.com/package/frameboard), which `canon:pick-by-eye` drives for each round of candidates.
78
79
 
79
80
  ### How domains reach you
80
81
 
@@ -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.53.0",
4
+ "version": "5.55.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: canon-cli
3
- description: Routes a job to the `canon` verb that does it, and warns which verbs can lose a project's edits before one runs. Use when asked "which canon command does X", "is there a verb for X", "which command tells me if X", "will this overwrite my changes", or before running `canon sync`, `canon gov sync`, `canon tooling sync`, `canon design sync`, `canon migrate`, or `canon indexes regen`. Do NOT use to execute a verb, only to pick one and know what it costs.
3
+ description: Routes a job to the `canon` verb that does it, and warns which verbs can lose a project's edits before one runs. Use when asked "which canon command does X", "is there a verb for X", "which command tells me if X", "will this overwrite my changes", or before running `canon sync`, `canon gov sync`, `canon tooling sync`, `canon migrate`, or `canon indexes regen`. Do NOT use to execute a verb, only to pick one and know what it costs.
4
4
  metadata:
5
5
  family: answer
6
6
  ---
@@ -50,7 +50,8 @@ Each verb here has a skill that owns the job. Load the skill rather than driving
50
50
  | Report one computed property across routes | `canon inventory` | `canon:target-check` |
51
51
  | Walk a page through interactions and measure | `canon drive` | `canon:ux-measure` |
52
52
  | Fetch a YouTube transcript | `canon transcripts` | `canon:youtube-transcripts` |
53
- | Work on the local canvas | `canon canvas` | `canon:canvas-board` |
53
+
54
+ The design board is Frameboard, a separate CLI outside canon, so a board job runs a `frameboard` verb rather than a `canon` one.
54
55
 
55
56
  ## Session and ship
56
57
 
@@ -84,11 +85,10 @@ Read the doc each line names before running one of these. `canon docs install-an
84
85
  - `canon gov sync` replaces a rule you edited and deletes a rule the toolkit retired, edited or not.
85
86
  - `canon tooling sync --write` replaces every golden config a stack ships. Seeds are copy-once. Nothing writes without the flag. See `canon docs sync`.
86
87
 
87
- ### Design, migrate, and indexes
88
+ ### Migrate and indexes
88
89
 
89
- Three more verbs rewrite files in place.
90
+ Two more verbs rewrite files in place.
90
91
 
91
- - `canon design sync` replaces the shipped design files and leaves `.claude/design/project/` alone.
92
92
  - `canon migrate --write` rewrites files that cite a retired name or layout. It reports and writes nothing without the flag. See `canon docs migrate`.
93
93
  - `canon indexes regen` rewrites each generated `index.md` from the folder's current state, so a hand edit there is lost. See `canon docs indexes`.
94
94
 
@@ -42,7 +42,7 @@ Read these in the same pass:
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.
45
- - Skip the confirmation when `CANON_NON_INTERACTIVE=1` is set or another skill's run invoked this one, such as `auto-ship` or a dispatched worker.
45
+ - Skip the confirmation when another skill's run invoked this one, such as `auto-ship`, or when a dispatched worker runs it.
46
46
  - Then put the three Step 1 answers and the two drafted paths in the output and continue to Step 5, since a question nobody reads parks the chain.
47
47
 
48
48
  ### Write and check
@@ -23,12 +23,12 @@ A session building this alone restates the render-and-pick loop from scratch, wh
23
23
 
24
24
  - Draft a mark the operator did not ask for, or mutate an existing logo file, which is a plain edit
25
25
  - Add a logo section to the design document's fixed section set, which its parser reads as a fixed key set
26
- - Modify `pick-by-eye`, `canon capture`, or `canon design render`, which this skill composes
26
+ - Modify `pick-by-eye` or `canon capture`, which this skill composes
27
27
  - Be taken as reached by more than an operator typing its name, which a later review reads back rather than assumes
28
28
 
29
29
  ## Out of scope
30
30
 
31
31
  - The render, hand-off, pick, and loop mechanics, which `pick-by-eye` owns
32
- - Carrying a picked direction into the design document, which `canvas-board` owns
32
+ - Carrying a picked direction into the design document, which `design-record` owns
33
33
  - Auditing an implemented UI against its tokens, which `ux-audit` owns
34
34
  - Wiring the produced files into the project's head or manifest, which the operator owns
@@ -62,15 +62,15 @@ Announce which tier decided, naming the tier rather than the path alone, so the
62
62
 
63
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
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
65
+ - Draft each arm inside the 1200x630 card frame, mark and type together, and add it with `frameboard frame add <page>/arm-<id> --width 1200 --height 630`, so one pick settles shape and composition
66
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
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
68
 
69
69
  ## Step 5: draft, render, pick, and loop
70
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.
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 Frameboard page, render and hand off, take the pick, and loop on it.
72
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.
73
+ The final icon and card renders below are not arms, so they stay off the board. 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
74
 
75
75
  ## Step 6: finalize the mark and the icons
76
76
 
@@ -110,9 +110,9 @@ canon capture <dest>/render/og-image.html --selector .render --out <write-folder
110
110
 
111
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
112
 
113
- ### Closing the scratch folder and the canvas
113
+ ### Closing the scratch folder and the board
114
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.
115
+ Delete `<dest>` once both captures land, then close the board 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
116
 
117
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
118
 
@@ -133,6 +133,6 @@ Card source: <the route, captured through the card server|a scratch page, since
133
133
  Cite these rather than restating them.
134
134
 
135
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.
136
+ - `canon:design-record` carries a picked direction into `canon/DESIGN.md`. This skill only reads it.
137
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
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.
@@ -24,10 +24,10 @@ Each project invents its own grouping, and its index restates the file tree rath
24
24
  - Write, copy, or delete a reference file by hand, or capture frames in place of a missing sync
25
25
  - Land a candidate the operator has not picked
26
26
  - Restate when a pick lands against the build, which the design-reference rule states
27
- - Be reached only by the author typing its name, since a pick from the picking or canvas skill should hand off to it
27
+ - Be reached only by the author typing its name, since a pick from `pick-by-eye` should hand off to it
28
28
 
29
29
  ## Out of scope
30
30
 
31
31
  - Drafting candidates and taking the pick, which `pick-by-eye` owns
32
- - Drawing, selecting, and capturing frames on the canvas, which `canvas-board` owns
32
+ - Drawing, selecting, and capturing frames on a board, which Frameboard owns
33
33
  - Judging whether a design is good, which `design-taste` owns
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: design-record
3
- description: Keeps the project's design record, being the design document at `canon/DESIGN.md` and the reference folder at `canon/design/` holding the accepted frames a build matches. Sets the folder up, lands a picked design through the project's design sync, keeps the index, redraws or retires a reference when its surface changes, and carries a pick's values into the stylesheet and its intent into the design document. Use whenever a picked frame or design moves into `canon/design/` or `canon/DESIGN.md`, before running the project's design sync or editing the index, including when asked to "land it in the design references", "add a design reference", "land this pick", "set up canon/design", "update the design index", "redraw the reference for X", "remove the reference for X", or "update DESIGN.md". Do NOT use to draft candidates or take a pick, which is `pick-by-eye`, to draw frames on the canvas, which is `canvas-board`, or to judge a design, which is `design-taste`.
3
+ description: Keeps the project's design record, being the design document at `canon/DESIGN.md` and the reference folder at `canon/design/` holding the accepted frames a build matches. Sets the folder up, lands a picked design through the project's design sync, keeps the index, redraws or retires a reference when its surface changes, and carries a pick's values into the stylesheet and its intent into the design document. Use whenever a picked frame or design moves into `canon/design/` or `canon/DESIGN.md`, before running the project's design sync or editing the index, including when asked to "land it in the design references", "add a design reference", "land this pick", "set up canon/design", "update the design index", "redraw the reference for X", "remove the reference for X", or "update DESIGN.md". Do NOT use to draft candidates or take a pick, which is `pick-by-eye`, to draw frames on a board, which is Frameboard, or to judge a design, which is `design-taste`.
4
4
  metadata:
5
5
  family: ship
6
6
  ---
@@ -19,7 +19,7 @@ The document holds the rules and each role's intent, and the folder holds the pi
19
19
  ## Guards
20
20
 
21
21
  - Write no reference file by hand, whether a copy, an edit, or a delete. The project's design sync writes the frames, so a hand-written file drifts from the frame it claims to show.
22
- - Never land a candidate the operator has not picked. The folder holds accepted designs, and a draft lives on the canvas.
22
+ - Never land a candidate the operator has not picked. The folder holds accepted designs, and a draft lives on the board.
23
23
 
24
24
  ## Step 1: read the record
25
25
 
@@ -66,10 +66,10 @@ Retire a reference in the change that removes its surface from the app.
66
66
  A pick that settles color, type, spacing, or radius changes the design document as well as the folder. Skip this step when the pick changed layout or structure alone, since the reference carries that.
67
67
 
68
68
  - Carry each value into the stylesheet the document's lead names, and its intent into the document's sections under `design.md`
69
- - A project with no stylesheet yet takes the values under `.claude/design/project/` after `canon design install`, and the lead names that path
69
+ - A project with no stylesheet yet writes one of its own for the values, and the lead names its path
70
70
  - A values record names in its lead the module it renders from and the command that renders it. Edit that module and run that command, never the document.
71
71
 
72
- Never cite a canvas frame path from the document or the index. The canvas folder is gitignored, so the citation resolves on one machine alone.
72
+ Never cite a board frame path from the document or the index. The board folder is gitignored, so the citation resolves on one machine alone.
73
73
 
74
74
  ## Output
75
75
 
@@ -15,7 +15,7 @@ Does not govern:
15
15
 
16
16
  - The design document at `canon/DESIGN.md`, which `design.md` beside this file governs
17
17
  - When a pick lands and how a build is held to a reference, which the design-reference governance rule states
18
- - The canvas content format a frame is drawn in, which the canvas standard owns
18
+ - The content format a frame is drawn in, which Frameboard owns and `frameboard docs --json` prints
19
19
 
20
20
  ## What a working folder looks like
21
21
 
@@ -31,5 +31,5 @@ The output has no standard of quality either. A model with no stated direction d
31
31
 
32
32
  - Accessibility, keyboard interaction, state coverage, forms, and rendered copy, which the `a11y`, `keyboard`, `ux-completeness`, `forms`, and `copy` rules own
33
33
  - The candidate loop and the pick, which `pick-by-eye` owns
34
- - The shape of the project's design document, which `canvas-board`'s design reference governs
34
+ - The shape of the project's design document, which `design-record`'s design reference governs
35
35
  - Prose on the surface being designed, which `write-human` and `markdown-craft` own
@@ -15,7 +15,7 @@ Three axes carry the report. Two answer from a verb and the third answers from a
15
15
 
16
16
  - `canon` absent from the path: stop. `❌ canon is not on PATH, so neither measured axis can be read.`
17
17
  - `git ls-files '*.md'` listing nothing: stop. `❌ No tracked markdown here, so there is no corpus to read.`
18
- - Run every command under `CANON_NON_INTERACTIVE=1` and prompt at no point. A caller reaching this from a rollout wave has nobody present to answer.
18
+ - Prompt at no point, since a caller reaching this from a rollout wave has nobody present to answer. A call with no terminal on stdin already runs headless, so no command takes a prefix.
19
19
  - Branch on each record's own fields rather than on an exit status, since a shell profile may wrap `canon` in a function whose trailing command reports every refusal as success
20
20
  - Repair nothing, write no file in the project, and open no pull request. Whoever read the report decides what to fix.
21
21
 
@@ -30,8 +30,8 @@ Drop what nobody hand-authors before reporting a finding against it: a generated
30
30
  Run these from the project root, in parallel:
31
31
 
32
32
  ```bash
33
- CANON_NON_INTERACTIVE=1 canon markdown audit --json
34
- CANON_NON_INTERACTIVE=1 canon context audit --json
33
+ canon markdown audit --json
34
+ canon context audit --json
35
35
  ```
36
36
 
37
37
  The first answers length, carrying the bullet, paragraph, and depth checkpoints and the per-file weights read against them. The second answers placement for the folders it resolves, carrying entry length, reference form, and index drift.
@@ -39,8 +39,8 @@ The first answers length, carrying the bullet, paragraph, and depth checkpoints
39
39
  Then read which classifier would run, and deepen placement with the verdicts per section:
40
40
 
41
41
  ```bash
42
- CANON_NON_INTERACTIVE=1 canon context classifier show
43
- CANON_NON_INTERACTIVE=1 canon context classify sweep --json
42
+ canon context classifier show
43
+ canon context classify sweep --json
44
44
  ```
45
45
 
46
46
  The first names the backend, the model, and the source that decided both. Report which layer answered, since a project with the model layer off reads from the regex layer alone and the sweep says nothing about which one it used.
@@ -65,7 +65,7 @@ Mark every staleness finding as a reading. It is this session's judgment rather
65
65
  When the scope reaches `canon/REQUIREMENTS.md`, read it for identity drift as well as for stale paths, and take the review point from the verb:
66
66
 
67
67
  ```bash
68
- CANON_NON_INTERACTIVE=1 canon records stale canonical --json
68
+ canon records stale canonical --json
69
69
  ```
70
70
 
71
71
  The doc in the record carries `reviewed` and `releasesSince`. `${CLAUDE_SKILL_DIR}/references/axes.md` holds the identity claim shapes to test and how the record reads. Skip both the read and the verb when the scope excludes the doc.
@@ -16,14 +16,14 @@ The CLI holds every number. `canon markdown audit` measures, and `canon markdown
16
16
  - `canon` absent from the path: stop. `❌ canon is not on PATH, so nothing can be measured or gated.`
17
17
  - The audit refusing: stop and name its `reason`. A `malformed-config` refusal names the file to fix by hand, since the verb will not append to a file it cannot read.
18
18
  - `gated add` refusing with `canon-checkout`: stop. Canon's own checkout gates through a constant in its source, which a code change edits.
19
- - Run every command under `CANON_NON_INTERACTIVE=1`, and branch on each record's own fields rather than on an exit status a shell wrapper can flatten
19
+ - Branch on each record's own fields rather than on an exit status a shell wrapper can flatten. A call with no terminal on stdin already runs headless, so no command takes a prefix.
20
20
 
21
21
  ## Step 1: read the audit
22
22
 
23
23
  Run the audit over the whole tree and take the density and reference shape findings from its record:
24
24
 
25
25
  ```bash
26
- CANON_NON_INTERACTIVE=1 canon markdown audit --json
26
+ canon markdown audit --json
27
27
  ```
28
28
 
29
29
  Take the candidate folders from the order table in `${CLAUDE_SKILL_DIR}/references/batches.md` rather than from the findings, since a clean folder carries no finding and would never be gated. Drop every folder `canon/config/markdown.toml` already lists, since a listed folder already gates.
@@ -41,7 +41,7 @@ Load `markdown-craft` and `write-human`, then rewrite each failing block by its
41
41
  Re-run the audit on the folder alone after each file:
42
42
 
43
43
  ```bash
44
- CANON_NON_INTERACTIVE=1 canon markdown audit <prefix> --json
44
+ canon markdown audit <prefix> --json
45
45
  ```
46
46
 
47
47
  Read `${CLAUDE_SKILL_DIR}/references/batches.md` for what a rewrite may cut. A stated reason survives every rewrite, and the audit reaching zero cannot see one that went missing.
@@ -49,7 +49,7 @@ Read `${CLAUDE_SKILL_DIR}/references/batches.md` for what a rewrite may cut. A s
49
49
  ## Step 4: gate the folder
50
50
 
51
51
  ```bash
52
- CANON_NON_INTERACTIVE=1 canon markdown gated add <prefix> --json
52
+ canon markdown gated add <prefix> --json
53
53
  ```
54
54
 
55
55
  Pass the prefix exactly as the batch named it: a folder with its one trailing slash, such as `docs/`, and a file by its bare path, such as `README.md`. The verb refuses a doubled slash and a slash after a file, since either matches nothing and would gate nothing.
@@ -61,7 +61,7 @@ Branch on the record. `action: appended` or `present` means the folder gates now
61
61
  A skill's `REQUIREMENT.md` gates only on its own path, never through a folder prefix, so gating `.claude/skills/` leaves each requirement reporting. Gate each one that reaches zero by its path:
62
62
 
63
63
  ```bash
64
- CANON_NON_INTERACTIVE=1 canon markdown gated add .claude/skills/<name>/REQUIREMENT.md --json
64
+ canon markdown gated add .claude/skills/<name>/REQUIREMENT.md --json
65
65
  ```
66
66
 
67
67
  ## Output
@@ -30,5 +30,5 @@ Asked to refresh one architecture view, it redraws every view beside it. It judg
30
30
  ## Out of scope
31
31
 
32
32
  - Mermaid's layout, budgets, and label rules inside the fence, which the mermaid standard owns
33
- - A UI screen mockup, and design tokens or the visual system, which `canvas-board` owns
33
+ - A UI screen mockup, which belongs on a Frameboard board, and design tokens or the visual system, which `design-record` owns
34
34
  - Implementation detail behind an architecture view, which the context entry the caption points at owns
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: draw-figure
3
- description: Drafts one hand-drawn figure for a document, deciding whether the subject is Mermaid-shaped, an architecture view, or needs freehand SVG, then draws it. Renders the Mermaid path through Mermaid's own hand-drawn look, reads the render back, and fixes what it exposes. Wraps every path in the figure standard's caption, color, and accessibility rules. Use when asked to "draw a figure", "add a hand-drawn diagram", "draft a figure for this doc", "draw this relationship as a figure", "draw the architecture", "diagram the system", or "show the components". Do NOT use for a UI screen mockup, which is `canvas-board`.
3
+ description: Drafts one hand-drawn figure for a document, deciding whether the subject is Mermaid-shaped, an architecture view, or needs freehand SVG, then draws it. Renders the Mermaid path through Mermaid's own hand-drawn look, reads the render back, and fixes what it exposes. Wraps every path in the figure standard's caption, color, and accessibility rules. Use when asked to "draw a figure", "add a hand-drawn diagram", "draft a figure for this doc", "draw this relationship as a figure", "draw the architecture", "diagram the system", or "show the components". Do NOT use for a UI screen mockup, which belongs on a Frameboard board.
4
4
  metadata:
5
5
  family: generate
6
6
  ---
@@ -14,8 +14,8 @@ The evidence fails as well. Arms get reported without being rendered or judged,
14
14
  ## Must
15
15
 
16
16
  - Three to five arms, the shipping state among them, each carry an id, a label, and a cost, and vary only at a layer named from the `design-taste` catalog
17
- - Each round is one canvas page of frames at their judged widths, themed by the canvas toggle and captured once as a composite, with the link ahead of the first pick question
18
- - Every arm is rendered and judged against a stated bar before handover, and a missing browser or a canvas that will not start is reported as a refusal
17
+ - Each round is one Frameboard page of frames at their judged widths, themed by the board toggle and captured once as a composite, with the link ahead of the first pick question
18
+ - Every arm is rendered and judged against a stated bar before handover, and a missing browser or a board that will not start is reported as a refusal
19
19
  - The pick comes through the structured question surface with the recommendation first and every option's cost, and the winner lands in one change
20
20
  - Every round stays openable on its own page until the pick, and the picked round's arms are captured into the citing record at the main root before the run's pages go
21
21
 
@@ -24,8 +24,8 @@ The evidence fails as well. Arms get reported without being rendered or judged,
24
24
  - Take the pick where two arms are defensible and the difference is taste
25
25
  - Draft candidates for a decision the operator has not asked to make, or for a request that already names one answer
26
26
  - Write into the real surface before the pick is final
27
- - Restate the mechanics `canon canvas` and `canon drive` own, or read a drive finding as a gate over the arms
28
- - Delete a canvas page or stop a server the run did not start
27
+ - Restate the mechanics Frameboard and `canon drive` own, or read a drive finding as a gate over the arms
28
+ - Delete a board page or stop a server the run did not start, or remove a page by any route but a `frameboard` verb
29
29
 
30
30
  ## Out of scope
31
31
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pick-by-eye
3
- description: Drafts several candidates for a decision judged by looking, lays them out side by side as frames on one canvas page, hands the operator the address, takes the pick through the structured question surface, and loops on the pick until they stop. Use when asked to "draft some options", "show me a few versions", "try a few variations", "mock up alternatives", "give me candidates for X", or when a choice is taste rather than correctness. Do NOT use when the request already names the answer and asks for it to be built, which is `plan-feature`. Do NOT use to read source for roughness, which is `ux-audit`, to measure what a running interface costs to paint, which is `ux-measure`, or to write what to look at on a change already made, which is `ui-checklist`.
3
+ description: Drafts several candidates for a decision judged by looking, lays them out side by side as frames on one Frameboard page, hands the operator the address, takes the pick through the structured question surface, and loops on the pick until they stop. Use when asked to "draft some options", "show me a few versions", "try a few variations", "mock up alternatives", "give me candidates for X", or when a choice is taste rather than correctness. Do NOT use when the request already names the answer and asks for it to be built, which is `plan-feature`. Do NOT use to read source for roughness, which is `ux-audit`, to measure what a running interface costs to paint, which is `ux-measure`, or to write what to look at on a change already made, which is `ui-checklist`.
4
4
  metadata:
5
5
  family: decide
6
6
  ---
@@ -9,13 +9,14 @@ metadata:
9
9
 
10
10
  Some decisions are settled by looking rather than by reasoning, and no draft is wrong until one is picked. Every step here puts several candidates in front of the operator and keeps the real surface untouched until they have chosen.
11
11
 
12
- The candidates live on the local design canvas, the surface `canon:canvas-board` drives. Every verb below is `canon canvas`, and `${CLAUDE_SKILL_DIR}/../canvas-board/references/canvas.md` fixes the content format a frame takes. Read that reference before writing the first frame.
12
+ The candidates live on a Frameboard board at `.canon/canvas/`, in a project named `picks` so rounds never mix with an operator's project. Read `${CLAUDE_SKILL_DIR}/references/board.md` before the first `frameboard` verb, for the flags every verb carries and how a selection resolves.
13
13
 
14
14
  ## Guards
15
15
 
16
16
  - If the request names one answer and asks for it to be built, stop: `❌ This names one answer, so there is nothing to pick between. Use /canon:plan-feature.`
17
17
  - If the decision has no visible form, stop: `❌ Nothing to look at. Drafting candidates needs a decision a render can show.`
18
18
  - Draft no candidate for a decision the operator has not asked to make, since options everywhere spend their attention rather than saving it
19
+ - If neither `frameboard` nor `bunx` is on PATH, stop: `❌ Frameboard not found. Install frameboard or bun and re-run.`
19
20
 
20
21
  ## Step 1: name the decision and the arms
21
22
 
@@ -28,26 +29,24 @@ The candidates live on the local design canvas, the surface `canon:canvas-board`
28
29
 
29
30
  Inside a live `plan-groundwork` track, renders land in the track's own `evidence/<slug>/renders/`, since a candidate render is evidence its decision file cites. Everywhere else they land in session scratch.
30
31
 
31
- ## Step 2: draft the arms as frames on one canvas page
32
+ ## Step 2: draft the arms as frames on one page
32
33
 
33
- Every arm of a round sits as one frame on one canvas page, side by side. The operator judges that page, never a set of separate images compared from memory.
34
+ Every arm of a round sits as one frame on one board page, side by side. The operator judges that page, never a set of separate images compared from memory.
34
35
 
35
- 1. Start the canvas the way `canon:canvas-board` Step 1 states, unless this run already has. Note whether this run started the server, since Step 6 stops only a server this run started.
36
- 2. Add the round's page with `canon canvas page add <page> --json` and record it on the run's list of pages. A name `canvas list` already shows is somebody else's, so take the next free suffix.
37
- 3. Add each arm with `canon canvas frame add <page> arm-<id> --width <px> --height <px> --json`. Step 6's archive keys on the `arm-<id>` names.
38
- 4. Write each arm's whole document to the `path` the add verb reported. From a linked worktree, take the heredoc route `canon:canvas-board` Step 3 gives for a main-root write.
39
- 5. Lay the frames out in one row, in arm order, with `canon canvas frame move <page> arm-<id> --x <px> --y <px> --json`.
36
+ 1. Start the board the way `references/board.md` states, unless this run already has. Note whether this run started the server, read off `reused`, since Step 6 ends only a server this run started.
37
+ 2. Read `frameboard list --root <board> --json` with no `--project`, so it lists every project. Run `frameboard project add picks --root <board> --json` when it lists no `picks`.
38
+ 3. Add the round's page with `frameboard page add <page>` and record its `ref` on the run's list of pages. A `name-taken` refusal means the name is somebody else's, so take the next free suffix.
39
+ 4. Add each arm with `frameboard frame add <page>/arm-<id> --width <px> --height <px> --x <px> --y <px>`, placing the frames in one row in arm order. Step 6's archive keys on the `arm-<id>` names.
40
+ 5. Write each arm's whole document to the `path` the add verb reported. From a linked worktree, take the heredoc route `session-worktree` gives for a main-root write.
40
41
 
41
- The `canvas-board` start reads `canon canvas list --json`, serves with `canon canvas serve --json` in the background unless the operator named an address that answers, and checks the shell's body holds a `<script` tag. A refused serve or a blank shell stops the run with its `reason`, and no file stands in for a canvas.
42
-
43
- Set each frame's width to the one the arm is judged at. A frame renders at its own layout width on the canvas and in a capture alike, so a layout decision needs no device toolbar.
42
+ Set each frame's width to the one the arm is judged at. A frame renders at its own layout width on the board and in a capture alike, so a layout decision needs no device toolbar.
44
43
 
45
44
  ### What every frame carries
46
45
 
47
- Each frame carries its own label and follows the canvas theme, so the set reads as one comparison.
46
+ Each frame carries its own label and follows the board theme, so the set reads as one comparison.
48
47
 
49
48
  - Label each arm inside its frame with its id and its cost, since the composite capture draws no captions
50
- - Theme every arm off the `data-theme` attribute the canvas sets on each frame's root, so the theme toggle sets the whole set at once. A set spanning both themes cannot be compared.
49
+ - Theme every arm off the `data-theme` attribute the board sets on each frame's root, so the theme toggle sets the whole set at once. A set spanning both themes cannot be compared.
51
50
  - Give no arm a script that stores a theme and reapplies it on load. It overwrites the toggle, and a fresh browser profile hides the fault.
52
51
 
53
52
  ### Default path and live app
@@ -55,8 +54,8 @@ Each frame carries its own label and follows the canvas theme, so the set reads
55
54
  A running app under decision takes the live-app branch, and every other decision takes the default path.
56
55
 
57
56
  - Live app: lift the rendered markup and link a copy of the built stylesheet rather than inlining, per `${CLAUDE_SKILL_DIR}/references/live-arms.md`
58
- - Default path: inline every style, script, and asset. A frame resolves nothing outside its own page folder, so a build step or network font silently drops out.
59
- - Default path: name a real font first in the stack, one the machine has or the frame embeds, such as the project's own family. A generic keyword such as `system-ui` resolves differently per machine.
57
+ - Default path: inline every style, script, and asset. A frame resolves nothing outside its page folder and its project's `assets/`, so a build step or network font silently drops out.
58
+ - Default path: name a real font first in the stack, one the board serves, the machine has, or the frame embeds. A generic keyword such as `system-ui` resolves differently per machine.
60
59
 
61
60
  The capture refuses a frame that would rewrap against a substitute font rather than ship a false comparison. A frame naming no font is refused on whatever the default resolves to.
62
61
 
@@ -73,18 +72,18 @@ Vary one property across the arms, since a pick cannot say which of three differ
73
72
  Render the page and look at what came back before handing anything over:
74
73
 
75
74
  ```bash
76
- canon canvas capture <page> --composite --json
75
+ frameboard capture --page <page> --composite --root <board> --project picks --json
77
76
  ```
78
77
 
79
- - Point `--out` at `evidence/<slug>/renders/<page>.png` inside a live track, and leave the scratch default elsewhere. Step 6 archives the picked round alone.
80
- - Read the PNG's `path` off the record. The composite shows each frame in its default theme, so check the other theme on the live canvas.
81
- - A capture refusing on a font names the family it read. Take the repair `canon:canvas-board` Step 6 gives and capture again.
78
+ - Point `--out` at `evidence/<slug>/renders/` inside a live track, and leave the board's default elsewhere. Step 6 archives the picked round alone.
79
+ - Read each image's `path` off the record's `images`. The composite lands once per theme, so look at both.
80
+ - A `font-missing` refusal names the family it read. Set that text's `font-family` to a named family the board serves or the machine has, never a generic keyword, and capture again.
82
81
 
83
- When `canon canvas capture` refuses for a missing browser binary, report it and name `bunx playwright install chromium` as the repair. Stop the canvas server if this run started it, then stop rather than describe an arm nobody has seen.
82
+ When the capture refuses with `browser-not-found`, report it and name `bunx playwright install chromium` as the repair. End the serve command if this run started it, then stop rather than describe an arm nobody has seen.
84
83
 
85
84
  ### Handing over
86
85
 
87
- Hand over the address rather than a description. Emit the canvas link first on its own line, naming the page, then the PNG path on its own line.
86
+ Hand over the address rather than a description. Emit the board link first on its own line, naming the page, then each PNG path on its own line.
88
87
 
89
88
  - A still answers how a thing looks and none of a hover, a scroll-linked position, or a pace, which the live frame does
90
89
  - Never report a visual result you have not looked at, since a claim about appearance with no render behind it is a guess
@@ -103,14 +102,7 @@ Put the choice to the operator through the structured question surface, since a
103
102
 
104
103
  Take no pick on the operator's behalf when two arms are both defensible and the difference is taste. That call is theirs, and a silent one is the failure this skill exists to prevent.
105
104
 
106
- Read `canon canvas selection --json` when the answer points at the canvas, such as "the selected one". Resolve it against the record's `page` as well as its `frame`, since every round reuses the `arm-<id>` names.
107
-
108
- | Selection | Reading |
109
- | ---------------------------------------------------------------- | ---------------------------------------------- |
110
- | A frame on the current round's page | The pick |
111
- | A frame on an earlier round's page | A revert, so name the round back before acting |
112
- | A fresh element inside a picked frame | A correction Step 5 carries by its `index` |
113
- | `selection: null`, a page this run did not add, or `stale: true` | No answer, so ask again rather than guess |
105
+ Read the selection when the answer points at the board, such as "the selected one". `references/board.md` maps each record to a pick, a revert, a correction, or no answer.
114
106
 
115
107
  ## Step 5: loop on the pick
116
108
 
@@ -118,22 +110,22 @@ Read `canon canvas selection --json` when the answer points at the canvas, such
118
110
  2. Write fresh arms off the pick and return to Step 2 where the correction opens a new question. Revise the one arm's frame where it does not.
119
111
  3. Re-render, hand off again, and take the next answer.
120
112
  4. Repeat until the operator says it is right. A run stopping because the arms stopped differing has stopped early.
121
- 5. Hold the real surface untouched across every iteration. Nothing outside the run's own canvas pages changes until the pick is final.
113
+ 5. Hold the real surface untouched across every iteration. Nothing outside the run's own board pages changes until the pick is final.
122
114
 
123
115
  ## Step 6: close
124
116
 
125
117
  1. Apply the winning arm to the real surface, in one change.
126
118
  2. Close out any document stating the decision as open, in the same change, naming the winner and the arms that stayed defensible. Skip this where nothing stated the decision.
127
- 3. Hand the winning frame to `canon:design-record` by its page and frame, which lands it in the project's design record. Report it rather than proceeding silently when that skill does not resolve.
128
- 4. Capture the picked round's frames with `canon canvas capture <page> --out <archive-dir> --json`. Each lands as `arm-<id>.png`, keeping the losing arms as a revert record.
129
- 5. Resolve `<archive-dir>` as `.canon/picks/<slug>/` against the main worktree root, since shared session scratch resolves there rather than in a linked worktree.
130
- 6. Delete every page folder on the run's list from under the `content` folder `canon canvas list --json` reports. Touch no page the run did not add, whatever its name.
131
- 7. Stop the canvas server if this run started it, and leave one the operator started running.
119
+ 3. Hand the winning frame's ref to `canon:design-record`, which lands it in the project's design record. Report it rather than proceeding silently when that skill does not resolve.
120
+ 4. Capture the picked round's frames with `frameboard capture --page <page> --out <canon-dir>`, keeping the losing arms as a revert record. Report each image's `path` off the record.
121
+ 5. Resolve `<canon-dir>` as `.canon/` against the main worktree root, since shared session scratch resolves there. Frameboard appends the project and page, so the archive lands at `.canon/picks/<page>/`.
122
+ 6. Delete every page on the run's list with `frameboard page delete <page>`. Touch no page the run did not add, whatever its name, and never remove a page folder by hand.
123
+ 7. End the serve command if this run started it, since Frameboard carries no stop verb. Leave a server the operator started running.
132
124
  8. Leave the renders in a live track's `evidence/<slug>/renders/`, since `plan-groundwork` treats evidence as durable.
133
- 9. Report each page whose delete is refused, naming the path for the operator to remove. The pick is applied either way.
125
+ 9. Report each page whose delete is refused, naming its `ref` and the `error.code`. The pick is applied either way.
134
126
  10. Report every surface that changed, each on its own line, name the winning arm by its id and its cost, and report the archive path.
135
127
 
136
- The picked round is the final one unless Step 4 resolved a revert. Archiving any other page lets item 6 delete the winning arm with nothing kept, and a variant left on the canvas is a second design nobody maintains.
128
+ The picked round is the final one unless Step 4 resolved a revert. Archiving any other page lets item 6 delete the winning arm with nothing kept, and a variant left on the board is a second design nobody maintains.
137
129
 
138
130
  ## Reading a measurement
139
131
 
@@ -154,10 +146,11 @@ Cite these rather than restating them. A step reimplemented here rots against th
154
146
  - `design-taste` carries the layer catalog, the ordering, grey-boxing, and the defaults an arm should reach past
155
147
  - `write-human` carries the voice for any copy an arm puts in front of a reader
156
148
 
157
- ### Git and review
149
+ ### Git, review, and the board
158
150
 
159
- Commits, review, and the canvas mechanics each have an owner.
151
+ Commits, review, and the board mechanics each have an owner.
160
152
 
161
153
  - `git-stage`, `git-pr`, and `git-followup` carry the commits and the pull request
162
154
  - `review-pr` and `review-address` run the review pass
163
- - `canon:canvas-board` carries the canvas start-and-check sequence, the main-root write route for a frame, and the selection and capture refusals
155
+ - `session-worktree` carries the main-root write route for a frame written from a linked worktree
156
+ - Frameboard carries the board itself, and `frameboard docs --json` prints its verbs, record shapes, content format, and refusals
@@ -0,0 +1,42 @@
1
+ # The Frameboard board
2
+
3
+ Read before the first `frameboard` verb a `pick-by-eye` run sends. It carries where the board sits, how the verbs are reached, how the server starts, and how a selection resolves to an answer.
4
+
5
+ ## Reaching the board
6
+
7
+ Resolve `<board>` as `.canon/canvas/` against the main worktree root, the way `session-worktree` resolves it, since a linked worktree holds no copy of the gitignored folder.
8
+
9
+ - Pass `--root <board> --project picks --json` to every verb unless the step says otherwise, so no verb relies on the only-project default
10
+ - Where `frameboard` is not on PATH, run every verb as `bunx -y frameboard@0.6 <verb>`. Say so once and keep that form for the run.
11
+ - The pin holds the minor, since record shapes move across a pre-1.0 minor
12
+
13
+ Run `frameboard docs --json` before writing the first frame. Its `contentFormat` fixes what a frame may hold and link, and its `exitCodes` name every refusal a verb can return.
14
+
15
+ ## Starting the board
16
+
17
+ Serve in the background unless the operator named an address that answers, since the server runs until its command ends:
18
+
19
+ ```bash
20
+ frameboard serve --root <board> --no-open --tokens <stylesheet> --json
21
+ ```
22
+
23
+ - Take `<stylesheet>` from the lead of `canon/DESIGN.md`, which names it in a hand-written record
24
+ - A lead naming a module, or no design document at all, means serving without `--tokens`. Say the frames render on the board's own tokens.
25
+ - Read `url` and `reused` off the record rather than composing an address
26
+ - `reused: true` means a server was already up, so this run did not start it and its close leaves it running
27
+ - Report a refusal's `error.code` and stop, since no file stands in for a board
28
+
29
+ ## Reading the selection
30
+
31
+ Read `frameboard selection --root <board> --json` when the operator's answer points at the board, such as "the selected one". Resolve it against the record's `project` and `page` as well as its `frames`, since every round reuses the `arm-<id>` names.
32
+
33
+ | Selection | Reading |
34
+ | ------------------------------------------------------------- | -------------------------------------------------------- |
35
+ | One frame in `frames`, on the current round's page in `picks` | The pick |
36
+ | One frame in `frames`, on an earlier round's page | A revert, so name the round back before acting |
37
+ | An `element` inside a picked frame | A correction the loop carries by its `index` and `hash` |
38
+ | Several entries in `frames` | Ask which one rather than taking the first |
39
+ | Empty `frames`, another project, or a page the run never made | No answer, so ask again rather than guess |
40
+ | `tabs: 0`, or a `server-not-running` refusal | No board is open, so hand the address over and ask again |
41
+
42
+ Pass the element's `hash` to `frameboard edit --hash` with its `index`. A frame rewritten since the operator picked refuses with `stale-address` rather than landing on another element, so ask for the pick again on that refusal.
@@ -5,7 +5,7 @@ Read when the surface under decision is a running app rather than a static mocku
5
5
  ## Lift from the app
6
6
 
7
7
  - Dump the rendered markup of the surface under decision from the built page, after it has loaded, into a scratch file the run reads from. Strip scripts from the dump.
8
- - Copy the built stylesheet and fonts to the canvas page folder at the path each frame links, since a frame resolves only its own page. Each arm then differs from the shipped page only in what it names.
8
+ - Copy the built stylesheet and fonts into the page folder or the project's `assets/`, since a frame resolves nothing else. Each arm then differs from the shipped page only in what it names.
9
9
  - Trim a large dump to the part the decision needs, and keep the wrapper classes intact so layout rules keyed to them still resolve.
10
10
  - Set each frame's `--width` to the content width the decision names rather than the window width, since a container query reads the frame.
11
11
  - Write copy an arm introduces with `write-human`, and take every other word from the dump.
@@ -13,7 +13,7 @@ Read when the surface under decision is a running app rather than a static mocku
13
13
  ## The frames
14
14
 
15
15
  - Generate the frames with a short script, one per round, so a shared change is one edit and a rerun.
16
- - Leave the theme to the canvas toggle, which sets the app's own `data-theme` switch on every frame's root. Name the attribute the stylesheet reads where it differs, as the toggle sets that one alone.
16
+ - Leave the theme to the board toggle, which sets the app's own `data-theme` switch on every frame's root. Name the attribute the stylesheet reads where it differs, as the toggle sets that one alone.
17
17
  - Print each frame's measurement under it from a script in the frame, so the numbers the operator reads are the browser's.
18
18
  - Draw an arm that is a whole page or a route as one frame at that page's width, so it still sits beside the other arms on the round's page.
19
- - Name anything the canvas cannot reproduce, such as an asset whose colors follow the browser rather than the frame's theme, rather than fixing the frame around it.
19
+ - Name anything the board cannot reproduce, such as an asset whose colors follow the browser rather than the frame's theme, rather than fixing the frame around it.