@erclx/canon 5.40.0 → 5.42.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 (187) hide show
  1. package/README.md +34 -17
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/api-design/references/adopted.md +34 -14
  4. package/claude/skills/auto-ship/REQUIREMENT.md +2 -0
  5. package/claude/skills/auto-ship/SKILL.md +28 -2
  6. package/claude/skills/auto-ship/references/draft-mark.md +32 -6
  7. package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
  8. package/claude/skills/auto-ship/references/fan-in.md +59 -0
  9. package/claude/skills/auto-ship/references/tier-failures.md +31 -10
  10. package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
  11. package/claude/skills/auto-ship/references/worktree-name.md +9 -3
  12. package/claude/skills/build-in-slices/references/adopted.md +35 -21
  13. package/claude/skills/canvas-board/references/canvas.md +17 -6
  14. package/claude/skills/canvas-board/references/design.md +26 -7
  15. package/claude/skills/code-craft/references/adopted.md +58 -20
  16. package/claude/skills/codebase-layout/references/adopted.md +49 -16
  17. package/claude/skills/codebase-layout/references/frontend.md +11 -4
  18. package/claude/skills/codebase-layout/references/tests.md +4 -2
  19. package/claude/skills/context-fold/references/classify.md +10 -15
  20. package/claude/skills/context-fold/references/completion-report.md +11 -9
  21. package/claude/skills/context-fold/references/context-refresh.md +26 -9
  22. package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
  23. package/claude/skills/create-rule/REQUIREMENT.md +5 -0
  24. package/claude/skills/create-rule/SKILL.md +9 -1
  25. package/claude/skills/create-rule/references/checklist.md +26 -0
  26. package/claude/skills/create-rule/references/rule.md +98 -20
  27. package/claude/skills/create-skill/SKILL.md +1 -0
  28. package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
  29. package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
  30. package/claude/skills/create-skill/references/skill-paths.md +7 -4
  31. package/claude/skills/create-skill/references/skill-practice.md +6 -3
  32. package/claude/skills/create-skill/references/skill-requirement.md +4 -2
  33. package/claude/skills/create-skill/references/skill.md +67 -44
  34. package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
  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 +54 -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-figure/references/architecture-set.md +7 -3
  58. package/claude/skills/draft-figure/references/figures.md +8 -6
  59. package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
  60. package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
  61. package/claude/skills/draft-figure/references/mermaid.md +10 -5
  62. package/claude/skills/draft-ready/references/ready.md +22 -15
  63. package/claude/skills/git-branch/REQUIREMENT.md +17 -6
  64. package/claude/skills/git-branch/SKILL.md +63 -7
  65. package/claude/skills/git-branch/references/branch.md +11 -1
  66. package/claude/skills/git-branch/references/slug.md +17 -5
  67. package/claude/skills/git-commit/references/commit.md +8 -0
  68. package/claude/skills/git-commit/references/versioning.md +23 -17
  69. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  70. package/claude/skills/git-followup/SKILL.md +5 -6
  71. package/claude/skills/git-issue/references/issue.md +29 -16
  72. package/claude/skills/git-pr/REQUIREMENT.md +1 -5
  73. package/claude/skills/git-pr/SKILL.md +11 -22
  74. package/claude/skills/git-pr/references/final-command.md +21 -8
  75. package/claude/skills/git-pr/references/labels.md +45 -28
  76. package/claude/skills/git-pr/references/pr.md +28 -9
  77. package/claude/skills/git-pr/references/publish.md +42 -28
  78. package/claude/skills/git-pr/references/task-number.md +20 -8
  79. package/claude/skills/git-ship/SKILL.md +1 -1
  80. package/claude/skills/plan-feature/references/batches.md +48 -1
  81. package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
  82. package/claude/skills/plan-feature/references/plan.md +59 -20
  83. package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
  84. package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
  85. package/claude/skills/plan-intake/references/intake.md +29 -24
  86. package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
  87. package/claude/skills/plan-intake-answer/SKILL.md +1 -2
  88. package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
  89. package/claude/skills/pr-evidence/SKILL.md +53 -0
  90. package/claude/skills/pr-evidence/references/evidence.md +150 -0
  91. package/claude/skills/review-address/references/post-review-findings.md +10 -3
  92. package/claude/skills/review-address/references/rebase-conflicts.md +22 -7
  93. package/claude/skills/review-address/references/rest-reads.md +3 -1
  94. package/claude/skills/review-craft/references/adopted.md +35 -18
  95. package/claude/skills/review-craft/references/security.md +42 -7
  96. package/claude/skills/review-craft/references/ui.md +23 -8
  97. package/claude/skills/review-pr/SKILL.md +6 -6
  98. package/claude/skills/review-pr/references/body-variants.md +29 -9
  99. package/claude/skills/review-pr/references/close-out.md +20 -5
  100. package/claude/skills/review-pr/references/key-changes.md +27 -3
  101. package/claude/skills/review-pr/references/post.md +83 -31
  102. package/claude/skills/review-pr/references/scope.md +54 -19
  103. package/claude/skills/review-ui/SKILL.md +2 -0
  104. package/claude/skills/review-ui/references/close-out.md +49 -0
  105. package/claude/skills/review-ui/references/driving.md +24 -4
  106. package/claude/skills/review-ui/references/post.md +43 -13
  107. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
  108. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +81 -40
  109. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
  110. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
  111. package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
  112. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
  113. package/claude/skills/role-orchestrator/references/orchestrator-output.md +12 -4
  114. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
  115. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
  116. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
  117. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
  118. package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
  119. package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
  120. package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
  121. package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
  122. package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
  123. package/claude/skills/role-worker/REQUIREMENT.md +2 -0
  124. package/claude/skills/role-worker/SKILL.md +17 -0
  125. package/claude/skills/search-craft/references/adopted.md +18 -6
  126. package/claude/skills/session-map/references/session.md +26 -7
  127. package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
  128. package/claude/skills/systematic-debugging/references/adopted.md +30 -16
  129. package/claude/skills/target-check/references/domains.md +39 -11
  130. package/claude/skills/target-setup/references/detect.md +80 -65
  131. package/claude/skills/target-setup/references/indexes.md +8 -6
  132. package/claude/skills/task-board/references/board.md +86 -30
  133. package/claude/skills/task-board/references/decline.md +29 -13
  134. package/claude/skills/task-board/references/tasks-decline.md +12 -5
  135. package/claude/skills/task-board/references/tasks.md +65 -33
  136. package/claude/skills/task-complete/references/archive.md +41 -17
  137. package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
  138. package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
  139. package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
  140. package/claude/skills/teach-workspace/SKILL.md +1 -2
  141. package/claude/skills/teach-workspace/references/glossary.md +6 -2
  142. package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
  143. package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
  144. package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
  145. package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
  146. package/claude/skills/teach-workspace/references/promotion.md +31 -8
  147. package/claude/skills/teach-workspace/references/revisit.md +8 -2
  148. package/claude/skills/teach-workspace/references/teach.md +17 -9
  149. package/claude/skills/test-craft/references/adopted.md +48 -14
  150. package/claude/skills/test-craft/references/component.md +7 -4
  151. package/claude/skills/test-craft/references/e2e.md +25 -7
  152. package/claude/skills/test-craft/references/unit.md +3 -1
  153. package/claude/skills/test-first/references/adopted.md +12 -4
  154. package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
  155. package/claude/skills/ui-checklist/SKILL.md +1 -1
  156. package/claude/skills/video-craft/references/adopted.md +62 -18
  157. package/claude/skills/write-human/references/adopted.md +21 -8
  158. package/docs/workflow/parallel-features.md +2 -1
  159. package/docs/workflow/skill-map.md +2 -1
  160. package/package.json +1 -1
  161. package/src/claude/cases/git.ts +4 -0
  162. package/src/claude/cases/workflow.ts +5 -0
  163. package/src/commands/pr.ts +174 -37
  164. package/src/commands/records.ts +11 -3
  165. package/src/context/shape-gated.ts +1 -0
  166. package/src/markdown/scope.ts +150 -2
  167. package/src/pr/frames.ts +53 -9
  168. package/src/pr/lift.ts +6 -3
  169. package/src/pr/review-state.ts +182 -0
  170. package/src/records/validate.ts +1 -0
  171. package/src/tasks/answers.ts +79 -2
  172. package/src/tasks/fan-in.ts +176 -0
  173. package/src/tasks/stack.ts +1 -1
  174. package/tooling/astro/reference.md +80 -39
  175. package/tooling/base/reference.md +63 -32
  176. package/tooling/base/seeds/canon/context/ci.md +7 -15
  177. package/tooling/base/seeds/canon/context/development.md +14 -14
  178. package/tooling/claude/reference.md +40 -22
  179. package/tooling/cloudflare/reference.md +31 -12
  180. package/tooling/go/reference.md +47 -23
  181. package/tooling/nextjs/reference.md +52 -19
  182. package/tooling/php/reference.md +35 -16
  183. package/tooling/python/reference.md +47 -30
  184. package/tooling/shell/reference.md +6 -5
  185. package/tooling/vite-react/reference.md +49 -21
  186. package/tooling/web/reference.md +130 -70
  187. package/claude/skills/git-pr/references/evidence.md +0 -124
@@ -44,9 +44,11 @@ Does not govern:
44
44
 
45
45
  - Name the folder `<nn>-<slug>`, a two-digit ordinal and a kebab-case slug.
46
46
  - The ordinal marks a folder per track, opened once and worked over time, unlike a file addressed by name, one with its own sorting prefix, or one overwritten on purpose.
47
- - Claim the ordinal through `canon records ordinal groundwork <slug> --claim`, which reads the highest one across both `.canon/groundwork/` and `.canon/intake/` and creates the folder in one atomic act, so two sessions opening at once never share a number. The two kinds share one order.
47
+ - Claim the ordinal through `canon records ordinal groundwork <slug> --claim`, which reads the highest across `.canon/groundwork/` and `.canon/intake/`, since the two kinds share one order
48
+ - The claim creates the folder in the same atomic act, so two sessions opening at once never share a number
48
49
  - With neither folder holding an entry, the first one opened takes `01`, whatever number a track's own files start at.
49
- - Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
50
+
51
+ Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
50
52
 
51
53
  ## What a working track looks like
52
54
 
@@ -86,20 +88,15 @@ A folder missing `06` and `07` is live, and that is its only status marker.
86
88
 
87
89
  ## README.md
88
90
 
89
- Orients. Holds no findings.
91
+ Orients and holds no findings. It states the phase out loud in its first three lines, in the form `Groundwork phase. Nothing here is a feature plan.`
90
92
 
91
93
  - A one-line definition of the investigation
92
94
  - A `## Why` section stating why the track is running now
93
95
  - A file-map table of filename and what it holds, kept current
94
96
  - A `## Method` section splitting internal sources from external ones, naming which were used and which were not yet done, and listing under a leads heading any external source found but not opened
97
+ - Closing `## Prior art` and `## Source citation` sections, the second stating the rule below so a returning session finds it in the folder
95
98
 
96
- ### Closing sections and phase
97
-
98
- - A `## Prior art` section
99
- - A `## Source citation` section stating the rule below, so a returning session finds it in the folder
100
- - The phase stated out loud in the first three lines, in the form `Groundwork phase. Nothing here is a feature plan.`
101
-
102
- Every claim about a source outside the project carries a link to it, wherever the claim appears in the folder. Without one, a later reader cannot tell a fetched page from recall. A source found and not read is listed as a lead and is never cited, since a link to a page nobody opened is worse than no link. Listing it stops a later pass re-searching for it.
99
+ Every claim about a source outside the project carries a link to it, wherever the claim appears in the folder, so a later reader can tell a fetched page from recall. A source found and not read is listed as a lead and never cited, since a link to a page nobody opened is worse than none. Listing it stops a later pass re-searching for it.
103
100
 
104
101
  Where the track supersedes an earlier plan or an earlier folder, name it and say not to go looking for it. Without that, the old reasoning keeps circulating.
105
102
 
@@ -117,11 +114,10 @@ Written when the subject is large enough to run away. Holds constraints, risks,
117
114
 
118
115
  ## 06-decision.md
119
116
 
120
- Closes the folder. Everything above it is input. Write it from the skeleton under `## Template`, with an H3 per dropped alternative.
117
+ Closes the folder. Everything above it is input. Write it from the skeleton under `## Template`, with an H3 per dropped alternative, a list that stops a future session re-proposing a rejected idea.
121
118
 
122
- `## Revisit when` carries the "Overturned by" line of each lean that became the decision, as written. A lean the decision did not take carries nothing, and a track whose deciding leans carried no overturn line omits the section.
123
-
124
- The dropped list stops a future session re-proposing a rejected idea.
119
+ - `## Revisit when` carries the "Overturned by" line of each lean that became the decision, as written
120
+ - A lean the decision did not take carries nothing, and a track whose deciding leans carried no overturn line omits the section
125
121
 
126
122
  ## 07-next-session.md
127
123
 
@@ -158,7 +154,9 @@ A lean is weaker than a plan's suggestion: it records the current read on an ope
158
154
 
159
155
  ## Template
160
156
 
161
- ### README.md
157
+ The orienting README comes first, then the closing decision, with an H3 per dropped alternative.
158
+
159
+ **`README.md`**
162
160
 
163
161
  ```markdown
164
162
  ---
@@ -203,7 +201,7 @@ Every claim about a source outside the project carries a link. A source found
203
201
  and not read is listed as a lead and is never cited.
204
202
  ```
205
203
 
206
- ### 06-decision.md
204
+ **`06-decision.md`**
207
205
 
208
206
  ```markdown
209
207
  ---
@@ -7,7 +7,7 @@ description: Folder layout, ordinal naming, reserved index number, frontmatter a
7
7
 
8
8
  Applies to an intake folder at `.canon/intake/<nn>-<slug>/`. One folder holds one dump, filed by domain, and every finding in it is an item carrying a measured problem, one proposed fix, and a verdict.
9
9
 
10
- The folder is gitignored, and backed wherever a records remote is configured: `canon records push` and `canon records pull` protect it against the machine being lost there, refuse with `no-remote` where it is not, and neither protects against a compaction dropping a session's reasoning before anyone has pushed. No check reaches its contents, so the shape below survives only by being read.
10
+ The folder is gitignored. Where a records remote is configured, `canon records push` and `canon records pull` protect it against losing the machine, and elsewhere they refuse with `no-remote`. Neither saves reasoning a compaction drops before a push. No check reaches its contents, so the shape below survives only by being read.
11
11
 
12
12
  <!-- canon-length-exempt: the folder shape and the item template share one reader, and a split into a second reference is queued as its own change -->
13
13
 
@@ -41,11 +41,13 @@ Does not govern:
41
41
 
42
42
  ## Folder name
43
43
 
44
- - Name the folder `<nn>-<slug>`, a two-digit zero-padded ordinal followed by a kebab-case slug. This is the folder's own ordinal, distinct from the `NN-<domain>.md` numbering a cluster file carries inside it.
44
+ - Name the folder `<nn>-<slug>`, a two-digit zero-padded ordinal and a kebab-case slug, distinct from the `NN-<domain>.md` numbering of its cluster files
45
45
  - The ordinal marks a folder per track, opened once and worked over time, distinct from a file addressed by name, one already carrying its own sorting prefix, or one deliberately overwritten.
46
- - Claim the ordinal through `canon records ordinal intake <slug> --claim`, which reads the highest one already present across both `.canon/intake/` and `.canon/groundwork/` and creates the folder in the same atomic act, closing the race a read-then-create sequence leaves open between two sessions opening at once. A listing then sorts by when each folder opened rather than alphabetically, and the count includes both kinds because the two share one creation-order line.
47
- - With neither folder holding an entry, the first one opened takes `01`. Do not read this off the numbering inside a dump, which starts at `00` and disagrees with groundwork's own first required file.
48
- - Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
46
+ - Claim the ordinal through `canon records ordinal intake <slug> --claim`, which reads the highest across `.canon/intake/` and `.canon/groundwork/`, since the two share one creation order
47
+ - The claim creates the folder in the same atomic act, closing the race a read-then-create leaves open between two sessions opening at once
48
+ - With neither folder holding an entry, the first one opened takes `01`, never read off a dump's inner numbering, which starts at `00`
49
+
50
+ Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
49
51
 
50
52
  ## What a working intake looks like
51
53
 
@@ -68,9 +70,8 @@ An intake failing these is non-conforming even when it satisfies every shape rul
68
70
 
69
71
  `00` is the only reserved number. Everything else is read order, and the domain rides in the filename so a reader knows what `07-tooling.md` holds without opening it.
70
72
 
71
- Do not reserve mid-range numbers. Clusters differ per dump, so a contract over `06` would force every future intake into one dump's shape. A folder whose shape is fixed can reserve its numbers, and that half of the convention does not transfer.
72
-
73
- Let the file count follow the number of separable domains. A large dump with two domains is a small folder.
73
+ - Do not reserve mid-range numbers, since clusters differ per dump and a contract over `06` would force every intake into one dump's shape
74
+ - Let the file count follow the number of separable domains. A large dump with two domains is a small folder.
74
75
 
75
76
  ## Frontmatter and dating
76
77
 
@@ -113,35 +114,39 @@ Where an item touches a task already on the board, say so in the index rather th
113
114
  ```
114
115
 
115
116
  - `Problem:`, `Fix:`, `Worth it:`, and the empty `You:` slot ship on every item. The other two are conditional.
116
- - Number items per cluster file, and give a finding split after the fact a letter suffix on the number it came from, as in `3a` beside `3`. Renumbering the items below it instead moves every label a reader or an answer already cited.
117
- - `Suggested:` is required whenever `Open:` is present. A bare question invites a bare answer, and `ok` against two defensible options carries no information. Where the answer is the operator's preference rather than a technical call, say so in that form rather than inventing a default.
118
- - `Overlaps:` never replaces `Worth it:`. The items where a live board task might be the thing that is wrong are exactly the ones whose verdict matters most.
119
-
120
- Two heading levels is the right depth inside a cluster file. A third means the cluster should have been its own file.
117
+ - Number items per cluster file, giving a finding split later a letter suffix such as `3a` beside `3`, since renumbering moves every cited label
118
+ - `Suggested:` is required whenever `Open:` is present, since `ok` against two defensible options carries no information
119
+ - Where the answer is the operator's preference rather than a technical call, say so in that form rather than inventing a default
120
+ - `Overlaps:` never replaces `Worth it:`, since an item a live board task might have wrong is the one whose verdict matters most
121
121
 
122
- An item may carry a bolded standalone line between the bullets where a finding needs a name of its own. Keep it rare. Everything fitting the four bullets belongs in them.
122
+ Two heading levels is the right depth inside a cluster file. A third means the cluster should have been its own file. An item may carry a rare bolded standalone line between the bullets where a finding needs a name of its own, and everything fitting the four bullets belongs in them.
123
123
 
124
124
  ## The answer contract
125
125
 
126
- `You:` belongs to the operator and ships empty on every item.
126
+ `You:` belongs to the operator and ships empty on every item. Empty means unread and never agreement, so accepting a verdict is typed as one token, `- **You:** ok`.
127
127
 
128
- Empty means unread. It never means agreement. Accepting a verdict is typed as one token, `- **You:** ok`.
128
+ - Never fill a `You:` slot, and never infer a disposition from an empty one
129
+ - On a resume pass, report unread items by count rather than deciding them
129
130
 
130
- That inverts the plan file's contract, where a blank answer slot means accept the suggestion, and the inversion is deliberate. A plan is read in one sitting with every question already surfaced in conversation. An intake folder is read over weeks, so an empty slot is ambiguous between accepting the verdict and never having reached the item, and the second reading is far more likely. Acting on silence as consent ships a change nobody approved.
131
+ ### Why silence is not consent
131
132
 
132
- Never fill a `You:` slot, and never infer a disposition from an empty one. On a resume pass, report unread items by count rather than deciding them.
133
+ This inverts the plan file's contract, where a blank slot means accept the suggestion. A plan is read in one sitting with every question already surfaced. An intake folder is read over weeks, so an empty slot more likely means nobody reached the item, and acting on it ships a change nobody approved.
133
134
 
134
- A slot is filled two ways. The operator types into the cluster file, or answers in chat and a verb lands the selection on the item. Both put the answer on the item, which is what keeps retrieval working, and neither lets a session decide one. An answer given in conversation and never written back leaves the item unread, since the file rather than the conversation is the record.
135
+ ### Filling a slot
135
136
 
136
- An item already carrying an answer is refused rather than overwritten, whichever route the second answer arrives by. A filled slot is a decision already made, and revising one is the operator editing their own line.
137
+ The operator types into the cluster file, or answers in chat and a verb lands the selection on the item. Both put the answer on the item, which keeps retrieval working, and neither lets a session decide one.
137
138
 
138
- ## Retrieval
139
+ - An answer given in conversation and never written back leaves the item unread, since the file is the record
140
+ - An item already carrying an answer is refused rather than overwritten, whichever route the second answer takes
141
+ - Revising a filled slot is the operator editing their own line
139
142
 
140
- Answers live on items, so one pass over the folder reports every touched slot.
143
+ ## Retrieval
141
144
 
142
- A session with the toolkit CLI on PATH reads the folder through `canon intake list`, which reports per-folder counts bare and one folder's items with `--json`, and takes `--unread` to keep only the empty slots. It is the surface under test, and it skips the index and every fenced sample, which the greps below cannot do.
145
+ Answers live on items, so one pass over the folder reports every touched slot. With the toolkit CLI on PATH, read the folder through `canon intake list`, the surface under test.
143
146
 
144
- The greps stay for a reader without the CLI, and they overcount by whatever the folder displays in a fence.
147
+ - Bare, it reports per-folder counts, `--json` gives one folder's items, and `--unread` keeps only the empty slots
148
+ - It skips the index and every fenced sample, which the greps below cannot do
149
+ - The greps stay for a reader without the CLI, and they overcount by whatever the folder displays in a fence
145
150
 
146
151
  ```bash
147
152
  awk '/^### /{h=FILENAME": "$0} /^- \*\*You:\*\*./{print h; print " "$0}' *.md
@@ -45,4 +45,4 @@ The batching fails a fifth way. A folder holding thirty unread items put as thir
45
45
  - Promoting an answered item onto the board, which is `task-board` and runs after the answers land
46
46
  - The item format, the answer contract, and retrieval, which the `plan-intake` skill's `references/intake.md` owns and this skill cites
47
47
  - The comparable answer slots in groundwork and feature plans, which carry their own contracts and are a separate measurement
48
- - Deciding when to fire. The skill is user-invoked through `disable-model-invocation`, so answering is the operator's call rather than a description match.
48
+ - Deciding when to fire. The description states `Do NOT auto-trigger`, so answering is the operator's call rather than a description match.
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: plan-intake-answer
3
- description: Walks an intake folder's unread items and puts them as batched questions in chat, writing each selection back onto the item it answers. Use when asked to "answer the intake", "work through the open items", "answer my intake questions", "go through the dump", or "let me answer these from here". Do NOT use to file a dump or write new items, which is `plan-intake`.
4
- disable-model-invocation: true
3
+ description: Walks an intake folder's unread items and puts them as batched questions in chat, writing each selection back onto the item it answers. Use when asked to "answer the intake", "work through the open items", "answer my intake questions", "go through the dump", or "let me answer these from here". Do NOT use to file a dump or write new items, which is `plan-intake`. Do NOT auto-trigger.
5
4
  metadata:
6
5
  family: decide
7
6
  ---
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: pr-evidence
3
+ description: What posting a pull request's rendered-surface evidence is for, the gaps it closes, and what it refuses to do
4
+ ---
5
+
6
+ # PR evidence requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, the evidence a pull request carries is one step inside `git-pr`. A session refreshing the screenshots on a new head either reruns a title and body it did not mean to touch, or borrows the step's reference by path. Two skills borrowed it that way, and each copy drifted.
11
+
12
+ A session judging from the diff whether an evidence image changed cannot see a regenerated image it did not author, so the image ships with no comment. A reviewer holding screenshots and a checklist has nothing to click into, and a slow deploy holds the ship chain while it waits for an address.
13
+
14
+ ## Must
15
+
16
+ - Run the evidence verb on every pull request it is given and let `no-evidence` be the skip, since asking a session to look lets an unseen image ship with no comment
17
+ - Run alone against an open pull request, resolving the number from the branch when none is passed, so a later head gets evidence without a body rewrite
18
+ - Edit the one marked comment in place on a later run, so a re-post never duplicates the thread or drops a carried checklist
19
+ - Put a preview address on a pull request changing a rendered surface when the project's deploy can mint one, since a reviewer needs a page to click into
20
+ - Bound the wait on that preview and finish without the link on a timeout, since a slow deploy must not hold the ship
21
+ - Link the branch's running local server when this worktree serves one, since a reviewer on the operator's machine can drive the branch
22
+ - Drop that link when the pull request closes, since a link outliving its branch points at whatever runs there next
23
+
24
+ ## Must not
25
+
26
+ - Dispatch a deploy whose command names no branch, since Cloudflare Pages publishes such a deploy to production
27
+ - Create a pull request, or post against a number it guessed, since a write to a wrong number lands on another branch's thread
28
+ - Call a GraphQL-backed `gh` subcommand, since the cloud review-address leg runs this skill through `git-followup`
29
+ - Print a result line of its own, since `git-pr` prints one and its report ends with the lines this skill returns
30
+ - Exist only for the author to type its name. `git-pr`, `git-followup`, and `git-ship` each invoke it, and a review of the catalog drops it when none does.
31
+
32
+ ## Guards
33
+
34
+ - Stop and ask for the number when none was passed and no open pull request resolves for the branch
35
+
36
+ ## Out of scope
37
+
38
+ - The title, body, labels, and pre-publish scan, which `git-pr` owns
39
+ - Writing the checklist, which `ui-checklist` owns. This skill only consumes the handoff file and removes it after posting.
40
+ - Driving the checklist in the running app, which `review-ui` owns
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: pr-evidence
3
+ description: Posts the rendered-surface evidence on an open pull request, being the screenshot comparison with the UI checklist, the checklist alone when git refuses the comparison, the local server link, and the preview address, editing the one marked comment in place on every later head. Use when asked to "post the evidence", "refresh the screenshots on the PR", or "re-post the evidence on the new head", and as the closing step of `git-pr`. Do NOT use to write a pull request's title or body, which is `git-pr`, or to write the checklist, which is `ui-checklist`.
4
+ metadata:
5
+ family: after-pr
6
+ ---
7
+
8
+ # PR evidence
9
+
10
+ The evidence a pull request carries is owed again on every new head, while its title and body are not. This skill posts it against one pull request number, so `git-pr` runs it as its last step and any session can run it alone after a push.
11
+
12
+ ## Resolve the pull request
13
+
14
+ Take the number the caller passed and look nothing up. `git-pr` passes the number its final command printed, and never invokes this skill when that command refused on a head mismatch and printed none.
15
+
16
+ Run bare, resolve the open pull request for the current branch:
17
+
18
+ ```bash
19
+ canon pr head --json
20
+ ```
21
+
22
+ Read `reason` on the record rather than the exit code, since a shell function wrapping `canon` can flatten it to zero.
23
+
24
+ - A record carrying `number`: hold it for every step below
25
+ - Any refusal, including `gh-failed` for a branch with no open pull request, stops the run with `❌ No open pull request resolved for this branch: <message>. Pass the number and re-run.`
26
+ - Never create a pull request here and never guess a number, since a write to a wrong number lands on another branch's thread
27
+
28
+ ## Post the evidence
29
+
30
+ Read `${CLAUDE_SKILL_DIR}/references/evidence.md` and run its sections in order against the number, being the checklist, the local server, the evidence comparison, the checklist alone, and the preview address.
31
+
32
+ - Every post and edit goes through `gh api` over REST, since a cloud session's proxy refuses the GraphQL that `gh pr` runs on
33
+ - Never judge from the diff whether an evidence image changed, since the verb answers `no-evidence` for a branch that changed none and a session cannot see an image it did not author
34
+ - A lone run on a later head edits the marked comment through the record's `commentId` and passes no `--checklist` for a handoff already deleted, since the verb carries the checklist forward
35
+
36
+ ## Report
37
+
38
+ Collect only the lines below whose condition holds, and nothing when none does. A lone run prints them. A run another skill invoked hands them back to that caller and prints nothing, since `git-pr` prints its own result line and then these lines, and printing here too shows them twice.
39
+
40
+ | Condition | Line |
41
+ | --------------------------------------------------------- | ------------------------------------------------------------------ |
42
+ | A checklist posted in the evidence comment | `📋 Posted the UI checklist to <number>, in the evidence comment.` |
43
+ | A checklist posted alone | `📋 Posted the UI checklist to <number>, on its own.` |
44
+ | The preview step returned an address | `🔗 Preview: <url>` |
45
+ | The evidence step posted the local link | `🖥️ Local preview: <url>` |
46
+ | The local step refused and evidence or a checklist posted | `🖥️ No local preview: <reason>` |
47
+ | A git refusal or a preview refusal the reference reports | `⚠️ <reason>: <message>` |
48
+
49
+ ### The no-local-preview line
50
+
51
+ It fires when the local step refused as `no-server` or `no-listener-reader`, since that pull request changes a rendered surface and a reviewer could have used the link. A later run only carries a link forward, so it cannot add one the comment never had.
52
+
53
+ To add the link later, start the server and run this skill again, adding `--checklist` to the evidence call when one is still owed.
@@ -0,0 +1,150 @@
1
+ ---
2
+ title: Rendered-surface evidence
3
+ description: How pr-evidence finds the UI checklist and the local server, posts the evidence comparison or the checklist alone as the fallback for a git refusal, and adds the preview address, for a change that touches a rendered surface
4
+ ---
5
+
6
+ # Rendered-surface evidence
7
+
8
+ The procedure of `pr-evidence`, run in order against one pull request number. It runs on every pull request with no test on the diff ahead of it, since `no-evidence` is the silent branch for one that changes no rendered surface.
9
+
10
+ ## Contents
11
+
12
+ - [Find the UI checklist](#find-the-ui-checklist)
13
+ - [Find the local server](#find-the-local-server)
14
+ - [Post the evidence comparison](#post-the-evidence-comparison)
15
+ - [Post the UI checklist alone](#post-the-ui-checklist-alone)
16
+ - [Post the preview address](#post-the-preview-address)
17
+
18
+ ## Find the UI checklist
19
+
20
+ `ui-checklist` writes a visual checklist to `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root when a change needs visual verification, with `<slug>` derived per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. This skill is the file's sole consumer.
21
+
22
+ - Resolve the main root the way `session-worktree` does, `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-` falling back to `pwd`
23
+ - A missing file means no checklist was produced, and the two steps below each skip their checklist half
24
+ - Scan an existing file against `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md` before either step posts it, the same as the body
25
+ - The evidence step decides where it lands, since a checklist reads next to its screenshots and posting it alone is the fallback for a refused render
26
+
27
+ ## Find the local server
28
+
29
+ A reviewer on the operator's machine can open the branch's running dev server, which screenshots and a checklist cannot stand in for. Ask the verb before the evidence step, so the first evidence comment already carries the link:
30
+
31
+ ```bash
32
+ canon pr local --json
33
+ ```
34
+
35
+ The verb reports the lowest port serving an HTML page whose process runs inside this worktree, never one in another worktree or the main checkout, which shows a different branch. `canon pr local --help` states the contract. Read `reason` on the record rather than the exit code.
36
+
37
+ - `ok`: hold the record's `url` for the evidence step below.
38
+ - `no-server` or `no-listener-reader`: hold the reason for the closing report and pass no link. Never start a server here, since one started inside the ship chain has no owner to stop it.
39
+ - Anything else, including no record or an older binary's unknown-subcommand error: move on silently, as a skip rather than a stop.
40
+
41
+ ### Where the link lands
42
+
43
+ Pass `--local` to the evidence step only on an `ok`. The binary answering `ok` is the one carrying the flag, so a binary lacking the verb never meets a flag it would reject.
44
+
45
+ - With a checklist, a diff carrying no evidence image still renders `ok`, and the link rides on the address line under `## Evidence`, above the checklist
46
+ - A link with neither an evidence image nor a checklist still reports `no-evidence`, so a branch changing no rendered surface gets no comment holding a link alone
47
+ - A seeded workflow drops the whole address line once the pull request closes, hosted and local together, so neither link outlives its branch
48
+
49
+ ## Post the evidence comparison
50
+
51
+ Run the verb once against the pull request number. Pass `--checklist` when the checklist step found a file and `--local` when the step above returned `ok`, and leave each flag off otherwise:
52
+
53
+ ```bash
54
+ canon pr evidence <number> --checklist <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --local <url> --json
55
+ ```
56
+
57
+ One call answers both questions because a checklist decides `no-evidence`. A diff carrying a checklist and no evidence image renders `ok` with the checklist in a marked body, so the checklist lands in the one comment a later call finds and edits.
58
+
59
+ - Pass `--checklist` only for a file that exists
60
+ - The verb refuses as `unreadable-checklist` on a path it cannot read or one holding nothing, a caller bug rather than a transient failure
61
+ - Stop and repair the path on that refusal rather than posting a body with the checklist silently dropped
62
+
63
+ ### Reading the record
64
+
65
+ Read `reason` on the record rather than the exit code.
66
+
67
+ - `no-evidence`: nothing changed under an `evidence/` segment and no checklist was passed. Say nothing about the evidence and move on.
68
+ - `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root, then post or update the comment:
69
+
70
+ ```bash
71
+ gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md --silent
72
+ ```
73
+
74
+ Both posts in this file use the REST issue-comments endpoint, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. `git-followup` runs this skill, so a GraphQL post here would break the cloud review-address leg.
75
+
76
+ When the record carries a `commentId`, edit that comment in place instead of posting a second. The body reads from the tmp file with `@`, which needs `-F`, since `-f` posts the path itself as the body:
77
+
78
+ ```bash
79
+ gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md
80
+ ```
81
+
82
+ Delete the handoff file and the tmp body once that call reports success, per the cleanup below, since the checklist now lives on the pull request.
83
+
84
+ ### Git refusals
85
+
86
+ Any other `reason` is a mirrored git refusal, being `gh-missing`, `gh-failed`, `no-base`, `unreadable-changes`, or `would-empty`. Report it and move on without stopping the chain, since a branch that rarely carries evidence images should not fail on a transient read.
87
+
88
+ Fall through to the checklist step, which posts the checklist alone rather than losing it.
89
+
90
+ ## Post the UI checklist alone
91
+
92
+ Run this step only as the fallback, when the evidence step reported a git refusal and a checklist file exists, since every other branch with a checklist rendered `ok` and carried it. The comment carries no marker, so a later `canon pr evidence` call reports no `checklist` for it.
93
+
94
+ ```bash
95
+ gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --silent
96
+ ```
97
+
98
+ ### Cleanup
99
+
100
+ Run the cleanup only once the call that carried the checklist reports success, whichever step that was. On a failure, stop and leave the file, since a retry needs it and deleting it loses the only copy.
101
+
102
+ The cleanup is a main-root delete, so it goes out as a plain `rm` and then a plain `rmdir`, routed the way `session-worktree` states:
103
+
104
+ ```bash
105
+ rm <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md
106
+ ```
107
+
108
+ ```bash
109
+ rmdir <main-root>/.canon/tmp/handoff/ui-checklist 2>/dev/null || true
110
+ ```
111
+
112
+ - The `rmdir` is a no-op while another branch's pending checklist sits in the folder, so this step never deletes a handoff not its own
113
+ - `git-followup` re-runs `canon pr evidence` with no `--checklist`, and the verb carries the checklist forward out of the comment it edits
114
+ - A tick survives a render at the head its stamp names and is cleared by one at a newer head, so the next UI pass earns it again
115
+
116
+ ## Post the preview address
117
+
118
+ Run this step when the evidence step returned `ok`, the fallback posted a checklist, or `canon pr evidence <number> --check --json` lists `preview` in `owed`. Otherwise skip it silently.
119
+
120
+ - The first two mean the pull request changes a rendered surface, and a reviewer holding a checklist with no screenshots needs the live page most
121
+ - The third is how `git-ship` reaches this step alone when an earlier run's deploy timed out
122
+ - An evidence record carrying a `commentId` takes the third alone, since a preview already on the comment counts as settled whatever head built it, so a later push does not re-mint one
123
+ - The evidence comment is already posted, so the reviewer has the screenshots while the deploy runs
124
+
125
+ ```bash
126
+ canon pr preview <number> --json
127
+ ```
128
+
129
+ ### What the verb refuses
130
+
131
+ The verb dispatches the project's Pages deploy on the pull request's branch and waits on the run for up to 15 minutes. `canon pr preview --help` states the contract. It refuses before dispatching anything in two cases.
132
+
133
+ - The deploy command passes no `--branch`, since that deploy would publish the branch to production
134
+ - The workflow's push path filter matches no changed path, since a dispatch ignores that filter and the site would show none of the change
135
+
136
+ ### Reading the preview record
137
+
138
+ Read `reason` on the record rather than the exit code.
139
+
140
+ - `ok`: re-render the evidence body with the address under `## Evidence`, then post or update it as the evidence step does, through the same tmp file and the record's `commentId`:
141
+
142
+ ```bash
143
+ canon pr evidence <number> --preview <url> --json
144
+ ```
145
+
146
+ The hosted address opens the address line, and a local link already on the comment follows it, carried forward with no flag.
147
+
148
+ - `no-deploy` or `unserved`: the project deploys nothing a dispatch can start, or its site builds from nothing this branch changed. Say nothing and move on.
149
+ - `unfenced`, `no-alias`, `run-failed`, `timeout`, or a mirrored `gh` refusal: report the record's `message` and move on without stopping the chain
150
+ - A missing link costs the reviewer a click, and a held ship costs the whole chain
@@ -5,11 +5,18 @@ description: How review-address posts something worth reporting after Step 7 clo
5
5
 
6
6
  # Post a finding after the review closed
7
7
 
8
- Outside the numbered flow of `review-address`. The session reads this file when it has something worth reaching the reviewing session after Step 7 already closed the review.
8
+ Outside the numbered flow of `review-address`. The session reads this file when it has something worth reaching the reviewing session after Step 7 already closed the review, such as a settled risk, a filed follow-up, or another finding. It posts directly rather than waiting on a review pass that has nothing left to trigger it.
9
9
 
10
- Not everything worth reaching the reviewing session surfaces inside the numbered flow in `SKILL.md`. A worker that settled a risk, filed a follow-up, or found something else worth reporting after Step 7 already closed the review posts it directly rather than waiting on a review pass that has nothing left to trigger it. Write the body the way Step 6 writes a reply: load `write-human` for voice and word choice, follow `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` for punctuation, and run the `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md` scan before posting with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`.
10
+ ## The body
11
11
 
12
- Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered. `review-pr` states the full heading set this belongs to and routes it the same as a response: `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass. Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer.
12
+ Write the body the way Step 6 writes a reply.
13
+
14
+ - Load `write-human` for voice and word choice, and follow `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` for punctuation
15
+ - Run the `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md` scan before posting, with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`
16
+ - Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered
17
+ - Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer
18
+
19
+ `review-pr` states the full heading set this belongs to and routes it the same as a response, so `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass.
13
20
 
14
21
  ```bash
15
22
  gh api -X POST 'repos/{owner}/{repo}/issues/<number>/comments' -F body=@.canon/tmp/pr/reply/reply-<number>.md --silent
@@ -21,20 +21,35 @@ Pop only when the stash ran. On a clean tree, which is what a run whose findings
21
21
 
22
22
  Never merge `main` into the branch. The repository squash-merges, so a merge commit here reads as noise on the pull request.
23
23
 
24
+ ### A branch carrying merges
25
+
26
+ A branch carrying merge commits of its own, such as a fan-in integrator's, rebases with `git rebase --rebase-merges origin/main` instead. A plain rebase drops the merges and replays every member commit in one line, which loses the one merge commit per member a reviewer reads.
27
+
28
+ - `--rebase-merges` re-runs each merge without the resolution it recorded, so resolve each again by the rules below
29
+ - `git config rerere.enabled true`, set before the first merge, replays a recorded resolution in place of resolving it again
30
+
24
31
  ## Resolving a conflict
25
32
 
26
33
  These rules apply to a hunk from the rebase and a hunk from the stash pop alike:
27
34
 
28
35
  - Never take one side wholesale with `--ours` or `--theirs`. Both sides are valid content, so the drop is silent and passes every check.
29
- - Never resolve a generated file by hand. A file the project check rebuilds, such as an `index.md` carrying no `auto: false`, takes either side to clear the conflict and gets its real content from the regen below.
30
- - Where two branches wrote prose into one file, keep both sides and rewrite what the merge broke. A section that opens by counting what follows needs the count updated rather than the two versions concatenated.
31
- - When a hunk needs a decision the tree does not carry, stop rather than guessing, and name where the branch was left. The two sources recover differently. A guess that compiles is the failure this stage would otherwise introduce, and either case reaches the operator as an ordinary finding on the next review pass.
32
- - A hunk raised by the rebase takes `git rebase --abort`, which restores the old base: `❌ Conflict needs a decision at <file>. Branch left on its old base.`
33
- - A hunk raised by the stash pop arrives after the rebase already landed, so no abort applies and the conflict stays in the tree: `❌ Conflict needs a decision at <file>. Branch rebased, fixes left conflicted in the tree.`
36
+ - Never resolve a generated file by hand, such as an `index.md` carrying no `auto: false`. Take either side and let the regen below rebuild it.
37
+ - Where two branches wrote prose into one file, keep both sides and rewrite what the merge broke, such as a count opening a section
38
+ - Both sides of every hunk sit in the conflict and `git log origin/main` names what landed, so never wait on the orchestrator for context
39
+
40
+ ### A hunk needing a decision
41
+
42
+ When a hunk needs a decision the tree does not carry, stop rather than guessing and name where the branch was left, since a guess that compiles is the failure this stage would introduce. Either case reaches the operator as an ordinary finding on the next review pass. The two sources recover differently.
43
+
44
+ - A hunk raised by the rebase takes `git rebase --abort`, which restores the old base: `❌ Conflict needs a decision at <file>. Branch left on its old base.`
45
+ - A hunk raised by the stash pop arrives after the rebase landed, so the conflict stays in the tree: `❌ Conflict needs a decision at <file>. Branch rebased, fixes left conflicted in the tree.`
46
+
47
+ ### The stop message
34
48
 
35
- Both sides of every hunk sit in the conflict and `git log origin/main` names what landed, so the tree carries the context. Do not wait on the orchestrator for it.
49
+ The stop still owes a message, since the next review pass never starts on a branch nobody pushed. When the launch named a controlling session, send it the stop line through `canon:session-relay` before halting, per the worker channel the `role-worker` skill states.
36
50
 
37
- The stop still owes a message. When the launch named a controlling session, send it the stop line through `canon:session-relay` before halting, adding the commit on `main` that wrote the other side of the hunk, per the worker channel the `role-worker` skill states. Nothing else surfaces the halt, since the next review pass that would read it as a finding never starts on a branch nobody pushed. With nobody named, print the two lines above and stop.
51
+ - Add the commit on `main` that wrote the other side of the hunk
52
+ - With nobody named, print the two lines above and stop
38
53
 
39
54
  ## After the rebase
40
55
 
@@ -5,7 +5,9 @@ description: The reads review-address runs over REST, being the findings on the
5
5
 
6
6
  # REST reads
7
7
 
8
- The guard and Step 1 of `review-address`. The session reads this file on reaching Step 1, and from the guard when `canon pr head --json` hands back no `number`. Every read runs on REST, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. A cloud worker answering a review runs this skill, so one GraphQL call breaks the whole leg.
8
+ The guard and Step 1 of `review-address`. The session reads this file on reaching Step 1, and from the guard when `canon pr head --json` hands back no `number`.
9
+
10
+ Every read runs on REST, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. A cloud worker answering a review runs this skill, so one GraphQL call breaks the whole leg.
9
11
 
10
12
  ## The findings
11
13