@erclx/canon 5.43.0 → 5.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/backlog-triage/references/apply.md +6 -6
- package/claude/skills/canon-cli/SKILL.md +4 -4
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +1 -1
- package/claude/skills/context-fold/references/context.md +1 -1
- package/claude/skills/create-skill/REQUIREMENT.md +1 -1
- package/claude/skills/create-skill/SKILL.md +2 -2
- package/claude/skills/create-skill/references/skill-requirement.md +68 -9
- package/claude/skills/create-skill/references/skill.md +1 -1
- package/claude/skills/design-identity/REQUIREMENT.md +40 -0
- package/claude/skills/design-identity/SKILL.md +138 -0
- package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
- package/claude/skills/design-taste/REQUIREMENT.md +4 -4
- package/claude/skills/design-taste/SKILL.md +2 -2
- package/claude/skills/design-taste/references/kinds.md +1 -1
- package/claude/skills/design-taste/references/preflight.md +1 -1
- package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
- package/claude/skills/draft-and-pick/SKILL.md +3 -153
- package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
- package/claude/skills/draft-doc/SKILL.md +4 -76
- package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
- package/claude/skills/draft-figure/SKILL.md +3 -77
- package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
- package/claude/skills/draft-identity/SKILL.md +3 -130
- package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
- package/claude/skills/draft-ready/SKILL.md +3 -128
- package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
- package/claude/skills/draft-screencast/SKILL.md +3 -62
- package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
- package/claude/skills/draft-slides/SKILL.md +3 -72
- package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
- package/claude/skills/draw-figure/SKILL.md +85 -0
- package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
- package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
- package/claude/skills/make-deck/REQUIREMENT.md +44 -0
- package/claude/skills/make-deck/SKILL.md +80 -0
- package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
- package/claude/skills/markdown-craft/SKILL.md +2 -2
- package/claude/skills/pick-by-eye/REQUIREMENT.md +86 -0
- package/claude/skills/pick-by-eye/SKILL.md +161 -0
- package/claude/skills/plan-feature/SKILL.md +2 -1
- package/claude/skills/plan-feature/references/plan.md +24 -10
- package/claude/skills/plan-groundwork/SKILL.md +1 -1
- package/claude/skills/plan-intake/SKILL.md +1 -1
- package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
- package/claude/skills/plan-ready/SKILL.md +136 -0
- package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
- package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
- package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
- package/claude/skills/record-screencast/SKILL.md +2 -2
- package/claude/skills/role-orchestrator/REQUIREMENT.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
- package/claude/skills/role-planner/SKILL.md +2 -1
- package/claude/skills/role-worker/SKILL.md +9 -0
- package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
- package/claude/skills/script-screencast/SKILL.md +70 -0
- package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
- package/claude/skills/search-craft/REQUIREMENT.md +4 -4
- package/claude/skills/search-craft/SKILL.md +1 -1
- package/claude/skills/target-setup/SKILL.md +1 -0
- package/claude/skills/task-board/SKILL.md +11 -9
- package/claude/skills/task-board/references/board.md +15 -12
- package/claude/skills/teach-workspace/SKILL.md +1 -1
- package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
- package/claude/skills/ui-checklist/SKILL.md +2 -0
- package/claude/skills/write-doc/REQUIREMENT.md +46 -0
- package/claude/skills/write-doc/SKILL.md +83 -0
- package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
- package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +3 -3
- package/docs/agents/markdown-audit.md +4 -2
- package/docs/agents/migrate.md +2 -2
- package/docs/target/migrations.md +17 -4
- package/docs/target/projects.md +1 -1
- package/docs/workflow/parallel-features.md +3 -2
- package/docs/workflow/skill-map-on-request.md +18 -12
- package/docs/workflow/skill-map.md +13 -12
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/governance/ledger/framework/astro.md +73 -0
- package/governance/ledger/framework/fastapi.md +76 -0
- package/governance/ledger/framework/nextjs.md +86 -0
- package/governance/ledger/framework/react.md +83 -0
- package/governance/ledger/framework/shadcn.md +60 -0
- package/governance/ledger/framework/tailwind.md +55 -0
- package/governance/rules/framework/astro.md +12 -14
- package/governance/rules/framework/fastapi.md +20 -24
- package/governance/rules/framework/nextjs.md +19 -27
- package/governance/rules/framework/react.md +22 -33
- package/governance/rules/framework/shadcn.md +11 -15
- package/governance/rules/framework/tailwind.md +12 -14
- package/governance/rules/writing/markdown.md +1 -1
- package/package.json +1 -1
- package/src/claude/cases/authoring.ts +15 -3
- package/src/claude/cases/misc.ts +12 -0
- package/src/claude/cases/workflow.ts +19 -1
- package/src/claude/skills-audit.ts +113 -1
- package/src/commands/claude.ts +34 -11
- package/src/commands/demo.ts +1 -1
- package/src/commands/markdown.ts +1 -1
- package/src/commands/migrate.ts +4 -0
- package/src/commands/pr.ts +30 -6
- package/src/commands/tasks.ts +383 -2
- package/src/context/audit.ts +1 -1
- package/src/demo/beats.ts +1 -1
- package/src/gov/audit.ts +3 -2
- package/src/markdown/scope.ts +45 -35
- package/src/migrate/record-layout.ts +1 -1
- package/src/migrate/skill-names.ts +68 -21
- package/src/pr/frames.ts +14 -3
- package/src/records/validate.ts +31 -0
- package/src/tasks/board.ts +854 -0
- package/src/tasks/record.ts +20 -1
- package/src/tasks/validate.ts +206 -9
- package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
- package/tooling/astro/reference.md +2 -2
- package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
- /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
- /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
- /package/claude/skills/{draft-doc → write-doc}/references/wiki.md +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: draw-figure
|
|
3
|
+
description: Why a figure decides between Mermaid, an architecture view, and freehand SVG before drawing, and why the Mermaid path carries a render-verification loop
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Draw figure requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, a session asked for a figure reaches for whichever path it thought of first. A graph-shaped subject gets model-authored SVG coordinates nobody checked against a render, drifting from the hand-drawn look every other figure in the project carries. A subject that is not graph-shaped gets forced through Mermaid's node-and-edge model, producing a diagram that answers a different question than the one asked. Either failure ships a figure a reader cannot trust, and a figure exists only to be trusted at a glance.
|
|
11
|
+
|
|
12
|
+
A teach lesson breaks the Mermaid path outright. The lesson letters its figures in a hand font the renderer cannot load, so the render sizes every label in a narrower fallback face and the lesson clips the text it actually shows. The check then reads the standalone image, rendered in that same fallback, and passes a figure the reader sees clipped. Both happened on one lesson, where every group title clipped mid-word and only a capture taken inside the lesson showed it.
|
|
13
|
+
|
|
14
|
+
An architecture view asked for one at a time fails its own way. A session asked to refresh one view redraws every view beside it, so pictures nobody checked change in the same commit and the reviewer cannot tell which one the pass was about. It reaches for C4, state, or class diagrams that render differently in every viewer. A Mermaid source can satisfy every rule in the standard and still render as a picture asserting something false about the system, so a session that judges the source and calls it verified has spent the only signal a reader has on a picture nobody looked at.
|
|
15
|
+
|
|
16
|
+
The color failure is the quiet one. Mermaid's own theme writes literal hex values, and a figure carrying one stops re-coloring itself the moment the host page switches its palette, which the figure standard's own accessibility bar rules out.
|
|
17
|
+
|
|
18
|
+
## Must
|
|
19
|
+
|
|
20
|
+
- Apply the standard's earn-its-place bar before drawing anything
|
|
21
|
+
- Decide between the Mermaid path and the freehand path by whether the subject reduces to a graph, not by which is faster to produce
|
|
22
|
+
- Draw an architecture view from its named source signal, inside `flowchart` and `sequenceDiagram`, and render it through the Mermaid path
|
|
23
|
+
- Draw only the view the request names, leaving every other figure in the destination untouched
|
|
24
|
+
- Draw a figure bound for a teach lesson freehand whatever its shape, since the lesson's hand font is one the renderer cannot measure
|
|
25
|
+
- Verify a figure bound for a rendered page by capturing it inside that page, and fall back to the standalone render only where the destination has no page to load
|
|
26
|
+
- Keep the scoped overflow style as the documented fallback for a clipped group title wherever the Mermaid path still runs
|
|
27
|
+
- Render the Mermaid path with the hand-drawn look and the figure font stack, never with Mermaid's default look
|
|
28
|
+
- Rewrite every literal color the renderer wrote into the custom property the host stylesheet defines
|
|
29
|
+
- Read the Mermaid render back and judge it against what the figure means to say, rather than judging the source
|
|
30
|
+
- Read the node labels by hand, since no hook checks inside a fence
|
|
31
|
+
- Cite only code paths that exist in an architecture view's caption or prose
|
|
32
|
+
- Wrap either path in a `<figure>` and `<figcaption>` and give it an accessible name
|
|
33
|
+
|
|
34
|
+
## Must not
|
|
35
|
+
|
|
36
|
+
- Force a non-graph-shaped subject through Mermaid, or route a graph-shaped one through freehand SVG coordinates a model authored by hand outside a teach lesson
|
|
37
|
+
- Report a figure bound for a rendered page as verified from the standalone render alone
|
|
38
|
+
- Ship a literal hex color on either path
|
|
39
|
+
- Report a clean verification when the Mermaid render was skipped or a defect survived
|
|
40
|
+
- Loop past two correction passes on a surviving defect
|
|
41
|
+
- Commit a scratch render. Only the SVG that ships in the destination document survives
|
|
42
|
+
- Redraw a figure the request did not name, or report one as drawn when it was left alone
|
|
43
|
+
- Leave an architecture view as an unrendered fence
|
|
44
|
+
|
|
45
|
+
## Guards
|
|
46
|
+
|
|
47
|
+
- No subject given: stop, since nothing states what the figure has to show
|
|
48
|
+
- No destination document given: stop, since the figure has nowhere to land
|
|
49
|
+
- Subject does not clear the earn-its-place bar: stop rather than drawing decoration
|
|
50
|
+
- An architecture view with no planning file and no folder structure to scan: stop, because nothing anchors it
|
|
51
|
+
- Render fails for any reason: continue to the output and name the skipped check. A missing renderer degrades the loop rather than failing it.
|
|
52
|
+
|
|
53
|
+
## Out of scope
|
|
54
|
+
|
|
55
|
+
- Mermaid's own layout, budgets, and label rules for the fence itself: the mermaid standard, cited rather than restated here
|
|
56
|
+
- A UI screen mockup: `canvas-board`
|
|
57
|
+
- Design tokens and the visual system: `canvas-board`, which carries a picked direction into the design document
|
|
58
|
+
- Implementation detail behind an architecture view, which belongs in a context entry the caption points at
|
|
59
|
+
- Which lesson needs a figure and where it sits among the lesson's blocks: `teach-workspace`, which calls this skill to draw one
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
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`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: generate
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Draw figure
|
|
9
|
+
|
|
10
|
+
Decide whether a requested figure reduces to a graph Mermaid can draw, is one of the architecture views, or needs freehand SVG, then draw it and verify what a reader will actually see.
|
|
11
|
+
|
|
12
|
+
## Guards
|
|
13
|
+
|
|
14
|
+
- If no subject is given, stop: `❌ No subject given. Name the relationship, boundary, path, or before-and-after this figure should show.`
|
|
15
|
+
- If no destination document is given, stop: `❌ No destination given. Name the file this figure belongs in.`
|
|
16
|
+
|
|
17
|
+
## Step 1: read sources
|
|
18
|
+
|
|
19
|
+
Read these in parallel:
|
|
20
|
+
|
|
21
|
+
- `${CLAUDE_SKILL_DIR}/references/figures.md`: when a figure earns its place, the render-first policy, wrapping and captioning, and the color and accessibility rules
|
|
22
|
+
- `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md`: formatting for the caption prose
|
|
23
|
+
- The `write-human` skill: voice and rhythm for the caption prose
|
|
24
|
+
|
|
25
|
+
## Step 2: does it earn its place
|
|
26
|
+
|
|
27
|
+
Apply the standard's bar: a relationship, a boundary, a path, or a before-and-after that prose or a list cannot carry as well. Stop when it does not: `❌ <subject> reads fine as prose. A figure adds nothing here.`
|
|
28
|
+
|
|
29
|
+
## Step 3: pick the path
|
|
30
|
+
|
|
31
|
+
Take the first that matches, and state which path was picked and why in one sentence:
|
|
32
|
+
|
|
33
|
+
1. **A teach lesson**, a page in a learning workspace's `lessons/` folder: the hand-drawn path, any shape. The renderer cannot load the lesson's hand font, so Mermaid labels measure narrow and clip.
|
|
34
|
+
2. **An architecture view**, meaning the request names system context, components, request flow, data pipeline, or deployment: the architecture set, then the Mermaid path.
|
|
35
|
+
3. **Graph-shaped**, meaning the relationship, boundary, or path is already what a flowchart or sequence diagram expresses: the Mermaid path.
|
|
36
|
+
4. **Anything else**, a spatial or physical arrangement no flowchart reduces to: the hand-drawn path.
|
|
37
|
+
|
|
38
|
+
The standard states this as a render-first policy rather than a ban on any tool-exported drawing, so outside a teach lesson a graph-shaped subject always routes through Mermaid even though that is itself an external renderer.
|
|
39
|
+
|
|
40
|
+
## Step 4: draw
|
|
41
|
+
|
|
42
|
+
Read the reference for the path Step 3 picked and follow it:
|
|
43
|
+
|
|
44
|
+
- Architecture set: shape the view per `${CLAUDE_SKILL_DIR}/references/architecture-set.md`, then draw, render, and read back per `${CLAUDE_SKILL_DIR}/references/mermaid-path.md`
|
|
45
|
+
- Mermaid path: read `${CLAUDE_SKILL_DIR}/references/mermaid-path.md`.
|
|
46
|
+
- Hand-drawn path: read `${CLAUDE_SKILL_DIR}/references/hand-drawn.md`.
|
|
47
|
+
|
|
48
|
+
## Step 5: wrap, caption, and verify
|
|
49
|
+
|
|
50
|
+
- Wrap the drawing in a `<figure>` element with a `<figcaption>` naming what to take from the figure, never what it shows. Let it run wider than the surrounding prose column.
|
|
51
|
+
- On the Mermaid path, run the read-back `mermaid-path.md` states before confirming.
|
|
52
|
+
- On every path, confirm the figure still reads once every color and font it depends on is stripped to its fallback, per the standard's own working-figure bar.
|
|
53
|
+
- On a rendered page, an HTML file a browser loads, the check that counts is the figure in the page, which Step 6 captures on either path. A markdown destination's whole check is the checks above.
|
|
54
|
+
|
|
55
|
+
## Step 6: confirm and write
|
|
56
|
+
|
|
57
|
+
Show the destination path, the decided path, and the full `<figure>` markup before writing. Confirm with the user, since the path decision and the render verdict are judgment calls with no diff to preview, then write the figure where the user named.
|
|
58
|
+
|
|
59
|
+
When the destination is a rendered page, read the `## Capture in the page` section of `${CLAUDE_SKILL_DIR}/references/hand-drawn.md` and run it, on the Mermaid path as well as the hand-drawn one, within the same two correction passes the read-back allows.
|
|
60
|
+
|
|
61
|
+
### Cleaning up
|
|
62
|
+
|
|
63
|
+
Renders and captures under `.canon/tmp/figures/` are verification artifacts. Delete the scratch PNGs, the stamps beside them, and the JSON config once the checks confirm, since only the SVG ships, and keep the `.mmd` source a later refresh redraws from.
|
|
64
|
+
|
|
65
|
+
## Output
|
|
66
|
+
|
|
67
|
+
### Preview
|
|
68
|
+
|
|
69
|
+
**Destination:** `<path>`
|
|
70
|
+
**Render path:** `<mermaid | architecture | freehand>`, `<one-sentence reason>`
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<drafted figure markup></drafted>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### After confirmation
|
|
77
|
+
|
|
78
|
+
Report the write in this shape.
|
|
79
|
+
|
|
80
|
+
```plaintext
|
|
81
|
+
✅ Drafted figure in <path>
|
|
82
|
+
Render path: <mermaid | architecture | freehand>
|
|
83
|
+
Verified <in page | as a standalone render>. <defect or skipped check, one line, omitted when clean>
|
|
84
|
+
<Font not embedded: run `canon design css --figures` to ship Virgil and Excalifont. Omitted when the project already ran it.>
|
|
85
|
+
```
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Architecture set
|
|
3
|
-
description: The five architecture views with each one's question, source signal, and diagram type, the code-scan fallback, cited paths, and what moves to canon/context/ instead, read by
|
|
3
|
+
description: The five architecture views with each one's question, source signal, and diagram type, the code-scan fallback, cited paths, and what moves to canon/context/ instead, read by draw-figure when a request names an architecture view
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Architecture set
|
|
7
7
|
|
|
8
|
-
`
|
|
8
|
+
`draw-figure` reads this file when the request names an architecture view. It shapes the subject, then the figure goes through `${CLAUDE_SKILL_DIR}/references/mermaid-path.md` like any other graph-shaped figure. The destination stays the one the user named.
|
|
9
9
|
|
|
10
10
|
## The five views
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Hand-drawn path
|
|
3
|
-
description: Authoring a freehand SVG, its color and accessibility audit, and the in-page capture loop a rendered destination takes, read by
|
|
3
|
+
description: Authoring a freehand SVG, its color and accessibility audit, and the in-page capture loop a rendered destination takes, read by draw-figure once a figure is drawn by hand
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Hand-drawn path
|
|
7
7
|
|
|
8
|
-
`
|
|
8
|
+
`draw-figure` reads this file when Step 3 routes a figure to a freehand drawing: a teach lesson whatever its subject, or a subject no flowchart reduces to.
|
|
9
9
|
|
|
10
10
|
## Draw
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Mermaid path
|
|
3
|
-
description: The hand-drawn render config, the SVG and PNG pair, the hex rewrite, the scoped overflow fallback, the label check, and the PNG read-back with its two-pass stop, read by
|
|
3
|
+
description: The hand-drawn render config, the SVG and PNG pair, the hex rewrite, the scoped overflow fallback, the label check, and the PNG read-back with its two-pass stop, read by draw-figure once a figure routes through Mermaid
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Mermaid path
|
|
7
7
|
|
|
8
|
-
`
|
|
8
|
+
`draw-figure` reads this file when Step 3 routes a figure through Mermaid, whether the subject is graph-shaped or an architecture view the architecture set already shaped.
|
|
9
9
|
|
|
10
10
|
## Draft the fence
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ Governs the Mermaid attribute wherever a fence is written, being direction and l
|
|
|
13
13
|
|
|
14
14
|
Does not govern:
|
|
15
15
|
|
|
16
|
-
- Which architecture view a figure draws and what question it answers: the `
|
|
16
|
+
- Which architecture view a figure draws and what question it answers: the `draw-figure` skill's architecture set
|
|
17
17
|
- Language, word choice, punctuation, and formatting in the prose around a fence: `markdown.md`
|
|
18
18
|
- Voice, rhythm, and sentence construction in that prose: the `write-human` skill
|
|
19
19
|
- The mechanism behind any component a diagram draws: `context.md`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: make-deck
|
|
3
|
+
description: Why the skill draws a deck as HTML in the project's tokens inside its own folder, why the CLI owns the conversion, and why one render is read back before the deck is called done
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Make deck requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, a deck request turns into hand-built output. The session writes a deck into whatever path occurs to it, so a second deck overwrites the first and nothing lists either. It writes pptxgenjs code or hex colors per deck, so the deck takes neither the project's design nor any other deck's, and it invents attributes the converter does not read, so a section, a chart, or an entrance silently goes missing. Every slide comes out as a title over bullets, which is the shape that needs no decision and reads as a document rather than a deck.
|
|
11
|
+
|
|
12
|
+
A first render shipped unread hands the audience the overlap, the overflow, and every element the converter fell back to a picture for, since markup that looks correct says nothing about the file it produces.
|
|
13
|
+
|
|
14
|
+
## Must
|
|
15
|
+
|
|
16
|
+
- Read the existing decks and the slide format from the CLI before drawing, and pick a deck name no listed deck carries unless the request names one
|
|
17
|
+
- Write each deck into its own folder under the slides record folder, one HTML file per slide in filename order
|
|
18
|
+
- Draw with the project's custom properties so the deck takes the project's design
|
|
19
|
+
- Vary the composition across the deck rather than repeating one shape
|
|
20
|
+
- Size content to fit the slide frame, keeping titles short and lines tight
|
|
21
|
+
- Shell out to the render command for the deck itself
|
|
22
|
+
- Read every fallback and refusal the render reports, run one QA pass over the rendered images, and fix what both report
|
|
23
|
+
|
|
24
|
+
## Must not
|
|
25
|
+
|
|
26
|
+
- Hardcode a deck name, an attribute, or a chart type, which goes stale the moment the CLI changes
|
|
27
|
+
- Reimplement the conversion, the master, or the packaging, which the CLI owns
|
|
28
|
+
- Write a deck into the shared layouts folder, which is never listed as a deck
|
|
29
|
+
- Invent token values when the project has no token stylesheet
|
|
30
|
+
- Write centered body text or content that overflows a slide
|
|
31
|
+
- Loop on aesthetics past a single fix pass
|
|
32
|
+
|
|
33
|
+
## Guards
|
|
34
|
+
|
|
35
|
+
- No token stylesheet: draw the deck anyway and say it renders unstyled.
|
|
36
|
+
- Image conversion tools missing: skip the image pass and say so. Do not fail the render over a verification step.
|
|
37
|
+
|
|
38
|
+
## Out of scope
|
|
39
|
+
|
|
40
|
+
- Converting HTML to PowerPoint, which the CLI owns end to end
|
|
41
|
+
- The project's palette and faces, which live in its token stylesheet rather than in the slides
|
|
42
|
+
- Writing the content the deck is about, which the caller brings
|
|
43
|
+
- Drafting a deck as a canvas page, which waits on a measurement of that authoring surface
|
|
44
|
+
- Recording a demo, which `script-screencast` owns
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: make-deck
|
|
3
|
+
description: Draws a deck as HTML slides in the project's own design, one folder under `.canon/slides/` per deck, then renders it to an editable PowerPoint file via `canon slides render`. Use when asked to "draft slides", "make a deck", "build a presentation", "turn this into slides", or "render the deck". Holds the deck design rules. Do NOT reimplement the conversion. The CLI owns layout into PowerPoint shapes, the master, and packaging. Assumes the `canon` CLI is on PATH.
|
|
4
|
+
metadata:
|
|
5
|
+
family: generate
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Make deck
|
|
9
|
+
|
|
10
|
+
Draw each slide as an HTML file in a deck folder, then shell out to `canon slides render`. The CLI lays every slide out in a browser and rebuilds it as editable PowerPoint shapes. This skill owns the content, the slide markup, and the design choices the markup encodes.
|
|
11
|
+
|
|
12
|
+
## Read the decks and the format
|
|
13
|
+
|
|
14
|
+
Run the list first, then read the format. Never hardcode a deck name, an attribute, or a chart type.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
canon slides list --json 2>/dev/null
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The list returns one row per deck, carrying its `name`, `title`, slide count, and `path`. When the request names a deck the list holds, edit that folder. Otherwise pick a new kebab-case name no row carries.
|
|
21
|
+
|
|
22
|
+
Read `${CLAUDE_SKILL_DIR}/references/deck.md`. It states what `deck.json` holds, what each slide declares on its `<body>`, the motion attributes, speaker notes, and charts. Each refusal prints as a `✗` line from the render.
|
|
23
|
+
|
|
24
|
+
## Draw the deck
|
|
25
|
+
|
|
26
|
+
A deck folder sits at `.canon/slides/<deck>/` from the project root, and holds:
|
|
27
|
+
|
|
28
|
+
- One `.html` file per slide, rendered in filename order. Number them with a zero-padded prefix, such as `01-cover.html`, so a slide inserted later sorts where it belongs.
|
|
29
|
+
- `deck.json`, optional, for the title, the header and footer bands, slide numbers, the mark, and embedded faces.
|
|
30
|
+
- `assets/` for images the slides reference by a relative path.
|
|
31
|
+
|
|
32
|
+
Never write a slide into `.canon/slides/layouts/`. That folder holds the project's shared layouts and is never listed as a deck.
|
|
33
|
+
|
|
34
|
+
Each slide is a full HTML document laid out at 1280 by 720 CSS pixels. Position its blocks absolutely or with a flex or grid container sized to that frame, and keep every element inside it.
|
|
35
|
+
|
|
36
|
+
## Design rules
|
|
37
|
+
|
|
38
|
+
The render injects the project's token stylesheet ahead of each slide's own styles, so the deck takes the project's design rather than the toolkit's.
|
|
39
|
+
|
|
40
|
+
- Use the project's custom properties, such as `var(--color-accent)`, for every color, face, and spacing value, read from `.claude/design/base.css` and overrides under `.claude/design/project/`
|
|
41
|
+
- When neither exists, say the deck renders unstyled rather than inventing values to cover it
|
|
42
|
+
- Leave the `--color-*` roles to the stylesheet. The master reads its colors off the first slide's `<html>`, so a slide computing its own `--color-text` is reported, since the bands keep the master's.
|
|
43
|
+
- Vary the composition across slides. Never repeat a title over bullets on every slide. Reach for columns, a row of large numbers, a grid of cards, a chart, a pull quote, and section dividers.
|
|
44
|
+
|
|
45
|
+
### Fit and shapes
|
|
46
|
+
|
|
47
|
+
Text and shapes have to survive the conversion.
|
|
48
|
+
|
|
49
|
+
- Keep titles short and lines tight, so text fits its box at the size the design sets rather than overflowing the frame.
|
|
50
|
+
- Never write centered body text.
|
|
51
|
+
- Prefer CSS the converter maps to native shapes. An unmappable property is drawn as a picture and reported on stderr, so a slide full of gradients and filters stops being editable.
|
|
52
|
+
|
|
53
|
+
## Render
|
|
54
|
+
|
|
55
|
+
Shell out to the CLI. It writes the deck and reports the path.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
canon slides render <deck>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
With one deck in the project the name can be left out. The render refuses with the deck list when there are several. Pass `--open` to open the deck, and `--mirror <dir>`, or set `CANON_SLIDES_MIRROR`, to copy it into a synced folder.
|
|
62
|
+
|
|
63
|
+
Read every `✗` line the render prints. A picture fallback, a refused link, chart, or effect, and a missing token each leave the deck written with that piece degraded or left out.
|
|
64
|
+
|
|
65
|
+
## QA loop
|
|
66
|
+
|
|
67
|
+
Run this once after the first render, then stop.
|
|
68
|
+
|
|
69
|
+
1. Convert the deck with `soffice --headless --convert-to pdf <deck>.pptx`, then `pdftoppm -r 90 -png <deck>.pdf slide`. If either is missing, skip the image pass and say so rather than fail the render.
|
|
70
|
+
2. Open and inspect every rendered image in this session, checking each slide for overlap, overflow, low contrast, and empty regions.
|
|
71
|
+
3. Fix the reported issues and the `✗` lines in the slide files once, re-render, and stop. Do not loop indefinitely on aesthetics.
|
|
72
|
+
|
|
73
|
+
## Response
|
|
74
|
+
|
|
75
|
+
After rendering, report:
|
|
76
|
+
|
|
77
|
+
- The deck folder, the slide count, and the written `.pptx` path
|
|
78
|
+
- Whether the project's token stylesheet was found
|
|
79
|
+
- Each `✗` line the final render printed, or that it printed none
|
|
80
|
+
- Any QA issues found and what changed, or that the deck passed clean
|
|
@@ -15,7 +15,7 @@ The rules also had three carriers, a standard, a generated rule pointing at it,
|
|
|
15
15
|
|
|
16
16
|
- Hold the format and structure reference in `references/markdown.md`, the one copy, read by sibling path from every skill that writes markdown
|
|
17
17
|
- Send the session to `canon markdown audit` after an edit, since the audit reads the bans from the package and a restated list would drift
|
|
18
|
-
- Route voice to `write-human` and a Mermaid fence to `
|
|
18
|
+
- Route voice to `write-human` and a Mermaid fence to `draw-figure` rather than restating either
|
|
19
19
|
|
|
20
20
|
## Must not
|
|
21
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: markdown-craft
|
|
3
|
-
description: Carries the format and structure rules for markdown, being headings, the density limits, paragraph and list shape, code spans, the date form, punctuation, emphasis, file references, American spelling, and frontmatter wording, and runs the audit after an edit. Use before a substantial markdown edit, when writing a README, a doc, a skill body, or any `.md` file, or when asked "what are the markdown rules" or "which characters are banned". Do NOT use for voice, rhythm, or word choice, which is `write-human`, or for a Mermaid fence or figure, which is `
|
|
3
|
+
description: Carries the format and structure rules for markdown, being headings, the density limits, paragraph and list shape, code spans, the date form, punctuation, emphasis, file references, American spelling, and frontmatter wording, and runs the audit after an edit. Use before a substantial markdown edit, when writing a README, a doc, a skill body, or any `.md` file, or when asked "what are the markdown rules" or "which characters are banned". Do NOT use for voice, rhythm, or word choice, which is `write-human`, or for a Mermaid fence or figure, which is `draw-figure`.
|
|
4
4
|
metadata:
|
|
5
5
|
family: answer
|
|
6
6
|
---
|
|
@@ -14,4 +14,4 @@ Run `canon markdown audit <path>` after the edit, and fix every ban and density
|
|
|
14
14
|
## Routes
|
|
15
15
|
|
|
16
16
|
- Voice, rhythm, sentence construction, and information density: load `write-human`.
|
|
17
|
-
- A Mermaid fence or a figure: load `
|
|
17
|
+
- A Mermaid fence or a figure: load `draw-figure`, since the audit skips every line inside a fence.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pick-by-eye
|
|
3
|
+
description: Why a decision settled by looking needs its own surface, and where its boundary against the planning, audit, measurement, and recording skills falls
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pick by eye requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, a session facing a decision nobody can settle from a diff:
|
|
11
|
+
|
|
12
|
+
- Describes two options in prose and asks the operator to choose. The operator decides by looking, so a described option is not an option and the answer that comes back is arbitrary.
|
|
13
|
+
- Produces one answer for a decision that was taste, so the operator never sees what they were choosing between and the call is taken silently by whoever wrote the code.
|
|
14
|
+
- Reports that a candidate reads well without rendering it, so the claim rests on the markup having been written rather than on the page having been seen.
|
|
15
|
+
- Hands over one image per arm, which asks the operator to hold the differences in memory rather than showing them. The comparison is the artifact and a set of separate files is not one.
|
|
16
|
+
- Varies three properties at once across the arms, so the pick cannot say which difference decided it and the next iteration guesses.
|
|
17
|
+
- Writes the candidates into the real surface, so the losing arms have to be unpicked out of a tree the operator has not judged yet, and a variant left behind a flag becomes a second design nobody maintains.
|
|
18
|
+
- Stops the loop when the arms stop differing rather than when the operator says the pick is right, which ends the run on the session's own patience.
|
|
19
|
+
- Reads a driver record as a verdict and drops an arm on it. `canon drive` reports findings and never gates, so a run filtering the arms on a probe reading has made a claim the probe catalog has not earned.
|
|
20
|
+
- Reads a color without compositing its alpha, samples a round control at the corner of its bounding box, or confirms a panel's dimensions while it sits above the viewport. Each reads as a passing measurement about something no reader sees.
|
|
21
|
+
- Meets a machine with no browser binary and reports on the arms anyway, since nothing in the default flow separates a render that failed from one that was never attempted.
|
|
22
|
+
- Hand-writes a mockup of a surface a running app already serves, which drifts from what ships by a few pixels and a few words the moment the app's own markup or stylesheet moves on.
|
|
23
|
+
- Varies a property the decision is not about, which satisfies the one-property rule and produces a set differing in the layer a reader notices least. Five palettes over one identical page read as five skins of one design, and the operator rejected the whole set on sight.
|
|
24
|
+
- Renders each arm in whatever theme it happens to carry, so a set spanning both themes cannot be compared without the operator toggling every arm and holding the earlier ones in memory.
|
|
25
|
+
- Looks at a render to confirm it came out rather than to judge whether it is worth showing, which satisfies the rule against reporting an unseen result and still hands over weak work.
|
|
26
|
+
- Writes the run's renders to a scratch path outside the record that cites them, leaving the folder holding source markup and none of the images, so the judgment is unreachable to everyone except the session that made it.
|
|
27
|
+
- Narrows the page onto the picked arm in place on each iteration, so every earlier round is overwritten and a later pass cannot see what was already rejected.
|
|
28
|
+
- Names no layer at all, since the instruction to name one carries no catalog to name from and nothing reports the omission. Four consecutive rounds against one page each varied a property at the top layer while the defect sat two below it, and three of the four changed nothing the operator could see.
|
|
29
|
+
- Judges a lower layer through a finished higher one, so an operator asked about composition looks at the palette instead and answers about that.
|
|
30
|
+
- Hands over the combined page alone for a decision about layout, where every arm sits in a column while the media queries answer to the whole window, so no arm is ever seen at its own viewport and a fault that appears only narrower survives the pick.
|
|
31
|
+
- Rebuilds a navigation harness by hand on a run with several rounds, since each round writes its own folder and nothing reaches all of them from one address. Two design tracks hand-wrote the same page picker and theme toggle.
|
|
32
|
+
- Meets a session with no canvas server and drafts into a file instead, which leaves the operator a second surface to open and the run a second close to remember. The canvas is the one drafting surface, so a run without one starts it rather than falling back.
|
|
33
|
+
- Puts the pick question with no address in its output, after capturing the page and reading the image back. The operator then has to ask for a served page before they can look, so the question goes unanswered or gets answered blind.
|
|
34
|
+
- Sets the theme on an arm that persists its own and reads it back on load, so the control reports one theme while the arm renders the other and the set is compared across two.
|
|
35
|
+
|
|
36
|
+
## Must
|
|
37
|
+
|
|
38
|
+
- Produce three to five arms with the shipping state among them, each carrying an id, a label, and what the arm costs.
|
|
39
|
+
- Draft every arm of a round as one self-contained frame on one canvas page and capture that page once as a composite, so the comparison arrives as one image, except where the surface under decision is a running app: there each frame links a copy of the built stylesheet inside the page folder rather than inlining it, per `references/live-arms.md`.
|
|
40
|
+
- Start the canvas when none is serving, and stop on a canvas that refuses to start or answers with a blank shell, rather than drafting into a file.
|
|
41
|
+
- Emit the layer in the run's own output, drawn from the catalog `design-taste` fixes rather than from a word invented per run, and vary the arms at that layer alone. A layer held privately is one nothing can report missing, which is how the instruction went unfollowed while every round passed its own rules.
|
|
42
|
+
- Grey-box the set when the declared layer sits below typography, and say the set is grey-boxed when handing it over, so the operator reads a flat page as the question rather than as unfinished work.
|
|
43
|
+
- Theme every arm off the attribute the canvas toggle sets on each frame, so one control sets the whole set and the comparison holds still while the operator reads it, and give no arm a script that reads a stored preference back on load over the toggle.
|
|
44
|
+
- Give each frame the width the arm is judged at, since a frame renders at its own layout width and answers how an arm behaves at a width where a column on a shared page could not.
|
|
45
|
+
- Judge each render against a stated bar before handing it over, name the weakest thing on the page, and fix it where that sentence would embarrass the work.
|
|
46
|
+
- Write each iteration to its own canvas page rather than narrowing the previous one in place, so every earlier round stays openable from the canvas page list.
|
|
47
|
+
- Write the run's renders inside the record that cites them wherever one exists, and reserve the scratch path for inputs that are re-runnable and cited by nothing.
|
|
48
|
+
- Render before reporting on any arm, and report a missing browser binary as a refusal naming the repair rather than describing an arm nobody has seen.
|
|
49
|
+
- Take the pick through the structured question surface, with the recommendation ranked first and marked, and every option carrying its cost. Read the canvas selection only to resolve an answer that points at it, and treat an empty or stale selection as no answer.
|
|
50
|
+
- Keep every write inside the run's own canvas pages until the pick is final.
|
|
51
|
+
- Apply the winning arm in one change.
|
|
52
|
+
- Capture every arm from the round the pick came from, whichever round that is, as an image named for its frame before deleting the run's pages, rather than discarding the losing arms with them.
|
|
53
|
+
- Delete only the canvas pages the run itself added, recorded as it adds them, and stop only a canvas server the run itself started.
|
|
54
|
+
- Resolve the archival capture's destination against the main worktree root, never against a linked worktree the run happens to be building in.
|
|
55
|
+
- Put the candidates on the canvas on every run, whatever the decision's layer, and emit the canvas link ahead of the first pick question, so the operator can open the page the question is about and a still is never the only address.
|
|
56
|
+
|
|
57
|
+
## Must not
|
|
58
|
+
|
|
59
|
+
- Take the pick where two arms are both defensible and the difference is taste. That call is the operator's, and taking it silently is the failure this skill exists to prevent.
|
|
60
|
+
- Draft candidates for a decision the operator has not asked to make. Each arm costs a render, and a run offering options everywhere spends their attention rather than saving it.
|
|
61
|
+
- Restate the mechanics of the canvas, the render, or the probes. `canon canvas` and `canon drive` own those and their help text is the source, so a second copy here hands one case two answers.
|
|
62
|
+
- Read a `canon drive` finding as a gate over the arms.
|
|
63
|
+
- Fire on a request that already names one answer.
|
|
64
|
+
|
|
65
|
+
## Guards
|
|
66
|
+
|
|
67
|
+
The refusal strings sit in the body, since the runtime loads that file and ignores this one. Two conditions stop a run: a request naming one answer and asking for it to be built, and a decision with no visible form for a render to show.
|
|
68
|
+
|
|
69
|
+
## Out of scope
|
|
70
|
+
|
|
71
|
+
- `plan-feature` plans the work once the answer is settled, and declares the pull request boundary its plan carries. This produces the answer to pick from and stops before the plan.
|
|
72
|
+
- `ux-audit` reads source to find roughness and reports it. This takes its input from the operator and changes nothing until they pick.
|
|
73
|
+
- `ux-measure` measures what a running interface costs to paint. This measures whatever a visual claim depends on, which is usually geometry or contrast rather than cost.
|
|
74
|
+
- `ui-checklist` writes what to look at on a change already made. This runs before there is a change to look at.
|
|
75
|
+
- `script-screencast` scripts a recording of something already built. This has nothing built yet.
|
|
76
|
+
- `canon canvas` owns the page, the frames, the selection, the address, and the render, and `canon drive` owns the probes. Both are invoked rather than reimplemented.
|
|
77
|
+
|
|
78
|
+
### What did not travel
|
|
79
|
+
|
|
80
|
+
This descends from a project-local skill whose interactive half was written against one repository. Three of its capabilities do not travel, and the two verbs above are what stands in their place:
|
|
81
|
+
|
|
82
|
+
- An arm switcher compiled into the project's own page, driven by a query parameter. A canvas page of frames replaces it, which puts the arms on the canvas rather than in the source and removes the call site a run had to remember to delete.
|
|
83
|
+
- A copy cycle keyed to canonical page text held in a second repository. No toolkit surface has that shape, so a project holding one owns the second edit and this skill states nothing about it.
|
|
84
|
+
- A walker that reads every control on every page and groups them by treatment. `canon drive` probes one page and reports findings, so a sweep across every surface of a site is out of reach here and a run needing one measures by hand.
|
|
85
|
+
|
|
86
|
+
The capture mechanics traveled with a change of owner rather than being lost. They sat in a project-local path-scoped rule that fired whether or not the skill ran, and `canon canvas capture` owns them here, which is why this file bars restating them rather than naming a rule to defer to.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
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`, to write what to look at on a change already made, which is `ui-checklist`, or to script a recording, which is `script-screencast`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: decide
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Pick by eye
|
|
9
|
+
|
|
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
|
+
|
|
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.
|
|
13
|
+
|
|
14
|
+
## Guards
|
|
15
|
+
|
|
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
|
+
- If the decision has no visible form, stop: `❌ Nothing to look at. Drafting candidates needs a decision a render can show.`
|
|
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
|
+
|
|
20
|
+
## Step 1: name the decision and the arms
|
|
21
|
+
|
|
22
|
+
1. State the decision in one sentence, naming what changes between arms and what stays fixed.
|
|
23
|
+
2. Emit the design read in the run's output, in the form `design-taste` fixes, taking the layer from its ordered catalog. The arms differ at that layer, and a missing read is visible.
|
|
24
|
+
3. Derive a kebab slug from that sentence. The first round's page is `<slug>`, and Step 5 names later rounds `<slug>-2`, `<slug>-3`, and so on.
|
|
25
|
+
4. Write one arm per candidate, each carrying an id, a label, and what the arm costs. An arm with no stated cost is not an option.
|
|
26
|
+
5. Make the current state arm `0`, so the baseline is a candidate rather than an absence. A decision with nothing shipped yet says so and starts at arm `1`.
|
|
27
|
+
6. Stop at three to five arms. Two is a comparison the operator can hold in prose, and past five the pick stops being a look and becomes a sort.
|
|
28
|
+
|
|
29
|
+
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
|
+
## Step 2: draft the arms as frames on one canvas page
|
|
32
|
+
|
|
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
|
+
|
|
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`.
|
|
40
|
+
|
|
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.
|
|
44
|
+
|
|
45
|
+
### What every frame carries
|
|
46
|
+
|
|
47
|
+
Each frame carries its own label and follows the canvas theme, so the set reads as one comparison.
|
|
48
|
+
|
|
49
|
+
- 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.
|
|
51
|
+
- 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
|
+
|
|
53
|
+
### Default path and live app
|
|
54
|
+
|
|
55
|
+
A running app under decision takes the live-app branch, and every other decision takes the default path.
|
|
56
|
+
|
|
57
|
+
- 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.
|
|
60
|
+
|
|
61
|
+
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
|
+
|
|
63
|
+
### What varies
|
|
64
|
+
|
|
65
|
+
Vary one property across the arms, since a pick cannot say which of three differences decided it.
|
|
66
|
+
|
|
67
|
+
- Vary the property the decision is about. Holding composition fixed and varying color produces five skins of one design, and a palette cannot be picked ahead of the composition it serves.
|
|
68
|
+
- Grey-box the arms when the declared layer sits below typography, per `design-taste`, and say the set is grey-boxed when handing it over
|
|
69
|
+
- Do not grey-box a set judged at composition that carries a finished palette, since the operator looks at the higher layers instead of the question
|
|
70
|
+
|
|
71
|
+
## Step 3: render and hand off
|
|
72
|
+
|
|
73
|
+
Render the page and look at what came back before handing anything over:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
canon canvas capture <page> --composite --json
|
|
77
|
+
```
|
|
78
|
+
|
|
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.
|
|
82
|
+
|
|
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.
|
|
84
|
+
|
|
85
|
+
### Handing over
|
|
86
|
+
|
|
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.
|
|
88
|
+
|
|
89
|
+
- 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
|
+
- Never report a visual result you have not looked at, since a claim about appearance with no render behind it is a guess
|
|
91
|
+
- Look to judge rather than to confirm. Name the weakest thing on the page in a sentence, fix it where that sentence would embarrass the work, and say what remains.
|
|
92
|
+
|
|
93
|
+
## Step 4: take the pick
|
|
94
|
+
|
|
95
|
+
Put the choice to the operator through the structured question surface, since a call the operator's preference decides always routes through it rather than through prose.
|
|
96
|
+
|
|
97
|
+
- Emit the link ahead of the question call and again in the question's text, since some surfaces render the card alone
|
|
98
|
+
- One option per arm, labeled with the arm's id and carrying its cost as the description
|
|
99
|
+
- Rank the recommendation first and mark it `(Recommended)`
|
|
100
|
+
- Author the real arms only. The surface appends its own free-text and reopen escapes, and a duplicate is rejected.
|
|
101
|
+
|
|
102
|
+
### Taking the answer
|
|
103
|
+
|
|
104
|
+
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
|
+
|
|
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 |
|
|
114
|
+
|
|
115
|
+
## Step 5: loop on the pick
|
|
116
|
+
|
|
117
|
+
1. Add each iteration as its own page, recorded on the run's list. An overwritten page cannot be reopened, and the losing round stops a correction re-proposing a rejected arm.
|
|
118
|
+
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
|
+
3. Re-render, hand off again, and take the next answer.
|
|
120
|
+
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.
|
|
122
|
+
|
|
123
|
+
## Step 6: close
|
|
124
|
+
|
|
125
|
+
1. Apply the winning arm to the real surface, in one change.
|
|
126
|
+
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. 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.
|
|
128
|
+
4. Resolve `<archive-dir>` as `.canon/picks/<slug>/` against the main worktree root, since shared session scratch resolves there rather than in a linked worktree.
|
|
129
|
+
5. 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.
|
|
130
|
+
6. Stop the canvas server if this run started it, and leave one the operator started running.
|
|
131
|
+
7. Leave the renders in a live track's `evidence/<slug>/renders/`, since `plan-groundwork` treats evidence as durable.
|
|
132
|
+
8. Report each page whose delete is refused, naming the path for the operator to remove. The pick is applied either way.
|
|
133
|
+
9. 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.
|
|
134
|
+
|
|
135
|
+
The picked round is the final one unless Step 4 resolved a revert. Archiving any other page lets item 5 delete the winning arm with nothing kept, and a variant left on the canvas is a second design nobody maintains.
|
|
136
|
+
|
|
137
|
+
## Reading a measurement
|
|
138
|
+
|
|
139
|
+
A capture proves appearance and a measurement proves a relationship, so reach for the second whenever the claim is a number, such as a contrast ratio, a column width, or a tap target. `canon drive` runs the probes and ships the failure modes each one carries.
|
|
140
|
+
|
|
141
|
+
- Composite alpha before reading a color. A `color-mix` toward transparent resolves to channels plus an alpha, and reading them as opaque reports a color nobody sees.
|
|
142
|
+
- Sample inside the shape. A patch at a bounding box corner misses a round control and reads the page behind it.
|
|
143
|
+
- Ask whether a reader would see the thing. A panel sized a healthy 1517 by 639 passed every size check while sitting 1868px above the viewport.
|
|
144
|
+
|
|
145
|
+
`canon drive` reports findings and never gates. Read its record as evidence for the operator rather than as a filter over the arms, since the probe catalog has not earned the right to drop one.
|
|
146
|
+
|
|
147
|
+
## What this delegates
|
|
148
|
+
|
|
149
|
+
Cite these rather than restating them. A step reimplemented here rots against the skill that owns it.
|
|
150
|
+
|
|
151
|
+
- `plan-feature` plans the work once the pick is made, and declares the pull request boundary that plan carries
|
|
152
|
+
- `design-taste` carries the layer catalog, the ordering, grey-boxing, and the defaults an arm should reach past
|
|
153
|
+
- `write-human` carries the voice for any copy an arm puts in front of a reader
|
|
154
|
+
|
|
155
|
+
### Git and review
|
|
156
|
+
|
|
157
|
+
Commits, review, and the canvas mechanics each have an owner.
|
|
158
|
+
|
|
159
|
+
- `git-stage`, `git-pr`, and `git-followup` carry the commits and the pull request
|
|
160
|
+
- `review-pr` and `review-address` run the review pass
|
|
161
|
+
- `canon:canvas-board` carries the canvas start-and-check sequence, the main-root write route for a frame, and the selection and capture refusals
|