@erclx/canon 5.41.0 → 5.43.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 (220) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/api-design/references/adopted.md +34 -14
  3. package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
  4. package/claude/skills/auto-ship/SKILL.md +24 -4
  5. package/claude/skills/auto-ship/references/draft-mark.md +32 -6
  6. package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
  7. package/claude/skills/auto-ship/references/tier-failures.md +31 -10
  8. package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
  9. package/claude/skills/auto-ship/references/worktree-name.md +9 -3
  10. package/claude/skills/build-in-slices/references/adopted.md +35 -21
  11. package/claude/skills/canvas-board/references/canvas.md +17 -6
  12. package/claude/skills/canvas-board/references/design.md +26 -7
  13. package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
  14. package/claude/skills/ci-workflow/SKILL.md +12 -2
  15. package/claude/skills/ci-workflow/references/workflows.md +12 -9
  16. package/claude/skills/code-craft/references/adopted.md +58 -20
  17. package/claude/skills/codebase-layout/references/adopted.md +49 -16
  18. package/claude/skills/codebase-layout/references/frontend.md +11 -4
  19. package/claude/skills/codebase-layout/references/tests.md +4 -2
  20. package/claude/skills/context-fold/references/classify.md +10 -15
  21. package/claude/skills/context-fold/references/completion-report.md +11 -9
  22. package/claude/skills/context-fold/references/context-refresh.md +26 -9
  23. package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
  24. package/claude/skills/create-rule/REQUIREMENT.md +5 -0
  25. package/claude/skills/create-rule/SKILL.md +10 -1
  26. package/claude/skills/create-rule/references/checklist.md +26 -0
  27. package/claude/skills/create-rule/references/rule.md +98 -20
  28. package/claude/skills/create-skill/SKILL.md +1 -0
  29. package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
  30. package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
  31. package/claude/skills/create-skill/references/skill-paths.md +7 -4
  32. package/claude/skills/create-skill/references/skill-practice.md +6 -3
  33. package/claude/skills/create-skill/references/skill-requirement.md +4 -2
  34. package/claude/skills/create-skill/references/skill.md +67 -44
  35. package/claude/skills/decision-escalate/SKILL.md +1 -2
  36. package/claude/skills/deploy-app/references/vercel.md +2 -1
  37. package/claude/skills/deprecation-migration/references/adopted.md +44 -25
  38. package/claude/skills/design-taste/references/adopted.md +9 -1
  39. package/claude/skills/design-taste/references/craft.md +3 -1
  40. package/claude/skills/design-taste/references/kinds.md +8 -7
  41. package/claude/skills/design-taste/references/preflight.md +12 -0
  42. package/claude/skills/design-taste/references/systems.md +7 -6
  43. package/claude/skills/design-taste/references/tells.md +24 -25
  44. package/claude/skills/design-taste/references/vocabulary.md +7 -5
  45. package/claude/skills/document-health/references/axes.md +55 -30
  46. package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
  47. package/claude/skills/draft-doc/references/context.md +4 -3
  48. package/claude/skills/draft-doc/references/docs.md +6 -3
  49. package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
  50. package/claude/skills/draft-doc/references/readme/application.md +8 -2
  51. package/claude/skills/draft-doc/references/readme/cli.md +5 -1
  52. package/claude/skills/draft-doc/references/readme/library.md +4 -0
  53. package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
  54. package/claude/skills/draft-doc/references/readme.md +30 -13
  55. package/claude/skills/draft-doc/references/requirements.md +17 -4
  56. package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
  57. package/claude/skills/draft-doc/references/wiki.md +1 -1
  58. package/claude/skills/draft-figure/references/architecture-set.md +7 -3
  59. package/claude/skills/draft-figure/references/figures.md +8 -6
  60. package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
  61. package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
  62. package/claude/skills/draft-figure/references/mermaid.md +10 -5
  63. package/claude/skills/draft-ready/references/ready.md +22 -15
  64. package/claude/skills/git-branch/references/branch.md +11 -1
  65. package/claude/skills/git-branch/references/slug.md +17 -5
  66. package/claude/skills/git-commit/references/commit.md +9 -5
  67. package/claude/skills/git-commit/references/versioning.md +23 -17
  68. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  69. package/claude/skills/git-followup/SKILL.md +5 -6
  70. package/claude/skills/git-issue/references/issue.md +29 -16
  71. package/claude/skills/git-pr/REQUIREMENT.md +1 -5
  72. package/claude/skills/git-pr/SKILL.md +11 -22
  73. package/claude/skills/git-pr/references/final-command.md +21 -8
  74. package/claude/skills/git-pr/references/labels.md +45 -28
  75. package/claude/skills/git-pr/references/pr.md +29 -9
  76. package/claude/skills/git-pr/references/publish.md +42 -28
  77. package/claude/skills/git-pr/references/task-number.md +20 -8
  78. package/claude/skills/git-ship/SKILL.md +1 -1
  79. package/claude/skills/plan-feature/SKILL.md +1 -1
  80. package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
  81. package/claude/skills/plan-feature/references/plan.md +58 -21
  82. package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
  83. package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
  84. package/claude/skills/plan-intake/references/intake.md +29 -24
  85. package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
  86. package/claude/skills/pr-evidence/SKILL.md +53 -0
  87. package/claude/skills/pr-evidence/references/evidence.md +150 -0
  88. package/claude/skills/review-address/references/post-review-findings.md +10 -3
  89. package/claude/skills/review-address/references/rebase-conflicts.md +15 -7
  90. package/claude/skills/review-address/references/rest-reads.md +3 -1
  91. package/claude/skills/review-craft/references/adopted.md +35 -18
  92. package/claude/skills/review-craft/references/security.md +42 -7
  93. package/claude/skills/review-craft/references/ui.md +23 -8
  94. package/claude/skills/review-pr/SKILL.md +6 -6
  95. package/claude/skills/review-pr/references/body-variants.md +29 -9
  96. package/claude/skills/review-pr/references/close-out.md +20 -5
  97. package/claude/skills/review-pr/references/key-changes.md +27 -3
  98. package/claude/skills/review-pr/references/post.md +83 -31
  99. package/claude/skills/review-pr/references/scope.md +54 -19
  100. package/claude/skills/review-ui/references/close-out.md +7 -5
  101. package/claude/skills/review-ui/references/driving.md +24 -4
  102. package/claude/skills/review-ui/references/post.md +43 -15
  103. package/claude/skills/role-orchestrator/SKILL.md +2 -0
  104. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
  105. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -40
  106. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
  107. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
  108. package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
  109. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
  110. package/claude/skills/role-orchestrator/references/orchestrator-output.md +16 -4
  111. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
  112. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
  113. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
  114. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
  115. package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
  116. package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
  117. package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
  118. package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
  119. package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
  120. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  121. package/claude/skills/role-planner/SKILL.md +3 -3
  122. package/claude/skills/role-worker/REQUIREMENT.md +3 -0
  123. package/claude/skills/role-worker/SKILL.md +34 -2
  124. package/claude/skills/search-craft/REQUIREMENT.md +1 -1
  125. package/claude/skills/search-craft/SKILL.md +2 -2
  126. package/claude/skills/search-craft/references/adopted.md +18 -6
  127. package/claude/skills/session-map/references/session.md +26 -7
  128. package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
  129. package/claude/skills/systematic-debugging/references/adopted.md +30 -16
  130. package/claude/skills/target-check/references/domains.md +39 -11
  131. package/claude/skills/target-setup/references/detect.md +80 -65
  132. package/claude/skills/target-setup/references/indexes.md +8 -6
  133. package/claude/skills/task-board/references/board.md +86 -30
  134. package/claude/skills/task-board/references/decline.md +29 -13
  135. package/claude/skills/task-board/references/tasks-decline.md +12 -5
  136. package/claude/skills/task-board/references/tasks.md +65 -33
  137. package/claude/skills/task-complete/references/archive.md +41 -17
  138. package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
  139. package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
  140. package/claude/skills/teach-workspace/references/glossary.md +6 -2
  141. package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
  142. package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
  143. package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
  144. package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
  145. package/claude/skills/teach-workspace/references/promotion.md +31 -8
  146. package/claude/skills/teach-workspace/references/revisit.md +8 -2
  147. package/claude/skills/teach-workspace/references/teach.md +17 -9
  148. package/claude/skills/test-craft/references/adopted.md +48 -14
  149. package/claude/skills/test-craft/references/component.md +7 -4
  150. package/claude/skills/test-craft/references/e2e.md +25 -7
  151. package/claude/skills/test-craft/references/unit.md +3 -1
  152. package/claude/skills/test-first/references/adopted.md +12 -4
  153. package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
  154. package/claude/skills/ui-checklist/SKILL.md +1 -1
  155. package/claude/skills/video-craft/references/adopted.md +62 -18
  156. package/claude/skills/write-human/references/adopted.md +21 -8
  157. package/docs/agents/audits.md +1 -0
  158. package/docs/agents/migrate.md +11 -8
  159. package/docs/target/migrations.md +11 -0
  160. package/docs/workflow/parallel-features.md +1 -1
  161. package/docs/workflow/skill-map.md +1 -0
  162. package/governance/detect.toml +4 -0
  163. package/governance/rules/canon/context.md +2 -1
  164. package/governance/rules/canon/plan.md +3 -5
  165. package/governance/rules/canon/scratch.md +3 -1
  166. package/governance/rules/canon/task-scope.md +2 -1
  167. package/governance/rules/canon/tasks.md +2 -1
  168. package/governance/rules/canon/worktrees.md +5 -2
  169. package/governance/rules/claude/output.md +7 -4
  170. package/governance/rules/claude/skill.md +6 -4
  171. package/governance/rules/tooling/ci-workflow.md +6 -39
  172. package/governance/rules/ui/design-reference.md +37 -0
  173. package/governance/rules/writing/markdown.md +2 -1
  174. package/package.json +6 -6
  175. package/src/audits/catalog.ts +42 -0
  176. package/src/claude/cases/workflow.ts +5 -0
  177. package/src/claude/settings.ts +8 -4
  178. package/src/commands/claude.ts +11 -1
  179. package/src/commands/gov.ts +198 -0
  180. package/src/commands/migrate.ts +121 -2
  181. package/src/commands/pr.ts +146 -105
  182. package/src/commands/tooling.ts +3 -3
  183. package/src/commands/worktrees.ts +49 -0
  184. package/src/gate/stages.ts +15 -0
  185. package/src/gov/audit.ts +440 -0
  186. package/src/listeners/belongs.ts +21 -0
  187. package/src/listeners/machine.ts +93 -0
  188. package/src/listeners/parse.ts +41 -0
  189. package/src/markdown/scope.ts +144 -0
  190. package/src/migrate/session-defaults.ts +138 -0
  191. package/src/pr/lift.ts +6 -3
  192. package/src/pr/local.ts +4 -69
  193. package/src/pr/review-state.ts +182 -0
  194. package/src/sync/check.ts +15 -0
  195. package/src/tooling/stamp.ts +56 -12
  196. package/src/worktrees/stop.ts +92 -0
  197. package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
  198. package/tooling/base/configs/commitlint.config.js +0 -20
  199. package/tooling/base/reference.md +1 -1
  200. package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
  201. package/tooling/claude/reference.md +13 -7
  202. package/tooling/claude/seeds/.claude/settings.json +4 -0
  203. package/tooling/claude/user/settings.template.json +0 -4
  204. package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
  205. package/tooling/public/configs/.github/dependabot.yml +12 -0
  206. package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
  207. package/tooling/public/manifest.toml +8 -0
  208. package/tooling/public/reference.md +53 -0
  209. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
  210. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
  211. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
  212. package/tooling/public/seeds/.release-please-manifest.json +3 -0
  213. package/tooling/public/seeds/CONTRIBUTING.md +50 -0
  214. package/tooling/public/seeds/LICENSE +21 -0
  215. package/tooling/public/seeds/SECURITY.md +13 -0
  216. package/tooling/public/seeds/release-please-config.json +12 -0
  217. package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
  218. package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
  219. package/tooling/web/configs/.github/workflows/verify.yml +15 -12
  220. package/claude/skills/git-pr/references/evidence.md +0 -124
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
4
- "version": "5.41.0",
4
+ "version": "5.43.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -5,36 +5,56 @@ description: Which external API design sources this skill adopted, which it decl
5
5
 
6
6
  # Adopted and declined
7
7
 
8
- External sources were read and filtered rather than imported. This file is the record. A later session extending the skill adds to it rather than re-arguing an item already settled here.
8
+ External sources were read and filtered rather than imported. This file is the record, and a later session extending the skill adds to it rather than re-arguing an item settled here.
9
9
 
10
- ## Adopted
10
+ ## Adopted from the default shelf
11
11
 
12
- ### From the default shelf
12
+ ### Observable behavior
13
13
 
14
- **Hyrum's Law.** [Software Engineering at Google, ch. 1](https://abseil.io/resources/swe-book/html/ch01.html): with enough users, every observable behavior of a system is depended on by somebody, whatever the contract promises. Adopted as the opening group, stated as design rules rather than as an observation, so a session decides what is observable before a caller decides it for them. Ordering and timing are named because the chapter's own examples are hash iteration order and timing.
14
+ [Software Engineering at Google, ch. 1](https://abseil.io/resources/swe-book/html/ch01.html) states Hyrum's Law, that with enough users, every observable behavior of a system is depended on by somebody, whatever the contract promises.
15
15
 
16
- **The One-Version Rule.** [Software Engineering at Google, ch. 21](https://abseil.io/resources/swe-book/html/ch21.html): a repository keeps one version of each dependency, so a change to it migrates every caller rather than leaving two versions live. Adopted under additive change for a caller that cannot pin, which is any module imported from inside one repository.
16
+ Adopted as the opening group, stated as design rules rather than as an observation, so a session decides what is observable before a caller decides it for them. Ordering and timing are named because the chapter's own examples are hash iteration order and timing.
17
17
 
18
- ### From one external skill
18
+ ### One version per dependency
19
19
 
20
- From `addyosmani/agent-skills@2686b620`, [`skills/api-and-interface-design/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md):
20
+ [Software Engineering at Google, ch. 21](https://abseil.io/resources/swe-book/html/ch21.html) states the One-Version Rule, keeping one version of each dependency in a repository, so a change to it migrates every caller rather than leaving two versions live. Adopted under additive change for a caller that cannot pin, which is any module imported from inside one repository.
21
+
22
+ ## Adopted from one external skill
23
+
24
+ From `addyosmani/agent-skills@2686b620`, [`skills/api-and-interface-design/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md).
25
+
26
+ ### Contract and errors
21
27
 
22
28
  **Contract first.** Write the interface before the body. Adopted as its own group, widened from an endpoint to a signature, a flag set, an output shape, and a schema.
23
29
 
24
- **One error shape.** Every failure on one surface carries the same structure. Adopted with a stable code added for the caller to branch on, and a clause keeping internal implementation details out of the message, since no project rule carries either for every code stack.
30
+ **One error shape.** Every failure on one surface carries the same structure. Adopted with a stable code for the caller to branch on, and internal details kept out of the message, since no project rule carries either for every code stack.
31
+
32
+ ### Input and change
25
33
 
26
34
  **Validation at the boundary.** Check input where it enters and trust it inside. Adopted, with a value read back from a file or another service counted as input.
27
35
 
28
- **Additive change.** New fields optional, nothing removed in place. Adopted, with a change of meaning under an existing name added as its own ban, since it breaks a caller as surely as a removal and no rename shows in the diff.
36
+ **Additive change.** New fields optional, nothing removed in place. Adopted, with a change of meaning under an existing name as its own ban, since it breaks a caller as surely as a removal and no rename shows in the diff.
37
+
38
+ ### Idempotency
29
39
 
30
- **Idempotency.** A stored key honored on retry, an atomic claim under a unique constraint, a reused key with a different body failing loudly, and retention past the longest retry. Adopted as four rules, keeping the reused-key rule, which is the one most often left out.
40
+ A stored key honored on retry, an atomic claim under a unique constraint, a reused key with a different body failing loudly, and retention past the longest retry. Adopted as four rules, keeping the reused-key rule, which is the one most often left out.
31
41
 
32
- **Excuses, red flags, and a closing checklist.** The same source's skill anatomy, adopted toolkit-wide through `${CLAUDE_SKILL_DIR}/../create-skill/references/skill-practice.md`. Each excuse row here rebuts a reason a session gives when it is about to break a caller, such as "nobody depends on that field".
42
+ ### The closing sections
43
+
44
+ The same source's skill anatomy supplies the excuses, red flags, and closing checklist, adopted toolkit-wide through `${CLAUDE_SKILL_DIR}/../create-skill/references/skill-practice.md`. Each excuse row here rebuts a reason a session gives when about to break a caller, such as "nobody depends on that field".
33
45
 
34
46
  ## Declined
35
47
 
36
- **Protocol-specific guidance.** The source skill carries verbs, status codes, pagination, and URL shapes for one protocol style. Declined because the body has to hold for a function's exports, a command's flags, and a file format as much as an endpoint, and a protocol section would route every non-network surface to rules that do not apply. A project needing those conventions states them in its own stack rule.
48
+ Each item below was read and left out, with the reason it changes nothing a session does here.
49
+
50
+ ### Protocol-specific guidance
51
+
52
+ The source skill carries verbs, status codes, pagination, and URL shapes for one protocol style. Declined because the body holds for a function's exports, a command's flags, and a file format as much as an endpoint, so a protocol section would route every non-network surface to rules that do not apply.
53
+
54
+ A project needing those conventions states them in its own stack rule.
55
+
56
+ ### Depth and versions
37
57
 
38
- **Interface depth.** Ousterhout's deep modules, after [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php), judge how much a module hides behind its surface. Declined here because depth is about what sits behind a boundary, and this skill owns only what crosses it. `code-craft` carries it.
58
+ **Interface depth.** Ousterhout's deep modules, after [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php), judge how much a module hides behind its surface. Depth is about what sits behind a boundary, and this skill owns only what crosses it, so `code-craft` carries it.
39
59
 
40
- **Versioned surfaces as the default.** Shipping a new version beside the old for every breaking change. Declined as the default because additive change avoids the break in the first place, and two live versions split the callers. The One-Version Rule covers a caller that cannot pin.
60
+ **Versioned surfaces as the default.** Shipping a new version beside the old for every breaking change. Additive change avoids the break in the first place and two live versions split the callers, so the One-Version Rule covers a caller that cannot pin.
@@ -20,6 +20,7 @@ Without this skill, the run from an approved plan to an open pull request is a c
20
20
  - Continue past a produced UI checklist rather than stopping on it, and report its unchecked boxes in the closing block, since the draft mark already holds the merge
21
21
  - Prove the draft target's head is the current branch and its state is open before marking it, and stop with nothing marked on a mismatch, since the number is retyped between steps and a draft mark on a release pull request holds that release
22
22
  - Stop a fan-in member after its verify and test order with a push and a done message rather than a pull request, and open an integrator's build by merging the member branches, since parallel batches sharing edge files put every open sibling into conflict on each merge
23
+ - Wait for both review families through `canon pr review-state --wait` once CI passes on a launch that named a controller, which alone dispatches the reviewers, bounded at the lift's own default, and hand the record to the controller on a timeout, since a worker improvising the read polled issue comments, never saw a UI close posted as a review, and stalled with both reviewers idle
23
24
  - Name the recovery for the stop it took, since the value of stopping is that the user knows where to resume
24
25
 
25
26
  ## Must not
@@ -65,9 +65,9 @@ If neither form is present, stop: `❌ <path> carries no plan sections. A plan l
65
65
 
66
66
  ### Unanswered questions
67
67
 
68
- The plan's sections and answer contract are fixed by `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`. A blank `- Answer:` accepts the `- Suggested:` line above it, so an unanswered question is a decision this run executes rather than a reason to stop.
68
+ Read `## The suggested-and-answer contract` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md` before acting on a question, for what it resolves to and the form an override takes. A question left open is a decision this run executes rather than a reason to stop.
69
69
 
70
- When this run decides against a suggestion, rewrite its line as `overridden at execution to <pick>,` plus the measurement, leaving `- Answer:` blank. Put the same deviation in one line under the open task's `## Findings`, opening with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
70
+ Open the task's `## Findings` line for an override with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
71
71
 
72
72
  ## Step 2: implement
73
73
 
@@ -107,7 +107,7 @@ When the plan's `**Constraints:**` carry a `Fan-in member of` bullet, push the b
107
107
 
108
108
  If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
109
109
 
110
- When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `git-pr` removes the file.
110
+ When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file. A diff passing this test also owes the preview server `role-worker` states, started before Step 6.
111
111
 
112
112
  ## Step 6: ship
113
113
 
@@ -119,9 +119,29 @@ This chain adds one thing. Mark the pull request as a draft as soon as `git-ship
119
119
 
120
120
  - Read `${CLAUDE_SKILL_DIR}/references/draft-mark.md` on reaching that point for the one command that proves the target, marks it, and reads the flag back
121
121
  - A `false` read stops the chain, and never re-issue the mark on it
122
- - Emit the Output block on the wake after `git-ship`'s background CI watch exits on `passing`, not when the turn ends on its watch line
122
+ - Act on the wake after the CI watch exits on `passing`, not when the turn ends on its watch line, moving to Step 7 under a named controller and to the Output block otherwise
123
123
  - Keep `git-ship`'s own verify gate, which repeats Step 3 on a clean run, since a resumed run enters at that gate
124
124
 
125
+ ## Step 7: wait for the reviews
126
+
127
+ Run this step only when the launch named a controlling session, since only a controller dispatches the reviewers. A hand-launched run has nobody reviewing, so it emits the Output block on the CI wake instead of waiting on a pass that cannot arrive.
128
+
129
+ Read review state through `canon pr review-state` alone, since both families post as pull request reviews, and a worker polling issue comments instead stalled with both reviewers idle. Run it in the background with the number Step 6 returned, since the wait outlasts a foreground shell call, and act on the wake.
130
+
131
+ ```bash
132
+ canon pr review-state <number> --wait 1200 --json
133
+ ```
134
+
135
+ Branch on the record's `reason` rather than on the exit, which a shell function wrapping `canon` can flatten to zero.
136
+
137
+ | `reason` | Route |
138
+ | ----------- | ---------------------------------------------------------------------------------------------------------------------- |
139
+ | `covered` | Emit the Output block. Invoke `canon:review-address` when `review.reason` or `ui.reason` reads open at the tip |
140
+ | `timeout` | Send the record to the controller per `canon:role-worker`, emit the Output block, and stop rather than waiting again |
141
+ | Any refusal | Report the `reason` to the controller the same way and stop, since an unread thread is not one nobody has reviewed yet |
142
+
143
+ Skip the `review-address` call when a reviewer's message already started it, since that message carries the same posted pass. A close in both families needs nothing from this session, since the reviewers run the lift on their close.
144
+
125
145
  ## Output
126
146
 
127
147
  Respond with up to two lines:
@@ -19,14 +19,40 @@ gh api graphql -f query='mutation($id: ID!) { convertPullRequestToDraft(input: {
19
19
  gh api repos/{owner}/{repo}/pulls/<number> --jq '{isDraft: .draft}'
20
20
  ```
21
21
 
22
- The target check and the read-back go through REST. The mark itself is a GraphQL mutation, because the REST pull request update carries no draft field, so the mark is local-only: a cloud session's GitHub access blocks GraphQL, the mutation fails there, and the read-back reports `false`. A cloud worker's pull request therefore opens ready, and its chain stops at this step with the pull request already open.
22
+ ## Why the mark is local-only
23
23
 
24
- Name the number `git-ship`'s pull request step returned in every position rather than leaving any to resolve by branch. `${CLAUDE_SKILL_DIR}/../git-pr/REQUIREMENT.md` states why: a lookup that resolves by branch alone can return a closed pull request sharing that head, so the number is resolved once and reused rather than re-derived.
24
+ The target check and the read-back go through REST. The mark itself is a GraphQL mutation, because the REST pull request update carries no draft field.
25
25
 
26
- A refusal is a stop. Report the line the shell printed, then resolve the number from the `number=` and `head=` lines of `git-pr`'s output and re-run the command by hand. The comparison sits in the shell rather than in the session's reading of a printed value, which is the same split `git-pr`'s `assert_own_pr` makes, because the judgment that picked a wrong number is the one that would read the check.
26
+ - A cloud session's GitHub access blocks GraphQL, so the mutation fails there and the read-back reports `false`
27
+ - A cloud worker's pull request therefore opens ready, and its chain stops at this step with the pull request already open
27
28
 
28
- The number crosses from that step's output into a command this session types, which is the one place a number gets authored rather than derived. A number misread there, or inferred from the newest pull request in view, would draft a stranger's pull request. A release pull request is the worst such target, since the mark holds the release and this role may not lift it again.
29
+ ## The number
29
30
 
30
- Report what the read returned rather than what the command printed, since the exit says the call ran and says nothing about the state. A `true` reports a draft. A `false` reports the pull request as opened ready and unsupervised, and the chain stops there. Never re-issue the mark on a disagreeing read, which fights whoever readied it instead of guarding anything.
31
+ Name the number `git-ship`'s pull request step returned in every position rather than leaving any to resolve by branch. `${CLAUDE_SKILL_DIR}/../git-pr/REQUIREMENT.md` states why, since a lookup by branch alone can return a closed pull request sharing that head.
31
32
 
32
- Placement is why the call sits ahead of the watch rather than after it. Marking afterwards leaves the pull request unmarked for the whole CI run, which is the stretch an unattended worker's branch is least supervised. What the mark buys is a reader learning the pull request has had no review yet. It buys no bound on that stretch: readying a pull request to merge lifts the mark, GitHub requires it before a merge, and the act runs through `canon pr lift`, which a reviewer runs on its close and the controlling session runs as the fallback, or through the operator directly. `role-worker` states the mirroring refusal of an instruction to ready the pull request directly, whoever sends it.
33
+ The number crosses from that step's output into a command this session types, the one place a number gets authored rather than derived. A number misread there, or inferred from the newest pull request in view, would draft a stranger's pull request.
34
+
35
+ - A release pull request is the worst such target, since the mark holds the release and this role may not lift it again
36
+
37
+ ### A refusal
38
+
39
+ A refusal is a stop. Report the line the shell printed, then resolve the number from the `number=` and `head=` lines of `git-pr`'s output and re-run the command by hand.
40
+
41
+ The comparison sits in the shell rather than in the session's reading of a printed value, the same split `git-pr`'s `assert_own_pr` makes. The judgment that picked a wrong number is the one that would read the check.
42
+
43
+ ## The read-back
44
+
45
+ Report what the read returned rather than what the command printed, since the exit says the call ran and says nothing about the state.
46
+
47
+ - A `true` reports a draft
48
+ - A `false` reports the pull request as opened ready and unsupervised, and the chain stops there
49
+ - Never re-issue the mark on a disagreeing read, which fights whoever readied it instead of guarding anything
50
+
51
+ ## Why the mark sits ahead of the watch
52
+
53
+ Marking afterwards leaves the pull request unmarked for the whole CI run, the stretch an unattended worker's branch is least supervised. What the mark buys is a reader learning the pull request has had no review yet.
54
+
55
+ It buys no bound on that stretch. Readying a pull request to merge lifts the mark, and GitHub requires it before a merge.
56
+
57
+ - The lift runs through `canon pr lift`, which a reviewer runs on its close and the controlling session runs as the fallback, or through the operator directly
58
+ - `role-worker` states the mirroring refusal of an instruction to ready the pull request directly, whoever sends it
@@ -7,16 +7,18 @@ description: The step an operator resumes from after each auto-ship stop point,
7
7
 
8
8
  Every stop point leaves recoverable state. The user resumes manually from the appropriate step.
9
9
 
10
- | Stop point | Recovery |
11
- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
12
- | No plan (derived) | Run `/plan-feature` to create one |
13
- | No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run |
14
- | No task (caller-supplied) | Check the task path passed to autoship, then re-run |
15
- | Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run |
16
- | Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly. |
17
- | Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run |
18
- | Resolved file carries no plan shape | Point autoship at a plan under `.canon/plans/feature-<slug>.md` or at a task under `.canon/tasks/`, then re-run |
19
- | Branch collision on worktree entry | `session-worktree` Step 5 found `<slug>` already as a local branch. Resolve manually (rename or delete the stale branch), then re-run autoship. |
20
- | Verify fails | Read logs, fix manually, run `/git-ship` |
21
- | git-ship fails | Inspect hook or remote error, run again |
22
- | Draft target is not this branch's | Nothing was marked. Read the number and `head=` from `git-pr`'s output, confirm they match, then run the mark by hand |
10
+ | Stop point | Recovery |
11
+ | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
12
+ | No plan (derived) | Run `/plan-feature` to create one |
13
+ | No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run |
14
+ | No task (caller-supplied) | Check the task path passed to autoship, then re-run |
15
+ | Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run |
16
+ | Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly. |
17
+ | Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run |
18
+ | Resolved file carries no plan shape | Point autoship at a plan under `.canon/plans/feature-<slug>.md` or at a task under `.canon/tasks/`, then re-run |
19
+ | Branch collision on worktree entry | `session-worktree` Step 5 found `<slug>` already as a local branch. Resolve manually (rename or delete the stale branch), then re-run autoship. |
20
+ | Verify fails | Read logs, fix manually, run `/git-ship` |
21
+ | git-ship fails | Inspect hook or remote error, run again |
22
+ | Draft target is not this branch's | Nothing was marked. Read the number and `head=` from `git-pr`'s output, confirm they match, then run the mark by hand |
23
+ | Review wait timed out | The record went to the controller. Once the reviewers are dispatched, re-run `canon pr review-state <number> --wait 1200 --json` in the background |
24
+ | Review wait refused | Fix what the `reason` names, such as an unreadable remote, then re-run `canon pr review-state <number> --wait 1200 --json` in the background |
@@ -9,21 +9,42 @@ Step 1 of `auto-ship`, tier 1. The session reads this file when the invocation c
9
9
 
10
10
  ## Reading the pointer
11
11
 
12
- One plan per task is what makes the tier 1 read unambiguous, so it takes the first `Plan:` line outside a fenced sample and never scans for a second line or reads past a second link on that one. A caller who means the task holds its path already, having read it off the board, which is why a bare slug never reaches this tier.
12
+ One plan per task is what makes the tier 1 read unambiguous. It takes the first `Plan:` line outside a fenced sample, and never scans for a second line or reads past a second link on that one.
13
13
 
14
- Read the target out of the link's parentheses, and take the rest of the line when the line carries no link, since an older task writes the target as a plain path with nothing around it. A bare line counts its leading run of tokens carrying `/` or ending in `.md` as targets and stops at the first word that is neither, so trailing prose after one path still names a single plan.
14
+ - A caller who means the task already holds its path, having read it off the board, which is why a bare slug never reaches this tier
15
+ - Read the target out of the link's parentheses, and take the rest of the line when it carries no link, since an older task writes the target as a plain path
16
+ - A bare line counts its leading run of tokens carrying `/` or ending in `.md` as targets and stops at the first word that is neither, so trailing prose after one path still names a single plan
15
17
 
16
- Resolve a relative target against the directory holding the task file rather than against `.canon/tasks/`, and take a project-root target from the root. The archived task is what makes that base matter, since the standard points its line at `../../plans/archive/feature-<slug>.md` once the task sits a folder deeper, and reading that from `.canon/tasks/` lands on a repository-root `plans/archive/` that never exists.
18
+ ### Resolving the target
19
+
20
+ Resolve a relative target against the directory holding the task file rather than against `.canon/tasks/`, and take a project-root target from the root.
21
+
22
+ The archived task is what makes that base matter. The standard points its line at `../../plans/archive/feature-<slug>.md` once the task sits a folder deeper, and reading that from `.canon/tasks/` lands on a repository-root `plans/archive/` that never exists.
17
23
 
18
24
  ## When a tier fails
19
25
 
20
- Tier 1 stops on four failures, and each names a different repair:
26
+ Tier 1 stops on four failures, each naming a different repair. Test them in the order below.
27
+
28
+ | Failure | Stop |
29
+ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
30
+ | The line links several plans | `❌ <path> links <N> plans on its Plan: line (<every target>), so the task does not say which one this run builds. Pass one plan path directly.` |
31
+ | No `Plan:` line at all | `❌ <path> carries no Plan: line, so nothing there names a plan to run. Write the plan and point the task at it, or pass the plan path directly.` |
32
+ | Pointer into a plans archive | `❌ <path> points at an archived plan, which describes work that already shipped. Reopen the task against a live plan, or pass that plan directly.` |
33
+ | Pointer resolves to no file | `❌ <path> points at <target>, which does not exist. The citation is stale, so repoint the task or pass the plan path directly.` |
34
+
35
+ ### Why each test sits where it does
36
+
37
+ Each row carries a reason a shortcut would get wrong.
38
+
39
+ - Test several links first, since taking the first link runs whichever plan leads the line and reports success
40
+ - A row still awaiting a plan is the ordinary case, so the no-line message names the missing pointer rather than the plan sections a reader would then hunt for
41
+ - Test the resolved path for an archive rather than the task's outcomes or its `Pull request:` line, since a stale board gets its ticks wrong and the standard fixes where a shipped pointer lands
42
+
43
+ ### What counts as an archive
21
44
 
22
- - The line links more than one plan. Stop: `❌ <path> links <N> plans on its Plan: line (<every target>), so the task does not say which one this run builds. Pass one plan path directly.` Test this ahead of the three below, since taking the first link runs whichever plan leads the line and reports success.
23
- - No `Plan:` line at all. Stop: `❌ <path> carries no Plan: line, so nothing there names a plan to run. Write the plan and point the task at it, or pass the plan path directly.` A row still awaiting a plan is the ordinary case, so the message names the missing pointer rather than the missing plan sections a reader would then go hunting for.
24
- - The pointer resolves into a plans archive. Stop: `❌ <path> points at an archived plan, which describes work that already shipped. Reopen the task against a live plan, or pass that plan directly.` Test the resolved path rather than the task's outcomes or its `Pull request:` line, since a stale board gets its ticks wrong and the standard fixes where a shipped pointer lands.
25
- - The pointer resolves to no file. Stop: `❌ <path> points at <target>, which does not exist. The citation is stale, so repoint the task or pass the plan path directly.`
45
+ An archive is `.canon/plans/archive/`, plus the two older spellings `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` leaves in place for a project that archived plans before the folder nested. From a task those read `../plans-archive/` and `../.tmp/plans-archive/`.
26
46
 
27
- An archive is `.canon/plans/archive/` and also the two older spellings `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` leaves in place for a project that archived plans before the folder nested, written from a task as `../plans-archive/` and `../.tmp/plans-archive/`. Test all three, since a shipped pointer in a project nobody migrated lands on the older two. Run the archive test ahead of the existence test, so a pointer into an archive that no longer holds the file still refuses as shipped work rather than as a stale citation.
47
+ - Test all three, since a shipped pointer in a project nobody migrated lands on the older two
48
+ - Run the archive test ahead of the existence test, so a pointer into an archive that no longer holds the file still refuses as shipped work rather than as a stale citation
28
49
 
29
- Each tier fails for a different reason and says so. A supplied path resolving to nothing is a typo, a derived path resolving to nothing is a plan nobody wrote, and a task pointer resolving to nothing is a stale citation the board should have caught.
50
+ Each tier fails for a different reason and says so. A supplied path resolving to nothing is a typo, a derived one is a plan nobody wrote, and a task pointer resolving to nothing is a stale citation the board should have caught.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: UI checklist counts
3
- description: What auto-ship Step 5 holds when ui-checklist produces a checklist, so the closing block can name the unchecked visual boxes after git-pr has removed the file
3
+ description: What auto-ship Step 5 holds when ui-checklist produces a checklist, so the closing block can name the unchecked visual boxes after pr-evidence has removed the file
4
4
  ---
5
5
 
6
6
  # Hold the checklist counts
@@ -9,13 +9,18 @@ Step 5 of `auto-ship`. The session reads this file when `ui-checklist` has produ
9
9
 
10
10
  The chain continues to Step 6 here in every run, dispatched or hand-run, since the skill cannot tell the two apart and the draft mark at Step 6 holds the merge either way.
11
11
 
12
+ ## What to count
13
+
12
14
  Count two things in `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root:
13
15
 
14
16
  - `<N>`, the `- [ ]` lines
15
17
  - `<M>`, how many of those end in `(taste)`
16
18
 
17
- Hold both until the Output block. `git-pr` removes the file once it posts the evidence comment, so a count taken after Step 6 reads nothing.
19
+ Hold both until the Output block. `pr-evidence` removes the file once it posts the evidence comment, so a count taken after Step 6 reads nothing.
20
+
21
+ ## Reading the counts into the closing block
18
22
 
19
- The Output block's second line takes both counts. When every box is a taste box, `<N>` and `<M>` match and the boxes are owed to the operator alone, since a driver reports a taste box as needing a person's eyes rather than passing it, so say the operator and drop the UI reviewer clause.
23
+ The Output block's second line takes both counts. When every box is a taste box, `<N>` and `<M>` match and the boxes are owed to the operator alone, so say the operator and drop the UI reviewer clause.
20
24
 
21
- When `ui-checklist` reports nothing to verify visually, it writes no file, Step 5 holds no count, and the Output block carries no boxes line.
25
+ - A driver reports a taste box as needing a person's eyes rather than passing it, which is why the operator owns an all-taste set
26
+ - When `ui-checklist` reports nothing to verify visually, it writes no file, Step 5 holds no count, and the Output block carries no boxes line
@@ -13,9 +13,15 @@ This step runs ahead of Step 1, so what it holds is the raw invocation argument
13
13
  canon tasks plan-branch <argument> --json
14
14
  ```
15
15
 
16
- - `conforms: true`: pass the record's `branch`, which is already `<type>/<slug>`, and invoke nothing else to derive a name.
17
- - `conforms: false`: the plan's own filename breaks a cap in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md`. Pass `branch` anyway and say the cap it broke, since the alternative is a name this session shortened by hand, which is a second derivation and the thing this call exists to prevent. `git-branch` decides the rename at ship.
18
- - Anything else, including a refusal, a record carrying no `branch` key, and an installed binary carrying no `plan-branch` subcommand: invoke `canon:session-worktree` bare and let its ladder derive the name. Say the verb did not answer, so a reader can tell a derived name from a fallback one.
16
+ | Record | Route |
17
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
18
+ | `conforms: true` | Pass the record's `branch`, already `<type>/<slug>`, and invoke nothing else to derive a name |
19
+ | `conforms: false` | The plan's filename breaks a cap in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md`. Pass `branch` anyway and say the cap it broke |
20
+ | Anything else | Invoke `canon:session-worktree` bare and let its ladder derive the name, saying the verb did not answer |
21
+
22
+ - On `conforms: false`, the alternative is a name this session shortened by hand, a second derivation and the thing this call exists to prevent. `git-branch` decides the rename at ship.
23
+ - Anything else covers a refusal, a record carrying no `branch` key, and an installed binary carrying no `plan-branch` subcommand
24
+ - Saying the verb did not answer lets a reader tell a derived name from a fallback one
19
25
 
20
26
  The dispatch runbook runs the same verb on the same plan to pick the branch its collision check clears, so calling it here is what makes the checked branch and the taken branch one string.
21
27
 
@@ -5,40 +5,54 @@ description: Which external sources on incremental building this skill adopted,
5
5
 
6
6
  # Adopted and declined
7
7
 
8
- External sources were read and filtered rather than imported. This file is the record. A later session extending the skill adds to it rather than re-arguing an item already settled here.
8
+ External sources were read and filtered rather than imported. This file is the record, and a later session extending the skill adds to it rather than re-arguing an item settled here.
9
9
 
10
- ## Adopted
10
+ ## Adopted from the default shelf
11
11
 
12
- ### From the default shelf
12
+ ### Small changes
13
13
 
14
- **Small changes.** [Small CLs](https://google.github.io/eng-practices/review/developer/small-cls.html), from Google's engineering practices: a change should be self-contained and address one thing, a refactor goes in a change apart from the feature that needs it, and a test goes in the same change as the code it covers. Adopted as the rule that each commit carries one logical change, the refactor excuse row, and the rule that a slice's test never lands after its code.
14
+ [Small CLs](https://google.github.io/eng-practices/review/developer/small-cls.html), from Google's engineering practices, keeps a change self-contained and about one thing, puts a refactor in a change apart from the feature needing it, and puts a test in the same change as its code.
15
15
 
16
- ### The increment cycle
16
+ Adopted as the rule that each commit carries one logical change, the refactor excuse row, and the rule that a slice's test never lands after its code.
17
17
 
18
- **Incremental implementation.** Addy Osmani's `agent-skills`, pinned at addyosmani/agent-skills@2686b620, [`skills/incremental-implementation/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620/skills/incremental-implementation/SKILL.md). Adopted from it:
18
+ ## Adopted for the increment cycle
19
19
 
20
- - The increment cycle of implement, test, verify, commit, and next slice, with the commit routed through `git-commit` rather than a message format of its own.
21
- - Vertical, risk-first, and contract-first slicing, stated as rules for choosing the next slice rather than as worked examples tied to one stack.
22
- - Rule 1, one thing at a time, as one logical change per commit.
23
- - Rule 2, keep it compilable, as a build left passing at every commit.
20
+ Addy Osmani's `agent-skills`, pinned at addyosmani/agent-skills@2686b620, [`skills/incremental-implementation/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620/skills/incremental-implementation/SKILL.md), supplies the cycle and most of the rules.
24
21
 
25
- #### Rollback and the notes
22
+ ### The cycle and its rules
26
23
 
27
- - Rule 5, rollback-friendly, as the group on keeping each commit safe to revert and the rule against deleting and replacing in one commit.
28
- - The "noticed but not touching" list from its scope section, routed to the open task's findings or the handover rather than offered as new tasks, since a worker may not add a row to the board.
29
- - The note against re-running a command on unchanged code, scoped to a session's own repeats so it never reads as permission to skip a chain's verify step.
30
- - The rationalizations and red flags that carry across stacks, reworded as reasons this toolkit's sessions give, with one row added for the ship step committing everything anyway.
24
+ The increment cycle of implement, test, verify, commit, and next slice is adopted with the commit routed through `git-commit` rather than a message format of its own.
25
+
26
+ - Vertical, risk-first, and contract-first slicing, stated as rules for choosing the next slice rather than as worked examples tied to one stack
27
+ - Rule 1, one thing at a time, as one logical change per commit
28
+ - Rule 2, keep it compilable, as a build left passing at every commit
29
+
30
+ ### Rollback and the notes
31
+
32
+ Rule 5, rollback-friendly, is the group on keeping each commit safe to revert and the rule against deleting and replacing in one commit.
33
+
34
+ - The "noticed but not touching" list from its scope section, routed to the open task's findings or the handover, since a worker may not add a row to the board
35
+ - The note against re-running a command on unchanged code, scoped to a session's own repeats so it never reads as permission to skip a chain's verify step
36
+ - The rationalizations and red flags that carry across stacks, reworded as this toolkit's sessions give them, plus one row for the ship step committing everything anyway
31
37
 
32
38
  ## Declined
33
39
 
34
- **Rule 0, simplicity first, and the abstraction red flags.** Declined because `code-craft` owns when an abstraction earns its place and when to write the plainest code that passes. Restating it here would put two owners on one rule.
40
+ Each item below was read and left out, with the reason it changes nothing a session does here.
41
+
42
+ ### Rules another skill owns
43
+
44
+ **Rule 0, simplicity first, and the abstraction red flags.** `code-craft` owns when an abstraction earns its place and when to write the plainest code that passes, and restating it here would put two owners on one rule.
45
+
46
+ **Rule 4, safe defaults.** A conservative default is a concern of the interface a caller sees, which belongs to the skill shaping that interface rather than to how the work is sequenced.
47
+
48
+ ### Rules this skill already covers
35
49
 
36
- **The rest of its scope section.** Declined as a scope call this skill makes: its slices already keep to the plan, and minimal edits, no unrequested features, and edits limited to what the user named restate that in different words. Only the noticed list was new.
50
+ **The rest of its scope section.** Its slices already keep to the plan, and minimal edits, no unrequested features, and edits limited to what the user named restate that in different words. Only the noticed list was new.
37
51
 
38
- **Rule 3, feature flags for incomplete features.** Declined because the slices of one branch merge together as one pull request rather than reaching trunk one at a time, so nothing incomplete is exposed between them.
52
+ **Rule 3, feature flags for incomplete features.** The slices of one branch merge together as one pull request rather than reaching trunk one at a time, so nothing incomplete is exposed between them.
39
53
 
40
- **Rule 4, safe defaults.** Declined because a conservative default is a concern of the interface a caller sees, which belongs to the skill shaping that interface rather than to how the work is sequenced.
54
+ ### Numbers and commands tied to one stack
41
55
 
42
- **The 100-line threshold.** Its red flag of more than 100 lines written without running tests. Declined because a line count means something different on every stack and a session cannot carry it from one to the next. The red flag is stated as a check instead: a slice implemented whose tests have not run.
56
+ **The 100-line threshold.** Its red flag of more than 100 lines written without running tests means something different on every stack. The red flag is stated as a check instead, being a slice implemented whose tests have not run.
43
57
 
44
- **Its per-stack command lists and its definition-of-done pointer.** Declined because the project's own `CLAUDE.md` names its verify commands, and a body naming runners stops holding on the next stack.
58
+ **Its per-stack command lists and its definition-of-done pointer.** The project's own `CLAUDE.md` names its verify commands, and a body naming runners stops holding on the next stack.
@@ -25,7 +25,8 @@ The folder is gitignored, so nothing in a repository checks its shape and nothin
25
25
 
26
26
  Governs the canvas content under `.canon/canvas/`: page folder names, frame files, the `layout.json` shape, how tokens reach a frame, and what a frame must not assume about where it renders.
27
27
 
28
- Also governs the house style of an explanation frame, being a diagram, a board of notes, or a comparison. A mockup of the project's own interface is not an explanation frame, and it follows the project's design document for type, color, and layout.
28
+ - Also governs the house style of an explanation frame, being a diagram, a board of notes, or a comparison
29
+ - A mockup of the project's own interface is not an explanation frame, and follows the project's design document for type, color, and layout
29
30
 
30
31
  Does not govern:
31
32
 
@@ -61,6 +62,8 @@ A canvas failing these is non-conforming even when it satisfies every shape rule
61
62
 
62
63
  ### Content and edits
63
64
 
65
+ A frame is the only copy of its markup, so it carries everything it needs.
66
+
64
67
  - Keep a frame self-contained. Inline its own styles and scripts, or link a file inside the same page folder, since a frame is served from its page and nothing outside the canvas resolves.
65
68
  - Use the project's custom properties, `var(--<name>)`, for every value the token stylesheet defines. A literal copied from it shows the right color today and the wrong one after the next token change.
66
69
  - Edit a frame by rewriting its file. The file is the frame, and nothing else holds a copy of its markup.
@@ -76,9 +79,12 @@ Applies to an explanation frame only. A mockup of the project's interface render
76
79
 
77
80
  ### Colors, faces, and fit
78
81
 
79
- - Take colors from the project's custom properties. A frame that defines colors of its own sets the dark values on `:root` and the light ones under `[data-theme="light"]`, since the shell sets `data-theme` on each frame's root.
80
- - Name only the faces the canvas serves into every frame: `Geist Variable` for text, `Noto Sans Mono` for code, and `Excalifont` for a hand-drawn look. They render the same in a capture and in any browser, so a height fitted against them holds.
81
- - Make each box tall enough to show all its content, with no scrollbar and no clipped line. Run `canon canvas fit <page>/<frame>` rather than estimating, since it measures the content in the capture browser and sets the height.
82
+ Take colors from the project's custom properties. A frame defining colors of its own sets the dark values on `:root` and the light ones under `[data-theme="light"]`, since the shell sets `data-theme` on each frame's root.
83
+
84
+ - Name only the faces the canvas serves into every frame, being `Geist Variable` for text, `Noto Sans Mono` for code, and `Excalifont` for a hand-drawn look
85
+ - Those render the same in a capture and in any browser, so a height fitted against them holds
86
+ - Make each box tall enough to show all its content, with no scrollbar and no clipped line
87
+ - Run `canon canvas fit <page>/<frame>` rather than estimating, since it measures the content in the capture browser and sets the height
82
88
  - Read frames left to right in reading order. Let `frame add` place each frame after the last with the standard gap, and move one only when the operator asks for a position.
83
89
 
84
90
  ## Layout
@@ -89,6 +95,8 @@ Applies to an explanation frame only. A mockup of the project's interface render
89
95
 
90
96
  ### Missing boxes and writes
91
97
 
98
+ The layout file is shared state, so a write never discards a box another writer or reader holds.
99
+
92
100
  - Leave a frame out of the layout only when its position does not matter yet. A reader places an unnamed frame in a row after the others, at the default size of 1440 by 900.
93
101
  - Never write the file while a writer holds its lock, which is the same name with `.lock` appended. Two writers each replacing the whole file lose one of the two edits.
94
102
  - Treat a layout that does not parse as a defect to repair, never as an empty one to overwrite. Writing over it erases every box it held.
@@ -107,7 +115,8 @@ The keys below are the ones a reader parses. The frame names are placeholders.
107
115
  ## Tokens
108
116
 
109
117
  - Expect the token stylesheet first in every frame's `head` when it is served, ahead of anything the frame links. A stylesheet the frame links itself still wins the cascade.
110
- - Read where the tokens come from in this order: the canvas tool's own module inside its own checkout, else the project's installed base stylesheet plus anything in its project override folder, else none. A canvas with no token source renders unstyled and says so.
118
+ - Read the tokens from the canvas tool's own module inside its own checkout, else the project's installed base stylesheet plus its project override folder, else none
119
+ - A canvas with no token source renders unstyled and says so
111
120
  - Never paste the token stylesheet into a frame. The injected copy follows the project, and a pasted one stops following it the moment it is written.
112
121
 
113
122
  ## What a frame must not assume
@@ -118,7 +127,9 @@ The keys below are the ones a reader parses. The frame names are placeholders.
118
127
 
119
128
  ### Font, source, and checkout
120
129
 
121
- - Do not assume a default font. Set `font-family` with a served face first on an element the frame's text inherits from, since a capture checks the first family of the text it renders and the browser's default serif is absent from many machines. A frame naming a machine family such as `DejaVu Sans` renders at another height in another browser, which `canon canvas fit` reports.
130
+ Do not assume a default font. Set `font-family` with a served face first on an element the frame's text inherits from, since a capture checks the first family of the text it renders and the browser's default serif is absent from many machines.
131
+
132
+ - A frame naming a machine family such as `DejaVu Sans` renders at another height in another browser, which `canon canvas fit` reports
122
133
  - Do not assume the frame is the source. A picked direction is carried into the project's design document or a plan, and the operator clears the frame once it has been carried.
123
134
  - Do not assume the canvas survives the checkout. The folder is gitignored, so a lost checkout loses every page in it.
124
135
 
@@ -30,8 +30,8 @@ Does not govern:
30
30
 
31
31
  ## Two shapes
32
32
 
33
- - **An intent record** is the shape a project writes by hand. It carries rules, omissions, and each role's intent, and its lead names the stylesheet the values live in. It carries no value, since a hand-typed copy of the stylesheet drifts from it.
34
- - **A values record** is generated from a token source and carries the value tables beside the rules. It is never edited by hand, and its lead names the module it is rendered from. The toolkit's own record is one.
33
+ - **An intent record** is the shape a project writes by hand, carrying rules, omissions, and each role's intent, with a lead naming the stylesheet. It carries no value, since a hand-typed copy drifts.
34
+ - **A values record** is generated from a token source and carries value tables beside the rules. Never hand-edited, its lead names the module it renders from. The toolkit's own record is one.
35
35
 
36
36
  Everything below applies to both shapes unless it names one.
37
37
 
@@ -68,24 +68,43 @@ Headings and table rows are never counted, and a section holding a table and no
68
68
 
69
69
  ## Sections
70
70
 
71
- Use `## Overview`, `## Colors`, `## Typography`, `## Spacing`, `## Shapes`, `## Motion`, and `## Iconography`, in that order, which follows Google's DESIGN.md for the sections the two share. An optional `## Layout` sits between Spacing and Shapes. The parser still reads a record written under the earlier names, `## Personality`, `## Color`, and `## Borders`, as the sections they became.
71
+ Use `## Overview`, `## Colors`, `## Typography`, `## Spacing`, `## Shapes`, `## Motion`, and `## Iconography`, in that order, which follows Google's DESIGN.md for the sections the two share.
72
+
73
+ - An optional `## Layout` sits between Spacing and Shapes
74
+ - The parser still reads the earlier names `## Personality`, `## Color`, and `## Borders` as the sections they became
72
75
 
73
76
  In an intent record, `## Colors` carries a `Role | Property | Intent` table and `## Shapes` a `Role | Property | When used` table. Each row names the custom property the stylesheet declares for that role, such as `--color-accent`. Typography and Spacing carry rules alone.
74
77
 
75
78
  Add either optional section when the project has content for it:
76
79
 
77
- - `## Layout`: page width, breakpoints, and grid rules, as current constraints. The surface-capture rule reads the breakpoints from here, so a project with none declared here is captured at the 320 reflow floor alone.
80
+ - `## Layout`: page width, breakpoints, and grid rules as current constraints. The surface-capture rule reads breakpoints here, so a project declaring none is captured at the 320 reflow floor alone.
78
81
  - `## Mark`: the logo's construction rules and the files that carry it
79
82
 
80
83
  ## The uncertainty tag
81
84
 
82
85
  Applies to a values record alone. An intent record carries no value to tag, and a guessed value is marked where it is written, in the stylesheet.
83
86
 
84
- A cell no source anchors ends in ` ? verify`, written inside the cell rather than as a trailing column, since a trailing marker breaks the table parse. A cell wrapping itself in a code span carries the tag inside the span, as in `` `#ffffff ? verify` ``. Both spellings parse.
87
+ ### Writing the tag
88
+
89
+ A cell no source anchors ends in ` ? verify`, written inside the cell rather than as a trailing column, since a trailing marker breaks the table parse. A cell wrapping itself in a code span carries the tag inside the span, as in `` `#ffffff ? verify` ``, and both spellings parse.
90
+
91
+ - The renderer splits the tag off the value, so a swatch and a font sample are built from the value alone and the marker shows beside it
92
+ - The preview reports anchored cells against tagged ones, which is where a reviewer reads the record's overall confidence
93
+
94
+ ### Which columns count
95
+
96
+ The table fixes which columns the ratio reads, not the record. The first column names its row, and `Multiplier` and `When used` restate what the row carries, so no source could anchor them and none is counted.
97
+
98
+ | Section | Counted columns |
99
+ | ---------- | ----------------------------------------- |
100
+ | Colors | `Intent`, `Value` |
101
+ | Typography | `Family`, `Weight`, `Size`, `Line height` |
102
+ | Spacing | `Value` |
103
+ | Shapes | `Radius`, `Width` |
85
104
 
86
- The renderer splits the tag off the value, so a swatch and a font sample are built from the value alone and the marker shows beside it. The preview also reports how many cells are anchored against how many are tagged, which is the reading a reviewer takes the record's overall confidence from.
105
+ A cell tagged outside that set counts anyway, so a marker the preview draws is never missing from the ratio beside it.
87
106
 
88
- Which columns that ratio reads is fixed by the table rather than by the record. The first column of each table names its row, and `Multiplier` and `When used` restate what the row already carries, so none of them is something a source could anchor and none is counted. That leaves `Intent` and `Value` in Colors, `Family`, `Weight`, `Size`, and `Line height` in Typography, `Value` in Spacing, and `Radius` and `Width` in Shapes. A cell tagged outside that set counts anyway, so a marker the preview draws is never missing from the ratio beside it.
107
+ ### Prose sections
89
108
 
90
109
  A prose section takes its uncertainty inline instead, in a sentence saying what is proposed and what has yet to confirm it. A tag appended to a paragraph renders verbatim.
91
110
 
@@ -21,7 +21,8 @@ A cache keyed on a static string serves a stale browser or toolchain after a ver
21
21
  - Start the checks that share setup in one job and split them only once a run log puts the gate past roughly two minutes
22
22
  - Pin every action to a tag that cannot cross a major version
23
23
  - Key a cache on the version string of the thing it caches
24
- - Give every workflow a manual trigger beside its primary one
24
+ - Give every workflow a manual trigger beside its primary one, except one that commits back, where a manual run has no branch to land on
25
+ - Default the token to read-only and grant a write scope only on the job that needs it
25
26
  - Bound artifact upload to failures and set an expiry on it
26
27
 
27
28
  ## Must not