@erclx/canon 5.43.0 → 5.45.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 (245) hide show
  1. package/README.md +1 -1
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/backlog-triage/references/apply.md +6 -6
  4. package/claude/skills/canon-cli/SKILL.md +4 -5
  5. package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
  6. package/claude/skills/canvas-board/SKILL.md +1 -1
  7. package/claude/skills/context-fold/references/context.md +1 -1
  8. package/claude/skills/create-skill/REQUIREMENT.md +1 -1
  9. package/claude/skills/create-skill/SKILL.md +2 -2
  10. package/claude/skills/create-skill/references/skill-requirement.md +68 -9
  11. package/claude/skills/create-skill/references/skill.md +1 -1
  12. package/claude/skills/design-identity/REQUIREMENT.md +40 -0
  13. package/claude/skills/design-identity/SKILL.md +138 -0
  14. package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
  15. package/claude/skills/design-taste/REQUIREMENT.md +6 -6
  16. package/claude/skills/design-taste/SKILL.md +2 -2
  17. package/claude/skills/design-taste/references/kinds.md +1 -1
  18. package/claude/skills/design-taste/references/preflight.md +1 -1
  19. package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
  20. package/claude/skills/draft-and-pick/SKILL.md +3 -153
  21. package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
  22. package/claude/skills/draft-doc/SKILL.md +4 -76
  23. package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
  24. package/claude/skills/draft-figure/SKILL.md +3 -77
  25. package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
  26. package/claude/skills/draft-identity/SKILL.md +3 -130
  27. package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
  28. package/claude/skills/draft-ready/SKILL.md +3 -128
  29. package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
  30. package/claude/skills/draft-screencast/SKILL.md +3 -62
  31. package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
  32. package/claude/skills/draft-slides/SKILL.md +3 -72
  33. package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
  34. package/claude/skills/draw-figure/SKILL.md +85 -0
  35. package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
  36. package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
  37. package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
  38. package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
  39. package/claude/skills/make-deck/REQUIREMENT.md +44 -0
  40. package/claude/skills/make-deck/SKILL.md +80 -0
  41. package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
  42. package/claude/skills/markdown-craft/SKILL.md +2 -2
  43. package/claude/skills/pick-by-eye/REQUIREMENT.md +36 -0
  44. package/claude/skills/pick-by-eye/SKILL.md +161 -0
  45. package/claude/skills/plan-feature/SKILL.md +2 -1
  46. package/claude/skills/plan-feature/references/plan.md +24 -10
  47. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  48. package/claude/skills/plan-intake/SKILL.md +1 -1
  49. package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
  50. package/claude/skills/plan-ready/SKILL.md +136 -0
  51. package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
  52. package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
  53. package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
  54. package/claude/skills/record-screencast/SKILL.md +2 -2
  55. package/claude/skills/role-orchestrator/REQUIREMENT.md +16 -99
  56. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
  57. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
  58. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
  59. package/claude/skills/role-planner/REQUIREMENT.md +15 -73
  60. package/claude/skills/role-planner/SKILL.md +2 -1
  61. package/claude/skills/role-worker/REQUIREMENT.md +13 -41
  62. package/claude/skills/role-worker/SKILL.md +9 -0
  63. package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
  64. package/claude/skills/script-screencast/SKILL.md +70 -0
  65. package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
  66. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  67. package/claude/skills/search-craft/SKILL.md +1 -1
  68. package/claude/skills/target-setup/SKILL.md +3 -2
  69. package/claude/skills/target-setup/references/detect.md +0 -1
  70. package/claude/skills/target-setup/references/verify.md +2 -2
  71. package/claude/skills/task-board/SKILL.md +11 -9
  72. package/claude/skills/task-board/references/board.md +15 -12
  73. package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
  74. package/claude/skills/teach-workspace/SKILL.md +1 -1
  75. package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
  76. package/claude/skills/teach-workspace/references/promotion.md +5 -5
  77. package/claude/skills/ui-checklist/SKILL.md +2 -0
  78. package/claude/skills/write-doc/REQUIREMENT.md +46 -0
  79. package/claude/skills/write-doc/SKILL.md +83 -0
  80. package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
  81. package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
  82. package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
  83. package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +3 -3
  84. package/docs/agents/install-and-sync.md +2 -2
  85. package/docs/agents/markdown-audit.md +4 -2
  86. package/docs/agents/migrate.md +2 -2
  87. package/docs/agents/output-shape.md +1 -2
  88. package/docs/target/migrations.md +35 -4
  89. package/docs/target/projects.md +2 -3
  90. package/docs/target/scenarios.md +4 -1
  91. package/docs/workflow/parallel-features.md +3 -2
  92. package/docs/workflow/skill-map-on-request.md +19 -13
  93. package/docs/workflow/skill-map.md +13 -12
  94. package/docs/workflow/visual-design-workflow.md +2 -2
  95. package/governance/detect.toml +4 -0
  96. package/governance/ledger/framework/astro.md +73 -0
  97. package/governance/ledger/framework/fastapi.md +76 -0
  98. package/governance/ledger/framework/nextjs.md +86 -0
  99. package/governance/ledger/framework/react.md +83 -0
  100. package/governance/ledger/framework/shadcn.md +60 -0
  101. package/governance/ledger/framework/tailwind.md +55 -0
  102. package/governance/ledger/lang/go.md +61 -0
  103. package/governance/ledger/lang/php.md +50 -0
  104. package/governance/ledger/lang/python.md +68 -0
  105. package/governance/ledger/lang/typescript.md +64 -0
  106. package/governance/ledger/lib/database.md +65 -0
  107. package/governance/ledger/lib/e2e-reliability.md +57 -0
  108. package/governance/ledger/lib/pydantic.md +61 -0
  109. package/governance/ledger/lib/security-server.md +62 -0
  110. package/governance/ledger/lib/security-web.md +51 -0
  111. package/governance/ledger/lib/tanstack-query.md +57 -0
  112. package/governance/ledger/lib/test-scope.md +43 -0
  113. package/governance/ledger/lib/testing-go.md +57 -0
  114. package/governance/ledger/lib/testing-php.md +51 -0
  115. package/governance/ledger/lib/testing-py.md +67 -0
  116. package/governance/ledger/lib/testing-ts.md +63 -0
  117. package/governance/ledger/lib/zod.md +47 -0
  118. package/governance/ledger/tooling/ci-workflow.md +33 -0
  119. package/governance/ledger/tooling/code-comments.md +48 -0
  120. package/governance/ledger/tooling/config-comments.md +27 -0
  121. package/governance/ledger/tooling/dependencies.md +38 -0
  122. package/governance/ledger/ui/a11y.md +55 -0
  123. package/governance/ledger/ui/copy.md +49 -0
  124. package/governance/ledger/ui/design-reference.md +42 -0
  125. package/governance/ledger/ui/design-taste.md +19 -0
  126. package/governance/ledger/ui/forms.md +71 -0
  127. package/governance/ledger/ui/interface-casing.md +47 -0
  128. package/governance/ledger/ui/keyboard.md +68 -0
  129. package/governance/ledger/ui/link-behavior.md +29 -0
  130. package/governance/ledger/ui/motion.md +33 -0
  131. package/governance/ledger/ui/surface-capture.md +69 -0
  132. package/governance/ledger/ui/ux-completeness.md +79 -0
  133. package/governance/rules/framework/astro.md +12 -14
  134. package/governance/rules/framework/fastapi.md +20 -24
  135. package/governance/rules/framework/nextjs.md +19 -27
  136. package/governance/rules/framework/react.md +22 -33
  137. package/governance/rules/framework/shadcn.md +11 -15
  138. package/governance/rules/framework/tailwind.md +12 -14
  139. package/governance/rules/lang/go.md +7 -16
  140. package/governance/rules/lang/php.md +3 -3
  141. package/governance/rules/lang/python.md +9 -18
  142. package/governance/rules/lang/typescript.md +9 -19
  143. package/governance/rules/lib/database.md +5 -5
  144. package/governance/rules/lib/e2e-reliability.md +4 -6
  145. package/governance/rules/lib/pydantic.md +14 -16
  146. package/governance/rules/lib/security-server.md +4 -4
  147. package/governance/rules/lib/security-web.md +6 -10
  148. package/governance/rules/lib/tanstack-query.md +10 -12
  149. package/governance/rules/lib/test-scope.md +4 -4
  150. package/governance/rules/lib/testing-go.md +1 -2
  151. package/governance/rules/lib/testing-php.md +4 -5
  152. package/governance/rules/lib/testing-py.md +11 -19
  153. package/governance/rules/lib/testing-ts.md +7 -16
  154. package/governance/rules/lib/zod.md +6 -8
  155. package/governance/rules/tooling/code-comments.md +2 -4
  156. package/governance/rules/tooling/config-comments.md +1 -4
  157. package/governance/rules/tooling/dependencies.md +1 -1
  158. package/governance/rules/ui/a11y.md +16 -45
  159. package/governance/rules/ui/copy.md +6 -9
  160. package/governance/rules/ui/forms.md +13 -19
  161. package/governance/rules/ui/interface-casing.md +5 -7
  162. package/governance/rules/ui/keyboard.md +38 -0
  163. package/governance/rules/ui/link-behavior.md +3 -3
  164. package/governance/rules/ui/motion.md +3 -3
  165. package/governance/rules/ui/surface-capture.md +15 -27
  166. package/governance/rules/ui/ux-completeness.md +16 -39
  167. package/governance/rules/writing/markdown.md +1 -1
  168. package/package.json +1 -1
  169. package/scripts/core/install-check.sh +1 -1
  170. package/src/claude/cases/authoring.ts +15 -3
  171. package/src/claude/cases/misc.ts +12 -0
  172. package/src/claude/cases/workflow.ts +19 -1
  173. package/src/claude/skills-audit.ts +113 -1
  174. package/src/cli/help.ts +0 -1
  175. package/src/cli.ts +0 -2
  176. package/src/commands/claude.ts +34 -11
  177. package/src/commands/demo.ts +1 -1
  178. package/src/commands/gov.ts +4 -0
  179. package/src/commands/init.ts +2 -2
  180. package/src/commands/markdown.ts +1 -1
  181. package/src/commands/migrate.ts +4 -0
  182. package/src/commands/pr.ts +30 -6
  183. package/src/commands/tasks.ts +383 -2
  184. package/src/commands/tooling.ts +18 -5
  185. package/src/context/audit.ts +1 -1
  186. package/src/demo/beats.ts +1 -1
  187. package/src/design/components.ts +1 -1
  188. package/src/gov/audit.ts +25 -4
  189. package/src/init/plan.ts +1 -8
  190. package/src/init/steps.ts +0 -8
  191. package/src/inventory/subjects.ts +1 -1
  192. package/src/markdown/scope.ts +49 -35
  193. package/src/migrate/record-layout.ts +1 -1
  194. package/src/migrate/scratch-evidence.ts +12 -4
  195. package/src/migrate/skill-names.ts +68 -21
  196. package/src/pr/frames.ts +14 -3
  197. package/src/records/backup.ts +3 -3
  198. package/src/records/validate.ts +31 -0
  199. package/src/roots/record.ts +17 -8
  200. package/src/tasks/board.ts +854 -0
  201. package/src/tasks/record.ts +20 -1
  202. package/src/tasks/validate.ts +206 -9
  203. package/src/tooling/inject.ts +26 -7
  204. package/src/tooling/package.ts +32 -0
  205. package/src/tooling/read.ts +46 -3
  206. package/src/tooling/scan.ts +8 -2
  207. package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
  208. package/tooling/astro/reference.md +64 -93
  209. package/tooling/base/configs/.github/workflows/phase-label-gate.yml +1 -1
  210. package/tooling/base/configs/scripts/verify.ts +1 -1
  211. package/tooling/base/reference.md +1 -9
  212. package/tooling/base/seeds/canon/context/{ci.md → development/ci.md} +1 -1
  213. package/tooling/base/seeds/canon/context/development/index.md +11 -0
  214. package/tooling/base/seeds/canon/context/{development.md → development/setup.md} +8 -12
  215. package/tooling/base/seeds/canon/context/index.md +1 -2
  216. package/tooling/claude/manifest.toml +1 -5
  217. package/tooling/claude/reference.md +36 -59
  218. package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
  219. package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +2 -7
  220. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +2 -7
  221. package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +3 -10
  222. package/tooling/claude/seeds/.claude/hooks/search-reminder.sh +2 -7
  223. package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +2 -4
  224. package/tooling/claude/seeds/.claude/settings.json +4 -0
  225. package/tooling/nextjs/reference.md +0 -6
  226. package/tooling/php/reference.md +0 -4
  227. package/tooling/web/configs/.github/workflows/verify.yml +28 -0
  228. package/tooling/web/configs/.oxlintrc.json +7 -0
  229. package/tooling/web/configs/e2e/capture-types.ts +35 -0
  230. package/tooling/web/configs/e2e/screenshot.ts +23 -72
  231. package/tooling/web/manifest.toml +1 -1
  232. package/tooling/web/reference.md +77 -124
  233. package/tooling/web/seeds/e2e/capture/cases.ts +47 -0
  234. package/src/commands/wiki.ts +0 -100
  235. package/src/wiki/init.ts +0 -85
  236. /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
  237. /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
  238. /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
  239. /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
  240. /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
  241. /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
  242. /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
  243. /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
  244. /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
  245. /package/claude/skills/{draft-doc → write-doc}/references/wiki.md +0 -0
@@ -7,113 +7,30 @@ description: What the one warm control session owns, why it plans and dispatches
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, the session holding the cross-feature picture starts building, and the picture goes with it. Two features land where one depends on the other or consumes a contract the other changes, because nobody read their plans against each other, and the second pull request rebases onto a tree it was never planned against. Findings from a merged pull request stay in a thread nobody re-reads, so the rule they should have changed never changes. Holding on one shared path costs as much, and ran six canvas rows one at a time on 2026-10-04 though no practitioner source serializes on a shared file.
10
+ Without this skill, the control session builds or merges, and the cross-feature picture goes with it. Plans go out unread against each other and a moved tree, the queue empties or fills with whatever is oldest, a parked row's blocker is never re-tested, and a second orchestrator writes a board neither can read.
11
11
 
12
- The queue fails in both directions. It empties and a free worker waits, or it fills with whatever is oldest rather than with what establishes a mechanism. A plan handed over unverified is the quiet one, since it goes stale from whatever merged after it was written, and a worker that trusts its account of the tree builds against a shape that no longer exists. A second orchestrator makes all of this unrecoverable, because the board is gitignored and neither session can read the other's writes.
13
-
14
- Refilling on a merge and on a thinning ready list leaves the window between them unwatched. A wave mid-build has merged nothing and has moved no rows, so both conditions stay silent across the whole build and the wave finishes into an empty queue, which lands planning on the critical path directly after the stretch where it would have cost nothing.
15
-
16
- Every one of those triggers looks forward, so a row already parked is measured once and re-tested never. A blocker cell is a claim about the tree that was true the day it was written, and a merge changes the tree under every parked row at once rather than under the rows naming it. A row therefore sits on a condition that stopped holding weeks earlier with nothing reporting the gap.
17
-
18
- Re-measuring one goes wrong twice over, and both ways return a confident number rather than an error. A count read looser than its consumer defines the shape answers a question nobody asked, and a condition measured against the tree at hand reads as unreachable while it stays live in the corpus a shipped command runs against. Waiting is not evidence either, and a task conflicting with everything by construction gets re-measured every pass rather than split.
19
-
20
- Writing those plans against the tree alone is the second half, since several branches are already changing the shape a plan describes. A plan carrying a bare path list rather than a constraint per in-flight track leaves the worker guessing which act each path forbids, which is the dangling citation the rule against bare paths already exists to prevent.
21
-
22
- The session also writes surfaces it is told only how to read. With no stated method for rewriting the priority file, a session invents one that can exit clean on a non-match, carry prose where a plan pointer belongs, or keep a pointer to a plan a worker's branch archived, and each reads as correct until a dispatch spends on it.
23
-
24
- The ban on writing at all fails on a different axis, which is that nothing enforces it and a session weighs proportionality against it. A one-line prose correction found while orchestrating satisfies the root instruction to handle a small edit immediately and violates this rule, and a session given no statement of which one wins takes the smaller apparent cost and authors the change.
25
-
26
- That removes the independent pass the repository built to catch what a self-review misses, and the vantage does not come back, since no later session can review the change without re-deriving the context that produced it. A correction no open task owns has nowhere to go either, so the route matters as much as the ban.
27
-
28
- The contract also stops one state short of what the session holds. Its sections cover what the human launches and what they review, and a self-dispatching session adds a third that sits between them for ten to thirty minutes, which a session reports under no section while the launch section keeps recommending a plan a worker is already building.
29
-
30
- Output drifts everywhere the contract stops. The specified shape covers invocation alone, so a sweep report, a board report, and an analysis each end in a decision the human owns and each buries it under the evidence they would have skipped. A compaction is the same failure one step earlier, since the file that survives it has a stated reader and no stated writer, and the session improvises what to save and loses the reasoning the board never held.
31
-
32
- Naming that reader without naming the way in fails on the next axis, and it fails circularly. The command that routes a resume request lives in this body, which is the surface a long session is likeliest to have dropped, and dropping it is the condition the handoff exists to survive, so the session holding a complete handoff cannot reach the runbook that reads it back. The review poll is lost in the same moment and recovered by neither, since it is session-scoped and the resume performs no restart, which leaves a reader who follows the whole handoff with a board and no trigger.
33
-
34
- The runbooks the session cannot run from memory fail on a third axis, which is where they are kept. A runbook reached by an installed path is a dependency on a channel this skill does not travel on, so a project holding the plugin and running no install follows the citation to nothing, and nothing reports the break because a missing file produces no error until someone opens the path.
35
-
36
- Every one of them therefore has to ship inside the skill. The review trigger fails on an axis of its own when it names one client's command as the way to start the loop, since the file ships to every target holding the plugin and a client without that command reaches no path.
37
-
38
- The dispatch's return leg is unplaced for the same reason. A reply reaches this session as a message and settles a finding, corrects which session holds which branch, or names a gate a worker's edits pass through, and reading it is the whole of what happens to it. Both sessions then end, so the half that belonged on the pull request never reaches it and the half that belonged on the board is rediscovered by whoever needs it next.
39
-
40
- Both halves of that channel are written here and one of them is performed elsewhere, so a worker owes what nothing it loads states. The review trigger inherits the same asymmetry: firing on a dispatch spends an interval against a building worker that has no pull request, and a trigger matching pull requests alone stays silent through a worker that crashes, which only a roster read the poll script cannot make would catch.
41
-
42
- Cost never enters the decision to widen a wave. The rule weighing how many tracks to open measures conflict and review attention, and both describe what a worker writes rather than what the loop spends. Claude Code delivers a message from another session as a fresh turn carrying the whole accumulated context, and a recurring poll bills that same window on its own interval, so a wave's spend tracks this session's context rather than the work coming back. The one setting that bounds it reads as available to whoever finds it, and the two values that would bound it break the handback the loop runs on.
43
-
44
- Dispatch parts from what it checked in three ways. The gate and the worker each derive the branch from their own reading of one plan and reach different strings, a launched worker inherits its launcher's model rather than the configured default, and a declared file set does not hold, since a track crosses the set its plan named.
12
+ The channel fails at every hand-off. A finding or a reply stays in a thread nobody re-reads, a dispatch launches a branch other than the one the check cleared, a wave's cost grows unweighed, a report buries the human's decision, and a compaction loses the way back in.
45
13
 
46
14
  ## Must
47
15
 
48
- - Read the priority file for execution order, since the index sorts by filename and states no order
49
- - Report the state of play so the human knows what to launch, what to review, and what to merge
50
- - Verify a plan against the tree before handing it over, counting the sites it claims and opening the files it describes
51
- - Hold a candidate only on a dependency, a contract, a relocation, a sweep, or a stated reason, since those predict a conflict a merge cannot settle and a shared file does not
52
- - State what a wave costs in inbound turns beside the conflict rule, and name the control that bounds it together with the reason it stays unset, since a lever recorded without its conclusion reads as available to set
53
- - Place every finding a merged pull request produced against the surface that owns it, and write the board so a row's readiness and hold claims stay checkable
54
- - Place what the return leg carries by what it changes, sending an answer that settles a finding onto the pull request and one that corrects this session's model of the world to the task owning that surface, since neither becomes a record by being read
55
- - Keep one planned, non-conflicting task in reserve beyond what is running
56
- - Refill the queue while a wave is still building, rather than on a merge and a thinning list alone, since neither of those fires across the window planning costs nothing
57
- - Carry a constraint naming each in-flight track's file set in every plan written from here, stating per set which of the two acts it forbids, since a bare path list leaves a broken citation in place
58
- - Carry a slot for this session's own workers mid-build, and withhold their plans from the launch slot, since the two other slots cover what a human launches and what they review and nothing between
59
- - Start the review poll on an open pull request rather than on a dispatch, and keep the dispatch as a fallback for an announcement that never arrives, since the script reads pull requests and a building worker has none
60
- - Point at the worker's own skill for the announcement, the block message, and the board ban, rather than holding the only written copy of obligations this session does not perform
61
- - Ship the roster-and-pull-request watch as a script beside the poll, since the loop that covered the gap lived in one session's temporary directory against a hardcoded path and died with that session
62
- - Lead a sweep report, a board report, and an analysis with the state, the open decisions, and the next action, keeping the evidence below them
63
- - Write the pre-compact handoff with what no other file carries, and name the runbook that reads it back
64
- - Carry the resume invocation and the owed poll restart in the handoff file itself, not in the runbook that writes it alone, since the file is what survives a compaction and the runbook is what a session has to already be holding to read
65
- - Distinguish this resume from the general-purpose `session-resume`, since the name an operator reaches for first reaches a skill that knows nothing about the board
66
- - Retire the sessions this wave delivered before the map is written and ahead of any reclaim run, reporting a hand-launched one rather than acting on it, since no verb decides a planner or an unmerged worker and a live session holding a worktree is what the reclaim reading refuses on
67
- - Carry every runbook the session cannot run from memory inside the skill, so each citation resolves for a project holding the plugin and nothing else
68
- - State which rule wins where the tracked-file ban collides with the root instruction on small edits, and where a correction no open task owns goes
69
- - State the review trigger as a recurring prompt rather than as one client's command, since the runbook ships to targets running whatever client they run
70
- - Read the handoff or the resume runbook when the human asks for that side of a compaction, since the request is the only signal available for a moment the loop cannot detect
71
- - Re-test every parked row's blocker against the current tree on request, since every refill trigger looks forward and none of them re-reads a row already waiting
72
- - Measure a condition the way the code consuming it defines the shape, and settle which tree the condition is about before counting, since both errors return a number rather than a failure
73
- - Write each re-test into the row and its measurement into that task's Findings, since a result reported in chat is gone at the next compaction and the next pass measures the same thing
74
- - Plan a row the re-test clears, since a cleared row carrying no plan is one the next pass looks at again
75
- - Split a task that conflicts with every other by construction, rather than re-measuring a scoping defect that reads as a blocker
76
- - Check a candidate branch is unclaimed by an existing worktree or a live session before dispatching a background worker for it, since the measured failure this closes is a worker colliding with someone else's work already sitting in the row
77
- - Dispatch a candidate sharing only files with a track in flight and name the shared paths, and have the branch merging second resolve after the first merges, since every source the gate cites tests at integration
78
- - Write a stated reason on the hold it makes, since two tracks interact in ways no plan reading shows
79
- - Name each self-dispatched worker explicitly with the `worker-` prefix, since that is the role the name marks and a client-derived name is a fragment of the session's identifier
80
- - Carry the dispatcher's `sessionId` in the launch prompt, since a worker owed two messages has no property on the roster that resolves a controller and a name goes stale inside the window it builds in
81
- - Report each self-dispatch and the row it fired against loudly enough to follow, since a person no longer watches the launch step happen
82
- - Stop dispatching once `## Run now` is empty or every row in it reads claimed, rather than waking again to fire on a board nobody is clearing
83
- - Launch a planner or worker the operator will talk with from the talk shape, with the `-talk` suffix and the brief sentence that tells it so, since a cold launch retires the session the moment its delivery lands while the operator still wants the conversation
84
- - Retire a talk session only on the operator's word and report it as held open until then, since its delivery says nothing about whether the conversation is over
85
- - Dispatch every non-release pull request's review to `role-reviewer`, leave each round's messages to it and the worker, and keep one cross-branch pass per wave here, since any pass or relay run here bills the context the wave shares
16
+ - Every plan is verified against the current tree and names each in-flight track's file set, and a candidate holds only on a dependency, a contract, a relocation, a sweep, or a stated reason
17
+ - One planned, non-conflicting task stays in reserve, refilled while a wave builds, and every parked row's blocker is re-tested against the current tree with the result written to the board
18
+ - A finding or a reply lands on the surface that owns it, the pull request or the task, rather than in chat
19
+ - A dispatch launches the branch the check cleared under a `worker-` name carrying this session's `sessionId`, hands review to `role-reviewer`, and states what the wave costs in inbound turns
20
+ - A report and the pre-compact handoff lead with state, open decisions, and next action, the handoff carries its own resume invocation and poll restart, and every runbook ships inside the skill
86
21
 
87
22
  ## Must not
88
23
 
89
- - Implement a feature or edit any tracked file from this session, at any size, since the ban offers no proportionality exception
90
- - Merge. Recommend merge or changes and leave the gate to the human.
91
- - Spawn a worker with the Agent tool, since an in-process subagent shares this session's context and cannot be steered or reached independently. A dispatched `claude --bg` process is not this: it is a separate session with its own worktree and its own PR, gated by the branch check and the conflict check.
92
- - Hand a worker anything but a plan, because scope lives there
93
- - Name a count of the defect's extent or the mechanism behind it while filing a row, since this seat measures a defect from where it stands and the planner is the reader who commits to that scope. A blocker re-test, a branch check, and a conflict check decide whether a row can start rather than how big it is, and they stay.
24
+ - Implement, edit any tracked file at any size, or merge
25
+ - Spawn a worker with the Agent tool, or hand a worker anything but a plan
94
26
  - Run a second orchestrator against the same board
95
- - Promote a task to fill the queue when nothing qualifies. A thin queue is a real answer.
96
- - Promote a parked row on how long it has waited, since age is not a measurement of the blocker
97
- - Schedule the parked-row pass on a recurring loop, since the review poll owns the one recurring trigger this skill has and a second loop fires into a static board
98
- - Rewrite the board with a shell stream editor or an inline string replace, both of which exit clean when they match nothing
99
- - Restate the board, a task file, or a groundwork folder in the pre-compact handoff, which is the padding that makes a handoff stop being read
100
- - Specify a shape for a correction, since a format for admitting error invites ceremony where plainness is the whole value
101
-
102
- ## Guards
103
-
104
- - Priority file absent: report the queue and say the order is unrecorded rather than inferring it from the index
105
- - Cross-version sequencing asked for: say no surface carries it, rather than asserting an active version the tree does not state
106
- - This body dropped from a long session approaching a compaction: name the re-invocation and the runbook paths, since the routing lives in the body and a user-invoked skill routes nothing once it is gone
107
- - Blocker only an operator can clear: record the row as untestable this pass and name the action owed, rather than re-measuring what no session can move
108
- - Branch check refuses, with no session registry or no repository resolved: treat the candidate as unverified and fall back to the human-launch line, rather than reading a check that could not run as a clear one
109
- - Candidate holds under the conflict check: leave the row ready and name the hold, rather than dispatching onto a contract still moving
110
- - Talk session the client renamed after launch: find it by the `sessionId` recorded in the map, since the `-talk` suffix is display only and a rename can drop it
111
- - Operator states a cap for the session: honor it for that session alone, rather than treating it as a standing rule or writing the number into a file
27
+ - Promote a row to fill the queue when nothing qualifies, or on how long it has waited
28
+ - Rewrite the board with a stream editor or a string replace that exits clean on no match
112
29
 
113
30
  ## Out of scope
114
31
 
115
- - Writing the plan itself, which `plan-feature` owns and this session runs rather than reimplements
116
- - Reviewing a worker's pull request, which `review-pr` owns, and the bounds of a reviewer dispatched to run it, which `role-reviewer` owns
117
- - Entering the worktree a build runs in, which the worker opens for itself whether a human launched it or this session dispatched it
118
- - The worker's half of the channel and the boundaries a building session holds, which `role-worker` states where that session reads them
119
- - The operating model this enacts, which the toolkit's own docs hold
32
+ - Writing the plan itself, which `plan-feature` owns
33
+ - Reviewing a worker's pull request, which `review-pr` and `role-reviewer` own
34
+ - Entering the worktree a build runs in, which `session-worktree` owns
35
+ - The worker's half of the channel and its boundaries, which `role-worker` owns
36
+ - Resuming a session with no board behind it, which `session-resume` owns
@@ -3,7 +3,7 @@ title: Orchestrator dispatch runbook
3
3
  description: The plan-answer gate, the collision check before a self-dispatch, the conflict check against the tracks in flight and the evidence it rests on, the branch the launch names, the one model test applied to each role, the fallback to a human launch, and the loop's stopping condition
4
4
  ---
5
5
 
6
- Run this at loop step 4, for a `## Run now` row whose plan is verified, in place of handing the worktree to a human. The conflict check below is where that row is tested against every track in flight, and it is the one statement of what holds a row there.
6
+ Run this at loop step 4, for a `## Up next` row whose plan is verified, in place of handing the worktree to a human. The conflict check below is where that row is tested against every track in flight, and it is the one statement of what holds a row there.
7
7
 
8
8
  ## Contents
9
9
 
@@ -40,6 +40,7 @@ Never shorten a non-conforming slug here, since a rename parts the branch from t
40
40
 
41
41
  Run `canon tasks plan-answers <plan> --json` and read `launchable` off the record. Branch on `launchable` rather than on the exit code, which a wrapping shell function can flatten to zero and so read a held row as clear.
42
42
 
43
+ - Hold a row whose `Waiting on` has not cleared, which no other check reads
43
44
  - `launchable: true`: the plan answers itself, so proceed to the branch check.
44
45
  - `launchable: false`: report every entry in `open`, each with its question label and stated reason, and hand the row to the human-launch line below
45
46
  - Never fill the slot on the operator's behalf, the one move the plan standard forbids outright
@@ -152,6 +153,8 @@ A row qualifies for that pick when its plan carries no open question and touches
152
153
 
153
154
  Read `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md` once every check above clears, and launch from its build template, which sits beside the review-address and planning shapes that skip these checks. A cloud row launches from `${CLAUDE_SKILL_DIR}/references/orchestrator-cloud-launch.md`, since the VM shares no plugin or board.
154
155
 
156
+ Once the launch succeeds, run `canon tasks promote <stem>`.
157
+
155
158
  ## Fall back to the human
156
159
 
157
160
  Hand the row to the human-launch line in step 4 instead of dispatching when any of these hold, and name which one. A shared file alone is not listed.
@@ -171,4 +174,4 @@ Hand the person one command, `/canon:auto-ship <plan>`, naming the row, the plan
171
174
 
172
175
  ## Stop the loop
173
176
 
174
- Wrapped in `/loop`, re-run the check against `## Run now` on each wake, and stop once the group is empty or every row reads `claimed: true`. Report that once, on the wake that finds it, rather than polling a board nobody is clearing, the reasoning `orchestrator-poll.md` carries for the review trigger.
177
+ Wrapped in `/loop`, re-run the check against `## Up next` on each wake, and stop once the group is empty or every row left in it is held. Report that once, on the wake that finds it, rather than polling a board nobody is clearing, the reasoning `orchestrator-poll.md` carries for the review trigger.
@@ -55,7 +55,7 @@ Every measurement this pass takes decides whether a row can start rather than ho
55
55
 
56
56
  Write the result into the row, since a re-test reported in chat is lost at the next compaction and measured again.
57
57
 
58
- - Rewrite a blocker cell whose test no longer holds, and move the row to the group its new state puts it in
58
+ - Rewrite a blocker cell whose test no longer holds through `canon tasks block <stem> "<blocker>"`, and move the row to the group its new state puts it in through `canon tasks place`
59
59
  - Record the measurement in the task's `## Findings` as a line labeled with this session and the date, per `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md`
60
60
  - `### Writing the board` in `role-orchestrator` owns the method, and `canon tasks validate` runs once the board is rewritten and before the report
61
61
 
@@ -69,7 +69,7 @@ A backlog row carries no blocker cell, since `${CLAUDE_SKILL_DIR}/../task-board/
69
69
 
70
70
  ### Moving a cleared row
71
71
 
72
- A cleared row moves out of `backlog.md` onto the bottom of `## Needs a plan`, with a `Waiting on` cell stating what changed and ending with the word `last`.
72
+ A cleared row moves out of `backlog.md` onto the bottom of `## Needs a plan` in one call, `canon tasks place <stem> --group needs-a-plan --bottom --waiting "<what changed>. Last"`.
73
73
 
74
74
  - `canon tasks validate`'s ordering check reads `last` as the ordinal the bottom placement claims
75
75
  - A cell stating only what changed matches neither the ordinal nor the rank reading, raising a finding against the pass's own row
@@ -25,7 +25,7 @@ The third trigger reaches a window the first two cannot. A session with three wo
25
25
  - Run `task-complete` to archive one the hook left in place
26
26
  - A task whose outcomes are standing policy never closes, so hand it to a worker to encode the policy where it is enforced, then cut the outcomes with the reason and archive once that branch merges
27
27
  - Encoding it from this session would write a tracked file, which `## Boundaries` in the skill body forbids
28
- 4. Read `.canon/tasks/priority.md` and count entries under its `## Run now` heading that carry a written plan. Keep one in reserve beyond what is running.
28
+ 4. Read `.canon/tasks/priority.md` and count the `## Up next` rows whose `Waiting on` has cleared, since a blocked row is no reserve. `## Run now` is what is running, so keep one in reserve beyond it.
29
29
  5. Promote from the top of `## Needs a plan`, where the last sweep recorded what to plan next.
30
30
  - Depart from that order when something changed under it and say what, since a position nobody honors is the ordering going stale
31
31
  - The order is set by whether a task establishes functionality, so prefer one that adds or proves a mechanism over one that trims, tidies, or audits
@@ -53,27 +53,32 @@ That block is the detail. Lead the reply with the three slots under `## Every la
53
53
 
54
54
  ## Writing the board
55
55
 
56
- Promoting, demoting, and archiving a row all write `.canon/tasks/priority.md`, and this session is the only writer apart from `canon tasks archive`. Moving a task between the board and `.canon/tasks/backlog.md` writes both files, and this session is that file's only writer.
56
+ Write `.canon/tasks/priority.md` through the `canon tasks` verbs alone, each reading the file once, rendering every table, and writing it once. Beside this session, `canon tasks archive` drops a shipped row and `plan-link` promotes a parked one.
57
57
 
58
- - Edit with the file-editing tool, which errors on a non-match, where a shell stream editor or an inline replace exits clean and leaves the board wrong
59
- - Write both halves of a move before reporting it, since a row on neither surface leaves a task file nothing names in a gitignored folder with no history
60
- - `canon tasks validate` reports that state, so run it after any move
61
- - Put the reason a row sits where it does in its Waiting on cell, since a row promoted with the cell left alone carries an order the next sweep cannot check
58
+ | Move | Verb |
59
+ | ----------------------------------------- | ---------------------------------------------------------- |
60
+ | A backlog row onto the board, or across | `canon tasks place <stem> --group <group> --waiting "..."` |
61
+ | A planned row to `## Run now` on dispatch | `canon tasks promote <stem>` |
62
+ | A row up or down inside its group | `canon tasks move <stem> --before <stem>` |
63
+ | What a row waits on, or why it sits there | `canon tasks block <stem> "<reason>"` |
64
+
65
+ - `place` removes the task's backlog line in the same call, so a row never sits on both surfaces or on neither
66
+ - Demoting a row to `backlog.md` has no verb yet. Add the backlog line first, then delete the row with the file-editing tool, which errors on a non-match.
67
+ - Put the reason a row sits where it does in its Waiting on cell through `block`, since a row promoted with the cell left alone carries an order the next sweep cannot check
68
+ - Run `canon tasks validate` after any move, which reports a hand edit the verbs would have refused
62
69
 
63
70
  ### Columns and read-back
64
71
 
65
- Each column carries a fact a later reader checks rather than reasons again.
72
+ The verbs derive the Task, Touches, and Plan cells from the task file and its live plans, so a later reader checks them rather than reasoning again.
66
73
 
67
- - Put a pointer in the Plan column, never prose, since `auto-ship` refuses at its guard when the column leads to no plan, spending a dispatch
68
- - `## Run now` claims a written plan covers every open outcome, which is what the pointer backs
69
- - Name the file set in the Touches column, which feeds the merge order and the shared paths a dispatch names, so step 6's hold call stays checkable later
70
- - Re-resolve every Plan pointer after anything archives a plan
71
- - Read the file back after writing it, since the row that lands is the row a worker acts on
74
+ - `place` and `promote` refuse a row the target group's test fails, so a Plan cell never leads `auto-ship` to no plan and spends a dispatch
75
+ - A Touches cell differing from its plan's list is `touches-stale`. Change the plan's list rather than the cell, and step 6's hold call reads the result.
76
+ - Read the board back after a write, since the row that lands is the row a worker acts on
72
77
 
73
78
  ### Stale plan pointers
74
79
 
75
80
  A Plan pointer goes stale from a merge this board never sees. The `post-merge` hook moves a plan to `.canon/plans/archive/` through `canon tasks archive` and rewrites the citation in the archived task file alone.
76
81
 
77
- - A row for a task still on the board keeps pointing into `.canon/plans/` at a file that has moved
82
+ - A row for a task still on the board keeps pointing into `.canon/plans/` at a file that has moved, until the next verb call re-derives every Plan cell from the live plans
78
83
  - `task-complete` marks outcomes on each worker's branch and moves nothing, so the move lands at the merge
79
84
  - The board then reads as correct until a pointer is followed
@@ -7,87 +7,29 @@ description: What a thinking session is across planning, groundwork, and intake,
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, a planning session is told what to plan and never what it
11
- is. `role-worker` states the building role and `auto-ship` Step 0 reaches
12
- it on every build, so a builder takes a role whether a person launched it or a
13
- dispatcher did. Planning has no equivalent, and two trials on 2026-08-31 ran
14
- entirely on prose the controller retyped into each launch. That is the shape
15
- `role-orchestrator` already bans on the building side, where one half held the
16
- only written copy of obligations the other half performs.
10
+ Without this skill, a planning, groundwork, or intake session is told what to plan and never what it is. Every launch retypes the role's rules, and the forgotten one fails. The session counts worktrees and branches as in flight though a squash merge leaves both behind, and it quotes a row's stale count instead of opening the source.
17
11
 
18
- Six rules went into each of those launches by hand: no worktree, no branch, no
19
- tracked file, no board write, report the path alone, and re-measure rather than
20
- trusting the task file. A seventh was added only after a trial got it wrong.
21
- Every one of them is a property of the role rather than of the row, so each
22
- dispatch reproduced them from memory and the one nobody remembered was the one
23
- that failed.
24
-
25
- The in-flight read is that failure. The first trial counted worktrees and local
26
- branches and named four branches as in flight, all four of which had merged,
27
- because this repository squash-merges and leaves both behind. A corrected brief
28
- naming `gh pr list` as the source closed it and no constraint in the second
29
- batch was wrong, which puts the fix in a launch string that the next dispatch
30
- has to remember to carry.
31
-
32
- Measuring rather than trusting the row is the other half and it is what the
33
- trials were strongest on. Across four plans the planner reported ten things the
34
- task files got wrong, and one plan overturned its own row's closing conclusion.
35
- Nothing in any skill body tells a planner to open the source rather than quote
36
- the row, so a session that skips that read produces a plan built on the same
37
- stale count the row already carried.
38
-
39
- A planner reading the board sees blockers and file sets and can write a
40
- confident merge order off a partial picture. Which rows collide, what merges
41
- before what, and whether a row should run at all stay with the controlling
42
- session, and no body states that boundary for the planning side.
43
-
44
- Nothing scans a plan for ban hits either. `.gitignore` ignores
45
- `.canon/plans/`, and the audit's default path set is what git lists, so no gate
46
- ever opens one. Six ban hits landed across the four trial plans and three of the
47
- four carried at least one, caught only because the planner ran
48
- `canon markdown audit` unprompted.
12
+ It also reaches past its seat. A planner reading blockers and file sets writes a merge order off a partial picture. Its plans land in a gitignored folder no gate audits, and the controller learns nothing of what the row got wrong unless the planner says so.
49
13
 
50
14
  ## Must
51
15
 
52
- - Assert what a thinking session is, what it may not write, and how long the role lasts, since `plan-feature`, `plan-groundwork`, and `plan-intake` each carry their own procedure and no body carries the role the three share
53
- - Cover all three of those skills rather than `plan-feature` alone, since a groundwork or intake session took no role at all while the body was written for one plan under one task
54
- - State the writes-records-never-source boundary once, and name the three folders in one line while deferring each scope's exceptions to the skill that owns it, so a change to one scope edits one body
55
- - Carry `plan-groundwork`'s close-time task file as an exception to the board ban, since widening the role without it makes the role forbid what that skill requires
56
- - State the in-flight read as a command composing the session roster with open pull requests, and say that a branch and a worktree are not evidence, since a count of either reported merged work as live
57
- - Run that read once per task rather than once per batch, since a reused session ages its picture of the tree while it works
58
- - Name every read a plan needed and a launch string did not carry, the task file's findings and the source files among them, since a count quoted from a row was wrong or stale in ten places across four plans
59
- - Name the validate and audit calls the written plan passes through, since nothing else opens a plan and the audit caught ban hits in three of four trial plans
60
- - State the shared board as read-only and name the cross-feature call as the controller's, since a planner reading blockers and file sets can write a merge order off a partial picture and will not notice that it has
61
- - Owe an announcement when the record lands, carrying the path and what the row got wrong, since the controller cannot watch the read happen
62
- - Owe a message before a block becomes an interactive prompt, since a session already waiting on input never reaches the tool round an inbound message drains at
63
- - Keep correcting the dispatcher a first-class move carrying its evidence, since a trial corrected a brief's premise, planned every row anyway, and carried the consequence into a plan question
64
- - Carry a talk clause for a launch whose operator is in the session, putting each open question to them, recording a settled pick in place, sending an ask about a row now building to the controller rather than the worker, and owing a close message when they end the conversation, since a cold planner's halting rules contradict a brief that asks it to talk
65
- - Point at each of the three skills for its record's shape and the steps that write it
66
- - Defer the addressee resolution to `session-relay` and keep only the last-rung inference, which discriminates differently here than it does for a worker because a session in this role holds no feature branch either
16
+ - One role covers `plan-feature`, `plan-groundwork`, and `plan-intake`, writing records and never source, with each scope's exceptions left to its own skill
17
+ - The in-flight read composes the session roster with open pull requests once per task, and never counts a branch or a worktree as evidence
18
+ - A plan rests on the task file's findings and the source files rather than on counts quoted from the row
19
+ - Every record passes the validate and audit calls before it is announced, and the announcement carries the path and what the row got wrong
20
+ - A block goes out as a message before it becomes a prompt, a correction to the dispatcher carries its evidence, and a talk launch puts each open question to the operator
67
21
 
68
22
  ## Must not
69
23
 
70
- - Restate a record's sections, its suggested-and-answer contract, or the steps the running skill carries, since thinness is what keeps one body correct for a dispatched session reading it as its whole contract
71
- - Restate the write-scope exceptions each of the three skills states about its own folder
72
- - Restate a boundary `role-orchestrator` or `role-worker` states about itself
73
- - Tell a planner to halt on a plan question, which the suggested line already answers, rather than on what blocks writing the plan at all. A talk launch is the exception, since putting the question to the operator in the session is its job.
74
- - Tell a planner to report the path with no account of what the row got wrong. That instruction came from a trial condition holding a blind comparison intact, and it is not a durable obligation.
75
- - Report progress through the channel, which rebuilds on the sender's side the poll the announcement exists to retire
76
- - Write the priority board or the backlog, at any size, or the task file outside `plan-groundwork`'s close-time exception
77
- - Be a skill nothing invokes but its author typing the name. `orchestrator-launch.md` names it on the planning launch the way it names `role-worker` on a build, so a stretch where only a typed invocation reaches it is the signal that the role never took.
78
-
79
- ## Guards
80
-
81
- - Task file does not resolve from where the session stands: report it unreadable and name the main-root path, rather than reporting the row as absent
82
- - A read of what is in flight returns nothing: report that no pull request is open and no live session holds another branch, rather than falling back to a raw branch or worktree count
83
- - Launch named no controlling session and an operator is present: ask which row to address rather than inferring
84
- - Launch named no controlling session and nobody is present: infer from the sessions holding no feature branch, never from a name prefix, and say the addressee was inferred
24
+ - Write the priority board or the backlog, or a task file outside the close-time exception `plan-groundwork` states
25
+ - Decide which rows run or in what order
26
+ - Restate a record's sections, its answer contract, or the steps the running skill carries
27
+ - Halt on a plan question the suggested line already answers, outside a talk launch
28
+ - Report progress through the channel
85
29
 
86
30
  ## Out of scope
87
31
 
88
- - Each record's sections and its answer contract, which the standard behind it fixes, and the steps that write the file, which `plan-feature`, `plan-groundwork`, and `plan-intake` each own for their own
89
- - The write-scope exceptions, which stay in the three skills: groundwork's close-time task file, its fixture and evidence paths, and intake's statement that it has none
90
- - The mechanical addressee resolution, which `session-relay` owns for every session with or without a role
32
+ - Each record's sections, answer contract, write-scope exceptions, and writing steps, which `plan-feature`, `plan-groundwork`, and `plan-intake` own
33
+ - Resolving an addressee, which `session-relay` owns
91
34
  - The branch, the build, and the pull request, which `role-worker` and `auto-ship` own
92
- - Deciding which rows run and in what order, which is the controlling session's call and stated in `role-orchestrator`
93
- - The dispatch itself, its collision check, and its conflict check, which `orchestrator-dispatch.md` holds
35
+ - Choosing which rows run, their order, and the dispatch with its collision and conflict checks, which `role-orchestrator` owns
@@ -72,7 +72,8 @@ The plan standard fixes that block for a feature plan, and a groundwork or intak
72
72
 
73
73
  ## The board is read-only
74
74
 
75
- - Never write `.canon/tasks/priority.md` or `.canon/tasks/backlog.md`. Both are gitignored, so an overwrite drops a row with no history to recover it from.
75
+ - Never write `.canon/tasks/priority.md` or `.canon/tasks/backlog.md` by hand. Both are gitignored, so an overwrite drops a row with no history to recover it from.
76
+ - `canon tasks plan-link` is the one board write this role makes. It moves the row out of `## Needs a plan` once the plan is linked, in one read and one write a hand edit cannot match.
76
77
  - Never write the task file. The record is the whole output, and a row edited from here changes what the controller reads back as the board's state.
77
78
  - Report what the row got wrong rather than repairing it, such as a stale count or a dead path, in the record and the handback. The controller decides which carries the correction.
78
79
  - Leave the cross-feature call alone. `priority.md` shows enough to write a confident merge order off a partial picture, which is the failure this boundary prevents.
@@ -7,58 +7,30 @@ description: What a building session is, the shared surfaces it may not write, a
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, a building session is told what to do and never what it is. One shipped body asserts a session role and it is the orchestrator, so worker behavior spreads across three skills that each own a step and none of them names the role or the channel it runs on. The handback works because a session reading plain text tends to follow it rather than because anything says it should, which held while a person launched every worker and stopped holding the first time one ran with nobody watching.
10
+ Without this skill, a building session is told what to do and never what it is. It writes shared surfaces, hand-writing the board from a stale copy, filing a task with no row, or re-drafting a readied pull request. From a linked worktree it finds no plan folder and reports the task has no plan.
11
11
 
12
- The session then writes surfaces nothing told it were shared. One worker split a concern its own run could not reach, hand-wrote the priority board from a copy taken minutes earlier, and reverted a promotion with nothing reporting it, on a board that still validated afterwards because a reverted row is a well-formed board. A second added a row and labelled it with an identifier another row already held. The rule against both sits inside the controlling session's own body, which no worker loads.
13
-
14
- Standing in a linked worktree fails one step earlier and reports confidently while it does. The plan folder is gitignored, so `git worktree add` never creates it, and a worker reading it from the build tree reports that the task has no plan. That is true from where the session stands and wrong about the world, and a reader holding no second tree cannot tell those apart. Three workers hit it in one day and an absolute path unblocked all three.
15
-
16
- A blocked worker reaches nobody at all. Two dispatched sessions opened an interactive prompt inside a background session no operator was attached to, and the roster read both as alive throughout. An answer relayed afterwards arrives and does not land, since a queued message drains at the next tool round and a session waiting on input never reaches one, so the channel closes the gap only when it is used before the prompt opens. One of the two held uncommitted work across three files, which made stopping and relaunching a destructive recovery rather than a free one.
17
-
18
- Finishing is invisible from the other side. A worker that opens a pull request goes idle rather than exiting, so the one push signal available fired for a worker that was stopped and never fired for the one that finished, which then sat unnoticed for eighteen minutes. Polling covers that interval by spending a fixed cost against a worker with no pull request to report, measured as five consecutive runs reporting no movement across roughly fifteen minutes while one worker built.
19
-
20
- Nothing tells the session that refusing is allowed either. Four occasions across two days had a worker halt correctly with the cost falling on the dispatcher, and the correction that mattered most reached the right place because a worker argued back with evidence rather than complying. A role written only as report-upward suppresses exactly that.
21
-
22
- The draft mark fails from both ends. On 2026-08-31 four sessions re-drafted a pull request someone had readied, acting on a belief no surface in the tree stated. On 2026-09-07 a controlling session told a worker to lift the mark rather than lifting it itself, and the worker complied and reported against the surface rather than the outcome. From 2026-10-12 `canon pr lift` reads the gates itself, so the reviewers run it on a close and the controlling session runs it as the fallback. A worker leaves the verb to them and readies a pull request directly for nobody, since a direct ready skips every gate the verb reads.
12
+ The channel fails on the worker's side. Blocks open prompts nobody is attached to, and a finished pull request goes idle unannounced or stalls silently on its reviews. Painted ones ship with no address for the UI reviewer. Late asks widen the reviewed scope, and a worker told only to report upward never argues back.
23
13
 
24
14
  ## Must
25
15
 
26
- - Assert what a building session is, what it may not do, and how long the role lasts, since the three step-owning skills each carry a procedure and none carries a role
27
- - State that session scratch resolves at the main worktree root, since a linked worktree holds none of those folders and their absence reads as a missing artifact rather than as a wrong vantage
28
- - State the shared board as read-only for a building session and name what it does instead when a row is owed, since a task file with no row is a dropped task and placing the row is the controlling session's call
29
- - Owe an announcement the moment the pull request opens, carrying the number, the branch, and the task, since that transition is the one interval only the worker can observe
30
- - Carry a row the build turned up in the pull request announcement, and send it alone only when the session ends before a pull request opens, since the worker files no task file of its own and the channel is the row's only route
31
- - Carry a fan-in member's branch and head commit in its done message in place of a pull request number, and end its role at the push, since a member opens no pull request and its integrator fixes what the merge surfaces
32
- - Send the controller the `canon pr review-state` record when a wait for the reviews times out, rather than waiting on, since a worker improvising that read stalled silently with both reviewers idle behind it
33
- - Owe a message before a block becomes an interactive prompt, since a session already waiting on input never reaches the tool round an inbound message drains at
34
- - Defer the addressee resolution to `session-relay` and keep only the operator ask and the last-rung inference, which discriminates here because a worker holds a feature branch and a controller does not, and which falls back to the roster and says so, since an operator's own launch names nobody
35
- - Keep refusing a dispatcher a first-class move carrying its evidence, since the halts measured so far were correct and the cost of each fell where it belonged
36
- - State that a held body may be older than the branch under it, since a plugin skill loads from the marketplace cache rather than from the working tree
37
- - Carry a talk clause for a launch whose operator is in the session, asking them at a judgment call and sending a close message when they end the conversation, since a cold worker's halt-toward-the-controller and merge-ends-the-role rules contradict a brief that asks it to talk
38
- - Freeze the plan's scope at dispatch, sorting a late ask into a defect to fix, a follow-up row to report, or an addition the operator's word admits with its re-review cost stated, since intake 155 measured about four UI review rounds on one pull request from late asks, each re-running both reviews
39
- - Own the local preview server for a painted diff, started as a tracked background command before the pull request opens, since a `no-server` read leaves the evidence comment and the UI reviewer without an address on the one path nobody watched being built (erclx/frameboard#1 and erclx/frameboard#4)
40
- - Point at `session-worktree`, `auto-ship`, and `review-address` for the steps each already owns
16
+ - Session scratch resolves at the main worktree root, and a plan that fails to resolve is reported unreadable from there rather than absent
17
+ - The pull request announcement carries the number, the branch, the task, the reach, and any row the build turned up, and a painted diff has its preview server running before the pull request opens
18
+ - A block goes out as a message before it becomes a prompt, a fan-in member's done message carries its branch and head commit, and a review wait that times out reaches the controller
19
+ - The plan's scope freezes at dispatch, and a late ask is sorted into a defect, a follow-up row, or an addition on the operator's word
20
+ - A refusal of an instruction the tree contradicts carries its evidence, and a talk launch puts its judgment calls to the operator in the session
41
21
 
42
22
  ## Must not
43
23
 
44
- - Restate a procedure any of the three step-owning skills carries, since thinness is what keeps one body correct for a dispatched worker reading it as its whole contract and for a hand-launched one reading it beside a person
45
- - Restate a boundary the orchestrator already states about itself
46
- - Report progress through the channel, which rebuilds on the sender's side the poll the announcement exists to retire
47
24
  - Write the priority board or the backlog, at any size
48
- - Create a task file for work the build turns up, through `task-board` or by hand, since the file lands with no row and the placement is not the worker's to make
49
- - Be a skill nothing invokes but its author typing the name. `auto-ship` Step 0 invokes it on every build, dispatched or hand-launched, so a stretch where only a typed invocation reaches it is the signal that the role never took.
50
-
51
- ## Guards
52
-
53
- - Plan path does not resolve from inside the worktree: report it unreadable from here and name the main-root path, rather than reporting the task as having no plan
54
- - Plan carries a suggestion written as needing the operator's call: halt and message, rather than answering it
55
- - Launch named no controlling session: resolve from the roster, address the match, and say the addressee was inferred
56
- - No live session holds the other end: report what would have been sent and stop, rather than retrying or waiting
25
+ - Create a task file for work the build turns up
26
+ - Ready the pull request directly, or re-draft one someone readied
27
+ - Report progress through the channel
28
+ - Restate a procedure `session-worktree`, `auto-ship`, or `review-address` carries
57
29
 
58
30
  ## Out of scope
59
31
 
60
32
  - Entering the worktree, which `session-worktree` owns
61
33
  - The chain from implement through pull request, which `auto-ship` owns
62
- - How the build moves through the plan, slice by slice with a commit each, which `build-in-slices` owns
34
+ - Moving through the plan slice by slice, which `build-in-slices` owns
63
35
  - Answering a posted review, which `review-address` owns
64
- - The controlling session's half of the channel, the review poll, and the watch beside it, which `role-orchestrator` and its runbooks hold
36
+ - The controlling session's half of the channel and the review poll, which `role-orchestrator` owns
@@ -51,6 +51,15 @@ A painted pull request needs a server in this worktree for `canon pr local` to f
51
51
 
52
52
  A hand-run `git-ship` or `git-pr` starts no server, since only a worker has a lifetime to own one.
53
53
 
54
+ ### Building against a design reference
55
+
56
+ A plan carrying a `**Design references:**` section names the accepted design for the surface it changes. Open it before building, since the build matches it and a worker that reads the dark image alone ships a light theme nobody saw.
57
+
58
+ - Open each cited folder's light and dark images and its frame HTML before the first edit to that surface
59
+ - Take sizes, spacing, and colors from the frame HTML rather than from the image
60
+ - Report a reference that does not resolve in the working tree, naming the path, rather than building without it
61
+ - Leave `None identified.` as it stands and build without a reference
62
+
54
63
  ## Scope after dispatch
55
64
 
56
65
  The plan is the scope from the dispatch on. A late ask restarts both reviews, and one pull request took about four UI review rounds from asks that arrived mid-build.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: script-screencast
3
+ description: Why a recording script ships pre-seeded rather than blank, what the four discovery questions buy, and why the draft stays stack-agnostic
4
+ ---
5
+
6
+ # Script screencast requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a recording plan arrives as a wall of blank fields, so the user fills a template instead of editing a draft and the work the skill was meant to do lands back on them. The opposite failure costs more. A session that skips discovery guesses the audience, the length, and the hero moment, then writes five beats for a video nobody asked for, and every one of them has to be thrown away rather than edited.
11
+
12
+ A draft that names the recording software, the editing software, or the window manager pins the script to one machine and one person's setup, so it stops being reusable the moment anyone else records. And re-invoking to refine silently overwrites the edits the user made in the file, which is the one failure that destroys work rather than wasting it.
13
+
14
+ ## Must
15
+
16
+ - Read project context and recent commits before proposing, since what shipped recently is usually the subject
17
+ - Ask exactly four discovery questions, each carrying a default derived from that context
18
+ - Wait for answers rather than reading silence as acceptance
19
+ - Pre-seed every section with concrete content so the draft is shippable as written and the user edits down
20
+ - Derive the slug from the topic and the discovery answers
21
+ - Write to `demos/<slug>/beats.md` at the project root, the committed folder the rest of the demo lives in, and print that path on its own line
22
+ - Seed a wrap section naming intro, outro, and music with a default each, so the choice of what surrounds the take is made at draft time rather than discovered at compose time
23
+
24
+ ## Must not
25
+
26
+ - Name recording software, editing software, fonts, or window managers
27
+ - Record, edit video, or generate captions
28
+ - Re-run against an existing draft to refine it, since re-running overwrites
29
+ - Infer the hero moment without asking, which is the beat the whole script is built around
30
+
31
+ ## Guards
32
+
33
+ - No topic provided: stop rather than guessing what is being recorded
34
+
35
+ ## Out of scope
36
+
37
+ - Producing the recording, which `record-screencast` owns
38
+ - Refining an existing draft, which is a direct edit of the file
39
+ - Slide decks, which `make-deck` owns
40
+ - Where the recording ships, which the draft lists and the user decides