@erclx/canon 5.32.0 → 5.33.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 (210) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +1 -1
  3. package/claude/skills/auto-ship/references/worktree-name.md +1 -1
  4. package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
  5. package/claude/skills/backlog-triage/SKILL.md +1 -1
  6. package/claude/skills/canon-cli/REQUIREMENT.md +16 -13
  7. package/claude/skills/canon-cli/SKILL.md +75 -32
  8. package/claude/skills/canon-feedback/SKILL.md +1 -1
  9. package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +2 -2
  10. package/claude/skills/{canvas → canvas-board}/SKILL.md +2 -2
  11. package/{standards → claude/skills/canvas-board/references}/design.md +11 -2
  12. package/claude/skills/context-fold/REQUIREMENT.md +25 -33
  13. package/claude/skills/context-fold/SKILL.md +25 -70
  14. package/claude/skills/context-fold/references/classify.md +3 -3
  15. package/claude/skills/context-fold/references/completion-report.md +4 -4
  16. package/claude/skills/context-fold/references/context-refresh.md +5 -5
  17. package/{standards → claude/skills/context-fold/references}/context.md +16 -5
  18. package/claude/skills/context-fold/references/unusable-baseline.md +3 -5
  19. package/claude/skills/create-rule/SKILL.md +2 -2
  20. package/{standards → claude/skills/create-rule/references}/rule.md +12 -5
  21. package/claude/skills/create-skill/SKILL.md +2 -2
  22. package/{standards → claude/skills/create-skill/references}/skill.md +17 -14
  23. package/claude/skills/design-taste/REQUIREMENT.md +3 -3
  24. package/claude/skills/design-taste/SKILL.md +1 -1
  25. package/claude/skills/docs-sync/REQUIREMENT.md +1 -1
  26. package/claude/skills/docs-sync/SKILL.md +3 -3
  27. package/{standards → claude/skills/docs-sync/references}/docs.md +11 -0
  28. package/{standards → claude/skills/docs-sync/references}/readme.md +9 -2
  29. package/claude/skills/draft-and-pick/SKILL.md +5 -5
  30. package/claude/skills/draft-doc/SKILL.md +6 -6
  31. package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
  32. package/claude/skills/draft-figure/SKILL.md +2 -2
  33. package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
  34. package/claude/skills/draft-figure/references/mermaid-path.md +1 -1
  35. package/claude/skills/draft-identity/REQUIREMENT.md +2 -2
  36. package/claude/skills/draft-identity/SKILL.md +2 -2
  37. package/claude/skills/draft-ready/SKILL.md +1 -1
  38. package/claude/skills/git-branch/SKILL.md +1 -1
  39. package/{standards → claude/skills/git-branch/references}/branch.md +1 -1
  40. package/claude/skills/git-commit/SKILL.md +2 -2
  41. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  42. package/claude/skills/git-followup/SKILL.md +1 -1
  43. package/claude/skills/git-issue/SKILL.md +1 -1
  44. package/claude/skills/git-pr/SKILL.md +13 -13
  45. package/claude/skills/git-pr/references/evidence.md +2 -2
  46. package/claude/skills/git-pr/references/final-command.md +38 -14
  47. package/claude/skills/git-pr/references/labels.md +5 -1
  48. package/{standards → claude/skills/git-pr/references}/pr.md +19 -9
  49. package/{standards → claude/skills/git-pr/references}/publish.md +4 -2
  50. package/claude/skills/git-pr/references/task-number.md +1 -1
  51. package/claude/skills/git-ship/SKILL.md +15 -14
  52. package/claude/skills/git-split/SKILL.md +3 -3
  53. package/claude/skills/git-stage/SKILL.md +1 -1
  54. package/claude/skills/plan-feature/REQUIREMENT.md +1 -1
  55. package/claude/skills/review-address/SKILL.md +1 -1
  56. package/claude/skills/review-address/references/post-review-findings.md +1 -1
  57. package/claude/skills/review-pr/REQUIREMENT.md +1 -1
  58. package/claude/skills/review-pr/SKILL.md +3 -3
  59. package/claude/skills/review-pr/references/body-variants.md +2 -2
  60. package/claude/skills/review-pr/references/key-changes.md +3 -3
  61. package/claude/skills/review-pr/references/post.md +4 -2
  62. package/claude/skills/review-ui/REQUIREMENT.md +1 -1
  63. package/claude/skills/review-ui/SKILL.md +1 -1
  64. package/claude/skills/review-ui/references/post.md +1 -1
  65. package/claude/skills/role-orchestrator/REQUIREMENT.md +3 -0
  66. package/claude/skills/role-orchestrator/SKILL.md +2 -2
  67. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +2 -2
  68. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +8 -5
  69. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +23 -1
  70. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +2 -2
  71. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +3 -0
  72. package/claude/skills/role-planner/REQUIREMENT.md +2 -1
  73. package/claude/skills/role-planner/SKILL.md +13 -2
  74. package/claude/skills/role-reviewer/SKILL.md +1 -1
  75. package/claude/skills/role-worker/REQUIREMENT.md +1 -0
  76. package/claude/skills/role-worker/SKILL.md +9 -1
  77. package/claude/skills/session-map/SKILL.md +1 -1
  78. package/claude/skills/session-resume/REQUIREMENT.md +2 -2
  79. package/claude/skills/session-worktree/SKILL.md +5 -5
  80. package/claude/skills/target-setup/references/detect.md +1 -1
  81. package/claude/skills/task-board/REQUIREMENT.md +7 -12
  82. package/claude/skills/task-board/SKILL.md +5 -17
  83. package/claude/skills/task-board/references/tasks.md +2 -2
  84. package/claude/skills/task-complete/REQUIREMENT.md +47 -0
  85. package/claude/skills/task-complete/SKILL.md +86 -0
  86. package/claude/skills/{task-board → task-complete}/references/archive.md +4 -4
  87. package/claude/skills/{context-fold → task-complete}/references/receipt-sweep.md +5 -5
  88. package/claude/skills/task-complete/references/unusable-baseline.md +19 -0
  89. package/claude/skills/teach-workspace/REQUIREMENT.md +6 -2
  90. package/claude/skills/teach-workspace/SKILL.md +8 -4
  91. package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
  92. package/claude/skills/{context-fold/references/promoted-pages.md → teach-workspace/references/promotion-fold.md} +3 -3
  93. package/claude/skills/teach-workspace/references/promotion.md +3 -3
  94. package/claude/skills/ui-checklist/SKILL.md +1 -1
  95. package/claude/skills/ux-audit/SKILL.md +1 -1
  96. package/claude/skills/ux-measure/SKILL.md +1 -1
  97. package/docs/agents/canvas.md +1 -1
  98. package/docs/agents/commands.md +3 -2
  99. package/docs/agents/context-audit-checks.md +4 -4
  100. package/docs/agents/index.md +3 -3
  101. package/docs/agents/indexes.md +1 -1
  102. package/docs/agents/install-and-sync.md +6 -11
  103. package/docs/agents/key-changes.md +5 -5
  104. package/docs/agents/label-coverage.md +11 -0
  105. package/docs/agents/migrate.md +1 -1
  106. package/docs/agents/records-push.md +2 -2
  107. package/docs/agents/records-stale.md +12 -47
  108. package/docs/agents/records-validate.md +3 -7
  109. package/docs/agents/records.md +5 -27
  110. package/docs/agents/rule-citations.md +1 -1
  111. package/docs/agents/sandbox.md +4 -4
  112. package/docs/agents/skills-audit.md +1 -1
  113. package/docs/agents/tasks-plans.md +2 -2
  114. package/docs/agents/tasks.md +2 -2
  115. package/docs/target/migrations.md +10 -2
  116. package/docs/target/projects.md +1 -1
  117. package/docs/target/sync.md +1 -1
  118. package/docs/workflow/operating-model.md +2 -2
  119. package/docs/workflow/parallel-features.md +7 -7
  120. package/docs/workflow/skill-map-on-request.md +9 -9
  121. package/docs/workflow/skill-map.md +12 -11
  122. package/docs/workflow/visual-design-workflow.md +2 -2
  123. package/governance/renames.toml +0 -11
  124. package/governance/rules/canon/context.md +13 -0
  125. package/governance/rules/claude/skill.md +17 -0
  126. package/governance/stacks/base.toml +2 -4
  127. package/package.json +4 -4
  128. package/scripts/core/install-check.sh +3 -3
  129. package/scripts/lib/ui.sh +0 -159
  130. package/src/audits/catalog.ts +0 -1
  131. package/src/claude/cases/misc.ts +1 -1
  132. package/src/claude/cases/setup.ts +4 -0
  133. package/src/claude/cases/workflow.ts +6 -1
  134. package/src/claude/seeds.ts +1 -1
  135. package/src/claude/skills-audit.ts +2 -2
  136. package/src/cli/help.ts +3 -1
  137. package/src/cli/ui.ts +2 -3
  138. package/src/commands/claude.ts +1 -1
  139. package/src/commands/gov.ts +2 -15
  140. package/src/commands/labels.ts +326 -7
  141. package/src/commands/migrate.ts +6 -1
  142. package/src/commands/pr.ts +1 -1
  143. package/src/commands/records.ts +13 -399
  144. package/src/commands/sandbox.ts +3 -6
  145. package/src/commands/tasks.ts +3 -3
  146. package/src/context/audit.ts +5 -5
  147. package/src/context/folders.ts +1 -1
  148. package/src/design/budget.ts +1 -1
  149. package/src/design/components.ts +1 -1
  150. package/src/design/document.ts +1 -1
  151. package/src/design/regen.ts +1 -1
  152. package/src/design/render.ts +1 -1
  153. package/src/gate/measures.ts +1 -1
  154. package/src/gate/sequencer.ts +56 -1
  155. package/src/gate/stages.ts +1 -7
  156. package/src/gov/install.ts +2 -3
  157. package/src/gov/stacks.ts +1 -1
  158. package/src/hooks/post-merge.ts +1 -1
  159. package/src/labels/apply.ts +39 -0
  160. package/src/labels/format.ts +3 -3
  161. package/src/labels/phase.ts +3 -3
  162. package/src/labels/sections.ts +43 -0
  163. package/src/migrate/skill-names.ts +20 -1
  164. package/src/pr/paths.ts +4 -4
  165. package/src/records/backup.ts +16 -6
  166. package/src/records/stale-canonical.ts +31 -1
  167. package/src/records/validate.ts +2 -188
  168. package/src/sandbox/census.ts +1 -1
  169. package/src/sandbox/coverage.ts +2 -6
  170. package/src/sandbox/equivalence.ts +5 -44
  171. package/src/sandbox/expect.ts +4 -4
  172. package/src/sandbox/provision.ts +13 -36
  173. package/src/sandbox/scenario.ts +26 -48
  174. package/src/sandbox/tree.ts +2 -6
  175. package/src/standards/read.ts +14 -1
  176. package/src/sync/git.ts +1 -1
  177. package/src/tasks/archive.ts +5 -5
  178. package/src/tasks/branch.ts +3 -3
  179. package/src/tasks/label.ts +1 -1
  180. package/src/tasks/record.ts +2 -2
  181. package/src/tasks/validate.ts +1 -1
  182. package/standards/index.md +0 -13
  183. package/standards/standard.md +1 -7
  184. package/tooling/base/reference.md +1 -1
  185. package/tooling/base/seeds/.github/pull_request_template.md +2 -2
  186. package/tooling/claude/reference.md +1 -1
  187. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +9 -1
  188. package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +171 -0
  189. package/tooling/claude/seeds/.claude/settings.json +9 -0
  190. package/governance/rules/standards/context.md +0 -14
  191. package/governance/rules/standards/design.md +0 -12
  192. package/governance/rules/standards/readme.md +0 -12
  193. package/governance/rules/standards/rule.md +0 -13
  194. package/governance/rules/standards/skill.md +0 -21
  195. package/governance/rules/standards/standard.md +0 -13
  196. package/scripts/config.sh +0 -11
  197. package/scripts/lib/gov.sh +0 -14
  198. package/scripts/lib/sandbox-fixtures.sh +0 -191
  199. package/scripts/lib/sandbox-git.sh +0 -125
  200. package/scripts/lib/sandbox-path.sh +0 -50
  201. package/scripts/sandbox-hook.sh +0 -99
  202. package/src/gov/standard-rules.ts +0 -179
  203. package/src/records/migrate.ts +0 -78
  204. package/src/records/stale.ts +0 -243
  205. package/src/sandbox/hooks.ts +0 -128
  206. /package/claude/skills/{canvas → canvas-board}/references/canvas.md +0 -0
  207. /package/{standards → claude/skills/draft-figure/references}/figures.md +0 -0
  208. /package/{standards → claude/skills/git-branch/references}/slug.md +0 -0
  209. /package/{standards → claude/skills/git-commit/references}/commit.md +0 -0
  210. /package/{standards → claude/skills/git-commit/references}/versioning.md +0 -0
@@ -38,23 +38,23 @@ The plan's shape is fixed by `claude/skills/plan-feature/references/plan.md`: th
38
38
 
39
39
  An execution that picks other than the suggestion rewrites the `- Suggested:` line as `overridden at execution to <pick>,` followed by the measurement that moved it, and leaves the slot blank. That fixed phrase is how a reader of the archived plan tells an override from a suggestion the execution accepted, since an authored suggestion often carries a number of its own. The same deviation takes one line in the open task's `## Findings`, which is the register that survives the plan being archived. A deviation from a question somebody already answered goes back to whoever answered it instead, since a filled slot is a decision already made.
40
40
 
41
- `canon records validate plans` reports where a plan and that standard disagree: a filename that is not `feature-<slug>.md`, a missing required section, a files-to-touch entry naming no file, and a question carrying a suggestion with no answer slot. The same verb takes `groundwork`, `intake`, `memory`, and `teach`, which are governed the same way and were unreachable for the same reason. Nothing fires it automatically, because all five folders are gitignored and every check the repository runs reads changed files from git. It reports and never writes, since the folders are per-machine scratch with no history to recover a wrong repair from.
41
+ `canon records validate plans` reports where a plan and that standard disagree: a filename that is not `feature-<slug>.md`, a missing required section, a files-to-touch entry naming no file, and a question carrying a suggestion with no answer slot. The same verb takes `groundwork`, `intake`, and `teach`, which are governed the same way and were unreachable for the same reason. Nothing fires it automatically, because all four folders are gitignored and every check the repository runs reads changed files from git. It reports and never writes, since the folders are per-machine scratch with no history to recover a wrong repair from.
42
42
 
43
43
  `canon records push` carries these folders off the disk they live on, and `canon records pull` brings them back. Every top-level entry under `.canon/` is backed except `tmp`, `ordinal-locks`, and `.records.git`, so a folder added later enters the payload on its own rather than waiting on a name written into a list. Push names each folder it carries the first time it sees it, which is what keeps a stray folder visible instead of silently entering the payload. It refuses the whole push, naming each path, when a new or changed file is over 25 MB or carries a credential `canon secrets scan` would report. The history lives in a second git directory at `.canon/.records.git` with `.canon/` as its work tree, so every path a task file cites stays where it is.
44
44
 
45
45
  A person points it at a private repository once and both verbs refuse until they have, and `push` refuses when that origin is also a remote of the project, since the payload is the task board and the groundwork trails. `.husky/post-merge` runs the push after its archive loop, on every merge rather than only on one that closed a task. See [records push](../agents/records-push.md) for the refusal table.
46
46
 
47
- `canon records size` reports what each of these folders holds, heaviest first, along with `.canon/tmp`. Each row carries the file count, the bytes, how many files were written in the last 7 and 30 days, and the dates of the least and most recently written one. Nothing fails on a number, because a record folder has no correct size. What the verb replaces is a reading somebody had to remember to take: the memory pen went from 44 entries to 236 between two counts made by hand a fortnight apart, and nothing reported the rate in between.
47
+ `canon records size` reports what each of these folders holds, heaviest first, along with `.canon/tmp`. Each row carries the file count, the bytes, how many files were written in the last 7 and 30 days, and the dates of the least and most recently written one. Nothing fails on a number, because a record folder has no correct size. What the verb replaces is a reading somebody had to remember to take: a pen went from 44 entries to 236 between two counts made by hand a fortnight apart, and nothing reported the rate in between.
48
48
 
49
49
  `canon records prune-tmp` reports scratch under `.canon/tmp` nobody has touched inside an age window, and deletes it only with `--write`. A `tmp/handoff/` folder and the live `tmp/pr/poll/` baseline are never offered, since a reader deletes a handoff once it is read and a poll baseline is state a session still needs. See [records](../agents/records.md) for the candidate shapes and the exit codes.
50
50
 
51
- `canon records stale memory` reads the memory pen as a review queue. It names each entry due for review, meaning one carrying no `reviewed` date or one older than 30 days, and every backticked path an entry cites that the tree no longer holds. Due entries come first, with the ones citing a missing path ahead of the rest, so a review takes the first batch rather than the whole pen. It writes nothing. See [records stale](../agents/records-stale.md) for how a path is read and the refusals.
51
+ `canon records stale canonical` reports when the requirements record was last reviewed and how many releases have shipped since, so a review of it starts from a count rather than from the tag list. It writes nothing. See [records stale](../agents/records-stale.md) for how the count is taken and the refusals.
52
52
 
53
53
  A plan that ships is archived, never deleted. `canon tasks archive` moves it to `.canon/plans/archive/` alongside the task it belonged to and retargets that task's `Plan:` line at the new location, so a completed task still leads to the reasoning behind it. An archive sits inside the record folder it archives rather than beside it, so one ignore entry and one backed-folder entry cover a record and everything it has retired. The folder is gitignored, which is why a deleted plan had no recovery path. A plan cited by more than one task stays put until the last of them closes, since moving it early would strand every other pointer.
54
54
 
55
- An older branch review report takes the other route and is swept rather than archived. It sits flat in `.canon/review/` as `branch-<slug>.md`, the session addressing it read it once, and the durable record of what a review found is the comment `review-pr` posts on the pull request, so `context-fold` deletes any report whose branch is gone. The body that writes a report owns how long it lives, which leaves the shipping branch's own report on disk through the run that cites it and collects it a branch later. What that loses is a local-only review on a branch that never opened a pull request, which is why the report says so where a reader meets it.
55
+ An older branch review report takes the other route and is swept rather than archived. It sits flat in `.canon/review/` as `branch-<slug>.md`, the session addressing it read it once, and the durable record of what a review found is the comment `review-pr` posts on the pull request, so `canon:task-complete` deletes any report whose branch is gone. The body that writes a report owns how long it lives, which leaves the shipping branch's own report on disk through the run that cites it and collects it a branch later. What that loses is a local-only review on a branch that never opened a pull request, which is why the report says so where a reader meets it.
56
56
 
57
- `canon:context-fold` decides which task closed by reading the diff rather than the conversation. It resolves a merge base against `origin/main`, unions the committed diff with the working tree and untracked files, then matches unchecked outcomes on the board against what shipped. A task that shipped without ever being discussed still gets marked. Decisions and design stay session-sourced, because a diff cannot carry a judgment. The requirements record is never folded. A direction change gets one report line naming `canon:document-health`, which reviews that record only when asked.
57
+ `canon:task-complete` decides which task closed by reading the diff rather than the conversation, as the ship-chain step after `canon:context-fold`. It resolves a merge base against `origin/main`, unions the committed diff with the working tree and untracked files, then matches unchecked outcomes on the board against what shipped. A task that shipped without ever being discussed still gets marked. Decisions stay session-sourced, because a diff cannot carry a judgment, and `canon:context-fold` folds them into the context entries. The requirements record is never folded. A direction change gets one report line naming `canon:document-health`, which reviews that record only when asked.
58
58
 
59
59
  ## Shipping a fan-out
60
60
 
@@ -87,12 +87,12 @@ A hand-maintained `priority.md` sits beside the index carrying execution order a
87
87
 
88
88
  Past that shape, it checks what a surviving row claims against what the tree holds: every plan pointer resolves, every task file is named by a board row or a backlog line and never by both, no task sits in two groups, and every row marked ready names its files. One check across both surfaces is what lets a task move between the board and the backlog without the move reading as a dropped file. Paths two ready rows share go to a `shared` array moving no exit code, the candidate list the orchestrator's conflict check reads. Blockers re-takes what a parked row waits on, reporting one whose cited task reached the trunk and one whose cited file nothing running still holds. A cited task settles the row by being archived, or by closing every outcome and naming a pull request the trunk carries, since the checkbox alone is marked while the branch is still in review. Both halves read a citation out of the blocker cell, so a row citing neither is reported as untested rather than counted clean, and so is a cited task the trunk could not answer for. It reports and never writes, because a row is the orchestrator's claim and a validator repairing one would assert the claim it exists to test. Nothing fires it automatically, since the board is gitignored per-machine scratch with no shared moment to hang a hook on, so the orchestrator's sweep calls it at the point the readiness claim is made and follows it with the parked re-test.
89
89
 
90
- `canon:task-board` owns the two operations that bracket a task's life. It creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and it moves a shipped task to `.canon/tasks/archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do.
90
+ `canon:task-board` creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and declines a task decided against. `canon:task-complete` marks a shipped task's outcomes and moves one the merge hook left to `.canon/tasks/archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do.
91
91
 
92
92
  Archiving a task carries its plan with it, in the same act. The merge is what settles a plan, and the hook below reaches the archive with nobody watching, so a second call after it would be a second failure point leaving the task archived and the plan live. A task whose plan a sibling still cites archives on its own and leaves the plan live, since moving it on the first task to close strands every other pointer at a path that has gone.
93
93
 
94
94
  Nothing chained that archive until the `post-merge` git hook landed. Every earlier step fires from `canon:auto-ship` or `canon:git-ship`, both of which finish while the pull request is still open, so a task archived there would close for work that may be abandoned. The board is gitignored, which rules out reading it from anywhere but the machine that pulled. The hook archives the task a merged pull request closed, through the same verb the base stack ships to every target, and does nothing on a project with no board.
95
95
 
96
- The archive gates on a pull request number the merge carried and a closed task, because outcomes are marked on the branch and a task can read all `[x]` while its pull request is still open, so `canon:task-board` still confirms the work reached `main` when a person archives by hand. A companion `post-rewrite` hook carries the same steps for anyone pulling with rebase, which fires that event instead of `post-merge`.
96
+ The archive gates on a pull request number the merge carried and a closed task, because outcomes are marked on the branch and a task can read all `[x]` while its pull request is still open, so `canon:task-complete` still confirms the work reached `main` when a person archives by hand. A companion `post-rewrite` hook carries the same steps for anyone pulling with rebase, which fires that event instead of `post-merge`.
97
97
 
98
98
  The hook archives through `canon tasks archive`, which carries the refusals above, so a task whose pull request has not merged stays where it is. Both hooks ship with the `base` tooling stack, so a target project running this workflow gets the same trigger, and `CANON_SKIP_RECLAIM`, `CANON_SKIP_UPGRADE`, and `CANON_SKIP_PLUGIN_UPDATE` turn off the three steps that act on the machine.
@@ -25,15 +25,15 @@ These two groups hold the skills no single moment in a project's life calls for,
25
25
 
26
26
  ## Answer a question at any point
27
27
 
28
- | Skill | When to use |
29
- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
30
- | `canon:canon-cli` | Before running an unfamiliar verb, a sync, or an install, to learn which command to run, which reference doc covers it, or what it overwrites, merges, or leaves alone |
31
- | `canon:youtube-transcripts` | When a video transcript is wanted in the repo as context |
32
- | `canon:read-frames` | To read a recorded demo back frame by frame and report what each one shows, with no verdict on whether the recording looks right |
33
- | `canon:teach-workspace` | To learn a subject across sessions, in a workspace that holds the progress |
34
- | `canon:markdown-craft` | Before a substantial markdown edit, for the format and structure rules and the audit that follows |
35
- | `canon:write-human` | Before drafting or revising prose, for voice, rhythm, and density |
28
+ | Skill | When to use |
29
+ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
30
+ | `canon:canon-cli` | To pick the `canon` verb that does a job, or before a sync or migrate, to learn which verbs can lose the project's edits |
31
+ | `canon:youtube-transcripts` | When a video transcript is wanted in the repo as context |
32
+ | `canon:read-frames` | To read a recorded demo back frame by frame and report what each one shows, with no verdict on whether the recording looks right |
33
+ | `canon:teach-workspace` | To learn a subject across sessions, in a workspace that holds the progress |
34
+ | `canon:markdown-craft` | Before a substantial markdown edit, for the format and structure rules and the audit that follows |
35
+ | `canon:write-human` | Before drafting or revising prose, for voice, rhythm, and density |
36
36
 
37
37
  Every row answers a question rather than marking a point in a project's life, so filing one under a phase on the [skill map](skill-map.md) would send a reader to the wrong group.
38
38
 
39
- A learning workspace produces two halves and only one of them leaves. A lesson is worked through once and stays in the workspace, and a reference page or a glossary carries no learner, so it belongs wherever the project already keeps prose on that subject. Asking `canon:teach-workspace` to promote sorts each durable page by who owns its subject, sending an Anthropic-owned subject to the wiki, an internal one to the matching context entry, and everything else, subject-neutral material included, to the public docs. It proposes and waits, because a promoted page is public prose that needs a line naming who owns the subject, and it writes nothing to a destination: each page the operator confirms goes to a handoff file that `canon:context-fold` folds in from a branch. A project with no wiki folder gets a refusal naming `canon wiki init` rather than a folder it never asked for.
39
+ A learning workspace produces two halves and only one of them leaves. A lesson is worked through once and stays in the workspace, and a reference page or a glossary carries no learner, so it belongs wherever the project already keeps prose on that subject. Asking `canon:teach-workspace` to promote sorts each durable page by who owns its subject, sending an Anthropic-owned subject to the wiki, an internal one to the matching context entry, and everything else, subject-neutral material included, to the public docs. It proposes and waits, because a promoted page is public prose that needs a line naming who owns the subject, and it writes nothing to a destination: each page the operator confirms goes to a handoff file that `canon:teach-workspace` folds in from a branch in its fold mode. A project with no wiki folder gets a refusal naming `canon wiki init` rather than a folder it never asked for.
@@ -29,8 +29,8 @@ Each row sits under the group its skill's `metadata.family` names. The landing p
29
29
  | `canon:plan-groundwork` | When the state is unmeasured and more than one approach is live |
30
30
  | `canon:decision-escalate` | When open decisions turn on your preference and want batching into one set |
31
31
  | `canon:draft-and-pick` | When the call is taste and wants several candidates rendered side by side |
32
- | `canon:canvas` | When a direction should be drawn as frames the operator can see, select, and edit |
33
- | `canon:task-board` | When a decided item needs a file on the board, or a shipped one needs archiving |
32
+ | `canon:canvas-board` | When a direction should be drawn as frames the operator can see, select, and edit |
33
+ | `canon:task-board` | When a decided item needs a file on the board, or one is decided against |
34
34
  | `canon:plan-feature` | When the approach is settled and the next step is a plan |
35
35
  | `canon:codebase-layout` | When a plan or change adds a file and you need to decide which folder holds it |
36
36
 
@@ -63,15 +63,16 @@ Each row sits under the group its skill's `metadata.family` names. The landing p
63
63
 
64
64
  ## Ship it
65
65
 
66
- | Skill | When to use |
67
- | -------------------- | ---------------------------------------------------------------------------------- |
68
- | `canon:git-ship` | To run the whole post-feature chain from the verify gate through open PR |
69
- | `canon:context-fold` | When decisions diverged from the plan, or a shipped task needs its outcomes marked |
70
- | `canon:docs-sync` | When a change since main left `README.md` or `docs/` stale |
71
- | `canon:git-stage` | When the staged set spans several concerns and wants one commit each |
72
- | `canon:git-commit` | When the staged set is one concern, or was staged hunk by hand |
73
- | `canon:git-branch` | When a branch name needs generating or renaming to conventional form |
74
- | `canon:git-pr` | When a pull request needs a title and body written from the diff |
66
+ | Skill | When to use |
67
+ | --------------------- | ----------------------------------------------------------------------------------------------- |
68
+ | `canon:git-ship` | To run the whole post-feature chain from the verify gate through open PR |
69
+ | `canon:context-fold` | When decisions diverged from the plan, or the diff left a context entry stale |
70
+ | `canon:task-complete` | After the fold, to mark the outcomes the diff shipped, or to archive a task the merge hook left |
71
+ | `canon:docs-sync` | When a change since main left `README.md` or `docs/` stale |
72
+ | `canon:git-stage` | When the staged set spans several concerns and wants one commit each |
73
+ | `canon:git-commit` | When the staged set is one concern, or was staged hunk by hand |
74
+ | `canon:git-branch` | When a branch name needs generating or renaming to conventional form |
75
+ | `canon:git-pr` | When a pull request needs a title and body written from the diff |
75
76
 
76
77
  ## After the pull request opens
77
78
 
@@ -20,7 +20,7 @@ Claude Code reads it and writes the implementation. Works for CLI tools, interna
20
20
 
21
21
  ### Seed shape
22
22
 
23
- The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships a token-table template with a starting set of roles, and `standards/design.md` carries the same tables under `## Template` with placeholder rows. The column headers are what the renderer parses, so they stay verbatim in either, while the rows and values are the project's own.
23
+ The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships a token-table template with a starting set of roles, and `claude/skills/canvas-board/references/design.md` carries the same tables under `## Template` with placeholder rows. The column headers are what the renderer parses, so they stay verbatim in either, while the rows and values are the project's own.
24
24
 
25
25
  `canon design render` writes an HTML plus CSS preview to `.canon/tmp/render/design/` for eyeballing the current system without leaving Claude Code. See `canon/context/design/index.md`.
26
26
 
@@ -39,7 +39,7 @@ A cell no source anchors ends in `? verify`, and the preview shows that marker b
39
39
  - `canon:ux-audit` for UX gap detection on existing surfaces
40
40
  - `canon:ux-measure` for what a running surface costs to paint, read against published thresholds
41
41
  - `canon:draft-and-pick` for a call settled by looking, drafting several candidates as frames on the canvas and taking your pick
42
- - `canon:canvas` for a direction worked out over several turns, drawn as HTML frames you drag, select, and restyle in the browser while the session reads your changes back. Only the pick moves into `canon/DESIGN.md`, since the canvas folder is gitignored
42
+ - `canon:canvas-board` for a direction worked out over several turns, drawn as HTML frames you drag, select, and restyle in the browser while the session reads your changes back. Only the pick moves into `canon/DESIGN.md`, since the canvas folder is gitignored
43
43
  - `canon:draft-identity` to draft a project's logo mark and compose it into an icon sequence and a social card, through `draft-and-pick`'s own render-and-pick loop. On an Astro project holding the card route scaffold, the card lands as a route the project keeps and is captured through a running server, so it reads the project's real stylesheet rather than typed copies of every color. Everywhere else it ships as a PNG and the run says so.
44
44
  - Anthropic's `frontend-design` plugin optional for light visual steering
45
45
 
@@ -13,10 +13,6 @@
13
13
  # resolves A only while both links stay. A key must name no live rule and every
14
14
  # chain must end on one, which `src/gov/renames.test.ts` checks against this
15
15
  # file.
16
- #
17
- # A numbered rule replaced by the rule `canon gov regen` generates from its
18
- # standard is a rename too: the generated rule keeps every glob and bullet, so
19
- # the pair is one-to-one identity under the standard's name.
20
16
  [renamed]
21
17
  "015-output" = "566-output"
22
18
  "035-tasks" = "602-tasks"
@@ -25,22 +21,15 @@
25
21
  "087-git" = "606-git"
26
22
  "510-context" = "610-context"
27
23
  "511-indexes" = "611-indexes"
28
- "550-design" = "650-design"
29
24
  "555-tasks" = "655-tasks"
30
25
  "558-plan" = "658-plan"
31
26
  "501-markdown" = "801-markdown"
32
- "580-readme" = "880-readme"
33
- "591-standard-authoring" = "891-standard-authoring"
34
27
  "065-spelling" = "765-spelling"
35
28
  "075-dependencies" = "775-dependencies"
36
29
  "080-config-comments" = "780-config-comments"
37
30
  "090-code-comments" = "790-code-comments"
38
31
  "658-plan" = "plan"
39
32
  "610-context" = "context"
40
- "650-design" = "design"
41
33
  "655-tasks" = "tasks"
42
34
  "570-skill" = "skill"
43
- "590-rule-authoring" = "rule"
44
35
  "801-markdown" = "markdown"
45
- "880-readme" = "readme"
46
- "891-standard-authoring" = "standard"
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Route edits under canon/context/ to the context-fold skill for the entry shape, and keep each entry conforming to the work in its domain
3
+ paths:
4
+ - 'canon/context/**'
5
+ ---
6
+
7
+ # Context standards
8
+
9
+ ## Context entries
10
+
11
+ - Load the `canon:context-fold` skill before a hand edit under `canon/context/`. It carries the entry shape and the content rules for a domain entry. Report it rather than proceeding silently when the skill does not resolve.
12
+ - Before non-trivial work in a domain, read its `canon/context/<domain>/` entry. Use `canon/context/index.md` to find it.
13
+ - Leave the entry conforming when work in its domain changes what it describes.
@@ -0,0 +1,17 @@
1
+ ---
2
+ description: Route edits to a skill body or its requirement to the create-skill skill for the shape, and hold the creation-time questions and the re-read rule
3
+ paths:
4
+ - '.claude/skills/**/SKILL.md'
5
+ - 'claude/skills/**/SKILL.md'
6
+ - '.claude/skills/**/REQUIREMENT.md'
7
+ - 'claude/skills/**/REQUIREMENT.md'
8
+ ---
9
+
10
+ # Skill standards
11
+
12
+ ## Skill files
13
+
14
+ - Load the `canon:create-skill` skill before a hand edit to a `SKILL.md` or a `REQUIREMENT.md`. It carries the skill structure, the requirement shape, and the path rules for a skill body. Report it rather than proceeding silently when the skill does not resolve. It ships with the plugin and this rule ships with the CLI, so a project that installed governance alone does not have it.
15
+ - Confirm `canon:create-skill`'s two creation-time questions are answered before a new `SKILL.md` lands, whether drafted by hand, by another skill, or by `canon:create-skill` itself. Carry the third question into the sibling `REQUIREMENT.md`'s `Must not` section as a review criterion rather than a gate.
16
+ - Re-read a skill body this session edited before invoking that skill again in the same session.
17
+ - Do not read a resolved file path in a held body as evidence the body is current.
@@ -5,7 +5,5 @@ extends = ""
5
5
  # session conduct and `.claude/` authoring rules, `tooling` the dev setup and
6
6
  # CI workflow rules, and `writing` the prose and document-shape rules. The
7
7
  # `code` group is left to the stacks that write code, so a docs or writing
8
- # project loads no rule it can never apply. `standards` holds one rule per
9
- # standard routing its paths to it, generated by `canon gov regen` from each
10
- # standard's frontmatter rather than authored.
11
- rules = ["canon", "claude", "standards", "tooling", "writing"]
8
+ # project loads no rule it can never apply.
9
+ rules = ["canon", "claude", "tooling", "writing"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "5.32.0",
4
+ "version": "5.33.0",
5
5
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "scripts": {
28
28
  "check:spell": "cspell '**' '.*/**' '.*' --no-progress --color --show-context",
29
- "format": "prettier --write --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --write --indent 2 scripts/ sandbox/ tooling/ claude/",
30
- "check:format": "prettier --check --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --diff --indent 2 scripts/ sandbox/ tooling/ claude/",
31
- "check:shell": "find scripts sandbox tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
29
+ "format": "prettier --write --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --write --indent 2 scripts/ tooling/ claude/",
30
+ "check:format": "prettier --check --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --diff --indent 2 scripts/ tooling/ claude/",
31
+ "check:shell": "find scripts tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
32
32
  "check:types": "tsc --noEmit",
33
33
  "check:install": "./scripts/core/install-check.sh",
34
34
  "test": "bun --bun vitest run",
@@ -55,10 +55,10 @@ open_timeline "Install verification"
55
55
  # nothing, so the excluded tree has to exist here before its absence below can
56
56
  # mean the publish left it out.
57
57
  log_step "Assert excluded path exists in source"
58
- if [ ! -f "$PROJECT_ROOT/sandbox/run.sh" ]; then
59
- log_error "sandbox/run.sh is missing from the source tree, so the absence check below would pass on nothing"
58
+ if [ ! -f "$PROJECT_ROOT/sandbox/exempt.toml" ]; then
59
+ log_error "sandbox/exempt.toml is missing from the source tree, so the absence check below would pass on nothing"
60
60
  fi
61
- log_info "Present: sandbox/run.sh"
61
+ log_info "Present: sandbox/exempt.toml"
62
62
 
63
63
  log_step "Pack"
64
64
  TARBALL_PATH="$(cd "$PROJECT_ROOT" && bun pm pack --quiet --ignore-scripts --destination "$PACK_DIR" | tail -n 1)"
package/scripts/lib/ui.sh CHANGED
@@ -6,12 +6,6 @@ if [ "${BASH_VERSINFO[0]:-0}" -lt 4 ]; then
6
6
  exit 1
7
7
  fi
8
8
 
9
- # Resolved from this file's own location rather than `$PROJECT_ROOT`, because
10
- # `require_project_root` is what several scripts call before anything has
11
- # established a root.
12
- # shellcheck source=/dev/null
13
- source "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/sandbox-path.sh"
14
-
15
9
  # `NO_COLOR` follows the published convention, where any non-empty value turns
16
10
  # color off whatever the value says.
17
11
  supports_color() {
@@ -111,156 +105,3 @@ guard_root() {
111
105
  log_error "Cannot run against toolkit root. Files here are the source of truth."
112
106
  fi
113
107
  }
114
-
115
- require_project_root() {
116
- local GREEN RED YELLOW WHITE GREY NC
117
- set_palette 2
118
- local sandbox in_sandbox=0
119
- if [ -n "${CANON_SANDBOX_DIR:-}" ]; then
120
- sandbox="$CANON_SANDBOX_DIR"
121
- [[ "$PWD" == "$sandbox" || "$PWD" == "$sandbox"/* ]] && in_sandbox=1
122
- else
123
- sandbox="$(sandbox_dir_prefix)"
124
- [[ "$PWD" == "$sandbox" || "$PWD" == "$sandbox"/* || "$PWD" == "$sandbox"-* ]] && in_sandbox=1
125
- fi
126
- if [ "$in_sandbox" -eq 1 ]; then
127
- echo -e "${GREY}┌${NC}" >&2
128
- log_error "Execution restricted: Command cannot be run from inside the sandbox environment."
129
- fi
130
- if [[ "$PWD" != "$PROJECT_ROOT"* ]]; then
131
- echo -e "${GREY}┌${NC}" >&2
132
- log_error "Context Error: You must run this command from inside the repository."
133
- fi
134
- }
135
-
136
- # The retired spelling stays honored, and permanently. This variable is the
137
- # documented way to drive any command headlessly, so every skill body, CI job,
138
- # and operator script already written sets the old name, and those callers live
139
- # in repositories and plugin caches this release cannot reach. Dropping it
140
- # leaves them waiting on a TTY nobody is watching.
141
- is_non_interactive() {
142
- # canon-keep-retired
143
- [[ "${CANON_NON_INTERACTIVE:-}" == "1" || "${AITK_NON_INTERACTIVE:-}" == "1" ]]
144
- }
145
-
146
- ask() {
147
- local GREEN RED YELLOW WHITE GREY NC
148
- set_palette 2
149
- local prompt_text=$1
150
- local var_name=$2
151
- local default_val=$3
152
- local input=""
153
- local char
154
- local display_default=""
155
- if [ -n "$default_val" ]; then
156
- display_default=" (${default_val})"
157
- fi
158
- if is_non_interactive; then
159
- echo -e "${GREY}│${NC}" >&2
160
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${default_val}${NC}" >&2
161
- export "$var_name"="$default_val"
162
- return
163
- fi
164
- echo -e "${GREY}│${NC}" >&2
165
- echo -ne "${GREEN}◆${NC} ${prompt_text}${display_default} " >&2
166
- while IFS= read -r -s -n1 char; do
167
- if [[ $char == $'\x1b' ]]; then
168
- read -rsn2 -t 0.001 _ || true
169
- echo -ne "\r\033[K" >&2
170
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
171
- exit 1
172
- elif [[ $char == $'\x7f' || $char == $'\x08' ]]; then
173
- if [ -n "$input" ]; then
174
- input="${input%?}"
175
- echo -ne "\b \b" >&2
176
- fi
177
- elif [[ -z "$char" ]]; then
178
- break
179
- else
180
- input+="$char"
181
- echo -n "$char" >&2
182
- fi
183
- done
184
- [ -z "$input" ] && input="$default_val"
185
- echo -ne "\r\033[K" >&2
186
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${input}${NC}" >&2
187
- export "$var_name"="$input"
188
- }
189
-
190
- select_or_route_scenario() {
191
- local GREEN RED YELLOW WHITE GREY NC
192
- set_palette 2
193
- local prompt_text=$1
194
- shift
195
- local options=("$@")
196
-
197
- if [ -n "${SANDBOX_SCENARIO:-}" ]; then
198
- echo -e "${GREY}│${NC}" >&2
199
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${SANDBOX_SCENARIO}${NC}" >&2
200
- export SELECTED_OPTION="$SANDBOX_SCENARIO"
201
- return
202
- fi
203
-
204
- select_option "$prompt_text" "${options[@]}"
205
- }
206
-
207
- select_option() {
208
- local GREEN RED YELLOW WHITE GREY NC
209
- set_palette 2
210
- local prompt_text=$1
211
- shift
212
- local options=("$@")
213
- local cur=0
214
- local count=${#options[@]}
215
-
216
- if is_non_interactive; then
217
- echo -e "${GREY}│${NC}" >&2
218
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${options[0]}${NC}" >&2
219
- export SELECTED_OPTION="${options[0]}"
220
- return
221
- fi
222
-
223
- if [ ! -t 0 ]; then
224
- log_error "${prompt_text} requires a TTY. Pass an argument or set CANON_NON_INTERACTIVE=1."
225
- fi
226
-
227
- echo -e "${GREY}│${NC}" >&2
228
- echo -ne "${GREEN}◆${NC} ${prompt_text}\n" >&2
229
-
230
- while true; do
231
- for i in "${!options[@]}"; do
232
- if [ "$i" -eq "$cur" ]; then
233
- echo -e "${GREY}│${NC} ${GREEN}❯ ${options[$i]}${NC}" >&2
234
- else
235
- echo -e "${GREY}│${NC} ${GREY}${options[$i]}${NC}" >&2
236
- fi
237
- done
238
-
239
- read -rsn1 key
240
- case "$key" in
241
- $'\x1b')
242
- if read -rsn2 -t 0.001 key_seq; then
243
- if [[ "$key_seq" == "[A" ]]; then cur=$(((cur - 1 + count) % count)); fi
244
- if [[ "$key_seq" == "[B" ]]; then cur=$(((cur + 1) % count)); fi
245
- else
246
- echo -ne "\033[$((count + 1))A\033[J" >&2
247
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
248
- exit 1
249
- fi
250
- ;;
251
- "k") cur=$(((cur - 1 + count) % count)) ;;
252
- "j") cur=$(((cur + 1) % count)) ;;
253
- "q")
254
- echo -ne "\033[$((count + 1))A\033[J" >&2
255
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
256
- exit 1
257
- ;;
258
- "") break ;;
259
- esac
260
- echo -ne "\033[${count}A" >&2
261
- done
262
-
263
- echo -ne "\033[$((count + 1))A\033[J" >&2
264
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${options[$cur]}${NC}" >&2
265
- export SELECTED_OPTION="${options[$cur]}"
266
- }
@@ -468,7 +468,6 @@ const RECORD_KINDS: readonly (readonly [string, Corpus])[] = [
468
468
  ['plans', 'per-machine'],
469
469
  ['groundwork', 'per-machine'],
470
470
  ['intake', 'per-machine'],
471
- ['memory', 'per-machine'],
472
471
  ['standards', 'tracked'],
473
472
  ['teach', 'per-machine'],
474
473
  ]
@@ -25,7 +25,7 @@ export const MISC_CASES: readonly SkillCase[] = [
25
25
  {
26
26
  prompt:
27
27
  'Draw the signup screen as a frame on the canvas, then restyle the element I just selected there.',
28
- expect: 'canvas',
28
+ expect: 'canvas-board',
29
29
  },
30
30
  {
31
31
  prompt:
@@ -40,6 +40,10 @@ export const SETUP_CASES: readonly SkillCase[] = [
40
40
  "Before I run this sync, tell me exactly what it's going to overwrite.",
41
41
  expect: 'canon-cli',
42
42
  },
43
+ {
44
+ prompt: 'Which canon command tells me if my markdown breaks the rules?',
45
+ expect: 'canon-cli',
46
+ },
43
47
  {
44
48
  prompt:
45
49
  'Something about the toolkit itself is broken, write it up and send it back to the maintainers.',
@@ -31,7 +31,7 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
31
31
  },
32
32
  {
33
33
  prompt:
34
- 'Fold what we decided this session into the context entries and mark off what shipped on the task board.',
34
+ 'Fold what we decided this session into the context entries before this branch goes out.',
35
35
  expect: 'context-fold',
36
36
  },
37
37
  {
@@ -127,6 +127,11 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
127
127
  prompt: 'Open a new entry on the task board for this piece of work.',
128
128
  expect: 'task-board',
129
129
  },
130
+ {
131
+ prompt:
132
+ 'This branch finished the pagination work, so tick off whichever board outcomes it actually delivered.',
133
+ expect: 'task-complete',
134
+ },
130
135
  {
131
136
  prompt: 'Open a learning workspace so I can study this topic properly.',
132
137
  expect: 'teach-workspace',
@@ -17,7 +17,7 @@ const HOOKS = 'hooks'
17
17
  * stem in an older layout, which is what `@/sync/layout` pairs a target against
18
18
  * to find a superseded artifact.
19
19
  */
20
- export const SUBDIRS: readonly string[] = [HOOKS, 'context', 'memory', 'tasks']
20
+ export const SUBDIRS: readonly string[] = [HOOKS, 'context', 'tasks']
21
21
 
22
22
  export type SeedScope = 'claude' | 'root'
23
23
 
@@ -7,7 +7,7 @@ import { bodyLines, maskDisplayed } from '@/markdown/scan'
7
7
  /** Returned when a skill folder carries no `REQUIREMENT.md`, the gating check. */
8
8
  export const EXIT_MISSING_REQUIREMENT = 2
9
9
 
10
- /** The description ceiling stated in the frontmatter rules of `standards/skill.md`. */
10
+ /** The description ceiling stated in the frontmatter rules of `claude/skills/create-skill/references/skill.md`. */
11
11
  export const DESCRIPTION_LIMIT = 1024
12
12
 
13
13
  /** The two headings the requirement template declares, matched at any level. */
@@ -160,7 +160,7 @@ interface SkillText {
160
160
  }
161
161
 
162
162
  /**
163
- * Measures both skill corpora against the rules `standards/skill.md` states
163
+ * Measures both skill corpora against the rules `claude/skills/create-skill/references/skill.md` states
164
164
  * mechanically. A corpus the project does not carry is skipped rather than
165
165
  * reported, so a target holding only `.claude/skills/` reads as in scope.
166
166
  *
package/src/cli/help.ts CHANGED
@@ -10,6 +10,8 @@ type HelpStream = { isTTY?: boolean }
10
10
 
11
11
  // The grouping mirrors the README's domain table and has no other source, so a
12
12
  // command added to the program needs a row here or help-option.test.ts fails.
13
+ // A row here also needs a `canon <verb>` line in claude/skills/canon-cli, or a
14
+ // name in TOOLKIT_ONLY in canon-cli-skill.test.ts, which reads this list.
13
15
  export const COMMAND_GROUPS: { title: string; rows: CommandRow[] }[] = [
14
16
  {
15
17
  title: 'Project',
@@ -25,7 +27,7 @@ export const COMMAND_GROUPS: { title: string; rows: CommandRow[] }[] = [
25
27
  title: 'Domains',
26
28
  rows: [
27
29
  ['gov [cmd]', 'Governance rules (install, sync, list)'],
28
- ['standards [cmd]', 'Standards (install, sync, list, <name>)'],
30
+ ['standards [cmd]', 'Standards (list, <name>)'],
29
31
  ['tooling [cmd]', 'Tooling stacks (sync, ref, create)'],
30
32
  ['claude [cmd]', 'Claude workflow (init, sync, setup)'],
31
33
  ['wiki [cmd]', 'Wiki pages (init)'],
package/src/cli/ui.ts CHANGED
@@ -154,9 +154,8 @@ export function isNonInteractive(): boolean {
154
154
  }
155
155
 
156
156
  /**
157
- * `nonInteractiveDefault` opts a prompt into the `select_option` behavior from
158
- * `scripts/lib/ui.sh`, where `CANON_NON_INTERACTIVE=1` resolves to the first
159
- * option instead of failing. Callers that would rather fail loudly than pick
157
+ * `nonInteractiveDefault` opts a prompt into resolving to its first option
158
+ * under `CANON_NON_INTERACTIVE=1` instead of failing. Callers that would rather fail loudly than pick
160
159
  * for the user leave it off.
161
160
  */
162
161
  export async function select<Value>(opts: {
@@ -386,7 +386,7 @@ export function register(program: Command): void {
386
386
  skills
387
387
  .command('audit')
388
388
  .description(
389
- 'Report both skill corpora against the mechanical rules in standards/skill.md',
389
+ 'Report both skill corpora against the mechanical rules in claude/skills/create-skill/references/skill.md',
390
390
  )
391
391
  .argument('[path]', 'Project root, defaulting to the current directory')
392
392
  .helpOption('-h, --help', 'Show this help message')
@@ -12,7 +12,6 @@ import { checkoutMismatchWarning, PROJECT_ROOT } from '@/roots/project'
12
12
  import { creationRel, SCRATCH } from '@/roots/record'
13
13
  import { createGovAdapter } from '@/gov/adapter'
14
14
  import { regenConsumedRules } from '@/gov/consumed'
15
- import { regenStandardRules } from '@/gov/standard-rules'
16
15
  import { installRules, lookupRules } from '@/gov/install'
17
16
  import { buildGovCatalog, describeRule, describeStack } from '@/gov/list'
18
17
  import { buildRulesPayload, listRuleFiles } from '@/gov/payload'
@@ -191,18 +190,14 @@ export function register(program: Command): void {
191
190
 
192
191
  gov
193
192
  .command('regen')
194
- .description(
195
- "Rebuild the standard-pointer rules and a repository's own .claude/rules/",
196
- )
193
+ .description("Rebuild a repository's own .claude/rules/")
197
194
  .helpOption('-h, --help', 'Show this help message')
198
195
  .option('--root <path>', 'Repository root to regenerate', PROJECT_ROOT)
199
196
  .addHelpText(
200
197
  'after',
201
198
  [
202
199
  '',
203
- 'First writes governance/rules/standards/ from the paths: and rule:',
204
- 'fields in each standard under standards/. Then reads',
205
- 'internal/governance.toml and installs the stack it names, plus any',
200
+ 'Reads internal/governance.toml and installs the stack it names, plus any',
206
201
  'rules under internal/rules/. Unlike install and sync, this runs',
207
202
  'against the toolkit root, whose .claude/rules/ is produced output.',
208
203
  '',
@@ -1121,14 +1116,6 @@ async function runRegen(
1121
1116
 
1122
1117
  const root = resolve(opts.root ?? PROJECT_ROOT)
1123
1118
 
1124
- // The consumed copy installs from `governance/rules/`, so the band this
1125
- // writes has to be fresh before that copy is built from it.
1126
- const generated = await regenStandardRules(root)
1127
- if (!generated.ok) {
1128
- process.stderr.write(`Standard-rules regen failed: ${generated.reason}\n`)
1129
- return 1
1130
- }
1131
-
1132
1119
  const result = await regenConsumedRules(root)
1133
1120
 
1134
1121
  if (!result.ok) {