@erclx/canon 5.42.0 → 5.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +3 -3
  3. package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
  4. package/claude/skills/ci-workflow/SKILL.md +12 -2
  5. package/claude/skills/ci-workflow/references/workflows.md +12 -9
  6. package/claude/skills/create-rule/SKILL.md +1 -0
  7. package/claude/skills/decision-escalate/SKILL.md +1 -2
  8. package/claude/skills/document-health/references/axes.md +2 -1
  9. package/claude/skills/draft-doc/references/wiki-kind.md +1 -1
  10. package/claude/skills/draft-doc/references/wiki.md +1 -1
  11. package/claude/skills/git-commit/references/commit.md +1 -5
  12. package/claude/skills/git-pr/references/pr.md +1 -0
  13. package/claude/skills/plan-feature/SKILL.md +1 -1
  14. package/claude/skills/plan-feature/references/plan.md +1 -1
  15. package/claude/skills/pr-evidence/references/evidence.md +1 -1
  16. package/claude/skills/role-orchestrator/SKILL.md +2 -0
  17. package/claude/skills/role-orchestrator/references/orchestrator-output.md +4 -0
  18. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  19. package/claude/skills/role-planner/SKILL.md +3 -3
  20. package/claude/skills/role-worker/REQUIREMENT.md +2 -0
  21. package/claude/skills/role-worker/SKILL.md +26 -2
  22. package/claude/skills/search-craft/REQUIREMENT.md +1 -1
  23. package/claude/skills/search-craft/SKILL.md +2 -2
  24. package/docs/agents/audits.md +1 -0
  25. package/docs/agents/migrate.md +11 -8
  26. package/docs/target/migrations.md +11 -0
  27. package/governance/detect.toml +4 -0
  28. package/governance/rules/canon/context.md +2 -1
  29. package/governance/rules/canon/plan.md +3 -5
  30. package/governance/rules/canon/scratch.md +3 -1
  31. package/governance/rules/canon/task-scope.md +2 -1
  32. package/governance/rules/canon/tasks.md +2 -1
  33. package/governance/rules/canon/worktrees.md +5 -2
  34. package/governance/rules/claude/output.md +7 -4
  35. package/governance/rules/claude/skill.md +6 -4
  36. package/governance/rules/tooling/ci-workflow.md +6 -39
  37. package/governance/rules/ui/design-reference.md +37 -0
  38. package/governance/rules/writing/markdown.md +2 -1
  39. package/package.json +6 -6
  40. package/src/audits/catalog.ts +42 -0
  41. package/src/claude/settings.ts +8 -4
  42. package/src/commands/claude.ts +11 -1
  43. package/src/commands/gov.ts +198 -0
  44. package/src/commands/migrate.ts +121 -2
  45. package/src/commands/pr.ts +4 -77
  46. package/src/commands/tooling.ts +3 -3
  47. package/src/commands/worktrees.ts +49 -0
  48. package/src/gate/stages.ts +15 -0
  49. package/src/gov/audit.ts +440 -0
  50. package/src/listeners/belongs.ts +21 -0
  51. package/src/listeners/machine.ts +93 -0
  52. package/src/listeners/parse.ts +41 -0
  53. package/src/migrate/session-defaults.ts +138 -0
  54. package/src/pr/local.ts +4 -69
  55. package/src/sync/check.ts +15 -0
  56. package/src/tooling/stamp.ts +56 -12
  57. package/src/worktrees/stop.ts +92 -0
  58. package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
  59. package/tooling/base/configs/commitlint.config.js +0 -20
  60. package/tooling/base/reference.md +1 -1
  61. package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
  62. package/tooling/claude/reference.md +13 -7
  63. package/tooling/claude/seeds/.claude/settings.json +4 -0
  64. package/tooling/claude/user/settings.template.json +0 -4
  65. package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
  66. package/tooling/public/configs/.github/dependabot.yml +12 -0
  67. package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
  68. package/tooling/public/manifest.toml +8 -0
  69. package/tooling/public/reference.md +53 -0
  70. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
  71. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
  72. package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
  73. package/tooling/public/seeds/.release-please-manifest.json +3 -0
  74. package/tooling/public/seeds/CONTRIBUTING.md +50 -0
  75. package/tooling/public/seeds/LICENSE +21 -0
  76. package/tooling/public/seeds/SECURITY.md +13 -0
  77. package/tooling/public/seeds/release-please-config.json +12 -0
  78. package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
  79. package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
  80. package/tooling/web/configs/.github/workflows/verify.yml +15 -12
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
4
- "version": "5.42.0",
4
+ "version": "5.43.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -65,9 +65,9 @@ If neither form is present, stop: `❌ <path> carries no plan sections. A plan l
65
65
 
66
66
  ### Unanswered questions
67
67
 
68
- The plan's sections and answer contract are fixed by `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`. A blank `- Answer:` accepts the `- Suggested:` line above it, so an unanswered question is a decision this run executes rather than a reason to stop.
68
+ Read `## The suggested-and-answer contract` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md` before acting on a question, for what it resolves to and the form an override takes. A question left open is a decision this run executes rather than a reason to stop.
69
69
 
70
- When this run decides against a suggestion, rewrite its line as `overridden at execution to <pick>,` plus the measurement, leaving `- Answer:` blank. Put the same deviation in one line under the open task's `## Findings`, opening with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
70
+ Open the task's `## Findings` line for an override with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
71
71
 
72
72
  ## Step 2: implement
73
73
 
@@ -107,7 +107,7 @@ When the plan's `**Constraints:**` carry a `Fan-in member of` bullet, push the b
107
107
 
108
108
  If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
109
109
 
110
- When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file.
110
+ When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file. A diff passing this test also owes the preview server `role-worker` states, started before Step 6.
111
111
 
112
112
  ## Step 6: ship
113
113
 
@@ -21,7 +21,8 @@ A cache keyed on a static string serves a stale browser or toolchain after a ver
21
21
  - Start the checks that share setup in one job and split them only once a run log puts the gate past roughly two minutes
22
22
  - Pin every action to a tag that cannot cross a major version
23
23
  - Key a cache on the version string of the thing it caches
24
- - Give every workflow a manual trigger beside its primary one
24
+ - Give every workflow a manual trigger beside its primary one, except one that commits back, where a manual run has no branch to land on
25
+ - Default the token to read-only and grant a write scope only on the job that needs it
25
26
  - Bound artifact upload to failures and set an expiry on it
26
27
 
27
28
  ## Must not
@@ -17,7 +17,8 @@ Generate GitHub Actions workflow files for CI pipelines. Enforce parallel job ex
17
17
 
18
18
  ## Workflow setup
19
19
 
20
- - Include `workflow_dispatch` on every workflow alongside the primary trigger.
20
+ - Include `workflow_dispatch` alongside the primary trigger, except on a commit-back workflow, where a manual run has no branch to commit onto and would pass while doing nothing.
21
+ - Set `permissions: contents: read` at the top level, and grant a write scope only on the job that needs it.
21
22
  - Pin all actions to major version tags (`@v4`, never `@latest` or `@main`).
22
23
  - Use `runs-on: ubuntu-latest` for all jobs.
23
24
 
@@ -50,6 +51,14 @@ Generate GitHub Actions workflow files for CI pipelines. Enforce parallel job ex
50
51
  - Install with `bun install --frozen-lockfile`.
51
52
  - Cache Playwright browsers keyed on the Playwright version string, never a static key.
52
53
 
54
+ ## Commit-back
55
+
56
+ A workflow that pushes a regenerated file onto the pull request branch takes these on top of the setup above.
57
+
58
+ - Set the concurrency group on the ref so a newer push cancels the run committing onto a stale head.
59
+ - Set `HUSKY: 0` on the commit step when the runner lacks a tool a hook shells out to.
60
+ - Fail a template's first step while a path list still holds its placeholder, so an unfinished install fails loudly rather than never firing.
61
+
53
62
  ## Template
54
63
 
55
64
  Load `${CLAUDE_SKILL_DIR}/references/workflows.md` for the base workflow template. Adapt it to the project's stack, test commands, and build output. Add or remove jobs as needed. The template already carries the folded shape, and the split beside it applies once the granularity rule above calls for it.
@@ -58,7 +67,8 @@ Load `${CLAUDE_SKILL_DIR}/references/workflows.md` for the base workflow templat
58
67
 
59
68
  Before responding, verify:
60
69
 
61
- - `workflow_dispatch` is present alongside the primary trigger.
70
+ - `workflow_dispatch` is present alongside the primary trigger, and absent from a commit-back workflow.
71
+ - The top-level `permissions` reads `contents: read`, and every write scope sits on a job.
62
72
  - All actions pinned to major version tags, no `@latest` or `@main`.
63
73
  - A new pipeline folds static, unit, and build into one job, and a gate a run log put past two minutes gives them no `needs` so they run in parallel.
64
74
  - Every name in a `needs` matches a job declared in the same file. E2E names the artifact producer, release and deploy name E2E.
@@ -12,12 +12,15 @@ on:
12
12
  branches: [main]
13
13
  workflow_dispatch:
14
14
 
15
+ permissions:
16
+ contents: read
17
+
15
18
  jobs:
16
19
  checks:
17
20
  name: '🛡️ Checks'
18
21
  runs-on: ubuntu-latest
19
22
  steps:
20
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v7
21
24
  - uses: oven-sh/setup-bun@v2
22
25
  with:
23
26
  bun-version: latest
@@ -25,7 +28,7 @@ jobs:
25
28
  - run: bun run check
26
29
  - run: bun run test
27
30
  - run: bun run build
28
- - uses: actions/upload-artifact@v4
31
+ - uses: actions/upload-artifact@v7
29
32
  with:
30
33
  name: build-output
31
34
  path: dist/
@@ -35,17 +38,17 @@ jobs:
35
38
  needs: checks
36
39
  runs-on: ubuntu-latest
37
40
  steps:
38
- - uses: actions/checkout@v4
41
+ - uses: actions/checkout@v7
39
42
  - uses: oven-sh/setup-bun@v2
40
43
  with:
41
44
  bun-version: latest
42
45
  - run: bun install --frozen-lockfile
43
- - uses: actions/download-artifact@v4
46
+ - uses: actions/download-artifact@v8
44
47
  with:
45
48
  name: build-output
46
49
  path: dist/
47
50
  - run: bun run test:e2e
48
- - uses: actions/upload-artifact@v4
51
+ - uses: actions/upload-artifact@v7
49
52
  if: failure()
50
53
  with:
51
54
  name: e2e-results
@@ -63,7 +66,7 @@ jobs:
63
66
  name: '🛡️ Static Checks'
64
67
  runs-on: ubuntu-latest
65
68
  steps:
66
- - uses: actions/checkout@v4
69
+ - uses: actions/checkout@v7
67
70
  - uses: oven-sh/setup-bun@v2
68
71
  with:
69
72
  bun-version: latest
@@ -74,7 +77,7 @@ jobs:
74
77
  name: '🧪 Unit Tests'
75
78
  runs-on: ubuntu-latest
76
79
  steps:
77
- - uses: actions/checkout@v4
80
+ - uses: actions/checkout@v7
78
81
  - uses: oven-sh/setup-bun@v2
79
82
  with:
80
83
  bun-version: latest
@@ -85,13 +88,13 @@ jobs:
85
88
  name: '📦 Build Check'
86
89
  runs-on: ubuntu-latest
87
90
  steps:
88
- - uses: actions/checkout@v4
91
+ - uses: actions/checkout@v7
89
92
  - uses: oven-sh/setup-bun@v2
90
93
  with:
91
94
  bun-version: latest
92
95
  - run: bun install --frozen-lockfile
93
96
  - run: bun run build
94
- - uses: actions/upload-artifact@v4
97
+ - uses: actions/upload-artifact@v7
95
98
  with:
96
99
  name: build-output
97
100
  path: dist/
@@ -80,6 +80,7 @@ Title casing is sentence case, with proper nouns keeping their own casing (`# Ty
80
80
  Read `${CLAUDE_SKILL_DIR}/references/checklist.md` and run every bullet of the written rule through it, along with the shape limits and the content test in `rule.md`.
81
81
 
82
82
  - Rewrite a bullet marked revise and cut one marked drop, then run the checklist again over what changed
83
+ - Run `canon gov audit .claude/rules/project/<subdir>/<slug>.md` and fix every finding it reports, since the shape limits are counts the verb takes rather than a judgment
83
84
  - Report the verdict counts with the path, and name any bullet kept against a criterion with the reason
84
85
 
85
86
  ## After writing
@@ -70,8 +70,7 @@ Restate each pick in one line, then continue the work.
70
70
 
71
71
  A pick that changes a written artifact goes into it under the rule its own standard sets, and a pick that settles nothing written stays in the session.
72
72
 
73
- - An answer to an open plan question rewrites its `- Suggested:` line to the pick, naming the operator as source, per `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`
74
- - Leave the `- Answer:` slot blank, since the standard bars a session from filling it, and the blank resolves to the rewritten suggestion
73
+ - Record an answer to an open plan question per `### Overrides and settled questions` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`
75
74
 
76
75
  Output after the answers land:
77
76
 
@@ -14,7 +14,7 @@ The skill body holds the order, the guards, and the report shape. This holds the
14
14
  | Field | Value |
15
15
  | -------------- | ------------------------------------------------------------------------------------------ |
16
16
  | Measures | Whether a document, or a passage inside it, has grown past what a reader takes in one pass |
17
- | Verb | `canon markdown audit --json` |
17
+ | Verbs | `canon markdown audit --json`, and `canon gov audit --json` for a rule |
18
18
  | Evidence class | `measured` |
19
19
 
20
20
  The record carries the checkpoints it read against under `checkpoints` and the per-file weights under `entries`. Read both from the record rather than from a number stated here, since the CLI moves a checkpoint on its own cadence and a copy goes stale in place.
@@ -23,6 +23,7 @@ The record carries the checkpoints it read against under `checkpoints` and the p
23
23
  - `heavyParagraphs`: a paragraph past the sentence or character checkpoint
24
24
  - `longestRun`, against `longestRunLine`: unbroken rendered lines between headings, which is the depth checkpoint
25
25
  - `cadence`, carrying `measured`, `flat`, and `repeating`: sentence-length spread and repeated openers
26
+ - `rules[].findings`: a rule past one of its own six shape limits or carrying an emphasis word, since the density weights above never read a rule file
26
27
 
27
28
  ### Reading a length finding
28
29
 
@@ -37,7 +37,7 @@ Do not widen the split to admit a subject. Adding a sibling folder is a change t
37
37
 
38
38
  The standard forbids working from training knowledge, so the draft is built on a read rather than on recall.
39
39
 
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.
40
+ Fetch a Claude Code subject from Anthropic's docs directly, starting at the index `https://code.claude.com/docs/llms.txt` and reading the `.md` form of the page it names, and write from that page. Reach any other subject through the owner's own published documentation.
41
41
 
42
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.
43
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.
@@ -45,7 +45,7 @@ A page failing either is non-conforming even when it satisfies every shape rule
45
45
 
46
46
  - Close the intro paragraph with a `Source:` sentence naming the owner. Link the canonical page where one exists, and name the owner alone where the subject has no single URL.
47
47
  - Link a docs page in its fetchable form, `https://code.claude.com/docs/en/<page>.md`, so a session reads the live text rather than a copy.
48
- - Fetch current information through the `claude-code-guide` agent when the subject is Claude Code. Do not work from training knowledge.
48
+ - Fetch a Claude Code subject directly, starting at the index `https://code.claude.com/docs/llms.txt`. Do not work from training knowledge.
49
49
  - Propose an addition or correction and wait for confirmation. Do not write to a wiki file unasked.
50
50
 
51
51
  ## Shape
@@ -56,6 +56,7 @@ A scope names a component, never a file or the type again.
56
56
  - Use imperative mood (`add` not `added`)
57
57
  - Describe the actual technical change, not that something changed
58
58
  - Do not use vague verbs (`improve`, `refine`, `enhance`)
59
+ - Name what changed in the project on a sync or upgrade commit, never the toolkit version, since the config stamp records it
59
60
 
60
61
  ### Form and quoting
61
62
 
@@ -66,11 +67,6 @@ The subject carries the change and nothing around it.
66
67
  - No backslash escaping or internal double quotes
67
68
  - No conversational filler or introductory phrases
68
69
 
69
- ## Trailers
70
-
71
- - Do not add a `Co-authored-by` trailer crediting Claude or Anthropic, by name or by address
72
- - The `commit-msg` hook refuses a commit carrying one, so remove the line and commit again
73
-
74
70
  ## Examples
75
71
 
76
72
  ### Correct
@@ -33,6 +33,7 @@ Does not govern:
33
33
  - Format: `<type>(<scope>): <subject>`, with `!` before the colon for a breaking change
34
34
  - Casing: lowercase for `<type>`, `<scope>`, and first word of `<subject>`
35
35
  - Length: 72 characters maximum
36
+ - Subject: follows the subject rules in `commit.md`, including the one for a sync or upgrade title
36
37
 
37
38
  ## Content
38
39
 
@@ -49,7 +49,7 @@ Measure against the tree rather than recall, since a count carried from an earli
49
49
  When a decision rests on an outside practice or a third-party behavior, invoke `canon:search-craft` before searching, fetch each source, and record the passage relied on. Skip this for a plan that rests on nothing outside the project.
50
50
 
51
51
  - Confirm exact wording through `curl` where a decision turns on it, since `WebFetch` returns a model's answer rather than the page
52
- - Route a Claude Code subject to the `claude-code-guide` agent
52
+ - Fetch a Claude Code subject from Anthropic's docs directly, starting at the index `https://code.claude.com/docs/llms.txt` and reading the `.md` form of the page it names
53
53
  - Mark a source that could not be fetched as unverified rather than citing recall
54
54
  - Report it rather than proceeding silently when `canon:search-craft` does not resolve
55
55
 
@@ -203,7 +203,7 @@ A deviation from an unanswered question rewrites the `- Suggested:` line to the
203
203
  - The fixed phrase tells an override from an authored suggestion, which routinely carries a number too
204
204
  - Take a deviation from an answered question back to whoever answered it rather than rewriting either line
205
205
  - A filled slot is a decision already made, and a suggestion rewritten under one leaves two picks with no default resolving them
206
- - Answer in place when a question is settled in conversation, so the file and the decision do not disagree.
206
+ - Record a pick settled in conversation on the `- Suggested:` line, naming who settled it, and leave the slot blank. A deviation from it goes back to whoever settled it.
207
207
 
208
208
  The plan is archived at ship, so the same deviation takes one line in the open task's `## Findings` naming what shipped. The plan holds why the pick moved and the task holds what the tree now has.
209
209
 
@@ -35,7 +35,7 @@ canon pr local --json
35
35
  The verb reports the lowest port serving an HTML page whose process runs inside this worktree, never one in another worktree or the main checkout, which shows a different branch. `canon pr local --help` states the contract. Read `reason` on the record rather than the exit code.
36
36
 
37
37
  - `ok`: hold the record's `url` for the evidence step below.
38
- - `no-server` or `no-listener-reader`: hold the reason for the closing report and pass no link. Never start a server here, since one started inside the ship chain has no owner to stop it.
38
+ - `no-server` or `no-listener-reader`: hold the reason for the closing report and pass no link. Never start a server here, since the ship chain cannot own one. A worker starts one under `role-worker`.
39
39
  - Anything else, including no record or an older binary's unknown-subcommand error: move on silently, as a skip rather than a stop.
40
40
 
41
41
  ### Where the link lands
@@ -132,6 +132,8 @@ A worker is a separate process the controller can steer, and scope reaches it th
132
132
  - Do not edit tracked files from this session, at any size. The boundary offers no proportionality exception and nothing enforces it.
133
133
  - Do not hand a worker anything but a plan, which carries exact diffs only when already known and otherwise states scope and open questions
134
134
 
135
+ A late ask about a building row is a follow-up filed through `task-board`, with the ask as its origin and the running task cited in the intro. Amend the plan only on the operator's word, naming the re-review cost, and message the worker.
136
+
135
137
  The tracked-file boundary collides with `CLAUDE.md`, which says to handle a small edit immediately, and this rule wins wherever the two meet. A session that writes a change cannot review it independently afterwards, which is the separation `review-pr` exists to supply.
136
138
 
137
139
  ### Filing a row
@@ -65,5 +65,9 @@ Keep the detail below the block and keep it skippable. A decision reached at the
65
65
 
66
66
  - Reuse the vocabulary above rather than inventing a second one
67
67
  - Keep a file set on the row claiming it, so the reader can check a hold or a shared-path claim instead of taking it
68
+ - Name a session by its launch name in any line sending the operator into it, such as `claude attach worker-frameboard-design-reference-set`, with the id in parentheses
69
+ - A bare id tells the operator nothing about which session it is
70
+ - A rename leaves the launch name matching nothing, so read the current name off `canon sessions list --json` when the line is written
71
+ - `claude rm` takes the id alone, so that line carries the id
68
72
 
69
73
  Write no shape for a correction. A correction is a sentence, and a format for admitting error invites ceremony where plainness is the whole value.
@@ -61,7 +61,7 @@ four carried at least one, caught only because the planner ran
61
61
  - Owe an announcement when the record lands, carrying the path and what the row got wrong, since the controller cannot watch the read happen
62
62
  - Owe a message before a block becomes an interactive prompt, since a session already waiting on input never reaches the tool round an inbound message drains at
63
63
  - Keep correcting the dispatcher a first-class move carrying its evidence, since a trial corrected a brief's premise, planned every row anyway, and carried the consequence into a plan question
64
- - Carry a talk clause for a launch whose operator is in the session, putting each open question to them, recording a settled pick in place, and owing a close message when they end the conversation, since a cold planner's halting rules contradict a brief that asks it to talk
64
+ - Carry a talk clause for a launch whose operator is in the session, putting each open question to them, recording a settled pick in place, sending an ask about a row now building to the controller rather than the worker, and owing a close message when they end the conversation, since a cold planner's halting rules contradict a brief that asks it to talk
65
65
  - Point at each of the three skills for its record's shape and the steps that write it
66
66
  - Defer the addressee resolution to `session-relay` and keep only the last-rung inference, which discriminates differently here than it does for a worker because a session in this role holds no feature branch either
67
67
 
@@ -101,10 +101,10 @@ One rung stays here because it differs between roles. Inference takes the sessio
101
101
 
102
102
  A launch whose brief says it is a talk session puts the operator in this one. Everything above holds, and the clause below changes how questions are answered and when the role ends. A launch carrying no such sentence takes none of this.
103
103
 
104
- - Put each open question to the operator through the structured question surface before writing the record, and record a settled pick in place per the plan standard
105
- - Never fill an `- Answer:` slot the operator did not answer
104
+ - Put each open question to the operator through the structured question surface before writing the record
105
+ - Record each pick per `### Overrides and settled questions` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`
106
106
  - Keep answering under `plan-feature`'s discussion rounds after the record lands, since the operator launched this session to keep talking.
107
- - Owe the landing announcement as usual, plus a close message when the operator ends the conversation.
107
+ - Owe the landing announcement as usual, plus a close message when the operator ends the conversation. Send an ask about a building row to the controller, never the worker.
108
108
  - Skip the before-prompt block message for a question put to the operator in the session. Keep it for a block the operator cannot answer, since a controller learns of a stall only from a message.
109
109
 
110
110
  The operator being present is an assumption the launch carries. A talk planner whose operator has walked away waits silently on its first question, so say what the session is waiting on in the turn it stops.
@@ -35,6 +35,8 @@ The draft mark fails from both ends. On 2026-08-31 four sessions re-drafted a pu
35
35
  - Keep refusing a dispatcher a first-class move carrying its evidence, since the halts measured so far were correct and the cost of each fell where it belonged
36
36
  - State that a held body may be older than the branch under it, since a plugin skill loads from the marketplace cache rather than from the working tree
37
37
  - Carry a talk clause for a launch whose operator is in the session, asking them at a judgment call and sending a close message when they end the conversation, since a cold worker's halt-toward-the-controller and merge-ends-the-role rules contradict a brief that asks it to talk
38
+ - Freeze the plan's scope at dispatch, sorting a late ask into a defect to fix, a follow-up row to report, or an addition the operator's word admits with its re-review cost stated, since intake 155 measured about four UI review rounds on one pull request from late asks, each re-running both reviews
39
+ - Own the local preview server for a painted diff, started as a tracked background command before the pull request opens, since a `no-server` read leaves the evidence comment and the UI reviewer without an address on the one path nobody watched being built (erclx/frameboard#1 and erclx/frameboard#4)
38
40
  - Point at `session-worktree`, `auto-ship`, and `review-address` for the steps each already owns
39
41
 
40
42
  ## Must not
@@ -36,9 +36,32 @@ A ready folder and the draft mark each carry work another session already did, s
36
36
 
37
37
  ### Overriding a plan question
38
38
 
39
- Rewrite an unanswered question's `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when this build decides against it, leaving `- Answer:` blank, per `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`.
39
+ Follow `### Overrides and settled questions` in `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md` when this build decides against a suggestion.
40
40
 
41
- Put the same deviation in one line under the open task's `## Findings`, opening with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
41
+ Open the task's `## Findings` line for an override with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
42
+
43
+ ### The preview server
44
+
45
+ A painted pull request needs a server in this worktree for `canon pr local` to find, and this session is the one with a lifetime to own it. `auto-ship` Step 5 decides whether the diff is painted, so this body restates no file test.
46
+
47
+ - Run `canon pr local --json` first and start nothing when `reason` reads `ok`
48
+ - Otherwise start the stack's `dev` script as a background command from the worktree root before the pull request step. `dev` follows the worktree, so a `review-address` fix shows on the same link.
49
+ - Wait up to 60 seconds for the verb to read `ok`, then ship either way. A stack with no `dev` script gets no start, and `pr-evidence` reports `no-server`.
50
+ - Never detach it with `nohup`, `setsid`, or `disown`, since the owning session is the stop. `canon worktrees reclaim` ends any listener left in a worktree it removes.
51
+
52
+ A hand-run `git-ship` or `git-pr` starts no server, since only a worker has a lifetime to own one.
53
+
54
+ ## Scope after dispatch
55
+
56
+ The plan is the scope from the dispatch on. A late ask restarts both reviews, and one pull request took about four UI review rounds from asks that arrived mid-build.
57
+
58
+ Sort each ask that arrives after dispatch three ways:
59
+
60
+ - A defect is a failed outcome or a regression in what the plan builds. Fix it in this build, and take every review finding on the pull request through `review-address` the same way.
61
+ - Anything else is a follow-up row. Do not build it. Reply with the follow-up wording, and report the row to the controller with its title, origin, and surface.
62
+ - Add it to this pull request only on the operator's word, never a bare controller or planner message without an amended plan. Before the commit, say that both reviews run again.
63
+
64
+ When the operator approves an addition through the controller, the controller amends the plan in place and sends the pointer, so the added scope stays checkable against the diff. Fall back to `session-relay`'s copyable block when no controller is live, and never drop the row.
42
65
 
43
66
  ## The board is read-only
44
67
 
@@ -107,6 +130,7 @@ A launch whose brief says it is a talk session puts the operator in this one. Ev
107
130
 
108
131
  - Ask the operator in the session through the structured question surface at a judgment call, rather than halting toward the controller
109
132
  - Put a plan question written as needing the operator's call to them directly
133
+ - Sort a late ask from the operator in place under the scope rule above, and send the controller the follow-up row rather than relaying the ask
110
134
  - Send the controller a close message when the operator ends the conversation, beside the announcements the channel above owes.
111
135
  - Keep the before-prompt block message for a block the operator cannot answer. A question put to the operator who is in the session needs none.
112
136
 
@@ -42,7 +42,7 @@ Access is a second gap a session cannot derive. Probed on 2026-10-02, Reddit ref
42
42
  ## Out of scope
43
43
 
44
44
  - The form a citation takes: the procedure or standard writing it
45
- - A Claude Code subject: the `claude-code-guide` agent, which `draft-doc`'s wiki sourcing step already routes to
45
+ - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `draft-doc`'s wiki sourcing step already does
46
46
  - Image generation, which makes a picture rather than finding a source
47
47
  - Loading on every web search rather than on a research-shaped request: a hook matching `WebSearch`, planned on its own
48
48
  - Whether a session already scopes searches without the skill, which only a run on a fresh research request without it would show
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: search-craft
3
- description: Carries the thinking step a session takes before it searches outside the project, naming the field, deriving who that field treats as authoritative, and running a search scoped to those sources beside an open one, plus a dated note on which sites refuse access. Use before any outside search for evidence, papers, documentation, statistics, or opinion, when a procedure loads it at its sourcing step, or when asked "find me the strongest evidence on X", "where should I look for this", "what does the research say", "find papers on", "look up the docs for", or "what are people saying about". Do NOT use to format a citation, which belongs to the surface writing it, to source a Claude Code subject, which is the `claude-code-guide` agent, or to generate an image, which is not search.
3
+ description: Carries the thinking step a session takes before it searches outside the project, naming the field, deriving who that field treats as authoritative, and running a search scoped to those sources beside an open one, plus a dated note on which sites refuse access. Use before any outside search for evidence, papers, documentation, statistics, or opinion, when a procedure loads it at its sourcing step, or when asked "find me the strongest evidence on X", "where should I look for this", "what does the research say", "find papers on", "look up the docs for", or "what are people saying about". Do NOT use to format a citation, which belongs to the surface writing it, to source a Claude Code subject, which is a direct fetch of Anthropic's docs index, or to generate an image, which is not search.
4
4
  metadata:
5
5
  family: build
6
6
  ---
@@ -87,6 +87,6 @@ These flags fire after the search has run.
87
87
  ## What this delegates
88
88
 
89
89
  - The form a citation takes: the surface writing it, such as the standard the procedure writes to
90
- - A Claude Code subject: the `claude-code-guide` agent, which `draft-doc`'s wiki sourcing step routes to
90
+ - A Claude Code subject: a direct fetch of `https://code.claude.com/docs/llms.txt` and the `.md` page it names, as `draft-doc`'s wiki sourcing step does
91
91
  - Generating an image: whatever draws the surface, since making one is not search
92
92
  - Access code a session needs repeatedly: a `canon` verb, never a script in this skill
@@ -83,6 +83,7 @@ The placement entry runs pinned to `--backend off`, so its tally stays comparabl
83
83
  | `secrets` | `canon secrets scan` | Credential-shaped values in the shipped tree | Gates |
84
84
  | `labels` | `canon labels audit` | Changed paths no row of the label map reaches | Reports |
85
85
  | `restated` | `canon gov restated` | Instructions `CLAUDE.md` states that a second surface states too | Reports |
86
+ | `rules` | `canon gov audit` | Rules past a shape limit, and here outside-practice rules short of a source ledger | Reports |
86
87
  | `counts` | `canon gov counts` | Sentences stating a closed catalog's size that disagree with the tree | Reports |
87
88
  | `census` | `canon census` | File count, extension breakdown, and line total | Reports |
88
89
  | `deps` | `canon deps audit` | Advisories against the resolved dependencies | Reports |
@@ -18,11 +18,13 @@ kind: reference
18
18
  | `rule-layout` | A flat installed-rule layout onto the `canon/`-wrapped one |
19
19
  | `scratch-evidence` | A folder a durable record cites out of `.tmp/`, with its citations |
20
20
  | `record-layout` | Review receipts, memory archives, feedback, renders, picks, and evidence into their current folders |
21
+ | `session-defaults` | The seeded session defaults into an existing `.claude/settings.json`: `Agent` and `Task` denied, auto memory off |
21
22
 
22
23
  - `skill-names` takes no `--scope` and skips the changelog and eval transcripts
23
24
  - `surface-roots` leaves `rules/`, `skills/`, `hooks/`, and `settings.json` where Claude Code reads them
24
25
  - `rule-layout` classifies each flat file against the stamp as clean, edited, or unclaimed. Clean and edited files move untouched, and an unclaimed name stays.
25
26
  - `record-layout` labels each evidence folder `(pick)` or `(evidence)` in the dry run
27
+ - `session-defaults` adds a key only when absent. It never removes a deny entry or changes a set `autoMemoryEnabled`, and a missing settings file is nothing to do.
26
28
 
27
29
  ## Output
28
30
 
@@ -43,14 +45,15 @@ Three markers keep an old spelling on a line. Each also covers the nearest non-b
43
45
 
44
46
  ## Refusals
45
47
 
46
- | Verb | Refuses when |
47
- | ------------------ | ----------------------------------------------------------------------------------- |
48
- | `records` | The project does not ignore `.canon/`. Run `canon tooling sync --write` first. |
49
- | `records` | A record folder already exists at the destination |
50
- | `surface-roots` | Any destination already exists under `canon/`, refusing the whole plan |
51
- | `scratch-evidence` | A destination is occupied |
52
- | `record-layout` | A destination already exists, each move refused on its own |
53
- | `rule-layout` | A destination holds different bytes. Neither file is touched and other moves apply. |
48
+ | Verb | Refuses when |
49
+ | ------------------ | ------------------------------------------------------------------------------------- |
50
+ | `records` | The project does not ignore `.canon/`. Run `canon tooling sync --write` first. |
51
+ | `records` | A record folder already exists at the destination |
52
+ | `surface-roots` | Any destination already exists under `canon/`, refusing the whole plan |
53
+ | `scratch-evidence` | A destination is occupied |
54
+ | `record-layout` | A destination already exists, each move refused on its own |
55
+ | `rule-layout` | A destination holds different bytes. Neither file is touched and other moves apply. |
56
+ | `session-defaults` | The settings file is not valid JSON, or `permissions` or its `deny` has another shape |
54
57
 
55
58
  A `rule-layout` destination holding the same bytes marks a duplicate, which `--write` deletes.
56
59
 
@@ -136,3 +136,14 @@ The wireframes record is retired, and nothing deletes what a project holds.
136
136
  ## Move decisions out of a held architecture record, once
137
137
 
138
138
  The toolkit no longer seeds `canon/ARCHITECTURE.md`, and a held file and its `CLAUDE.md` import stay. Move a trap a session would hit into that domain's `## Gotchas`, then delete the file and its `@canon/ARCHITECTURE.md` line.
139
+
140
+ ## Deny subagents and turn auto memory off, once
141
+
142
+ The seeded `.claude/settings.json` now denies the `Agent` and `Task` tools and sets `autoMemoryEnabled` to `false`. `canon claude sync` never rewrites a settings file you hold, so it warns while the file holds neither default. Removing the deny later to allow subagents draws no warning.
143
+
144
+ ```bash
145
+ canon migrate session-defaults --json
146
+ canon migrate session-defaults --write --json
147
+ ```
148
+
149
+ The verb only adds a key that is absent. A person who wants auto memory back sets it in their own `.claude/settings.local.json`.
@@ -200,3 +200,7 @@ files = ["index.html", "*/index.html"]
200
200
  ["canvas"]
201
201
  deps = []
202
202
  files = [".canon/canvas"]
203
+
204
+ ["design-reference"]
205
+ deps = []
206
+ files = ["canon/design"]
@@ -8,6 +8,7 @@ paths:
8
8
 
9
9
  ## Context entries
10
10
 
11
- - Load the `canon:context-fold` skill before a hand edit under `canon/context/`. It carries the entry shape and the content rules for a domain entry. Report it rather than proceeding silently when the skill does not resolve.
11
+ - Load the `canon:context-fold` skill before a hand edit under `canon/context/`, since it carries the entry shape and the content rules for a domain entry.
12
+ - Report it rather than proceeding silently when `canon:context-fold` does not resolve.
12
13
  - Before non-trivial work in a domain, read its `canon/context/<domain>/` entry. Use `canon/context/index.md` to find it.
13
14
  - Leave the entry conforming when work in its domain changes what it describes.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Route edits under .canon/plans/ to the plan-feature skill for the plan's sections, the answer contract, and its lifecycle
2
+ description: Route edits under .canon/plans/ to the plan-feature skill, and keep the five hand-edit floors a plan breaks silently
3
3
  paths:
4
4
  - '.canon/plans/**'
5
5
  ---
@@ -8,11 +8,9 @@ paths:
8
8
 
9
9
  ## Plan files
10
10
 
11
- - Load the `canon:plan-feature` skill before a hand edit under `.canon/plans/`. It carries the filename and slug, the required sections, and the suggested-and-answer contract for a feature plan. Report it rather than proceeding silently when the skill does not resolve.
11
+ - Load the `canon:plan-feature` skill before a hand edit under `.canon/plans/`, whose references own its shape and lifecycle. Report it rather than proceeding silently when it does not resolve.
12
12
  - Never fill an `- Answer:` slot on behalf of the person who owns it. A blank slot accepts the suggestion at execution time.
13
- - Never ship a question without a `- Suggested:` line. Write `- Suggested: needs your call, <why>` where the answer turns on preference.
14
- - Rewrite the `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when execution deviates from an unanswered question, leaving the slot blank. Put the same deviation in one line under the open task's `## Findings`.
13
+ - Rewrite an unanswered question's `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when execution deviates, leaving the slot blank.
15
14
  - Fetch the source a decision rests on and quote the passage under `**Sources:**`, or mark the entry `unverified`. Never cite an outside source from recall.
16
15
  - Move a shipped plan to `.canon/plans/archive/`. Never delete one.
17
16
  - Amend a plan in place when a decision changes. Do not append a second passage narrating the change.
18
- - Follow the lifecycle the `canon:plan-feature` skill carries for when a plan is written, how it is amended, and its move to the archive.
@@ -6,4 +6,6 @@ description: Write temporary files to the scratch folder structure
6
6
 
7
7
  ## Temporary files
8
8
 
9
- - Write temporary files to `.canon/tmp/<slug>/<file>.md` at the current worktree's root, a nested folder with a kebab-slug tied to the topic rather than a flat `<slug>-<file>.md`. The slug must not take one of the five reserved names `runs`, `hooks`, `handoff`, `pr`, and `render`. A skill that resolves a write at the main root instead states so in its own body.
9
+ - Write temporary files to `.canon/tmp/<slug>/<file>.md` at the current worktree's root, with a kebab-slug tied to the topic rather than a flat `<slug>-<file>.md`.
10
+ - Never take one of the reserved slugs `runs`, `hooks`, `handoff`, `pr`, and `render`.
11
+ - Write scratch at the main root instead only when a skill's own body says so.
@@ -8,4 +8,5 @@ description: Scope, size, and link a task file correctly
8
8
 
9
9
  - Only create a task for work that spans multiple sessions or has real dependencies. Handle small edits immediately without a task entry.
10
10
  - Do not add tasks retroactively for work already completed. Completed work is visible in git.
11
- - When a task needs execution detail beyond its own file, write a plan in `.canon/plans/` in the same session as the task and link to it from the task's intro paragraph. The session that executes the plan later inherits reasoning context it would otherwise have to re-derive.
11
+ - Write a plan in `.canon/plans/` when a task needs execution detail beyond its own file, and link it from the task's intro paragraph.
12
+ - Write that plan in the same session as the task, since the executing session would otherwise re-derive the reasoning behind it.
@@ -8,7 +8,8 @@ paths:
8
8
 
9
9
  ## Task files
10
10
 
11
- - Load the `canon:task-board` skill before a hand edit under `.canon/tasks/`. It carries the folder layout, filename convention, file format, origin lines, and archiving for a task file. Report it rather than proceeding silently when the skill does not resolve.
11
+ - Load the `canon:task-board` skill before a hand edit under `.canon/tasks/`, since it carries the layout, filenames, format, origin lines, and archiving of a task file.
12
+ - Report it rather than proceeding silently when `canon:task-board` does not resolve.
12
13
  - Follow the board shape the `canon:task-board` skill carries for `priority.md` and `backlog.md`, their readiness groups, and row order.
13
14
  - Never hand-edit `.canon/tasks/index.md`. A hook regenerates it from sibling frontmatter.
14
15
  - Follow the decline shape the `canon:task-board` skill carries for a task decided against.
@@ -10,5 +10,8 @@ description: Enter a linked worktree for implementation, resolve shared session
10
10
 
11
11
  ## Shared session scratch
12
12
 
13
- - Shared session scratch (`.canon/plans/`, `.canon/review/`, `.canon/tasks/`) lives at the main worktree root, not inside a linked worktree. From a linked worktree, resolve these paths against the main root via `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`. Fall back to `pwd` if not a git repo.
14
- - From a linked worktree, or from a background session that entered none, `Edit` and `Write` refuse a main-root path and redirect to a worktree copy no later session reads. Never take that redirect. Route the write the way the `session-worktree` skill states, and report it rather than proceeding silently when that skill does not resolve. It ships with the plugin and this rule ships with the CLI, so a project that installed governance alone does not have it.
13
+ - Resolve shared session scratch (`.canon/plans/`, `.canon/review/`, `.canon/tasks/`) at the main worktree root, never inside a linked worktree.
14
+ - Read the main root from `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, and fall back to `pwd` outside a git repo.
15
+ - Never take the worktree copy `Edit` and `Write` redirect a main-root path to, since no later session reads it. Revisit when Edit and Write stop redirecting a main-root path from a linked worktree.
16
+ - Route a main-root write from a linked worktree, or from a background session that entered none, the way the `session-worktree` skill states.
17
+ - Report it rather than proceeding silently when `session-worktree` does not resolve, as in a project that installed governance without the plugin.
@@ -7,10 +7,13 @@ description: Report file paths correctly for the reading surface and group them
7
7
  ## Reporting paths
8
8
 
9
9
  - After creating or modifying a file, include its path on its own line so the reader can open it. Do not paraphrase paths into prose ("the seeds folder", "your CLAUDE.md").
10
- - Emit a path in the form the surface's own instructions give, such as a markdown link where the harness asks for one, and bare where it gives none. A terminal makes a bare path clickable through its own path detection, and link markup defeats that.
11
- - That form governs a path emitted in a response. A path written into a markdown file follows the markdown standard instead, which your toolkit resolves by name, and which backticks a file reference and never repeats it as a link label.
12
- - In a linked worktree (under `.claude/worktrees/<name>/`), emit the absolute path, since the editor is rooted at the main project root and a path relative to the worktree resolves nowhere there. Prefer the form a `PostToolUse` hook hands back after a write where one is installed.
10
+ - Emit a path in the form the surface's own instructions give, such as a markdown link where the harness asks for one, and bare where it gives none.
11
+ - Never add link markup where the surface gives no form, since a terminal makes a bare path clickable through its own path detection and the markup defeats it.
12
+ - Backtick a path written into a markdown file and never repeat it as a link label, per the markdown standard. The response form above governs a response alone.
13
+ - Emit the absolute path from a linked worktree (under `.claude/worktrees/<name>/`), since the editor is rooted at the main root, where a worktree-relative path resolves nowhere.
14
+ - Prefer the form a `PostToolUse` hook hands back after a write where one is installed.
13
15
 
14
16
  ## Grouping multiple files
15
17
 
16
- - When the response covers multiple files, group paths under headers: `**Created:**`, `**Modified:**`, `**Deleted:**`. Every path under them takes that form, not the first alone. For single-file changes, the path on its own line is enough.
18
+ - Group paths under `**Created:**`, `**Modified:**`, and `**Deleted:**` headers when the response covers multiple files, with every path under them in that form.
19
+ - Put a single-file change's path on its own line, with no header.