@erclx/canon 4.118.0 → 4.120.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 (103) hide show
  1. package/README.md +2 -2
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/canon-rollout/SKILL.md +2 -2
  4. package/claude/skills/create-skill/SKILL.md +2 -1
  5. package/claude/skills/design-extract/SKILL.md +1 -1
  6. package/claude/skills/docs-fold/SKILL.md +2 -2
  7. package/claude/skills/draft-ready/REQUIREMENT.md +1 -1
  8. package/claude/skills/draft-ready/SKILL.md +1 -1
  9. package/claude/skills/draft-screencast/SKILL.md +1 -1
  10. package/claude/skills/git-pr/REQUIREMENT.md +1 -0
  11. package/claude/skills/git-pr/SKILL.md +39 -7
  12. package/claude/skills/memory-capture/SKILL.md +3 -3
  13. package/claude/skills/memory-review/SKILL.md +3 -3
  14. package/claude/skills/plan-feature/SKILL.md +1 -1
  15. package/claude/skills/review-branch/SKILL.md +1 -1
  16. package/claude/skills/review-pr/SKILL.md +13 -242
  17. package/claude/skills/review-pr/references/close-out.md +30 -0
  18. package/claude/skills/review-pr/references/post.md +145 -0
  19. package/claude/skills/review-pr/references/scope.md +82 -0
  20. package/claude/skills/role-orchestrator/REQUIREMENT.md +9 -16
  21. package/claude/skills/role-orchestrator/SKILL.md +9 -153
  22. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +4 -193
  23. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +22 -0
  24. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +85 -0
  25. package/claude/skills/role-orchestrator/references/orchestrator-output.md +61 -0
  26. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
  27. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +1 -1
  28. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +56 -0
  29. package/claude/skills/role-orchestrator/references/orchestrator-review-fallback.md +18 -0
  30. package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +1 -1
  31. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  32. package/claude/skills/role-planner/SKILL.md +1 -1
  33. package/claude/skills/role-worker/REQUIREMENT.md +1 -1
  34. package/claude/skills/role-worker/SKILL.md +10 -41
  35. package/claude/skills/seed-sync/SKILL.md +1 -1
  36. package/claude/skills/session-compact/SKILL.md +1 -1
  37. package/claude/skills/session-map/SKILL.md +1 -1
  38. package/claude/skills/session-relay/REQUIREMENT.md +7 -1
  39. package/claude/skills/session-relay/SKILL.md +4 -7
  40. package/claude/skills/session-worktree/REQUIREMENT.md +5 -1
  41. package/claude/skills/session-worktree/SKILL.md +7 -1
  42. package/claude/skills/session-worktree/references/main-root-writes.md +24 -0
  43. package/claude/skills/task-board/SKILL.md +4 -3
  44. package/claude/skills/teach-workspace/SKILL.md +4 -4
  45. package/claude/skills/ui-checklist/SKILL.md +1 -1
  46. package/claude/skills/ux-audit/SKILL.md +1 -1
  47. package/claude/skills/ux-measure/SKILL.md +1 -1
  48. package/claude/skills/ux-walkthrough/references/relay.md +1 -1
  49. package/docs/agents/commands.md +4 -3
  50. package/docs/agents/counts.md +1 -1
  51. package/docs/agents/index.md +8 -3
  52. package/docs/agents/install-and-sync.md +11 -6
  53. package/docs/agents/pr-evidence.md +19 -3
  54. package/docs/agents/pr-local.md +102 -0
  55. package/docs/agents/pr-preview.md +2 -2
  56. package/docs/agents/records-push.md +61 -0
  57. package/docs/agents/records-validate.md +73 -0
  58. package/docs/agents/records.md +3 -119
  59. package/docs/agents/sessions-transfer.md +91 -0
  60. package/docs/agents/sessions.md +3 -82
  61. package/docs/agents/skills-audit.md +2 -2
  62. package/docs/agents/tasks.md +4 -4
  63. package/docs/agents/teach-authoring.md +112 -0
  64. package/docs/agents/teach.md +3 -103
  65. package/docs/target-projects.md +2 -2
  66. package/docs/workflow/ai-workflow.md +10 -10
  67. package/docs/workflow/visual-design-workflow.md +2 -2
  68. package/governance/renames.toml +13 -0
  69. package/governance/rules/claude/570-skill.md +2 -1
  70. package/governance/rules/core/085-worktrees.md +2 -8
  71. package/package.json +1 -1
  72. package/scripts/core/check-ignore-parity.sh +1 -1
  73. package/scripts/lib/sandbox-git.sh +1 -1
  74. package/src/claude/cases/workflow.ts +10 -0
  75. package/src/commands/pr.ts +324 -2
  76. package/src/commands/sync.ts +11 -3
  77. package/src/commands/tasks.ts +9 -8
  78. package/src/context/classify/extract.ts +2 -2
  79. package/src/counts/scan.ts +1 -1
  80. package/src/design/base.css +19 -19
  81. package/src/design/board.ts +18 -7
  82. package/src/design/neutral.ts +127 -0
  83. package/src/design/regen.ts +6 -4
  84. package/src/design/tokens.ts +6 -3
  85. package/src/gate/stages.ts +6 -6
  86. package/src/gov/adapter.ts +51 -1
  87. package/src/gov/install.ts +13 -3
  88. package/src/gov/renames.ts +76 -0
  89. package/src/gov/stacks.ts +5 -1
  90. package/src/pr/evidence.ts +42 -2
  91. package/src/pr/local.ts +125 -0
  92. package/src/sync/check.ts +19 -4
  93. package/src/sync/engine.ts +67 -3
  94. package/src/tasks/archive.ts +28 -7
  95. package/src/tasks/record.ts +16 -9
  96. package/src/tasks/validate.ts +3 -1
  97. package/standards/index.md +1 -0
  98. package/standards/skill-requirement.md +72 -0
  99. package/standards/skill.md +34 -152
  100. package/standards/tasks.md +5 -3
  101. package/tooling/astro/reference.md +1 -1
  102. package/tooling/base/configs/.github/workflows/pr-local-preview.yml +32 -0
  103. package/governance/rules/core/091-channel.md +0 -13
@@ -7,7 +7,7 @@ description: Claude skill structure and authoring rules
7
7
 
8
8
  ## Overview
9
9
 
10
- Skills give Claude Code domain-specific constraints and rules inline, so it can act immediately without reading all docs. Each skill body contains actionable rules for its domain. Full reference docs are the fallback for edge cases and deeper context. Skills use progressive disclosure: Claude reads only frontmatter at session start (~100 tokens each), matches a query against descriptions, then loads the full skill body.
10
+ Skills give Claude Code domain-specific constraints and rules inline, so it can act immediately without reading all docs.
11
11
 
12
12
  ## Scope
13
13
 
@@ -15,12 +15,12 @@ Governs a skill folder under `skills/` as one artifact: `SKILL.md`, its siblings
15
15
 
16
16
  Does not govern:
17
17
 
18
+ - What a `REQUIREMENT.md` must answer, its sections, and its template: `skill-requirement.md`
18
19
  - Path-scoped coding rules, which load on a file match rather than on a request match: `rule.md`
19
20
  - Single-purpose chat prompts carrying no frontmatter, references, or scripts: `snippets.md`
20
21
  - Voice, rhythm, and sentence construction in a skill body: the `write-human` skill
21
22
  - Punctuation, formatting, and word choice in a skill body: `markdown.md`
22
23
  - The transform from a branch name to a slug a skill carries in a filename: `slug.md`
23
- - The domain conventions a skill cites, each of which belongs to the standard that owns it
24
24
  - Whether a new skill earns its place: the three-question test in the `create-skill` skill and the clause in `570-skill.md`
25
25
 
26
26
  ## Changing a skill
@@ -32,15 +32,13 @@ Answer all four before editing, and carry the answers into wherever the change i
32
32
  - What deterministic check catches a regression? Name it, or say none exists and the step holds on a session reading it.
33
33
  - What does this collide with? Name the sibling skill, rule, or requirement it contradicts, or state that nothing does.
34
34
 
35
- The second question is the one that decides between a body and a rule, which the next section tests in two parts.
36
-
37
35
  ## Whether a rule belongs beside the skill
38
36
 
39
- A skill fires when a session invokes it or its description matches the request. A path-scoped rule fires when a session reads a file matching its glob, with no decision from the session at all. The two are layers rather than alternatives, so the rule is the floor and the skill is the depth.
37
+ A skill fires when a session invokes it or its description matches the request. A path-scoped rule fires when a session reads a file matching its glob, with no decision from the session at all. The rule is the floor and the skill is the depth.
40
38
 
41
- Run the two-part test over what the body states before calling the skill finished. Does the invariant fire when a specific path is edited, and does violating it ship silently? An invariant passing both halves belongs in a rule as well, because a session that never invoked the skill still edits that path and needs the floor under it. An invariant failing either half stays here, which is most of a body, since procedure and orientation are what a rule cannot carry.
39
+ Run the two-part test over what the body states before calling the skill finished. Does the invariant fire when a specific path is edited, and does violating it ship silently? An invariant passing both halves belongs in a rule as well, since a session that never invoked the skill still edits that path. An invariant failing either half stays here, which is most of a body.
42
40
 
43
- Write that rule to the shape `rule.md` sets and leave the procedure here, since the two carry one invariant at two depths rather than two copies of it. Nothing checks the split. The checkpoint is a judgment prompt rather than an invariant, so it ships as prose with no gate behind it, and a skill that skips it fails silently in the same way the invariants it is meant to catch do.
41
+ Write that rule to the shape `rule.md` sets and leave the procedure here, since the two carry one invariant at two depths rather than two copies of it. Nothing checks the split.
44
42
 
45
43
  ## Skill types
46
44
 
@@ -49,23 +47,7 @@ Pick the type before writing. It decides the body shape.
49
47
  - Reference: conventions, patterns, and domain knowledge Claude applies inline. The body is rule bullets grouped by concern.
50
48
  - Task: step-by-step workflows Claude executes as actions. The body is numbered steps plus the rules constraining them.
51
49
 
52
- Reference template:
53
-
54
- ```markdown
55
- ---
56
- name: <skill-name>
57
- description: <what it does, when to use it, trigger phrases>
58
- ---
59
-
60
- # <Topic>
61
-
62
- ## <Concern group>
63
-
64
- - <actionable constraint>
65
- - <preference in X over Y form>
66
- ```
67
-
68
- Task template:
50
+ A task skill takes the template below. A reference skill takes the same frontmatter and replaces `## Steps` and `## Rules` with one H2 per concern group, each holding constraint bullets.
69
51
 
70
52
  ```markdown
71
53
  ---
@@ -90,97 +72,37 @@ allowed-tools: <tools required>
90
72
  ## Structure
91
73
 
92
74
  - Skill is a folder named in kebab-case containing `SKILL.md` (required), `REQUIREMENT.md` (required), `EVAL.md` (optional), `scripts/` (optional), `references/` (optional), `assets/` (optional)
75
+ - Create a new skill with its `REQUIREMENT.md` beside it, even where nobody contests its scope. A requirement present for some skills and absent for others cannot be scanned, since an absence reads as a gap rather than as a verdict
93
76
  - Name a file sitting directly in the skill folder in capitals and a bundled folder in lowercase, so the parts a reader opens are distinct from the ones a skill loads
94
- - `EVAL.md` holds prompts and a judging rubric a person runs by hand, which is the path open to everyone. `claude plugin eval` is the automated one and it is gated in early access, refusing before it parses a target, so write the hand-run rubric and know that the runner exists rather than that it does not
77
+ - `EVAL.md` holds prompts and a judging rubric a person runs by hand, since the automated `claude plugin eval` runner is gated in early access
95
78
  - `SKILL.md` must start with YAML frontmatter between `---` delimiters
96
79
  - No `README.md` inside the skill folder
97
80
  - No spaces, capitals, or underscores in folder or skill name
98
81
 
99
- ## Requirement
100
-
101
- `REQUIREMENT.md` states what a skill is for, so a proposed change can be argued against something and the corpus can be read to decide whether a skill should exist at all. This standard governs shape across the corpus and the requirement governs scope and behavior for one skill. Claude Code loads `SKILL.md` as the entry and ignores the sibling, so the file costs a target session nothing.
102
-
103
- The file serves a second purpose beside the argument. A skill body is procedural by design, so what the skill is for sits spread across its steps rather than stated in one place. The requirement is the compressed statement a reader gets before opening the body, and that purpose holds whether or not the skill's scope is contested.
104
-
105
- Read it before editing the skill. When a change closes no gap the requirement states, change the requirement first or drop the change.
106
-
107
- Write the gaps from what the skill is for, then compare the body against them. Deriving the requirement from the body is circular, because a requirement reverse-engineered from an overfitted skill records the overfitting as the requirement. That failure costs more under the orientation purpose than under the argument one, since a file summarizing the body misinforms whoever reads it in place of the body rather than merely failing to gate a change.
108
-
109
- Every skill carries one. Coverage was selective while the file existed only to disambiguate a contested boundary, and a file present for some skills and absent for others cannot be scanned, because an absence reads as a gap rather than as a verdict. A skill whose scope nobody contests still owes the statement, since the reader deciding whether a skill should exist reads the corpus rather than one entry. A new skill is created with the sibling beside it rather than acquiring one in a later sweep.
110
-
111
- ### What a working requirement looks like
112
-
113
- A requirement works when a proposed change to the skill can be settled by reading it alone, without re-deriving what the skill is for:
114
-
115
- - Does this change close a gap the file states?
116
- - Does a line already in the body trace to one of those gaps?
117
- - Does this behavior belong to this skill or to a sibling the file names?
118
-
119
- A requirement that leaves any of the three open is non-conforming regardless of whether it satisfies every shape rule below. The third question is what makes a requirement worth more than a restated description, because a boundary stated only in prose is never checked against the skill on the other side of it.
120
-
121
- - State each gap as an observed failure, not an intent. "Without this skill a session invents its own filename" can be shown wrong. "This skill helps manage tasks" cannot fail, so it constrains nothing.
122
- - Trace everything under `## Must` to a stated gap. A `Must` with no gap behind it is the padding the file exists to prevent.
123
- - Keep it high level. A requirement that outgrows one file has stopped being a requirement, and `references/` already holds detail.
124
- - Use `name` and `description` frontmatter, matching `SKILL.md` so the pair is consistent.
125
-
126
- ```markdown
127
- ---
128
- name: <skill-name>
129
- description: <one line, distinct from the SKILL.md description>
130
- ---
131
-
132
- # <Skill name> requirement
133
-
134
- ## Gap
135
-
136
- Without this skill, a session <observed failure>, <observed failure>.
137
-
138
- ## Must
139
-
140
- - <behavior that closes a named gap>
141
-
142
- ## Must not
143
-
144
- - <behavior that would be wrong even though it closes a gap>
145
-
146
- ## Guards
147
-
148
- - <the refusal condition and its message>
149
-
150
- ## Out of scope
151
-
152
- - <the adjacent thing this deliberately does not cover, and what covers it>
153
- ```
154
-
155
82
  ## Frontmatter
156
83
 
157
84
  - `name` (required): kebab-case, matches folder name, no spaces or capitals
158
85
  - `description` (required): what it does + when to use it, under 1024 chars, no XML tags
159
- - `disable-model-invocation: true`: user-invoked only, Claude will not auto-trigger. Set it on a skill that starts a process the operator owns, never on one reachable by a matched trigger. The field marks that boundary, not a style preference.
86
+ - `disable-model-invocation: true`: user-invoked only, Claude will not auto-trigger. Set it on a skill that starts a process the operator owns, never on one reachable by a matched trigger.
160
87
  - `allowed-tools`: restrict tool access when the skill is active
161
88
  - `metadata`: optional key-value pairs (`author`, `version`, `mcp-server`)
162
89
 
163
90
  ## Description
164
91
 
165
- - Structure: `[What it does] + [When to use it] + [Key trigger phrases]`
166
- - Include specific phrases users would say to trigger it
92
+ - Structure: `[What it does] + [When to use it] + [Key trigger phrases]`, quoting phrases users would say
167
93
  - Be specific, not vague. Claude routes based on this field alone.
168
94
  - Add negative triggers if skill is over-triggering: `Do NOT use for X`
169
95
 
170
96
  ## Body
171
97
 
172
- ### Voice and headings
173
-
174
- - Use imperative voice throughout
175
- - Use sentence case for all headings (H1, H2, H3)
176
-
177
98
  ### Rule content and scope
178
99
 
100
+ - Use imperative voice throughout, and sentence case for every heading
179
101
  - Front-load critical instructions
180
102
  - Contain only behavioral rules (what to do, what not to do) and pointers to reference docs. Narrative descriptions of what files are or how the system works belong in `docs/`, not in the skill body.
181
103
  - State rules, not inventories. Reference docs for lists that change, and phrase a rule as a ban on the forbidden shape rather than an enumeration of allowed options, so it stays stable as categories change.
182
104
  - Cut any rule that resists crisp one-line phrasing. Vague guidance is worse than none.
183
- - State the current rule only, in the body and in every file under `references/`. The incident and the date that earned a rule go in `REQUIREMENT.md` under `Gap`, or stay in git. A date inside a fence or a code span is example data and stays. `canon claude skills audit` names every other ISO date.
105
+ - State the current rule only, in the body and in every file under `references/`. The incident and the date that earned a rule go in `REQUIREMENT.md` under `Gap`, or stay in git. A date inside a fence or a code span is example data and stays.
184
106
  - Group bullets under H2 headings by domain concern. Keep dos and don'ts together under the topic they belong to rather than splitting them into flat rules and constraints sections.
185
107
  - One actionable constraint per bullet. Prefer the `X over Y` form for preferences.
186
108
  - Do not include code examples unless a one to three line inline snippet captures a pattern the model cannot infer.
@@ -188,17 +110,17 @@ Without this skill, a session <observed failure>, <observed failure>.
188
110
 
189
111
  ### Progressive disclosure
190
112
 
191
- - Look at a body once it passes 150 lines. The number prompts a look rather than gating a build, so nothing enforces it and a body carrying nothing but procedure stays whole at any length.
192
- - Move a catalog, a table of cases, or a format spec running past roughly 15 lines to `references/`. Procedure prose stays, since a session sent to a reference for its own steps pays two reads for one job.
193
- - Name the branch that skips a block before moving it. Body lines are paid on every invocation and a reference only when the body sends the session to it, so a block every run dereferences costs a read and saves nothing.
113
+ - Keep `SKILL.md` and each file under `references/` at or under the 300 rendered line ceiling `markdown.md` sets for a whole document. The ceiling binds procedure as much as reference material.
114
+ - Look at a body once it passes 150 lines. That number prompts a look and gates nothing.
115
+ - Move a catalog, a table of cases, or a format spec running past roughly 15 lines to `references/` at any body length.
116
+ - Below the ceiling, name the branch that skips a block before moving it. A block every run dereferences costs a read and saves nothing.
117
+ - Past the ceiling, move a whole step to a reference, preferring a step a named branch skips. Keep the step heading in the body with one line naming the file to read on reaching it, so the body still shows every step in order.
118
+ - Name every file under `references/` in the body at the point a session reads it, since an unnamed reference is never loaded.
194
119
  - Keep the trigger, the skip condition, and the guard in the body. A run that never reaches the block has to decide that without opening the reference.
195
120
  - Never point one skill at a sibling skill's folder for a reference both read. Each skill carries its own copy under `references/`, generated rather than hand-copied by the rule in `## Path resolution`.
196
- - Use progressive disclosure: `SKILL.md` for core instructions, `references/` for detail, `scripts/` for deterministic operations
197
- - Link to `references/` files explicitly so Claude knows to load them
198
121
 
199
122
  ### Reading and running commands
200
123
 
201
- - Reference a bundled `references/` or `scripts/` file with `${CLAUDE_SKILL_DIR}/<path>`, never a bare relative path. A bare path resolves against the session cwd and fails when a plugin skill runs from another project. `${CLAUDE_SKILL_DIR}` expands to the skill's own directory at render time and resolves from any cwd.
202
124
  - When referencing project files, include "from the project root" in the read instruction
203
125
  - When executing multiple independent operations (file reads, shell commands), run them in parallel to reduce latency
204
126
 
@@ -206,97 +128,57 @@ Without this skill, a session <observed failure>, <observed failure>.
206
128
 
207
129
  - Avoid flags that dispatch between alternate flows. The model misreads them and runs the vanilla path. Dry-run-style toggles are fine. For alternate flows, prefer a separate skill or manual invocation of two skills in sequence.
208
130
  - When a skill should fire from multiple callers, rely on description matching with strong trigger phrases. Do not hardcode `Skill` calls in sibling skills that could trigger it naturally.
209
- - Before collapsing a manual multi-step flow into a skill, ask what the manual pauses do. Pauses that carry external timing, error-surfacing, or judgment weight are the feature. Prefer a snippet over a skill, or require explicit per-step confirmation.
131
+ - Before collapsing a manual multi-step flow into a skill, ask what the manual pauses do. Where a pause carries external timing, error-surfacing, or judgment weight, prefer a snippet or explicit per-step confirmation.
210
132
 
211
133
  ### Output and tuning
212
134
 
213
135
  - Skill success lines emit the full relative path from the project root (`<dir>/<file>`) for any file written, updated, or deleted. A bare filename names a file the reader cannot open. The `## Output` section of the project's instruction file sets the form that path takes, so a skill body states which path is emitted and leaves the form to that section.
214
- - Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `memory/`, `groundwork/`, `intake/`, `proposals/`, `diagrams/`, `teach/`, `ready/`, `feedback/`, `picks/`, `evidence/`, `transcripts/`, or `walkthroughs/`, with `tmp/` for scratch nothing else claims), never in a folder the body invents. A `review/` writer names its file `<kind>-<slug>.md` and writes it flat, and an `evidence/` folder takes the next two-digit ordinal as `<nn>-<slug>/`, numbered in the order the folders first appeared. `canon/ARCHITECTURE.md`'s per-folder decisions are the precedent for which kind takes which folder.
136
+ - Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `memory/`, `groundwork/`, `intake/`, `proposals/`, `diagrams/`, `teach/`, `ready/`, `feedback/`, `picks/`, `evidence/`, `transcripts/`, or `walkthroughs/`, with `tmp/` for scratch nothing else claims), never in a folder the body invents. A `review/` writer names its file `<kind>-<slug>.md` and writes it flat, and an `evidence/` folder takes the next two-digit ordinal as `<nn>-<slug>/`, numbered in the order the folders first appeared.
215
137
  - Codify a skill's posted or generated output as a fenced template, and keep the body consistent with every capability the frontmatter description names.
216
138
  - When a skill gathers user input or pre-seeds a template, attach a concrete proposed default to every question, derived from project context. Accept "use defaults" as a bulk-confirm.
217
- - Separate correctness axes (routing, sourcing, escalation, decline) from shape axes (line count, formatting, variant sprawl) when tuning a skill. Tighten only on correctness regressions. Do not convert soft caps to hard caps for aesthetic drift when correctness passes.
139
+ - Separate correctness axes (routing, sourcing, escalation, decline) from shape axes (line count, formatting, variant sprawl) when tuning a skill. Tighten only on correctness regressions, never turning a soft cap hard for aesthetic drift.
218
140
 
219
141
  ## Scripts
220
142
 
221
143
  - Use `scripts/` for operations that must be deterministic or repetitive
222
- - Claude executes scripts and receives stdout. Scripts are not loaded into context.
223
144
  - Use XML tags in script output for reliable parsing: `<SECTION>content</SECTION>`
224
145
  - Use `#!/usr/bin/env bash` shebang
225
146
  - Always include `2>/dev/null || echo "FALLBACK"` guards on git and shell commands
226
147
 
227
148
  ## Path resolution
228
149
 
229
- A skill reads from two roots. Know which one a file lives under before referencing it.
150
+ A skill reads from two roots, so know which one a file lives under before referencing it.
230
151
 
231
- - Bundled skill assets (`references/`, `scripts/`, `assets/`) resolve against the skill's own directory in the source clone. Reference them with `${CLAUDE_SKILL_DIR}/<path>`, never a bare relative path, so a plugin skill running from another project still finds them.
152
+ - Bundled skill assets (`references/`, `scripts/`, `assets/`) resolve against the skill's own directory. Reference them with `${CLAUDE_SKILL_DIR}/<path>`, never a bare relative path, which resolves against the session cwd and fails when a plugin skill runs from another project.
232
153
  - Installed shared docs (`.claude/rules/`, `canon/context/`) resolve against the target project cwd, where install placed them. Reference them by that path.
233
- - Do not hand-copy a standard into a skill. A hand-copied file drifts from its source and belongs to no owner. If a skill must carry its own copy, generate it from the single source and reference it through `${CLAUDE_SKILL_DIR}`, so one owner keeps every copy in sync.
154
+ - Do not hand-copy a standard into a skill. If a skill must carry its own copy, generate it from the single source and reference it through `${CLAUDE_SKILL_DIR}`, so one owner keeps every copy in sync.
234
155
 
235
156
  ### Citing a standard
236
157
 
237
158
  No standard installs into a project, so a body cites one place rather than choosing between two.
238
159
 
239
- - Cite `${CLAUDE_SKILL_DIR}/../../standards/X.md`. The plugin ships the whole standards folder beside `skills/`, so the path resolves in every install and needs no fallback behind it.
240
- - Never cite `.claude/standards/X.md` from a shipped body. A target holds no such folder, and one left behind by an older toolkit is a stale copy no resolver reads. <!-- audit-ignore-citations: .claude/standards/X.md -->
160
+ - Cite `${CLAUDE_SKILL_DIR}/../../standards/X.md`. The plugin ships the whole standards folder beside `skills/`, so the path resolves in every install.
161
+ - Never cite `.claude/standards/X.md` from a shipped body. A target holds no such folder. <!-- audit-ignore-citations: .claude/standards/X.md -->
241
162
  - Name `canon standards X` instead where the body wants the document rather than a path to open, such as a value it captures or reports. That verb resolves `standards/` at the project root and then the corpus inside the package.
242
163
  - State the path once per body, at the site that reads the standard. A later mention of a standard the body already read stays bare, since repeating the path at every mention is noise rather than instruction.
243
164
  - A guard on a standard's presence names the file rather than the folder holding it, since a folder test answers for a sibling that happens to be there.
244
- - Use `${CLAUDE_SKILL_DIR}`, never a bare `../../` and never `${CLAUDE_PLUGIN_ROOT}`. Only `${CLAUDE_SKILL_DIR}` is expanded before the body reaches the model. The other two leave the model to infer a base path, which it may resolve against the session cwd instead.
245
- - Cite a shared procedure, never restate it. A procedure two or more skills execute gets one definition in a standard and a citation in each body. Nothing catches a restatement that drifts, because the drift assertion covers generated copies and a hand-written one is not generated, so the guarantee is only that a single definition exists to correct.
165
+ - Use `${CLAUDE_SKILL_DIR}`, never a bare `../../` and never `${CLAUDE_PLUGIN_ROOT}`, since only the first expands before the body reaches the model.
166
+ - Cite a shared procedure, never restate it. A procedure two or more skills execute gets one definition in a standard and a citation in each body.
246
167
  - Keep the trigger in the body and the procedure in the standard. The citing skill states when the procedure runs and what it runs against, since that varies per skill and the standard cannot know it.
247
168
 
248
169
  ## Invocation
249
170
 
250
- - Skills auto-trigger when Claude matches the request against the description
251
- - Invoke manually with `/skill-name` or `/<plugin>:skill-name` for plugin skills
252
- - Plugin skills are namespaced: `plugin-name:skill-name`
253
- - Priority order when names conflict: enterprise > personal > project > plugin
254
-
255
- ## Execution
256
-
257
- - Task skills with preview+execute patterns must execute commands immediately after outputting the preview. Do not include "confirm before running" language or pause for user input.
258
- - Claude Code's tool permission dialog is the confirmation gate. The user hits Enter to approve or Escape to interrupt and revise.
171
+ - Invoke a plugin skill by its namespaced name, `/<plugin>:<skill-name>`.
172
+ - Task skills with preview+execute patterns execute commands immediately after outputting the preview, with no "confirm before running" pause, since the tool permission dialog is the confirmation gate.
259
173
 
260
174
  ## Examples
261
175
 
262
176
  ### Correct
263
177
 
264
- ```markdown
265
- ---
266
- name: code-review
267
- description: Reviews code for bugs, clarity, and standards compliance. Use when asking to review code, check a PR, or asking "does this look right".
268
- ---
269
-
270
- # Code review
271
-
272
- Before reviewing, read from the project root:
273
-
274
- - `CLAUDE.md`: project conventions and behavior rules
275
- - `.claude/rules/`: path-scoped coding rules
276
-
277
- ## Guards
278
-
279
- - If no file or diff is provided, stop: `❌ No code to review. Provide a file or diff.`
280
-
281
- ## Response format
282
-
283
- - **Issues found:** <count>
284
- - **Summary:** <one line>
285
-
286
- List each issue with file, line, and suggested fix.
287
- ```
178
+ - `description: Reviews code for bugs and clarity. Use when asked to "review this" or "check the PR".` # names the action, then the trigger phrases
179
+ - `Read ${CLAUDE_SKILL_DIR}/references/post.md on reaching this step.` # a moved step keeps its heading and one load line
288
180
 
289
181
  ### Incorrect
290
182
 
291
- ```markdown
292
- ---
293
- name: code-review
294
- description: Handles all code-related tasks in scripts/, src/, and lib/. Also activate when user mentions bugs, refactoring, testing, linting, formatting, or any file ending in .ts .js .py .sh. # path-focused + keyword-stuffed
295
- ---
296
-
297
- # Code review
298
-
299
- A good code review should check for bugs, performance issues, security vulnerabilities,
300
- code style, naming conventions, test coverage, documentation, error handling,
301
- edge cases, and adherence to SOLID principles... # dumps everything inline instead of referencing standards
302
- ```
183
+ - `description: Handles all code tasks in scripts/, src/, and lib/, and any file ending in .ts .js .py .sh.` # path-focused and keyword-stuffed
184
+ - `A good review checks bugs, performance, security, style, naming, coverage, docs, and SOLID...` # dumps everything inline instead of citing a standard
@@ -173,6 +173,8 @@ Add no third heading. Status stays inline on an outcome rather than becoming an
173
173
 
174
174
  Size the outcomes so one pull request closes all of them. A task whose outcomes span two pull requests ships the first half and leaves the rest open, with nothing recording which outcomes the merged work covered, so the board reads as in-progress work that no branch is carrying. Split the task before handing it off rather than after. This is what `## Archiving` below depends on, since a task closes whole or not at all.
175
175
 
176
+ A sliced task is the one allowed exception: a task the operator decided to ship across several pull requests on purpose, one slice each. Its `Pull request:` line lists every slice, so the board records which merged work covered which outcomes, and it closes whole when the last slice's merge finds every outcome ticked.
177
+
176
178
  Prefix the H1 with the `vX.Y:` phase label, then a short title whose form depends on the task type:
177
179
 
178
180
  - Feature: an outcome describing what the user can now do
@@ -227,15 +229,15 @@ A project that archived plans before the folder nested under `.canon/plans/` hol
227
229
 
228
230
  One plan per task. A plan cited by two tasks is a misfile rather than a shape to design for, which is why the sweep counts citations before archiving: the count is a guard against the misfile stranding a pointer, not support for the shape.
229
231
 
230
- `canon tasks plan-link <task> <plan>` writes or corrects the `Plan:` line, mirroring how `canon tasks pull-request` writes its own. `plan-feature` calls it right after the plan file lands, when an existing task names the feature, so the line is a mechanical write rather than hand-edited markdown.
232
+ `canon tasks plan-link <task> <plan>` writes or corrects the `Plan:` line. `plan-feature` calls it right after the plan file lands, when an existing task names the feature, so the line is a mechanical write rather than hand-edited markdown.
231
233
 
232
234
  `Groundwork:` points at `../groundwork/<slug>/`, the folder `plan-groundwork` fills. It names the surface it points at the way `Plan:` does. Use this key alone. `Research record` and `Decision record` are earlier spellings of the same thing and both convert to it.
233
235
 
234
236
  `Intake:` points at `../intake/<slug>/`, the folder an intake pass fills. Use it rather than `Groundwork:`, because a groundwork track measures one question in depth while an intake dispositions many across a tree, and one key covering both loses which kind of pass produced the task. The line names the folder rather than an item inside it. A task routinely promotes several items at once, so an anchored line would name one and drop the rest, and the item numbers belong in that task's `## Findings`.
235
237
 
236
- `Pull request:` records which pull request carries the task's work, as a bare `#NNN` the way `Issue:` does. It is not an origin, so a task without one is well-formed. `git-pr` writes it when a pull request opens, which is the one step that always runs whether the chain drives it or a person does.
238
+ `Pull request:` records which pull requests carry the task's work, each as a bare `#NNN` the way `Issue:` does. It lists every pull request that shipped part of the task, oldest first and separated by commas, as in `Pull request: #NNN, #NNN`, and a task shipped whole lists one. It is not an origin, so a task without one is well-formed. `git-pr` writes it when a pull request opens, which is the one step that always runs whether the chain drives it or a person does, and appends to the line rather than replacing it.
237
239
 
238
- The line is what lets a merge close its own task. Every merge on `main` is a squash carrying the number in its subject, so the number survives where a branch name does not, and `canon tasks archive --pull-request <n>` resolves the task from it. Without the line the board can only be swept blind, and a blind sweep cannot tell a shipped task from an abandoned one. One task, one pull request: two tasks naming the same number refuse to archive rather than both moving.
240
+ The line is what lets a merge close its own task. Every merge on `main` is a squash carrying the number in its subject, so the number survives where a branch name does not, and `canon tasks archive --pull-request <n>` finds the task by any number the line lists and archives it only on the last, since outcomes are ticked at ship time and an earlier slice can merge after the last one shipped. Without the line the board can only be swept blind, and a blind sweep cannot tell a shipped task from an abandoned one. One pull request, one task: two tasks naming the same number refuse to archive rather than both moving.
239
241
 
240
242
  ## What goes in
241
243
 
@@ -22,7 +22,7 @@ The astro stack covers Astro + TypeScript projects: content sites, marketing sit
22
22
  - `playwright.config.ts`: all browsers, `webServer` runs `bun run build && bun run preview` on port `4321` plus `WORKTREE_PORT_OFFSET`, `reuseExistingServer: false`. Astro's dev/prod gap is wide (MDX, island hydration, asset optimization), so E2E always tests the built `dist/`. `DIST_PREBUILT` set in the environment drops the `build` half, running `bun run preview` alone against a `dist/` a prior CI job already produced.
23
23
  - `tsconfig.json`: extends `astro/tsconfigs/strict`, adds `skipLibCheck`, `vitest/globals` and `@testing-library/jest-dom` in types, `@/` paths.
24
24
  - `card.config.mjs`, `card-src/pages/og-card.astro`, and `scripts/check-card-exclusion.sh`: the social card route, its structural build exclusion, and the check enforcing it. See `## Social card route` below.
25
- - `eslint.config.js`: overrides the web layer. Adds `eslint-plugin-astro` (`.astro` parser via `astro-eslint-parser`). React-hooks scoped to `.jsx`/`.tsx` only (`.astro` is not React). The shared block's `files` selector includes `.astro`, so `check-file/filename-naming-convention` reaches `.ts`, `.tsx`, and `.astro` under `KEBAB_CASE`, overriding Astro's own PascalCase component convention deliberately, on the ground that a component's name in markup comes from the import binding rather than the filename. `.js` and `.jsx` stay out of the rule's own pattern, matching `web` and `nextjs`. `check-file/folder-naming-convention` reaches every `src/**` folder except `__tests__` and the whole `pages/` subtree, which carries its own off-block for the bracket-named dynamic routes and nested slug folders Astro's file-based routing produces. See `canon/context/tooling.md` for the measurement.
25
+ - `eslint.config.js`: overrides the web layer. Adds `eslint-plugin-astro` (`.astro` parser via `astro-eslint-parser`). React-hooks scoped to `.jsx`/`.tsx` only (`.astro` is not React). The shared block's `files` selector includes `.astro`, so `check-file/filename-naming-convention` reaches `.ts`, `.tsx`, and `.astro` under `KEBAB_CASE`, overriding Astro's own PascalCase component convention deliberately, on the ground that a component's name in markup comes from the import binding rather than the filename. `.js` and `.jsx` stay out of the rule's own pattern, matching `web` and `nextjs`. `check-file/folder-naming-convention` reaches every `src/**` folder except `__tests__` and the whole `pages/` subtree, which carries its own off-block for the bracket-named dynamic routes and nested slug folders Astro's file-based routing produces. See `canon/context/tooling/stacks.md` for the measurement.
26
26
 
27
27
  ## Typecheck
28
28
 
@@ -0,0 +1,32 @@
1
+ name: PR Local Preview Cleanup
2
+
3
+ on:
4
+ pull_request:
5
+ types: [closed]
6
+
7
+ permissions:
8
+ pull-requests: write
9
+
10
+ jobs:
11
+ remove-local-preview:
12
+ name: 🖥️ Remove Local Preview Link
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ # A fork pull request gets a read-only token, so the edit cannot land.
16
+ # Say so and pass rather than failing a close nobody can fix.
17
+ - name: Skip a fork pull request
18
+ if: github.event.pull_request.head.repo.full_name != github.repository
19
+ run: echo "::notice::Fork pull request, so the token cannot edit the evidence comment. The local preview line stays."
20
+
21
+ - name: Setup Bun
22
+ if: github.event.pull_request.head.repo.full_name == github.repository
23
+ uses: oven-sh/setup-bun@v2
24
+ with:
25
+ bun-version: latest
26
+
27
+ - name: Replace the local preview line on the evidence comment
28
+ if: github.event.pull_request.head.repo.full_name == github.repository
29
+ env:
30
+ GH_TOKEN: ${{ github.token }}
31
+ GH_REPO: ${{ github.repository }}
32
+ run: bunx -y @erclx/canon pr local ${{ github.event.pull_request.number }} --remove --json
@@ -1,13 +0,0 @@
1
- ---
2
- description: The addressing and timing a session holding neither role-worker nor role-planner owes when it must message whoever dispatched it
3
- ---
4
-
5
- # Channel standards
6
-
7
- ## A session holding neither role
8
-
9
- - Resolve the addressee at send time through `canon sessions list --json`, keyed on the id or branch the dispatcher named at launch, never by name prefix. A name is derived from what a session turns out to be doing and goes stale before a build finishes.
10
- - Send a block out as a message before it becomes an interactive prompt. A session already waiting on input never reaches the tool round that drains an inbound message, so an answer relayed afterwards arrives under the open question and changes nothing.
11
- - Leave the message content, and which transition earns one, to whatever dispatched this session. Both are task-specific and already stated where they apply.
12
- - A session holding `canon:role-worker` or `canon:role-planner` follows that body's own addressee ladder instead, stated in its own `## The channel` section. This rule states what neither role leaves stated elsewhere, not a replacement for either ladder.
13
- - Report it rather than proceeding silently when neither skill resolves to check against. Both ship with the plugin and this rule ships with the CLI, so a project that installed governance alone does not have them.