@erclx/canon 5.39.0 → 5.41.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 (162) hide show
  1. package/README.md +39 -22
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
  4. package/claude/skills/auto-ship/SKILL.md +6 -0
  5. package/claude/skills/auto-ship/references/fan-in.md +59 -0
  6. package/claude/skills/canvas-board/SKILL.md +1 -1
  7. package/claude/skills/create-skill/references/skill.md +1 -1
  8. package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
  9. package/claude/skills/decision-escalate/SKILL.md +1 -2
  10. package/claude/skills/draft-slides/SKILL.md +2 -3
  11. package/claude/skills/draft-slides/references/deck.md +183 -0
  12. package/claude/skills/git-branch/REQUIREMENT.md +17 -6
  13. package/claude/skills/git-branch/SKILL.md +63 -7
  14. package/claude/skills/git-pr/references/evidence.md +2 -2
  15. package/claude/skills/git-pr/references/final-command.md +1 -1
  16. package/claude/skills/git-pr/references/labels.md +1 -1
  17. package/claude/skills/git-pr/references/publish.md +1 -1
  18. package/claude/skills/plan-feature/references/batches.md +48 -1
  19. package/claude/skills/plan-feature/references/plan.md +2 -0
  20. package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
  21. package/claude/skills/plan-intake-answer/SKILL.md +1 -2
  22. package/claude/skills/review-address/references/rebase-conflicts.md +7 -0
  23. package/claude/skills/review-ui/SKILL.md +3 -0
  24. package/claude/skills/review-ui/references/close-out.md +47 -0
  25. package/claude/skills/review-ui/references/post.md +3 -1
  26. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +1 -0
  27. package/claude/skills/role-orchestrator/references/orchestrator-handback.md +1 -1
  28. package/claude/skills/role-worker/REQUIREMENT.md +1 -0
  29. package/claude/skills/role-worker/SKILL.md +9 -0
  30. package/claude/skills/task-board/references/board.md +1 -1
  31. package/claude/skills/task-board/references/tasks.md +1 -1
  32. package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
  33. package/claude/skills/teach-workspace/SKILL.md +1 -2
  34. package/claude/skills/ux-measure/SKILL.md +1 -1
  35. package/docs/agents/audits.md +61 -60
  36. package/docs/agents/context-audit.md +40 -58
  37. package/docs/agents/index.md +5 -51
  38. package/docs/agents/install-and-sync.md +1 -0
  39. package/docs/agents/markdown-audit.md +53 -99
  40. package/docs/agents/records.md +37 -79
  41. package/docs/agents/sessions-transfer.md +26 -70
  42. package/docs/target/index.md +0 -1
  43. package/docs/target/migrations.md +57 -66
  44. package/docs/target/projects.md +36 -78
  45. package/docs/target/scenarios.md +9 -19
  46. package/docs/target/sync.md +27 -68
  47. package/docs/workflow/ai-workflow.md +22 -68
  48. package/docs/workflow/operating-model.md +32 -186
  49. package/docs/workflow/parallel-features.md +30 -66
  50. package/docs/workflow/skill-map-on-request.md +22 -24
  51. package/docs/workflow/skill-map.md +72 -76
  52. package/docs/workflow/visual-design-workflow.md +25 -118
  53. package/docs/workflow/zshrc-aliases.md +18 -37
  54. package/package.json +1 -1
  55. package/src/canvas/client/inspector/fields.css +4 -0
  56. package/src/canvas/index.html +6 -0
  57. package/src/claude/cases/git.ts +4 -0
  58. package/src/claude/skills-reach.ts +2 -2
  59. package/src/cli/ui.ts +3 -1
  60. package/src/commands/canvas.ts +23 -0
  61. package/src/commands/capture.ts +14 -0
  62. package/src/commands/claude.ts +13 -0
  63. package/src/commands/demo.ts +22 -0
  64. package/src/commands/deps.ts +6 -0
  65. package/src/commands/driver.ts +28 -2
  66. package/src/commands/gov.ts +52 -18
  67. package/src/commands/intake.ts +17 -0
  68. package/src/commands/labels.ts +38 -5
  69. package/src/commands/pr.ts +192 -52
  70. package/src/commands/records.ts +19 -3
  71. package/src/commands/secrets.ts +6 -0
  72. package/src/commands/sessions.ts +8 -0
  73. package/src/commands/tasks.ts +52 -0
  74. package/src/commands/teach.ts +13 -0
  75. package/src/commands/upstream.ts +25 -1
  76. package/src/commands/worktrees.ts +5 -0
  77. package/src/context/audit.ts +22 -4
  78. package/src/context/folders.ts +1 -1
  79. package/src/context/shape-gated.ts +5 -2
  80. package/src/counts/scan.ts +1 -1
  81. package/src/design/components.ts +1 -1
  82. package/src/design/document.ts +1 -1
  83. package/src/design/tokens.ts +1 -1
  84. package/src/gate/boundaries.ts +4 -1
  85. package/src/gate/measures.ts +1 -1
  86. package/src/gate/stages.ts +7 -7
  87. package/src/git/env.ts +6 -0
  88. package/src/markdown/scope.ts +11 -19
  89. package/src/pr/frames.ts +53 -9
  90. package/src/pr/lift.ts +153 -19
  91. package/src/pr/painted.ts +87 -0
  92. package/src/records/validate.ts +1 -0
  93. package/src/roots/record.ts +18 -1
  94. package/src/sandbox/census.ts +1 -1
  95. package/src/sandbox/headless/run.ts +3 -2
  96. package/src/sandbox/headless/watch.ts +3 -4
  97. package/src/slides/convert/master.ts +3 -0
  98. package/src/sync/format.ts +46 -0
  99. package/src/sync/stamp.ts +6 -0
  100. package/src/tasks/answers.ts +79 -2
  101. package/src/tasks/fan-in.ts +176 -0
  102. package/src/tasks/stack.ts +1 -1
  103. package/tooling/astro/reference.md +80 -39
  104. package/tooling/base/reference.md +63 -32
  105. package/tooling/base/seeds/canon/context/ci.md +7 -15
  106. package/tooling/base/seeds/canon/context/development.md +14 -14
  107. package/tooling/claude/reference.md +40 -22
  108. package/tooling/cloudflare/reference.md +31 -12
  109. package/tooling/go/reference.md +47 -23
  110. package/tooling/nextjs/reference.md +52 -19
  111. package/tooling/php/reference.md +35 -16
  112. package/tooling/python/reference.md +47 -30
  113. package/tooling/shell/reference.md +6 -5
  114. package/tooling/vite-react/reference.md +49 -21
  115. package/tooling/web/reference.md +131 -71
  116. package/docs/agents/canvas.md +0 -86
  117. package/docs/agents/capture.md +0 -65
  118. package/docs/agents/census.md +0 -23
  119. package/docs/agents/comments.md +0 -34
  120. package/docs/agents/context-audit-checks.md +0 -108
  121. package/docs/agents/context-classify.md +0 -101
  122. package/docs/agents/counts.md +0 -74
  123. package/docs/agents/demo.md +0 -140
  124. package/docs/agents/driver.md +0 -103
  125. package/docs/agents/gate.md +0 -90
  126. package/docs/agents/hooks.md +0 -78
  127. package/docs/agents/intake.md +0 -81
  128. package/docs/agents/key-changes.md +0 -116
  129. package/docs/agents/label-coverage.md +0 -86
  130. package/docs/agents/markdown-audit-density.md +0 -39
  131. package/docs/agents/markdown-audit-weight.md +0 -83
  132. package/docs/agents/pr-evidence-layout.md +0 -70
  133. package/docs/agents/pr-evidence.md +0 -273
  134. package/docs/agents/pr-frames.md +0 -131
  135. package/docs/agents/pr-lift.md +0 -132
  136. package/docs/agents/pr-local.md +0 -111
  137. package/docs/agents/pr-preview.md +0 -155
  138. package/docs/agents/pr-reads.md +0 -111
  139. package/docs/agents/pr-tick.md +0 -72
  140. package/docs/agents/records-push.md +0 -61
  141. package/docs/agents/records-stale.md +0 -40
  142. package/docs/agents/records-validate.md +0 -57
  143. package/docs/agents/restated.md +0 -83
  144. package/docs/agents/routing.md +0 -61
  145. package/docs/agents/rule-citations.md +0 -90
  146. package/docs/agents/sandbox.md +0 -126
  147. package/docs/agents/sessions.md +0 -128
  148. package/docs/agents/skills-audit.md +0 -120
  149. package/docs/agents/skills-reach.md +0 -64
  150. package/docs/agents/slides.md +0 -176
  151. package/docs/agents/state-scoped-risk.md +0 -105
  152. package/docs/agents/superseded.md +0 -85
  153. package/docs/agents/tasks-archive.md +0 -83
  154. package/docs/agents/tasks-plans.md +0 -152
  155. package/docs/agents/tasks-validate.md +0 -133
  156. package/docs/agents/tasks.md +0 -123
  157. package/docs/agents/teach-authoring.md +0 -118
  158. package/docs/agents/teach.md +0 -157
  159. package/docs/agents/test-order.md +0 -58
  160. package/docs/agents/upstream.md +0 -94
  161. package/docs/agents/worktrees.md +0 -118
  162. package/docs/target/standards-moved.md +0 -34
@@ -6,7 +6,7 @@ category: Agent surface
6
6
 
7
7
  # Target scenarios
8
8
 
9
- Three worked setups, each from the first session through ongoing maintenance. [Target projects](projects.md) carries the lifecycle they walk.
9
+ Three worked setups from the first session through maintenance. [Target projects](projects.md) carries the lifecycle they walk.
10
10
 
11
11
  ## Markdown-heavy project
12
12
 
@@ -15,9 +15,7 @@ cd <your-project>
15
15
  claude
16
16
  ```
17
17
 
18
- In the session, invoke `canon:target-setup`. The skill detects no framework and resolves tooling to `base` and governance to `base`. The preview marks both stacks as fallbacks, since neither came from a match, then the chain runs `canon init`.
19
-
20
- Ongoing: run `canon sync --check .` to see what has drifted, then merge seed drift by hand against the toolkit copy, or run `canon sync .` for a catch-all refresh.
18
+ Invoke `canon:target-setup`. It detects no framework, resolves tooling and governance to `base`, marks both as fallbacks in the preview, and runs `canon init`. Later, run `canon sync --check .` to see drift, merge seed drift by hand, or run `canon sync .` for a catch-all refresh.
21
19
 
22
20
  ## Web application
23
21
 
@@ -26,19 +24,15 @@ bun create vite my-app && cd my-app
26
24
  claude
27
25
  ```
28
26
 
29
- Invoke `canon:target-setup`. The skill reads `package.json` and the Vite config, resolves tooling to `vite-react` and governance to `node`, proposes `react` and the other rules its manifest matches as extras, and runs `canon init` with the resolved flags.
30
-
31
- Ongoing maintenance:
27
+ Invoke `canon:target-setup`. It reads `package.json` and the Vite config, resolves tooling to `vite-react` and governance to `node`, proposes the rules the manifest matches, and runs `canon init`.
32
28
 
33
- - What has drifted: `canon sync --check .`
34
- - Seed drift: merge by hand against the toolkit copy
35
- - Catch-all sync: `canon sync .`
36
- - Governance rule refresh only: `canon gov sync .`
37
- - Layer a new rule on top, for example `shadcn` after adopting shadcn: `canon gov install node --add shadcn .`
29
+ - Check drift with `canon sync --check .` and sync everything with `canon sync .`
30
+ - Refresh governance alone with `canon gov sync .`
31
+ - Layer a rule on top, such as `canon gov install node --add shadcn .`
38
32
 
39
33
  ## Monorepo with multiple language roots
40
34
 
41
- The repo root owns the shared `base` layer, and each language lives in its own subfolder.
35
+ The repo root owns the shared `base` layer, and each language lives in a subfolder.
42
36
 
43
37
  ```bash
44
38
  canon init --stack node --add react .
@@ -46,10 +40,6 @@ canon tooling sync vite-react ./frontend --skip base --write
46
40
  canon tooling sync python ./backend --skip base --write
47
41
  ```
48
42
 
49
- `--skip base` drops the `base` layer from each subtree sync, so husky, oxfmt, commitlint, and CI stay single at the repo root. The one exception is base's verify runner, `scripts/verify.ts` and `scripts/verify.json`, which every subtree still receives so it can verify on its own. Without it, every subtree re-drops husky, and since git honors only one `core.hooksPath` the extra hook dirs silently break. Each subtree still gets its own framework configs (oxlint, vitest, tsconfig, vite), and its own stack reference reads through `canon tooling reference <stack>`.
50
-
51
- A sync whose target sits below the git root knows it is writing into a subfolder:
43
+ `--skip base` keeps husky, oxfmt, commitlint, and CI at the root. Every subtree still receives `scripts/verify.ts` and `scripts/verify.json`, and its own framework configs.
52
44
 
53
- - It withholds `.github/`, since GitHub reads workflows only at the repository root, and names each withheld file. Run the subtree from a job in the root workflow instead, with `working-directory` set to the subtree path the sync prints, such as `working-directory: frontend`.
54
- - It installs no dependencies and adds no scripts to a subtree without a `package.json`. It names what it skipped and ends on `run 'bun init' in <path>, then sync again`.
55
- - The subtree carries no `check` script, since that lives in the root's base layer, so run `bun scripts/verify.ts` there. It skips the format phase a subtree does not declare, since the root runs them, and still fails on a missing lint, typecheck, or test script, the phases its stack's `scripts/verify.json` requires.
45
+ A sync into a subfolder withholds `.github/`, so run the subtree from the root workflow with `working-directory` set to the path the sync prints. It installs nothing into a subtree without a `package.json` and ends on `run 'bun init' in <path>, then sync again`. Run `bun scripts/verify.ts` in the subtree, since the `check` script lives at the root.
@@ -6,90 +6,49 @@ category: Agent surface
6
6
 
7
7
  # Target sync
8
8
 
9
- When the toolkit updates, a target project pulls changes per domain. There is one catch-all and several targeted entry points. A project scaffolded before a layout move runs the one-time moves in [target migrations](migrations.md) first.
9
+ A target pulls toolkit changes per domain, through one catch-all and several targeted entry points. A project scaffolded before a layout move runs [target migrations](migrations.md) first. See [install and sync](../agents/install-and-sync.md) for what each verb writes.
10
10
 
11
11
  ## Check first
12
12
 
13
- `canon sync --check <path>` reports what has drifted without writing anything. It splits each difference by cause, which is the question that decides what to do next.
13
+ `canon sync --check <path>` reports drift without writing, split by cause. `canon:target-check` groups the same state by domain and repairs nothing.
14
14
 
15
- `canon:target-check` is the same reading grouped by domain rather than by cause, run from inside the project. It reports the toolkit version, the `canon/` folder, governance rules, tooling, and seeds from the verbs that own each comparison, and reports the Claude harness as unchecked because no verb reads it. It repairs nothing, so it is what to run before deciding rather than instead of deciding.
15
+ The report opens with the binary version against the newest published one, and a version behind means run `canon upgrade` first.
16
16
 
17
- ### The binary first
17
+ | Cause | Meaning | Action |
18
+ | ----------------- | ------------------------------------------- | ---------------------------------------- |
19
+ | `stale` | Matches what the toolkit installed | Take the update |
20
+ | `customized` | Carries local edits | Decide by hand against the toolkit |
21
+ | `stranded` | Sits where an older toolkit installed it | Relocate by hand |
22
+ | `retired` | A rule the toolkit no longer ships | `canon gov sync` deletes it |
23
+ | `renamed` | A rule shipped under a new name | `canon gov sync` installs the new one |
24
+ | `seeds` | A seed the project edited | Merge by hand |
25
+ | `unmovedSurfaces` | A surface still at its `.claude/` spelling | `canon migrate surface-roots` |
26
+ | `newRules` | A rule your stack ships that you lack | `canon gov install <stack> --add <rule>` |
27
+ | `reverse` | A folder at a path the toolkit once shipped | Read its verdict below |
18
28
 
19
- The report opens by naming the binary running it. The installed version reads against the newest published one, and a version behind that points you at `canon upgrade`, since every section under it is a reading taken by whichever toolkit you happen to have. An unreachable registry reports unknown with its reason rather than failing, so `--exit-code` still gates on the drift the check measured locally and an offline machine stays green.
29
+ Attribution reads `canon/config/config.json`, falling back to `.claude/canon/config.json`. Without a stamp the report reads the toolkit's git history, which needs a clone. `newRules` installs nothing, and a target on a retired stack such as `react` or `astro` runs `canon gov detect . --stack node --json` for the rules its manifests propose.
20
30
 
21
- ### Then the causes
31
+ `reverse` marks each folder:
22
32
 
23
- A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision made by hand against the toolkit copy. A `stranded` file sits where an older toolkit installed it and the toolkit has since moved, which is a relocation the report names but no command runs. A `retired` rule is one under `.claude/rules/canon/` the toolkit no longer ships, and the next `canon gov sync` deletes it. A `renamed` rule is one the toolkit now ships under a new name, and the next sync installs the new name and deletes the old file.
33
+ - `dropped` is the toolkit's copy, with the publishing commit
34
+ - `unattributed` means the toolkit shipped the path, but the content matches no published version
35
+ - `project` means it only shares a retired name
24
36
 
25
- That attribution comes from `canon/config/config.json`, which every install and sync now writes, falling back to `.claude/canon/config.json` for a target stamped before that move. A target stamped before that path shipped is read from the retired `.claude/canon.json` instead, reported rather than migrated. Governance records a hash per installed file, plus the stack `canon gov install` was given, and tooling records the stack chain it resolved instead of any file hash, since its install runs no per-file walk to attribute.
26
-
27
- Each domain holds its own toolkit commit, so syncing governance today does not move the revision tooling measures against, and each domain reports the upstream commits touching its own source path. Running any sync stamps that domain, and the report names the ones still unstamped.
28
-
29
- A project that has never synced under a toolkit new enough to write a stamp falls back to the toolkit's own git history. Installed content matching any version that history published proves the file untouched, so it reports `stale` naming the commit it came from, and content matching no published version stays `drifted`. That fallback needs the toolkit as a git checkout. Installed from the registry it ships source without history, and the report says attribution was unavailable rather than reading every file as a local edit.
30
-
31
- Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and merged by hand, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.canon/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself. A surface still at its `.claude/` spelling with nothing under `canon/`, such as `.claude/REQUIREMENTS.md`, is reported under `unmovedSurfaces`, since rules glob the `canon/` spelling alone, and `canon migrate surface-roots` moves it. <!-- canon-keep-surface-root -->
32
-
33
- `unmigrated` currently names no domain, since snippets is the one the toolkit ever installed at the project root, and it retired outright. A leftover `.claude/snippets/` reports under `reverse` below instead.
34
-
35
- ### Rules you never received
36
-
37
- A sync refreshes the files you already hold and adds none, so your rule set is frozen at the date you installed governance while every file in it reports as current. `newRules` names a rule you could receive that your tree does not hold, which is the one section that reads your absence rather than your contents. `canon gov sync` reports the same rules per file, marked `missing`, so you see them either way you check.
38
-
39
- Take a clean section as reporting rather than as delivering. Nothing here installs, and it counts toward nothing, so pick the rules up with `canon gov install <stack>` or take one with `--add <rule>`. That separation is deliberate: adopting a rule changes what your project is governed by, which is a choice a sync has no business making for you.
40
-
41
- Since `canon gov install` records the stack you gave it, the list is read by comparing that stack's current rules against what you hold right now, with no date involved at all. That is what lets it name a rule the toolkit shipped before you last synced: nothing here depends on when you installed. A target stamped before this recording shipped falls back to the older read below.
42
-
43
- The fallback filters to what your stack can receive, read off the rule folders you already carry plus the folders holding a base rule. A rule under `lang/` or `ui/` belongs to some stacks and not others, so an unfiltered list would name rules you can never install. A target with neither a recorded stack nor a governance anchor reports nothing at all, since there is no date to measure against either.
44
-
45
- A target recorded on a stack the toolkit retired, such as `react` or `astro`, reads as having no recorded stack and takes this fallback, so it keeps receiving updates to the rules it holds and is offered new rules only in the rule folders it already carries. Run `canon gov detect . --stack node --json` to see which rules its manifests propose beyond those.
46
-
47
- In the fallback, an empty section is not proof either way when the toolkit running the check is not a full git clone. The read needs history to reach your anchor, and an install from the registry ships none, so the section goes quiet rather than saying it could not measure. Run the check from a clone before reading a clean result as a complete one. The stack-based read above is untouched by this, since it consults no history.
48
-
49
- This also closes the case where a rule arrives citing a sibling you do not have. A sync refreshing a rule can land a version pointing at a file it never installs, and the section names the missing sibling rather than the broken citation, which is enough to act on.
50
-
51
- ### What the toolkit stopped shipping
52
-
53
- The last cause runs backwards. Every one above starts from what the toolkit ships and asks whether the target matches, so a folder the toolkit dropped appears in none of them. `reverse` walks the target instead and reports a folder sitting at a top-level path the toolkit once shipped and has since deleted.
54
-
55
- Each entry carries a verdict, since a dropped folder and one the project wrote are the same bytes at the same path.
56
-
57
- - `dropped` names the commit that published the content
58
- - `unattributed` means the toolkit shipped that path and the content matches no version it published
59
- - `project` means the folder only shares a retired name
60
-
61
- A `.claude/snippets/` folder an older toolkit installed is the case this walk exists for, since the toolkit retired the domain and deleted its `snippets/` root. It reports as `dropped`, and [target migrations](migrations.md) says what to do with it.
62
-
63
- Nothing acts on any of them, and the verdict is what makes the list safe to read.
64
-
65
- Add `--json` for the machine-readable report, and `--exit-code` to fail a CI job when a target falls behind. Files the project authored itself never count toward that exit code, and neither do superseded artifacts, seed drift, tooling, or anything the reverse walk reports, since each names content the project is expected to edit or place itself. An unmigrated domain does count, because running the relocation closes it.
66
-
67
- Tooling reports under a section of its own, and `measured` there says whether the target ever recorded a chain. One that never ran a tooling sync reports unmeasured rather than clean, which is what separates tooling nobody has looked at from tooling that is current. A workspace root records nothing either way, since each package resolves its own chain.
68
-
69
- Reconcile the configs with `canon tooling diff <stack> <path>` to read which files differ, then run `canon tooling sync <stack> <path> --write` to apply them. The drift report counts categories and the diff names paths, which is the difference worth knowing before a golden config the project edited is replaced.
37
+ Add `--json` for a machine-readable report and `--exit-code` to fail CI when a target falls behind. Project-authored files, superseded artifacts, seed drift, tooling, and `reverse` never count toward that code, and an unmigrated domain does.
70
38
 
71
39
  ## Catch-all
72
40
 
73
- `canon sync <path>` runs every installed domain's sync in sequence. Safe to run on a cadence.
74
-
75
- It never touches user-owned seed files. Governance rules in `.claude/rules/` and tooling configs refresh in place. Stale `.claude/GOV.md` from earlier installs is removed.
41
+ `canon sync <path>` runs every installed domain's sync and never touches user-owned seeds.
76
42
 
77
43
  ## Targeted
78
44
 
79
- - Claude seed docs such as `CLAUDE.md` and `canon/REQUIREMENTS.md`: merge by hand against the toolkit copy, section by section, keeping the project's customizations. A `stale` seed is safe to take whole.
80
- - Governance rules already installed: `canon gov sync <path>` diffs and applies, and never adds new rules. A rule your recorded stack lists reports as `missing` instead.
81
- - Tooling configs and seeds: `canon tooling <stack> <path>` overwrites golden configs and copies each seed once, leaving an existing file alone
82
- - Reference docs for a stack: `canon tooling reference <stack>` reads and never writes, so there is nothing to sync
83
- - Index regeneration after markdown edits: `canon indexes regen`
45
+ - Seed docs such as `CLAUDE.md` and `canon/REQUIREMENTS.md`: merge by hand, keeping the project's customizations
46
+ - Installed governance rules: `canon gov sync <path>`, which adds no new rules
47
+ - Tooling configs and seeds: read differences with `canon tooling diff <stack> <path>`, then `canon tooling sync <stack> <path> --write`, which overwrites golden configs and copies each seed once
48
+ - Index regeneration: `canon indexes regen`
84
49
 
85
- Use a targeted entry point when only one surface moved upstream. Use the catch-all when the toolkit lands a bundled release.
86
-
87
- ## Verify a sync
88
-
89
- Before running a sync against a real project, run the relevant sandbox scenario. The sandbox provisions a representative project state and routes `SANDBOX_SCENARIO=sync` through the domain flow. See [sandbox](../../canon/context/sandbox/index.md) for the scenario catalog and routing patterns.
50
+ Try a scenario from [sandbox](../../canon/context/development/sandbox.md) before syncing a real project.
90
51
 
91
52
  ## Running sync from an agent session
92
53
 
93
- `canon sync .` applies every installed domain sync, then offers to commit the result and open a pull request. That last step needs a terminal. Under `CANON_NON_INTERACTIVE=1`, which is how an agent runs it, the domain syncs still apply and the git workflow is refused: the command reports the branch and commit it would have created, writes nothing to git, and exits 0. Review the working tree and commit it yourself, or rerun interactively to reach the commit and pull request options.
94
-
95
- Sync also refuses a target whose working tree is dirty, so commit or stash before running it. `canon sync --check .` has neither restriction, since it writes nothing.
54
+ `canon sync .` applies every domain sync, then offers a commit and pull request that needs a terminal. Under `CANON_NON_INTERACTIVE=1` the syncs apply, the git step is refused, and the command exits 0. Commit yourself. Sync refuses a dirty working tree, and `canon sync --check .` does not.
@@ -6,13 +6,11 @@ category: Agent surface
6
6
 
7
7
  # AI workflow reference
8
8
 
9
- A concise reference for when to reach for which tool, organized by what you're trying to do.
10
-
11
- > **Mental model:** Claude Code for everything: planning, implementation, review, docs, git, and release.
9
+ Which tool to reach for, by what you are trying to do.
12
10
 
13
11
  ## Documents
14
12
 
15
- Project docs split across three roots at the project root. What the project authors and commits lives in `canon/`, what Claude Code reads lives in `.claude/`, and every gitignored session record lives in `.canon/`, which a single ignore entry covers.
13
+ Project docs split across three roots. `canon/` holds what the project authors and commits, `.claude/` holds what Claude Code reads, and `.canon/` holds every gitignored session record.
16
14
 
17
15
  ```plaintext
18
16
  canon/
@@ -24,96 +22,52 @@ canon/
24
22
  └── rules/ ← path-scoped governance rules, written by canon gov install
25
23
 
26
24
  .canon/
27
- ├── tasks/ ← one file per task with a generated index.md, local scratch
28
- ├── plans/ ← one plan per feature, archived inside itself once it ships
29
- └── tmp/ ← deletable scratch, safe to remove without loss
25
+ ├── tasks/ ← one file per task with a generated index.md
26
+ ├── plans/ ← one plan per feature, archived once it ships
27
+ └── tmp/ ← deletable scratch
30
28
  ```
31
29
 
32
- A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. `canon migrate records` moves one project across and repoints what cites it, and `canon migrate record-tree` follows it to reach the citations inside the records themselves, which the first verb passes over because it enumerates through git. A project scaffolded before the surface move keeps its context and loose documents under `.claude/` the same way, and `canon migrate surface-roots` moves those to `canon/` with the history following each file.
33
-
34
- Three tiers of context load with different cost: always-loaded (root `CLAUDE.md` and `canon/REQUIREMENTS.md`), path-scoped lazy (`.claude/rules/<scope>.md` with `paths:` glob), and on-demand lookup (`canon/context/<domain>.md`, or `canon/context/<domain>/` once a domain outgrows one file, discovered via `canon/context/index.md`). See [the context model](../../canon/context/context-model.md) for the full picture.
30
+ A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. See [target migrations](../target/migrations.md).
35
31
 
36
- Run `canon init` to seed the `.claude/` directory, a root `CLAUDE.md` file, and `.claude/rules/` in one pass. `canon init` chains claude init and governance install. Claude Code auto-loads every file in `.claude/rules/` at session start, applying always-on rules unconditionally and path-scoped rules to files matching their `paths:` glob.
32
+ Context loads always (`CLAUDE.md` and `canon/REQUIREMENTS.md`), by path (`.claude/rules/` with a `paths:` glob), or on demand (`canon/context/`, found through its `index.md`). Run `canon init` to seed `.claude/`, `CLAUDE.md`, and the rules.
37
33
 
38
34
  ## Scenarios
39
35
 
40
36
  ### Bootstrap a new project
41
37
 
42
- See [target projects](../target/projects.md) for the scaffold decision, core domains and skips, and the full lifecycle across scaffold, add-a-domain-later, and upstream sync.
38
+ See [target projects](../target/projects.md).
43
39
 
44
40
  ### New feature
45
41
 
46
- One session works for most features. Prefer splitting across two sessions only when the feature is large enough that you want a cold, independent reviewer on the diff. Plan and implement in session 1, then review and ship in session 2.
47
-
48
- #### Session 1
49
-
50
- Work in Claude Code directly. It reads `CLAUDE.md` automatically and has full file access, no pasting needed.
51
-
52
- - When the input is a pile of findings rather than one feature, invoke `canon:plan-intake` first. It files the dump into `.canon/intake/<nn>-<slug>/`, one item per finding carrying a problem measured against the tree, a proposed fix, and a verdict, then names which items are plan-ready, which need measuring, and which are already settled.
53
- - When the backlog has grown past what anyone rereads, invoke `canon:backlog-triage`. It files one item per backlog row into an intake folder, suggesting decline, archive, keep, or promote and leaning toward decline, and once `canon:plan-intake-answer` has taken your answers, a second run applies the approved verdicts through the task verbs.
54
- - When the current state is unmeasured and more than one approach is live, invoke `canon:plan-groundwork` first. It opens a track folder under `.canon/groundwork/<nn>-<slug>/` and ends in a decision, which may be to do nothing. Skip it when the approach is already settled.
55
-
56
- Then plan and build:
57
-
58
- - Invoke `canon:plan-feature` to scan for code-level conflicts and ambiguities, confirm approach before proceeding
59
- - Implement the feature, then Claude Code runs the commands defined in `CLAUDE.md`, fixes failures, and iterates until all pass
60
- - For UI changes, invoke `canon:ui-checklist` to write what a reviewer has to look at and name any behavior shipping without a test
61
- End the session once the feature works and tests pass. Invoke `canon:context-fold` before closing to refresh any context entry the diff left untrue.
62
-
63
- The routing test is whether the repository can answer an item today. A session grepping handles the yes, and a groundwork track handles the no.
64
-
65
- A groundwork track may run experiments to settle a question, writing a fixture it reads itself under `.canon/tmp/runs/groundwork-fixtures/<slug>/` and spawning up to three billed headless runs before it asks. A fixture a headless run is pointed at sits outside the repository, since a session started under the project root inherits that project's `CLAUDE.md` and rules and would measure them instead of the arm.
66
-
67
- A spike starts against a sample, bounded on input size, duration, and spend, and scales up once the sample shows the method works. Nothing checks this, so it holds while a session reads the standard.
42
+ Plan and build in session 1, then review and ship in a fresh session 2 when you want a cold reviewer on the diff.
68
43
 
69
- What a spike leaves behind splits on whether a later reader needs the file to check a claim. Bulk input, such as a large fixture, is re-runnable and cited by nothing, so the scratch path above is the right lifetime for it. Everything a reader opens to verify a result lives inside the track in one of three folders: `evidence/` for a recording or a render, `scripts/` for the arm scripts, and `clones/` for checkouts and copies of outside material a claim rests on. The scratch tree holds only what can be deleted without loss, which none of those is.
44
+ - For a pile of findings, invoke `canon:plan-intake`, and for a grown backlog `canon:backlog-triage`
45
+ - For an unmeasured state with live approaches, invoke `canon:plan-groundwork`
46
+ - Invoke `canon:plan-feature`, implement, and run the `CLAUDE.md` commands until they pass
47
+ - For UI changes, invoke `canon:ui-checklist`
48
+ - Invoke `canon:context-fold` before closing
70
49
 
71
- #### Session 2
72
-
73
- Start a fresh Claude Code session. The diff is sufficient context for ship.
74
-
75
- - Invoke `canon:git-ship` to run the project's verify commands, sync docs, commit by concern, rename branch, and open PR
50
+ Session 2 invokes `canon:git-ship` to verify, sync docs, commit by concern, and open the pull request.
76
51
 
77
52
  ### Parallel features
78
53
 
79
- When features are independent, run them in parallel, one worktree and one session per feature. See [parallel features](parallel-features.md) for the loop in each worktree, the orchestrated flow, and the records and task board every session shares.
54
+ Run independent features in parallel, one worktree and one session each. See [parallel features](parallel-features.md).
80
55
 
81
56
  ### Autonomous ship
82
57
 
83
- For features on a mature stack, chain the post-plan pipeline in one session. Approve the plan, invoke `canon:auto-ship`, and the skill runs implement → verify → ship sequentially.
84
-
85
- - Use when the plan is tight and the stack has real verify commands and test coverage
86
- - Autoship stops on: verify failure after one fix attempt, or hook failure
87
- - A produced UI checklist does not stop it. The checklist rides to the draft pull request's evidence comment, and the closing block names how many visual boxes are still unchecked and who owes them
88
- - Every stop leaves recoverable state. Fix and resume with `/git-ship`
89
- - Skip autoship for auth, migrations, security-sensitive changes, or work where the plan itself is uncertain
90
-
91
- ### UI polish
92
-
93
- Verify the change manually in the browser. Invoke `canon:ui-checklist` if you need a written list of what to look at. For the fix itself, describe the change in Claude Code directly.
58
+ On a mature stack, approve the plan and invoke `canon:auto-ship` to implement, verify, and ship in one session.
94
59
 
95
- ### Quick fix
96
-
97
- - Verify failure or isolated bug → continue in Claude Code (it has the implementation context)
98
- - Design or planning conflict → escalate to a new Claude chat session with the relevant plan context
99
- - Fast file edit (a task file, config, renaming) → Claude Code directly, no chat needed
60
+ - It stops on a verify failure after one fix attempt, or on a hook failure, and you resume with `/git-ship`
61
+ - Skip it for auth, migrations, security-sensitive changes, or an uncertain plan
100
62
 
101
63
  ### Review
102
64
 
103
- Review runs on the pull request. An independent session invokes `canon:review-pr` once `canon:git-ship` has opened it, and the worker answers what it posts with `canon:review-address`.
65
+ An independent session invokes `canon:review-pr` once the pull request is open, and the worker answers with `canon:review-address`. A verify failure goes to the session that built it, a design conflict to a new chat session with the plan, and a review finding to the worker.
104
66
 
105
67
  ### UI-heavy project
106
68
 
107
- Before the first feature session on a UI-heavy project, pick a design tier. The tier determines seed shape, installed MCP servers, and installed plugin skills. See [visual design workflow](visual-design-workflow.md) for the framework and decision guide.
69
+ Pick a design tier before the first feature session. See [visual design workflow](visual-design-workflow.md).
108
70
 
109
71
  ## Skills
110
72
 
111
- The [skill map](skill-map.md) and its sibling [skill map on request](skill-map-on-request.md) give every skill the plugin ships one row saying when to reach for it. The first groups rows by the moment a project meets them, and the sibling holds the skills that answer a request.
112
-
113
- ## Feedback routing
114
-
115
- ```plaintext
116
- verify fails → Session 1 (it has implementation context)
117
- design fails → new Claude chat session (planning problem)
118
- review finds → Session 2 (fix alongside review, before ship)
119
- ```
73
+ The [skill map](skill-map.md) and [skill map on request](skill-map-on-request.md) give every plugin skill one row saying when to reach for it.
@@ -6,18 +6,10 @@ category: Workflow
6
6
 
7
7
  # Operating model
8
8
 
9
- A way to build fast and reliably across parallel Claude Code sessions without a
10
- loop and without losing the human review gate. One warm session holds the
11
- cross-feature call and reviews. Planning runs there or in a session of its own.
12
- Cold worker sessions build. The human launches workers and merges.
13
-
14
- This page covers the roles and the loop. For merge order and fan-out rules, see
15
- [Parallel features](parallel-features.md), and for worktree gotchas, [Claude Code and git worktrees](../../wiki/claude/worktrees.md).
9
+ One warm session holds the cross-feature call and reviews. Cold worker sessions build, and the human launches workers and merges. For merge order see [Parallel features](parallel-features.md), and for worktree gotchas see [Claude Code and git worktrees](../../wiki/claude/worktrees.md).
16
10
 
17
11
  ## Four roles
18
12
 
19
- The split is by vantage, not by capability. All four are Claude Code sessions.
20
-
21
13
  | Role | Session | Owns | Does not |
22
14
  | ------------ | ------------------------------------- | ---------------------------------------------------- | ---------------------------------- |
23
15
  | Orchestrator | One warm, long-lived session | The cross-feature call, review dispatch, merge order | Review in place, edit, merge PRs |
@@ -25,204 +17,58 @@ The split is by vantage, not by capability. All four are Claude Code sessions.
25
17
  | Planner | One session per row, warm or cold | Measure the row against the tree, write one plan | Enter a worktree, write the board |
26
18
  | Worker | One cold worktree session per feature | Implement, self-check, open PR, answer the reviewer | Write the shared board, merge |
27
19
 
28
- Each role is asserted explicitly rather than inferred. The orchestrator loads
29
- `role-orchestrator` at the start of its session, a worker loads `role-worker`,
30
- which `auto-ship` invokes at Step 0 so a dispatched build and a
31
- hand-launched one reach it on the same path, and a planner loads
32
- `role-planner` and a reviewer `role-reviewer` from the launch that dispatches
33
- it. All four are framing and boundaries rather than logic.
34
-
35
- The planner is the one role the orchestrator also performs. Per-row planning
36
- runs warm inside the orchestrator's own session or cold in a dispatched one, and
37
- the boundary between them is the cross-feature call: which rows conflict, what
38
- merges before what, and whether a row should run at all stay with the
39
- orchestrator, because a session reading the board sees blockers and file sets
40
- and can write a confident merge order off a partial picture. The per-row
41
- measurement is free to go cold, since a cold planner reads the tree rather than
42
- trusting what the task file claims.
43
-
44
- A dispatched planner owes two messages: the plan's path as the file lands, with
45
- what the task file got wrong beside it, and a block before that block becomes an
46
- interactive prompt. The plan file is its only write. A stale count, a moved line,
47
- or a path that no longer resolves is reported rather than repaired, since the
48
- task file and the board stay the orchestrator's to write.
49
-
50
- A worker that halts on a plan question it may not answer, or argues back against
51
- an instruction the tree contradicts, is working correctly. It writes neither
52
- `.canon/tasks/priority.md`, the backlog, nor a task file for work it turns up,
53
- and hands the row to the orchestrator. `role-worker` gives the reason for each.
54
-
55
- The orchestrator's cell reads every tracked file rather than every feature, and
56
- it offers no exception for a small one. A correction found while orchestrating
57
- goes to the task that owns the surface, or folds into the next task touching it,
58
- because a session that writes a change cannot review it independently afterwards
59
- and no later session recovers that vantage.
60
-
61
- Filing that row stops at the defect and the surface it was seen on. How far the
62
- defect reaches and what causes it belong to whoever plans the row, so it arrives
63
- carrying neither a count nor an asserted mechanism, and the seat that found it
64
- says as much in a plain sentence rather than supplying either. What separates the
65
- two is what a measurement decides: the blocker re-test, the branch check, and
66
- the conflict check against every track in flight all decide whether a row can
67
- start, and only a count of the defect's extent decides how big it is.
20
+ - The orchestrator loads `role-orchestrator`, a worker loads `role-worker` through `auto-ship` Step 0, and a planner and a reviewer load theirs from the launch that dispatches them
21
+ - The orchestrator decides which rows conflict, what merges first, and whether a row runs at all. Per-row planning can go cold.
22
+ - A dispatched planner writes only the plan, and reports what the task file got wrong rather than repairing it
23
+ - A worker that halts on a plan question, or argues back against an instruction the tree contradicts, is working correctly
24
+ - The orchestrator edits no tracked file. File a row with the defect and the surface, with no count or cause.
68
25
 
69
26
  ## The loop
70
27
 
71
- One feature travels this path end to end.
72
-
73
- 1. The next feature is planned with `plan-feature`, writing a plan to `.canon/plans/`. The orchestrator runs it warm when the row turns on a contract other features consume or a dependency on another row, and dispatches a planner under `role-planner` otherwise. A cold planner measures the row against the tree rather than trusting what the row claims, and it reads what is in flight by composing the live session roster with open pull requests. A bare branch or worktree is not evidence on its own, since this repository leaves both behind after a squash merge.
74
- 2. Orchestrator checks the plan waits on nobody, checks the branch is unclaimed, and checks no conflict holds the plan behind a track in flight, then dispatches a background worker with `claude --bg` against the plan, naming the branch and the model on the launch rather than leaving the worker to derive either. No count caps how many run at once. The branch travels as the argument to the worker's own worktree call, which is the one place the name is read rather than inferred. It falls back to naming the invocation for a human to run through `session-worktree` and `auto-ship` when the plan still waits on an answer only the operator can give, the branch check refuses, or a conflict holds the plan behind a track already in flight. Either way, the worker enters its own worktree, builds, self-checks, opens a PR, and stops at the PR boundary.
75
- 3. Orchestrator dispatches a reviewer under `role-reviewer` for every pull request but a release one, which posts `review-pr` findings, and `review-ui` drives any visual checklist beside it.
76
- 4. The reviewer tells the session holding that branch to run `review-address` once the pass posted a finding at any severity, resolving it with `canon sessions list --branch` and falling back to the orchestrator when none is live. The worker addresses the findings, rebases onto `origin/main` when a sibling landed first on a file it writes, then pushes a follow-up. A pass carrying only minor findings dispatches too, since the grade runs low often enough that a floor at should-fix loses fixes a worker would have made. `review-pr` states that threshold and the heading follows it, so an open heading is itself the signal to send.
77
- 5. The worker asks that reviewer for the re-review directly, and the reviewer closes the review out with `review-pr` again. The second pass reads only the commits the follow-up added, or the worker's response alone when the follow-up added none, and posts under `## Review` when it finds anything and under `## Review closed` when it finds nothing, so a reader learns from the heading whether work is still owed and takes the merge decision from the counts on the line under it. A pass finding nothing where a close-out already stands rewrites that comment to cover what it read rather than posting a second one, so the thread carries one live verdict. Repeat from step 4 until a pass closes the review. Each reviewer then runs `canon pr lift`, which lifts the draft mark once every gate it reads is clear.
78
- 6. The human reads the result and merges. After each merge, the orchestrator tells any trailing worker whose files the merged diff touches to run `review-address`, which rebases whether or not the review left anything open.
28
+ 1. Plan the next feature with `plan-feature` into `.canon/plans/`. Run it warm when the row turns on a contract other rows consume, and dispatch a planner otherwise.
29
+ 2. Check the plan waits on nobody, the branch is unclaimed, and no track in flight conflicts. Dispatch a background worker with `claude --bg`, naming the branch and the model.
30
+ 3. The worker enters its own worktree, builds, self-checks, opens a PR, and stops there.
31
+ 4. Dispatch a reviewer under `role-reviewer` for every PR but a release one. It posts `review-pr` findings, and `review-ui` drives any visual checklist.
32
+ 5. The reviewer tells the session holding the branch to run `review-address`, found with `canon sessions list --branch`, once a pass posts a finding at any severity.
33
+ 6. The worker addresses the findings, rebases onto `origin/main` if a sibling landed on its files, pushes, and asks that reviewer for a re-review of the added commits.
34
+ 7. A pass posts `## Review` while anything is open and `## Review closed` when nothing is. The reviewer then runs `canon pr lift`.
35
+ 8. The human merges. The orchestrator tells any trailing worker whose files the merge touched to run `review-address`, which rebases.
79
36
 
80
- There is no loop construct here. Each worker is a single build that halts at the
81
- PR. The merge stays a manual human gate. Reliability comes from the plan being
82
- complete enough that the cold session does not come back with questions, and
83
- from merging promptly so the next PR does not rot against a moving main.
37
+ Each worker halts at the PR, and the merge stays a human gate.
84
38
 
85
39
  ## The review layer
86
40
 
87
- The worker's chain carries no review step. The session that wrote the code is
88
- structurally blind to its own misreadings, because the same misreading wrote
89
- both the code and any review of it, so the first review a change gets is a
90
- dispatched reviewer's.
91
-
92
- - Worker gate, inside `auto-ship`: the session that wrote the code. Its job is "did I build the plan and does it pass?" The verify commands and the test order read decide whether the PR opens, and the draft mark holds the merge.
93
- - Reviewer pass, via `review-pr`: a fresh session holding one pull request, briefed with the cross-feature facts the orchestrator's wave pass found (a sibling PR in flight, a shared file, the merge order). Its job is "is this right and does it fit?" It can question the plan itself. This is the merge gate.
94
-
95
- The human read at merge is the final gate. No layer repeats another.
41
+ The first review a change gets is a dispatched reviewer's. The worker's gate inside `auto-ship` decides whether the PR opens, and the draft mark holds the merge. The reviewer pass is the merge gate.
96
42
 
97
- The orchestrator's pass also reads the pull request body against itself, which is
98
- a vantage the worker never has. This repository squash-merges, so the body
99
- becomes the commit message and the record on the trunk once the branch is gone.
100
- `canon pr key-changes` compares the paths the body's Key changes claims against
101
- its own changed-file list, and a claim the diff does not carry is a finding on
102
- the body rather than on a file. See
103
- [Key changes bijection](../agents/key-changes.md).
43
+ `canon pr key-changes` flags a Key changes claim the diff does not carry. See `canon pr key-changes --help`.
104
44
 
105
45
  ## The review channel
106
46
 
107
- Findings travel on the PR. `review-pr` posts them there.
108
- `review-address` reads them back, fixes each, replies or resolves the
109
- threads, and pushes a follow-up. `review-pr` then runs again, reading only
110
- what the follow-up added.
111
-
112
- Both halves of that loop key on a commit rather than on the pull request object,
113
- which trails the branch ref by up to a minute after a push and says nothing
114
- about the trail. `canon pr head` resolves the tip the review pass scopes its
115
- delta against, and `canon pr checks` reports the runs belonging to that tip, so a
116
- follow-up push cannot be read as green off the predecessor's completed run. See
117
- [Head-sensitive pull request reads](../agents/pr-reads.md).
118
-
119
- Three messages travel from the worker to its controller, each stated with its
120
- reason in `role-worker`: the pull request as it opens, carrying any row the
121
- build turned up, the end of each address-review pass with the new CI state, and
122
- a block before it becomes an interactive prompt. Nothing is sent on progress. An
123
- open pull request is what starts the controller's review poll, with a dispatch
124
- still silent after thirty minutes kept as a fallback.
125
-
126
- What the session channel carries is the handback instruction and the worker's
127
- reply to it, which is a notification layer over a record that stays on the PR. A
128
- reply that changes an outcome, such as a worker naming the plan question that
129
- already declined a finding, still belongs back on the PR, since the session
130
- holding it ends and the thread is what a later reader opens.
131
-
132
- Two rules put it there rather than leaving that to whoever remembers. A finding
133
- the worker declines carries the fact that settled it in the same reply body that
134
- already maps every finding, and a pass accepting that argument states the
135
- withdrawal or the regrade with what produced it instead of dropping the finding
136
- from its next comment.
137
-
138
- A reply that corrects the reviewing session rather than a finding stays off the
139
- thread. Which session holds which branch, or what gate a worker's edits pass
140
- through, changes no finding on a pull request that closes, so it goes to the task
141
- owning that surface. Nothing checks either rule, so both hold while a session
142
- applies them.
143
-
144
- A finding answered without a commit leaves the head where the first pass read it,
145
- which a gitignored record and a finding accepted as recorded both produce. The
146
- close-out is still owed there, since the newest heading is what tells an operator
147
- whether the branch is blocked, so the pass reads the worker's response rather than
148
- a delta and names its body from that response instead of from a tree that did not
149
- change.
150
-
151
- A branch `main` moved under during review, conflicting or not, is the worker's
152
- problem to close. `review-address` rebases onto `origin/main` between the fixes
153
- and the push, so one force-push carries both and the reviewer reads one delta.
154
- The staleness test sits ahead of the no-findings guard, so a branch whose review
155
- closed clean and then went stale still rebases when the skill is invoked. The
156
- re-read costs a full pass rather than a delta, since the prior reviewed commit no
157
- longer reaches the head, and `review-pr` detects that itself.
158
-
159
- The heading carries the state rather than the pass number. A pass carrying
160
- anything owed takes `## Review` and a pass carrying nothing takes
161
- `## Review closed`, so a thread can be scanned for what still owes work without
162
- opening a comment. One threshold governs the heading and the dispatch alike, and
163
- `review-pr` is where it is stated, so every other surface cites that skill
164
- rather than restating the grades.
165
-
166
- The merge decision comes off the counts on the summary line, since an open
167
- heading now covers a minor as well as a critical. One thing the pass posts sits
168
- outside those counts and inside the threshold anyway. It reads the description's
169
- Testing section against what the repository can drive, and asks about a box left
170
- unchecked for a person where a harness already covers the run. The question
171
- takes no severity, because whether a human is required is a judgment the author
172
- may hold a reason for, and it still opens the heading and sends the dispatch,
173
- because the author is the only party who can answer it.
174
-
175
- A minor the worker declines goes to the findings of the task the
176
- branch closes, since a thread does not survive the merge. Feedback kept on the
177
- PR outlives both sessions, so no human copies review between them.
47
+ Findings travel on the PR. `review-pr` posts them, `review-address` fixes them and pushes, and `review-pr` runs again on the added commits.
48
+
49
+ - `canon pr head` resolves the tip a pass scopes against, and `canon pr checks` reports the runs for it. See `canon pr head --help`.
50
+ - A worker messages its controller when the PR opens with any row it turned up, when each address pass ends with the CI state, and before a block becomes a prompt. It sends nothing on progress.
51
+ - A declined finding carries the fact that settled it in its reply body, and a minor goes to the findings of the task the branch closes
52
+ - A finding answered without a commit still owes a close-out, read from the worker's response
53
+ - A branch `main` moved under is the worker's to rebase, in the same force-push as the fixes
178
54
 
179
55
  ## Feature sizing
180
56
 
181
- The unit is fixed by the ceremony: one feature is one plan, one worktree, one
182
- PR, one review sitting. Split a feature down when a backend contract and its
183
- consumer both change, landing the contract first so no UI is built on a shaky
184
- contract. Merge a change up into an ordinary edit when it is a few lines with no
185
- new contract, skipping the plan and worktree entirely. The smell test: if the
186
- whole change does not fit in your head at review time it was too big, and if the
187
- coordination costs more than the change it was too small.
57
+ One feature is one plan, one worktree, one PR, one review sitting. Split a feature when a backend contract and its consumer both change, landing the contract first. Make a few-line change an ordinary edit.
188
58
 
189
59
  ## Where work comes from
190
60
 
191
- Two tiers hold work at different altitudes.
192
-
193
- - Tasks (`.canon/tasks/`): the active few pulled into the current turn, one file each. Gitignored, high churn. Shape governed by the `task-board` skill. `priority.md` beside them carries execution order, and `backlog.md` carries what nobody is scheduling, both shaped by the same skill.
194
- - Edits: a few lines, done immediately with no ceremony.
195
-
196
- Nothing above these sequences work into versions. Scope is stated in
197
- `canon/REQUIREMENTS.md` and reaches the board as discrete tasks, so why one
198
- task runs before its neighbors is on its row and why one group of work runs
199
- before another is carried nowhere at all.
61
+ Tasks in `.canon/tasks/` hold the active few, one file each. `priority.md` carries execution order and `backlog.md` carries what nobody schedules.
200
62
 
201
63
  ## Parallelism
202
64
 
203
- Review attention binds, and no number caps worker tracks, so stop adding once you cannot review every output. A row waits only on a conflict a merge cannot settle, which the `role-orchestrator` dispatch runbook states once. A shared file is not one: both rows build, and the branch merging second resolves any conflict in its own session after the first lands, since no practice source serializes on a file. [Fowler](https://martinfowler.com/articles/branching-patterns.html) has whoever integrates second check health "even if it's a clean merge", and [DORA](https://dora.dev/capabilities/trunk-based-development/) keeps branches to hours with no integration phase.
204
-
205
- Review splits by vantage. A reviewer under `role-reviewer` takes every pull
206
- request's read but a release one's and trades each round with the worker. The
207
- orchestrator keeps one cross-branch pass per wave over file sets and merge order.
208
-
209
- Inbound turns cost the controlling session as well, so weigh the spend before
210
- widening. A message from one of your other sessions arrives as a new turn
211
- carrying the whole accumulated context, and a recurring poll bills that window
212
- again on its own interval, which means a wide wave spends against the
213
- orchestrator rather than against any worker. `crossSessionInbound` is the one
214
- control over that and stays unset here, since `hold` and `refuse` both break the
215
- worker handback and `accept` bounds nothing.
65
+ Stop adding worker tracks once you cannot review every output. A row waits only on a conflict a merge cannot settle, as the `role-orchestrator` runbook states. A shared file is not one, and the branch merging second resolves it. See [Fowler](https://martinfowler.com/articles/branching-patterns.html) and [DORA](https://dora.dev/capabilities/trunk-based-development/).
216
66
 
217
- Unit checks run freely in many worktrees at once.
218
- A dev server, an end-to-end run, and a screenshot run alongside each other on a
219
- web stack, since every worktree derives its own port. Singleton resources (one
220
- local model server, one GPU) still serialize, as does any port a stack fixes by
221
- hand. See [Parallel features](parallel-features.md) for merge order and
222
- [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for port collisions.
67
+ - The orchestrator keeps one cross-branch pass per wave
68
+ - Checks, dev servers, and screenshots run in many worktrees at once, each on its own port, while singleton resources serialize
223
69
 
224
70
  ## Related
225
71
 
226
- - [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for the worktree mechanism and its gotchas
227
- - [Claude Code subagents](../../wiki/claude/subagents.md) for in-session parallelism without worktrees, and [blocking subagents](../../wiki/claude/permissions.md#blocking-subagents) for the `permissions.deny` rule that stops every spawn
228
- - `canon/context/claude-plugin/skill-strategy/overview.md` for how the skills in the loop are categorized
72
+ - [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for the mechanism and port collisions
73
+ - [Claude Code subagents](../../wiki/claude/subagents.md) for in-session parallelism, and [blocking subagents](../../wiki/claude/permissions.md#blocking-subagents) for the `permissions.deny` rule
74
+ - [Skill map](skill-map.md) for how the skills in the loop are categorized