@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.
Files changed (133) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/backlog-triage/references/apply.md +6 -6
  3. package/claude/skills/canon-cli/SKILL.md +4 -4
  4. package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
  5. package/claude/skills/canvas-board/SKILL.md +1 -1
  6. package/claude/skills/context-fold/references/context.md +1 -1
  7. package/claude/skills/create-skill/REQUIREMENT.md +1 -1
  8. package/claude/skills/create-skill/SKILL.md +2 -2
  9. package/claude/skills/create-skill/references/skill-requirement.md +68 -9
  10. package/claude/skills/create-skill/references/skill.md +1 -1
  11. package/claude/skills/design-identity/REQUIREMENT.md +40 -0
  12. package/claude/skills/design-identity/SKILL.md +138 -0
  13. package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
  14. package/claude/skills/design-taste/REQUIREMENT.md +4 -4
  15. package/claude/skills/design-taste/SKILL.md +2 -2
  16. package/claude/skills/design-taste/references/kinds.md +1 -1
  17. package/claude/skills/design-taste/references/preflight.md +1 -1
  18. package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
  19. package/claude/skills/draft-and-pick/SKILL.md +3 -153
  20. package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
  21. package/claude/skills/draft-doc/SKILL.md +4 -76
  22. package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
  23. package/claude/skills/draft-figure/SKILL.md +3 -77
  24. package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
  25. package/claude/skills/draft-identity/SKILL.md +3 -130
  26. package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
  27. package/claude/skills/draft-ready/SKILL.md +3 -128
  28. package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
  29. package/claude/skills/draft-screencast/SKILL.md +3 -62
  30. package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
  31. package/claude/skills/draft-slides/SKILL.md +3 -72
  32. package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
  33. package/claude/skills/draw-figure/SKILL.md +85 -0
  34. package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
  35. package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
  36. package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
  37. package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
  38. package/claude/skills/make-deck/REQUIREMENT.md +44 -0
  39. package/claude/skills/make-deck/SKILL.md +80 -0
  40. package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
  41. package/claude/skills/markdown-craft/SKILL.md +2 -2
  42. package/claude/skills/pick-by-eye/REQUIREMENT.md +86 -0
  43. package/claude/skills/pick-by-eye/SKILL.md +161 -0
  44. package/claude/skills/plan-feature/SKILL.md +2 -1
  45. package/claude/skills/plan-feature/references/plan.md +24 -10
  46. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  47. package/claude/skills/plan-intake/SKILL.md +1 -1
  48. package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
  49. package/claude/skills/plan-ready/SKILL.md +136 -0
  50. package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
  51. package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
  52. package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
  53. package/claude/skills/record-screencast/SKILL.md +2 -2
  54. package/claude/skills/role-orchestrator/REQUIREMENT.md +1 -1
  55. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
  56. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
  57. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
  58. package/claude/skills/role-planner/SKILL.md +2 -1
  59. package/claude/skills/role-worker/SKILL.md +9 -0
  60. package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
  61. package/claude/skills/script-screencast/SKILL.md +70 -0
  62. package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
  63. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  64. package/claude/skills/search-craft/SKILL.md +1 -1
  65. package/claude/skills/target-setup/SKILL.md +1 -0
  66. package/claude/skills/task-board/SKILL.md +11 -9
  67. package/claude/skills/task-board/references/board.md +15 -12
  68. package/claude/skills/teach-workspace/SKILL.md +1 -1
  69. package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
  70. package/claude/skills/ui-checklist/SKILL.md +2 -0
  71. package/claude/skills/write-doc/REQUIREMENT.md +46 -0
  72. package/claude/skills/write-doc/SKILL.md +83 -0
  73. package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
  74. package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
  75. package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
  76. package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +3 -3
  77. package/docs/agents/markdown-audit.md +4 -2
  78. package/docs/agents/migrate.md +2 -2
  79. package/docs/target/migrations.md +17 -4
  80. package/docs/target/projects.md +1 -1
  81. package/docs/workflow/parallel-features.md +3 -2
  82. package/docs/workflow/skill-map-on-request.md +18 -12
  83. package/docs/workflow/skill-map.md +13 -12
  84. package/docs/workflow/visual-design-workflow.md +2 -2
  85. package/governance/ledger/framework/astro.md +73 -0
  86. package/governance/ledger/framework/fastapi.md +76 -0
  87. package/governance/ledger/framework/nextjs.md +86 -0
  88. package/governance/ledger/framework/react.md +83 -0
  89. package/governance/ledger/framework/shadcn.md +60 -0
  90. package/governance/ledger/framework/tailwind.md +55 -0
  91. package/governance/rules/framework/astro.md +12 -14
  92. package/governance/rules/framework/fastapi.md +20 -24
  93. package/governance/rules/framework/nextjs.md +19 -27
  94. package/governance/rules/framework/react.md +22 -33
  95. package/governance/rules/framework/shadcn.md +11 -15
  96. package/governance/rules/framework/tailwind.md +12 -14
  97. package/governance/rules/writing/markdown.md +1 -1
  98. package/package.json +1 -1
  99. package/src/claude/cases/authoring.ts +15 -3
  100. package/src/claude/cases/misc.ts +12 -0
  101. package/src/claude/cases/workflow.ts +19 -1
  102. package/src/claude/skills-audit.ts +113 -1
  103. package/src/commands/claude.ts +34 -11
  104. package/src/commands/demo.ts +1 -1
  105. package/src/commands/markdown.ts +1 -1
  106. package/src/commands/migrate.ts +4 -0
  107. package/src/commands/pr.ts +30 -6
  108. package/src/commands/tasks.ts +383 -2
  109. package/src/context/audit.ts +1 -1
  110. package/src/demo/beats.ts +1 -1
  111. package/src/gov/audit.ts +3 -2
  112. package/src/markdown/scope.ts +45 -35
  113. package/src/migrate/record-layout.ts +1 -1
  114. package/src/migrate/skill-names.ts +68 -21
  115. package/src/pr/frames.ts +14 -3
  116. package/src/records/validate.ts +31 -0
  117. package/src/tasks/board.ts +854 -0
  118. package/src/tasks/record.ts +20 -1
  119. package/src/tasks/validate.ts +206 -9
  120. package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
  121. package/tooling/astro/reference.md +2 -2
  122. package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
  123. package/tooling/claude/seeds/.claude/settings.json +4 -0
  124. /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
  125. /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
  126. /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
  127. /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
  128. /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
  129. /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
  130. /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
  131. /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
  132. /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
  133. /package/claude/skills/{draft-doc → write-doc}/references/wiki.md +0 -0
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: script-screencast
3
+ description: Drafts a screencast script with pre-seeded beats, defaults, and decisions to `demos/<slug>/beats.md`. Reads project context, asks four discovery questions with proposed defaults, then writes a shippable draft. Use when asked to "draft a screencast", "write a recording script", "plan a demo video", or "scaffold a screencast for X". Do NOT re-invoke to refine an existing draft. Re-running overwrites. Edit the draft file directly.
4
+ metadata:
5
+ family: generate
6
+ ---
7
+
8
+ # Script screencast
9
+
10
+ ## Guards
11
+
12
+ - If no topic is provided, stop: `❌ No screencast topic. Describe what you are recording.`
13
+ - Draft, then hand off. Do not edit video, generate captions, or drive the application, since a recording is `record-screencast`'s job. Name it as the next step and stop.
14
+ - Stack-agnostic in the draft. Never name a recording tool, an editing tool, a font, or a window manager.
15
+ - Keep selectors, URLs, wait conditions, and timings out of the beats, since the compiler adds those four in a plan of its own and a beat carrying them stops being readable
16
+
17
+ ## Step 1: read the project context
18
+
19
+ Read these in parallel from the project root, skipping any that do not exist:
20
+
21
+ - `CLAUDE.md`: behavior rules and project pitch
22
+ - `canon/REQUIREMENTS.md`: feature scope, non-goals, audience hints
23
+ - `.canon/tasks/index.md`: current scope
24
+ - Recent commits via `git log --oneline -20 2>/dev/null || echo "FALLBACK"`: what shipped recently is usually the recording subject.
25
+
26
+ ## Step 2: discovery with proposed defaults
27
+
28
+ Ask exactly four questions in chat. Each carries a proposed default derived from Step 1. The user confirms, overrides, or says "use defaults" to accept all.
29
+
30
+ ```markdown
31
+ **Discovery:**
32
+
33
+ 1. Audience: proposing technical peers. Override?
34
+ 2. Length: proposing 75-90s. Override?
35
+ 3. Hero moment: proposing <best guess from context, or "the single thing that has to land">. Override?
36
+ 4. What to cut: proposing <best guess, or "anything that is not the hero moment">. Override?
37
+ ```
38
+
39
+ Wait for answers before drafting. Do not infer silence as acceptance.
40
+
41
+ ## Step 3: derive the slug
42
+
43
+ Build a 2-to-4-word kebab-case slug from the topic and discovery answers. Examples: `auth-flow-redesign`, `cli-onboarding`, `inline-edit-launch`.
44
+
45
+ ## Step 4: write the draft
46
+
47
+ Create `demos/<slug>/beats.md` at the project root, creating the folder if it does not exist. The file is committed with the rest of the demo's sources, so a recording can be rebuilt from the folder alone.
48
+
49
+ ### Fill the template
50
+
51
+ Write all nine sections from `${CLAUDE_SKILL_DIR}/references/beats-template.md`, read on reaching this step. Pre-seed every section with concrete content so the draft ships as-is, and the user edits down rather than fills blanks. A run stopped at discovery skips it.
52
+
53
+ Load `canon:video-craft` for every zoom and caption value the draft names, and report it rather than proceeding silently when it does not resolve.
54
+
55
+ ## Step 5: output
56
+
57
+ Print the file path on its own line and a one-line summary. Do not paraphrase the path into prose.
58
+
59
+ ```markdown
60
+ 📝 Wrote demos/<slug>/beats.md
61
+
62
+ Draft has 5 beats and pre-seeded defaults. Edit the beats, the resolved decisions, and the wrap.
63
+
64
+ To record it rather than shoot it by hand:
65
+ record-screencast demos/<slug>/beats.md
66
+ ```
67
+
68
+ Name the skill and stop there. Do not compile the draft, do not run it, and do not generate captions. The operator edits the beats first, and the compiler reports which selectors and URLs they still owe it.
69
+
70
+ Say so plainly if `canon demo compile` is not available, rather than driving the application some other way. The command ships with the CLI and the skills ship with the plugin, so a project carrying one and not the other is a real state.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Beats template
3
- description: The nine-section template draft-screencast writes to demos/<slug>/beats.md, pre-seeded so the draft ships as-is
3
+ description: The nine-section template script-screencast writes to demos/<slug>/beats.md, pre-seeded so the draft ships as-is
4
4
  ---
5
5
 
6
6
  # Beats template
7
7
 
8
- Applies to the draft `draft-screencast` Step 4 writes. Fill every placeholder from the project context and the discovery answers. The template states no zoom or caption value, since each traces to a source `canon:video-craft` records.
8
+ Applies to the draft `script-screencast` Step 4 writes. Fill every placeholder from the project context and the discovery answers. The template states no zoom or caption value, since each traces to a source `canon:video-craft` records.
9
9
 
10
10
  ## Template
11
11
 
@@ -7,7 +7,7 @@ description: Why a session needs a thinking step before an outside search, deriv
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, a session reaching outside the project runs one generic `WebSearch` and takes what ranks highest. Nothing in the toolkit says how to search, and the two procedures that require an outside source, `plan-groundwork` and `draft-doc`'s wiki kind, give no route to one.
10
+ Without this skill, a session reaching outside the project runs one generic `WebSearch` and takes what ranks highest. Nothing in the toolkit says how to search, and the two procedures that require an outside source, `plan-groundwork` and `write-doc`'s wiki kind, give no route to one.
11
11
 
12
12
  The miss is measured. On 2026-10-02 two queries ran twice each with identical text, once open and once with `allowed_domains` set to authorities the session derived itself with no list to consult.
13
13
 
@@ -30,7 +30,7 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
30
30
  - Prefer a public API over a fetched and summarized page where one exists, since the API returns the dates, authors, and identifiers a citation needs
31
31
  - Carry a dated access note grown only from a failure a session hit, and stop to ask the operator before any paid or logged-in route
32
32
  - Close with the practice skill's excuses, red flags, and closing checklist, answering "the model already knows the good sites" and "one search was enough"
33
- - Be loaded from the sourcing steps of `plan-groundwork` and `draft-doc`'s wiki kind, each reporting when the skill does not resolve
33
+ - Be loaded from the sourcing steps of `plan-groundwork` and `write-doc`'s wiki kind, each reporting when the skill does not resolve
34
34
 
35
35
  ## Must not
36
36
 
@@ -42,7 +42,7 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
42
42
  ## Out of scope
43
43
 
44
44
  - The form a citation takes: the procedure or standard writing it
45
- - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `draft-doc`'s wiki sourcing step already does
45
+ - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `write-doc`'s wiki sourcing step already does
46
46
  - Image generation, which makes a picture rather than finding a source
47
47
  - Loading on every web search rather than on a research-shaped request: a hook matching `WebSearch`, planned on its own
48
48
  - Whether a session already scopes searches without the skill, which only a run on a fresh research request without it would show
@@ -54,4 +54,4 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
54
54
  - No `Skill` call fired, so the description did not route a plain research request to the body.
55
55
  - The run searched four times with no domain filter, naming authors and journals from recall, then fetched the papers' own pages. It never named the field, so the scenario's field pattern failed and the arm went red on one of its assertions.
56
56
 
57
- The arm shows the trigger is the gap rather than the body: a session that never loads the skill cannot follow it. The pointers from `plan-groundwork` and `draft-doc`'s wiki kind reach only those procedures, and the hook matching `WebSearch` is the route for every other search. One run on one model shows the miss exists and does not size it.
57
+ The arm shows the trigger is the gap rather than the body: a session that never loads the skill cannot follow it. The pointers from `plan-groundwork` and `write-doc`'s wiki kind reach only those procedures, and the hook matching `WebSearch` is the route for every other search. One run on one model shows the miss exists and does not size it.
@@ -87,6 +87,6 @@ These flags fire after the search has run.
87
87
  ## What this delegates
88
88
 
89
89
  - The form a citation takes: the surface writing it, such as the standard the procedure writes to
90
- - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `draft-doc`'s wiki sourcing step does
90
+ - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `write-doc`'s wiki sourcing step does
91
91
  - Generating an image: whatever draws the surface, since making one is not search
92
92
  - Access code a session needs repeatedly: a `canon` verb, never a script in this skill
@@ -183,6 +183,7 @@ After the chain, report as well:
183
183
  - Any domains or scripts that failed
184
184
  - Any detection gaps surfaced during resolve
185
185
  - Claude Code plugins as an onboarding step this chain does not cover, so a clean result does not read as onboarding complete
186
+ - `/canon:write-doc README.md` when the root `README.md` is missing or carries no H1 naming the project, and nothing when it is authored
186
187
 
187
188
  A resolved name and a fallback read alike once written, so the preview marks the
188
189
  fallback rather than this report. The preview is the last point before the first
@@ -67,10 +67,12 @@ Write `.canon/tasks/vXX.Y-<slug>.md` under the claimed label, reading the file f
67
67
 
68
68
  A task file with no row is a dropped task, so name its surface in the same pass that creates it. The test and both file shapes are in `${CLAUDE_SKILL_DIR}/references/board.md`.
69
69
 
70
- | Task | Surface |
71
- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
72
- | Plausibly planned within the next few waves | A row under `## Needs a plan` in `.canon/tasks/priority.md`, positioned against the rows there, with the reason in `Waiting on` |
73
- | Anything else | A line in `.canon/tasks/backlog.md`, which is unordered |
70
+ | Task | Surface |
71
+ | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | Plausibly planned within the next few waves | A row under `## Needs a plan` in `.canon/tasks/priority.md`, through `canon tasks place <stem> --group needs-a-plan --waiting "<reason>"` |
73
+ | Anything else | A line in `.canon/tasks/backlog.md`, which is unordered |
74
+
75
+ Position the row against its siblings with `--before <stem>` or `--after <stem>`, and state what it ranks against in the reason.
74
76
 
75
77
  ### Check for a live orchestrator
76
78
 
@@ -80,11 +82,11 @@ Check the roster before writing either file. Read `canon sessions list --self --
80
82
  - Its `name` starts with `orchestrator-`, the convention every hand-launched controller here uses, which excludes every `worker-` and `planner-` session
81
83
  - Treat a refusal from either call the same as a roster read that failed
82
84
 
83
- | Roster read | Act |
84
- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
85
- | **Found** | Write neither file. Report the surface and reason, and message that session so it places the row itself |
86
- | **Not found**, and this session's name starts with `worker-` or `planner-` | Write neither file, since both role bodies ban a board write. Report the row and its surface. |
87
- | **Not found otherwise**, or the read fails | Write the row directly, through the same heredoc route as the file. A failed read looks like a solo project. |
85
+ | Roster read | Act |
86
+ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
87
+ | **Found** | Write neither file. Report the surface and reason, and message that session so it places the row itself |
88
+ | **Not found**, and this session's name starts with `worker-` or `planner-` | Write neither file, since both role bodies ban a board write. Report the row and its surface. |
89
+ | **Not found otherwise**, or the read fails | Place the row through `canon tasks place`. A failed read looks like a solo project. |
88
90
 
89
91
  Say which branch fired and why in the report. A placement with no stated reason is one the next sweep re-derives from nothing.
90
92
 
@@ -70,28 +70,31 @@ Group tasks by readiness rather than by status, one row per task, under the colu
70
70
 
71
71
  Readiness is three groups under fixed headings, `## Run now`, `## Up next`, and `## Needs a plan`, in that order. A task belongs to exactly one, and the tests are read in order.
72
72
 
73
- | Group | Test |
74
- | ----------------- | -------------------------------------------------------------------------------------- |
75
- | `## Run now` | A written plan covers every open outcome, and nothing stated keeps the task from start |
76
- | `## Up next` | A written plan exists, and the `Waiting on` column names why the task cannot start |
77
- | `## Needs a plan` | Everything else. No plan, or a plan that no longer describes the work |
73
+ | Group | Test |
74
+ | ----------------- | ------------------------------------------------------------------------------------ |
75
+ | `## Run now` | A worker was dispatched on it, under a written plan covering every open outcome |
76
+ | `## Up next` | A written plan exists and no worker holds it yet, and `Waiting on` names what is due |
77
+ | `## Needs a plan` | Everything else. No plan, or a plan that no longer describes the work |
78
78
 
79
79
  The names are the contract. A board grouped by readiness under names of its own reads as empty to anything counting rows under a heading, so add no fourth group.
80
80
 
81
+ ### Writing the board
82
+
83
+ Every write goes through `canon tasks place`, `promote`, `move`, or `block`, each reading the file once, rendering the columns the template fixes, and writing it once. `plan-link` promotes a parked row the same way. Only `Waiting on` is typed, since every other cell derives from the task and its live plans.
84
+
81
85
  ### What blocks a run
82
86
 
83
87
  A collision with running work blocks a task only where no merge settles it, being a contract, a relocation, or a sweep. A shared file alone is none, since the branch merging second rebases.
84
88
 
85
- - A worker is handed a task from `## Run now` alone, and its `Touches` column states the set to read
86
- - Each group's columns follow from its test. Neither half of the `## Run now` test is checkable without the file set and the plan beside the task.
89
+ - A dispatcher picks from `## Up next` and runs `canon tasks promote` once the launch succeeds
90
+ - Each group's columns follow from its test. Neither half of the `## Up next` test is checkable without the file set and the plan beside the task.
87
91
 
88
92
  ### The `Touches` cell
89
93
 
90
- A `Touches` cell is copied from its plan's list, so it states what the branch sets out to write rather than a bound on it. A branch outgrows it while the row still reads as it did at dispatch.
94
+ A `Touches` cell is the first three paths of its plan's `**Files to touch:**` and a count of the rest, the union in line order for a sliced task. It states what the branch sets out to write, and a running branch outgrows it.
91
95
 
92
- - Once a branch runs, correct the cell from the diff rather than the plan, which is the prediction that already went stale
93
- - `canon tasks plan-reach <plan>` reads that diff against every live plan and every cell in the group
94
- - The row's owner writes the correction. A worker never edits this board.
96
+ - `canon tasks plan-reach <plan>` reads the current reach off the branch's diff
97
+ - Change the plan's list to change the cell. A worker never edits this board.
95
98
 
96
99
  ### Cell width
97
100
 
@@ -118,7 +121,7 @@ The `Waiting on` column under `## Up next` carries the reason in one of three fo
118
121
  | Sibling task | That task |
119
122
  | External condition | The condition and what would satisfy it |
120
123
 
121
- Naming what would satisfy a condition separates a blocked row from one nobody examined, so a condition with no way out fails the test. The header text is the contract, since a reader resolves the column by header rather than position.
124
+ Naming what would satisfy a condition separates a blocked row from one nobody examined, so a condition with no way out fails the test. The header text is the contract, since a reader resolves the column by header rather than position. A cell renders at most 120 characters, a link counting as its label alone, and the verbs refuse a longer one.
122
125
 
123
126
  ### The needs-a-plan cell
124
127
 
@@ -183,7 +183,7 @@ Read `${CLAUDE_SKILL_DIR}/references/promotion-fold.md` for how each block lands
183
183
  Lesson: .canon/teach/<nn>-<topic>/lessons/<nnnn>-<slug>.html
184
184
  Reference: .canon/teach/<nn>-<topic>/reference/<slug>.md
185
185
  Record: .canon/teach/<nn>-<topic>/learning-records/<nnnn>-<slug>.md
186
- Figure: <drawn through draft-figure, or the one-line reason prose carries it>
186
+ Figure: <drawn through draw-figure, or the one-line reason prose carries it>
187
187
  Progress: <n> of <m> success lines met
188
188
  Open: [<the url the serve verb reported>](<the same url>)
189
189
  ```
@@ -51,8 +51,8 @@ Every element competes with the material for attention.
51
51
  Decide the figure once per lesson, before writing the body.
52
52
 
53
53
  1. Name the one relationship, boundary, path, or before-and-after the lesson is about. A lesson about none ends here, with `Figure: none, <why it names no structure>` on the reply.
54
- 2. Hold it against the bar in `${CLAUDE_SKILL_DIR}/../draft-figure/references/figures.md`, which also carries the drawing rules.
55
- 3. Draw it through `canon:draft-figure` into a `raw` block before the quiz, never inside it or after its feedback, which breaks the stepper's gating. Report an unresolved skill rather than drawing.
54
+ 2. Hold it against the bar in `${CLAUDE_SKILL_DIR}/../draw-figure/references/figures.md`, which also carries the drawing rules.
55
+ 3. Draw it through `canon:draw-figure` into a `raw` block before the quiz, never inside it or after its feedback, which breaks the stepper's gating. Report an unresolved skill rather than drawing.
56
56
  4. Or write one line on why prose carries it better, such as a structure an earlier lesson gave.
57
57
 
58
58
  A structure lesson takes step 3 or 4, never neither. Put the outcome on the reply's `Figure:` line, off the lesson page. Never draw to satisfy the step, or on every section (`## Restraint`).
@@ -43,6 +43,8 @@ Write each box so a session driving the running app can run it without guessing:
43
43
  | Taste | End the line with `(taste)` when the result is a judgment of look or feel. A driver reports such a box as needing a person's eyes rather than passing it. |
44
44
  | Setup | State inline any setup the page does not open in. End the line with `(local only)` when a hosted preview cannot reach that state, such as a stopped service or a seeded record. |
45
45
 
46
+ When the plan cites `canon/design/<surface>/` under `**Design references:**`, name the reference as the comparison on each box for that surface, such as "→ matches `canon/design/<surface>/` in light and dark". The reviewer then judges the build against the accepted design instead of against taste.
47
+
46
48
  The checkbox stays `- [ ]` followed by the action and the result, since the evidence comment reads boxes by that shape. Only the UI reviewer ticks a box, stamping it with the commit it passed at, and the comment carries that tick forward only while the head it names is current.
47
49
 
48
50
  ## The missing-test list
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: write-doc
3
+ description: Why a brand-new project document needs its kind's standard, a catalog collision check, and a confirm step, not the rewrite and refresh paths docs-sync and context-fold already own
4
+ ---
5
+
6
+ # Write doc requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session drafting a document that has no prior version either invents a shape from memory or reaches for a rewrite or refresh surface. `docs-sync` and `context-fold` read an existing document and a diff, and a document that never existed has neither, so they report the request as unrelated to any change. Either way the document ships with no read of the standard its kind answers to and no check against the catalog for a sibling already covering the same ground under a different name.
11
+
12
+ The same procedure ran as five skills, one per kind, each restating the read, the collision check, the confirm, and the write. They drifted on their own cadence, and five descriptions competed for one trigger, writing a new document.
13
+
14
+ ## Must
15
+
16
+ - Resolve the kind from the destination the request names, and ask rather than defaulting when it names none, since a document in the wrong surface is invisible where a reader looks for it
17
+ - Load exactly one kind reference per run, so every step that differs by kind lives in one file and the shared procedure in one body
18
+ - Read the kind's standard before drafting, since its frontmatter contract and its reader questions make the document arguable against a sibling
19
+ - Check the catalog by exact name and by title and description, since a subject can be covered under a name the request does not guess
20
+ - Confirm the resolved path, the kind's detections, and the full content with the user before writing, since placement and detection are judgment calls with no diff to preview them against
21
+ - Regenerate the catalog of the folder the document landed in, where the kind keeps one, so the next run's collision check sees it
22
+ - Draft a README from the template for every detected project type and combine them, never the closest one, since a project that is a CLI and a plugin owes its reader both
23
+ - Carry each kind's own musts in its reference: the root check for context, both placement tests and a fetched source for the wiki, and project detection and rendered-value badges for the readme
24
+
25
+ ## Must not
26
+
27
+ - Rewrite, refresh, or sync a document that already exists. A collision refuses toward the surface that owns the existing document.
28
+ - Hand-edit an `index.md`. It regenerates from sibling frontmatter, and a hand edit is overwritten on the next regen.
29
+ - Substitute recall for a failed fetch on the wiki kind, or invent an image or a placeholder path on the readme kind.
30
+ - Build a hand-drawn diagram loop for a docs page.
31
+ - Widen the wiki's folder split to admit a subject its second placement test rejects. That is a change to the standard, argued there.
32
+ - Assume this skill's routing needs no check. One description now covers four triggers, and a ranking over descriptions is a proxy for how Claude Code routes, so a review some months in should read real invocations back.
33
+
34
+ ## Guards
35
+
36
+ - No subject given, for any kind but the readme: stop and ask what the document should cover.
37
+ - No destination named: ask which kind rather than defaulting to `docs/`.
38
+ - Every other guard is the kind's own, stated in its reference.
39
+
40
+ ## Out of scope
41
+
42
+ - Rewriting or syncing an existing `docs/` page or an authored README against a diff: `docs-sync`
43
+ - Refreshing an existing context entry: `context-fold`
44
+ - Drafting a governance rule: `create-rule`
45
+ - Drawing a figure or a diagram for a document: `draw-figure`
46
+ - Voice, rhythm, punctuation, and formatting in the drafted document: the `write-human` skill and the markdown standard
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: write-doc
3
+ description: Drafts one brand-new project document from scratch against the standard for its kind, picking the kind from where it lands, a `docs/` page, a `canon/context/` entry, a wiki reference page, or a README.md. Checks the catalog for a name or topic collision, places it, confirms with the user, then writes. Use when asked to "write a new docs page for X", "write a context entry for X", "write a wiki page for X", or "write a README" where none exists yet. Do NOT use to rewrite or sync an existing page or README against a diff, which is `docs-sync`, or to refresh a context entry, which is `context-fold`.
4
+ metadata:
5
+ family: generate
6
+ ---
7
+
8
+ # Write doc
9
+
10
+ Drafts one brand-new project document end to end: resolve its kind, read the standard that kind answers to, check the catalog for a collision, place it, draft, confirm with the user, then write.
11
+
12
+ ## Resolve the kind
13
+
14
+ Each kind has one standard and one reference. Load the reference for the resolved kind and no other, since every step below that differs by kind lives there.
15
+
16
+ | Kind | Lands at | Standard | Reference |
17
+ | ------- | -------------------------------------------------------- | ----------------------------------------------------------- | --------------------------------------------- |
18
+ | docs | a page under `docs/` | `${CLAUDE_SKILL_DIR}/../docs-sync/references/docs.md` | `${CLAUDE_SKILL_DIR}/references/docs.md` |
19
+ | context | an entry under `canon/context/` | `${CLAUDE_SKILL_DIR}/../context-fold/references/context.md` | `${CLAUDE_SKILL_DIR}/references/context.md` |
20
+ | wiki | a reference page on a subject owned outside this project | `${CLAUDE_SKILL_DIR}/references/wiki.md` | `${CLAUDE_SKILL_DIR}/references/wiki-kind.md` |
21
+ | readme | a `README.md`, at the root or in a folder | `${CLAUDE_SKILL_DIR}/../docs-sync/references/readme.md` | `${CLAUDE_SKILL_DIR}/references/readme.md` |
22
+
23
+ - Read the kind off the destination the request names: a path, a folder, or the document's own name, such as "a context entry" or "a wiki page".
24
+ - Ask which kind when the request names no destination, offering the candidates the subject fits with the likeliest first
25
+ - Never default to `docs/` without saying so, since a subject documented in the wrong surface is invisible to the session that looks for it in the right one
26
+ - If no subject is given for any kind but readme, stop: `❌ No subject given. Name what this document should cover.`
27
+ - A README covers the project or the folder it sits in, so its subject is the target path
28
+
29
+ ## Read
30
+
31
+ Read these in parallel, from the project root where a path is relative:
32
+
33
+ - The kind's standard from the table above: the reader the document serves, its frontmatter, its structure, and what it links out to rather than restates
34
+ - `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md`: punctuation and formatting for all generated text
35
+ - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
36
+ - The kind's reference from the table above
37
+
38
+ ## Guards
39
+
40
+ Run the guards the reference states before placing or drafting anything. Each one stops toward the surface that owns the case, and a stop writes nothing.
41
+
42
+ ## Placement
43
+
44
+ Settle the path and check the catalog for a collision the way the reference states. An exact-name check alone misses a document already covering the subject under another name, so check the titles and descriptions of the catalog the placement step already reads, and stop the same way on a match.
45
+
46
+ ## Draft
47
+
48
+ - Draft against the kind's standard, keeping its template and its section order.
49
+ - Draft frontmatter where the standard requires it, then the body, following the reference for what the kind adds.
50
+ - Write for a reader with no source open. Omit an expected section with nothing to put in it rather than padding it.
51
+
52
+ ## Confirm
53
+
54
+ - Show the kind, the resolved path, whatever else the reference names for the preview, and the full drafted content before writing.
55
+ - Confirm with the user, and wait for that answer rather than treating the tool permission dialog as the gate
56
+ - The kind, the placement, and every detection the reference runs are judgment calls with no diff to preview them against, which is why the dialog cannot stand in
57
+
58
+ ## Write
59
+
60
+ - Write the file at the confirmed path, creating the folder when it is absent unless the reference narrows that.
61
+ - Run `canon markdown audit <path>` and fix every ban, density, and reference shape finding until a re-run reports none. The whole file is this run's draft, so every finding is its own.
62
+ - Run `canon indexes regen <folder>` on the folder the reference names, so its `index.md` picks up the new document. Skip it where the reference says the kind keeps no catalog.
63
+
64
+ ## Response format
65
+
66
+ ### Preview
67
+
68
+ **Kind:** `<docs | context | wiki | readme>`
69
+ **Subject:** `<subject, or the target path for a README>`
70
+ **Placement:** `<path>`
71
+ <one line per preview field the reference names>
72
+
73
+ ```markdown
74
+ <drafted frontmatter and body>
75
+ ```
76
+
77
+ ### After confirmation
78
+
79
+ One line once the file is written and its audit reports nothing.
80
+
81
+ ```plaintext
82
+ ✅ Drafted: <path>
83
+ ```
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Context kind
3
- description: The root check, guard, flat-file placement, three-question draft, and regen folder for a brand-new context entry, read by draft-doc once the request resolves to the context kind
3
+ description: The root check, guard, flat-file placement, three-question draft, and regen folder for a brand-new context entry, read by write-doc once the request resolves to the context kind
4
4
  ---
5
5
 
6
6
  # Context kind
7
7
 
8
- `draft-doc` reads this file when the request resolves to an entry under `canon/context/`. An entry that already exists is refreshed by `context-fold`, never drafted here.
8
+ `write-doc` reads this file when the request resolves to an entry under `canon/context/`. An entry that already exists is refreshed by `context-fold`, never drafted here.
9
9
 
10
10
  ## Root
11
11
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Docs kind
3
- description: The guard, placement, draft additions, and regen folder for a brand-new page under docs/, read by draft-doc once the request resolves to the docs kind
3
+ description: The guard, placement, draft additions, and regen folder for a brand-new page under docs/, read by write-doc once the request resolves to the docs kind
4
4
  ---
5
5
 
6
6
  # Docs kind
7
7
 
8
- `draft-doc` reads this file when the request resolves to a page under `docs/`. A page that already exists is rewritten by `docs-sync`, never drafted here.
8
+ `write-doc` reads this file when the request resolves to a page under `docs/`. A page that already exists is rewritten by `docs-sync`, never drafted here.
9
9
 
10
10
  ## Guards
11
11
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Readme kind
3
- description: The target default, authored-versus-scaffold guard, project detection, header block, and badges for a README.md, read by draft-doc once the request resolves to the readme kind
3
+ description: The target default, authored-versus-scaffold guard, project detection, header block, and badges for a README.md, read by write-doc once the request resolves to the readme kind
4
4
  ---
5
5
 
6
6
  # Readme kind
7
7
 
8
- `draft-doc` reads this file when the request resolves to a `README.md`. An authored README is rewritten by `docs-sync`, never drafted here.
8
+ `write-doc` reads this file when the request resolves to a `README.md`. An authored README is rewritten by `docs-sync`, never drafted here.
9
9
 
10
10
  The readme standard claims the voice of a repository-root README. `write-human` yields voice there and keeps rhythm, density, and the machine-tell catalog everywhere, the root README included.
11
11
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Wiki kind
3
- description: The root guard, both placement tests, catalog collision, sourcing from the owner, and vendor-folder regen for a brand-new wiki reference page, read by draft-doc once the request resolves to the wiki kind
3
+ description: The root guard, both placement tests, catalog collision, sourcing from the owner, and vendor-folder regen for a brand-new wiki reference page, read by write-doc once the request resolves to the wiki kind
4
4
  ---
5
5
 
6
6
  # Wiki kind
7
7
 
8
- `draft-doc` reads this file when the request resolves to a wiki reference page. A page that already exists is edited against the same standard, never drafted a second time.
8
+ `write-doc` reads this file when the request resolves to a wiki reference page. A page that already exists is edited against the same standard, never drafted a second time.
9
9
 
10
10
  The standard's `## Placement` section names the folder a page lands in and the vendor subfolder under it. Resolve both from the project root and call them `<wiki-root>` and `<vendor>` below, so the standard stays the one owner of the path.
11
11
 
@@ -19,7 +19,7 @@ The standard sets two tests and a page has to pass both. Run them before draftin
19
19
 
20
20
  | Test | Fails on | Refusal |
21
21
  | ------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
22
- | Owned outside this repository | A subject describing how this repository works | `❌ <subject> is owned by this project, so it belongs in the docs surface or a context entry. Re-run draft-doc naming that destination.` |
22
+ | Owned outside this repository | A subject describing how this repository works | `❌ <subject> is owned by this project, so it belongs in the docs surface or a context entry. Re-run write-doc naming that destination.` |
23
23
  | Owned by the vendor the folder split covers | A third-party tool or a vendor-neutral concept, however reference-like it reads | `❌ <subject> is outside the wiki's folder split. Route it to the docs surface or a skill body rather than adding a second folder for it.` |
24
24
 
25
25
  On the first test, offer the docs or context kind of this skill. The standard names one owner and one subfolder for the second.
@@ -45,8 +45,10 @@ A page marked `kind: reference` holds its opening, then `Output`, `Refusals`, an
45
45
  - A paragraph under a list item counts toward that bullet, never as a paragraph
46
46
  - A table, fence, list, heading, or bold section marker ends a run of paragraphs
47
47
  - A run whose every item opens with a bold label or a link is exempt, and numbered items never count
48
- - Only context entries, docs, skill bodies and references, tooling seeds and stack references, the wiki, `README.md`, and `CONTRIBUTING.md` take a finding
49
- - A bullet run gates everywhere those paths sit, and the rest gates under `GATED_PATHS` in `src/markdown/scope.ts`. Outside a canon checkout nothing gates.
48
+ - Only context entries, docs, skill bodies, references, and requirements, tooling seeds and stack references, the wiki, `README.md`, and `CONTRIBUTING.md` take a finding
49
+ - A bullet run gates on those paths, and the rest gates under `GATED_PATHS` in `src/markdown/scope.ts`. Outside a canon checkout nothing gates.
50
+
51
+ A requirement is the one exception to both. It gates only once `GATED_PATHS` names its own file, never through its skill's prefix and never on a bullet run alone.
50
52
 
51
53
  Five measures report and never set the exit code on their own.
52
54
 
@@ -11,7 +11,7 @@ kind: reference
11
11
  | Verb | Moves |
12
12
  | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
13
13
  | `rename` | The retired `aitk` name. `--scope target` rewrites toolkit-owned folders only. |
14
- | `skill-names` | Plugin skills off their `claude-` prefix and other retired names, with every citation |
14
+ | `skill-names` | Plugin skills off their `claude-` and `draft-` prefixes and other retired names, with every citation |
15
15
  | `records` | Session records from `.claude/` to `.canon/`, with every tracked citation |
16
16
  | `surface-roots` | `context/`, `wireframes/`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`, and the stamp folder from `.claude/` to `canon/`, by `git mv` |
17
17
  | `record-tree` | Citations inside `.canon/` folders a session still follows: `diagrams`, `memory`, `plans`, `proposals`, `review`, `tasks`, `teach` |
@@ -20,7 +20,7 @@ kind: reference
20
20
  | `record-layout` | Review receipts, memory archives, feedback, renders, picks, and evidence into their current folders |
21
21
  | `session-defaults` | The seeded session defaults into an existing `.claude/settings.json`: `Agent` and `Task` denied, auto memory off |
22
22
 
23
- - `skill-names` takes no `--scope` and skips the changelog and eval transcripts
23
+ - `skill-names` takes no `--scope`, and skips the changelog, eval transcripts, and the pointer each renamed `draft-` skill leaves at its old name
24
24
  - `surface-roots` leaves `rules/`, `skills/`, `hooks/`, and `settings.json` where Claude Code reads them
25
25
  - `rule-layout` classifies each flat file against the stamp as clean, edited, or unclaimed. Clean and edited files move untouched, and an unclaimed name stays.
26
26
  - `record-layout` labels each evidence folder `(pick)` or `(evidence)` in the dry run
@@ -46,9 +46,22 @@ Run it once, ahead of `canon gov sync` or `canon gov install`.
46
46
 
47
47
  ## Rename the skill citations, once
48
48
 
49
- Plugin skills dropped their `claude-` prefix, so `canon:claude-docs` answers as `canon:context-fold` and `canon:claude-tasks` as `canon:task-board`. The five per-kind drafters merged into `draft-doc`, and no pointer under an old name ships. <!-- canon-keep-retired -->
49
+ Plugin skills dropped their `claude-` prefix, so `canon:claude-docs` answers as `canon:context-fold` and `canon:claude-tasks` as `canon:task-board`. The five per-kind drafters merged into `write-doc`, and no pointer under an old name ships. <!-- canon-keep-retired -->
50
+
51
+ The seven `draft-` skills took verb-first names for what each makes. `canon migrate skill-names --write` carries a project across, and a pointer under each old name answers a typed invocation until it retires.
52
+
53
+ | Old name | New name |
54
+ | ------------------ | ----------------------------------------------- |
55
+ | `draft-doc` | `write-doc` <!-- canon-keep-retired --> |
56
+ | `draft-figure` | `draw-figure` <!-- canon-keep-retired --> |
57
+ | `draft-identity` | `design-identity` <!-- canon-keep-retired --> |
58
+ | `draft-slides` | `make-deck` <!-- canon-keep-retired --> |
59
+ | `draft-and-pick` | `pick-by-eye` <!-- canon-keep-retired --> |
60
+ | `draft-ready` | `plan-ready` <!-- canon-keep-retired --> |
61
+ | `draft-screencast` | `script-screencast` <!-- canon-keep-retired --> |
50
62
 
51
63
  - `canvas` is now `canvas-board`. The sweep rewrites only `canon:canvas` and `skills/canvas`, so replace a bare prose mention by hand. <!-- canon-keep-retired -->
64
+ - `draft-ready` is rewritten only as `canon:draft-ready` and `skills/draft-ready`, since bare it also describes a pull request. Replace a bare mention of the skill by hand. <!-- canon-keep-retired -->
52
65
  - `design-extract` and `sketch-design` are replaced by `canon:canvas-board`. <!-- canon-keep-retired -->
53
66
  - `review-branch`, `seed-sync`, `restate-plainly`, `bash-cli-script`, `canon-operator`, and `canon-rollout` have no successor <!-- canon-keep-retired -->
54
67
  - `create-standard`, `markdown-propose`, `memory-review`, `project-commands`, `repo-metadata`, and `ux-walkthrough` have no successor <!-- canon-keep-retired -->
@@ -108,7 +121,7 @@ From the registry the walk reports `historyUnavailable`, so check both paths by
108
121
  | `context-fold` | `context` |
109
122
  | `canvas-board` | `canvas`, `design` |
110
123
  | `docs-sync` | `docs`, `readme` |
111
- | `draft-figure` | `figures`, `mermaid` |
124
+ | `draw-figure` | `figures`, `mermaid` |
112
125
  | `create-rule` | `rule` |
113
126
  | `create-skill` | `skill`, `skill-paths`, `skill-practice`, `skill-requirement` |
114
127
  | `git-branch` | `branch`, `slug` |
@@ -119,8 +132,8 @@ From the registry the walk reports `historyUnavailable`, so check both paths by
119
132
  | `plan-groundwork` | `groundwork`, `groundwork-spikes` |
120
133
  | `plan-intake` | `intake` |
121
134
  | `plan-feature` | `plan`, `plan-lifecycle` |
122
- | `draft-ready` | `ready` |
123
- | `draft-doc` | `requirements`, `wiki` |
135
+ | `plan-ready` | `ready` |
136
+ | `write-doc` | `requirements`, `wiki` |
124
137
  | `session-map` | `session` |
125
138
 
126
139
  The `standard` name became `skill-reference.md` in `create-skill`.
@@ -57,7 +57,7 @@ Before the first feature session:
57
57
 
58
58
  1. Fill `canon/REQUIREMENTS.md` with the problem, goals, and non-goals. The seed's 600-word cap gates under `canon context audit`.
59
59
  2. For a UI project, write `canon/DESIGN.md` from the seed and name the stylesheet in its lead, or work the direction out with `canon:canvas-board`
60
- 3. Optionally invoke `canon:draft-figure` for an architecture view. The Mermaid CLI downloads on first use.
60
+ 3. Optionally invoke `canon:draw-figure` for an architecture view. The Mermaid CLI downloads on first use.
61
61
  4. Start the feature loop in [AI workflow](../workflow/ai-workflow.md)
62
62
 
63
63
  ### Stack decision
@@ -49,13 +49,14 @@ Merge order matters only when two branches touch the same file. Expect to rebase
49
49
 
50
50
  ## The task board
51
51
 
52
- `.canon/tasks/` is gitignored and resolves at the main worktree root, one file per task. A hook generates `index.md`, and `priority.md` carries execution order and blockers.
52
+ `.canon/tasks/` is gitignored and resolves at the main worktree root, one file per task. A hook generates `index.md`, and `priority.md` carries execution order and blockers. `canon tasks place`, `promote`, `move`, and `block` write it, deriving every cell but `Waiting on`.
53
53
 
54
54
  `canon tasks validate` reports and never writes:
55
55
 
56
56
  - A row's cell count must match its header, and a `## Needs a plan` row stating its position is checked against where it sits
57
57
  - Every plan pointer resolves, every task file is named once, and every ready row names its files
58
- - A parked row is reported when its cited task reached the trunk
58
+ - A parked row is reported when its cited task reached the trunk, whether the cell links it or names its bare label
59
+ - A group header must be the columns the group owns, a `Touches` cell must match its plan, and a `Waiting on` cell renders at most 120 characters
59
60
 
60
61
  `canon:task-board` creates a task file, and `canon:task-complete` marks outcomes. The `post-merge` hook archives the task a merged pull request closed, with its plan, and a `post-rewrite` hook does the same for a rebase pull. Both archive only when the merge carried a PR number and the task is closed.
61
62