@erclx/canon 4.90.0 → 4.93.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 (63) hide show
  1. package/README.md +5 -5
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/design-taste/REQUIREMENT.md +78 -0
  4. package/claude/skills/design-taste/SKILL.md +148 -0
  5. package/claude/skills/design-taste/references/craft.md +58 -0
  6. package/claude/skills/design-taste/references/kinds.md +52 -0
  7. package/claude/skills/design-taste/references/preflight.md +77 -0
  8. package/claude/skills/design-taste/references/systems.md +49 -0
  9. package/claude/skills/design-taste/references/tells.md +101 -0
  10. package/claude/skills/design-taste/references/vocabulary.md +62 -0
  11. package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -2
  12. package/claude/skills/draft-and-pick/SKILL.md +13 -5
  13. package/claude/skills/draft-ready/REQUIREMENT.md +53 -0
  14. package/claude/skills/draft-ready/SKILL.md +118 -0
  15. package/claude/skills/draft-ready/references/assembly.md +67 -0
  16. package/claude/skills/session-compact/REQUIREMENT.md +44 -0
  17. package/claude/skills/session-compact/SKILL.md +60 -0
  18. package/claude/skills/session-compact/references/handoff-note.md +68 -0
  19. package/claude/skills/session-map/REQUIREMENT.md +3 -2
  20. package/claude/skills/session-map/SKILL.md +2 -2
  21. package/claude/skills/session-resume/SKILL.md +3 -3
  22. package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
  23. package/docs/agents/capture.md +12 -5
  24. package/docs/agents/commands.md +3 -3
  25. package/docs/agents/rule-citations.md +1 -1
  26. package/docs/agents/teach.md +2 -2
  27. package/docs/workflow/ai-workflow.md +3 -1
  28. package/governance/rules/claude/563-ready.md +4 -0
  29. package/governance/rules/lib/305-e2e-reliability.md +3 -2
  30. package/governance/rules/lib/306-test-scope.md +1 -2
  31. package/governance/rules/ui/410-a11y.md +9 -0
  32. package/governance/rules/ui/420-forms.md +9 -0
  33. package/governance/rules/ui/460-design-taste.md +29 -0
  34. package/governance/rules/ui/470-motion.md +23 -0
  35. package/governance/stacks/astro.toml +1 -1
  36. package/governance/stacks/react.toml +1 -1
  37. package/package.json +3 -2
  38. package/scripts/core/regen-hero.sh +4 -3
  39. package/src/capture/render.ts +15 -1
  40. package/src/claude/cases/authoring.ts +5 -0
  41. package/src/claude/cases/misc.ts +10 -0
  42. package/src/cli.ts +1 -1
  43. package/src/commands/capture.ts +26 -1
  44. package/src/commands/design.ts +5 -0
  45. package/src/commands/feedback.ts +1 -0
  46. package/src/commands/serve.ts +11 -1
  47. package/src/commands/slides.ts +3 -0
  48. package/src/commands/transcripts.ts +1 -0
  49. package/src/design/base.css +25 -19
  50. package/src/design/css.ts +4 -0
  51. package/src/design/fonts.ts +17 -0
  52. package/src/design/tokens.ts +45 -30
  53. package/src/gate/measures.ts +5 -4
  54. package/src/gate/stages.ts +1 -1
  55. package/src/serve/static.ts +90 -6
  56. package/src/teach/render.ts +2 -2
  57. package/src/teach/workspace.ts +1 -0
  58. package/standards/ready.md +2 -0
  59. package/standards/session.md +1 -0
  60. package/tooling/astro/configs/playwright.config.ts +2 -0
  61. package/tooling/nextjs/configs/playwright.config.ts +2 -0
  62. package/tooling/vite-react/configs/playwright.config.ts +2 -0
  63. package/src/teach/render-fixture.tsx +0 -95
@@ -0,0 +1,101 @@
1
+ ---
2
+ title: Machine tells in design
3
+ description: The visual defaults a model reaches for when nothing states a direction, each with what to do instead, plus the record of which external items were adopted, which were declined, and why
4
+ ---
5
+
6
+ # Machine tells in design
7
+
8
+ Each item below is a shape rather than a value, which is why no ban list of colors or fonts reaches any of them. Read this before handing over anything a model drafted. Skip it on a small change to a surface that already has a settled direction.
9
+
10
+ The skill body carries the ten most common of these. This is the same catalog at full length, so an item appearing in both is one list rather than two.
11
+
12
+ An item is a default to reach past, not a prohibition. A brief that explicitly asks for one gets it, and the point is that it was chosen rather than defaulted into.
13
+
14
+ ## Composition
15
+
16
+ - **The three equal cards.** Three identical boxes in a row under a heading is the most-reached-for feature section in existence. Reach for a two-column alternation, an asymmetric grid, a list with one item given weight, or a single worked example.
17
+ - **One section shape repeated down the page.** A page where every section is a centered heading over a centered body reads flat whatever its palette. Vary alignment, container width and the ratio between sections.
18
+ - **The centered hero over a dark wash.** Centered headline, centered subhead, two buttons, gradient behind. Reach for an asymmetric split, a full-bleed artifact, or content that starts immediately.
19
+ - **Decoration standing in for structure.** Hairline grids, crosshairs, floating rules and corner marks added so a page feels designed. Use them where they organize real content and remove them where they do not.
20
+ - **The corner floater.** A large left-aligned section heading with a small explanatory paragraph floating in the top right, aligned to nothing. Put the sub-text under the heading or build a real two-column header.
21
+
22
+ ## Content and labels
23
+
24
+ - **Enumerated eyebrows.** `001 / Capabilities`, `Phase 02`, `Step 1`, `Stage One`. The content is the label. Where progression genuinely matters, use the verb.
25
+ - **Poetic section labels.** "From the field", "On our desks", "Currently on the bench". Use the plain functional label or drop the label.
26
+ - **Atmospheric strips.** City, time zone, temperature, coordinates, build version, last-sync time, placed for texture rather than information. Keep one only where it carries real state a reader acts on.
27
+ - **Scroll cues.** "Scroll", an animated wheel, a downward arrow with a label. A reader looking at the top of a page knows what scrolling is.
28
+ - **Decorative status dots.** A coloured dot before every nav item, list row or badge. Keep it only where it reports genuine state, and then sparingly.
29
+ - **Filler verbs.** A verb chosen for its warmth rather than for what it reports, such as `elevate`, `unleash`, `empower` or `next-generation`. Name the thing the surface does.
30
+ - **Placeholder that reads as placeholder.** Generic person names, egg avatars, invented company names of the `Acme` family, one portrait reused for several people, every item dated identically. Real collections are uneven and specific.
31
+ - **Invented precision.** A figure like 4.1x or 48k either came from real data, is marked as sample, or does not appear. There is no fourth case. Inventing a number to look engineered is the version of this that gets shipped, because it reads as confidence.
32
+ - **The fake screenshot built from boxes.** A product UI simulated out of styled rectangles inside a hero. Show the real thing, a real capture, or nothing.
33
+ - **Copy nobody re-read.** Read every visible string once as a reader rather than as its author, before handing anything over. Rewrite what is grammatically broken, what carries a pronoun with no antecedent on the page, and what reaches for charm it has not earned. Plain beats clever and wrong, which is what a model drafting copy produces by default.
34
+
35
+ ## Surface and palette
36
+
37
+ - **Glow as depth.** Outer glows and neon rims standing in for elevation. Use a border, a tint, or a real shadow with direction.
38
+ - **Pure black and pure white as grounds.** Both are harsher than nearly any surface wants. Move off the extreme.
39
+ - **Saturation everywhere.** An accent at full saturation next to neutrals that are also tinted leaves nothing to anchor on. Desaturate the neutrals and let one accent carry.
40
+ - **The gradient as a substitute for a decision.** A gradient covering a section, a heading, or a button set, applied because the flat version looked plain. Flat is usually the fix for flat composition, not gradient.
41
+ - **Uniform radius and uniform elevation.** Every card at the same radius with the same shadow flattens hierarchy. Let the thing that matters differ.
42
+
43
+ ## Typography
44
+
45
+ - **Scale as the only hierarchy.** An enormous heading over uniform body text. Weight, color, spacing and measure carry hierarchy at lower cost.
46
+ - **One family doing every job.** Pairing is not decoration. A second family, or a real weight range, separates roles that scale alone cannot.
47
+ - **Unbounded measure.** Body text running the full width of a wide container. Cap the line length.
48
+ - **Caps and letter-spacing as a texture.** Small caps with wide tracking on every label reads as a template. Use it where the label is genuinely a different kind of thing.
49
+
50
+ ## Motion
51
+
52
+ - **Motion nobody can justify.** Before adding any animation, say in one sentence what it communicates: hierarchy, sequence, feedback, or a state that changed. "It looked good" is not one of those. A sentence that will not come is the answer, and the animation goes.
53
+ - **The permanent loop.** Anything animating forever with no input. It costs attention on every frame and earns none back.
54
+ - **Motion on arrival for everything.** Every section fading up on scroll. Reserve entrance motion for what genuinely needs the eye.
55
+ - **Motion claimed but not present, or present but not claimed.** A surface described as restrained that animates on every scroll, or one described as fluid that sits still, has decided nothing. Ship the motion or drop the claim.
56
+ - **Motion that ignores a reduced-motion preference.** Not a taste failure at all. It is a correctness failure the `ui` governance rules own, listed here only so a motion pass does not read this catalog as the whole of what motion owes.
57
+
58
+ ## The countable limits
59
+
60
+ These are the rules with numbers, so they are checked by counting rather than by judging. Every one came out of production testing by people shipping model-drafted pages.
61
+
62
+ - **A layout family appears once.** Once a section uses a shape, no other section on the surface uses it. Eight sections need at least four distinct families.
63
+ - **Two consecutive splits, never three.** Alternating image-left and image-right reads as considered twice and as filler by the third. Break it with a full-width section, a vertical stack, a grid, or anything else.
64
+ - **One small uppercase label per three sections.** The tiny wide-tracked line above a heading is the single most over-reached default in model output. Count them: more than `ceil(sections / 3)` is too many, and the first screen counts as one. The fix is usually to delete it, since a section's position already says what it is.
65
+ - **One marquee.** Two sliding strips on one surface read as filler rather than as a device.
66
+ - **Cells equal items.** A grid with a hole in it, or a blank tile at the end, means the grid was shaped before the content was counted. Reshape it.
67
+ - **Over five items wants a different component.** A longer list is the lazy answer. Group into clusters, split into columns, give each item a card, make them scrollable, or collapse the tail behind a disclosure.
68
+
69
+ ## The first screen
70
+
71
+ - **It fits.** The point and the primary action are both visible without scrolling. If the copy will not fit, the copy is too long or the type is too large, and the second is the more common cause.
72
+ - **At most four text elements.** A label or a brand strip, a headline, a short supporting line, and the actions. That is the whole budget.
73
+ - **Everything else moves down.** A small tagline under the actions, a trust strip, a pricing hint, a feature list, a row of faces. Each of those is a section of its own below, not a fifth element above.
74
+ - **Plan the type scale against the asset.** A headline wrapping to four lines is a size error rather than a length error.
75
+ - **Logos go under it, never inside it.** A credibility row shares no space with the point.
76
+
77
+ ## Adopted, declined, and why
78
+
79
+ External catalogs were read and filtered rather than imported. This section is the record, and a later session extends it rather than re-deriving it.
80
+
81
+ ### Adopted
82
+
83
+ **Adopted with no change.** The three equal cards, the centered hero over a wash, enumerated eyebrows, scroll cues, decorative status dots, atmospheric strips, the fake screenshot built from boxes, filler verbs, and placeholder that reads as placeholder. Each names a shape, each carries a replacement, and none depends on a stack.
84
+
85
+ **Adopted with the stack removed.** Source items naming an icon set, a component library, a font by name, or an animation package were rewritten to state what the rule is about. "Do not use Inter" became one family doing every job, since the defensible claim is about pairing and role separation rather than about one typeface.
86
+
87
+ ### Declined
88
+
89
+ **Banned fonts by name.** A font ban is a value ban, and a value belongs to the project's own design document rather than to a skill that loads everywhere. A project that wants a typeface ruled out rules it out there.
90
+
91
+ **Numeric intensity dials.** Every external source carries a 1-to-10 scale for variance, motion and density. A session picks a middle value and reports compliance. That satisfies the rule, decides nothing, and leaves no trace a later reader could check it by. The declared read carries the same information in a sentence somebody can argue with.
92
+
93
+ **The em dash ban as a design rule.** One source bans the character on a page as a visual tell. The markdown standard already bans it for prose reasons and `canon markdown audit` gates that from package data, so restating it here would put a second copy of an enforced rule behind an unenforced pointer.
94
+
95
+ **The official-package map.** A table routing a brief to Fluent, Material, Carbon, Polaris, Primer or a government design system. It is real advice and it is a stack decision a project takes once, so it belongs in that project's own records rather than in a skill that loads on every design round.
96
+
97
+ **Scoping out application UI.** The largest source covers landing pages, portfolios and redesigns, and excludes dashboards, data tables and multi-step product UI. Those exclusions are most of what software projects actually build, so the kinds reference carries application UI as a first-class kind.
98
+
99
+ ### Carried as a caution
100
+
101
+ **Greeking.** Placeholder text is correct while judging space and wrong once an arm is judged on content, since real copy length is what breaks a composition. State which of the two a set is doing.
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: Design vocabulary
3
+ description: The layer, property, pattern and process terms this skill uses, so an operator and a session name the same thing the same way
4
+ ---
5
+
6
+ # Design vocabulary
7
+
8
+ Terms used by `design-taste` and by the skills it is loaded alongside. It changes when a design round needs a name it cannot look up here.
9
+
10
+ This glossary departs from one rule in `glossary.md`: an entry does not name where the term first appears. The material is five short files a reader can scan, so a location per entry costs more than it returns.
11
+
12
+ Every other rule there holds, and the one deciding membership holds strictly. A term appears here once this skill's own material uses it, never ahead of that, and the section below records what was considered and left out.
13
+
14
+ ## Layers
15
+
16
+ Ordered by when each settles, not alphabetically, since the order is the content. Everything below is alphabetical within its group.
17
+
18
+ - **Content**: what is actually present and what it says. Settles first, because every layer above it is arranging something.
19
+ - **Composition**: which sections a surface carries, in what order, at what relative weight. Avoid "structure", which names the same thing in the five-plane model and is used here only for that model.
20
+ - **Layout**: how one section divides its own space, meaning grid, columns, alignment and container width.
21
+ - **Space**: rhythm and proximity, deciding what reads as grouped with what. Avoid "spacing", which names the token scale rather than the decision.
22
+ - **Typography**: scale, weight, measure, casing and pairing.
23
+ - **Surface**: elevation, border, radius and fill. The same word commonly names a place content is published to, so say "the surface layer" wherever both readings are in reach.
24
+ - **Palette**: ground, accent, saturation and contrast. The values themselves live in the project's design document, never here.
25
+ - **Imagery**: what a picture carries and where it sits.
26
+ - **Motion**: what moves, why, and how far.
27
+
28
+ ## Properties
29
+
30
+ - **Casing**: whether text is set upper, lower, title or sentence case, treated as a hierarchy decision rather than a typing one.
31
+ - **Density**: how much information a given area carries. High density is correct in an application surface and reads as clutter on a marketing one, which is why it belongs to the kind rather than to taste.
32
+ - **Hierarchy**: the order a reader takes things in, produced by weight, color, space and position together rather than by size alone.
33
+ - **Ground**: the surface a thing sits on, whether the page behind everything or the fill behind one element. Named apart from "background" because the relationship that matters is what sits against it.
34
+ - **Line height**: the vertical distance from one baseline to the next, set against size rather than fixed across a scale. Avoid "leading", which names the same thing.
35
+ - **Measure**: the length of a line of text, capped so the eye finds the next line.
36
+ - **Orphan**: a single word left alone on the last line of a heading or paragraph.
37
+ - **Scale**: the fixed set of sizes a surface draws from, for type or space.
38
+ - **Tabular figures**: numerals drawn to one shared width, so a column of changing numbers does not shift as it updates.
39
+ - **Tracking**: the letter spacing applied across a run of text, set by size rather than by taste.
40
+
41
+ ## Patterns
42
+
43
+ Named compositions, carried so an operator can ask for one by name instead of describing it. A pattern earns an entry once this skill's own material names it, never ahead of that.
44
+
45
+ - **Chrome**: the persistent frame around content, being navigation, status and context, which is read constantly and looked at rarely.
46
+ - **Eyebrow**: the small wide-tracked label sitting above a heading, usually uppercase. The term matters because the budget is countable: no more than one per three sections.
47
+ - **Hairline**: a rule thin enough to separate without dividing, used where a border would read as a box.
48
+ - **Marquee**: a strip of content sliding horizontally on a loop, independent of the reader's scroll.
49
+ - **Scrollspy**: a persistent index marking which section the reader is currently in as they scroll.
50
+
51
+ ## Process terms
52
+
53
+ How a draft is staged while unfinished.
54
+
55
+ - **FPO**: a placeholder held at the true final size and marked as a placeholder, from print production where it abbreviates "for position only". Marking it is the point, since an unmarked stand-in gets read as a decision.
56
+ - **Greeking**: standing text in for copy that does not exist yet, of which lorem ipsum is the common form. Correct while judging space and wrong once an arm is judged on content.
57
+ - **Grey-box**: drawing every element as a flat neutral block so the layers above the one under judgment are removed from view. Avoid "wireframe", which names a committed document governed by `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md` rather than a drafting stage.
58
+
59
+ ## Terms this vocabulary deliberately does not carry
60
+
61
+ - **Magic number**: an unexplained hardcoded value. The term already means that in code, so it is not redefined here as a design term.
62
+ - **Glyph**: a single rendered character. A typographic unit rather than a pattern, and nothing here needs the word.
@@ -25,13 +25,19 @@ Without this skill, a session facing a decision nobody can settle from a diff:
25
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
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
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
+ - 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.
28
32
 
29
33
  ## Must
30
34
 
31
35
  - Produce three to five arms with the shipping state among them, each carrying an id, a label, and what the arm costs.
32
36
  - Author the whole candidate set as one self-contained page and render it once, so the comparison arrives as one image, except where the surface under decision is a running app: there the page links a copy of the built stylesheet rather than inlining it, per `references/live-arms.md`.
33
- - Name the layer the decision lives at before drafting, and vary the arms at that layer alone, so the answer names the difference that decided it rather than the cheapest one to change.
34
- - Render every arm in one theme at a time, with a control that sets the whole set, so the comparison holds still while the operator reads it.
37
+ - 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.
38
+ - 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.
39
+ - Render every arm in one theme at a time, with a control that sets the whole set, so the comparison holds still while the operator reads it, and set the theme in a way that survives an arm reading its own stored preference back on load.
40
+ - Hand over the per-arm file addresses beside the combined page where the declared layer is composition, layout or space, since only a whole-page file at a real viewport answers how an arm behaves at a width, and the browser's own device toolbar is the control.
35
41
  - 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.
36
42
  - Write each iteration to its own folder rather than narrowing the previous one in place, so every earlier round stays openable.
37
43
  - 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.
@@ -15,11 +15,12 @@ Some decisions are settled by looking rather than by reasoning, and no draft is
15
15
 
16
16
  ## Step 1: name the decision and the arms
17
17
 
18
- 1. State the decision in one sentence, naming what changes between arms and what stays fixed. Name the layer that sentence puts the decision at, and check that the arms will differ there rather than somewhere cheaper to change.
19
- 2. Derive a kebab slug from that sentence. Call the folder every file this run writes to `<dest>` below. `<dest>` is `.canon/tmp/<slug>/`, a nested `<slug>/` folder rather than a flat `<slug>-<file>.md`, which is the shape every temporary write in this project takes. Running inside a live `plan-groundwork` track is the one exception: `<dest>` is the track's own `evidence/<slug>/` instead, since a candidate render is evidence the track's decision file cites rather than spike input.
20
- 3. 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.
21
- 4. 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`.
22
- 5. 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.
18
+ 1. State the decision in one sentence, naming what changes between arms and what stays fixed.
19
+ 2. Emit the design read in the run's own output, in the form `design-taste` fixes. The layer comes from that skill's ordered catalog rather than from a word invented here, and the arms differ at it rather than somewhere cheaper to change. A run emitting no read has not decided what it is drafting, and a missing line is visible where an unstated layer is not.
20
+ 3. Derive a kebab slug from that sentence. Call the folder every file this run writes to `<dest>` below. `<dest>` is `.canon/tmp/<slug>/`, a nested `<slug>/` folder rather than a flat `<slug>-<file>.md`, which is the shape every temporary write in this project takes. Running inside a live `plan-groundwork` track is the one exception: `<dest>` is the track's own `evidence/<slug>/` instead, since a candidate render is evidence the track's decision file cites rather than spike input.
21
+ 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.
22
+ 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`.
23
+ 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.
23
24
 
24
25
  ## Step 2: author the candidate set as one page
25
26
 
@@ -29,10 +30,16 @@ Write every arm side by side on one self-contained HTML page at `<dest>/candidat
29
30
  - Wrap each arm's markup in the same class on both files, chosen once per run and reused everywhere, so one selector addresses an arm on the combined page and on its own standalone file alike.
30
31
  - Label each arm on the page with its id and its cost, so the render carries what the question will ask about.
31
32
  - Give the combined page one control that sets every arm's theme at once, beside whatever per-arm control the arms carry. A set spanning both themes cannot be compared, since the operator has to toggle each arm and hold the earlier ones in memory, which is the failure the single-page rule exists to prevent.
33
+ - Set that theme so it survives the arm reading its own preference back. An arm that stores a theme and applies it on load will overwrite whatever the control set, which shows the control in one state and the arm in the other, and it passes a fresh browser profile because the stored value is not there yet.
34
+ - Hand over the per-arm file addresses beside the combined page where the declared layer is composition, layout or space, and say that an arm is judged at a width by opening its own file in the browser's device toolbar. The combined page cannot answer that question at all: every arm sits in a column there while the media queries answer to the whole window, so each one renders its widest layout in a narrow space no matter how the window is sized. Build no width control of your own, since the browser already has one.
32
35
  - Take the live-app branch instead when the surface under decision is a running app: lift the rendered markup and link a copy of the built stylesheet rather than inlining, per `${CLAUDE_SKILL_DIR}/references/live-arms.md`.
33
36
  - On the default path, inline every style, script, and asset the page needs. The render reads the file off disk, so a page reaching for a build step or a network font renders without it and the arms differ by something nobody chose.
34
37
  - On the default path, declare a font stack the machine resolves, such as `system-ui` behind a generic fallback. The render refuses a page that would rewrap against a substitute rather than shipping a false comparison, so a page naming no font at all is refused on whatever the default resolves to.
38
+
39
+ ### What varies
40
+
35
41
  - Vary one property across the arms. A page whose arms differ in three ways answers no question, since the pick cannot say which difference decided it.
42
+ - Grey-box the arms when the declared layer sits below typography, per `design-taste`. A set judged at composition that carries a finished palette is not grey-boxed, and the higher layers are what the operator will look at instead of the question. Say the set is grey-boxed when handing it over.
36
43
  - Vary the property the decision is about, which the rule above is satisfiable without. Holding composition fixed and varying color obeys it exactly and produces five skins of one design, because a set differing in the layer a reader notices least answers nothing. A palette is chosen to serve a composition, so it cannot be picked ahead of one.
37
44
 
38
45
  ## Step 3: render and hand off
@@ -96,6 +103,7 @@ Three rules no probe reaches:
96
103
  Cite these rather than restating them. A step reimplemented here rots against the skill that owns it.
97
104
 
98
105
  - `plan-feature` plans the work once the pick is made, and declares the pull request boundary that plan carries
106
+ - `design-taste` carries the layer catalog, the ordering, grey-boxing, and the defaults an arm should reach past
99
107
  - `write-human` carries the voice for any copy an arm puts in front of a reader
100
108
  - `git-stage`, `git-pr`, and `git-followup` carry the commits and the pull request
101
109
  - `review-branch` and `review-address` run the review pass
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: draft-ready
3
+ description: Why writing a ready folder, its overview, the thin plan, and the task row is one invocation rather than four hand writes, and where the boundary against the planning and shipping skills falls
4
+ ---
5
+
6
+ # Draft ready requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session holding finished files that hands them to a worker:
11
+
12
+ - Writes the folder, the overview, the plan, and the task row as four separate hand writes, and the four drift from each other because nothing compares them.
13
+ - Lists a destination in the overview that the plan's `**Files to touch:**` omits, or the reverse. The omitted path is invisible to `plan-reach`, so a second track writes the same file and neither side finds out.
14
+ - Picks the next ordinal by reading only the live folder, and reuses a number an archived folder already spent, which the pull request that shipped it cites by name.
15
+ - Picks a phase label by scanning the live board alone, which is the scan that let two sessions hand out one label within minutes of each other.
16
+ - Leaves the plan's `**Constraints:**` without a line naming the folder as the verbatim source, so the worker reads the files as inspiration and writes its own version.
17
+ - Leaves a note, an alternate, or a draft passage in the folder beside the real files, so the worker guesses which one is the source.
18
+ - Writes into the main worktree root from a linked worktree with `Edit` or `Write`, which the isolation guard refuses, and takes the refusal's redirect into a second gitignored copy no later session reads.
19
+ - Reports the handoff as done while the archive move at the end, which no verb performs, is left for someone to remember.
20
+
21
+ ## Must
22
+
23
+ - Refuse before writing when the operator has named no finished file, since a folder assembled from a description is a plan with extra steps.
24
+ - Read the ordinal from the live folder and its archive together, so a spent number is never reused.
25
+ - Take the phase label from `canon tasks next-label` rather than from a scan of its own.
26
+ - Derive the overview's `destinations` and the plan's `**Files to touch:**` from one list, and compare the two before reporting, so neither can name a path the other lacks.
27
+ - Write the plan's `**Constraints:**` line naming the folder as the verbatim source.
28
+ - Copy each finished file whole to its destination path inside the folder, and carry nothing else into it.
29
+ - Write the plan and the task through `canon tasks plan-link`, `canon records validate plans`, and `canon markdown audit` rather than by restating what those verbs check.
30
+ - Place the task's row by the three branches `task-board` Step 4 states, so a solo project never ends with a task file on no surface.
31
+ - Route a write at the main root from a linked worktree through `Bash`, per `085-worktrees.md`.
32
+ - Name the archive move in the closing report, since the skill writes a folder that stays live until someone moves it.
33
+
34
+ ## Must not
35
+
36
+ - Edit a finished file. The worker copies verbatim, so a change made here is a change the warm session should have made before invoking the skill.
37
+ - Hardcode a branch type, which `branch.md` owns, or restate the folder shape, which `ready.md` owns.
38
+ - Write `priority.md` or `backlog.md` where an orchestrator is on the roster or the session is a worker or planner, since one board writer at a time is what keeps a gitignored board safe. Those two cases report the row instead.
39
+ - Automate the archive move. No verb owns the relocation, and a skill doing it by hand would be the second copy of a step the standard already states.
40
+ - Dispatch or start the worker, which belongs to whoever runs the board.
41
+
42
+ ## Guards
43
+
44
+ - No finished file named, stop: `❌ No finished file named. A ready folder carries text that already exists, so write the files first or use /canon:plan-feature.`
45
+ - A named file that does not resolve, stop: `❌ <path> does not exist. Name a file that is already written.`
46
+
47
+ ## Out of scope
48
+
49
+ - `plan-feature` writes a plan describing a change nobody has written yet. This begins from text already written and writes a plan thin enough to point at it.
50
+ - `role-worker` copies the folder into a worktree and ships it. This stops once the three artifacts exist.
51
+ - `task-board` creates a task file for a row with no ready folder. This writes the row it needs beside the folder and calls the same verbs.
52
+ - `git-ship` ships a branch, and a ready folder never reaches one.
53
+ - `standards/ready.md` owns the folder's shape and lifecycle, and this skill owns the procedure that produces it, the way `write-human` and `500-prose` split.
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: draft-ready
3
+ description: Writes a ready folder for finished files, its `00-overview.md`, the thin plan that points at it, and the task with a board row placed, reported to an orchestrator, or left to the operator, in one invocation. Use when asked to "write a ready folder", "hand these files to a worker", "package these finished files for a worker", "make a ready handoff", or when a session already holds the exact text of a skill, rule, or doc and a worker should copy it rather than author it. Do NOT use to plan a change nobody has written yet, which is `plan-feature`, to copy a folder into a worktree and ship it, which is `role-worker`, or to file a task with no finished files behind it, which is `task-board`.
4
+ ---
5
+
6
+ # Draft ready
7
+
8
+ A warm session that has already written a change hands the exact text to the worker that ships it. This skill writes the three artifacts that handoff needs and stops before anyone is dispatched.
9
+
10
+ Read these in parallel before writing:
11
+
12
+ - `${CLAUDE_SKILL_DIR}/../../standards/ready.md`: the folder layout, the overview frontmatter, the mirrored tree, and the thin-plan contract
13
+ - `${CLAUDE_SKILL_DIR}/../../standards/plan.md`: the plan's sections and its answer contract
14
+ - `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`: the task file's shape and origin lines
15
+ - `${CLAUDE_SKILL_DIR}/references/assembly.md`: the overview and thin-plan templates and the destination match check
16
+
17
+ ## Guards
18
+
19
+ - If the operator named no finished file, stop: `❌ No finished file named. A ready folder carries text that already exists, so write the files first or use /canon:plan-feature.`
20
+ - If a named file does not resolve, stop: `❌ <path> does not exist. Name a file that is already written.`
21
+ - Resolve `<main-root>` as `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. The folder, the plan, and the task all live there.
22
+
23
+ ## Step 1: read the finished files
24
+
25
+ 1. Take each finished file with the destination path the operator gave it. A file arriving with no destination is asked for once, since the mirrored tree cannot place it.
26
+ 2. Read every file whole. The overview states what the worker still owns beyond copying, and that comes off the files, not off the operator's description of them.
27
+ 3. Take the branch type from `${CLAUDE_SKILL_DIR}/../../standards/branch.md`, never from a list carried here.
28
+ 4. Derive one kebab slug for the change. The folder, the plan, and the task all carry it.
29
+
30
+ ## Step 2: allocate the ordinal and the label
31
+
32
+ Read `<main-root>/.canon/ready/` and `<main-root>/.canon/ready/archive/` together and take the highest `<nn>` across both, plus one. A folder set with no entry takes `01`. Keep this skill-local. No verb allocates a ready ordinal, and two writers running at once can claim one number, so re-read the folder immediately before Step 3 writes.
33
+
34
+ Take the label from the verb rather than from a scan:
35
+
36
+ ```bash
37
+ canon tasks next-label --json
38
+ ```
39
+
40
+ Branch on the record's `label` rather than on the exit code. Report the verb as unavailable and stop when the installed binary carries no `next-label` subcommand, since a label picked by hand is the collision the verb exists to prevent.
41
+
42
+ ## Step 3: write the overview
43
+
44
+ Write `<main-root>/.canon/ready/<nn>-<slug>/00-overview.md` from the template in `${CLAUDE_SKILL_DIR}/references/assembly.md`. Set `destinations` from the Step 1 list and nothing else, and state in prose what the worker still owns, or `nothing further` where the files are the whole change.
45
+
46
+ ## Step 4: mirror the tree
47
+
48
+ Copy each finished file to `<main-root>/.canon/ready/<nn>-<slug>/<destination path>`, one command per file, so the tree mirrors the destinations exactly.
49
+
50
+ ```bash
51
+ install -D -m 0644 <source> <main-root>/.canon/ready/<nn>-<slug>/<destination path>
52
+ ```
53
+
54
+ - Copy whole and edit nothing. A change wanted now is made in the source file first and copied after.
55
+ - Carry no notes, alternates, or drafts into the folder. Anything else belongs in the plan or the pull request body.
56
+ - Write each of these at the main root through `Bash`, one plain command apiece. From a linked worktree `Edit` and `Write` are refused there, and the refusal's redirect names a second gitignored copy no later session reads, per `085-worktrees.md`. Create a whole new file with a heredoc.
57
+
58
+ ## Step 5: write the thin plan
59
+
60
+ Write `<main-root>/.canon/plans/feature-<slug>.md` from the template, by heredoc, per `${CLAUDE_SKILL_DIR}/../../standards/plan.md`.
61
+
62
+ - List every Step 1 destination under `**Files to touch:**`, each with one clause on why it changes, pointing at the folder's copy rather than restating it.
63
+ - Add a `**Constraints:**` line naming the ready folder as the verbatim source for those paths.
64
+ - Name the branch type from Step 1 in `## Summary`. Write `None identified.` under `**Questions:**` unless a call is genuinely the operator's.
65
+
66
+ Run the match check in `${CLAUDE_SKILL_DIR}/references/assembly.md` before going further. The two lists are one list, and a path in either without the other stops the run.
67
+
68
+ ## Step 6: write the task
69
+
70
+ Write `<main-root>/.canon/tasks/<label>-<slug>.md` by heredoc, from the label Step 2 read. Its frontmatter, H1, and `## Outcomes` follow `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`. Write a `Ready:` line beside the `Plan:` line pointing at the folder, then point the task at the plan through the verb:
71
+
72
+ ```bash
73
+ canon tasks plan-link <task-stem> .canon/plans/feature-<slug>.md --json
74
+ ```
75
+
76
+ Branch on the record rather than on the exit. `Ready:` is defined nowhere yet, so the line orients a worker reading the task and no check reads it.
77
+
78
+ A task file with no row is a dropped task, so place the row in the same pass. The plan exists, so the row takes `## Run now` when `canon tasks plan-reach` reports nothing claimed and `## Up next` otherwise, with the held path in its `Waiting on` cell, per the tests in `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`. Check the roster the way `canon:task-board` Step 4 does, reading `canon sessions list --self --json` for this session and `canon sessions list --json` for a row from the same repository, under another `sessionId`, whose `name` starts with `orchestrator-`. Treat a refused read as a roster read that failed.
79
+
80
+ - **Orchestrator found.** Write neither file. Message that session with the row's title, the plan link, and the group with its reason, so it places the row itself rather than two sessions writing the board at once.
81
+ - **Not found, and this session's name starts with `worker-` or `planner-`.** Write neither file, since both role bodies ban a board write with no exception. Report the row and its group in Step 8.
82
+ - **Not found otherwise, or the roster read fails.** Write the row into `priority.md` through the same `Bash` route the task file took. A failed read looks like a solo project, and stopping would strand the task on the one path with nobody to place it.
83
+
84
+ Say which branch fired in Step 8.
85
+
86
+ Regenerate the task index after writing, since a hook on `Write|Edit` never fires on `Bash`:
87
+
88
+ ```bash
89
+ canon indexes regen .canon/tasks
90
+ ```
91
+
92
+ ## Step 7: validate
93
+
94
+ ```bash
95
+ canon records validate plans --json
96
+ canon markdown audit <main-root>/.canon/ready/<nn>-<slug>/00-overview.md
97
+ canon markdown audit <main-root>/.canon/plans/feature-<slug>.md
98
+ ```
99
+
100
+ Fix what the records name in the files this run wrote and re-run once. Report a finding on a file it did not write, such as a neighbor folder missing its overview, without repairing it.
101
+
102
+ ## Step 8: report
103
+
104
+ ```plaintext
105
+ ✅ Ready folder written: .canon/ready/<nn>-<slug>/
106
+ Plan: .canon/plans/feature-<slug>.md
107
+ Task: .canon/tasks/<label>-<slug>.md
108
+ Row: <label> <title>, <written under ## Run now | reported to <orchestrator name> | left for the operator to place>, <reason>
109
+ Archive on ship: move the folder to .canon/ready/archive/<nn>-<slug>/ by hand, then retarget the task's Ready: line
110
+ ```
111
+
112
+ Name the archive move every time. `canon tasks archive` moves the task and its plan and leaves the folder live, so the move is the one step this run leaves for whoever ships.
113
+
114
+ ## Rules
115
+
116
+ - Edit no finished file. The worker copies verbatim, so a change belongs in the source before this runs.
117
+ - Restate nothing the standards own. A shape question is answered by `ready.md` and a plan question by `plan.md`.
118
+ - Dispatch nothing. Starting the worker belongs to whoever runs the board.
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: assembly
3
+ description: The overview and thin-plan templates for a ready folder, and the match check between the two lists of destinations
4
+ ---
5
+
6
+ # Assembly
7
+
8
+ Loaded from Step 3 and Step 5 of `draft-ready`. The shape rules live in `${CLAUDE_SKILL_DIR}/../../standards/ready.md` and `${CLAUDE_SKILL_DIR}/../../standards/plan.md`, so this file holds the fill-in forms and the one check that compares them.
9
+
10
+ ## The overview
11
+
12
+ ```markdown
13
+ ---
14
+ title: <Change in sentence case>
15
+ description: <one line naming what the handoff carries>
16
+ type: <branch type from branch.md>
17
+ destinations:
18
+ - <path/to/file>
19
+ ---
20
+
21
+ <What the files carry, one bullet each where a file's purpose is not its name.>
22
+
23
+ <What the worker still owns beyond copying, or "nothing further".>
24
+ ```
25
+
26
+ - Write `destinations` from the Step 1 list in the order the plan will list them.
27
+ - Keep the prose to what the files cannot say themselves, such as a docs sync, a sandbox scenario, a test the folder does not carry, or the order a change lands in.
28
+
29
+ ## The thin plan
30
+
31
+ ```markdown
32
+ # Feature: <short title>
33
+
34
+ <Two or three sentences on why this ships as a copy rather than as an authoring job.>
35
+
36
+ ## Summary
37
+
38
+ - <what the change does, one bullet per file group>
39
+ - <branch type and what the worker still owns>
40
+
41
+ **Constraints:**
42
+
43
+ - `.canon/ready/<nn>-<slug>/` holds the verbatim source for every path below. Copy each file whole rather than reading it as a description and writing a version.
44
+ - <a live plan or run row holding a path, when one exists>
45
+
46
+ **Files to touch:**
47
+
48
+ - `<path/to/file>`: copy from the ready folder, <one clause on what it changes>
49
+
50
+ **Risks:**
51
+
52
+ - <what could go wrong, or "None identified.">
53
+
54
+ **Questions:**
55
+
56
+ None identified.
57
+ ```
58
+
59
+ ## The destination match check
60
+
61
+ Read the overview's `destinations` and the plan's `**Files to touch:**` paths, then compare the two sets:
62
+
63
+ - A path in `destinations` and not in the plan is invisible to `plan-reach`, so the plan gains the line.
64
+ - A path in the plan and not in `destinations` names a file the folder does not carry, so either the folder gains the file or the plan loses the line.
65
+ - A path in either list with no file at that relative path inside the folder is a broken mirror. Report it and stop rather than writing a plan around a hole.
66
+
67
+ Report the sets as equal, or name each path that differs and on which side. Do not report the check as passed without having read both lists.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: session-compact
3
+ description: Why a plain session needs a handoff surface that is not the task board
4
+ ---
5
+
6
+ # Session compact requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session facing a compaction reaches for `session-map`, which writes `.canon/tasks/session-<slug>.md`. The board carries four such files today, and `session-resume` drops them by name prefix to read the real rows, so a reader works around a misplacement on every run.
11
+
12
+ `session-map` also carries the orchestrator's shape: a drift check against a start commit nothing records, a step for role sections, and a `## State` section. A session that shipped nothing pays all three to leave one note behind, and `standards/session.md` already names a `## State` filled from the tree as non-conforming, which is the failure that shape invites.
13
+
14
+ Sessions also write the wrong thing into a handoff. They restate the tree, which survives a compaction, and omit what each decision beat, which does not.
15
+
16
+ ## Must
17
+
18
+ - Write to `.canon/compact/`, outside the task board and outside scratch.
19
+ - Invoke `canon:memory-capture` before writing, so the note cites entries rather than repeating them.
20
+ - Carry a stated shape for the note, so what belongs in it is not re-derived per session.
21
+ - Require a citation for every claim, and a rejected alternative beside every decision.
22
+ - Decline in one line where the session holds nothing a compaction would destroy.
23
+
24
+ ## Must not
25
+
26
+ - Write a task row, a plan, or anything under `.canon/tasks/`.
27
+ - Write a `## State` section, or any section a reader could fill from `git status`.
28
+ - Run a drift check or recover a start commit. Both belong to the role that ships code.
29
+ - Restate a memory entry the capture pass wrote.
30
+ - Lose its caller. The `PreCompact` hook names this skill on a manual compaction, and that hook plus an operator typing it are the two callers the third creation question asks for. A hook edit that names another skill leaves one caller, which is a reason to revisit this skill rather than to keep it.
31
+
32
+ ## Guards
33
+
34
+ - No repository is required. The slug comes from the work, so a session outside git still writes a note.
35
+ - `.canon/` resolves at the main worktree root. From a linked worktree the write goes through the shell, since the file-editing tools refuse that path.
36
+ - Decline rather than pad. A note a reader finds is a note a reader trusts.
37
+ - The note is backed up by `canon records push`, which carries every top-level `.canon/` folder, and the push is a run someone makes. Until it runs, or where no remote is configured, the note sits on one disk. The skill's report does not say so, since it would restate a run the operator owns on every note.
38
+
39
+ ## Out of scope
40
+
41
+ - The orchestrator's handoff, which carries a drift check and a board row: `canon:session-map`. The two skills are held apart by role, so a plain session belongs here and a session holding `canon:role-orchestrator` belongs there.
42
+ - Reading a handoff back: `canon:session-resume`, which reads `.canon/compact/` ahead of the older task-board form.
43
+ - The memory pen, its routing and its shape: `canon:memory-capture` and `standards/memory.md`.
44
+ - A decision a groundwork track owns, which belongs in that track's `06-decision.md`: `canon:plan-groundwork`.
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: session-compact
3
+ description: Captures a session's memory, then writes one handoff note to .canon/compact/ so the session after a compaction picks up where this one stopped. Use before running /compact, when asked to "write a handoff", "prepare for compaction", "save where we got to", or when a PreCompact hook blocks and names this skill. Do NOT use for a session holding the orchestrator role, whose board handoff is `session-map`. Do NOT use to record a decision a groundwork track owns, which is `plan-groundwork`.
4
+ ---
5
+
6
+ # Session compact
7
+
8
+ A compaction keeps conclusions and drops the reasoning that produced them. This writes the reasoning down first, in one file, outside the task board.
9
+
10
+ Write only what a compaction destroys. Everything a later session can read from git, from the tree, or from a durable record is already safe, and restating it is what makes a handoff untrustworthy rather than long.
11
+
12
+ ## Guards
13
+
14
+ - If `git rev-parse --git-dir` does not resolve, the note still writes. The filename comes from the work rather than from the branch, so nothing here needs a repository.
15
+ - Decline where the session holds no reasoning a reader could not get faster from git or from a record already written. Say so in one line and write nothing. A padded note is worse than an absent one, because a reader who finds a note trusts it.
16
+ - Resolve `.canon/` at the main worktree root, the way `session-worktree` does. From a linked worktree the file-editing tools refuse that path, so the write goes out through `Bash` as one plain command carrying a heredoc.
17
+
18
+ ## Step 1: capture memory
19
+
20
+ Invoke `canon:memory-capture` and let it return before writing. The note then cites what was written rather than restating the same lesson in prose.
21
+
22
+ State the caveat the caller gives about committing. A caller that does not commit says so, and capture skips routing and writes memory files alone.
23
+
24
+ Carry through the line capture returns when a fact routed, so the session knows a fold is still owed. Report nothing else about what it wrote.
25
+
26
+ ## Step 2: write the note
27
+
28
+ Write one file to `.canon/compact/<slug>.md`. Name `<slug>` for the work as a short kebab-case phrase, taken from what the session did rather than from the branch, so a session that ran on `main` still gets a name a reader recognizes. Use `latest` when nothing in the session names the work.
29
+
30
+ Follow `${CLAUDE_SKILL_DIR}/references/handoff-note.md` for what each section carries and what stays out. Read it before drafting rather than working the shape from memory.
31
+
32
+ Overwrite a note of the same name. One session's work has one note, and a second file for the same work splits the handoff.
33
+
34
+ ## Step 3: report
35
+
36
+ ```plaintext
37
+ ✅ Handoff written: .canon/compact/<slug>.md
38
+ <the line memory-capture returned, where a fact routed>
39
+ ```
40
+
41
+ A decline reports itself so a caller can tell it from a failure:
42
+
43
+ ```plaintext
44
+ ✅ No handoff. <what the session holds that git does not, and why it is nothing>
45
+ ```
46
+
47
+ ## Rules
48
+
49
+ - Cite a file, a commit, or a record for every claim. A handoff no reader can check is a story.
50
+ - Name what was decided together with what it beat. A decision with no rejected alternative reads as arbitrary and gets reopened.
51
+ - Write `## Where to pick up` as one instruction, not a menu. A reader who has to choose has not been handed off to.
52
+ - Leave the task board alone. A task is work somebody filed, and a handoff is context for one reader.
53
+ - Do not write a `## State` section. A session that committed nothing has no state a reader could not get from `git status` faster, and one that did has it in the log.
54
+
55
+ ## What this delegates
56
+
57
+ - The memory pass, its routing, and the pen's shape: `canon:memory-capture`
58
+ - The orchestrator's handoff, which carries a drift check and writes a task row: `canon:session-map`
59
+ - Reading a handoff back at the start of the next session: `canon:session-resume`
60
+ - A decision a groundwork track owns, which belongs in its own `06-decision.md`: `canon:plan-groundwork`