@erclx/canon 5.32.0 → 5.34.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 (250) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/api-design/REQUIREMENT.md +1 -2
  3. package/claude/skills/api-design/SKILL.md +2 -3
  4. package/claude/skills/api-design/references/adopted.md +1 -1
  5. package/claude/skills/auto-ship/SKILL.md +1 -1
  6. package/claude/skills/auto-ship/references/worktree-name.md +1 -1
  7. package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
  8. package/claude/skills/backlog-triage/SKILL.md +1 -1
  9. package/claude/skills/canon-cli/REQUIREMENT.md +16 -13
  10. package/claude/skills/canon-cli/SKILL.md +75 -32
  11. package/claude/skills/canon-feedback/REQUIREMENT.md +1 -0
  12. package/claude/skills/canon-feedback/SKILL.md +11 -29
  13. package/claude/skills/canon-feedback/references/template.md +53 -0
  14. package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +2 -2
  15. package/claude/skills/{canvas → canvas-board}/SKILL.md +6 -3
  16. package/claude/skills/{canvas → canvas-board}/references/canvas.md +26 -3
  17. package/{standards → claude/skills/canvas-board/references}/design.md +11 -2
  18. package/claude/skills/code-craft/REQUIREMENT.md +1 -1
  19. package/claude/skills/code-craft/SKILL.md +0 -1
  20. package/claude/skills/context-fold/REQUIREMENT.md +25 -33
  21. package/claude/skills/context-fold/SKILL.md +25 -70
  22. package/claude/skills/context-fold/references/classify.md +3 -3
  23. package/claude/skills/context-fold/references/completion-report.md +4 -4
  24. package/claude/skills/context-fold/references/context-refresh.md +5 -5
  25. package/{standards → claude/skills/context-fold/references}/context.md +16 -5
  26. package/claude/skills/context-fold/references/unusable-baseline.md +3 -5
  27. package/claude/skills/create-rule/SKILL.md +3 -3
  28. package/{standards → claude/skills/create-rule/references}/rule.md +15 -6
  29. package/claude/skills/create-skill/SKILL.md +2 -2
  30. package/{standards → claude/skills/create-skill/references}/skill.md +18 -15
  31. package/claude/skills/design-taste/REQUIREMENT.md +3 -3
  32. package/claude/skills/design-taste/SKILL.md +1 -1
  33. package/claude/skills/docs-sync/REQUIREMENT.md +1 -1
  34. package/claude/skills/docs-sync/SKILL.md +3 -3
  35. package/{standards → claude/skills/docs-sync/references}/docs.md +11 -0
  36. package/{standards → claude/skills/docs-sync/references}/readme.md +9 -2
  37. package/claude/skills/draft-and-pick/SKILL.md +5 -5
  38. package/claude/skills/draft-doc/SKILL.md +6 -6
  39. package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
  40. package/claude/skills/draft-figure/SKILL.md +2 -2
  41. package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
  42. package/claude/skills/draft-figure/references/mermaid-path.md +1 -1
  43. package/claude/skills/draft-identity/REQUIREMENT.md +2 -2
  44. package/claude/skills/draft-identity/SKILL.md +2 -2
  45. package/claude/skills/draft-ready/SKILL.md +1 -1
  46. package/claude/skills/git-branch/SKILL.md +1 -1
  47. package/{standards → claude/skills/git-branch/references}/branch.md +1 -1
  48. package/claude/skills/git-commit/SKILL.md +2 -2
  49. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  50. package/claude/skills/git-followup/SKILL.md +1 -1
  51. package/claude/skills/git-issue/SKILL.md +1 -1
  52. package/claude/skills/git-issue/references/issue.md +4 -1
  53. package/claude/skills/git-pr/SKILL.md +13 -13
  54. package/claude/skills/git-pr/references/evidence.md +2 -2
  55. package/claude/skills/git-pr/references/final-command.md +38 -14
  56. package/claude/skills/git-pr/references/labels.md +5 -1
  57. package/{standards → claude/skills/git-pr/references}/pr.md +19 -9
  58. package/{standards → claude/skills/git-pr/references}/publish.md +4 -2
  59. package/claude/skills/git-pr/references/task-number.md +1 -1
  60. package/claude/skills/git-ship/SKILL.md +15 -14
  61. package/claude/skills/git-split/SKILL.md +3 -3
  62. package/claude/skills/git-stage/SKILL.md +1 -1
  63. package/claude/skills/plan-feature/REQUIREMENT.md +1 -1
  64. package/claude/skills/review-address/SKILL.md +1 -1
  65. package/claude/skills/review-address/references/post-review-findings.md +1 -1
  66. package/claude/skills/review-craft/references/ui.md +1 -1
  67. package/claude/skills/review-pr/REQUIREMENT.md +1 -1
  68. package/claude/skills/review-pr/SKILL.md +3 -3
  69. package/claude/skills/review-pr/references/body-variants.md +2 -2
  70. package/claude/skills/review-pr/references/key-changes.md +3 -3
  71. package/claude/skills/review-pr/references/post.md +4 -2
  72. package/claude/skills/review-ui/REQUIREMENT.md +1 -1
  73. package/claude/skills/review-ui/SKILL.md +8 -6
  74. package/claude/skills/review-ui/references/driving.md +8 -8
  75. package/claude/skills/review-ui/references/post.md +53 -17
  76. package/claude/skills/role-orchestrator/REQUIREMENT.md +3 -0
  77. package/claude/skills/role-orchestrator/SKILL.md +2 -2
  78. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +2 -2
  79. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +8 -5
  80. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +32 -1
  81. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +2 -2
  82. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +3 -0
  83. package/claude/skills/role-planner/REQUIREMENT.md +2 -1
  84. package/claude/skills/role-planner/SKILL.md +13 -2
  85. package/claude/skills/role-reviewer/SKILL.md +1 -1
  86. package/claude/skills/role-worker/REQUIREMENT.md +1 -0
  87. package/claude/skills/role-worker/SKILL.md +9 -1
  88. package/claude/skills/session-map/SKILL.md +1 -1
  89. package/claude/skills/session-resume/REQUIREMENT.md +2 -2
  90. package/claude/skills/session-worktree/SKILL.md +5 -5
  91. package/claude/skills/target-setup/SKILL.md +10 -4
  92. package/claude/skills/target-setup/references/detect.md +20 -3
  93. package/claude/skills/task-board/REQUIREMENT.md +7 -12
  94. package/claude/skills/task-board/SKILL.md +5 -17
  95. package/claude/skills/task-board/references/tasks.md +2 -2
  96. package/claude/skills/task-complete/REQUIREMENT.md +47 -0
  97. package/claude/skills/task-complete/SKILL.md +86 -0
  98. package/claude/skills/{task-board → task-complete}/references/archive.md +4 -4
  99. package/claude/skills/{context-fold → task-complete}/references/receipt-sweep.md +5 -5
  100. package/claude/skills/task-complete/references/unusable-baseline.md +19 -0
  101. package/claude/skills/teach-workspace/REQUIREMENT.md +6 -2
  102. package/claude/skills/teach-workspace/SKILL.md +8 -4
  103. package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
  104. package/claude/skills/{context-fold/references/promoted-pages.md → teach-workspace/references/promotion-fold.md} +3 -3
  105. package/claude/skills/teach-workspace/references/promotion.md +3 -3
  106. package/claude/skills/test-craft/REQUIREMENT.md +2 -3
  107. package/claude/skills/test-craft/SKILL.md +15 -3
  108. package/claude/skills/ui-checklist/SKILL.md +1 -1
  109. package/claude/skills/ux-audit/SKILL.md +1 -1
  110. package/claude/skills/ux-measure/SKILL.md +1 -1
  111. package/docs/agents/canvas.md +6 -2
  112. package/docs/agents/commands.md +4 -3
  113. package/docs/agents/context-audit-checks.md +4 -4
  114. package/docs/agents/gov-detect.md +47 -0
  115. package/docs/agents/index.md +7 -4
  116. package/docs/agents/indexes.md +1 -1
  117. package/docs/agents/install-and-sync.md +10 -11
  118. package/docs/agents/key-changes.md +5 -5
  119. package/docs/agents/label-coverage.md +11 -0
  120. package/docs/agents/migrate.md +1 -1
  121. package/docs/agents/pr-evidence-layout.md +70 -0
  122. package/docs/agents/pr-evidence.md +8 -9
  123. package/docs/agents/pr-frames.md +7 -2
  124. package/docs/agents/pr-lift.md +132 -0
  125. package/docs/agents/records-push.md +2 -2
  126. package/docs/agents/records-stale.md +12 -47
  127. package/docs/agents/records-validate.md +3 -7
  128. package/docs/agents/records.md +5 -27
  129. package/docs/agents/rule-citations.md +1 -1
  130. package/docs/agents/sandbox.md +4 -4
  131. package/docs/agents/scripting.md +2 -1
  132. package/docs/agents/skills-audit.md +1 -1
  133. package/docs/agents/tasks-plans.md +2 -2
  134. package/docs/agents/tasks.md +2 -2
  135. package/docs/target/migrations.md +10 -2
  136. package/docs/target/projects.md +4 -4
  137. package/docs/target/sync.md +1 -1
  138. package/docs/workflow/operating-model.md +2 -2
  139. package/docs/workflow/parallel-features.md +7 -7
  140. package/docs/workflow/skill-map-on-request.md +9 -9
  141. package/docs/workflow/skill-map.md +12 -11
  142. package/docs/workflow/visual-design-workflow.md +2 -2
  143. package/governance/detect.toml +201 -0
  144. package/governance/renames.toml +0 -11
  145. package/governance/rules/canon/context.md +13 -0
  146. package/governance/rules/claude/skill.md +17 -0
  147. package/governance/rules/code/000-code.md +1 -13
  148. package/governance/rules/code/010-testing.md +2 -30
  149. package/governance/rules/ui/400-ui.md +1 -1
  150. package/governance/rules/ui/480-canvas.md +13 -0
  151. package/governance/stacks/base.toml +2 -4
  152. package/package.json +4 -4
  153. package/scripts/core/install-check.sh +3 -3
  154. package/scripts/core/regen-hero.ts +0 -6
  155. package/scripts/lib/ui.sh +0 -168
  156. package/src/audits/catalog.ts +0 -1
  157. package/src/canvas/arrange.ts +66 -0
  158. package/src/canvas/capture.ts +20 -6
  159. package/src/canvas/content.ts +39 -0
  160. package/src/canvas/fit.ts +238 -0
  161. package/src/canvas/tokens.ts +28 -10
  162. package/src/capture/frame-values.ts +2 -32
  163. package/src/claude/cases/misc.ts +1 -1
  164. package/src/claude/cases/setup.ts +4 -0
  165. package/src/claude/cases/workflow.ts +6 -1
  166. package/src/claude/seeds.ts +1 -1
  167. package/src/claude/skills-audit.ts +2 -2
  168. package/src/cli/help.ts +3 -1
  169. package/src/cli/ui.ts +2 -3
  170. package/src/commands/canvas.ts +179 -1
  171. package/src/commands/claude.ts +1 -1
  172. package/src/commands/gov.ts +146 -16
  173. package/src/commands/labels.ts +326 -7
  174. package/src/commands/migrate.ts +6 -1
  175. package/src/commands/pr.ts +377 -2
  176. package/src/commands/records.ts +13 -399
  177. package/src/commands/sandbox.ts +3 -6
  178. package/src/commands/tasks.ts +3 -3
  179. package/src/context/audit.ts +5 -5
  180. package/src/context/folders.ts +1 -1
  181. package/src/design/budget.ts +1 -1
  182. package/src/design/components.ts +1 -1
  183. package/src/design/document.ts +1 -1
  184. package/src/design/regen.ts +1 -1
  185. package/src/design/render.ts +1 -1
  186. package/src/feedback/body.ts +26 -5
  187. package/src/gate/measures.ts +59 -45
  188. package/src/gate/sequencer.ts +56 -1
  189. package/src/gate/stages.ts +4 -11
  190. package/src/gov/detect.ts +301 -0
  191. package/src/gov/install.ts +2 -3
  192. package/src/gov/list.ts +23 -2
  193. package/src/gov/stacks.ts +10 -1
  194. package/src/hooks/post-merge.ts +1 -1
  195. package/src/labels/apply.ts +39 -0
  196. package/src/labels/format.ts +3 -3
  197. package/src/labels/phase.ts +3 -3
  198. package/src/labels/sections.ts +43 -0
  199. package/src/migrate/skill-names.ts +20 -1
  200. package/src/pr/evidence.ts +218 -45
  201. package/src/pr/frames.ts +23 -3
  202. package/src/pr/lift.ts +418 -0
  203. package/src/pr/paths.ts +4 -4
  204. package/src/pr/rest.ts +3 -0
  205. package/src/pr/review-scope.ts +76 -0
  206. package/src/records/backup.ts +16 -6
  207. package/src/records/stale-canonical.ts +31 -1
  208. package/src/records/validate.ts +2 -188
  209. package/src/sandbox/census.ts +1 -1
  210. package/src/sandbox/coverage.ts +2 -6
  211. package/src/sandbox/equivalence.ts +19 -51
  212. package/src/sandbox/expect.ts +4 -4
  213. package/src/sandbox/provision.ts +13 -36
  214. package/src/sandbox/scenario.ts +26 -48
  215. package/src/sandbox/tree.ts +2 -6
  216. package/src/standards/read.ts +14 -1
  217. package/src/sync/git.ts +1 -1
  218. package/src/tasks/archive.ts +5 -5
  219. package/src/tasks/branch.ts +3 -3
  220. package/src/tasks/label.ts +1 -1
  221. package/src/tasks/record.ts +2 -2
  222. package/src/tasks/validate.ts +1 -1
  223. package/standards/index.md +0 -13
  224. package/standards/standard.md +1 -7
  225. package/tooling/base/reference.md +1 -1
  226. package/tooling/base/seeds/.github/pull_request_template.md +2 -2
  227. package/tooling/claude/reference.md +1 -1
  228. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +9 -1
  229. package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +171 -0
  230. package/tooling/claude/seeds/.claude/settings.json +9 -0
  231. package/governance/rules/standards/context.md +0 -14
  232. package/governance/rules/standards/design.md +0 -12
  233. package/governance/rules/standards/readme.md +0 -12
  234. package/governance/rules/standards/rule.md +0 -13
  235. package/governance/rules/standards/skill.md +0 -21
  236. package/governance/rules/standards/standard.md +0 -13
  237. package/scripts/config.sh +0 -11
  238. package/scripts/lib/gov.sh +0 -14
  239. package/scripts/lib/sandbox-fixtures.sh +0 -191
  240. package/scripts/lib/sandbox-git.sh +0 -125
  241. package/scripts/lib/sandbox-path.sh +0 -50
  242. package/scripts/sandbox-hook.sh +0 -99
  243. package/src/gov/standard-rules.ts +0 -179
  244. package/src/records/migrate.ts +0 -78
  245. package/src/records/stale.ts +0 -243
  246. package/src/sandbox/hooks.ts +0 -128
  247. /package/{standards → claude/skills/draft-figure/references}/figures.md +0 -0
  248. /package/{standards → claude/skills/git-branch/references}/slug.md +0 -0
  249. /package/{standards → claude/skills/git-commit/references}/commit.md +0 -0
  250. /package/{standards → claude/skills/git-commit/references}/versioning.md +0 -0
@@ -59,10 +59,10 @@ Report the state of play in the invocation block, and open every later sweep rep
59
59
 
60
60
  ## The loop
61
61
 
62
- 1. Plan the next feature. The cross-feature call stays in this warm session, being which rows conflict, what merges before what, and whether a row should run at all. Per-row planning runs either way: `plan-feature` here with that context, or a cold planner dispatched under `role-planner` through the planning shape in `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md`. Every plan written from here also carries a constraint per track in flight, which the paragraph below this list states.
62
+ 1. Plan the next feature. The cross-feature call stays in this warm session, being which rows conflict, what merges before what, and whether a row should run at all. Per-row planning runs either way: `plan-feature` here with that context, or a cold planner dispatched under `role-planner` through the planning shape in `${CLAUDE_SKILL_DIR}/references/orchestrator-launch.md`, or a talk planner from that file's talk shape when the operator wants to shape the row with the session. Every plan written from here also carries a constraint per track in flight, which the paragraph below this list states.
63
63
  2. Decide parallelism and merge order. Note which plans depend on another or change a contract another consumes, since those hold, and which merely share a file, since those build together and the second to merge rebases.
64
64
  3. Verify the plan against the tree. Reading it is not enough, since a plan goes stale from whatever merged after it was written. Grep for each construct it names and count the sites against the count it claims. Check that every phase label it cites is still open. Open each file it describes rather than trusting its account of the contents. Correct the plan before handing it over.
65
- 4. Hand off. Read `${CLAUDE_SKILL_DIR}/references/orchestrator-dispatch.md` and follow it: check the branch is unclaimed, run its conflict check against every track in flight, then dispatch a background worker with `claude --bg`. Fall back to the human-launch line it replaces when the branch check refuses or the conflict check holds the row behind something already out.
65
+ 4. Hand off. Read `${CLAUDE_SKILL_DIR}/references/orchestrator-dispatch.md` and follow it: check the branch is unclaimed, run its conflict check against every track in flight, then dispatch a background worker with `claude --bg`. Fall back to the human-launch line it replaces when the branch check refuses or the conflict check holds the row behind something already out. Where the operator wants to talk with the worker, launch the talk build from the talk shape in the launch runbook after the same checks clear.
66
66
  5. Review the PR. When a worker opens a PR, its first pass runs through `review-pr` in a reviewer dispatched under `role-reviewer` when `### The review dispatch` below fires, and in this session otherwise. Either is the deep, independent pass. The worker's chain carries no review step, so this is the first review the change gets.
67
67
  - Learning that a PR moved is the mechanical half, so read `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` and run the poll under the condition it states rather than checking the board by hand. That runbook holds the routing and the trigger, and a summary of it here is a second source that drifts from it.
68
68
  6. Dispatch the handback. A pass posting anything owed, a finding at any severity or a testing question, tells the session holding that branch to run `review-address`, rather than waiting for a person to relay it. Re-review when the worker's own message says the address pass finished, per the channel `role-worker` states, rather than polling for an answer nothing else marks as landed, and send the re-review back to the dispatched reviewer when one took the first pass. Once a pass posts `## Review closed`, a UI close names the current head wherever the PR carries a checklist, the poll run as `--check <number>` prints `CLEAR`, and `--check` reports `settled`, lift the pull request's draft mark yourself, per Boundaries below. Then the human merges. Tell each trailing worker whose files the merged diff touches to run `review-address`, which rebases it when it no longer merges or when `main` changed a file it writes, after each merge rather than once per wave.
@@ -23,7 +23,7 @@ Run this at loop step 4, for a `## Run now` row whose plan is verified, in place
23
23
  Run `canon tasks plan-branch <plan> --json` against the row's plan file and read `branch`, `type`, `slug`, and `conforms` off the record.
24
24
 
25
25
  - `conforms: true`: take `branch` as the candidate, and take `type` and `slug` from the same record for the check below.
26
- - `conforms: false`: the plan's own filename breaks a cap in `${CLAUDE_SKILL_DIR}/../../standards/branch.md`. Report which, and hand the row to the human-launch line below rather than shortening the slug here. A rename parts the branch from the plan filename that `session-worktree` tier 1 and `git-pr`'s plan lookup both read back.
26
+ - `conforms: false`: the plan's own filename breaks a cap in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md`. Report which, and hand the row to the human-launch line below rather than shortening the slug here. A rename parts the branch from the plan filename that `session-worktree` tier 1 and `git-pr`'s plan lookup both read back.
27
27
  - `reason: archived`, `no-plan`, or `bad-input`: the row does not cite a live plan. Repoint the row or fix the citation rather than dispatching, since `auto-ship` Step 1 refuses the same file and the worker would meet that refusal after the launch spent.
28
28
  - Anything else, including a record carrying no `branch` key and an installed binary carrying no `plan-branch` subcommand: treat the candidate as unverified rather than clear, name which reading could not be taken, and fall back to the human-launch line below. Re-deriving by prose here rebuilds the defect the verb closes, and does it quietly.
29
29
 
@@ -94,7 +94,7 @@ No practitioner source serializes on a shared file. Each builds in parallel and
94
94
 
95
95
  Read `canon sessions list --json` for the branches in flight as well as the board, since a track a person launched by hand carries no row, and read the plan of any branch no row names. `canon tasks validate` and `canon tasks plan-reach` report the paths two rows share, which is a candidate list for the five holds and the paths the dispatch names. A shared folder means a Touches cell claimed it bare, so narrow that cell rather than reading the folder as a sweep.
96
96
 
97
- A declared set predicts what a branch writes rather than bounding it, since `canon:context-fold`, `canon:docs-sync`, and the regenerated drift stages write past every plan. Such a crossing changes what the second branch rebases over rather than whether a row holds, and `canon tasks plan-reach` at `canon:git-ship` step 4 names it before the pull request opens. What binds past the five holds is review attention, which `## Parallelism` in the skill body states. The one number this skill carries is the review dispatch's count of three in `orchestrator-review-dispatch.md`, which moves a review rather than binding a track, and this runbook carries none.
97
+ A declared set predicts what a branch writes rather than bounding it, since `canon:context-fold`, `canon:docs-sync`, and the regenerated drift stages write past every plan. Such a crossing changes what the second branch rebases over rather than whether a row holds, and `canon tasks plan-reach` at `canon:git-ship` step 5 names it before the pull request opens. What binds past the five holds is review attention, which `## Parallelism` in the skill body states. The one number this skill carries is the review dispatch's count of three in `orchestrator-review-dispatch.md`, which moves a review rather than binding a track, and this runbook carries none.
98
98
 
99
99
  ## Pick the model
100
100
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Orchestrator handoff runbook
3
- description: Retirement act the wind-down owes the fleet it dispatched, the two sections an orchestrating session adds over the shared session map, where a lesson goes from a session that never commits, and the resume invocation the file carries out
3
+ description: Retirement act the wind-down owes the fleet it dispatched, the talk sessions it exempts, the three sections an orchestrating session adds over the shared session map, where a lesson goes from a session that never commits, and the resume invocation the file carries out
4
4
  ---
5
5
 
6
6
  ## Retire what the wave delivered
@@ -15,7 +15,9 @@ Name the planner as the case always in this set, and scope the act no narrower.
15
15
 
16
16
  ### Which sessions this session may retire unasked
17
17
 
18
- Retire what this session dispatched. Report a hand-launched session and leave the act to the operator, since the knowledge making the act safe is a delivery this session received and it received nothing from a session it never launched. The `worker-` and `planner-` name prefixes separate the two populations, per `orchestrator-dispatch.md`.
18
+ Retire what this session dispatched. Report a hand-launched session and leave the act to the operator, since the knowledge making the act safe is a delivery this session received and it received nothing from a session it never launched. The `worker-` and `planner-` name prefixes separate the two populations, per `orchestrator-launch.md`.
19
+
20
+ A talk session is the exception inside the dispatched population. Retire it only on the operator's word, given here or carried in the session's own close message, and never on its delivery, at wind-down or at any other point. Its plan landing or its pull request opening tells this session nothing about whether the conversation is over. Until the word arrives, report it as held open next to the hand-launched read. A talk session is found by the `sessionId` the prior map records or this session's own launch output carries, since the client can rename it and drop the `-talk` suffix `orchestrator-launch.md` gives it.
19
21
 
20
22
  A capability gap sits beside the knowledge gap, and it holds even where delivery is somehow known. A hand-launched session is as often interactive as background, and `claude rm <id>` has no id to take for an interactive one at all, so the command cannot reach it whatever this session learned about its delivery.
21
23
 
@@ -39,10 +41,11 @@ Report the retired sessions as a list, the hand-launched ones under it as a read
39
41
 
40
42
  Write the pre-compaction handoff as orchestrator. Invoke `canon:session-map` for the generic half, which is the filename, the three core sections, the write procedure, the drift step and the ref it reads, and the citation rule. Everything in this section is the extension this role adds over that core, and none of it belongs to a session holding no delegated authority.
41
43
 
42
- Settle both steps below before the door writes, so one write carries the core and the extension together. The door reports the map as written and knows nothing of this role, so its success line ends the generic half rather than this runbook, and a session that stops there ships a map missing both of the things this section adds to it.
44
+ Settle all three steps below before the door writes, so one write carries the core and the extension together. The door reports the map as written and knows nothing of this role, so its success line ends the generic half rather than this runbook, and a session that stops there ships a map missing everything this section adds to it.
43
45
 
44
46
  1. Add `## Decisions taken under delegated authority` directly after `## State`, holding each decision and why it went that way, so nobody re-proposes it. It sits there rather than after the core because a decision is read against the state it was taken in.
45
- 2. Close the file with the block below, resolving `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md` and `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` to absolute paths as you write it and pasting each in place of `<RESUME_RUNBOOK>` and `<POLL_RUNBOOK>`:
47
+ 2. Add `## Talk sessions held open` directly after that section, with one line per open talk session giving its name, its `sessionId`, and its row, or `None.` when there are none. The next session reads it to know which sessions it must not retire on a delivery.
48
+ 3. Close the file with the block below, resolving `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md` and `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` to absolute paths as you write it and pasting each in place of `<RESUME_RUNBOOK>` and `<POLL_RUNBOOK>`:
46
49
 
47
50
  ```markdown
48
51
  Resume by loading the orchestrator skill and asking it to resume after a compaction. This repository spells that `/canon:role-orchestrator` followed by the request. Following <RESUME_RUNBOOK> reaches the same place with no skill loaded at all.
@@ -52,7 +55,7 @@ That resume reads the board and stops. It restarts nothing, so the review poll i
52
55
 
53
56
  The delegated-authority section is the orchestrator's alone because a worker holds no delegation to have exercised, and a section a session cannot fill teaches its reader to skip the file. The closing block is the orchestrator's for the same reason from the other direction: it restarts a review poll no other role runs.
54
57
 
55
- The substitution belongs in step 2 because that step ends the write. A reader who treats the list as finished elsewhere ships the literal placeholders, and the variable expands while this runbook renders rather than in the turn that reads the handoff back, so a path left unresolved reaches a session holding no skill as a string matching nothing. `orchestrator-poll.md` resolves its script at the same point and for the same reason.
58
+ The substitution belongs in step 3 because that step ends the write. A reader who treats the list as finished elsewhere ships the literal placeholders, and the variable expands while this runbook renders rather than in the turn that reads the handoff back, so a path left unresolved reaches a session holding no skill as a string matching nothing. `orchestrator-poll.md` resolves its script at the same point and for the same reason.
56
59
 
57
60
  That block sits in this runbook and again in the file this runbook writes, which is the fix rather than a copy for a later pass to collapse. A session has to already be holding this runbook to read it, and a compaction that took the skill body took the routing to it too, so the session that most needs the resume is the one that can no longer find it. The map survives that, so it carries the invocation itself. Each of the two reaches a reader the other cannot.
58
61
 
@@ -1,10 +1,19 @@
1
1
  ---
2
2
  title: Orchestrator launch runbook
3
- description: The launch every dispatch kind shares, being the build, cloud build, review-address, and planning templates, the session name and controller id each carries, why the command sits at position zero, and what the brief may carry
3
+ description: The launch every dispatch kind shares, being the build, cloud build, review-address, planning, and talk templates, the session name and controller id each carries, why the command sits at position zero, and what the brief may carry
4
4
  ---
5
5
 
6
6
  Run this once `orchestrator-dispatch.md` has cleared a row, or from its planning or review-address shape below when that runbook's checks do not bind. The model each template names comes from `## Pick the model` in that runbook.
7
7
 
8
+ ## Contents
9
+
10
+ - [Dispatch](#dispatch)
11
+ - [Dispatch to a cloud worker](#dispatch-to-a-cloud-worker)
12
+ - [Dispatch to address a review](#dispatch-to-address-a-review)
13
+ - [Dispatch to plan a row](#dispatch-to-plan-a-row)
14
+ - [Dispatch a talk session](#dispatch-a-talk-session)
15
+ - [Dispatch a reviewer](#dispatch-a-reviewer)
16
+
8
17
  ## Dispatch
9
18
 
10
19
  ```bash
@@ -89,6 +98,28 @@ What a planning dispatch owes instead is the reverse reading, because the plan i
89
98
 
90
99
  One row per dispatch. A session reused across a batch pays the context load once and ages its picture of the tree while it works, which is what puts the in-flight read on the task rather than on the batch, and one that compacts mid-batch loses the reasoning behind its earlier plans with nothing reporting it. Cap a reused session where the saving is worth it and say what the cap was.
91
100
 
101
+ ## Dispatch a talk session
102
+
103
+ A planner or worker the operator will talk with takes the same launch as its cold shape above, with two changes. It carries a `-talk` suffix on its name, and its brief gains one sentence. A cold session works alone and reports back, and a talk session stays open after its plan or pull request lands so the operator can keep shaping the row with it.
104
+
105
+ Take the planning shape or the build shape and change those two things:
106
+
107
+ ```bash
108
+ claude --bg --model <model> -n "planner-<project>-<slug>-talk" "Run /canon:role-planner, then /canon:plan-feature <task>. This is a talk session: the operator will talk with you here, so run your role's talk clause, and message your controller when the operator ends the conversation. Your controller is the session whose sessionId is <dispatcher-id>. ..."
109
+ claude --bg --model <model> -n "worker-<project>-<slug>-talk" "/canon:auto-ship <plan>
110
+ This is a talk session: the operator will talk with you here, so run your role's talk clause, and message your controller when the operator ends the conversation. Your controller is the session whose sessionId is <dispatcher-id>. ..."
111
+ ```
112
+
113
+ The ellipsis stands for the rest of the cold template's message clauses, unchanged. The build variant keeps `/canon:auto-ship <plan>` at position zero with nothing before it, per the rule above.
114
+
115
+ Keep the role prefix and add the suffix rather than inventing a prefix. `orchestrator-handoff.md` separates dispatched sessions from hand-launched ones by `worker-` and `planner-`, so a new prefix would read as a hand launch and fall outside the retirement act.
116
+
117
+ Read the session's `sessionId` off the launch output and carry it in this session's own context, then write it into the map's `## Talk sessions held open` section at the next handoff. The map exists only once the handoff writes it, so the launches this session made, read from its own context with the prior map, are the source the first wind-down reads talk sessions from. The client can rename a session after launch and drop the suffix, so the id is the durable marker and the suffix is only for display.
118
+
119
+ A talk session is retired only on the operator's word, which `orchestrator-handoff.md` states under the retirement act. That runbook is the one place the rule lives, so do not restate it in a launch report.
120
+
121
+ Reviewers get no talk shape, since a reviewer's pass holds no operator dialogue.
122
+
92
123
  ## Dispatch a reviewer
93
124
 
94
125
  Read `${CLAUDE_SKILL_DIR}/references/orchestrator-reviewer-launch.md` when `orchestrator-review-dispatch.md` sends a pull request to a dispatched reviewer, for the code, cloud, and UI reviewer shapes.
@@ -14,7 +14,7 @@ It counts unclaimed plans against workers rather than reading the reserve in ste
14
14
  1. Run `gh pr list --state open` and `git log --oneline -8`. Report any pull request whose review has not been posted and stop for that one first.
15
15
  2. For each pull request merged since the last sweep, place every finding it produced. Route a finding that changes a rule to the standard or rule that states it, one that changes another task to that task's Findings, and one that overturns a groundwork lean to that folder marked answered. Never leave a finding in a pull request thread alone.
16
16
  3. Archive what closed.
17
- - A task whose outcomes are all `[x]` runs `context-fold` for the plan sweep, then `task-board` to archive
17
+ - A task whose outcomes are all `[x]` and whose pull request merged is archived by the `post-merge` hook through `canon tasks archive`, which carries its plans with it. Run `task-complete` to archive one the hook left in place
18
18
  - A task whose outcomes describe standing policy rather than a deliverable never closes on its own, so hand it to a worker to encode the policy where it is enforced, then cut the outcomes with the reason recorded and archive once that branch merges. Encoding it from this session would write a tracked file, which `## Boundaries` in the skill body forbids.
19
19
  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.
20
20
  5. Promote from the top of `## Needs a plan`, which is where the last sweep recorded what to plan next. Depart from that order when something has changed under it and say what changed, since a position nobody honors is the ordering going stale on the surface built to hold it. What sets the order in the first place is whether a task establishes functionality rather than how old it is, so prefer a task that adds or proves a mechanism over one that trims, tidies, or audits an existing surface.
@@ -50,4 +50,4 @@ Promoting, demoting, and archiving a row all write `.canon/tasks/priority.md`, a
50
50
  - Re-resolve every Plan pointer after anything archives a plan
51
51
  - Read the file back after writing it, since the row that lands is the row a worker acts on
52
52
 
53
- A Plan pointer goes stale from a branch this board never sees. `context-fold` moves a plan to `.canon/plans/archive/` and rewrites the citation in the task file alone, so a row for a task still on the board keeps pointing into `.canon/plans/` at a file that has moved. Workers running the ship chain on their own branches archive plans this board still cites, and the board reads as correct until a pointer is followed.
53
+ 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, so a row for a task still on the board keeps pointing into `.canon/plans/` at a file that has moved. `task-complete` marks outcomes on each worker's branch and moves nothing, so the move lands at the merge, and the board reads as correct until a pointer is followed.
@@ -17,8 +17,11 @@ Read: <task files>, <groundwork folders>
17
17
  Shipped since: <commits or PRs>
18
18
  Stale in the groundwork: <lean or number the shipped work overturned>
19
19
  Next: <the one or two tasks ready to hand a worker>
20
+ Held open: <talk sessions from the map's `## Talk sessions held open`, or none>
20
21
  ```
21
22
 
23
+ Read `Held open:` off the newest session map's `## Talk sessions held open`, so a resumed session does not mistake a conversation for a finished delivery. `orchestrator-handoff.md` states what ends one.
24
+
22
25
  Treat a groundwork folder as three kinds of content with different shelf lives. Trust the reasoning and the method, which stay correct. Re-measure every count, size, and cost, because they were true when written. Check every `Leaning:` against what has shipped, because work spawned by a track routinely overturns the lean that spawned it and nothing writes back.
23
26
 
24
27
  A plan a live task cites goes stale the same way, and `role-orchestrator` states the check that catches it.
@@ -61,6 +61,7 @@ four carried at least one, caught only because the planner ran
61
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
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
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, 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
64
65
  - Point at each of the three skills for its record's shape and the steps that write it
65
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
66
67
 
@@ -69,7 +70,7 @@ four carried at least one, caught only because the planner ran
69
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
70
71
  - Restate the write-scope exceptions each of the three skills states about its own folder
71
72
  - Restate a boundary `role-orchestrator` or `role-worker` states about itself
72
- - 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
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.
73
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.
74
75
  - Report progress through the channel, which rebuilds on the sender's side the poll the announcement exists to retire
75
76
  - Write the priority board or the backlog, at any size, or the task file outside `plan-groundwork`'s close-time exception
@@ -94,14 +94,25 @@ controller. Report the candidates and stop where more than one does, rather than
94
94
  addressing the first. Send to the single row where exactly one comes back, and
95
95
  say the addressee was inferred.
96
96
 
97
+ ## Talk launch
98
+
99
+ A launch whose brief says it is a talk session puts the operator in this one. Everything above holds, and the clause below changes how questions are answered and when the role ends. A launch carrying no such sentence takes none of this.
100
+
101
+ - Put each open question to the operator through the structured question surface before writing the record, and record a settled pick in place per the plan standard's answer-in-place rule. Never fill an `- Answer:` slot the operator did not answer.
102
+ - Keep answering under `plan-feature`'s discussion rounds after the record lands, since the operator launched this session to keep talking.
103
+ - Owe the landing announcement as usual, plus a close message when the operator ends the conversation.
104
+ - Skip the before-prompt block message for a question put to the operator who is in the session. Keep it for a block the operator cannot answer, since a controller learns of a stall only from a message.
105
+
106
+ The operator being present is an assumption the launch carries. A talk planner whose operator has walked away waits silently on its first question, so say what the session is waiting on in the turn it stops.
107
+
97
108
  ## Refusing is part of the job
98
109
 
99
110
  - Refuse an instruction the tree contradicts, and carry the evidence with it. Name the commands read and what complying would produce, rather than reporting reluctance.
100
111
  - Correct a premise the brief carried when the tree disagrees with it. One trial was told two rows were free of a renamed token and found they carried it as command names rather than path segments, planned all three rows anyway, and put the consequence into a plan question. Correct, continue, and record what the correction changed.
101
- - Answer a plan question rather than halting on it. Every question carries a `- Suggested:` line the operator accepts or overrules, so a judgment written down is the deliverable. Halt only on what blocks writing the record at all, and send that out as a message before it becomes a prompt.
112
+ - Answer a plan question rather than halting on it. Every question carries a `- Suggested:` line the operator accepts or overrules, so a judgment written down is the deliverable. Halt only on what blocks writing the record at all, and send that out as a message before it becomes a prompt. A talk launch is the exception, per `## Talk launch` above, where a question goes to the operator in the session.
102
113
 
103
114
  ## Lifetime
104
115
 
105
- - The role runs from the launch to the record landing, and one record closes it. A session handed a second row works it under the same role and reads the tree again for that row.
116
+ - The role runs from the launch to the record landing. The record closes the role, and the operator closes a talk session. A session handed a second row works it under the same role and reads the tree again for that row.
106
117
  - A reused session pays the context load once and stales differently. Its picture of the tree ages while it works, which is why the in-flight read runs per row, and it accumulates toward a compaction that drops the reasoning behind its earlier records with nothing reporting it. Cap a reused session rather than letting it run the board.
107
118
  - Treat this body as possibly older than the branch under it. A plugin skill loads from the marketplace cache rather than from the working tree.
@@ -35,7 +35,7 @@ from here.
35
35
 
36
36
  - Read the diff, the plan the branch built under, the task's `## Outcomes`, the rules the diff's paths load, and `review-craft`. That is the artifact and the contract the change answers to.
37
37
  - Read the pull request's `## For the reviewer` bullets and its `## Testing` section, which `review-pr` already bounds its read to, and stop there.
38
- - Leave the author's Summary and Technical Context unread while judging, and never open the worker's session or its transcript. Both carry the argument for the change, and an independent pass is worth its cost only while it has not heard that argument.
38
+ - Leave the author's Summary and Technical context unread while judging, and never open the worker's session or its transcript. Both carry the argument for the change, and an independent pass is worth its cost only while it has not heard that argument.
39
39
  - Read none of the above as a UI reviewer. `review-ui` states its own reads, being the checklist and the address, and a UI pass that has read the diff drives towards what it expects the code to do.
40
40
  - Treat the cross-branch facts the launch carries as facts rather than findings. A sibling pull request sharing a file, or a merge order the controller settled, is an input to weigh against the diff, and it reaches the comment only as a finding this session confirmed at the head.
41
41
 
@@ -32,6 +32,7 @@ The draft mark fails from both ends. On 2026-08-31 four sessions re-drafted a pu
32
32
  - 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
33
33
  - 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
34
34
  - 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
35
+ - 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
35
36
  - Point at `session-worktree`, `auto-ship`, and `review-address` for the steps each already owns
36
37
 
37
38
  ## Must not
@@ -79,6 +79,14 @@ correct it. This rung stays here rather than in the relay because it differs
79
79
  between roles, and it discriminates for a worker because a worker holds a
80
80
  feature branch and a controller does not.
81
81
 
82
+ ## Talk launch
83
+
84
+ A launch whose brief says it is a talk session puts the operator in this one. Everything above holds, and the clause below changes where a judgment call goes and when the role ends. A launch carrying no such sentence takes none of this.
85
+
86
+ - Ask the operator in the session through the structured question surface at a judgment call, rather than halting toward the controller. A plan question written as needing the operator's call is put to them directly.
87
+ - Send the controller a close message when the operator ends the conversation, beside the announcements the channel above owes.
88
+ - Keep the before-prompt block message for a block the operator cannot answer. A question put to the operator who is in the session needs none.
89
+
82
90
  ## Refusing is part of the job
83
91
 
84
92
  - Refuse an instruction the tree contradicts, and carry the evidence with it. Name the commands read and the consequences of complying, rather than reporting reluctance.
@@ -92,5 +100,5 @@ feature branch and a controller does not.
92
100
 
93
101
  ## Lifetime
94
102
 
95
- - The role runs from the worktree entry to the merge of the branch it built, and nothing carries across to a second row. A worker handed another row after that is a new build under a new plan.
103
+ - The role runs from the worktree entry to the merge of the branch it built, and nothing carries across to a second row. A talk session outlives the merge and ends when the operator says the conversation is over. A worker handed another row after that is a new build under a new plan.
96
104
  - Treat this body as possibly older than the branch under it. A plugin skill loads from the marketplace cache rather than the working tree, so a session building a change to its own skills may be holding the copy from before the last update.
@@ -22,7 +22,7 @@ Decline where the session holds no reasoning a reader could not get faster from
22
22
  ## Guards
23
23
 
24
24
  - If `git rev-parse --git-dir` does not resolve, stop: `❌ Not a git repository. A session map takes its filename from the branch.`
25
- - Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. An empty result falls back to `latest` rather than stopping, since a handoff is scratch and a stop loses the reasoning the file exists to save.
25
+ - Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. An empty result falls back to `latest` rather than stopping, since a handoff is scratch and a stop loses the reasoning the file exists to save.
26
26
  - Resolve the containing folder at the main worktree root with `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. The guard above already stopped where that read has no repository to answer from, so it takes no fallback.
27
27
 
28
28
  ## Step 1: recover the commit the drift step reads
@@ -42,6 +42,6 @@ A resume is a read, and a session that treats it as a cleanup pass offers to arc
42
42
 
43
43
  - Writing a handoff, which happens at the close of a session rather than at its start. This skill names the standard that governs one and follows it no further.
44
44
  - The sections a role adds over the core handoff, which belong to that role's own surface
45
- - Archiving a shipped task out of the folder: `task-board`
46
- - Archiving a plan and marking an outcome, which `context-fold` does when the work ships
45
+ - Archiving a shipped task out of the folder: `task-complete`
46
+ - Marking an outcome, which `task-complete` does when the work ships, and archiving a plan, which the merge does
47
47
  - Implementing the item it recommends, which is the next request rather than part of this one
@@ -41,8 +41,8 @@ The directory test separates the defect from a genuinely bare repository, which
41
41
 
42
42
  Try each source in order. Stop at the first match.
43
43
 
44
- 0. **Caller-supplied.** The invocation carried an argument. Take it as the name and infer nothing further. Accept `<name>` or `<type>/<name>`, where a leading segment matching a type in `${CLAUDE_SKILL_DIR}/../../standards/branch.md` sets `<type>` and the rest is `<name>`. A bare `<name>` falls to the default type below.
45
- 1. **Plan matched to current branch.** Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. An empty result falls through to the next source here rather than becoming `latest`, since the slug is one candidate among several. If `<main-root>/.canon/plans/feature-<slug>.md` exists, use `<slug>`.
44
+ 0. **Caller-supplied.** The invocation carried an argument. Take it as the name and infer nothing further. Accept `<name>` or `<type>/<name>`, where a leading segment matching a type in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md` sets `<type>` and the rest is `<name>`. A bare `<name>` falls to the default type below.
45
+ 1. **Plan matched to current branch.** Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. An empty result falls through to the next source here rather than becoming `latest`, since the slug is one candidate among several. If `<main-root>/.canon/plans/feature-<slug>.md` exists, use `<slug>`.
46
46
  2. **Single plan file.** List `<main-root>/.canon/plans/feature-*.md`. If exactly one match, derive `<slug>` from the filename.
47
47
  3. **Multiple plan files, no branch match.** Ask the user which plan. Show the candidate slugs as a numbered list. Do not pick.
48
48
  4. **Current branch.** When no plan exists, use the `<slug>` from step 1 if it is not `main` or `master`.
@@ -53,7 +53,7 @@ Tier 0 sits ahead of the inference because every tier below it answers from stat
53
53
 
54
54
  Validate the result: letters, digits, dots, underscores, dashes only, max 64 chars (`/` separators are also allowed). If the derived name violates the rule, sanitize by replacing invalid chars with `-` and truncating. Show the sanitized name in the preview before invoking.
55
55
 
56
- Resolve `<type>` here as well, since Step 3 previews it and Step 5 renames onto it, drawing the value from the type vocabulary in `${CLAUDE_SKILL_DIR}/../../standards/branch.md`. A type the caller spelled in tier 0 wins outright and no reading overrides it. A name that came from a plan, through tier 1 or tier 2, takes its type from `canon tasks plan-branch <plan> --json`, read off the record's `type` field. Every other case takes `feat`, which covers a name from a branch, a bare name from the user, and a plan the verb could not answer for.
56
+ Resolve `<type>` here as well, since Step 3 previews it and Step 5 renames onto it, drawing the value from the type vocabulary in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md`. A type the caller spelled in tier 0 wins outright and no reading overrides it. A name that came from a plan, through tier 1 or tier 2, takes its type from `canon tasks plan-branch <plan> --json`, read off the record's `type` field. Every other case takes `feat`, which covers a name from a branch, a bare name from the user, and a plan the verb could not answer for.
57
57
 
58
58
  The verb is the reading rather than this body, because a type read off a plan's sections is a judgment that two sessions reading one plan can grade differently, and the verb answers the same for both. The caller's type still wins over the verb's, because tier 0 is the one source that knows something no file states.
59
59
 
@@ -68,7 +68,7 @@ Then test both names the entry is about to claim. Neither read needs a worktree,
68
68
 
69
69
  Leave both in place. Resolving either automatically risks the wrong one.
70
70
 
71
- The two tests catch different collisions. The branch test misses the one `${CLAUDE_SKILL_DIR}/../../standards/slug.md` records, where two branches differing only in type collapse onto one name: `feat/foo` and `fix/foo` are distinct refs and reach one directory. The directory test is the only read that sees it.
71
+ The two tests catch different collisions. The branch test misses the one `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md` records, where two branches differing only in type collapse onto one name: `feat/foo` and `fix/foo` are distinct refs and reach one directory. The directory test is the only read that sees it.
72
72
 
73
73
  The branch test fires on the tier 1 and tier 4 sources whenever the branch the session started on is already conventional, since a name derived from that branch resolves back onto it. Stopping is the answer there. The concern already has a branch, git refuses a second under the same name, and the bare-name rename this replaces only carried the collision forward to the `git-branch` step. It fires on tier 0 as well, where a caller handed a name something already holds.
74
74
 
@@ -98,7 +98,7 @@ Call `EnterWorktree` with `name: "<name>"`. Claude Code's tool permission dialog
98
98
  git branch -m worktree-<name> <type>/<name>
99
99
  ```
100
100
 
101
- The slug transform drops a leading type segment, so `<name>` is what every downstream derivation reads back out of the typed branch. See `${CLAUDE_SKILL_DIR}/../../standards/slug.md`.
101
+ The slug transform drops a leading type segment, so `<name>` is what every downstream derivation reads back out of the typed branch. See `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`.
102
102
 
103
103
  Step 2 already cleared the target name, so the rename runs unguarded here. Do not repeat the test. A ref created between the two points is a second session racing this one, which a re-read narrows rather than closes.
104
104
 
@@ -33,7 +33,7 @@ rather than a step within it, so the full chain never runs it separately.
33
33
 
34
34
  ## Non-interactive path
35
35
 
36
- Every phase runs under `CANON_NON_INTERACTIVE=1` with no TTY. Two phases
36
+ Every phase runs under `CANON_NON_INTERACTIVE=1` with no TTY. Three phases
37
37
  otherwise pause, and each takes an argument that answers its prompt ahead of
38
38
  time:
39
39
 
@@ -41,11 +41,15 @@ time:
41
41
  takes every candidate the scan found, and `--folders <a>,<b>` takes a named
42
42
  set. With neither, and with no TTY, the phase reports its candidates and stops
43
43
  rather than choosing for the operator.
44
+ - `install` and `gov` confirm the proposed extras with the operator.
45
+ `--extras <a>,<b>` takes a named set and `--extras none` takes none. With
46
+ neither, and with nobody to answer, both take every proposal and list each in
47
+ the report rather than stopping.
44
48
  - `gov` stops on a detected technology with no matching rule. `--skip-gaps`
45
49
  proceeds with the matched layer and lists the gap in the report.
46
50
 
47
51
  Claude Code's tool permission dialog is the confirmation gate for everything
48
- else. Do not pause for a separate confirmation.
52
+ else. Do not pause for a separate confirmation beyond the extras question.
49
53
 
50
54
  ## Scope
51
55
 
@@ -71,7 +75,8 @@ the `install` and `gov` phases share rather than each stating.
71
75
 
72
76
  ## Phase: install
73
77
 
74
- Run the chain in order, starting immediately after the preview. Run from the
78
+ Run the chain in order, starting once the operator has confirmed the extras the
79
+ preview proposed, per the detect reference. Run from the
75
80
  target project's current directory. Do not cd into the toolkit source tree. The
76
81
  `canon` CLI is global.
77
82
 
@@ -116,7 +121,8 @@ Do not generate ESLint, Vitest, or Playwright configs. They ship as golden files
116
121
  ## Phase: gov
117
122
 
118
123
  Governance rules and nothing else, for a project declining the tooling layer.
119
- Resolve exactly as the detect reference states, then run:
124
+ Resolve exactly as the detect reference states, confirm the proposed extras
125
+ there, then run:
120
126
 
121
127
  ```bash
122
128
  CANON_NON_INTERACTIVE=1 canon gov install <stack> --add <extras> <target>
@@ -80,7 +80,8 @@ root.
80
80
  - **Stack:** pick the closest governance stack by matching the repository root's detected runtime or framework against stack names in the catalog. If the root matched nothing, `base` is the stack, including when subfolders matched, since no subfolder owns the repository and picking one by order would state a preference nobody gave. Mark it `fallback` in the preview only when no root matched anywhere.
81
81
  - **Tooling stack:** for each language root, pick the closest tooling stack from `canon tooling list --json` (e.g. `vite-react`, `astro`, `nextjs`). Distinct from the governance stack. Fall back to `base` for a root with no framework or language match, and carry that fallback into its preview row.
82
82
  - **Next.js:** map `next` in a root's `package.json` dependencies, or a `next.config.ts`/`.js`/`.mjs` file in that root, to the `nextjs` governance stack and the `nextjs` tooling stack. The dependency name does not match either stack name by itself.
83
- - **Extras:** identify technologies not already covered by the picked governance stack, across every language root. A subfolder that matched a governance stack of its own contributes that stack's rules, read from `canon gov list --json`, and every root contributes its language rule. For each technology, find a rule whose `description` or `paths` points at it and pass it via `--add`. Dedupe against the picked stack's own rules. Do not add a rule the stack already pulls in.
83
+ - **Extras:** run `canon gov detect <target> --stack <stack> --json` from the target and take its `proposals` array as the candidate extras. Each proposal names a `rule` and the `evidence` that matched it across every language root to depth two. The verb already leaves out every rule the picked stack resolves, so do not dedupe again, and do not match a rule's `description` or `paths` by hand.
84
+ - **Subfolder language rules:** a language root below the repository root whose language the picked stack does not carry contributes its language rule by name, read from `canon gov list --json`. The verb proposes no language rule, since a stack reaches each one.
84
85
  - **Subfolder tooling:** a language root below the repository root takes its own `canon tooling sync <stack> <path> --skip base`, since `canon init` already lands `base` once at the root. Leave a root whose stack resolves to `base` out of the commands, since that sync would land nothing. A repository-root `package.json` hosting only formatters and hooks is that case, and it adds no row.
85
86
  - **Skip (`--skip`):** `wiki` installs by default. Add `--skip wiki` only when the user explicitly wants it left out.
86
87
 
@@ -96,7 +97,7 @@ target project on the fly.
96
97
 
97
98
  On the `gov` phase, stop and present four options rather than picking:
98
99
 
99
- 1. Author a new rule in the toolkit at `governance/rules/<domain>/<num>-<name>.md` following `${CLAUDE_SKILL_DIR}/../../standards/rule.md`, commit, then re-run install. Take this route when the toolkit should ship the rule to every project.
100
+ 1. Author a new rule in the toolkit at `governance/rules/<domain>/<num>-<name>.md` following `${CLAUDE_SKILL_DIR}/../create-rule/references/rule.md`, commit, then re-run install. Take this route when the toolkit should ship the rule to every project.
100
101
  2. Invoke `create-rule`, which scaffolds the file into the target project at a non-colliding number. Take this route when the rule is specific to this project and no sync should ever overwrite it.
101
102
  3. Install the matching non-`<tech>` rules and skip the tech-specific layer.
102
103
  4. Abort.
@@ -112,7 +113,7 @@ Before executing, output:
112
113
  - **Detected:** each technology with its evidence file, path included, so a subfolder marker reads as one
113
114
  - **Stack:** picked governance stack and resolved rule count. Mark it `fallback` when no detected runtime or framework matched a catalog name.
114
115
  - **Tooling stack:** one row per language root, each carrying its path, its picked tooling stack, a `fallback` mark on the same test, and its own command. On the repository root's row, name what `base` lands: configs, seeds, and gitignore entries in every case, plus the JavaScript development dependencies, scripts, and hook activation wherever a `package.json` exists to carry them. A project outside that ecosystem runs none of the second group and keeps the first. Omit these rows entirely on the `gov` phase, which syncs no tooling.
115
- - **Extras:** each `--add` rule with a one-line reason, listed in full. A second matched stack reaches the install only through this list, since `canon init --stack` takes one stack, so a shortened list reads as that stack dropped.
116
+ - **Extras:** each proposal with the evidence the verb returned, plus each subfolder language rule, listed in full as the list the operator confirms. A second matched stack reaches the install only through this list, since `canon init --stack` takes one stack, so a shortened list reads as that stack dropped.
116
117
  - **Skip:** any `--skip` entries with reason
117
118
  - **Target:** resolved target path
118
119
  - **Commands:** the full chain that will run
@@ -120,3 +121,19 @@ Before executing, output:
120
121
  A resolved name and a fallback read alike once written, so mark the fallback
121
122
  here rather than in the report. The preview is the last point before the first
122
123
  write, and the report runs after the files have landed.
124
+
125
+ ### Confirm the extras
126
+
127
+ The extras are the one part of the preview the operator confirms before the
128
+ install runs, since a proposal is evidence that a project might want a rule
129
+ rather than proof that it does. Put the list through the structured question
130
+ surface with three options: take every proposal, which is the recommended
131
+ first option, take none, or name a subset, which the operator types as a
132
+ comma-separated list. Pass what they kept to `--add` and drop the flag when
133
+ they kept nothing.
134
+
135
+ An `--extras` argument answers ahead of time and skips the question.
136
+ `--extras <a>,<b>` takes the named rules, and `--extras none` takes none. With
137
+ neither and no one to answer, take every proposal and list each in the report,
138
+ since a proposed rule costs one file to delete and stopping would break every
139
+ headless setup.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: task-board
3
- description: Why creating and archiving a task file is one skill, the origin invariant enforceable only at creation, and why archiving routes through the command the merge hook calls
3
+ description: Why creating and declining a task file is one skill, the origin invariant enforceable only at creation, and why settling a shipped task belongs elsewhere
4
4
  ---
5
5
 
6
6
  # Task board requirement
@@ -9,8 +9,6 @@ description: Why creating and archiving a task file is one skill, the origin inv
9
9
 
10
10
  Without this skill, a task file gets a filename and frontmatter invented on the spot, so the board sorts wrong and the regenerated index reads fields that are not there. A task arrives with no origin, which is either lost context or work nobody decided to do, and by the time anyone notices there is no way to recover which it was. The phase label gets derived from a version file rather than from what the board already means, and a single-digit phase sorts after a double-digit one because nobody padded it. A label picked off the live board alone repeats one the archive already spent, since the archive holds most of what has ever been allocated and a board-only scan cannot see it.
11
11
 
12
- Archiving fails in two ways that both lose work. Moving the file, editing the ordering file, and regenerating the index as three separate acts drifts from the one command the merge hook calls, so the attended and unattended paths stop agreeing. And an all-`[x]` task gets archived while its pull request is still open, because marking outcomes happens on the branch as the first step of shipping. The board is gitignored, so nothing restores a task archived early.
13
-
14
12
  Placing a row without checking for another writer collides the same way. Two sessions filing work at once can claim one phase label twice or land two rows beside each other unread, since neither reads the board before writing it.
15
13
 
16
14
  ## Must
@@ -20,29 +18,26 @@ Placing a row without checking for another writer collides the same way. Two ses
20
18
  - Require an origin at creation, because that is the only moment the invariant is enforceable
21
19
  - Claim the phase label with `canon tasks next-label --claim` rather than reading or proposing one by hand
22
20
  - Check the roster for a live orchestrator before writing a row, and hand off rather than write when one is found
23
- - Confirm the work reached the default branch before archiving
24
- - Run the archive command and route on the reason it refuses, since each reason has one resolution
21
+ - Run the decline command and route on the reason it refuses, since each reason has one resolution
25
22
  - Report an origin that carries no task, as a list rather than a prompt
26
23
 
27
24
  ## Must not
28
25
 
29
- - Mark an outcome complete or archive a plan
26
+ - Mark an outcome complete, archive a task, or move a plan
30
27
  - Hand-edit the index or the ordering file, or move the task file directly
31
28
  - Write a pull request line at creation, when any number is a guess at someone else's work
32
- - Archive around a refusal
33
- - Split the legacy single-file archive into per-task files nobody wrote
29
+ - Decline around a refusal
34
30
  - Claim a label or write a task file for a session holding the worker role, since that role reports a row upward and the controlling session places it
35
31
  - Fall through to a direct write when no orchestrator is found and this session's own name starts with `worker-` or `planner-`, since those role bodies ban the write with no exception
36
32
 
37
33
  ## Guards
38
34
 
39
35
  - No task board at the main root: stop
40
- - The request fits neither creating nor archiving: stop rather than picking one
41
- - Work not yet on the default branch: stop, because the board has no history to restore from
36
+ - The request fits neither creating nor declining: stop rather than picking one
42
37
  - No origin given and none offered: stop
43
38
 
44
39
  ## Out of scope
45
40
 
46
- - Editing the contents of a task that already exists, which `context-fold` owns along with marking outcomes and sweeping plans
41
+ - Marking a shipped task's outcomes and archiving it, which `task-complete` owns, with the `post-merge` hook running the unattended archive
47
42
  - Deciding what the task should argue. This owns the file's existence and its shape, not its content.
48
- - Relocating a plan, which one skill owns so two do not relocate it differently
43
+ - Relocating a plan, which `canon tasks archive` owns so two movers do not relocate it differently
@@ -1,22 +1,22 @@
1
1
  ---
2
2
  name: task-board
3
- description: Creates a task file in `.canon/tasks/` with the filename, phase label, and frontmatter the standard requires, and archives a shipped one out of the folder. Use when asked to "add a task", "create a task", "queue this", "put this on the board", "archive that task", or "close out a shipped task". Do NOT use to mark an outcome `[x]`. That is `context-fold`.
3
+ description: Creates a task file in `.canon/tasks/` with the filename, phase label, and frontmatter the standard requires, and declines one decided against. Use when asked to "add a task", "create a task", "queue this", "put this on the board", or "decline that task". Do NOT use to mark an outcome `[x]` or to archive a shipped task. That is `task-complete`.
4
4
  metadata:
5
5
  family: decide
6
6
  ---
7
7
 
8
8
  # Task board
9
9
 
10
- Owns the two operations that bring a task file into existence and take it out of the folder. `context-fold` edits the contents of a task that already exists, marking outcomes `[x]`. Do not mark outcomes here, and do not move a plan by hand: the archive carries it.
10
+ Owns the two operations that decide a task: bringing its file into existence, and declining one decided against. `task-complete` settles a task once its work exists, marking outcomes `[x]` and archiving a shipped one. Do not mark outcomes or archive here, and do not move a plan by hand.
11
11
 
12
12
  Read `${CLAUDE_SKILL_DIR}/references/tasks.md` before writing any file. It holds the filename convention, the frontmatter contract, and the file format. Do not work them from memory.
13
13
 
14
14
  ## Guards
15
15
 
16
16
  - Resolve the board at the main worktree root, not `pwd`. Run `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, falling back to `pwd` outside a git repo. Every read and write below resolves against that root. The board is gitignored scratch shared across worktrees, so a linked worktree writing to its own `pwd` creates a second board nothing else reads.
17
- - A new task file is a main-root write, so it goes out as a heredoc. Archiving already runs through `canon tasks archive`, which resolves the root in-process. Marking an outcome shipped is `context-fold` and runs through `canon tasks outcome`. Resolve that root and route the write the way `session-worktree` states.
17
+ - A new task file is a main-root write, so it goes out as a heredoc. Declining already runs through `canon tasks decline`, which resolves the root in-process. Resolve that root and route the write the way `session-worktree` states.
18
18
  - If `.canon/tasks/` does not exist at that root, stop: `❌ No .canon/tasks/ board. Run canon claude init to set it up.`
19
- - Route on the request rather than on a flag. Creating names work that does not exist yet, archiving names a task file already shipped, and declining names one decided against. If the request fits none of the three, stop: `❌ Ambiguous. Say whether to create a task, archive one, or decline one.`
19
+ - Route on the request rather than on a flag. Creating names work that does not exist yet, and declining names a task file decided against. A request to archive a shipped task or mark its outcomes belongs to `task-complete`, so name it and stop. If the request fits neither, stop: `❌ Ambiguous. Say whether to create a task or decline one.`
20
20
  - Never hand-edit `.canon/tasks/index.md`. A hook regenerates it from sibling frontmatter after a write. Do not run the regen command directly, except after a shell write from a linked worktree: the hook matches `Write|Edit|MultiEdit` and nothing fires on `Bash`, so that one case regenerates explicitly with `canon indexes regen --no-stage --root <main-root> <main-root>/.canon/tasks/index.md`.
21
21
 
22
22
  ## Create
@@ -39,7 +39,7 @@ The guard sits ahead of Step 2 because `--claim` reserves a label on disk, so a
39
39
 
40
40
  Run `canon tasks next-label --claim --json` and take its `label` field. The verb reads the live board and its `archive/` sibling together, so the label it returns accounts for what the board alone no longer shows, and `--claim` reserves it under `.canon/ordinal-locks/` so a second session filing at the same moment gets the next one. Branch on the record's `reason` rather than the exit: `label-contended` means re-run the claim, and a usage error from an unknown `--claim` means the installed binary predates the flag, so report the verb as unavailable rather than falling back to a bare read, which reopens the race.
41
41
 
42
- Do not derive the label from a version file. `${CLAUDE_SKILL_DIR}/../../standards/versioning.md` permits free renumbering, so the verb's two folders are the only surface that knows what a label currently means.
42
+ Do not derive the label from a version file. `${CLAUDE_SKILL_DIR}/../git-commit/references/versioning.md` permits free renumbering, so the verb's two folders are the only surface that knows what a label currently means.
43
43
 
44
44
  ### Step 3: write the file
45
45
 
@@ -90,10 +90,6 @@ Report rather than prompt. A track can be opened long after its task would have
90
90
 
91
91
  Say the origins were read even when nothing comes back, which is the ordinary result. A step going silent on a clean pass is indistinguishable from one that never ran.
92
92
 
93
- ## Archive
94
-
95
- Read `${CLAUDE_SKILL_DIR}/references/archive.md` when the request names a shipped task to archive. It carries the check that the work reached `main`, the `canon tasks archive` call, the route for each refusal, and the prose to clear afterwards. Never move the file, edit `priority.md`, or regenerate the index by hand, since the command owns all three.
96
-
97
93
  ## Decline
98
94
 
99
95
  Read `${CLAUDE_SKILL_DIR}/references/decline.md` when the request names a task decided against. It carries gathering the reason, the `canon tasks decline` call, the route for each refusal, and the prose to clear afterwards. Never move the file, edit `priority.md` or `backlog.md`, or regenerate the index by hand, since the command owns all three.
@@ -124,12 +120,4 @@ Create:
124
120
 
125
121
  Drop either block when it carries no rows. When both are empty, which is the ordinary result, replace them with one line naming what was read: `Read <n> tracks, <n> dumps, and <n> open issues. Nothing unlinked.`
126
122
 
127
- Archive, reporting the paths the command returned:
128
-
129
- ```plaintext
130
- 📦 Archived: .canon/tasks/archive/vXX.Y-<slug>.md
131
-
132
- <ordering and index disposition in one line>
133
- ```
134
-
135
123
  A refusal reports the reason and the resolution the mode's reference routes it to under its Step 3, on one line each.
@@ -54,13 +54,13 @@ One file per task is what keeps the board safe under parallel sessions. Two sess
54
54
 
55
55
  Siblings sit in the folder without being tasks, and each earns its place by being governed somewhere. `index.md`, `priority.md`, and `backlog.md` are governed by `board.md`. Every `session-` file is a pre-compaction handoff governed by `session.md`, and each is optional: a project whose sessions never approach a compaction carries none. Anything filtering the folder to tasks skips all of them, so a name outside the set is a task whatever it holds.
56
56
 
57
- The `task-board` skill creates and archives task files, and the archive carries the task's plan with it. `context-fold` marks outcomes `[x]` in an existing file. Neither does the other's job.
57
+ The `task-board` skill creates and declines task files. The `task-complete` skill marks outcomes `[x]` in an existing file and archives a shipped one, and the archive carries the task's plan with it. Neither does the other's job.
58
58
 
59
59
  ## Filenames
60
60
 
61
61
  `vXX.Y-<slug>.md`, where the version is the phase label zero-padded to two digits and the slug is kebab-case.
62
62
 
63
- Padding is load-bearing. Index entries sort by filename and nothing else, so a bare `v9.0` sorts after `v15.0` and the catalog reads out of board order. `standards/versioning.md` governs the label itself and permits free renumbering, so expect the occasional rename. Nothing points at a task filename, since a `Plan:` line runs from task to plan rather than the reverse. <!-- canon-allow-reference: illustrates the padding rule's own sort collision, not a citation of a real task -->
63
+ Padding is load-bearing. Index entries sort by filename and nothing else, so a bare `v9.0` sorts after `v15.0` and the catalog reads out of board order. `${CLAUDE_SKILL_DIR}/../git-commit/references/versioning.md` governs the label itself and permits free renumbering, so expect the occasional rename. Nothing points at a task filename, since a `Plan:` line runs from task to plan rather than the reverse. <!-- canon-allow-reference: illustrates the padding rule's own sort collision, not a citation of a real task -->
64
64
 
65
65
  ## Frontmatter
66
66