@erclx/canon 5.40.0 → 5.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +34 -17
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/api-design/references/adopted.md +34 -14
  4. package/claude/skills/auto-ship/REQUIREMENT.md +2 -0
  5. package/claude/skills/auto-ship/SKILL.md +28 -2
  6. package/claude/skills/auto-ship/references/draft-mark.md +32 -6
  7. package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
  8. package/claude/skills/auto-ship/references/fan-in.md +59 -0
  9. package/claude/skills/auto-ship/references/tier-failures.md +31 -10
  10. package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
  11. package/claude/skills/auto-ship/references/worktree-name.md +9 -3
  12. package/claude/skills/build-in-slices/references/adopted.md +35 -21
  13. package/claude/skills/canvas-board/references/canvas.md +17 -6
  14. package/claude/skills/canvas-board/references/design.md +26 -7
  15. package/claude/skills/code-craft/references/adopted.md +58 -20
  16. package/claude/skills/codebase-layout/references/adopted.md +49 -16
  17. package/claude/skills/codebase-layout/references/frontend.md +11 -4
  18. package/claude/skills/codebase-layout/references/tests.md +4 -2
  19. package/claude/skills/context-fold/references/classify.md +10 -15
  20. package/claude/skills/context-fold/references/completion-report.md +11 -9
  21. package/claude/skills/context-fold/references/context-refresh.md +26 -9
  22. package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
  23. package/claude/skills/create-rule/REQUIREMENT.md +5 -0
  24. package/claude/skills/create-rule/SKILL.md +9 -1
  25. package/claude/skills/create-rule/references/checklist.md +26 -0
  26. package/claude/skills/create-rule/references/rule.md +98 -20
  27. package/claude/skills/create-skill/SKILL.md +1 -0
  28. package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
  29. package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
  30. package/claude/skills/create-skill/references/skill-paths.md +7 -4
  31. package/claude/skills/create-skill/references/skill-practice.md +6 -3
  32. package/claude/skills/create-skill/references/skill-requirement.md +4 -2
  33. package/claude/skills/create-skill/references/skill.md +67 -44
  34. package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
  35. package/claude/skills/decision-escalate/SKILL.md +1 -2
  36. package/claude/skills/deploy-app/references/vercel.md +2 -1
  37. package/claude/skills/deprecation-migration/references/adopted.md +44 -25
  38. package/claude/skills/design-taste/references/adopted.md +9 -1
  39. package/claude/skills/design-taste/references/craft.md +3 -1
  40. package/claude/skills/design-taste/references/kinds.md +8 -7
  41. package/claude/skills/design-taste/references/preflight.md +12 -0
  42. package/claude/skills/design-taste/references/systems.md +7 -6
  43. package/claude/skills/design-taste/references/tells.md +24 -25
  44. package/claude/skills/design-taste/references/vocabulary.md +7 -5
  45. package/claude/skills/document-health/references/axes.md +54 -30
  46. package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
  47. package/claude/skills/draft-doc/references/context.md +4 -3
  48. package/claude/skills/draft-doc/references/docs.md +6 -3
  49. package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
  50. package/claude/skills/draft-doc/references/readme/application.md +8 -2
  51. package/claude/skills/draft-doc/references/readme/cli.md +5 -1
  52. package/claude/skills/draft-doc/references/readme/library.md +4 -0
  53. package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
  54. package/claude/skills/draft-doc/references/readme.md +30 -13
  55. package/claude/skills/draft-doc/references/requirements.md +17 -4
  56. package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
  57. package/claude/skills/draft-figure/references/architecture-set.md +7 -3
  58. package/claude/skills/draft-figure/references/figures.md +8 -6
  59. package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
  60. package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
  61. package/claude/skills/draft-figure/references/mermaid.md +10 -5
  62. package/claude/skills/draft-ready/references/ready.md +22 -15
  63. package/claude/skills/git-branch/REQUIREMENT.md +17 -6
  64. package/claude/skills/git-branch/SKILL.md +63 -7
  65. package/claude/skills/git-branch/references/branch.md +11 -1
  66. package/claude/skills/git-branch/references/slug.md +17 -5
  67. package/claude/skills/git-commit/references/commit.md +8 -0
  68. package/claude/skills/git-commit/references/versioning.md +23 -17
  69. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  70. package/claude/skills/git-followup/SKILL.md +5 -6
  71. package/claude/skills/git-issue/references/issue.md +29 -16
  72. package/claude/skills/git-pr/REQUIREMENT.md +1 -5
  73. package/claude/skills/git-pr/SKILL.md +11 -22
  74. package/claude/skills/git-pr/references/final-command.md +21 -8
  75. package/claude/skills/git-pr/references/labels.md +45 -28
  76. package/claude/skills/git-pr/references/pr.md +28 -9
  77. package/claude/skills/git-pr/references/publish.md +42 -28
  78. package/claude/skills/git-pr/references/task-number.md +20 -8
  79. package/claude/skills/git-ship/SKILL.md +1 -1
  80. package/claude/skills/plan-feature/references/batches.md +48 -1
  81. package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
  82. package/claude/skills/plan-feature/references/plan.md +59 -20
  83. package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
  84. package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
  85. package/claude/skills/plan-intake/references/intake.md +29 -24
  86. package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
  87. package/claude/skills/plan-intake-answer/SKILL.md +1 -2
  88. package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
  89. package/claude/skills/pr-evidence/SKILL.md +53 -0
  90. package/claude/skills/pr-evidence/references/evidence.md +150 -0
  91. package/claude/skills/review-address/references/post-review-findings.md +10 -3
  92. package/claude/skills/review-address/references/rebase-conflicts.md +22 -7
  93. package/claude/skills/review-address/references/rest-reads.md +3 -1
  94. package/claude/skills/review-craft/references/adopted.md +35 -18
  95. package/claude/skills/review-craft/references/security.md +42 -7
  96. package/claude/skills/review-craft/references/ui.md +23 -8
  97. package/claude/skills/review-pr/SKILL.md +6 -6
  98. package/claude/skills/review-pr/references/body-variants.md +29 -9
  99. package/claude/skills/review-pr/references/close-out.md +20 -5
  100. package/claude/skills/review-pr/references/key-changes.md +27 -3
  101. package/claude/skills/review-pr/references/post.md +83 -31
  102. package/claude/skills/review-pr/references/scope.md +54 -19
  103. package/claude/skills/review-ui/SKILL.md +2 -0
  104. package/claude/skills/review-ui/references/close-out.md +49 -0
  105. package/claude/skills/review-ui/references/driving.md +24 -4
  106. package/claude/skills/review-ui/references/post.md +43 -13
  107. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
  108. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +81 -40
  109. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
  110. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
  111. package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
  112. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
  113. package/claude/skills/role-orchestrator/references/orchestrator-output.md +12 -4
  114. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
  115. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
  116. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
  117. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
  118. package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
  119. package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
  120. package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
  121. package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
  122. package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
  123. package/claude/skills/role-worker/REQUIREMENT.md +2 -0
  124. package/claude/skills/role-worker/SKILL.md +17 -0
  125. package/claude/skills/search-craft/references/adopted.md +18 -6
  126. package/claude/skills/session-map/references/session.md +26 -7
  127. package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
  128. package/claude/skills/systematic-debugging/references/adopted.md +30 -16
  129. package/claude/skills/target-check/references/domains.md +39 -11
  130. package/claude/skills/target-setup/references/detect.md +80 -65
  131. package/claude/skills/target-setup/references/indexes.md +8 -6
  132. package/claude/skills/task-board/references/board.md +86 -30
  133. package/claude/skills/task-board/references/decline.md +29 -13
  134. package/claude/skills/task-board/references/tasks-decline.md +12 -5
  135. package/claude/skills/task-board/references/tasks.md +65 -33
  136. package/claude/skills/task-complete/references/archive.md +41 -17
  137. package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
  138. package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
  139. package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
  140. package/claude/skills/teach-workspace/SKILL.md +1 -2
  141. package/claude/skills/teach-workspace/references/glossary.md +6 -2
  142. package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
  143. package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
  144. package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
  145. package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
  146. package/claude/skills/teach-workspace/references/promotion.md +31 -8
  147. package/claude/skills/teach-workspace/references/revisit.md +8 -2
  148. package/claude/skills/teach-workspace/references/teach.md +17 -9
  149. package/claude/skills/test-craft/references/adopted.md +48 -14
  150. package/claude/skills/test-craft/references/component.md +7 -4
  151. package/claude/skills/test-craft/references/e2e.md +25 -7
  152. package/claude/skills/test-craft/references/unit.md +3 -1
  153. package/claude/skills/test-first/references/adopted.md +12 -4
  154. package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
  155. package/claude/skills/ui-checklist/SKILL.md +1 -1
  156. package/claude/skills/video-craft/references/adopted.md +62 -18
  157. package/claude/skills/write-human/references/adopted.md +21 -8
  158. package/docs/workflow/parallel-features.md +2 -1
  159. package/docs/workflow/skill-map.md +2 -1
  160. package/package.json +1 -1
  161. package/src/claude/cases/git.ts +4 -0
  162. package/src/claude/cases/workflow.ts +5 -0
  163. package/src/commands/pr.ts +174 -37
  164. package/src/commands/records.ts +11 -3
  165. package/src/context/shape-gated.ts +1 -0
  166. package/src/markdown/scope.ts +150 -2
  167. package/src/pr/frames.ts +53 -9
  168. package/src/pr/lift.ts +6 -3
  169. package/src/pr/review-state.ts +182 -0
  170. package/src/records/validate.ts +1 -0
  171. package/src/tasks/answers.ts +79 -2
  172. package/src/tasks/fan-in.ts +176 -0
  173. package/src/tasks/stack.ts +1 -1
  174. package/tooling/astro/reference.md +80 -39
  175. package/tooling/base/reference.md +63 -32
  176. package/tooling/base/seeds/canon/context/ci.md +7 -15
  177. package/tooling/base/seeds/canon/context/development.md +14 -14
  178. package/tooling/claude/reference.md +40 -22
  179. package/tooling/cloudflare/reference.md +31 -12
  180. package/tooling/go/reference.md +47 -23
  181. package/tooling/nextjs/reference.md +52 -19
  182. package/tooling/php/reference.md +35 -16
  183. package/tooling/python/reference.md +47 -30
  184. package/tooling/shell/reference.md +6 -5
  185. package/tooling/vite-react/reference.md +49 -21
  186. package/tooling/web/reference.md +130 -70
  187. package/claude/skills/git-pr/references/evidence.md +0 -124
@@ -20,7 +20,8 @@ Does not govern:
20
20
 
21
21
  - The problem being solved and for whom, as the record's opening line under the title
22
22
  - User-facing goals stated as outcomes, not implementation
23
- - Explicit non-goals that prevent feature creep. Mark deferred items "(deferred)" so they read as paused, not excluded. A non-goal resting on how an outside tool, an installer, or the model behaves may close with one `Revisit when <finding>.` sentence, and a non-goal resting on scope alone takes none.
23
+ - Explicit non-goals that prevent feature creep. Mark deferred items "(deferred)" so they read as paused, not excluded.
24
+ - A non-goal resting on how an outside tool, an installer, or the model behaves may close with one `Revisit when <finding>.` sentence. One resting on scope alone takes none.
24
25
  - Hard constraints that shape every decision, when the project has any
25
26
 
26
27
  ## What does not go in
@@ -32,17 +33,29 @@ Does not govern:
32
33
 
33
34
  ## Sections
34
35
 
35
- Require `## Goals` and `## Non-goals`. Add `## Constraints` when the project holds hard limits that shape every decision. Add `## Worldview` when the project holds beliefs that shape every decision, and keep a belief there only when it changes a decision, since a padded worldview turns into a second goals list. Drop a section rather than pad it with filler.
36
+ Require `## Goals` and `## Non-goals`, and drop any other section rather than pad it with filler.
37
+
38
+ - Add `## Constraints` when the project holds hard limits that shape every decision
39
+ - Add `## Worldview` when the project holds beliefs that shape every decision
40
+ - Keep a belief there only when it changes a decision, since a padded worldview turns into a second goals list
36
41
 
37
42
  ## Length
38
43
 
39
- This file loads into every session, so its weight is paid before any work starts. Cap it by stating the clause `This record holds at most <n> words.` in the record itself, where a checker reads it and counts every word below the frontmatter. The cap is the record's own, so a record stating none is measured and never gated. The template and the seed a new project installs state it at 600, and a project loosens it by editing the number in its own record. At the cap, cut a goal or a constraint that no longer changes a decision before adding one.
44
+ This file loads into every session, so its weight is paid before any work starts. Cap it by stating the clause `This record holds at most <n> words.` in the record itself, where a checker reads it and counts every word below the frontmatter.
45
+
46
+ - The cap is the record's own, so a record stating none is measured and never gated
47
+ - The template and the seed a new project installs state 600, and a project loosens it by editing the number in its own record
48
+ - At the cap, cut a goal or a constraint that no longer changes a decision before adding one
40
49
 
41
50
  ## Lifecycle
42
51
 
43
52
  The record may carry an optional `reviewed: YYYY-MM-DD` frontmatter field naming the day someone last read it whole for identity drift. Whoever finishes that review sets it as the review's last edit, and `canon records stale canonical` reads it to count the releases shipped since. A record with no field reads as never reviewed.
44
53
 
45
- Later scope arrives as a new section rather than as an extension of the goals. Name the section for what it delivers and state its entries as outcomes, the same way the goals are stated. Once every entry in it has shipped, delete the section, since version history keeps the old text and the document states the project as it stands. Nothing sequences a section into versions. Work reaches the board as discrete tasks under `tasks.md`, and `board.md` orders them by readiness, so a section here states what is wanted and never when it lands.
54
+ Later scope arrives as a new section rather than as an extension of the goals. Name it for what it delivers and state its entries as outcomes, the same way the goals are stated.
55
+
56
+ - Once every entry in it has shipped, delete the section, since version history keeps the old text and the document states the project as it stands
57
+ - Nothing sequences a section into versions. Work reaches the board as discrete tasks under `tasks.md`, and `board.md` orders them by readiness.
58
+ - A section states what is wanted and never when it lands
46
59
 
47
60
  ## Template
48
61
 
@@ -11,35 +11,43 @@ The standard's `## Placement` section names the folder a page lands in and the v
11
11
 
12
12
  ## Guards
13
13
 
14
- - If `<wiki-root>` does not resolve, say so and ask whether to create it before drafting. A project carrying no such folder has never taken the standard's placement rule, so creating it is a decision rather than a step.
14
+ If `<wiki-root>` does not resolve, say so and ask whether to create it before drafting. A project carrying no such folder has never taken the standard's placement rule, so creating it is a decision rather than a step.
15
15
 
16
16
  ## Placement
17
17
 
18
18
  The standard sets two tests and a page has to pass both. Run them before drafting anything, since a page failing either is non-conforming however well it is written.
19
19
 
20
- - **Owned outside this repository.** A subject describing how this repository works fails. Refuse and offer the docs or context kind of this skill: `❌ <subject> is owned by this project, so it belongs in the docs surface or a context entry. Re-run draft-doc naming that destination.`
21
- - **Owned by the vendor the folder split covers.** The standard names one owner and one subfolder. A third-party tool or a vendor-neutral concept fails, however reference-like it reads. Refuse: `❌ <subject> is outside the wiki's folder split. Route it to the docs surface or a skill body rather than adding a second folder for it.`
20
+ | Test | Fails on | Refusal |
21
+ | ------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
22
+ | Owned outside this repository | A subject describing how this repository works | `❌ <subject> is owned by this project, so it belongs in the docs surface or a context entry. Re-run draft-doc naming that destination.` |
23
+ | Owned by the vendor the folder split covers | A third-party tool or a vendor-neutral concept, however reference-like it reads | `❌ <subject> is outside the wiki's folder split. Route it to the docs surface or a skill body rather than adding a second folder for it.` |
24
+
25
+ On the first test, offer the docs or context kind of this skill. The standard names one owner and one subfolder for the second.
22
26
 
23
27
  Do not widen the split to admit a subject. Adding a sibling folder is a change to the standard, argued there, rather than a placement this kind takes on its own.
24
28
 
25
29
  ## Collision
26
30
 
27
- - Derive the page slug per the standard's `## Naming` section and check whether `<wiki-root>/<vendor>/<slug>.md` already exists. If it does, stop: `❌ <path> already covers this subject. Edit that page against the standard instead of drafting a second one.`
28
- - Read `<wiki-root>/<vendor>/index.md` and check every title and description it lists against the subject. Stop on a match: `❌ <path> already covers this subject under a different name. Edit that page instead.`
31
+ - Derive the page slug per the standard's `## Naming` section and check whether `<wiki-root>/<vendor>/<slug>.md` already exists
32
+ - If it does, stop: `❌ <path> already covers this subject. Edit that page against the standard instead of drafting a second one.`
33
+ - Read `<wiki-root>/<vendor>/index.md` and check every title and description it lists against the subject
34
+ - Stop on a match: `❌ <path> already covers this subject under a different name. Edit that page instead.`
29
35
 
30
36
  ## Source
31
37
 
32
38
  The standard forbids working from training knowledge, so the draft is built on a read rather than on recall.
33
39
 
34
- - Fetch current information through the `claude-code-guide` agent for any subject that agent covers. Its answer is the source the page is written from.
35
- - Reach a subject the agent does not cover through the owner's own published documentation. Invoke `canon:search-craft` with the skill tool before searching for it, since finding the owner's documentation is the field-and-authority step that skill carries, and report it rather than proceeding silently when the skill does not resolve.
40
+ Fetch current information through the `claude-code-guide` agent for any subject that agent covers, and write from its answer. Reach any other subject through the owner's own published documentation.
41
+
42
+ - Invoke `canon:search-craft` with the skill tool before that search, since finding the owner's documentation is its field-and-authority step. Report it when it does not resolve.
36
43
  - Say the fetch failed and stop rather than substituting recall, even for a subject the session believes it knows. A page sourced from memory ships looking identical to one that was checked.
37
- - Close the intro with the `Source:` sentence the standard requires, linking the canonical page where one exists and naming the owner alone where the subject has no single URL.
44
+ - Close the intro with the `Source:` sentence the standard requires, linking the canonical page, or naming the owner alone where the subject has no single URL
38
45
  - Stamp the read date on a source revised without notice, as `read <date>`. A claim traced to an undated read cannot be checked against what was actually read.
39
46
 
40
47
  ## Draft
41
48
 
42
- - Draft `title` and `description` frontmatter against the standard's contract, then the intro paragraph closing on `Source:` as a short orientation, then the lesson sections. Let the read of the source decide what is a lesson: keep a fact only when the source page does not state it, and leave reference detail to the source.
49
+ - Draft `title` and `description` frontmatter against the standard's contract, then the intro paragraph closing on `Source:` as a short orientation, then the lesson sections
50
+ - Let the read of the source decide what is a lesson. Keep a fact only when the source page does not state it, and leave reference detail to the source.
43
51
  - Write what the fetch returned rather than what the subject is assumed to do.
44
52
  - Answer one question per section and stop. A reader arrives to settle something specific rather than to read the page through.
45
53
  - Mark a claim the fetch left unsettled rather than smoothing over it. An unmarked gap reads as a checked fact.
@@ -50,4 +58,6 @@ Add `**Source:** <owner, and the read it came from>`, and confirm the source wit
50
58
 
51
59
  ## Write
52
60
 
53
- Regenerate `<wiki-root>/<vendor>`, naming the folder the page landed in rather than the root above it. The verb rewrites the `index.md` in the folder it is given and does not walk down, so regenerating at the root leaves the vendor catalog untouched. A page absent there is invisible to the next run's Collision step, which then drafts a second page on the same subject.
61
+ Regenerate `<wiki-root>/<vendor>`, naming the folder the page landed in rather than the root above it. The verb rewrites the `index.md` in the folder it is given and does not walk down, so regenerating at the root leaves the vendor catalog untouched.
62
+
63
+ A page absent from that catalog is invisible to the next run's Collision step, which then drafts a second page on the same subject.
@@ -25,11 +25,15 @@ Stay inside `flowchart` and `sequenceDiagram`. C4, state, ER, and class diagrams
25
25
 
26
26
  ## Sources
27
27
 
28
- - Read `canon/REQUIREMENTS.md`, `canon/context/index.md`, `CLAUDE.md`, and the language manifest (`package.json`, `pyproject.toml`, `Cargo.toml`) when present, plus the top-level folder layout through `ls`. Do not recurse speculatively.
28
+ - Read `canon/REQUIREMENTS.md`, `canon/context/index.md`, `CLAUDE.md`, and the language manifest (`package.json`, `pyproject.toml`, `Cargo.toml`) when present
29
+ - Read the top-level folder layout through `ls`, and do not recurse speculatively
29
30
  - When neither planning file exists and no folder structure names a boundary, stop: `❌ No source signal for <view>. Add canon/REQUIREMENTS.md or run inside a project folder.`
30
31
  - When the view came from a code scan rather than planning prose, open the caption with `Source: code.` and add `Fidelity is lower than prose-driven figures. Verify against the project's intent.`
31
32
 
32
33
  ## Caption and prose
33
34
 
34
- - Name one or two code paths a reader can open, in the caption or the prose beside the figure. Cite only paths that exist and spell each one exactly, since a reader deciding whether the figure still holds starts by opening them.
35
- - Keep implementation detail out of the figure: function names and call signatures, library versions, config keys and environment variable names, retry counts and timeouts, and workarounds needing more than a sentence. That detail belongs in a `canon/context/` entry, which the caption points at by path when a reader needs the mechanism.
35
+ Name one or two code paths a reader can open, in the caption or the prose beside the figure. Cite only paths that exist and spell each one exactly, since a reader deciding whether the figure still holds starts by opening them.
36
+
37
+ - Keep implementation detail out of the figure, being function names and call signatures, library versions, config keys and environment variable names, retry counts and timeouts
38
+ - A workaround needing more than a sentence stays out too
39
+ - That detail belongs in a `canon/context/` entry, which the caption points at by path when a reader needs the mechanism
@@ -9,7 +9,7 @@ Applies to every hand-drawn figure, wherever it is authored. A figure sits insid
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs a hand-drawn figure wherever one is authored, naming no path because an attribute standard governs a fragment rather than a document type: when it earns its place, the render-first policy routing a graph-shaped subject through Mermaid, the wrapping and caption every figure carries, and its color and accessibility rules. It carries no template, since a figure has no document shape of its own and sits inside one another standard sets.
12
+ Governs a hand-drawn figure wherever one is authored, being when it earns its place, the render-first policy routing a graph-shaped subject through Mermaid, the wrapping and caption every figure carries, and its color and accessibility rules. It names no path and carries no template, since it governs a fragment rather than a document type.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -35,10 +35,12 @@ A figure failing these is non-conforming even when it satisfies every shape rule
35
35
 
36
36
  ## The render-first policy
37
37
 
38
- - Route a graph-shaped subject, one whose relationship, boundary, or path a flowchart already expresses, through Mermaid's own hand-drawn look rather than through model-authored SVG coordinates. `mermaid.md` governs the fence itself.
39
- - Reserve freehand inline SVG, plain shapes and lines authored directly in the markup, for a subject that is not graph-shaped. A figure that cannot express its subject through the deterministic path is a worse failure than an inconsistent one drawn by hand, so the hatch stays open rather than forcing every figure through the renderer.
40
- - Draw a figure in a teach lesson freehand whatever its shape. A lesson letters its figures in a hand font the renderer cannot load, so Mermaid measures every label in a narrower fallback face, and the page then clips the wider text it actually shows.
41
- - State this as a render-first policy rather than a ban on a tool-exported drawing. Routing a graph-shaped figure through Mermaid is itself running it through an external tool, so a rule banning any diagram "exported from a diagramming tool" would forbid the path this policy requires.
38
+ Route a graph-shaped subject, one whose relationship, boundary, or path a flowchart already expresses, through Mermaid's own hand-drawn look rather than through model-authored SVG coordinates. `mermaid.md` governs the fence itself.
39
+
40
+ - Reserve freehand inline SVG, plain shapes and lines authored in the markup, for a subject that is not graph-shaped
41
+ - A figure that cannot express its subject through the deterministic path is a worse failure than an inconsistent hand-drawn one, so the hatch stays open
42
+ - Draw a figure in a teach lesson freehand whatever its shape. Its hand font cannot load in the renderer, so Mermaid measures labels in a narrower fallback face and the page clips them.
43
+ - State this as a render-first policy rather than a ban on a tool-exported drawing, since routing through Mermaid is itself running an external tool
42
44
 
43
45
  ## Wrapping and captioning
44
46
 
@@ -47,5 +49,5 @@ A figure failing these is non-conforming even when it satisfies every shape rule
47
49
 
48
50
  ## Color and accessibility
49
51
 
50
- - Color every fill and stroke through a custom property the surrounding document's own stylesheet defines, never a literal hex value. The figure then re-colors itself on the same switch that re-colors the page.
52
+ - Color every fill and stroke through a custom property the surrounding document's stylesheet defines, never a literal hex value, so the figure re-colors on the switch that re-colors the page
51
53
  - Give the drawing an accessible name: `role="img"` with `aria-label` for one short line, or `aria-labelledby` pointing at a `<title>` element inside it for a longer one.
@@ -12,7 +12,9 @@ description: Authoring a freehand SVG, its color and accessibility audit, and th
12
12
  - Author the SVG by hand: plain shapes and lines authored directly in the markup.
13
13
  - Follow the `## Color and accessibility` section of `${CLAUDE_SKILL_DIR}/references/figures.md` for every fill, stroke, and accessible name.
14
14
 
15
- There is no external render to verify a freehand drawing against before it is written. The check here is the stroke-and-fill audit above and a read of the markup against what the subject means to show, done once rather than looped. Hand-placed coordinates can drift out of line where a layout engine would not, so a freehand figure bound for a rendered page also takes the in-page capture below.
15
+ There is no external render to verify a freehand drawing against before it is written. The check is the stroke-and-fill audit above and one read of the markup against what the subject means to show, done once rather than looped.
16
+
17
+ Hand-placed coordinates can drift out of line where a layout engine would not, so a freehand figure bound for a rendered page also takes the in-page capture below.
16
18
 
17
19
  ## Capture in the page
18
20
 
@@ -9,8 +9,11 @@ description: The hand-drawn render config, the SVG and PNG pair, the hex rewrite
9
9
 
10
10
  ## Draft the fence
11
11
 
12
- - Draft the fence against `${CLAUDE_SKILL_DIR}/references/mermaid.md` for direction, node and edge budgets, `accTitle` and `accDescr`, and quoted labels. Do not work the layout or the budgets from memory.
13
- - Read every node and subgraph label against the banned characters `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` lists. The audit hook skips every line inside a fence, so a label carrying a banned character passes silently while the same character in the caption is caught. Reading the labels is the only gate they have. A colon works as a replacement inside a label.
12
+ Draft the fence against `${CLAUDE_SKILL_DIR}/references/mermaid.md` for direction, node and edge budgets, `accTitle` and `accDescr`, and quoted labels. Do not work the layout or the budgets from memory.
13
+
14
+ - Read every node and subgraph label against the banned characters `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` lists
15
+ - The audit hook skips every line inside a fence, so a banned character in a label passes silently while the same one in the caption is caught. Reading the labels is their only gate.
16
+ - A colon works as a replacement inside a label
14
17
 
15
18
  ## Render
16
19
 
@@ -25,9 +28,9 @@ bunx -y @mermaid-js/mermaid-cli -i .canon/tmp/figures/<slug>.mmd -o .canon/tmp/f
25
28
  bunx -y @mermaid-js/mermaid-cli -i .canon/tmp/figures/<slug>.mmd -o .canon/tmp/figures/<slug>.png -c .canon/tmp/figures/<slug>.json
26
29
  ```
27
30
 
28
- Render both formats in one pass. The SVG is what ships inside the `<figure>`, and the PNG is what the read-back below judges, since an SVG's markup carries no recoverable spatial meaning.
31
+ Render both formats in one pass. The SVG ships inside the `<figure>`, and the PNG is what the read-back below judges, since an SVG's markup carries no recoverable spatial meaning.
29
32
 
30
- Use `bunx` when bun is available, falling back to `npx -y @mermaid-js/mermaid-cli ...` otherwise.
33
+ - Use `bunx` when bun is available, falling back to `npx -y @mermaid-js/mermaid-cli ...` otherwise
31
34
 
32
35
  Before the first render in a project, say what is about to block:
33
36
 
@@ -42,14 +45,21 @@ Rewrite every stroke, fill, and text color the renderer wrote as a literal hex v
42
45
  ## Clipped titles
43
46
 
44
47
  - Expect a group title or a long label to clip once the destination shows it in the hand font, since the renderer sized its box in a fallback face.
45
- - When the in-page check shows a clipped title, add a `<style>` inside the SVG, scoped to that SVG's own id, that sets `overflow: visible` on the clipped label's `foreignObject` and centers the label within it, so the wider text spills past both edges evenly. The style hides the mismatch for a title and does nothing for a node label crowding its box, which takes a shorter label instead.
48
+ - When the in-page check shows a clipped title, add a `<style>` inside the SVG, scoped to that SVG's own id
49
+ - The style sets `overflow: visible` on the clipped label's `foreignObject` and centers the label within it, so the wider text spills past both edges evenly
50
+ - It does nothing for a node label crowding its box, which takes a shorter label instead
46
51
 
47
52
  ## Fonts
48
53
 
49
- Check whether the project ran `canon design css --figures`. The figure and figcaption styling ships unconditionally either way, but that flag alone embeds the Virgil and Excalifont font files. Without it, the figure falls back to the browser's own generic `cursive` face rather than the intended hand-drawn font, and the output names that gap when the flag was not passed.
54
+ Check whether the project ran `canon design css --figures`. The figure and figcaption styling ships either way, but that flag alone embeds the Virgil and Excalifont font files.
55
+
56
+ Without it, the figure falls back to the browser's generic `cursive` face rather than the hand-drawn font, and the output names that gap.
50
57
 
51
58
  ## Read the render back
52
59
 
53
- - Read the rendered PNG and judge it against what the figure means to say, applying the verification properties in the mermaid standard. A source satisfying every rule there can still render as a picture asserting something false, so the image is what gets judged.
54
- - Fix the Mermaid source and re-render on a defect. Stop after two correction passes. When a defect survives, keep the figure and name the defect in the output rather than reporting a false verification.
55
- - When the render fails for any reason, no browser engine, no network, no package manager, continue to the confirm step and name the skipped check. A missing renderer degrades the loop rather than failing it.
60
+ Read the rendered PNG and judge it against what the figure means to say, applying the verification properties in the mermaid standard. A source satisfying every rule there can still render as a picture asserting something false, so the image is what gets judged.
61
+
62
+ - Fix the Mermaid source and re-render on a defect, stopping after two correction passes
63
+ - When a defect survives, keep the figure and name the defect in the output rather than reporting a false verification
64
+ - When the render fails for any reason, such as no browser engine, network, or package manager, continue to the confirm step and name the skipped check
65
+ - A missing renderer degrades the loop rather than failing it
@@ -9,7 +9,7 @@ Applies to every Mermaid fence, wherever it is written. A fence sits inside a do
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs the Mermaid attribute wherever a fence is written, naming no path because an attribute standard governs a drawing rather than a document type: direction and layout, node and edge budgets, the accessibility fields, how punctuation reaches a label, and how a rendered diagram is verified. It carries no template, since a fence has no document shape of its own and sits inside one another standard sets.
12
+ Governs the Mermaid attribute wherever a fence is written, being direction and layout, node and edge budgets, the accessibility fields, how punctuation reaches a label, and how a rendered diagram is verified. It names no path and carries no template, since it governs a drawing rather than a document type.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -31,17 +31,21 @@ A diagram failing these is non-conforming even when it satisfies every shape rul
31
31
 
32
32
  ## Layout
33
33
 
34
- - Declare `flowchart TB` by default. Mermaid ignores a subgraph's direction whenever that subgraph links outward, and an architecture diagram links across its subgraphs as the normal case, so top-bottom is a declaration rather than a guarantee.
34
+ - Declare `flowchart TB` by default. Mermaid ignores a subgraph's direction when it links outward, as an architecture diagram normally does, so top-bottom is a declaration, not a guarantee.
35
35
  - Restructure a diagram that renders diagonal or left-to-right. Repeating the direction keyword does not fix it.
36
36
  - Render a context, component, or pipeline diagram taller than wide. A `sequenceDiagram` is wide by construction and is exempt.
37
37
 
38
38
  ### Rows and edges
39
39
 
40
+ A row or a bundle asserts something about the system, so each is drawn only where it is true.
41
+
40
42
  - Do not let independent nodes render in a row. A row of siblings reads as a sequential chain and asserts a pipeline the system does not have.
41
43
  - Do not converge many edges on one node from one side. A crossing bundle is unreadable whatever it encodes.
42
44
 
43
45
  ### Labels and subgraphs
44
46
 
47
+ A label names a node, and the paragraph below the diagram carries the detail.
48
+
45
49
  - Keep node labels short. Three or four words max. Detail goes in the paragraph below the diagram.
46
50
  - Use `<br/>` for a second short line on a node when the label is two ideas, never for a sentence.
47
51
  - Subgraphs are for grouping unrelated lanes such as offline versus online or browser versus server. Do not subgraph a single linear flow.
@@ -51,12 +55,13 @@ A diagram failing these is non-conforming even when it satisfies every shape rul
51
55
  - Hold a diagram to roughly 5 to 10 nodes. Split it past 15.
52
56
  - Watch edge count harder than node count. It binds first, and a diagram whose edges outnumber its nodes is already too dense to read.
53
57
  - Treat a diagram that cannot be described in one sentence as two diagrams.
54
- - Warn rather than refuse on a budget, and name the split that would fix it. These numbers come from published Mermaid practice rather than from a measurement against a corpus, so a hard refusal on them will be wrong sometimes and unarguable when it is.
58
+ - Warn rather than refuse on a budget, and name the split that would fix it
59
+ - These numbers come from published Mermaid practice rather than a measurement, so a hard refusal on them would be wrong sometimes and unarguable when it is
55
60
 
56
61
  ## Labels
57
62
 
58
- - Apply the punctuation bans in `markdown.md` to node and subgraph labels. A label is not prose, so a check scoped to prose does not reach it, and reading the labels before shipping is the only gate they have.
59
- - Treat the prose around a fence and the text inside it as two surfaces. The paragraphs are prose and follow `markdown.md` and the `write-human` skill. The fenced block is not, which is why a check scoped to prose is the wrong thing to rely on for what sits inside it.
63
+ - Apply the punctuation bans in `markdown.md` to node and subgraph labels. A check scoped to prose does not reach a label, so reading the labels before shipping is their only gate.
64
+ - Treat the prose around a fence and the text inside it as two surfaces. The paragraphs follow `markdown.md` and the `write-human` skill, and a prose check does not reach the fenced block.
60
65
 
61
66
  ## Accessibility
62
67
 
@@ -5,9 +5,13 @@ description: Folder layout, ordinal naming, the overview frontmatter, the thin-p
5
5
 
6
6
  # Ready reference
7
7
 
8
- Applies to a ready folder at `.canon/ready/<nn>-<slug>/`. A warm session that has already written a skill, a rule, or another finished file uses it to hand the exact text to the worker that ships it, since a plan only describes a change and a cold worker reading a description writes the file again from scratch. The folder holds the finished files themselves, laid out at their destination paths, so the worker's job is to copy rather than to author.
8
+ Applies to a ready folder at `.canon/ready/<nn>-<slug>/`. A warm session that has already written a finished file uses it to hand the exact text to the worker that ships it, since a cold worker reading a plan's description writes the file again from scratch.
9
9
 
10
- The folder is gitignored, and backed wherever a records remote is configured: `canon records push` and `canon records pull` protect it against the machine being lost there, refuse with `no-remote` where it is not, and protect nothing against a folder deleted before anyone has pushed. That is why the archive step below is a move rather than a cleanup.
10
+ The folder holds the finished files at their destination paths, so the worker copies rather than authors. It is gitignored, which is why the archive step below is a move rather than a cleanup.
11
+
12
+ - Where a records remote is configured, `canon records push` and `canon records pull` protect it against the machine being lost
13
+ - Where none is, they refuse with `no-remote`
14
+ - Neither protects a folder deleted before anyone has pushed
11
15
 
12
16
  ## Contents
13
17
 
@@ -23,9 +27,7 @@ The folder is gitignored, and backed wherever a records remote is configured: `c
23
27
 
24
28
  ## Scope
25
29
 
26
- The `draft-ready` skill owns the procedure that writes a ready folder, and this standard owns the shape it writes to.
27
-
28
- Governs a ready folder under `.canon/ready/<nn>-<slug>/`: folder layout, ordinal naming, the overview's frontmatter, what the mirrored tree holds, the thin-plan contract that ships it, and the lifecycle from the live folder to the archive.
30
+ The `draft-ready` skill owns the procedure, and this standard owns the shape. It governs a ready folder under `.canon/ready/<nn>-<slug>/`, being its layout, ordinal naming, the overview's frontmatter, what the mirrored tree holds, the thin-plan contract that ships it, and the lifecycle from the live folder to the archive.
29
31
 
30
32
  Does not govern:
31
33
 
@@ -49,8 +51,9 @@ A ready folder failing these is non-conforming even when it satisfies every shap
49
51
  ## Folder name
50
52
 
51
53
  - Name the folder `<nn>-<slug>`, a two-digit zero-padded ordinal followed by a kebab-case slug matching the plan's own slug.
52
- - The ordinal marks a folder per handoff, opened once by the warm session that writes it. It runs on its own sequence, separate from groundwork and intake's shared one, since a ready folder is not a measurement track.
53
- - With no folder holding an entry yet, the first one opened takes `01`. Read the highest existing `.canon/ready/<nn>-*/` folder, including the archive, and take the next integer.
54
+ - The ordinal marks a folder per handoff, opened once by the warm session that writes it
55
+ - It runs on its own sequence, separate from groundwork and intake's shared one, since a ready folder is not a measurement track
56
+ - The first folder opened takes `01`. After that, read the highest existing `.canon/ready/<nn>-*/` folder, including the archive, and take the next integer.
54
57
  - Never renumber an existing folder. The ordinal is the order it opened, and the pull request that shipped it cites the folder by that name.
55
58
 
56
59
  ## 00-overview.md
@@ -76,29 +79,33 @@ Below the frontmatter, state in prose what the worker still owns beyond copying
76
79
 
77
80
  ## The mirrored tree
78
81
 
79
- - Every other file in the folder sits at the same relative path its destination has in the project, so `standards/ready.md` inside the destination tree sits at `<nn>-<slug>/standards/ready.md` inside the ready folder. <!-- canon-allow-reference: the example shows a target tree, where the standard sits under standards/ -->
80
- - Carry no file the destination tree would not carry. A ready folder is a source for `git mv`-shaped copies, not a scratch pad for the warm session's own notes. Anything else belongs in the plan or in the pull request body.
81
- - Write each file exactly as it should land. The worker copies verbatim and edits only what the gate or the overview's own list requires, so a placeholder or a half-finished passage ships as written.
82
+ Every other file in the folder sits at the same relative path its destination has in the project.
83
+
84
+ - For example, `standards/ready.md` in the destination tree sits at `<nn>-<slug>/standards/ready.md` in the ready folder <!-- canon-allow-reference: a target tree -->
85
+ - Carry no file the destination tree would not carry. The folder is a source for `git mv`-shaped copies, never a scratch pad, and anything else goes in the plan or the pull request body.
86
+ - Write each file exactly as it should land. The worker copies verbatim and edits only what the gate or the overview's list requires, so a placeholder ships as written.
82
87
 
83
88
  ## The thin-plan contract
84
89
 
85
90
  - A ready folder ships through an ordinary task row and a plan at `.canon/plans/feature-<slug>.md`, per `plan.md`. No new plan shape exists for it.
86
91
  - Name the ready folder in the plan's `**Constraints:**`, stating that the folder's files are the verbatim source for the paths the plan's `**Files to touch:**` lists.
87
- - List every destination path in `**Files to touch:**`, matching `00-overview.md`'s `destinations` field. A path the plan omits is invisible to `plan-reach`'s collision check, so a mismatch between the two lists is a defect in the plan rather than a variant the standard permits.
88
- - Keep the plan itself thin. Its `**Files to touch:**` entries may point at the ready folder's own copy for the reason behind each file rather than restating it, since the overview and the files already carry the detail a plan would otherwise duplicate.
92
+ - List every destination path in `**Files to touch:**`, matching `00-overview.md`'s `destinations` field
93
+ - A path the plan omits is invisible to `plan-reach`'s collision check, so a mismatch between the two lists is a defect in the plan, not a variant
94
+ - Keep the plan thin. Its `**Files to touch:**` entries may point at the folder's copy for the reason behind each file, since the overview and the files carry that detail.
89
95
 
90
96
  ## Lifecycle
91
97
 
92
98
  - Write the ready folder in the same session that writes the files it carries. A folder assembled later from memory is a plan with extra steps, not a handoff.
93
- - Leave the move to `canon tasks archive`, which carries the folder to `.canon/ready/archive/<nn>-<slug>/` with its plan when the task that shipped it archives, and retargets the task's `Ready:` line. A plan another live task still cites keeps its folder.
99
+ - Leave the move to `canon tasks archive`, which carries the folder to `.canon/ready/archive/<nn>-<slug>/` with its plan when the shipping task archives, retargeting its `Ready:` line
100
+ - A plan another live task still cites keeps its folder
94
101
  - Never delete a ready folder. The archived copy sits beside the merged pull request as the exact text that shipped, the way an archived plan sits beside the reasoning that produced it.
95
102
 
96
103
  ## Anti-patterns
97
104
 
98
- - **The folder with an undeclared destination.** A file the plan's `**Files to touch:**` does not list passes the collision check unseen, and a second track can write the same path without either side finding out.
105
+ - **The folder with an undeclared destination.** A file the plan's `**Files to touch:**` omits passes the collision check unseen, so a second track can write the same path with neither side finding out.
99
106
  - **The rewritten copy.** A worker that reads the folder's files as inspiration and writes its own version loses the exact text the handoff exists to carry.
100
107
  - **The folder as scratch.** Notes, alternates, or draft passages left in the folder beside the real files leave the worker guessing which is the source.
101
- - **The folder left live after shipping.** A ready folder the archive verb did not move reads as unshipped work to the next session that lists the live folder. The verb skips one whose task carries no `Ready:` line and cites no folder path in its plan.
108
+ - **The folder left live after shipping.** An unmoved folder reads as unshipped work to the next session listing it. The verb skips one whose task has no `Ready:` line and whose plan cites no folder.
102
109
 
103
110
  ## Template
104
111
 
@@ -9,12 +9,17 @@ description: What branch naming is for, the gaps it closes, and where the family
9
9
 
10
10
  Without this skill, a branch name is invented once per session. The type prefix drifts from what the history already carries, the name runs past the width a pull request list renders, and a rename lands on a branch that already exists on the remote, which detaches every open pull request pointing at it.
11
11
 
12
+ A session standing on `main` has no route either. The `git.md` rule sends every git operation through a `git-*` skill, and the only one for branches stopped on `Cannot rename a protected branch`, so the first act of any feature, creating its branch, had no skill to go through.
13
+
12
14
  ## Must
13
15
 
14
16
  - Read the branch format reference before generating, so the type vocabulary and the length limit come from one source
15
- - Derive the name from the commits ahead of main when the invocation carries no description
17
+ - Create the branch on `main` or `master` and rename it anywhere else, so one skill covers both ends of a branch's start
18
+ - Derive the name from the commits ahead of main when a rename carries no description
19
+ - Take a created name from `canon tasks plan-branch` when the invocation names a plan, so the skill and the dispatch gate hold one derivation
16
20
  - Resolve whether the branch exists on the remote before proposing a rename, since the hazard is invisible from local state
17
- - Show the name and its length against the limit before renaming
21
+ - Read the remote itself with `git ls-remote` before creating, since `origin/<name>` sees only the last fetch
22
+ - Show the name and its length against the limit before renaming or creating
18
23
  - Execute immediately after the preview. The tool permission dialog is the confirmation gate.
19
24
 
20
25
  ## Must not
@@ -22,17 +27,23 @@ Without this skill, a branch name is invented once per session. The type prefix
22
27
  - Rename `main` or `master`
23
28
  - Rename when the current name already conforms. The skill is chained, so a conforming name has to pass through rather than churn the branch.
24
29
  - Rename a branch that exists on the remote. Local rename plus force push is not the same operation and it breaks the pull request.
30
+ - Create a branch from anywhere but `main` or `master`, or create one whose name exists locally or on the remote
31
+ - Invent a name when the plan verb refuses, since a name the skill calls non-conforming strands the rename at ship
32
+ - Fetch or stash while creating
25
33
  - Emit anything after the result line
26
34
 
27
35
  ## Guards
28
36
 
29
- - On a protected branch: stop and say the branch is protected
30
- - Name already conforms: stop with a success marker, not a failure, since a chained caller continues past it
31
- - No commits and no description: stop and name both missing inputs
32
- - Branch exists on the remote: stop and route to the surface that preserves the pull request link
37
+ - Create with no plan and no name: stop and name both missing inputs
38
+ - Create with a name breaking the branch standard: stop and name the cap
39
+ - Create with a name existing locally or on the remote: stop and say which
40
+ - Rename name already conforms: stop with a success marker, not a failure, since a chained caller continues past it
41
+ - Rename with no commits and no description: stop and name both missing inputs
42
+ - Rename of a branch existing on the remote: stop and route to the surface that preserves the pull request link
33
43
 
34
44
  ## Out of scope
35
45
 
36
46
  - The commit message, which `git-commit` owns
37
47
  - Pushing and opening the pull request, which `git-pr` owns. That skill reads a conforming name as a precondition and refuses without one, so this skill runs first.
38
48
  - Splitting a branch whose commits span concerns, which `git-split` owns
49
+ - Entering a worktree, which `session-worktree` owns and which names its own branch
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: git-branch
3
- description: Generates and validates conventional branch names. Use for any branch naming or renaming, such as when asked to "name this branch".
3
+ description: Generates and validates conventional branch names, creating the branch from main or master and renaming it anywhere else. Use for any branch naming, creating, or renaming, such as when asked to "name this branch" or "create the branch for this feature".
4
4
  metadata:
5
5
  family: ship
6
6
  ---
@@ -13,7 +13,64 @@ Before generating a branch name, read:
13
13
 
14
14
  Follow it exactly.
15
15
 
16
- ## Context
16
+ Run `git branch --show-current` to pick the mode. On `main` or `master` the skill creates a branch, and anywhere else it renames the current one.
17
+
18
+ ## Create mode
19
+
20
+ ### Name
21
+
22
+ Take the name from the invocation. An argument ending in `.md` or resolving under `.canon/plans/` is a plan, and anything else is a branch name, since a name always carries a `<type>/` segment.
23
+
24
+ - For a plan, run `canon tasks plan-branch <plan> --json` and take the record's `branch`. The verb fixes the type at `feat`, so a plan never yields another type.
25
+ - When the verb refuses or the record carries `conforms: false`, stop and relay its reason. Never invent a name in its place.
26
+ - For a name, check it against the whole Format section of `branch.md`, including the description word bound and the no-repeated-type rule, as the rename guard does.
27
+
28
+ ### Context
29
+
30
+ Run these in parallel once the name is known:
31
+
32
+ - `git show-ref --verify --quiet "refs/heads/<name>" && echo "LOCAL_EXISTS" || echo "LOCAL_FREE"`
33
+ - `git ls-remote --exit-code --heads origin "<name>" 2>/dev/null; echo "REMOTE_EXIT=$?"`
34
+
35
+ Exit 0 on the remote read is a collision. Exit 2, or a repository with no `origin`, is no collision. The check reads the remote itself, never `origin/<name>`, which sees only the last fetch. The skill does not fetch.
36
+
37
+ ### Guards
38
+
39
+ Each guard stops before any ref moves.
40
+
41
+ - If the invocation carries no plan and no name, stop: `❌ No plan or branch name to create from.`
42
+ - If the name breaks `branch.md`, stop and name the cap it broke: `❌ <name> breaks the branch standard: <cap>.`
43
+ - If the name exists locally, stop: `❌ Branch <name> already exists locally.`
44
+ - If the name exists on the remote, stop: `❌ Branch <name> already exists on origin.`
45
+
46
+ ### Preview
47
+
48
+ Output the preview first.
49
+
50
+ - **Current:** <main_or_master>
51
+ - **Creating:** <name>
52
+ - **Length:** <count>/50
53
+ - **Source:** <plan | name>
54
+
55
+ After outputting the preview, execute the final command immediately. Claude Code's tool permission dialog is the confirmation gate. Do not wait for user input.
56
+
57
+ ### Final command
58
+
59
+ The branch starts at the current tip, and uncommitted changes carry onto it. The skill stashes nothing.
60
+
61
+ ```bash
62
+ git switch -c <name>
63
+ ```
64
+
65
+ ### After execution
66
+
67
+ Respond with exactly one line and add no other text:
68
+
69
+ `✅ Created: <name>`
70
+
71
+ ## Rename mode
72
+
73
+ ### Context
17
74
 
18
75
  Run these commands in parallel to gather git context:
19
76
 
@@ -21,14 +78,13 @@ Run these commands in parallel to gather git context:
21
78
  - `git rev-parse --verify "origin/$(git branch --show-current)" 2>/dev/null && echo "EXISTS" || echo "LOCAL_ONLY"`
22
79
  - `git log main..HEAD --oneline 2>/dev/null || echo "NO_COMMITS"`
23
80
 
24
- ## Guards
81
+ ### Guards
82
+
83
+ A conforming name passes through, so a chained caller continues past it.
25
84
 
26
- - If already on main or master, stop: `❌ Cannot rename a protected branch.`
27
85
  - If branch name already follows conventions, stop: `✅ Branch name already follows conventions.`
28
86
  - If no commits and no args provided, stop: `❌ No commits or description to derive a branch name from.`
29
87
 
30
- ## Response format
31
-
32
88
  ### Preview
33
89
 
34
90
  Output the preview first.
@@ -55,7 +111,7 @@ Only output if LOCAL_ONLY:
55
111
  git branch -m <current> <suggested>
56
112
  ```
57
113
 
58
- ## After execution
114
+ ### After execution
59
115
 
60
116
  Respond with exactly one line and add no other text:
61
117
 
@@ -25,11 +25,17 @@ Does not govern:
25
25
 
26
26
  ### Description content
27
27
 
28
+ The description names the change, and 2 words stays the target.
29
+
28
30
  - Capture the core change, not the commit message verbatim
29
31
  - For branches with multiple commits, use the unifying concern as the description.
30
32
  - Do not duplicate type in description (e.g., `feat/feature-login`)
31
33
 
32
- The upper bound reads 4 rather than 3 for every branch, whoever named it. It was widened so that a branch taking its description from a planning document's own filename stops being renamed at ship, since a rename there is a third derivation and parts the branch from the filename that later tooling reads back to find the document. Nothing can tell such a name from any other, so the wider bound holds for all of them and 2 words stays the target.
34
+ ### Why the bound reads 4
35
+
36
+ The upper bound reads 4 for every branch, whoever named it, so a branch taking its description from a planning document's filename is not renamed at ship. A rename there is a third derivation, and it parts the branch from the filename later tooling reads back to find the document.
37
+
38
+ Nothing can tell such a name from any other, so the wider bound holds for all of them.
33
39
 
34
40
  ## Types
35
41
 
@@ -51,6 +57,8 @@ The upper bound reads 4 rather than 3 for every branch, whoever named it. It was
51
57
 
52
58
  ### Correct
53
59
 
60
+ Each line names its reason after the `#`.
61
+
54
62
  ```plaintext
55
63
  feat/jwt-expiration # clear feature scope
56
64
  fix/AUTH-123-connection-pool # includes ticket ID
@@ -59,6 +67,8 @@ refactor/remove-deprecated-endpoints # clear refactor intent
59
67
 
60
68
  ### Incorrect
61
69
 
70
+ Each line names its fault after the `#`.
71
+
62
72
  ```plaintext
63
73
  feature/auth_stuff # wrong type + underscore
64
74
  feat/feature-add-login # duplicates type in description
@@ -16,11 +16,20 @@ Does not govern:
16
16
 
17
17
  ## The transform
18
18
 
19
- Run `git branch --show-current`. Drop a leading segment naming one of the types `branch.md` defines when a further segment follows it, then replace every remaining `/` with `-`. The result is `<slug>`. Anything reading a branch-derived name uses this transform, so two surfaces cannot spell it differently.
19
+ Run `git branch --show-current`. Drop a leading segment naming one of the types `branch.md` defines when a further segment follows it, then replace every remaining `/` with `-`. The result is `<slug>`, and anything reading a branch-derived name uses this transform, so two surfaces cannot spell it differently.
20
20
 
21
- The type comes off because a plan takes its slug from the concern it covers and the branch executing that plan carries the same slug behind a type prefix. Keeping the prefix sends every surface that finds a plan from a branch name looking for `feat-jwt-expiration`, which no plan is filed under. A first segment matching no type stays, so `spike/parser` still yields `spike-parser`.
21
+ ### Why the type comes off
22
22
 
23
- A surface that persists output to a shared folder carries the slug in the filename, which is what keeps parallel worktrees from overwriting each other's output. Two branches differing only in type collapse onto one slug. That collision reaches the worktree directory as well, since it takes its name from the same string, so the branch is not where it would first surface.
23
+ A plan takes its slug from the concern it covers, and the branch executing it carries the same slug behind a type prefix. Keeping the prefix sends every surface that finds a plan from a branch name looking for `feat-jwt-expiration`, which no plan is filed under.
24
+
25
+ - A first segment matching no type stays, so `spike/parser` still yields `spike-parser`
26
+
27
+ ### Slugs in shared folders
28
+
29
+ A surface persisting output to a shared folder carries the slug in the filename, which keeps parallel worktrees from overwriting each other's output.
30
+
31
+ - Two branches differing only in type collapse onto one slug
32
+ - That collision reaches the worktree directory too, since it takes its name from the same string, so the branch is not where it first surfaces
24
33
 
25
34
  ## An empty result
26
35
 
@@ -32,8 +41,11 @@ The empty result is a detached HEAD, and the surface picks one of three response
32
41
 
33
42
  ## Changing the transform
34
43
 
35
- A change here moves what the transform produces, and every declaration asserting the old output keeps asserting it. Nothing reports those, because a fixture carrying an old filename names neither this file nor the surface that reads it, so a diff over the change reaches none of them. Dropping the type segment is the change that proved it: four fixtures and three scenario scripts kept the type-carrying spelling, one surfaced as a red arm months later, and the other six were found by deriving from the rule.
44
+ A change here moves what the transform produces, and every declaration asserting the old output keeps asserting it. A fixture carrying an old filename names neither this file nor the surface reading it, so a diff over the change reaches none of them.
45
+
46
+ Run `canon gov superseded <old> <new>` in the same change, with the old output and the new one as the two arguments. The value is the only key both sides carry, and the sweep reads the whole tracked tree rather than a path someone predicted.
36
47
 
37
- Run `canon gov superseded <old> <new>` in the same change, with the old output and the new one as the two arguments. The value is the only key both sides carry, and the sweep reads the whole tracked tree rather than a path someone predicted. Its output is a reading rather than a verdict, since a string appears for reasons unrelated to any convention, and a declaration disagreeing on purpose carries a `canon-allow-superseded: <reason>` marker on its own line or the one above.
48
+ - Its output is a reading rather than a verdict, since a string appears for reasons unrelated to any convention
49
+ - A declaration disagreeing on purpose carries a `canon-allow-superseded: <reason>` marker on its own line or the one above
38
50
 
39
51
  The sweep sees a value and nothing else. A prose reference that went stale without carrying it, such as a passage citing the wrong standard for the transform, is reached by reading rather than by any key.