@erclx/canon 5.68.0 → 5.70.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 (125) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +33 -159
  3. package/assets/brand/mark.svg +17 -9
  4. package/claude/.claude-plugin/plugin.json +1 -1
  5. package/claude/skills/app-drive/REQUIREMENT.md +5 -5
  6. package/claude/skills/app-drive/SKILL.md +17 -6
  7. package/claude/skills/app-drive/references/drive-record.md +61 -8
  8. package/claude/skills/app-drive/references/isolate.md +1 -1
  9. package/claude/skills/canon-cli/SKILL.md +2 -2
  10. package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
  11. package/claude/skills/canon-feedback/SKILL.md +1 -1
  12. package/claude/skills/design-identity/REQUIREMENT.md +4 -4
  13. package/claude/skills/design-identity/SKILL.md +7 -7
  14. package/claude/skills/{pick-by-eye → design-pick}/REQUIREMENT.md +6 -6
  15. package/claude/skills/{pick-by-eye → design-pick}/SKILL.md +19 -10
  16. package/claude/skills/{pick-by-eye → design-pick}/references/board.md +17 -11
  17. package/claude/skills/design-pick/references/design-config.md +33 -0
  18. package/claude/skills/design-record/REQUIREMENT.md +2 -2
  19. package/claude/skills/design-record/SKILL.md +1 -1
  20. package/claude/skills/design-taste/REQUIREMENT.md +2 -2
  21. package/claude/skills/design-taste/SKILL.md +3 -3
  22. package/claude/skills/design-taste/references/preflight.md +1 -1
  23. package/claude/skills/git-issue/REQUIREMENT.md +1 -1
  24. package/claude/skills/git-issue/references/issue.md +1 -1
  25. package/claude/skills/plan-feature/SKILL.md +1 -1
  26. package/claude/skills/plan-feature/references/plan.md +21 -6
  27. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  28. package/claude/skills/pr-evidence/references/evidence.md +2 -2
  29. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +3 -3
  30. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +1 -1
  31. package/claude/skills/role-orchestrator/references/orchestrator-planning-wait.md +24 -0
  32. package/claude/skills/role-planner/SKILL.md +4 -2
  33. package/claude/skills/role-worker/SKILL.md +5 -6
  34. package/claude/skills/task-board/references/tasks.md +1 -1
  35. package/claude/skills/task-complete/references/receipt-sweep.md +1 -1
  36. package/claude/skills/{ux-audit → ui-audit}/REQUIREMENT.md +3 -3
  37. package/claude/skills/{ux-audit → ui-audit}/SKILL.md +7 -7
  38. package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
  39. package/claude/skills/ui-craft/SKILL.md +1 -1
  40. package/claude/skills/ui-craft/references/copy.md +4 -1
  41. package/claude/skills/{ui-record → ui-film}/REQUIREMENT.md +6 -4
  42. package/claude/skills/{ui-record → ui-film}/SKILL.md +26 -13
  43. package/claude/skills/ui-film/references/compose-craft.md +81 -0
  44. package/claude/skills/{ui-record → ui-film}/references/config.md +9 -4
  45. package/claude/skills/{ui-record → ui-film}/references/handoff.md +17 -7
  46. package/claude/skills/{ui-record → ui-film}/references/pr-clip.md +5 -5
  47. package/claude/skills/{ui-record → ui-film}/references/take-craft.md +28 -2
  48. package/claude/skills/{ux-measure → ui-measure}/REQUIREMENT.md +3 -3
  49. package/claude/skills/{ux-measure → ui-measure}/SKILL.md +6 -6
  50. package/docs/agents/audits.md +1 -1
  51. package/docs/agents/migrate.md +13 -13
  52. package/docs/index.md +1 -0
  53. package/docs/migrations/by-hand.md +107 -0
  54. package/docs/migrations/by-verb.md +118 -0
  55. package/docs/migrations/index.md +14 -0
  56. package/docs/target/index.md +1 -2
  57. package/docs/target/projects.md +3 -3
  58. package/docs/target/sync.md +23 -3
  59. package/docs/workflow/ai-workflow.md +1 -1
  60. package/docs/workflow/skill-map-on-request.md +1 -2
  61. package/docs/workflow/skill-map.md +9 -10
  62. package/docs/workflow/visual-design-workflow.md +6 -1
  63. package/governance/ledger/claude/background.md +26 -0
  64. package/governance/ledger/skills/ui-craft/copy.md +8 -4
  65. package/governance/rules/claude/background.md +19 -0
  66. package/governance/stacks/base.toml +1 -0
  67. package/package.json +6 -4
  68. package/scripts/ci/install-playwright-deps.sh +52 -0
  69. package/scripts/core/design-sync.ts +204 -0
  70. package/scripts/core/regen-web-favicon.ts +27 -12
  71. package/scripts/core/regen-web-previews.ts +8 -1
  72. package/scripts/core/render-film.ts +179 -0
  73. package/src/capture/frame-values.ts +12 -12
  74. package/src/claude/cases/authoring.ts +2 -2
  75. package/src/claude/cases/misc.ts +1 -1
  76. package/src/claude/cases/setup.ts +0 -5
  77. package/src/claude/cases/workflow.ts +6 -6
  78. package/src/commands/fixtures/gh.sh +64 -0
  79. package/src/commands/gov.ts +33 -3
  80. package/src/commands/migrate.ts +12 -2
  81. package/src/commands/records.ts +3 -2
  82. package/src/commands/sandbox.ts +9 -2
  83. package/src/commands/take.ts +159 -11
  84. package/src/commands/tasks.ts +183 -0
  85. package/src/design/favicon.ts +85 -13
  86. package/src/design/reference.ts +98 -0
  87. package/src/design/render.ts +16 -14
  88. package/src/design/tokens.ts +4 -3
  89. package/src/gate/stages.ts +8 -2
  90. package/src/gov/audit.ts +48 -11
  91. package/src/gov/detect.ts +1 -1
  92. package/src/init/steps.ts +2 -2
  93. package/src/markdown/scope.ts +9 -14
  94. package/src/migrate/record-layout.ts +5 -3
  95. package/src/migrate/skill-names.ts +21 -4
  96. package/src/migrate/status.ts +3 -3
  97. package/src/records/validate.ts +15 -2
  98. package/src/sandbox/expect.ts +32 -0
  99. package/src/sandbox/headless/dispatch-shim.sh +15 -0
  100. package/src/sandbox/headless/dispatch.ts +12 -14
  101. package/src/sandbox/headless/run.ts +6 -3
  102. package/src/sandbox/stub-gh.sh +26 -0
  103. package/src/sandbox/stub-remote.ts +8 -29
  104. package/src/sync/engine.ts +1 -1
  105. package/src/take/camera.ts +100 -11
  106. package/src/take/film.ts +55 -4
  107. package/src/take/fixtures/input.html +138 -0
  108. package/src/take/keys.ts +193 -0
  109. package/src/take/log.ts +94 -1
  110. package/src/take/perform.ts +165 -10
  111. package/src/take/plan.ts +101 -6
  112. package/src/take/pointer.ts +2 -1
  113. package/src/take/screencast.ts +28 -3
  114. package/src/take/stepper.ts +141 -23
  115. package/src/take/zoom/NOTICE.md +1 -1
  116. package/src/tasks/launch-wait.ts +160 -0
  117. package/tooling/claude/reference.md +1 -1
  118. package/claude/skills/canon-feedback-triage/REQUIREMENT.md +0 -34
  119. package/claude/skills/canon-feedback-triage/SKILL.md +0 -98
  120. package/claude/skills/plan-ready/REQUIREMENT.md +0 -35
  121. package/claude/skills/plan-ready/SKILL.md +0 -136
  122. package/claude/skills/plan-ready/references/assembly.md +0 -75
  123. package/claude/skills/plan-ready/references/ready.md +0 -128
  124. package/docs/target/migrations.md +0 -203
  125. /package/claude/skills/{pick-by-eye → design-pick}/references/live-arms.md +0 -0
package/docs/index.md CHANGED
@@ -8,5 +8,6 @@ subtitle: One-line reference for each doc in this folder.
8
8
  One-line reference for each doc in this folder.
9
9
 
10
10
  - [Agents](agents/index.md): CLI catalog and invocation rules for agents, split by command domain. Start with overview.
11
+ - [Target migrations](migrations/index.md): One-time moves a project scaffolded under an older toolkit makes before its next sync, split by whether a canon migrate verb runs them or a person makes them by hand.
11
12
  - [Target](target/index.md): Scaffold, sync, and migrate a toolkit-managed project, with worked setups for three project shapes.
12
13
  - [Workflow](workflow/index.md): How a person and their agents run a feature, from the design loop through the parallel-session loop to the shell that launches them.
@@ -0,0 +1,107 @@
1
+ ---
2
+ title: Target migrations by hand
3
+ description: One-time moves and keep-or-delete calls a person makes by hand, which no canon migrate verb runs or detects
4
+ category: Agent surface
5
+ ---
6
+
7
+ # Target migrations by hand
8
+
9
+ Each section is a move a project scaffolded before the change it names makes by hand, since no `canon migrate` verb runs it and `canon migrate status` never lists it. The moves a verb runs, and the order to run them in, are in [target migrations by verb](by-verb.md).
10
+
11
+ ## Back records up off this machine, once
12
+
13
+ Run `canon records push` once a private repository exists. It prints the one-time setup command when it finds none, and `canon init` prints the same reminder.
14
+
15
+ ## Rename the pull request template headings, once
16
+
17
+ The template headings are now `## Key changes` and `## Technical context`, and `canon labels scan` compares case exactly. Rename them in `.github/pull_request_template.md`, or delete it and run `canon tooling sync base . --write`.
18
+
19
+ ## Delete the retired snippets, once
20
+
21
+ A project scaffolded while snippets installed may hold `.claude/snippets/` or a root `snippets/`.
22
+
23
+ ```bash
24
+ canon sync --check . --json | jq '.reverse'
25
+ ```
26
+
27
+ - `dropped` is the toolkit's copy, unchanged, so delete it
28
+ - `unattributed` is often an edited copy, so read what changed first
29
+ - `project` is the project's own content, so leave it
30
+
31
+ From the registry the walk reports `historyUnavailable`, so check both paths by hand.
32
+
33
+ ## Stop calling the standards verb, once
34
+
35
+ `canon standards <name>` is gone, and a call now fails with a too-many-arguments error. Replace each call with the skill that owns the standard, at `references/<name>.md`. <!-- canon-allow-reference: verb retired -->
36
+
37
+ | Skill | Standards |
38
+ | ----------------- | ------------------------------------------------------------- |
39
+ | `task-board` | `board`, `tasks`, `tasks-decline` |
40
+ | `context-fold` | `context` |
41
+ | `canvas-board` | `canvas`, `design` <!-- canon-keep-retired --> |
42
+ | `docs-sync` | `docs`, `readme` |
43
+ | `draw-figure` | `figures`, `mermaid` |
44
+ | `create-rule` | `rule` |
45
+ | `create-skill` | `skill`, `skill-paths`, `skill-practice`, `skill-requirement` |
46
+ | `git-branch` | `branch`, `slug` |
47
+ | `git-commit` | `commit`, `versioning` |
48
+ | `git-pr` | `pr`, `publish` |
49
+ | `markdown-craft` | `markdown` |
50
+ | `teach-workspace` | `glossary`, `teach` <!-- canon-keep-retired --> |
51
+ | `plan-groundwork` | `groundwork`, `groundwork-spikes` |
52
+ | `plan-intake` | `intake` |
53
+ | `plan-feature` | `plan`, `plan-lifecycle` |
54
+ | `plan-ready` | `ready` <!-- canon-keep-retired --> |
55
+ | `write-doc` | `requirements`, `wiki` |
56
+ | `session-map` | `session` |
57
+
58
+ The `standard` name became `skill-reference.md` in `create-skill`.
59
+
60
+ ## Keep or delete the wireframes folder, your call
61
+
62
+ The wireframes record is retired, and nothing deletes what a project holds.
63
+
64
+ - `canon/wireframes/` stays yours and unaudited. Keep it as notes or delete it.
65
+ - Delete the `@canon/wireframes/index.md` line in your `CLAUDE.md` with the folder. `canon claude sync` does not rewrite it.
66
+ - `canon gov sync` removes `.claude/rules/canon/standards/wireframes.md`
67
+
68
+ ## Keep or delete the retired product files, your call
69
+
70
+ The learning workspace, deck renderer, app recorder, canvas, and design install are retired with their verbs, and nothing deletes what a project holds.
71
+
72
+ - `.canon/teach/` holds HTML that opens as it is <!-- canon-keep-retired -->
73
+ - `.canon/slides/` and a `demos/` folder hold sources nothing renders any more, so delete them once nothing cites them <!-- canon-keep-retired -->
74
+ - Move the `.claude/design/project/` values, `fonts/`, and `fonts.css` to the stylesheet your `canon/DESIGN.md` lead names, then delete `.claude/design/`
75
+
76
+ A reference to a retired skill takes a hand edit.
77
+
78
+ - Replace a `canon:teach-workspace` reference with `canon:teach-craft` by hand, since `canon migrate skill-names` does not rewrite it <!-- canon-keep-retired -->
79
+ - Delete a `canon:make-deck`, `canon:script-screencast`, `canon:record-screencast`, `canon:read-frames`, or `canon:video-craft` reference, since none has a successor <!-- canon-keep-retired -->
80
+ - Delete a `canon:canvas-board` reference too. Frameboard, which `canon:design-pick` drives, reads each `.canon/canvas/` folder as a project, so move a kept page under one <!-- canon-keep-retired -->
81
+
82
+ ## Move decisions out of a held architecture record, once
83
+
84
+ 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.
85
+
86
+ ## Move the capture cases out of the harness, once
87
+
88
+ A web project's `e2e/screenshot.ts` is a config. It now loads `CASES` from a seeded `e2e/capture/cases.ts` that sync copies once and never overwrites. A harness you edited is held on `--write`, so the new one lands only once you pass `--replace e2e/screenshot.ts`.
89
+
90
+ - Copy your cases from the old `e2e/screenshot.ts` into `e2e/capture/cases.ts`, then sync with `--replace e2e/screenshot.ts`.
91
+ - Evidence now defaults to `e2e/evidence/`. Set `export const EVIDENCE_ROOT = 'evidence'` in `e2e/capture/cases.ts` to keep a committed baseline at the old path.
92
+ - A run from a folder with no `e2e/capture/cases.ts` exits 1 and names the file.
93
+
94
+ ## Fold the ui rules onto one pointer, once
95
+
96
+ Eleven ui rules moved unchanged into the `ui-craft` skill, being `a11y`, `keyboard`, `pointer`, `forms`, `motion`, `ux-controls`, `ux-completeness`, `surface-capture`, `copy`, `interface-casing`, and `link-behavior`. Update the plugin, then sync, which folds each one you hold and `design-taste.md` onto one `craft.md` pointer without local edits.
97
+
98
+ ```bash
99
+ canon gov sync .
100
+ ```
101
+
102
+ ## Group a long paths section in `CLAUDE.md`, once
103
+
104
+ The `## Key paths` section of `CLAUDE.md` now keeps to 5 bullets in a row, and every other section stays exempt. `canon claude sync` never rewrites a `CLAUDE.md` you hold, so it warns with the line of each longer run.
105
+
106
+ - Regroup the section by hand under H3s, each opening on a one-sentence lead.
107
+ - List `CLAUDE.md` in `canon/config/markdown.toml` to gate it from then on.
@@ -0,0 +1,118 @@
1
+ ---
2
+ title: Target migrations by verb
3
+ description: One-time moves a canon migrate verb runs, for a project scaffolded under an older toolkit, in the order canon migrate status lists them
4
+ category: Agent surface
5
+ ---
6
+
7
+ # Target migrations by verb
8
+
9
+ Each section is a move a `canon migrate` verb runs once, for a project scaffolded before the change it names. Run `canon upgrade` first, then `canon migrate status --json` to list the moves still pending in the order to run them. A pending verb with no section here, such as `scratch-evidence` or `rename`, is in [migrate](../agents/migrate.md).
10
+
11
+ `canon:target-update` is the guided path through both, running the moves in that order once you approve its preview. The moves no verb runs are in [target migrations by hand](by-hand.md), and the recurring sync that follows is in [target sync](../target/sync.md).
12
+
13
+ ## Move the records first, once
14
+
15
+ Gitignored session records, being the task board, plans, review reports, and scratch, moved from `.claude/` to `.canon/`. Run these from inside the project, and read the `ok` field of the `--json` record rather than the exit code.
16
+
17
+ ```bash
18
+ canon tooling sync claude . --write
19
+ canon migrate records --json
20
+ canon migrate records --write --json
21
+ ```
22
+
23
+ The first line takes the `.canon/` ignore entry. The second reports and the third applies, repointing files that cite a moved folder and deleting a `.gitignore` line `.canon/` covers, as `dropped`. A line naming an old path keeps it via `canon-keep-record-root` on that line or the nearest non-blank one above.
24
+
25
+ Then sweep the citations inside the records, which the verb above never reaches.
26
+
27
+ ```bash
28
+ canon migrate record-tree --json
29
+ canon migrate record-tree --write --json
30
+ ```
31
+
32
+ It covers `diagrams`, `memory`, `plans`, `proposals`, `review`, `tasks`, and `teach`. Read the report before `--write`. The record tree is untracked, and a wrong rewrite has no undo.
33
+
34
+ ## Move the design board to `board/`, once
35
+
36
+ A pick round with no board named now drafts in `.canon/board/`, the folder Frameboard reads, rather than `.canon/canvas/`. Stop any `frameboard serve` on the old folder first.
37
+
38
+ ```bash
39
+ canon migrate record-layout --json
40
+ canon migrate record-layout --write --json
41
+ ```
42
+
43
+ A project holding both folders gets a collision, and neither moves. A `board` key in `design.toml` naming `.canon/canvas` stays as written, so update it by hand.
44
+
45
+ ## Move rules off the flat layout, once
46
+
47
+ Installed rules moved from `.claude/rules/<subdir>/` to `.claude/rules/canon/<subdir>/`. On the flat layout `canon gov sync` exits 0 reporting `No governance surfaces found in target`, and `canon gov install` lands a second copy.
48
+
49
+ ```bash
50
+ canon migrate rule-layout --json
51
+ canon migrate rule-layout --write --json
52
+ ```
53
+
54
+ Run it once, ahead of `canon gov sync` or `canon gov install`.
55
+
56
+ ## Rename the skill citations, once
57
+
58
+ Plugin skills dropped their `claude-` prefix, so `canon:claude-docs` is now `canon:context-fold`. Five drafters merged into `write-doc`, seven `draft-` skills took verb-first names, and four joined their family. No old name keeps a pointer, and `canon migrate skill-names --write` moves a project. <!-- canon-keep-retired -->
59
+
60
+ | Old name | New name |
61
+ | ------------------ | ----------------------------------------------- |
62
+ | `draft-doc` | `write-doc` <!-- canon-keep-retired --> |
63
+ | `draft-figure` | `draw-figure` <!-- canon-keep-retired --> |
64
+ | `draft-identity` | `design-identity` <!-- canon-keep-retired --> |
65
+ | `draft-slides` | `make-deck` <!-- canon-keep-retired --> |
66
+ | `draft-and-pick` | `design-pick` <!-- canon-keep-retired --> |
67
+ | `draft-ready` | `plan-ready` <!-- canon-keep-retired --> |
68
+ | `draft-screencast` | `script-screencast` <!-- canon-keep-retired --> |
69
+ | `pick-by-eye` | `design-pick` <!-- canon-keep-retired --> |
70
+ | `ui-record` | `ui-film` <!-- canon-keep-retired --> |
71
+ | `ux-audit` | `ui-audit` <!-- canon-keep-retired --> |
72
+ | `ux-measure` | `ui-measure` <!-- canon-keep-retired --> |
73
+
74
+ Replace a citation of a skill with no successor by hand, or delete the sentence.
75
+
76
+ - `canvas` is now `canvas-board`. The sweep rewrites only `canon:canvas` and `skills/canvas`, so replace a bare mention by hand. <!-- canon-keep-retired -->
77
+ - `draft-ready` is rewritten only as `canon:draft-ready` and `skills/draft-ready`, since bare it also describes a pull request, so replace a bare mention by hand. <!-- canon-keep-retired -->
78
+ - `design-extract` and `sketch-design` are replaced by `canon:canvas-board`. <!-- canon-keep-retired -->
79
+ - `review-branch`, `seed-sync`, `restate-plainly`, `bash-cli-script`, `canon-operator`, `canon-rollout`, and `canon-feedback-triage` have no successor <!-- canon-keep-retired -->
80
+ - `create-standard`, `markdown-propose`, `memory-review`, `project-commands`, `repo-metadata`, `ux-walkthrough`, and `plan-ready` have no successor <!-- canon-keep-retired -->
81
+
82
+ The `memory` record kind left `canon records`, so `canon records validate memory` refuses as an unknown kind and `canon records migrate` is gone.
83
+
84
+ - `canon repo metadata`, `canon autoship`, and the `120-bash` rule are gone, and `canon gov sync` removes the rule <!-- canon-keep-retired -->
85
+ - `memory-capture`, the `603-memory` rule, and the `memory` standard are gone, so send a lesson to the context entry that owns the fact <!-- canon-keep-retired -->
86
+
87
+ Two held files run, `.husky/post-merge` and `.claude/hooks/pr-create-log.sh`, and a stale copy calls a missing binary or names a removed skill. Resync what the toolkit owns before sweeping what the project wrote, and run the second line once per stack, naming a held hook with `--replace`.
88
+
89
+ ```bash
90
+ canon gov sync
91
+ canon tooling sync <stack> . --write
92
+ canon migrate skill-names --json
93
+ canon migrate skill-names --write --json
94
+ ```
95
+
96
+ ## Move the surfaces off `.claude/`, once
97
+
98
+ `context/`, `wireframes/`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`, and the install stamp folder, now `canon/config/`, moved under `canon/`. `rules/`, `skills/`, `hooks/`, and `settings.json` stay where Claude Code reads them.
99
+
100
+ ```bash
101
+ canon migrate surface-roots --json
102
+ canon migrate surface-roots --write --json
103
+ ```
104
+
105
+ It moves each surface with `git mv` and repoints every tracked citation. No other command notices a surface left at `.claude/`.
106
+
107
+ ## Deny subagents and merges, and turn auto memory off, once
108
+
109
+ The seeded `.claude/settings.json` now denies the `Agent` and `Task` tools and both merge commands, and sets `autoMemoryEnabled` to `false`. `canon claude sync` never rewrites a settings file you hold, so it warns while the file holds no default or lacks a merge entry. Removing `Agent` and `Task` later draws no warning.
110
+
111
+ ```bash
112
+ canon migrate session-defaults --json
113
+ canon migrate session-defaults --write --json
114
+ ```
115
+
116
+ 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`.
117
+
118
+ The verb adds `Bash(canon pr merge:*)` and `Bash(gh pr merge:*)` so a session cannot merge. A project migrated before them runs `--write` once more, which also restores `Agent` and `Task` for a person who removed them to allow subagents, so remove them again after.
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: Target migrations
3
+ subtitle: One-time moves a project scaffolded under an older toolkit makes before its next sync, split by whether a canon migrate verb runs them or a person makes them by hand.
4
+ category: Agent surface
5
+ ---
6
+
7
+ # Target migrations
8
+
9
+ One-time moves a project scaffolded under an older toolkit makes before its next sync, split by whether a canon migrate verb runs them or a person makes them by hand.
10
+
11
+ ## Agent surface
12
+
13
+ - [Target migrations by hand](by-hand.md): One-time moves and keep-or-delete calls a person makes by hand, which no canon migrate verb runs or detects
14
+ - [Target migrations by verb](by-verb.md): One-time moves a canon migrate verb runs, for a project scaffolded under an older toolkit, in the order canon migrate status lists them
@@ -10,7 +10,6 @@ Scaffold, sync, and migrate a toolkit-managed project, with worked setups for th
10
10
 
11
11
  ## Agent surface
12
12
 
13
- - [Target migrations](migrations.md): One-time moves a project scaffolded under an older toolkit runs before its next sync
14
13
  - [Target projects](projects.md): Scaffold, add domains later, and sync upstream drift in a toolkit-managed project
15
14
  - [Target scenarios](scenarios.md): Worked setups for a markdown-heavy project, a web application, and a monorepo
16
- - [Target sync](sync.md): Check what drifted in a toolkit-managed project and pull it in, per domain or all at once
15
+ - [Target sync](sync.md): Check what drifted in a toolkit-managed project and pull it in, per domain or all at once, and update canon itself
@@ -56,7 +56,7 @@ Keep the `## Scripts` table in `canon/context/development/local-loop.md` current
56
56
  Before the first feature session:
57
57
 
58
58
  1. Fill `canon/REQUIREMENTS.md` with the problem, goals, and non-goals. The seed's 600-word cap gates under `canon context audit`.
59
- 2. For a UI project, write `canon/DESIGN.md` from the seed and name the stylesheet in its lead, or work the direction out with `canon:pick-by-eye`
59
+ 2. For a UI project, write `canon/DESIGN.md` from the seed and name the stylesheet in its lead, or work the direction out with `canon:design-pick`
60
60
  3. Optionally invoke `canon:draw-figure` for an architecture view. The Mermaid CLI downloads on first use.
61
61
  4. Start the feature loop in [AI workflow](../workflow/ai-workflow.md)
62
62
 
@@ -84,11 +84,11 @@ Install one domain without re-running `canon init`.
84
84
  - A project-specific rule: invoke `canon:create-rule`, which writes into `.claude/rules/project/`. A rule under `.claude/rules/canon/` is deleted on the next sync.
85
85
  - An `index.md` system for a markdown-heavy folder: invoke `canon:target-setup indexes`
86
86
 
87
- For a leftover `.claude/snippets/` see [target migrations](migrations.md).
87
+ For a leftover `.claude/snippets/` see [target migrations by hand](../migrations/by-hand.md).
88
88
 
89
89
  ## Sync upstream drift
90
90
 
91
- A project scaffolded before a layout move runs the one-time moves in [target migrations](migrations.md) first. [Target sync](sync.md) covers reading drift and running a sync. [Target scenarios](scenarios.md) walks three worked setups.
91
+ A project scaffolded before a layout move runs the one-time moves in [target migrations](../migrations/index.md) first. [Target sync](sync.md) covers reading drift and running a sync. [Target scenarios](scenarios.md) walks three worked setups.
92
92
 
93
93
  ## Related
94
94
 
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  title: Target sync
3
- description: Check what drifted in a toolkit-managed project and pull it in, per domain or all at once
3
+ description: Check what drifted in a toolkit-managed project and pull it in, per domain or all at once, and update canon itself
4
4
  category: Agent surface
5
5
  ---
6
6
 
7
7
  # Target sync
8
8
 
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.
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/index.md) first. See [install and sync](../agents/install-and-sync.md) for what each verb writes.
10
10
 
11
11
  ## Check first
12
12
 
@@ -36,6 +36,26 @@ Attribution reads `canon/config/config.json`, falling back to `.claude/canon/con
36
36
 
37
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.
38
38
 
39
+ ## Update canon itself
40
+
41
+ Nothing refreshes on its own. Claude Code ships auto-update off for third-party marketplaces, so an installed copy serves whatever version it was installed at until you refresh it.
42
+
43
+ ```bash
44
+ claude plugin marketplace update canon
45
+ claude plugin update canon@canon
46
+ canon upgrade
47
+ ```
48
+
49
+ The first two update the skills, the third updates the CLI, and they move independently. Restart Claude Code, or run `/reload-plugins`, to pick the skills up.
50
+
51
+ `canon upgrade` reads the package manager off its own install path and reinstalls with that one. It names what it detected before it runs anything, and it refuses a source checkout rather than reinstalling over your clone.
52
+
53
+ ### Checking for drift
54
+
55
+ `canon sync --check` and `canon claude skills drift` both report the installed version against the newest published one, and neither changes its exit code over it, so an offline machine reads unknown rather than red.
56
+
57
+ To stop doing this by hand, turn auto-update on once under `/plugin` in the Marketplaces tab. Confirm what you are running with `canon --version` and `claude plugin list`.
58
+
39
59
  ## Catch-all
40
60
 
41
61
  `canon sync <path>` runs every installed domain's sync and never touches user-owned seeds.
@@ -48,7 +68,7 @@ Add `--json` for a machine-readable report and `--exit-code` to fail CI when a t
48
68
  - Tooling dependencies: a dependency on a later major than the stack pins reads as `ahead`, and sync leaves it
49
69
  - Index regeneration: `canon indexes regen`
50
70
 
51
- After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:ux-audit`. `--json` writes `{ "coverage": [{ "rule", "paths", "files", "ui" }] }` to stdout, empty when nothing was copied, with `files` null outside git. The report never changes the exit code.
71
+ After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:ui-audit`. `--json` writes `{ "coverage": [{ "rule", "paths", "files", "ui" }] }` to stdout, empty when nothing was copied, with `files` null outside git. The report never changes the exit code.
52
72
 
53
73
  Try a scenario from [sandbox](../../canon/context/development/sandbox.md) before syncing a real project.
54
74
 
@@ -27,7 +27,7 @@ canon/
27
27
  └── tmp/ ← deletable scratch
28
28
  ```
29
29
 
30
- A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. See [target migrations](../target/migrations.md).
30
+ A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. See [target migrations by verb](../migrations/by-verb.md).
31
31
 
32
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.
33
33
 
@@ -15,11 +15,10 @@ These skills serve a request rather than a moment. With the [skill map](skill-ma
15
15
  | `canon:create-rule` | A project rule the toolkit does not ship |
16
16
  | `canon:create-skill` | A new `SKILL.md` |
17
17
  | `canon:write-doc` | A new `docs/` page, context entry, or `README.md` |
18
- | `canon:plan-ready` | Finished files a worker should copy |
19
18
  | `canon:draw-figure` | A figure or architecture view inside a doc |
20
19
  | `canon:ci-workflow` | A GitHub Actions workflow file |
21
20
  | `canon:design-identity` | A logo mark and social card |
22
- | `canon:ui-record` | Real footage of the app for a video |
21
+ | `canon:ui-film` | Real footage of the app for a video |
23
22
 
24
23
  ## Answer a question at any point
25
24
 
@@ -24,7 +24,7 @@ Groups run in the order a project meets them. Every name `canon claude skills li
24
24
  | `canon:backlog-triage` | The backlog needs pruning |
25
25
  | `canon:plan-groundwork` | The state is unmeasured and approaches compete |
26
26
  | `canon:decision-escalate` | Open decisions turn on your preference |
27
- | `canon:pick-by-eye` | The call is taste, wanting candidates side by side |
27
+ | `canon:design-pick` | The call is taste, wanting candidates side by side |
28
28
  | `canon:task-board` | A decided item needs a file on the board |
29
29
  | `canon:plan-feature` | The approach is settled and needs a plan |
30
30
  | `canon:codebase-layout` | A change adds a file and needs a folder |
@@ -53,8 +53,8 @@ Groups run in the order a project meets them. Every name `canon claude skills li
53
53
  | Skill | When to use |
54
54
  | ----------------------- | ---------------------------------------------- |
55
55
  | `canon:document-health` | Documents must answer for length and staleness |
56
- | `canon:ux-audit` | To read UI source for missing states |
57
- | `canon:ux-measure` | To measure paint, processor, and layout cost |
56
+ | `canon:ui-audit` | To read UI source for missing states |
57
+ | `canon:ui-measure` | To measure paint, processor, and layout cost |
58
58
  | `canon:app-drive` | To drive a built app with the operator |
59
59
 
60
60
  ## Ship it
@@ -100,10 +100,9 @@ Groups run in the order a project meets them. Every name `canon claude skills li
100
100
 
101
101
  ## Keep the project current with the toolkit
102
102
 
103
- | Skill | When to use |
104
- | ----------------------------- | ------------------------------------------------------- |
105
- | `canon:target-check` | In a target, to compare each domain with the toolkit |
106
- | `canon:target-update` | After a release, to catch a target up to the toolkit |
107
- | `canon:document-repair` | Rewrite a failing docs folder to the limits and gate it |
108
- | `canon:canon-feedback` | The toolkit is broken, missing, or off |
109
- | `canon:canon-feedback-triage` | In the toolkit repo, to file feedback issues |
103
+ | Skill | When to use |
104
+ | ----------------------- | ------------------------------------------------------- |
105
+ | `canon:target-check` | In a target, to compare each domain with the toolkit |
106
+ | `canon:target-update` | After a release, to catch a target up to the toolkit |
107
+ | `canon:document-repair` | Rewrite a failing docs folder to the limits and gate it |
108
+ | `canon:canon-feedback` | The toolkit is broken, missing, or off |
@@ -72,7 +72,12 @@ A close posts as `## UI review closed`. The reviewers lift the draft mark on the
72
72
 
73
73
  ## Design authoring
74
74
 
75
- Most projects author design in the loop above and need nothing more. Start with `canon:pick-by-eye`, which drafts candidates as frames on a [Frameboard](https://www.npmjs.com/package/frameboard) board and takes your pick, then record the pick with `canon:design-record`. `canon:design-identity` drafts a logo mark and social card the same way.
75
+ Most projects author design in the loop above and need nothing more. Start with `canon:design-pick`, which drafts candidates as frames on a [Frameboard](https://www.npmjs.com/package/frameboard) board and takes your pick, then record the pick with `canon:design-record`. `canon:design-identity` drafts a logo mark and social card the same way.
76
+
77
+ A pick round drafts on `.canon/board/` unless the project names another board in `canon/config/design.toml`.
78
+
79
+ - Set `board` when your design sync reads another Frameboard board, so the picked frame lands without a redraw.
80
+ - Leave `project` unset to keep rounds in their own `picks` project on that board.
76
81
 
77
82
  A graphical tool earns its place when design is the product, a designer owns it, and it changes more often than code. Then the tool is the source of truth, and `canon/DESIGN.md` carries a top note naming the upstream project.
78
83
 
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: Background rule ledger
3
+ description: Decisions behind governance/rules/claude/background.md, one row per bullet
4
+ ---
5
+
6
+ # Background rule ledger
7
+
8
+ The rule is a core rule, so every row is a house choice rather than a citation. Each names what goes wrong without its bullet and the option the bullet beat, with the date it was decided.
9
+
10
+ ## Slow commands
11
+
12
+ | Bullet | Source | Read |
13
+ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
14
+ | Background past about a minute | House choice: a foreground run holds the conversation, so the operator waits on a check they could have talked over. It beat a warning hook, which would only warn and still let the run block | 2026-10-26 |
15
+ | Name the slow kinds | House choice: a minute is a guess made before the run, and with no cases to match a session reads a full check as quick. It beat the threshold alone | 2026-10-26 |
16
+ | Keep a seconds command foreground | House choice: each wake costs a turn, so backgrounding a quick command spends two turns where one did. It beat backgrounding every command | 2026-10-26 |
17
+ | End the turn on one status line | House choice: a turn that stops silently leaves the operator unable to tell a wait from a stall. It beat ending on the tool call alone | 2026-10-26 |
18
+ | Keep working beside a server | House choice: a dev server or a watch never exits, so a session awaiting its wake waits forever. It beat treating every background command as awaited | 2026-10-26 |
19
+
20
+ ## Waking
21
+
22
+ | Bullet | Source | Read |
23
+ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
24
+ | Act on the wake, never a guess | House choice: a session guessing a command is done reads a partial output as the result. It beat checking the output file on a hunch | 2026-10-26 |
25
+ | No sleep, poll, or scheduled wait | House choice: a foreground sleep or poll holds the conversation the rule freed, and a scheduled prompt spends a turn on every check. It beat all three as ways to wait on one command | 2026-10-26 |
26
+ | Keep a skill's own wait | House choice: a skill owns the verb and the timeout it waits on, such as a review-state wait, and one rule-wide wait would override it. It beat a single wait for every caller | 2026-10-26 |
@@ -13,10 +13,13 @@ The four casing sections rest on the GOV.UK style guide, which sets sentence cas
13
13
 
14
14
  ## Punctuation
15
15
 
16
- | Bullet | Source | Read |
17
- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
18
- | No em dash or semicolon | House choice: both read as generated copy in an interface, and a comma, a period, or a split sentence carries the same meaning in a shorter line | 2026-10-18 |
19
- | No trailing label punctuation | [Button](https://design-system.service.gov.uk/components/button/): every example label, such as "Start now", "Sign in", and "Continue", carries no trailing punctuation | 2026-10-18 |
16
+ | Bullet | Source | Read |
17
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
18
+ | No em dash or semicolon | House choice: both read as generated copy in an interface, and a comma, a period, or a split sentence carries the same meaning in a shorter line | 2026-10-18 |
19
+ | No end punctuation but a question mark | [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style): page titles should "not have a full stop at the end", and [Button](https://design-system.service.gov.uk/components/button/) labels such as "Start now" and "Continue" carry none. Every other kind in the list, from headings to taglines, is a house choice by analogy to the title and the button. [Question pages](https://design-system.service.gov.uk/patterns/question-pages/) keep the question mark, since "Page headings can be questions or statements", as in "What is your date of birth?". | 2026-10-27 |
20
+ | One-sentence tagline | House choice: a period inside a tagline makes it prose, which the short-string rule then has to end with a period, so one sentence keeps it a title-like string | 2026-10-27 |
21
+ | One-sentence error, no period | [Error message](https://design-system.service.gov.uk/components/error-message/): every example, such as "Enter how many hours you work a week" and "Name must be 35 characters or less", ends with no full stop | 2026-10-27 |
22
+ | Prose keeps its period | House choice by analogy to [A to Z of GOV.UK style](https://www.gov.uk/guidance/style-guide/a-to-z-of-gov-uk-style), whose summaries should "end with a full stop". The reach to body copy, multi-sentence messages, and quoted text is canon's. | 2026-10-27 |
20
23
 
21
24
  ## Button copy
22
25
 
@@ -86,6 +89,7 @@ Every bullet the rewrite removed or reshaped, grouped by why.
86
89
 
87
90
  ### Merged or reworded
88
91
 
92
+ - Widened the button-label punctuation bullet to every short rendered string, since board frames shipped tagline periods under the narrower wording.
89
93
  - Merged the imperative verb and padded phrasing bullets. The `Save` over `Save changes` example went, since GOV.UK adds words "to better describe the action".
90
94
  - Merged "keep messages short and actionable" and "one sentence maximum" into the plain language bullet.
91
95
  - Reworded the error example to `Enter an email address`, the instruction form GOV.UK prefers over a description.
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: Run a command that may take more than about a minute in the background and resume on the harness wake, so the operator keeps the conversation
3
+ ---
4
+
5
+ # Background standards
6
+
7
+ ## Slow commands
8
+
9
+ - Start a command that may run past about a minute with `run_in_background: true`, since a foreground run holds the conversation. Revisit when a foreground Bash call stops blocking the turn.
10
+ - Treat a full check, a sandbox run, a capture or render, a build, and a wait on another session as slow.
11
+ - Keep a command expected to finish in seconds in the foreground, since each wake costs a turn.
12
+ - End the turn on one line naming what runs, when the next step needs that command's result.
13
+ - Keep working beside a server or a watch the session never waits on, since it never exits and its wake never comes.
14
+
15
+ ## Waking
16
+
17
+ - Act on the wake the harness sends when an awaited command exits, never on a guess about when it is done. Revisit when a background Bash command stops waking the session at exit.
18
+ - Never wait with a foreground `sleep`, a foreground poll loop, or a scheduled prompt for one wait. The background run and its wake replace all three.
19
+ - Keep a skill's own wait as the skill states it, since the skill owns the verb and the timeout it waits on.
@@ -12,4 +12,5 @@ rules = [
12
12
  "tasks",
13
13
  "plan",
14
14
  "markdown",
15
+ "background",
15
16
  ]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "5.68.0",
4
+ "version": "5.70.0",
5
5
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -25,9 +25,9 @@
25
25
  "access": "public"
26
26
  },
27
27
  "scripts": {
28
- "format": "oxfmt . && prettier --write --log-level warn 'web/**/*.astro' && shfmt --write --indent 2 scripts/ tooling/ claude/",
29
- "check:format": "oxfmt --check . && prettier --check --log-level warn 'web/**/*.astro' && shfmt --diff --indent 2 scripts/ tooling/ claude/",
30
- "check:shell": "find scripts tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
28
+ "format": "oxfmt . && prettier --write --log-level warn 'web/**/*.astro' && shfmt --write --indent 2 scripts/ tooling/ claude/ src/",
29
+ "check:format": "oxfmt --check . && prettier --check --log-level warn 'web/**/*.astro' && shfmt --diff --indent 2 scripts/ tooling/ claude/ src/",
30
+ "check:shell": "find scripts tooling claude src .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
31
31
  "check:lint": "oxlint --disable-nested-config --max-warnings 0",
32
32
  "check:types": "tsc --noEmit",
33
33
  "check:install": "bun scripts/core/install-check.ts",
@@ -42,6 +42,8 @@
42
42
  "canon:sandbox:reset": "canon sandbox reset",
43
43
  "web:tokens": "bun src/cli.ts design css --no-components > web/src/styles/tokens.css.new && (echo '/* Generated by `canon design css --no-components`. Regenerate with `bun run web:tokens`. Do not hand-edit. */'; cat web/src/styles/tokens.css.new) > web/src/styles/tokens.css && rm web/src/styles/tokens.css.new",
44
44
  "web:dev": "cd web && astro dev",
45
+ "film:render": "bun scripts/core/render-film.ts",
46
+ "design:sync": "bun scripts/core/design-sync.ts",
45
47
  "web:favicon": "bun scripts/core/regen-web-favicon.ts",
46
48
  "web:previews": "bun scripts/core/regen-web-previews.ts",
47
49
  "web:build": "bun run web:tokens && bun run web:favicon && bun run web:previews && cd web && astro check && astro build",
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bash
2
+ # Installs the Playwright system packages for the named browsers, killing an
3
+ # attempt that outlives its bound and retrying it. A degraded apt mirror hangs
4
+ # one connection rather than failing it, so a step timeout alone turns the
5
+ # hang into a red check and never recovers it, while a fresh attempt usually
6
+ # lands on a healthy backend.
7
+ #
8
+ # Usage: install-playwright-deps.sh [--package <spec>] <browser>...
9
+ # Exits 0 on the first success, 2 when no browser is named, and the last
10
+ # attempt's code when every attempt fails.
11
+ set -e
12
+
13
+ package=playwright
14
+ if [ "$1" = "--package" ]; then
15
+ package=$2
16
+ shift 2
17
+ fi
18
+
19
+ if [ $# -eq 0 ]; then
20
+ echo "Usage: install-playwright-deps.sh [--package <spec>] <browser>..." >&2
21
+ exit 2
22
+ fi
23
+
24
+ attempts=3
25
+ bound=${INSTALL_ATTEMPT_SECONDS:-150}
26
+
27
+ # The runner image sets these, yet a stalled log shows gaps of minutes, so
28
+ # print what apt actually reads to settle whether they took effect
29
+ apt-config dump | grep -E '^Acquire::(Retries|http::Timeout) ' || true
30
+
31
+ status=0
32
+ for attempt in $(seq 1 "$attempts"); do
33
+ if [ "$attempt" -gt 1 ]; then
34
+ # timeout runs as the runner user, and Linux drops its signal to the root
35
+ # apt-get playwright spawns through sudo. sudo relays it only to its own
36
+ # child shell, so a root apt-get or dpkg can outlive the kill and hold the
37
+ # lock the next attempt needs.
38
+ sudo pkill -KILL -x 'apt-get|dpkg' || true
39
+ # A kill during unpack leaves dpkg interrupted, which refuses the next
40
+ # install. Its own failure must not end the loop.
41
+ sudo dpkg --configure -a || echo "dpkg --configure -a failed before attempt ${attempt}" >&2
42
+ fi
43
+
44
+ status=0
45
+ timeout --kill-after=10 "$bound" bunx "$package" install-deps "$@" || status=$?
46
+ if [ "$status" -eq 0 ]; then
47
+ exit 0
48
+ fi
49
+ echo "attempt ${attempt}/${attempts} failed with exit ${status}" >&2
50
+ done
51
+
52
+ exit "$status"