@erclx/canon 4.103.0 → 4.104.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 (52) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/canon-cli/SKILL.md +3 -77
  3. package/claude/skills/canon-operator/REQUIREMENT.md +2 -2
  4. package/claude/skills/canon-operator/SKILL.md +5 -5
  5. package/claude/skills/design-taste/references/craft.md +1 -1
  6. package/claude/skills/design-taste/references/preflight.md +2 -2
  7. package/claude/skills/design-taste/references/tells.md +1 -1
  8. package/claude/skills/git-followup/SKILL.md +1 -1
  9. package/claude/skills/git-issue/SKILL.md +2 -2
  10. package/{standards → claude/skills/git-issue/references}/issue.md +3 -8
  11. package/claude/skills/git-pr/SKILL.md +2 -2
  12. package/claude/skills/index-lookup/REQUIREMENT.md +2 -2
  13. package/claude/skills/project-commands/REQUIREMENT.md +1 -1
  14. package/claude/skills/seed-sync/REQUIREMENT.md +1 -1
  15. package/claude/skills/target-check/REQUIREMENT.md +1 -1
  16. package/claude/skills/target-setup/REQUIREMENT.md +56 -0
  17. package/claude/skills/target-setup/SKILL.md +163 -0
  18. package/claude/skills/target-setup/references/detect.md +80 -0
  19. package/claude/skills/{setup-indexes/SKILL.md → target-setup/references/indexes.md} +59 -23
  20. package/claude/skills/target-setup/references/verify.md +95 -0
  21. package/docs/agents/sandbox.md +1 -1
  22. package/docs/agents/scripting.md +3 -2
  23. package/docs/target-projects.md +11 -11
  24. package/docs/workflow/ai-workflow.md +8 -13
  25. package/governance/rules/ui/400-ui.md +0 -5
  26. package/governance/rules/ui/460-design-taste.md +1 -1
  27. package/governance/rules/ui/465-interface-casing.md +31 -0
  28. package/governance/stacks/astro.toml +1 -1
  29. package/governance/stacks/react.toml +1 -1
  30. package/package.json +1 -1
  31. package/scripts/core/regen-hero.sh +1 -1
  32. package/src/claude/cases/setup.ts +12 -11
  33. package/src/commands/sync.ts +1 -1
  34. package/src/gate/measures.ts +57 -0
  35. package/src/gate/stages.ts +10 -14
  36. package/src/gov/list.ts +1 -1
  37. package/src/sandbox/census.ts +3 -3
  38. package/src/shipped/references.ts +1 -1
  39. package/standards/index.md +0 -1
  40. package/claude/skills/setup-gov/REQUIREMENT.md +0 -37
  41. package/claude/skills/setup-gov/SKILL.md +0 -77
  42. package/claude/skills/setup-indexes/REQUIREMENT.md +0 -48
  43. package/claude/skills/setup-init/REQUIREMENT.md +0 -46
  44. package/claude/skills/setup-init/SKILL.md +0 -133
  45. package/claude/skills/setup-plugins/REQUIREMENT.md +0 -42
  46. package/claude/skills/setup-plugins/SKILL.md +0 -81
  47. package/claude/skills/setup-plugins/references/plugin-catalog.md +0 -53
  48. package/claude/skills/setup-smoke/REQUIREMENT.md +0 -38
  49. package/claude/skills/setup-smoke/SKILL.md +0 -53
  50. package/claude/skills/setup-verify/REQUIREMENT.md +0 -39
  51. package/claude/skills/setup-verify/SKILL.md +0 -51
  52. package/scripts/core/regen-tooling-paths.sh +0 -61
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "4.103.0",
4
+ "version": "4.104.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -17,7 +17,7 @@ Consult before running an unfamiliar `canon` verb, before a sync or install, or
17
17
 
18
18
  | Surface | Command | Effect on existing files |
19
19
  | -------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------- |
20
- | Golden configs, listed in full below | `canon tooling sync` | Overwritten once `--write` is passed. Local edits are lost. |
20
+ | Golden configs | `canon tooling sync` | Overwritten once `--write` is passed. Local edits are lost. |
21
21
  | Dictionary seeds (`.cspell/*.txt`) | `canon tooling sync` | Merged and sorted. Existing terms preserved. |
22
22
  | Other seeds (`cspell.json`, `.lintstagedrc`, state docs) | `canon tooling sync` | Copy-once. Dropped on first install, untouched after. |
23
23
  | Standards | none | Nothing installs. `canon standards <name>` reads and never writes. |
@@ -31,86 +31,12 @@ Consult before running an unfamiliar `canon` verb, before a sync or install, or
31
31
 
32
32
  A golden config is any file a stack ships under `configs/`, and the category is wider than its name suggests. It carries the CI workflow, the git hooks, the end-to-end harness, the shell scripts under `scripts/`, and the editor settings, alongside the linters and compilers a reader expects. A stack inherits its parent's configs, so syncing `astro` also writes everything `web` and `base` hold.
33
33
 
34
- Run `canon tooling diff <stack> <target>` for the list resolved against a real target. It reports every path, writes nothing, and exits 1 when any differs. The list below is what the stacks hold as shipped, before any chain resolution.
35
-
36
- <!-- generated:tooling-paths -->
37
-
38
- ### astro
39
-
40
- - `astro.config.mjs`
41
- - `eslint.config.js`
42
- - `playwright.config.ts`
43
- - `src/components/dev/scenarios.astro`
44
- - `tsconfig.json`
45
- - `vitest.config.ts`
46
-
47
- ### base
48
-
49
- - `.editorconfig`
50
- - `.github/pull_request_template.md`
51
- - `.github/workflows/phase-label-gate.yml`
52
- - `.github/workflows/verify.yml`
53
- - `.husky/commit-msg`
54
- - `.husky/post-merge`
55
- - `.husky/post-rewrite`
56
- - `.husky/pre-commit`
57
- - `.husky/pre-push`
58
- - `.prettierrc`
59
- - `.shellcheckrc`
60
- - `.vscode/extensions.json`
61
- - `.vscode/settings.json`
62
- - `commitlint.config.js`
63
- - `scripts/verify.sh`
64
-
65
- ### cloudflare
66
-
67
- - `.github/workflows/deploy.yml`
68
-
69
- ### nextjs
70
-
71
- - `eslint.config.js`
72
- - `next.config.ts`
73
- - `playwright.config.ts`
74
- - `vitest.config.ts`
75
-
76
- ### python
77
-
78
- - `.coveragerc`
79
- - `.python-version`
80
- - `mypy.ini`
81
- - `pytest.ini`
82
- - `ruff.toml`
83
- - `scripts/verify.sh`
84
-
85
- ### vite-react
86
-
87
- - `playwright.config.ts`
88
- - `tsconfig.json`
89
- - `vite.config.ts`
90
- - `vitest.config.ts`
91
-
92
- ### web
93
-
94
- - `.github/workflows/readme-screenshot.yml`
95
- - `.github/workflows/verify.yml`
96
- - `.vscode/extensions.json`
97
- - `.vscode/settings.json`
98
- - `e2e/home.spec.ts`
99
- - `e2e/screenshot.ts`
100
- - `eslint.config.js`
101
- - `scripts/lib/preview-server.sh`
102
- - `scripts/readme-screenshot.sh`
103
- - `scripts/screenshot.sh`
104
- - `scripts/verify.sh`
105
- - `scripts/worktree-port.sh`
106
- - `src/test/setup.ts`
107
-
108
- <!-- /generated:tooling-paths -->
34
+ No list of those paths ships in this body, since a copy would go stale on a different cadence than the stacks. Run `canon tooling diff <stack> <target>` for the list resolved against a real target. It reports every path, writes nothing, and exits 1 when any differs. A binary older than that verb answers the same question through `canon tooling sync <stack> <target> --check`, which names each file it would replace.
109
35
 
110
36
  ## Rules
111
37
 
112
38
  - `canon tooling sync` writes nothing until `--write` is passed. A headless run without it reports and exits 1, so a script that forgets the flag fails rather than silently skipping the sync.
113
- - Run `--check` first when the project carries local edits to any path above. The report names each file it would replace, which is the warning the user needs before the write.
39
+ - Run `--check` first when the project carries local edits to a config the stack ships. The report names each file it would replace, which is the warning the user needs before the write.
114
40
  - An interactive run still prompts. `--write` skips the prompt, and `--check` refuses to write even with a TTY.
115
41
  - Seeds are user-owned. Dictionary `.txt` files merge and sort. Other seeds are copy-once, so re-seeding a structured file means deleting it and syncing again.
116
42
  - No command writes a standard into a project. A `.claude/standards/` folder from an older toolkit is inert, and deleting it costs nothing.
@@ -53,9 +53,9 @@ The last failure is a section no route reaches. `## Route` maps an intent or a d
53
53
 
54
54
  ## Out of scope
55
55
 
56
- - First-time scaffold of a fresh project: `setup-init`
56
+ - First-time scaffold of a fresh project: `target-setup`
57
57
  - Seed and preamble drift in installed files: `seed-sync`
58
- - Governance rule install and index bootstrap: `setup-gov` and `setup-indexes`
58
+ - Governance rule install and index bootstrap: `target-setup`, on its `gov` and `indexes` phases
59
59
  - What a given sync overwrites once it runs: `canon-cli`
60
60
 
61
61
  That last contract carries no row for the governance install this skill routes to, so the overwrite `Must` above reads nothing at one of its own destinations. The row belongs to the skill owning the table. This file records the silence rather than answering it, since a rule written here for a silent contract teaches a session that silence means safe.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: canon-operator
3
- description: Front door to the toolkit in a target project. Orients on the toolkit's own docs and live `canon` catalogs, then runs or routes any toolkit operation from a plain-language intent. Use when you want one entry point instead of picking a specific setup or sync skill, or when asked to "use the toolkit", "what can the toolkit do", "sync my standards", "install rules", or "help me set up this project". User-invoked only. Defers first-time scaffold to setup-init and seed drift to seed-sync.
3
+ description: Front door to the toolkit in a target project. Orients on the toolkit's own docs and live `canon` catalogs, then runs or routes any toolkit operation from a plain-language intent. Use when you want one entry point instead of picking a specific setup or sync skill, or when asked to "use the toolkit", "what can the toolkit do", "sync my standards", "install rules", or "help me set up this project". User-invoked only. Defers first-time scaffold to setup and seed drift to seed-sync.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -47,9 +47,9 @@ The two can name different rows, and a reply answers both rather than picking on
47
47
  - Anything in `superseded`: name which files and what replaced them, then hand off to `migration-superseded`. Both skills propose, so neither moves nor deletes the file
48
48
  - A folder in `unclaimed`: name it and the attribution it carries. No command moves it and the content may be the project's own, so the decision is the user's
49
49
 
50
- - First-time scaffold of a fresh project: hand off to `setup-init`
51
- - Governance rules for the project stack: hand off to `setup-gov`
52
- - Bootstrap the `index.md` system: hand off to `setup-indexes`
50
+ - First-time scaffold of a fresh project: hand off to `target-setup`
51
+ - Governance rules for the project stack: hand off to `target-setup`, which installs them alone on its `gov` phase
52
+ - Bootstrap the `index.md` system: hand off to `target-setup`, which bootstraps it on its `indexes` phase
53
53
  - Seed or standards drift in `CLAUDE.md` or `.claude/` preambles: hand off to `seed-sync`
54
54
  - Install one snippet, standard, or rule: run the domain `install` command
55
55
  - Sync one domain or every installed domain: run `canon <domain> sync` or `canon sync`
@@ -104,5 +104,5 @@ The comparison needs the earlier report. When `## Diagnose` was skipped because
104
104
  ## Boundaries
105
105
 
106
106
  - Run `canon`. Never reimplement its install or sync logic, and never edit managed files like rules, configs, or seeds by hand.
107
- - Hand off the deep flows. Do not duplicate `setup-init` detection or `seed-sync` part-diffing inline.
107
+ - Hand off the deep flows. Do not duplicate `target-setup` detection or `seed-sync` part-diffing inline.
108
108
  - Resolve names from catalogs at runtime. A hardcoded name is a bug.
@@ -39,7 +39,7 @@ Reaching for size is the first instinct and the weakest tool.
39
39
  - **Measure.** Body text running the full width of a wide container is unreadable however good the type is.
40
40
  - **Figures in columns.** Numbers that change, in a table, a price or a timer, need tabular figures or the column jitters.
41
41
  - **Tracking by size.** Large type wants tighter letter spacing, small uppercase labels want looser. Body text wants whatever the face was drawn with.
42
- - **Casing.** Sentence case for headings and labels. Title case on every heading reads as a template.
42
+ - **Casing.** Sentence case for headings and labels. `465-interface-casing` states the rule and its exceptions.
43
43
 
44
44
  ## Depth and texture
45
45
 
@@ -28,7 +28,7 @@ Skip nothing on the ground that it is obviously fine. A rule is on this list bec
28
28
 
29
29
  - [ ] No layout family used twice. Eight sections carry at least four families
30
30
  - [ ] No three consecutive sections sharing the image-and-text split
31
- - [ ] Small uppercase labels above headings number no more than one per three sections
31
+ - [ ] Small uppercase labels above headings number no more than one per three sections, per `465-interface-casing`
32
32
  - [ ] At most one horizontal marquee
33
33
  - [ ] Grid cells equal content items, with no blank tile filling a gap
34
34
  - [ ] Lists over five items use something other than a longer list
@@ -62,7 +62,7 @@ Skip this group where the surface draws on a system already settled.
62
62
  - [ ] Every number either real, labeled as sample, or removed
63
63
  - [ ] No placeholder that reads as placeholder: generic names, generic company names, reused portraits, identical dates
64
64
  - [ ] No filler verbs
65
- - [ ] Sentence case throughout
65
+ - [ ] Sentence case throughout, with exceptions per `465-interface-casing`
66
66
  - [ ] Every claim about what the product does is a thing it does
67
67
 
68
68
  ## Motion
@@ -61,7 +61,7 @@ These are the rules with numbers, so they are checked by counting rather than by
61
61
 
62
62
  - **A layout family appears once.** Once a section uses a shape, no other section on the surface uses it. Eight sections need at least four distinct families.
63
63
  - **Two consecutive splits, never three.** Alternating image-left and image-right reads as considered twice and as filler by the third. Break it with a full-width section, a vertical stack, a grid, or anything else.
64
- - **One small uppercase label per three sections.** The tiny wide-tracked line above a heading is the single most over-reached default in model output. Count them: more than `ceil(sections / 3)` is too many, and the first screen counts as one. The fix is usually to delete it, since a section's position already says what it is.
64
+ - **One small uppercase label per three sections.** The tiny wide-tracked line above a heading is the single most over-reached default in model output. `465-interface-casing` carries the count. The fix is usually to delete it, since a section's position already says what it is.
65
65
  - **One marquee.** Two sliding strips on one surface read as filler rather than as a device.
66
66
  - **Cells equal items.** A grid with a hole in it, or a blank tile at the end, means the grid was shaped before the content was counted. Reshape it.
67
67
  - **Over five items wants a different component.** A longer list is the lazy answer. Group into clusters, split into columns, give each item a card, make them scrollable, or collapse the tail behind a disclosure.
@@ -31,7 +31,7 @@ A missing tracking ref is no longer a guard. An open pull request proves the bra
31
31
 
32
32
  5. Post the evidence comparison, on every invocation including `reply-owned`, since this comment is not the reply step 8 owns. Run `canon pr evidence <number> --json`, resolving `<number>` from `gh pr view --json number`, and read `reason` on the record rather than the exit code.
33
33
  - `no-evidence`: nothing changed under an `evidence/` segment this push. Say nothing and move on.
34
- - `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root (resolved the way `session-worktree` does), then post the comment with `gh pr comment <number> --body-file <main-root>/.canon/tmp/pr/evidence/body-<number>.md` when the record carries no `commentId`, or edit the existing one in place with `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -f body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md` when it does. Clean up the tmp file only after the call reports success.
34
+ - `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root (resolved the way `session-worktree` does), then post the comment with `gh pr comment <number> --body-file <main-root>/.canon/tmp/pr/evidence/body-<number>.md` when the record carries no `commentId`, or edit the existing one in place with `gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md` when it does. Clean up the tmp file only after the call reports success.
35
35
  - Any other reason is one of the mirrored git refusals (`gh-missing`, `gh-failed`, `no-base`, `unreadable-tree`, `unreadable-changes`). Report it and continue without stopping the chain.
36
36
  6. Check for existing review comments: `gh api 'repos/{owner}/{repo}/pulls/<number>/comments' --jq 'length'`, resolving `<number>` from `gh pr view --json number`.
37
37
  7. Sync the body and title on every invocation, before the routing below decides on the reply.
@@ -11,7 +11,7 @@ Format an issue from session context following the issue standard, then file it
11
11
 
12
12
  Read these in parallel:
13
13
 
14
- - `${CLAUDE_SKILL_DIR}/../../standards/issue.md`: issue title, labels, body sections, and banned phrases
14
+ - `${CLAUDE_SKILL_DIR}/references/issue.md`: issue title, labels, body sections, and banned phrases
15
15
  - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
17
17
 
@@ -39,7 +39,7 @@ After outputting the preview, execute the final command immediately. Claude Code
39
39
 
40
40
  ### Pre-publish scan
41
41
 
42
- Before running the final command, run the scan in `${CLAUDE_SKILL_DIR}/../../standards/publish.md` against the title and body. The title and body go straight to the remote with nothing checking them on the way, so this scan is the only gate. It covers the phase-label check as well as the characters, since both go to a reader who has no task board. It applies on top of the banned phrases in `${CLAUDE_SKILL_DIR}/../../standards/issue.md`.
42
+ Before running the final command, run the scan in `${CLAUDE_SKILL_DIR}/../../standards/publish.md` against the title and body. The title and body go straight to the remote with nothing checking them on the way, so this scan is the only gate. It covers the phase-label check as well as the characters, since both go to a reader who has no task board. It applies on top of the banned phrases in `${CLAUDE_SKILL_DIR}/references/issue.md`.
43
43
 
44
44
  The `pull_request` check the git-pr surface carries reads a pull request's own title and body alone, so an issue reaches no check behind this scan either.
45
45
 
@@ -1,8 +1,3 @@
1
- ---
2
- title: Issue reference
3
- description: GitHub issue title, labels, and body conventions
4
- ---
5
-
6
1
  # Issue reference
7
2
 
8
3
  ## Scope
@@ -11,10 +6,10 @@ Governs a tracker issue: its title, its labels, and the sections its body carrie
11
6
 
12
7
  Does not govern:
13
8
 
14
- - Pull request title and body: `pr.md`
15
- - Whether a phase label may appear in issue text: `versioning.md`
9
+ - Pull request title and body: the pull request standard
10
+ - Whether a phase label may appear in issue text: the versioning standard
16
11
  - Voice, rhythm, and sentence construction in issue prose: the `write-human` skill
17
- - Punctuation, formatting, and banned words in issue prose: `markdown.md`
12
+ - Punctuation, formatting, and banned words in issue prose: the markdown standard
18
13
 
19
14
  ## Title
20
15
 
@@ -181,10 +181,10 @@ Read `reason` on the record rather than the exit code.
181
181
  gh pr comment <number> --body-file <main-root>/.canon/tmp/pr/evidence/body-<number>.md
182
182
  ```
183
183
 
184
- When the record carries a `commentId`, edit that comment in place instead of posting a second one, reading the body field from the tmp file with `@`:
184
+ When the record carries a `commentId`, edit that comment in place instead of posting a second one, reading the body field from the tmp file with `@`, which needs the typed-field flag `-F` because the raw-string flag `-f` posts the path itself as the body:
185
185
 
186
186
  ```bash
187
- gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -f body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md
187
+ gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md
188
188
  ```
189
189
 
190
190
  Delete the handoff file once that call reports success, per the cleanup below, since the checklist now lives on the pull request. Clean up the tmp body file the same way.
@@ -30,6 +30,6 @@ Without this skill, `canon indexes list --json` exists as a verb with nobody wra
30
30
 
31
31
  ## Out of scope
32
32
 
33
- - Regenerating or scaffolding an index, which `canon indexes regen` and the `setup-indexes` skill own
33
+ - Regenerating or scaffolding an index, which `canon indexes regen` and the `target-setup` skill's `indexes` phase own
34
34
  - Reading a folder's contents once a hit names it, which is an ordinary file read rather than part of the lookup
35
- - Chaining this skill into `setup-indexes`'s bootstrap flow as a verification step. Left independent: `setup-indexes` already validates through `canon indexes regen --dry-run`, and a second skill call inside a bootstrap flow duplicates a check that already runs.
35
+ - Chaining this skill into the `target-setup` skill's `indexes` phase as a verification step. Left independent: that phase already validates through `canon indexes regen --dry-run`, and a second skill call inside a bootstrap flow duplicates a check that already runs.
@@ -38,5 +38,5 @@ Two more failures are mechanical. A command that stays up run in the foreground
38
38
 
39
39
  - Confirming a change works in the running app, which is a verification request and needs the steps this skill refuses
40
40
  - Deploying, publishing, releasing, migrating, and resetting
41
- - Running the scaffold verification chain against `package.json` scripts: `setup-verify`
41
+ - Running the scaffold verification chain against `package.json` scripts: the `target-setup` skill's `verify` phase
42
42
  - Writing the entry it reads, which belongs to the project's own development docs
@@ -41,5 +41,5 @@ Two failures belong to the audit rather than to the diff. A decision taken in ch
41
41
  - Bulk install and sync of a whole domain, which `canon <domain> install` and `canon <domain> sync` own and `canon-cli` documents. Reach for this skill when the target holds edits worth keeping, and for those commands when it does not.
42
42
  - Golden configs, which overwrite by design and carry no section structure to diff
43
43
  - Governance rules: `canon gov sync`
44
- - First-time scaffold of a project that has installed nothing yet: `setup-init`
44
+ - First-time scaffold of a project that has installed nothing yet: `target-setup`
45
45
  - Public `README.md` and `docs/` prose: `docs-sync`
@@ -39,4 +39,4 @@ The second half of the gap is silence. A session that runs a verb the target's b
39
39
  - Document health, which asks a content question rather than a structural one and takes its own surface
40
40
  - Repairing anything a section names. Each routes to the command or skill that owns it.
41
41
  - A target's own routes, which `canon inventory` reports as a listing rather than a verdict and which is a fact about the project rather than about what the toolkit ships
42
- - First-time scaffold, which is `setup-init`, and per-intent routing of a single toolkit operation, which is `canon-operator`
42
+ - First-time scaffold, which is `target-setup`, and per-intent routing of a single toolkit operation, which is `canon-operator`
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: target-setup
3
+ description: Why getting a project onto the toolkit is one skill with phases rather than a family a session has to pick among
4
+ ---
5
+
6
+ # Setup requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session facing a project that does not carry the toolkit
11
+ resolves the stack by hand, picks per-domain install commands from the CLI
12
+ surface, and runs them in an order nothing states. The install logic lives in
13
+ `canon init`, so what is missing is not the writing but the reading: which stack
14
+ matches this project, which extras it needs beyond the stack, and what the
15
+ commands will do before they run.
16
+
17
+ The naive shape is one skill per phase, and it failed on discrimination rather
18
+ than on content. Six descriptions covering one job made the model pick among
19
+ them on wording, and the two that split on how heavy their checks are gave a
20
+ session no way to tell from the catalog which one a scaffold wanted. A phase
21
+ argument answers the same question by naming the depth rather than by choosing
22
+ between two bodies that differ in a table.
23
+
24
+ Merging also closes a class of drift the family carried. Detection was stated
25
+ twice, once for the full chain and once for the governance-only route, and the
26
+ two copies could disagree with nothing comparing them.
27
+
28
+ ## Must
29
+
30
+ - Read the toolkit catalogs before resolving, and hardcode no stack, rule, or snippet name
31
+ - Preview the resolved arguments and the exact commands before the first write
32
+ - Mark a fallback resolution as a fallback in the preview, where it can still be declined
33
+ - Run every phase without a TTY, and carry an argument for each prompt a phase would otherwise open
34
+ - Reach each phase alone, so a caller wanting one layer does not run the chain to get it
35
+ - Name a destination for each state the chain declines rather than ending on the refusal
36
+
37
+ ## Must not
38
+
39
+ - Guard against clobbering an existing project's configs, which routes to `canon-operator` instead
40
+ - Author a rule or a stack in the target project on the fly
41
+ - Generate a config the tooling stack ships as a golden file
42
+ - Install Claude Code plugins, which provision a machine rather than a project
43
+ - Fail an unattended scaffold on a server start, which is flaky enough to be a depth the operator asks for
44
+ - Survive as a skill nothing invokes but a person typing its name. `canon-operator` hands first-time scaffold here and the target-projects page names it as the scaffold step, so a later read finding no caller but the author has found a body that should have stayed a verb
45
+
46
+ ## Guards
47
+
48
+ - No `package.json` at the project root stops the verify phase, since there are no declared scripts to read
49
+ - A missing dependency folder installs first rather than letting every script fail on the same cause
50
+ - A detected technology with no matching rule surfaces rather than resolving to a guess
51
+
52
+ ## Out of scope
53
+
54
+ - An existing project's per-domain drift, which `canon-operator` diagnoses and `target-check` reports
55
+ - Reaching a remote or the project's history, which `repo-metadata` and `git-commit` own
56
+ - Provisioning Claude Code plugins on a machine, which the `claude plugin` CLI does directly
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: target-setup
3
+ description: Gets a project onto the toolkit. Detects the stack, resolves per-domain arguments, previews the chain, runs `canon init`, then verifies at a stated depth and bootstraps the `index.md` system. Use when asked to "set up this project", "init this project", "bootstrap the toolkit", "install governance", "install gov rules", "set up indexes", "verify the scaffold", "run the smoke tests", or "one-shot install". Assumes the `canon` CLI is on PATH. Do NOT use on a project that already carries the toolkit, which is `canon-operator`, or to report per-domain drift without repairing it, which is `target-check`.
4
+ ---
5
+
6
+ # Setup
7
+
8
+ Gets a project onto the toolkit. Detects project type, resolves per-domain
9
+ arguments, previews the chain, runs `canon init`, then verifies what landed and
10
+ bootstraps the `index.md` system over the project's own documentation folders.
11
+
12
+ The CLI holds the install logic. This skill resolves, previews, and routes. It
13
+ reimplements no verb and hardcodes no stack, rule, or snippet name.
14
+
15
+ ## Phases
16
+
17
+ Five phases run in order on a bare invocation. Each is also reachable alone, so
18
+ a caller wanting one layer does not run the chain to get it.
19
+
20
+ | Phase | What it does | Reached alone by |
21
+ | --------- | ----------------------------------------------------------- | --------------------- |
22
+ | `detect` | Reads the project and resolves stack arguments | `setup detect` |
23
+ | `install` | Runs `canon init` and the tooling sync | `setup install` |
24
+ | `gov` | Installs governance rules and nothing else | `setup gov` |
25
+ | `verify` | Runs the installed scripts at a stated depth | `setup verify [deep]` |
26
+ | `indexes` | Bootstraps the `index.md` system over documentation folders | `setup indexes` |
27
+
28
+ An argument naming a phase runs that phase and stops. A bare invocation runs
29
+ `detect`, `install`, `verify`, then `indexes`. `gov` is a narrowing of `install`
30
+ rather than a step within it, so the full chain never runs it separately.
31
+
32
+ ## Non-interactive path
33
+
34
+ Every phase runs under `CANON_NON_INTERACTIVE=1` with no TTY. Two phases
35
+ otherwise pause, and each takes an argument that answers its prompt ahead of
36
+ time:
37
+
38
+ - `indexes` confirms its folder list with the operator. `setup indexes --all`
39
+ takes every candidate the scan found, and `--folders <a>,<b>` takes a named
40
+ set. With neither, and with no TTY, the phase reports its candidates and stops
41
+ rather than choosing for the operator.
42
+ - `gov` stops on a detected technology with no matching rule. `--skip-gaps`
43
+ proceeds with the matched layer and lists the gap in the report.
44
+
45
+ Claude Code's tool permission dialog is the confirmation gate for everything
46
+ else. Do not pause for a separate confirmation.
47
+
48
+ ## Scope
49
+
50
+ - This skill and `canon init` run once on a fresh scaffold, never on an existing project. They do not guard against clobbering existing configs. When tempted to add guards, mode switches, or an existing-project branch, stop. Extend the per-domain `canon <domain> install` or `canon sync` paths instead.
51
+ - The chain stops at the project edge. `repo-metadata` and `git-commit` also ship, reaching a remote and the project's history respectively, and neither runs here.
52
+ - Claude Code plugins are a machine concern rather than a project one, so no phase here installs them. Install them with `claude plugin install <name> --scope user`, which applies in every project on the machine and is copied into none.
53
+
54
+ ## Declined states
55
+
56
+ Three states reach this skill that the chain does not serve. Name the destination for each, so the refusal routes rather than ends. The first two stop the chain outright and the third runs it on a default the person may not want.
57
+
58
+ - **An existing project.** Stop and hand off to `canon-operator`. It reads what the target already carries before it names a command, which this chain never does, so any per-domain install picked here is a guess against configs nobody read. The Scope bullet above names the same commands as the authoring alternative, and this is the destination a person takes.
59
+ - **An install wanting the `.claude/` folder alone.** Stop. Run `canon claude init` for the seed docs, then run the `indexes` phase over the project's own documentation folders. Neither needs the tooling sync the `install` phase runs.
60
+ - **A language the toolkit carries no stack for.** The chain still runs, on `base`, with the fallback marked in the preview. A project that wants none of what `base` carries declines there and takes the `gov` phase, which is language-neutral and installs rules without the `base` development dependencies the tooling layer would drop on it. Say so at the preview rather than resolving it here, since the fallback is a working default and only the person can say whether it fits.
61
+
62
+ Do not add a stack, a mode switch, or an existing-project branch to satisfy one of these. Each destination already exists and routing to it costs a line.
63
+
64
+ ## Phase: detect
65
+
66
+ Read `${CLAUDE_SKILL_DIR}/references/detect.md`. It holds the catalog reads, the
67
+ evidence list, the argument resolution, the gap handling, and the preview, which
68
+ the `install` and `gov` phases share rather than each stating.
69
+
70
+ ## Phase: install
71
+
72
+ Run the chain in order, starting immediately after the preview. Run from the
73
+ target project's current directory. Do not cd into the toolkit source tree. The
74
+ `canon` CLI is global.
75
+
76
+ Step 1: `canon init` installs base tooling, claude seeds, governance rules, and wiki.
77
+
78
+ ```bash
79
+ CANON_NON_INTERACTIVE=1 canon init \
80
+ --stack <stack> \
81
+ --add <rules> \
82
+ <target>
83
+ ```
84
+
85
+ Omit any flag whose resolved value is empty.
86
+
87
+ Step 2: `canon tooling sync <tooling-stack> --write` installs stack deps, scripts, gitignore entries, seeds, golden configs, and drops the reference doc. The extends chain is walked, so syncing `vite-react` also pulls `web` and `base` configs. Skip if the tooling stack is `base` (already synced by `canon init`).
88
+
89
+ `--write` is required. A headless run without it reports what it would replace and exits 1, since golden configs overwrite whatever the target holds at those paths. Scaffolding into a fresh target has nothing to lose, so pass it directly rather than reading a report first.
90
+
91
+ ```bash
92
+ CANON_NON_INTERACTIVE=1 canon tooling sync <tooling-stack> <target> --write
93
+ ```
94
+
95
+ Monorepo with multiple language roots: run `canon init` once at the repo root so `base` (husky, prettier, cspell, commitlint, CI) lands single, then sync each subtree with `--skip base` so the shared layer is not re-dropped.
96
+
97
+ ```bash
98
+ CANON_NON_INTERACTIVE=1 canon tooling sync vite-react ./frontend --skip base --write
99
+ CANON_NON_INTERACTIVE=1 canon tooling sync python ./backend --skip base --write
100
+ ```
101
+
102
+ Without `--skip base`, each subtree re-drops husky, and git honors only one `core.hooksPath`, so the extra hook dirs silently break. Each subtree keeps its own framework configs, and its own stack reference reads through `canon tooling reference <stack>`.
103
+
104
+ Step 3: post-sync fixups. Golden configs arrive from sync, so no config generation is required. But a few items may need a one-time touch:
105
+
106
+ - **ESLint version pin.** If `bun create vite` installed `eslint@^10` and the manifest pins `eslint@^9`, sync does not override a present dep. Run `bun add -d eslint@^9` if `bun run lint:fix` fails with `Class extends value undefined`.
107
+ - **File naming.** `bun create vite`'s `App.tsx` violates the `KEBAB_CASE` rule. Rename to `app.tsx` and update the import in `main.tsx`.
108
+ - **Docs.** Run `canon tooling reference <tooling-stack>` and `canon tooling reference web` for any stack-specific follow-ups (Chrome extension overrides, setup script details).
109
+
110
+ Do not generate ESLint, Vitest, or Playwright configs. They ship as golden files. Generating from prose duplicates what sync already installed.
111
+
112
+ ## Phase: gov
113
+
114
+ Governance rules and nothing else, for a project declining the tooling layer.
115
+ Resolve exactly as the detect reference states, then run:
116
+
117
+ ```bash
118
+ CANON_NON_INTERACTIVE=1 canon gov install <stack> --add <extras> <target>
119
+ ```
120
+
121
+ Report the rule count installed, the target path, and any rules that failed to
122
+ resolve, which the CLI warns on.
123
+
124
+ ## Phase: verify
125
+
126
+ Read `${CLAUDE_SKILL_DIR}/references/verify.md`. It holds both depths and the
127
+ script chain each runs. The default depth runs the leaf scripts and reports pass
128
+ or fail per script. `deep` adds the dev and preview server smoke, the end-to-end
129
+ suite, and the screenshot harness.
130
+
131
+ The chain runs the default depth. `deep` is the operator's call rather than the
132
+ chain's, since a slow server start reads as a failure and an unattended run
133
+ should not fail a scaffold on that.
134
+
135
+ ## Phase: indexes
136
+
137
+ Read `${CLAUDE_SKILL_DIR}/references/indexes.md`. It holds the scan, the
138
+ frontmatter drafting, the scaffold, the validate step, and the convention seed
139
+ offer.
140
+
141
+ This phase confirms candidate folders with the operator rather than running
142
+ unattended, which is the one phase in the chain that pauses for a conversation
143
+ unless `--all` or `--folders` answered it ahead of time. A fresh scaffold usually
144
+ has no markdown-heavy folder yet, so this phase frequently finds nothing to
145
+ present, which its reference defines as its own outcome rather than a failure of
146
+ the chain.
147
+
148
+ ## Report
149
+
150
+ After the chain, report:
151
+
152
+ - Domains installed, with a check per domain
153
+ - Tooling stack synced, or skipped. Name the layers pulled via the extends chain.
154
+ - Any post-sync fixups applied (ESLint pin, filename renames)
155
+ - `verify` outcome, naming the depth it ran at
156
+ - `indexes` outcome (folders bootstrapped, or none found)
157
+ - Any domains or scripts that failed
158
+ - Any detection gaps surfaced during resolve
159
+ - Claude Code plugins as an onboarding step this chain does not cover, so a clean result does not read as onboarding complete
160
+
161
+ A resolved name and a fallback read alike once written, so the preview marks the
162
+ fallback rather than this report. The preview is the last point before the first
163
+ write, and the report runs after the files have landed.
@@ -0,0 +1,80 @@
1
+ ---
2
+ title: Detect and resolve
3
+ description: The catalog reads, evidence list, argument resolution, gap handling, and preview the install and gov phases share
4
+ ---
5
+
6
+ # Detect and resolve
7
+
8
+ What the `install` and `gov` phases both do before they write anything. Stated
9
+ once here rather than twice in the body, since the two phases differ in what
10
+ they install rather than in how they read the project.
11
+
12
+ ## Read the catalogs
13
+
14
+ Run in parallel. Never hardcode stack, rule, snippet, or standards names. The
15
+ catalog is the source of truth.
16
+
17
+ Run from the target project's current directory. Do not cd into the toolkit
18
+ source tree. The `canon` CLI is global.
19
+
20
+ ```bash
21
+ canon gov list --json 2>/dev/null
22
+ canon tooling list --json 2>/dev/null
23
+ ```
24
+
25
+ The `gov` phase needs only the first. Run both anyway on a bare invocation,
26
+ since the chain reaches the tooling resolution a moment later.
27
+
28
+ ## Detect
29
+
30
+ Read these from the project root in parallel, skipping any that do not exist:
31
+
32
+ - `package.json`: `dependencies` and `devDependencies`
33
+ - Root configs: `astro.config.*`, `next.config.*`, `vite.config.*`, `tailwind.config.*`, `tsconfig.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`
34
+ - `canon/REQUIREMENTS.md` and `canon/ARCHITECTURE.md` if present
35
+ - Directory structure via `ls -1` of the project root and `src/` if present
36
+
37
+ ## Resolve arguments
38
+
39
+ - **Stack:** pick the closest governance stack by matching detected runtime or framework against stack names in the catalog. If nothing matches, fall back to `base` and carry the fallback into the preview.
40
+ - **Tooling stack:** pick the closest tooling stack from `canon tooling list --json` (e.g. `vite-react`, `astro`, `nextjs`). Distinct from the governance stack. Fall back to `base` if no framework match, and carry that fallback into the preview too.
41
+ - **Next.js:** map `next` in `package.json` dependencies, or a root `next.config.ts`/`.js`/`.mjs` file, to the `nextjs` tooling stack. The dependency name does not match the stack name by itself.
42
+ - **Extras:** identify technologies not already covered by the picked stack. For each, find a rule whose `description` or `paths` points at that technology and pass it via `--add`. Dedupe against the stack's own rules. Do not add a rule the stack already pulls in.
43
+ - **Skip (`--skip`):** `wiki` installs by default. Add `--skip wiki` only when the user explicitly wants it left out.
44
+
45
+ ## Gap handling
46
+
47
+ If a detected technology has no matching rule or stack, do not guess. Surface
48
+ the gap.
49
+
50
+ On the full chain, either defer and author a rule in the toolkit before
51
+ re-running, or proceed with the matched layer and list the gap in the final
52
+ report. Rules and stacks are authored in the toolkit repository, never in the
53
+ target project on the fly.
54
+
55
+ On the `gov` phase, stop and present four options rather than picking:
56
+
57
+ 1. Author a new rule in the toolkit at `governance/rules/<domain>/<num>-<name>.md` following `${CLAUDE_SKILL_DIR}/../../standards/rule.md`, commit, then re-run install. Take this route when the toolkit should ship the rule to every project.
58
+ 2. Invoke `create-rule`, which scaffolds the file into the target project at a non-colliding number. Take this route when the rule is specific to this project and no sync should ever overwrite it.
59
+ 3. Install the matching non-`<tech>` rules and skip the tech-specific layer.
60
+ 4. Abort.
61
+
62
+ `--skip-gaps` takes option 3 ahead of the prompt, which is what keeps the phase
63
+ non-interactive. This skill authors no rule itself. Option 1 writes in the
64
+ toolkit repository, and option 2 hands the project-local file to `create-rule`.
65
+
66
+ ## Preview
67
+
68
+ Before executing, output:
69
+
70
+ - **Detected:** each technology with its evidence file
71
+ - **Stack:** picked governance stack and resolved rule count. Mark it `fallback` when no detected runtime or framework matched a catalog name.
72
+ - **Tooling stack:** picked tooling stack. Mark it `fallback` on the same test, and name what `base` lands: configs, seeds, and gitignore entries in every case, plus the JavaScript development dependencies, scripts, and hook activation wherever a `package.json` exists to carry them. A project outside that ecosystem runs none of the second group and keeps the first. Omit this line entirely on the `gov` phase, which syncs no tooling.
73
+ - **Extras:** each `--add` rule with a one-line reason
74
+ - **Skip:** any `--skip` entries with reason
75
+ - **Target:** resolved target path
76
+ - **Commands:** the full chain that will run
77
+
78
+ A resolved name and a fallback read alike once written, so mark the fallback
79
+ here rather than in the report. The preview is the last point before the first
80
+ write, and the report runs after the files have landed.