@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
@@ -42,41 +42,113 @@ export const GATED_PATHS: readonly string[] = [
42
42
  'canon/context/context-model.md',
43
43
  'canon/context/index.md',
44
44
  'claude/skills/api-design/SKILL.md',
45
+ 'claude/skills/api-design/references/adopted.md',
45
46
  'claude/skills/auto-ship/SKILL.md',
47
+ 'claude/skills/auto-ship/references/draft-mark.md',
48
+ 'claude/skills/auto-ship/references/failure-recovery.md',
49
+ 'claude/skills/auto-ship/references/fan-in.md',
50
+ 'claude/skills/auto-ship/references/tier-failures.md',
51
+ 'claude/skills/auto-ship/references/ui-checklist.md',
52
+ 'claude/skills/auto-ship/references/verb-absent.md',
53
+ 'claude/skills/auto-ship/references/worktree-name.md',
46
54
  'claude/skills/backlog-triage/SKILL.md',
47
55
  'claude/skills/backlog-triage/references/apply.md',
48
56
  'claude/skills/build-in-slices/SKILL.md',
57
+ 'claude/skills/build-in-slices/references/adopted.md',
49
58
  'claude/skills/canon-cli/SKILL.md',
50
59
  'claude/skills/canon-feedback-triage/SKILL.md',
51
60
  'claude/skills/canon-feedback/SKILL.md',
61
+ 'claude/skills/canon-feedback/references/template.md',
52
62
  'claude/skills/canvas-board/SKILL.md',
63
+ 'claude/skills/canvas-board/references/canvas.md',
64
+ 'claude/skills/canvas-board/references/design.md',
53
65
  'claude/skills/ci-workflow/SKILL.md',
66
+ 'claude/skills/ci-workflow/references/workflows.md',
54
67
  'claude/skills/code-craft/SKILL.md',
68
+ 'claude/skills/code-craft/references/adopted.md',
55
69
  'claude/skills/codebase-layout/SKILL.md',
70
+ 'claude/skills/codebase-layout/references/adopted.md',
71
+ 'claude/skills/codebase-layout/references/frontend.md',
72
+ 'claude/skills/codebase-layout/references/tests.md',
56
73
  'claude/skills/context-fold/SKILL.md',
74
+ 'claude/skills/context-fold/references/classify.md',
75
+ 'claude/skills/context-fold/references/completion-report.md',
76
+ 'claude/skills/context-fold/references/context-refresh.md',
77
+ 'claude/skills/context-fold/references/context.md',
78
+ 'claude/skills/context-fold/references/unusable-baseline.md',
57
79
  'claude/skills/create-rule/SKILL.md',
80
+ 'claude/skills/create-rule/references/rule.md',
58
81
  'claude/skills/create-skill/SKILL.md',
82
+ 'claude/skills/create-skill/references/skill-disclosure.md',
83
+ 'claude/skills/create-skill/references/skill-frontmatter.md',
84
+ 'claude/skills/create-skill/references/skill-paths.md',
85
+ 'claude/skills/create-skill/references/skill-practice.md',
86
+ 'claude/skills/create-skill/references/skill-reference.md',
87
+ 'claude/skills/create-skill/references/skill-requirement.md',
88
+ 'claude/skills/create-skill/references/skill.md',
59
89
  'claude/skills/decision-escalate/SKILL.md',
60
90
  'claude/skills/deploy-app/SKILL.md',
91
+ 'claude/skills/deploy-app/references/cloudflare.md',
92
+ 'claude/skills/deploy-app/references/vercel.md',
61
93
  'claude/skills/deprecation-migration/SKILL.md',
94
+ 'claude/skills/deprecation-migration/references/adopted.md',
62
95
  'claude/skills/design-taste/SKILL.md',
96
+ 'claude/skills/design-taste/references/adopted.md',
97
+ 'claude/skills/design-taste/references/craft.md',
98
+ 'claude/skills/design-taste/references/kinds.md',
99
+ 'claude/skills/design-taste/references/preflight.md',
100
+ 'claude/skills/design-taste/references/systems.md',
101
+ 'claude/skills/design-taste/references/tells.md',
102
+ 'claude/skills/design-taste/references/vocabulary.md',
63
103
  'claude/skills/docs-sync/SKILL.md',
104
+ 'claude/skills/docs-sync/references/docs.md',
105
+ 'claude/skills/docs-sync/references/readme.md',
64
106
  'claude/skills/document-health/SKILL.md',
107
+ 'claude/skills/document-health/references/axes.md',
65
108
  'claude/skills/draft-and-pick/SKILL.md',
109
+ 'claude/skills/draft-and-pick/references/live-arms.md',
66
110
  'claude/skills/draft-doc/SKILL.md',
111
+ 'claude/skills/draft-doc/references/context.md',
112
+ 'claude/skills/draft-doc/references/docs.md',
113
+ 'claude/skills/draft-doc/references/readme.md',
114
+ 'claude/skills/draft-doc/references/readme/agent-facing.md',
115
+ 'claude/skills/draft-doc/references/readme/application.md',
116
+ 'claude/skills/draft-doc/references/readme/cli.md',
117
+ 'claude/skills/draft-doc/references/readme/library.md',
118
+ 'claude/skills/draft-doc/references/readme/plugin.md',
119
+ 'claude/skills/draft-doc/references/requirements.md',
120
+ 'claude/skills/draft-doc/references/wiki-kind.md',
121
+ 'claude/skills/draft-doc/references/wiki.md',
67
122
  'claude/skills/draft-figure/SKILL.md',
123
+ 'claude/skills/draft-figure/references/architecture-set.md',
124
+ 'claude/skills/draft-figure/references/figures.md',
125
+ 'claude/skills/draft-figure/references/hand-drawn.md',
126
+ 'claude/skills/draft-figure/references/mermaid-path.md',
127
+ 'claude/skills/draft-figure/references/mermaid.md',
68
128
  'claude/skills/draft-identity/SKILL.md',
69
129
  'claude/skills/draft-identity/references/card-route.md',
70
130
  'claude/skills/draft-ready/SKILL.md',
131
+ 'claude/skills/draft-ready/references/assembly.md',
132
+ 'claude/skills/draft-ready/references/ready.md',
71
133
  'claude/skills/draft-screencast/SKILL.md',
72
134
  'claude/skills/draft-screencast/references/beats-template.md',
73
135
  'claude/skills/draft-slides/SKILL.md',
74
136
  'claude/skills/draft-slides/references/deck.md',
75
137
  'claude/skills/git-branch/SKILL.md',
138
+ 'claude/skills/git-branch/references/branch.md',
139
+ 'claude/skills/git-branch/references/slug.md',
76
140
  'claude/skills/git-commit/SKILL.md',
141
+ 'claude/skills/git-commit/references/commit.md',
142
+ 'claude/skills/git-commit/references/versioning.md',
77
143
  'claude/skills/git-followup/SKILL.md',
78
144
  'claude/skills/git-issue/SKILL.md',
145
+ 'claude/skills/git-issue/references/issue.md',
79
146
  'claude/skills/git-pr/SKILL.md',
147
+ 'claude/skills/git-pr/references/final-command.md',
148
+ 'claude/skills/git-pr/references/labels.md',
149
+ 'claude/skills/git-pr/references/pr.md',
150
+ 'claude/skills/git-pr/references/publish.md',
151
+ 'claude/skills/git-pr/references/task-number.md',
80
152
  'claude/skills/git-ship/SKILL.md',
81
153
  'claude/skills/git-ship/references/ci-watch.md',
82
154
  'claude/skills/git-split/SKILL.md',
@@ -86,45 +158,117 @@ export const GATED_PATHS: readonly string[] = [
86
158
  'claude/skills/git-worktree/SKILL.md',
87
159
  'claude/skills/git-worktree/references/cleanup.md',
88
160
  'claude/skills/markdown-craft/SKILL.md',
161
+ 'claude/skills/markdown-craft/references/markdown.md',
89
162
  'claude/skills/plan-feature/SKILL.md',
90
163
  'claude/skills/plan-feature/references/batches.md',
164
+ 'claude/skills/plan-feature/references/plan-lifecycle.md',
165
+ 'claude/skills/plan-feature/references/plan.md',
91
166
  'claude/skills/plan-groundwork/SKILL.md',
167
+ 'claude/skills/plan-groundwork/references/groundwork-spikes.md',
168
+ 'claude/skills/plan-groundwork/references/groundwork.md',
92
169
  'claude/skills/plan-groundwork/references/output.md',
93
170
  'claude/skills/plan-intake-answer/SKILL.md',
94
171
  'claude/skills/plan-intake/SKILL.md',
172
+ 'claude/skills/plan-intake/references/intake.md',
173
+ 'claude/skills/pr-evidence/SKILL.md',
174
+ 'claude/skills/pr-evidence/references/evidence.md',
95
175
  'claude/skills/read-frames/SKILL.md',
96
176
  'claude/skills/record-screencast/SKILL.md',
97
177
  'claude/skills/review-address/SKILL.md',
178
+ 'claude/skills/review-address/references/post-review-findings.md',
179
+ 'claude/skills/review-address/references/rebase-conflicts.md',
98
180
  'claude/skills/review-address/references/rebase-only.md',
181
+ 'claude/skills/review-address/references/rest-reads.md',
99
182
  'claude/skills/review-craft/SKILL.md',
183
+ 'claude/skills/review-craft/references/adopted.md',
184
+ 'claude/skills/review-craft/references/security.md',
185
+ 'claude/skills/review-craft/references/ui.md',
100
186
  'claude/skills/review-pr/SKILL.md',
187
+ 'claude/skills/review-pr/references/body-variants.md',
188
+ 'claude/skills/review-pr/references/close-out.md',
189
+ 'claude/skills/review-pr/references/key-changes.md',
190
+ 'claude/skills/review-pr/references/post.md',
191
+ 'claude/skills/review-pr/references/scope.md',
101
192
  'claude/skills/review-ui/SKILL.md',
193
+ 'claude/skills/review-ui/references/close-out.md',
194
+ 'claude/skills/review-ui/references/driving.md',
102
195
  'claude/skills/review-ui/references/hosted-preview.md',
196
+ 'claude/skills/review-ui/references/post.md',
197
+ 'claude/skills/review-ui/references/tick.md',
103
198
  'claude/skills/role-orchestrator/SKILL.md',
199
+ 'claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md',
200
+ 'claude/skills/role-orchestrator/references/orchestrator-dispatch.md',
104
201
  'claude/skills/role-orchestrator/references/orchestrator-filing.md',
202
+ 'claude/skills/role-orchestrator/references/orchestrator-handback.md',
203
+ 'claude/skills/role-orchestrator/references/orchestrator-handoff.md',
204
+ 'claude/skills/role-orchestrator/references/orchestrator-inbound.md',
205
+ 'claude/skills/role-orchestrator/references/orchestrator-launch.md',
206
+ 'claude/skills/role-orchestrator/references/orchestrator-output.md',
207
+ 'claude/skills/role-orchestrator/references/orchestrator-parked.md',
208
+ 'claude/skills/role-orchestrator/references/orchestrator-poll.md',
209
+ 'claude/skills/role-orchestrator/references/orchestrator-refill.md',
210
+ 'claude/skills/role-orchestrator/references/orchestrator-resume.md',
211
+ 'claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md',
212
+ 'claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md',
213
+ 'claude/skills/role-orchestrator/references/orchestrator-sweep.md',
214
+ 'claude/skills/role-orchestrator/references/orchestrator-watch.md',
105
215
  'claude/skills/role-planner/SKILL.md',
106
216
  'claude/skills/role-reviewer/SKILL.md',
107
217
  'claude/skills/role-worker/SKILL.md',
108
218
  'claude/skills/search-craft/SKILL.md',
219
+ 'claude/skills/search-craft/references/adopted.md',
109
220
  'claude/skills/session-compact/SKILL.md',
221
+ 'claude/skills/session-compact/references/handoff-note.md',
110
222
  'claude/skills/session-map/SKILL.md',
223
+ 'claude/skills/session-map/references/session.md',
111
224
  'claude/skills/session-relay/SKILL.md',
112
225
  'claude/skills/session-resume/SKILL.md',
113
226
  'claude/skills/session-worktree/SKILL.md',
227
+ 'claude/skills/session-worktree/references/install-command.md',
228
+ 'claude/skills/session-worktree/references/main-root-writes.md',
114
229
  'claude/skills/systematic-debugging/SKILL.md',
230
+ 'claude/skills/systematic-debugging/references/adopted.md',
115
231
  'claude/skills/target-check/SKILL.md',
232
+ 'claude/skills/target-check/references/domains.md',
116
233
  'claude/skills/target-setup/SKILL.md',
234
+ 'claude/skills/target-setup/references/detect.md',
235
+ 'claude/skills/target-setup/references/indexes.md',
236
+ 'claude/skills/target-setup/references/verify.md',
117
237
  'claude/skills/task-board/SKILL.md',
238
+ 'claude/skills/task-board/references/board.md',
118
239
  'claude/skills/task-board/references/create-report.md',
240
+ 'claude/skills/task-board/references/decline.md',
241
+ 'claude/skills/task-board/references/tasks-decline.md',
242
+ 'claude/skills/task-board/references/tasks.md',
119
243
  'claude/skills/task-complete/SKILL.md',
244
+ 'claude/skills/task-complete/references/archive.md',
245
+ 'claude/skills/task-complete/references/receipt-sweep.md',
246
+ 'claude/skills/task-complete/references/unusable-baseline.md',
120
247
  'claude/skills/teach-workspace/SKILL.md',
248
+ 'claude/skills/teach-workspace/references/glossary.md',
249
+ 'claude/skills/teach-workspace/references/lesson-build.md',
250
+ 'claude/skills/teach-workspace/references/lesson-craft.md',
251
+ 'claude/skills/teach-workspace/references/pedagogy.md',
252
+ 'claude/skills/teach-workspace/references/promotion-fold.md',
253
+ 'claude/skills/teach-workspace/references/promotion.md',
254
+ 'claude/skills/teach-workspace/references/revisit.md',
255
+ 'claude/skills/teach-workspace/references/teach.md',
121
256
  'claude/skills/test-craft/SKILL.md',
257
+ 'claude/skills/test-craft/references/adopted.md',
258
+ 'claude/skills/test-craft/references/component.md',
259
+ 'claude/skills/test-craft/references/e2e.md',
260
+ 'claude/skills/test-craft/references/unit.md',
122
261
  'claude/skills/test-first/SKILL.md',
262
+ 'claude/skills/test-first/references/adopted.md',
123
263
  'claude/skills/ui-checklist/SKILL.md',
124
264
  'claude/skills/ux-audit/SKILL.md',
125
265
  'claude/skills/ux-measure/SKILL.md',
126
266
  'claude/skills/video-craft/SKILL.md',
267
+ 'claude/skills/video-craft/references/adopted.md',
127
268
  'claude/skills/write-human/SKILL.md',
269
+ 'claude/skills/write-human/references/adopted.md',
270
+ 'claude/skills/write-human/references/density.md',
271
+ 'claude/skills/write-human/references/machine-tells.md',
128
272
  'claude/skills/youtube-transcripts/SKILL.md',
129
273
  '.claude/skills/internal-',
130
274
  'docs/',
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Adds the session defaults the seeded `.claude/settings.json` carries to a
3
+ * target that was seeded before them.
4
+ *
5
+ * `canon claude init` copies a seed only when the file is absent, so a target
6
+ * holding its own settings never sees a later seed change. This verb adds each
7
+ * default only where the key is absent: a deny entry is never removed, and a
8
+ * person's `autoMemoryEnabled: true` is never overwritten.
9
+ */
10
+
11
+ import { existsSync } from 'node:fs'
12
+ import { join } from 'node:path'
13
+ import {
14
+ readSettings,
15
+ type SettingsKey,
16
+ type SettingsRecord,
17
+ serializeSettings,
18
+ writeSettings,
19
+ } from '@/claude/settings'
20
+
21
+ /** Both names, since `Task` is the tool's name before Claude Code renamed it. */
22
+ export const DENIED_TOOLS: readonly string[] = ['Agent', 'Task']
23
+
24
+ export interface SessionDefaultsPlan {
25
+ readonly keys: readonly SettingsKey[]
26
+ readonly next: SettingsRecord
27
+ readonly changed: boolean
28
+ /**
29
+ * True when the file holds no default at all. A file holding either one has
30
+ * been through the seed or this verb, so a missing deny there was removed
31
+ * on purpose, which is how an operator opts back into subagents.
32
+ */
33
+ readonly predates: boolean
34
+ }
35
+
36
+ export type SessionDefaultsRead =
37
+ | { readonly kind: 'refused'; readonly reason: string }
38
+ | { readonly kind: 'absent'; readonly path: string }
39
+ | {
40
+ readonly kind: 'planned'
41
+ readonly path: string
42
+ readonly indent: string
43
+ readonly plan: SessionDefaultsPlan
44
+ }
45
+
46
+ export function settingsPath(root: string): string {
47
+ return join(root, '.claude', 'settings.json')
48
+ }
49
+
50
+ function isRecord(value: unknown): value is SettingsRecord {
51
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
52
+ }
53
+
54
+ /**
55
+ * Appends the denied tools a list lacks, keeping the list's own order, so the
56
+ * diff a person reads is the added entries alone.
57
+ */
58
+ export function planSessionDefaults(
59
+ current: SettingsRecord,
60
+ ): SessionDefaultsPlan {
61
+ const next: SettingsRecord = { ...current }
62
+ const permissions = isRecord(current.permissions) ? current.permissions : {}
63
+ const deny = Array.isArray(permissions.deny) ? permissions.deny : []
64
+
65
+ const missing = DENIED_TOOLS.filter((tool) => !deny.includes(tool))
66
+ if (missing.length > 0) {
67
+ next.permissions = { ...permissions, deny: [...deny, ...missing] }
68
+ }
69
+
70
+ const memoryAbsent = !('autoMemoryEnabled' in current)
71
+ if (memoryAbsent) next.autoMemoryEnabled = false
72
+
73
+ const keys: SettingsKey[] = [
74
+ { label: 'permissions.deny', changed: missing.length > 0 },
75
+ { label: 'autoMemoryEnabled', changed: memoryAbsent },
76
+ ]
77
+ return {
78
+ keys,
79
+ next,
80
+ changed: keys.some((key) => key.changed),
81
+ predates: memoryAbsent && missing.length === DENIED_TOOLS.length,
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Refuses rather than plans whenever a write could replace something the
87
+ * person owns: the toolkit's own settings, a file `JSON.parse` cannot read,
88
+ * or a `permissions` or `deny` value of an unexpected shape.
89
+ */
90
+ export async function readSessionDefaults(
91
+ root: string,
92
+ protectedRoot: string,
93
+ ): Promise<SessionDefaultsRead> {
94
+ if (root === protectedRoot) {
95
+ return {
96
+ kind: 'refused',
97
+ reason:
98
+ 'Cannot run against toolkit root. Files here are the source of truth.',
99
+ }
100
+ }
101
+
102
+ const path = settingsPath(root)
103
+ if (!existsSync(path)) return { kind: 'absent', path }
104
+
105
+ let read: Awaited<ReturnType<typeof readSettings>>
106
+ try {
107
+ read = await readSettings(path)
108
+ } catch (error) {
109
+ return {
110
+ kind: 'refused',
111
+ reason: error instanceof Error ? error.message : String(error),
112
+ }
113
+ }
114
+
115
+ const { permissions } = read.value
116
+ if (permissions !== undefined && !isRecord(permissions)) {
117
+ return { kind: 'refused', reason: `${path}: permissions is not an object` }
118
+ }
119
+ if (permissions?.deny !== undefined && !Array.isArray(permissions.deny)) {
120
+ return {
121
+ kind: 'refused',
122
+ reason: `${path}: permissions.deny is not a list`,
123
+ }
124
+ }
125
+
126
+ return {
127
+ kind: 'planned',
128
+ path,
129
+ indent: read.indent,
130
+ plan: planSessionDefaults(read.value),
131
+ }
132
+ }
133
+
134
+ export async function applySessionDefaults(
135
+ read: Extract<SessionDefaultsRead, { kind: 'planned' }>,
136
+ ): Promise<void> {
137
+ await writeSettings(read.path, serializeSettings(read.plan.next, read.indent))
138
+ }
package/src/pr/lift.ts CHANGED
@@ -144,7 +144,10 @@ function fail(gate: GateName, reason: LiftRefusal): GateResult {
144
144
  * since the commit it covers is a stamp GitHub wrote at submission, which the
145
145
  * marker exists to replace.
146
146
  */
147
- function reviewGate(reviews: readonly ReviewRow[], head: string): GateResult {
147
+ export function reviewGate(
148
+ reviews: readonly ReviewRow[],
149
+ head: string,
150
+ ): GateResult {
148
151
  const scope = resolveReviewScope({ reviews })
149
152
  if (scope.state === 'none') return fail('review', 'review-missing')
150
153
  if (scope.state === 'open') return fail('review', 'review-open')
@@ -175,8 +178,8 @@ function carried(gates: readonly GateResult[]): {
175
178
  * checklist the reviewer drove as true as it was. A close that is not an
176
179
  * ancestor, which a force-push or a rebase leaves, never carries.
177
180
  */
178
- async function uiGate(
179
- api: LiftApi,
181
+ export async function uiGate(
182
+ api: Pick<LiftApi, 'readChanged'>,
180
183
  painted: PaintedPatterns,
181
184
  reviews: readonly ReviewRow[],
182
185
  head: string,
package/src/pr/local.ts CHANGED
@@ -1,26 +1,11 @@
1
+ import { belongsTo } from '@/listeners/belongs'
2
+ import type { ListenerReader } from '@/listeners/machine'
1
3
  import { readAddresses } from '@/pr/evidence'
2
4
 
3
- /**
4
- * The folder linked worktrees sit under. A listener there belongs to another
5
- * branch even though its cwd sits inside the main checkout's toplevel.
6
- */
7
- const LINKED_WORKTREES = '.claude/worktrees'
8
-
9
- /** The state `/proc/net/tcp` writes for a socket in LISTEN. */
10
- const PROC_LISTEN_STATE = '0A'
11
-
12
5
  export type LocalRefusal = 'no-server' | 'no-listener-reader'
13
6
 
14
- export interface Listener {
15
- readonly port: number
16
- readonly pid: number
17
- }
18
-
19
- /** The machine reads a detection makes, injected so it can be driven without binding a socket. */
20
- export interface LocalRunner {
21
- /** Every TCP socket in LISTEN with its owning pid, or undefined when this machine offers no way to read them. */
22
- listListeners(): Promise<readonly Listener[] | undefined>
23
- cwdOf(pid: number): Promise<string | undefined>
7
+ /** The listener reads a detection makes plus an HTML probe, injected so it can be driven without binding a socket. */
8
+ export interface LocalRunner extends ListenerReader {
24
9
  /** Whether the port serves an HTML page at its root inside the runner's timeout. */
25
10
  probe(port: number): Promise<boolean>
26
11
  }
@@ -29,22 +14,6 @@ export type LocalResult =
29
14
  | { readonly kind: 'found'; readonly port: number; readonly url: string }
30
15
  | { readonly kind: 'refused'; readonly reason: LocalRefusal }
31
16
 
32
- function isInside(path: string, root: string): boolean {
33
- return path === root || path.startsWith(`${root}/`)
34
- }
35
-
36
- /**
37
- * Whether a process running in `cwd` serves this worktree. A tool that
38
- * changes into a subfolder before listening still counts, while a sibling
39
- * worktree nested under the main checkout's `.claude/worktrees/` does not.
40
- */
41
- function belongsTo(cwd: string, worktreeRoot: string): boolean {
42
- return (
43
- isInside(cwd, worktreeRoot) &&
44
- !isInside(cwd, `${worktreeRoot}/${LINKED_WORKTREES}`)
45
- )
46
- }
47
-
48
17
  /**
49
18
  * Finds the server this worktree is running: the lowest port whose listening
50
19
  * process runs inside the worktree and answers an HTTP probe. A port rather
@@ -76,40 +45,6 @@ export async function findLocalServer(
76
45
  return { kind: 'refused', reason: 'no-server' }
77
46
  }
78
47
 
79
- /** Reads `lsof -nP -iTCP -sTCP:LISTEN -Fpn` output, where a `p` line opens a process and each `n` line names one of its sockets. */
80
- export function parseLsofListeners(text: string): Listener[] {
81
- const listeners: Listener[] = []
82
- let pid: number | undefined
83
- for (const line of text.split('\n')) {
84
- if (line.startsWith('p')) pid = Number(line.slice(1))
85
- if (!line.startsWith('n') || pid === undefined) continue
86
- const port = Number(line.slice(line.lastIndexOf(':') + 1))
87
- if (Number.isInteger(port) && port > 0) listeners.push({ pid, port })
88
- }
89
- return listeners
90
- }
91
-
92
- export interface ProcSocket {
93
- readonly port: number
94
- readonly inode: string
95
- }
96
-
97
- /** Reads `/proc/net/tcp` or `tcp6`, keeping each listening socket's port and inode for matching against `/proc/<pid>/fd`. */
98
- export function parseProcNetTcp(text: string): ProcSocket[] {
99
- const sockets: ProcSocket[] = []
100
- for (const line of text.split('\n').slice(1)) {
101
- const fields = line.trim().split(/\s+/)
102
- const local = fields[1]
103
- const state = fields[3]
104
- const inode = fields[9]
105
- if (local === undefined || inode === undefined) continue
106
- if (state !== PROC_LISTEN_STATE) continue
107
- const port = Number.parseInt(local.slice(local.lastIndexOf(':') + 1), 16)
108
- if (Number.isInteger(port) && port > 0) sockets.push({ port, inode })
109
- }
110
- return sockets
111
- }
112
-
113
48
  /**
114
49
  * Drops the address line of a marked body, hosted and local segments alike,
115
50
  * since the close that runs this also deletes the branch's preview
@@ -0,0 +1,182 @@
1
+ import {
2
+ CHECKS_POLL_MS,
3
+ type GateResult,
4
+ type LiftApi,
5
+ type LiftRefusal,
6
+ reviewGate,
7
+ uiGate,
8
+ } from '@/pr/lift'
9
+ import { DEFAULT_PAINTED, type PaintedPatterns } from '@/pr/painted'
10
+ import {
11
+ coversHead,
12
+ type ReviewRow,
13
+ type ReviewScope,
14
+ resolveReviewScope,
15
+ resolveUiScope,
16
+ type UiScope,
17
+ } from '@/pr/review-scope'
18
+
19
+ /**
20
+ * The reads the verb makes, a subset of the lift's so a worker waiting here and
21
+ * a reviewer lifting read one answer. A read that failed returns undefined, and
22
+ * the verb refuses `gh-failed` rather than reading absence as no pass.
23
+ */
24
+ export type ReviewStateApi = Pick<
25
+ LiftApi,
26
+ 'readReviews' | 'readEvidence' | 'readChanged' | 'sleep' | 'now'
27
+ > & {
28
+ /** The branch tip from the remote, which is what a pass has to cover. */
29
+ readTip(): Promise<string | undefined>
30
+ }
31
+
32
+ /** One family's standing at the tip. */
33
+ export interface FamilyState {
34
+ /** The lift's refusal for this family, absent when its gate passes. */
35
+ readonly reason?: LiftRefusal
36
+ /**
37
+ * Whether a pass covers the tip, which is what a waiting worker reads. True
38
+ * when the gate passes, or when the newest pass, open or unmarked, names the
39
+ * tip. The reason alone cannot answer it, since the lift reads an open pass
40
+ * before it reads currency.
41
+ */
42
+ readonly isCovered: boolean
43
+ }
44
+
45
+ export interface UiState extends UiScope, FamilyState {
46
+ /** Whether the evidence comment carries a checklist, which binds the family. */
47
+ readonly isBound: boolean
48
+ readonly carriedFrom?: string
49
+ readonly paintedPaths?: readonly string[]
50
+ }
51
+
52
+ export interface ReviewStateRecord {
53
+ readonly head: string
54
+ readonly scope: ReviewScope
55
+ readonly review: FamilyState
56
+ readonly ui: UiState
57
+ }
58
+
59
+ export type ReviewStateRead =
60
+ | { readonly kind: 'read'; readonly record: ReviewStateRecord }
61
+ | { readonly kind: 'refused'; readonly reason: 'gh-failed' }
62
+
63
+ export type ReviewWait =
64
+ | {
65
+ readonly kind: 'read'
66
+ readonly reason: 'covered' | 'timeout'
67
+ readonly record: ReviewStateRecord
68
+ readonly waitedSeconds: number
69
+ }
70
+ | {
71
+ readonly kind: 'refused'
72
+ readonly reason: 'gh-failed'
73
+ readonly waitedSeconds: number
74
+ }
75
+
76
+ export interface WaitOptions {
77
+ readonly waitSeconds: number
78
+ readonly pollMs?: number
79
+ readonly painted?: PaintedPatterns
80
+ }
81
+
82
+ function familyOf(gate: GateResult, commit: string | undefined, tip: string) {
83
+ return {
84
+ ...(gate.reason !== undefined && { reason: gate.reason }),
85
+ isCovered: gate.isOk || (commit !== undefined && coversHead(commit, tip)),
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Both families at the tip through the lift's own gates, so a worker and the
91
+ * lift never disagree on a reason. The evidence is read by the caller, since a
92
+ * wait reads it once rather than once per poll.
93
+ */
94
+ async function readAt(
95
+ api: ReviewStateApi,
96
+ hasChecklist: boolean,
97
+ painted: PaintedPatterns,
98
+ ): Promise<ReviewStateRead> {
99
+ const [tip, reviews] = await Promise.all([api.readTip(), api.readReviews()])
100
+ if (tip === undefined || reviews === undefined) {
101
+ return { kind: 'refused', reason: 'gh-failed' }
102
+ }
103
+
104
+ const listing: { reviews: readonly ReviewRow[] } = { reviews }
105
+ const scope = resolveReviewScope(listing)
106
+ const uiScope = resolveUiScope(listing)
107
+ const ui = await uiGate(api, painted, reviews, tip, hasChecklist)
108
+ if (ui.reason === 'gh-failed') return { kind: 'refused', reason: 'gh-failed' }
109
+
110
+ return {
111
+ kind: 'read',
112
+ record: {
113
+ head: tip,
114
+ scope,
115
+ review: familyOf(reviewGate(reviews, tip), scope.commit, tip),
116
+ ui: {
117
+ ...uiScope,
118
+ ...familyOf(ui, uiScope.commit, tip),
119
+ isBound: hasChecklist,
120
+ ...(ui.carriedFrom !== undefined && { carriedFrom: ui.carriedFrom }),
121
+ ...(ui.paintedPaths !== undefined && { paintedPaths: ui.paintedPaths }),
122
+ },
123
+ },
124
+ }
125
+ }
126
+
127
+ export async function readReviewState(
128
+ api: ReviewStateApi,
129
+ painted: PaintedPatterns = DEFAULT_PAINTED,
130
+ ): Promise<ReviewStateRead> {
131
+ const evidence = await api.readEvidence()
132
+ if (evidence === undefined) return { kind: 'refused', reason: 'gh-failed' }
133
+ return readAt(api, evidence.hasChecklist, painted)
134
+ }
135
+
136
+ /**
137
+ * Holds until every bound family has a pass covering the tip, or the deadline
138
+ * passes. The tip is read again every poll, so a push during the wait moves
139
+ * what a pass has to cover. The evidence is read once, since a checklist
140
+ * appearing mid-wait is a ship-chain write the waiting worker made before it
141
+ * started.
142
+ */
143
+ export async function waitForReviews(
144
+ api: ReviewStateApi,
145
+ opts: WaitOptions,
146
+ ): Promise<ReviewWait> {
147
+ const pollMs = opts.pollMs ?? CHECKS_POLL_MS
148
+ const painted = opts.painted ?? DEFAULT_PAINTED
149
+ const started = api.now()
150
+ const deadline = started + opts.waitSeconds * 1000
151
+ const waited = () => Math.round((api.now() - started) / 1000)
152
+
153
+ const evidence = await api.readEvidence()
154
+ if (evidence === undefined) {
155
+ return { kind: 'refused', reason: 'gh-failed', waitedSeconds: waited() }
156
+ }
157
+
158
+ for (;;) {
159
+ const read = await readAt(api, evidence.hasChecklist, painted)
160
+ if (read.kind === 'refused') {
161
+ return { ...read, waitedSeconds: waited() }
162
+ }
163
+ const { record } = read
164
+ if (record.review.isCovered && record.ui.isCovered) {
165
+ return {
166
+ kind: 'read',
167
+ reason: 'covered',
168
+ record,
169
+ waitedSeconds: waited(),
170
+ }
171
+ }
172
+ if (api.now() + pollMs > deadline) {
173
+ return {
174
+ kind: 'read',
175
+ reason: 'timeout',
176
+ record,
177
+ waitedSeconds: waited(),
178
+ }
179
+ }
180
+ await api.sleep(pollMs)
181
+ }
182
+ }