@erclx/canon 4.78.0 → 4.79.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 (140) hide show
  1. package/README.md +9 -9
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/canon-operator/SKILL.md +1 -1
  4. package/claude/skills/create-standard/SKILL.md +1 -1
  5. package/claude/skills/design-extract/REQUIREMENT.md +4 -4
  6. package/claude/skills/design-extract/SKILL.md +11 -11
  7. package/claude/skills/docs-fold/SKILL.md +14 -14
  8. package/claude/skills/docs-fold/references/anchor-sweep.md +1 -1
  9. package/claude/skills/docs-fold/references/wireframe-sweep.md +4 -4
  10. package/claude/skills/draft-context/REQUIREMENT.md +6 -6
  11. package/claude/skills/draft-context/SKILL.md +8 -6
  12. package/claude/skills/draft-diagram/SKILL.md +5 -5
  13. package/claude/skills/draft-identity/SKILL.md +3 -3
  14. package/claude/skills/draft-readme/REQUIREMENT.md +1 -1
  15. package/claude/skills/draft-screencast/SKILL.md +1 -1
  16. package/claude/skills/draft-wireframes/REQUIREMENT.md +7 -7
  17. package/claude/skills/draft-wireframes/SKILL.md +7 -5
  18. package/claude/skills/memory-capture/REQUIREMENT.md +1 -1
  19. package/claude/skills/memory-capture/SKILL.md +6 -6
  20. package/claude/skills/memory-review/SKILL.md +1 -1
  21. package/claude/skills/migration-claude-md/REQUIREMENT.md +3 -3
  22. package/claude/skills/migration-claude-md/SKILL.md +7 -5
  23. package/claude/skills/migration-context/REQUIREMENT.md +3 -3
  24. package/claude/skills/migration-context/SKILL.md +11 -9
  25. package/claude/skills/plan-feature/SKILL.md +4 -4
  26. package/claude/skills/plan-groundwork/SKILL.md +2 -2
  27. package/claude/skills/plan-intake/SKILL.md +2 -2
  28. package/claude/skills/project-commands/SKILL.md +2 -2
  29. package/claude/skills/review-branch/SKILL.md +3 -3
  30. package/claude/skills/review-pr/SKILL.md +2 -2
  31. package/claude/skills/role-orchestrator/SKILL.md +1 -1
  32. package/claude/skills/role-planner/SKILL.md +1 -1
  33. package/claude/skills/session-relay/REQUIREMENT.md +1 -1
  34. package/claude/skills/session-resume/SKILL.md +1 -1
  35. package/claude/skills/setup-gov/SKILL.md +1 -1
  36. package/claude/skills/setup-init/SKILL.md +1 -1
  37. package/claude/skills/teach-workspace/references/promotion.md +5 -5
  38. package/claude/skills/ux-audit/SKILL.md +5 -5
  39. package/claude/skills/ux-measure/SKILL.md +1 -1
  40. package/docs/agents/commands.md +7 -2
  41. package/docs/agents/context-audit-checks.md +3 -3
  42. package/docs/agents/context-audit.md +2 -2
  43. package/docs/agents/counts.md +3 -3
  44. package/docs/agents/design-board.md +3 -3
  45. package/docs/agents/docs.md +3 -3
  46. package/docs/agents/indexes.md +1 -1
  47. package/docs/agents/install-and-sync.md +1 -1
  48. package/docs/agents/review-classification.md +1 -1
  49. package/docs/agents/routing.md +2 -2
  50. package/docs/agents/rule-citations.md +1 -1
  51. package/docs/agents/sandbox.md +1 -1
  52. package/docs/agents/scripting.md +1 -1
  53. package/docs/agents/skills-audit.md +1 -1
  54. package/docs/agents/skills-reach.md +4 -4
  55. package/docs/target-projects.md +10 -10
  56. package/docs/workflow/ai-workflow.md +15 -13
  57. package/docs/workflow/operating-model.md +2 -2
  58. package/docs/workflow/visual-design-workflow.md +8 -8
  59. package/governance/rules/claude/510-context.md +3 -2
  60. package/governance/rules/claude/520-wireframes.md +3 -2
  61. package/governance/rules/claude/530-requirements.md +2 -1
  62. package/governance/rules/claude/540-architecture.md +2 -1
  63. package/governance/rules/claude/550-design.md +2 -1
  64. package/governance/rules/core/025-indexes.md +1 -1
  65. package/governance/rules/core/045-memory.md +1 -1
  66. package/package.json +1 -1
  67. package/scripts/core/check-ignore-parity.sh +1 -1
  68. package/scripts/core/check-seed-independence.sh +5 -2
  69. package/scripts/core/install-check.sh +1 -1
  70. package/scripts/core/list-seed-roots.sh +3 -3
  71. package/scripts/core/regen-hero.sh +1 -1
  72. package/scripts/docs/list.sh +3 -3
  73. package/scripts/lib/sandbox-git.sh +1 -1
  74. package/scripts/lib/tooling.sh +6 -4
  75. package/snippets/claude/figma-steps.md +1 -1
  76. package/src/audits/catalog.ts +2 -2
  77. package/src/autoship/paths.ts +1 -1
  78. package/src/claude/cases/authoring.ts +2 -2
  79. package/src/claude/cases/setup.ts +1 -1
  80. package/src/claude/routing.ts +1 -1
  81. package/src/claude/seeds-list.ts +1 -1
  82. package/src/claude/seeds.ts +62 -28
  83. package/src/claude/skills-reach.ts +3 -3
  84. package/src/commands/claude.ts +1 -1
  85. package/src/commands/context.ts +8 -8
  86. package/src/commands/design.ts +1 -1
  87. package/src/commands/gov.ts +1 -1
  88. package/src/commands/migrate.ts +182 -1
  89. package/src/context/audit.ts +1 -1
  90. package/src/context/citations.ts +7 -5
  91. package/src/context/folders.ts +2 -2
  92. package/src/counts/scan.ts +4 -4
  93. package/src/design/board.ts +5 -5
  94. package/src/design/components.ts +2 -2
  95. package/src/design/css.ts +1 -1
  96. package/src/design/document.ts +1 -1
  97. package/src/design/regen.ts +1 -1
  98. package/src/design/render.ts +1 -1
  99. package/src/design/tokens.ts +2 -2
  100. package/src/docs/read.ts +9 -3
  101. package/src/gate/measures.ts +10 -7
  102. package/src/gate/stages.ts +4 -4
  103. package/src/markdown/scan.ts +1 -1
  104. package/src/migrate/surface-roots.ts +458 -0
  105. package/src/record-root.ts +6 -4
  106. package/src/sandbox/census.ts +1 -1
  107. package/src/shipped/references.ts +3 -3
  108. package/src/surface-root.ts +39 -7
  109. package/src/sync/layout.ts +10 -6
  110. package/src/sync/reverse.ts +1 -1
  111. package/src/tooling/inject.ts +5 -3
  112. package/src/tooling/scan.ts +4 -1
  113. package/standards/architecture.md +4 -4
  114. package/standards/context.md +7 -7
  115. package/standards/design.md +3 -3
  116. package/standards/diagrams.md +6 -6
  117. package/standards/index.md +5 -5
  118. package/standards/markdown.md +2 -2
  119. package/standards/publish.md +3 -3
  120. package/standards/readme.md +1 -1
  121. package/standards/requirements.md +4 -4
  122. package/standards/skill.md +2 -2
  123. package/standards/tasks.md +1 -1
  124. package/standards/wiki.md +1 -1
  125. package/standards/wireframes.md +8 -8
  126. package/tooling/astro/reference.md +3 -3
  127. package/tooling/base/reference.md +3 -3
  128. package/tooling/claude/reference.md +7 -3
  129. package/tooling/claude/seeds/CLAUDE.md +9 -9
  130. package/tooling/nextjs/reference.md +2 -2
  131. package/tooling/python/reference.md +1 -1
  132. package/tooling/vite-react/reference.md +2 -2
  133. package/tooling/web/reference.md +2 -2
  134. /package/tooling/base/seeds/{.claude → canon}/context/ci.md +0 -0
  135. /package/tooling/base/seeds/{.claude → canon}/context/development.md +0 -0
  136. /package/tooling/base/seeds/{.claude → canon}/context/index.md +0 -0
  137. /package/tooling/claude/seeds/{.claude → canon}/ARCHITECTURE.md +0 -0
  138. /package/tooling/claude/seeds/{.claude → canon}/DESIGN.md +0 -0
  139. /package/tooling/claude/seeds/{.claude → canon}/REQUIREMENTS.md +0 -0
  140. /package/tooling/claude/seeds/{.claude → canon}/wireframes/index.md +0 -0
@@ -52,10 +52,12 @@ const CANON_SCRATCH = 'tmp'
52
52
  * writes back. `worktrees` is absent because the harness creates a worktree
53
53
  * under `.claude/` and requires its target to sit there.
54
54
  *
55
- * Everything absent from this list is committed and stays where it is, which is
56
- * the rule the move ran on. `context`, `rules`, `skills`, `hooks`, `wireframes`,
57
- * and the loose documents at the root are all in that set, which is why a seed
58
- * and a superseded-layout report each ask this rather than assuming a root.
55
+ * Everything absent from this list is committed and never lands under the
56
+ * record root, which is the rule the move ran on. `rules`, `skills`, and
57
+ * `hooks` stay under `.claude/` because the vendor reads them there, while
58
+ * `context`, `wireframes`, and the loose documents are tracked surfaces that
59
+ * `surface-root.ts` resolves under `canon/` instead. A seed and a
60
+ * superseded-layout report each ask this rather than assuming a root.
59
61
  */
60
62
  export const RECORD_ENTRIES: readonly string[] = [
61
63
  '.records.git',
@@ -69,7 +69,7 @@ export function listSkills(root: string): string[] {
69
69
  /**
70
70
  * Maps a scenario to the skill it drives, trying two spellings in order.
71
71
  *
72
- * `<category>-<command>` is the rule `.claude/context/sandbox/coverage.md` states, and it
72
+ * `<category>-<command>` is the rule `canon/context/sandbox/coverage.md` states, and it
73
73
  * alone pairs 29 of 54 skills. The bare `<command>` fallback is what reaches the
74
74
  * rest: `claude/setup-init.sh` drives the `setup-init` skill, not a
75
75
  * `claude-setup-init` that does not exist. Stating one spelling and shipping two
@@ -139,10 +139,10 @@ const SAME_REPOSITORY =
139
139
  * named a target's own tree, measured on 2026-09-03. Resolving against `root`
140
140
  * is what turns that 124-hit pattern into the four-hit gate.
141
141
  *
142
- * `.claude/context/` carries no equivalent pattern. The same resolution test
142
+ * `canon/context/` carries no equivalent pattern. The same resolution test
143
143
  * cannot separate a path every scaffolded project holds, such as
144
- * `.claude/context/index.md`, from this repository's own domain entry, such
145
- * as `.claude/context/indexes.md`, since both resolve here and only the
144
+ * `canon/context/index.md`, from this repository's own domain entry, such
145
+ * as `canon/context/indexes.md`, since both resolve here and only the
146
146
  * second is a defect. That is a semantic read no pattern makes, so it stays
147
147
  * with the rule and the review checklist rather than joining this reader.
148
148
  */
@@ -23,13 +23,13 @@ export type SurfaceRoot = (typeof SURFACE_ROOTS)[number]
23
23
  /**
24
24
  * The root a surface is created at when neither root carries it yet.
25
25
  *
26
- * Disagreeing with the head of the read order for exactly one release: read
27
- * precedence is new-first so a tree that has moved is never answered from the
28
- * copy left behind, while creation stays at the old root so nothing writes a
29
- * fresh tracked file under a root a target's installed binary may not resolve
30
- * yet. A later batch flips this once a release carries the read side.
26
+ * It agrees with the head of the read precedence. While the two disagreed,
27
+ * creation stayed at `.claude/` so nothing wrote a fresh tracked file under a
28
+ * root a target's installed binary could not resolve. A release carries the
29
+ * read side now, so a fresh project scaffolds one root and an unmoved one keeps
30
+ * resolving its own surfaces through the fallback above.
31
31
  */
32
- export const CREATION_ROOT: SurfaceRoot = '.claude'
32
+ export const CREATION_ROOT: SurfaceRoot = 'canon'
33
33
 
34
34
  /**
35
35
  * Every tracked surface this module resolves, at the name `.claude/` gives it.
@@ -55,6 +55,18 @@ export function spell(root: SurfaceRoot, entry: string): string {
55
55
  return root === 'canon' && entry === 'canon' ? 'config' : entry
56
56
  }
57
57
 
58
+ /**
59
+ * The creation default for one entry.
60
+ *
61
+ * The stamp folder keeps creating under `.claude/` until its own move lands,
62
+ * since the install stamp and the audits baseline still write there by a
63
+ * fixed path. A read resolving to `canon/config/` in a fresh project would
64
+ * answer from a folder nothing writes.
65
+ */
66
+ function creationRootFor(entry: string): SurfaceRoot {
67
+ return entry === 'canon' ? '.claude' : CREATION_ROOT
68
+ }
69
+
58
70
  /**
59
71
  * The root a surface resolves at: the first that carries it, and the creation
60
72
  * default when neither does.
@@ -63,7 +75,7 @@ function rootOf(root: string, entry: string): SurfaceRoot {
63
75
  return (
64
76
  SURFACE_ROOTS.find((candidate) =>
65
77
  existsSync(join(root, candidate, spell(candidate, entry))),
66
- ) ?? CREATION_ROOT
78
+ ) ?? creationRootFor(entry)
67
79
  )
68
80
  }
69
81
 
@@ -82,6 +94,26 @@ export function surfaceDir(
82
94
  return join(root, at, spell(at, entry), ...rest)
83
95
  }
84
96
 
97
+ /**
98
+ * Where a path authored at the `canon/` spelling lands under `root`.
99
+ *
100
+ * A seed tree authors every surface once, at the new root, while a target may
101
+ * still hold that surface under `.claude/`. Writing the literal path there
102
+ * would open a `canon/` copy that wins read precedence and hides every entry
103
+ * the target already wrote, so the entry resolves the way a read does. A path
104
+ * naming no surface entry is joined as written.
105
+ */
106
+ export function resolveSurfacePath(root: string, rel: string): string {
107
+ const [head, entry, ...rest] = rel.split(/[\\/]/)
108
+
109
+ if (head !== 'canon' || entry === undefined || entry === 'canon') {
110
+ return join(root, rel)
111
+ }
112
+ if (!SURFACE_ENTRIES.includes(entry)) return join(root, rel)
113
+
114
+ return surfaceDir(root, entry, ...rest)
115
+ }
116
+
85
117
  /**
86
118
  * Every root a surface would be read at, in precedence order, whether or not
87
119
  * it is on disk.
@@ -1,7 +1,8 @@
1
1
  import { existsSync, statSync } from 'node:fs'
2
- import { basename, join } from 'node:path'
2
+ import { basename, join, relative } from 'node:path'
3
3
  import { SUBDIRS } from '@/claude/seeds'
4
4
  import { creationRel, isRecordEntry } from '@/record-root'
5
+ import { SURFACE_ENTRIES, surfaceDir } from '@/surface-root'
5
6
  import type { StampDomain } from '@/sync/stamp'
6
7
 
7
8
  const CLAUDE_DIR = '.claude'
@@ -70,13 +71,16 @@ export function collectSuperseded(target: string): SupersededEntry[] {
70
71
  const rel = join(CLAUDE_DIR, `${subdir.toUpperCase()}.md`)
71
72
  if (!isFile(join(target, rel))) continue
72
73
 
73
- // A record subdir now lives under the record root, so the replacement this
74
- // names is resolved against the target rather than fixed at `.claude/`.
75
- // Naming a folder the target does not have sends a person to migrate their
76
- // legacy file into a path nothing reads.
74
+ // A record subdir lives under the record root and a tracked surface under
75
+ // the surface root, so the replacement this names is resolved against the
76
+ // target rather than fixed at `.claude/`. Naming a folder the target does
77
+ // not have sends a person to migrate their legacy file into a path nothing
78
+ // reads.
77
79
  const replacedBy = isRecordEntry(subdir)
78
80
  ? creationRel(target, subdir)
79
- : join(CLAUDE_DIR, subdir)
81
+ : SURFACE_ENTRIES.includes(subdir)
82
+ ? relative(target, surfaceDir(target, subdir))
83
+ : join(CLAUDE_DIR, subdir)
80
84
 
81
85
  entries.push({ rel, replacedBy })
82
86
  }
@@ -234,7 +234,7 @@ export function detectMigrations(target: string): MigrationCandidate[] {
234
234
  if (docs > 0 && context === 0) {
235
235
  found.push({
236
236
  skill: 'migration-context',
237
- reason: `${docs} markdown files under docs/ with no .claude/context/ tier`,
237
+ reason: `${docs} markdown files under docs/ with no canon/context/ tier`,
238
238
  })
239
239
  }
240
240
 
@@ -1,9 +1,10 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
3
- import { dirname, join } from 'node:path'
3
+ import { dirname, join, relative } from 'node:path'
4
4
  import { $ } from 'bun'
5
5
  import { copyPreservingMode } from '@/copy'
6
6
  import { rewritesOnInstall, stripSeedMarker } from '@/seed-marker'
7
+ import { resolveSurfacePath } from '@/surface-root'
7
8
  import { mergeSections, pruneSections } from '@/tooling/gitignore'
8
9
  import { ancestorsFirst, listFiles, type Manifest } from '@/tooling/manifest'
9
10
  import {
@@ -92,8 +93,9 @@ export async function injectSeeds(
92
93
 
93
94
  logStep(`Applying ${manifest.name} seeds`)
94
95
  for (const rel of files) {
95
- await mergeSeedFile(join(manifest.seedsDir, rel), join(target, rel))
96
- logAdd(rel)
96
+ const dest = resolveSurfacePath(target, rel)
97
+ await mergeSeedFile(join(manifest.seedsDir, rel), dest)
98
+ logAdd(relative(target, dest))
97
99
  applied.push(rel)
98
100
  }
99
101
  }
@@ -1,5 +1,6 @@
1
1
  import { existsSync, readFileSync } from 'node:fs'
2
2
  import { join } from 'node:path'
3
+ import { resolveSurfacePath } from '@/surface-root'
3
4
  import { mergeSections } from '@/tooling/gitignore'
4
5
  import { ancestorsFirst, listFiles, type Manifest } from '@/tooling/manifest'
5
6
  import {
@@ -79,7 +80,9 @@ export function scan(chain: readonly Manifest[], target: string): ScanResult {
79
80
 
80
81
  seeds.push({
81
82
  rel,
82
- state: existsSync(join(target, rel)) ? 'present' : 'missing',
83
+ state: existsSync(resolveSurfacePath(target, rel))
84
+ ? 'present'
85
+ : 'missing',
83
86
  })
84
87
  }
85
88
  }
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: Architecture reference
3
- description: Shape and content rules for .claude/ARCHITECTURE.md
3
+ description: Shape and content rules for canon/ARCHITECTURE.md
4
4
  ---
5
5
 
6
6
  # Architecture reference
7
7
 
8
- Applies to `.claude/ARCHITECTURE.md`. Describes the system shape and the decisions behind it, not a tutorial, setup guide, or implementation walkthrough. Pair it with `CLAUDE.md`: principles live there, patterns and decisions live here. Update when a decision is made or a risk is resolved.
8
+ Applies to `canon/ARCHITECTURE.md`. Describes the system shape and the decisions behind it, not a tutorial, setup guide, or implementation walkthrough. Pair it with `CLAUDE.md`: principles live there, patterns and decisions live here. Update when a decision is made or a risk is resolved.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs the system-shape document at `.claude/ARCHITECTURE.md`: the overview, the decision entries, and the open risks.
12
+ Governs the system-shape document at `canon/ARCHITECTURE.md`: the overview, the decision entries, and the open risks.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -27,7 +27,7 @@ Does not govern:
27
27
 
28
28
  - How individual functions work line by line. The code carries its own behavior.
29
29
  - Full type definitions. They live in code. Reference the shape conceptually if needed.
30
- - A measurement paragraph specific to one domain's own mechanism. Route it to that domain's `.claude/context/<domain>.md` entry instead. The choice and its rejected alternative stay here whatever their reach, since reach is what makes a decision cross-domain, not how many domains its supporting measurement happens to touch.
30
+ - A measurement paragraph specific to one domain's own mechanism. Route it to that domain's `canon/context/<domain>.md` entry instead. The choice and its rejected alternative stay here whatever their reach, since reach is what makes a decision cross-domain, not how many domains its supporting measurement happens to touch.
31
31
 
32
32
  ## Sections
33
33
 
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: Context entry reference
3
- description: Shape and content rules for .claude/context/<domain>.md entries
3
+ description: Shape and content rules for canon/context/<domain>.md entries
4
4
  ---
5
5
 
6
6
  # Context entry reference
7
7
 
8
- Applies to per-domain narrative entries under `.claude/context/`. Skip for `index.md`, which is regenerated by `canon indexes regen`.
8
+ Applies to per-domain narrative entries under `canon/context/`. Skip for `index.md`, which is regenerated by `canon indexes regen`.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs per-domain narrative entries under `.claude/context/`: their structure, the decisions and gotchas they carry, and what they leave to the code.
12
+ Governs per-domain narrative entries under `canon/context/`: their structure, the decisions and gotchas they carry, and what they leave to the code.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -42,7 +42,7 @@ An entry that fails these is non-conforming regardless of whether it satisfies e
42
42
  - `title` (required): sentence case, names the domain (`Web`, `API`, `Agents`).
43
43
  - `description` (required): one line describing what the domain covers.
44
44
 
45
- Both fields feed `.claude/context/index.md` when regenerated.
45
+ Both fields feed `canon/context/index.md` when regenerated.
46
46
 
47
47
  ## Required sections
48
48
 
@@ -81,7 +81,7 @@ Only the `development` entry carries this section. It is not a general-purpose h
81
81
  ## What goes in
82
82
 
83
83
  - Per-domain narrative on how the code is structured and why
84
- - Decisions specific to the domain. Broader cross-domain decisions belong in `.claude/ARCHITECTURE.md`.
84
+ - Decisions specific to the domain. Broader cross-domain decisions belong in `canon/ARCHITECTURE.md`.
85
85
  - Constraints, gotchas, things tried and rejected
86
86
  - Domain-specific conventions that do not fit a `paths:`-scoped rule
87
87
  - A reference to another entry, spelled as the path that entry sits at rather than as its bare filename. A bare name resolves against whichever folder the reader is already in, so a domain that splits into subfolders strands every inbound reference and the break surfaces nowhere. A reference to a seed, a standard, or a file the project owns elsewhere keeps the form its own surface uses.
@@ -95,7 +95,7 @@ Only the `development` entry carries this section. It is not a general-purpose h
95
95
  - Rules. Those go in `.claude/rules/<scope>.md` with a `paths:` glob.
96
96
  - Tutorials or human onboarding. Those go in `docs/` if a public audience exists.
97
97
  - Generated content (API references). Generate, do not write by hand.
98
- - Anything already in `.claude/REQUIREMENTS.md` or `.claude/ARCHITECTURE.md`.
98
+ - Anything already in `canon/REQUIREMENTS.md` or `canon/ARCHITECTURE.md`.
99
99
  - The history of how the domain reached its current shape. An entry describes the repository as it stands, so a change number, release label, or date attached to a change goes wherever the project tracks work.
100
100
  - A rejected alternative's provenance, which is the same rule at the one place the section above admits history. Keep what was tried and why it lost. Cut who tried it and when.
101
101
 
@@ -107,7 +107,7 @@ Only the `development` entry carries this section. It is not a general-purpose h
107
107
  - Never cut a `## Decisions` or `## Gotchas` entry to shorten a file. Cut a `## Layout` or `## CLI` section instead.
108
108
  - Retire a decision or gotcha once its subject is gone, rewriting the bullet to state the current design rather than leaving the narration of what it replaced beside it. A rejected alternative is not a retired one, so what was tried and why it lost stays whatever its age. The rule above protects content whose subject is live, and this one releases content whose subject is not.
109
109
  - Rewrite a decision a later one replaced rather than appending the replacement beside it. The subject is still live, so the rule above does not reach it, and two bullets on one subject leave a reader to work out which of them is current. State the design that stands and keep the superseded reasoning only where it is the alternative that lost.
110
- - Split into a folder (`.claude/context/<domain>/<sub-area>.md`) when a domain has three or more sub-areas that do not fit cleanly in one file. That split is the natural ceiling.
110
+ - Split into a folder (`canon/context/<domain>/<sub-area>.md`) when a domain has three or more sub-areas that do not fit cleanly in one file. That split is the natural ceiling.
111
111
  - Keep a split domain's `index.md` generated. The catalog body is rewritten on every regen, so the domain's own overview and layout belong in a sibling file rather than in it, and the `subtitle` is what names the file to start with.
112
112
  - Author a catalog that grows a row per shipped thing as a bullet list, never a markdown table. A table pads its columns to a shared width, so one row outgrowing its column reflows every row and turns a one-line edit into a whole-file rewrite that conflicts with any sibling branch. This is what forced the split above.
113
113
 
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: Design reference
3
- description: Shape and content rules for .claude/DESIGN.md
3
+ description: Shape and content rules for canon/DESIGN.md
4
4
  ---
5
5
 
6
6
  # Design reference
7
7
 
8
- Applies to `.claude/DESIGN.md`. Captures visual intent and the decisions behind how things look, not a style guide, component spec, or framework reference. Update when a visual decision is made or a rule changes.
8
+ Applies to `canon/DESIGN.md`. Captures visual intent and the decisions behind how things look, not a style guide, component spec, or framework reference. Update when a visual decision is made or a rule changes.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs the visual-intent document at `.claude/DESIGN.md`: tokens described as intent, layout constraints, and the omissions that keep visual scope closed.
12
+ Governs the visual-intent document at `canon/DESIGN.md`: tokens described as intent, layout constraints, and the omissions that keep visual scope closed.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -7,7 +7,7 @@ description: Shape and content rules for .canon/diagrams/<kind>.md files
7
7
 
8
8
  Applies to per-kind entries under `.canon/diagrams/`. Skip for `index.md`, which is regenerated by `canon indexes regen`.
9
9
 
10
- A diagram entry answers one question about the system with one or more Mermaid diagrams and the prose that makes them readable. It is not a rendering of the file tree. The check for any single line: does it tell a reader something the code layout would not have told them? If not, it belongs in `.claude/context/`.
10
+ A diagram entry answers one question about the system with one or more Mermaid diagrams and the prose that makes them readable. It is not a rendering of the file tree. The check for any single line: does it tell a reader something the code layout would not have told them? If not, it belongs in `canon/context/`.
11
11
 
12
12
  ## Scope
13
13
 
@@ -50,8 +50,8 @@ One writer touches `verified`, which is the pass that renders an entry and reads
50
50
 
51
51
  Five kinds, each with a fixed filename and a fixed `category` value. Write a kind only when its source signal exists, and leave the rest absent rather than padding the folder.
52
52
 
53
- - `system-context.md`, category `System context` (`flowchart TB`): who uses the system, what it talks to, and where its boundary sits. Drawn from `.claude/REQUIREMENTS.md`. This is the entry a reader outside the team opens first, and the only kind that draws the world outside the boundary.
54
- - `components.md`, category `Components` (`flowchart TB` with `subgraph` boundaries): the layered structure inside the boundary. Drawn from `.claude/ARCHITECTURE.md`.
53
+ - `system-context.md`, category `System context` (`flowchart TB`): who uses the system, what it talks to, and where its boundary sits. Drawn from `canon/REQUIREMENTS.md`. This is the entry a reader outside the team opens first, and the only kind that draws the world outside the boundary.
54
+ - `components.md`, category `Components` (`flowchart TB` with `subgraph` boundaries): the layered structure inside the boundary. Drawn from `canon/ARCHITECTURE.md`.
55
55
  - `request-flow.md`, category `Request flow` (`sequenceDiagram`): a request lifecycle, an agent loop, or an interaction between actors.
56
56
  - `data-pipeline.md`, category `Data pipeline` (`flowchart TB`): retrieval, ranking, queues, or ETL.
57
57
  - `deployment.md`, category `Deployment` (`flowchart TB`): hosts, services, and infrastructure config.
@@ -78,9 +78,9 @@ A second entry for one kind takes a suffixed name (`request-flow-admin.md`) and
78
78
 
79
79
  This section states the voice for the surface, which is what claims the yield the `write-human` skill grants to a surface whose own standard sets it. Explanation prose is pedagogical here and the default developer-facing voice does not apply. The yield covers voice alone. The rhythm and density rules that skill carries stay in force, as do the language bans, punctuation, and formatting in `markdown.md`, which grants no yield at all.
80
80
 
81
- ## What moves to .claude/context/
81
+ ## What moves to canon/context/
82
82
 
83
- Implementation detail that answers how a component is built belongs in a `.claude/context/` entry, not a diagram:
83
+ Implementation detail that answers how a component is built belongs in a `canon/context/` entry, not a diagram:
84
84
 
85
85
  - Function names, call signatures, and lifecycle ordering
86
86
  - Library versions, config keys, and environment variable names
@@ -93,7 +93,7 @@ Reference the context entry by path when a reader needs the mechanism. The diagr
93
93
 
94
94
  - When the system changes, update the entries whose source signal changed and leave the rest alone. Rewriting the folder wholesale reproduces the defect the per-kind split exists to end.
95
95
  - A diagram showing a defunct host or library is worse than no diagram. Audit the affected entry in the same PR.
96
- - `System context` has no named source signal beyond `.claude/REQUIREMENTS.md`, so nothing tells a session it went stale. Re-read it when the boundary or the set of external dependencies moves.
96
+ - `System context` has no named source signal beyond `canon/REQUIREMENTS.md`, so nothing tells a session it went stale. Re-read it when the boundary or the set of external dependencies moves.
97
97
  - Nothing watches the folder for you. The entries are redrawn on demand rather than swept on every ship, so `verified` carries the whole signal: an entry whose date sits far behind the branch is due a read, and no pass is going to name which one.
98
98
 
99
99
  ## Template
@@ -7,11 +7,11 @@ subtitle: Reference docs for consistent authoring across the toolkit and target
7
7
 
8
8
  Reference docs for consistent authoring across the toolkit and target projects.
9
9
 
10
- - [Architecture reference](architecture.md): Shape and content rules for .claude/ARCHITECTURE.md
10
+ - [Architecture reference](architecture.md): Shape and content rules for canon/ARCHITECTURE.md
11
11
  - [Branch reference](branch.md): Branch naming format and type conventions
12
12
  - [Commit reference](commit.md): Commit message format and type conventions
13
- - [Context entry reference](context.md): Shape and content rules for .claude/context/<domain>.md entries
14
- - [Design reference](design.md): Shape and content rules for .claude/DESIGN.md
13
+ - [Context entry reference](context.md): Shape and content rules for canon/context/<domain>.md entries
14
+ - [Design reference](design.md): Shape and content rules for canon/DESIGN.md
15
15
  - [Diagram reference](diagrams.md): Shape and content rules for .canon/diagrams/<kind>.md files
16
16
  - [Docs reference](docs.md): Reader and jurisdiction, frontmatter, page structure, what a page links out to, the diagram permission, and when a category earns a subfolder
17
17
  - [Figure reference](figures.md): When a figure earns its place, the render-first policy for a graph-shaped subject, freehand SVG as the escape hatch, and its wrapping, color, and accessibility rules
@@ -26,7 +26,7 @@ Reference docs for consistent authoring across the toolkit and target projects.
26
26
  - [Pull request reference](pr.md): Pull request title and body conventions
27
27
  - [Publish reference](publish.md): Scan an author runs against finished text, the cross-reference form each destination takes, and the response to an unreadable source
28
28
  - [Readme reference](readme.md): Readme voice, structure, and content conventions
29
- - [Requirements reference](requirements.md): Shape and content rules for .claude/REQUIREMENTS.md
29
+ - [Requirements reference](requirements.md): Shape and content rules for canon/REQUIREMENTS.md
30
30
  - [Governance rule reference](rule.md): Rule frontmatter, body shape, and voice for .claude/rules files
31
31
  - [Session map reference](session.md): Filename and location, the sections a handoff carries, the write and read procedures, and how a role extends it
32
32
  - [Claude skill reference](skill.md): Claude skill structure and authoring rules
@@ -37,4 +37,4 @@ Reference docs for consistent authoring across the toolkit and target projects.
37
37
  - [Teach reference](teach.md): Workspace layout, ordinal naming, frontmatter, and the mission and learning-record formats for a learning workspace
38
38
  - [Versioning reference](versioning.md): Phase label vs semver discipline across tasks, PRs, reviews, issues, commits, and tags
39
39
  - [Wiki reference](wiki.md): Folder split, frontmatter, naming convention, and sourcing for a wiki reference page
40
- - [Wireframe reference](wireframes.md): Shape and content rules for .claude/wireframes/<surface>.md files
40
+ - [Wireframe reference](wireframes.md): Shape and content rules for canon/wireframes/<surface>.md files
@@ -108,8 +108,8 @@ When frontmatter carries a short `title` or `description` used for catalog displ
108
108
  Each pair shows a banned pattern and its fix.
109
109
 
110
110
  ```markdown
111
- Bad: See [.claude/context/retrieval.md](.claude/context/retrieval.md) for the retrieval flow.
112
- Good: See `.claude/context/retrieval.md` for the retrieval flow.
111
+ Bad: See [canon/context/retrieval.md](canon/context/retrieval.md) for the retrieval flow.
112
+ Good: See `canon/context/retrieval.md` for the retrieval flow.
113
113
  ```
114
114
 
115
115
  ```markdown
@@ -42,7 +42,7 @@ A phase label is one way text names the board, and a path under a record root is
42
42
 
43
43
  Two shapes get past a reader scanning for a bare label. A code span quoting a label is still the label, so read a span whose whole content is one as a hit and leave a longer token inside a span alone, which is a fixture name rather than a reference. The second shape is a path under a record root, gitignored and therefore absent from every clone, so `.canon/review/feedback/` names a folder the remote's reader cannot open.
44
44
 
45
- Under `.claude/`'s own tracked folders there is no hit, since `.claude/context/governance/rules.md` resolves everywhere. `.canon/` carries no such carve-out: one ignore line covers the root whole, so every path beneath it is a hit regardless of which folder names it.
45
+ Under the tracked `canon/` and `.claude/` folders there is no hit, since `canon/context/governance/rules.md` resolves everywhere. `.canon/` carries no such carve-out: one ignore line covers the root whole, so every path beneath it is a hit regardless of which folder names it.
46
46
 
47
47
  Rewrite a hit to name what the reader can reach rather than deleting it. A row's subject stated plainly replaces its label, and what a record folder holds, said in a sentence, replaces its path.
48
48
 
@@ -66,11 +66,11 @@ Text published to a remote is the auto-linking half: a pull request body, an iss
66
66
 
67
67
  Content that installs into another repository is the third destination, and it splits on which repository the number names. A skill body loads from a plugin cache, a docs page is read through `canon docs`, and a standard through `canon standards`, so the reader holds their own repository rather than the one a bare number belongs to. Qualifying a number against a different, resolvable repository fixes that, since the reader can open that repository even without this one.
68
68
 
69
- Qualifying it against `erclx/canon` fixes nothing, because a reader holding only the plugin cache or the published package still cannot open this repository's own history. A same-repository citation takes no number here at all, bare or qualified. State the fact the citation was standing in for instead, and where the identifier is the only trace of a one-off incident rather than a reproducible count, carry it into the `.claude/context/` entry that owns the surface.
69
+ Qualifying it against `erclx/canon` fixes nothing, because a reader holding only the plugin cache or the published package still cannot open this repository's own history. A same-repository citation takes no number here at all, bare or qualified. State the fact the citation was standing in for instead, and where the identifier is the only trace of a one-off incident rather than a reproducible count, carry it into the `canon/context/` entry that owns the surface.
70
70
 
71
71
  Write `owner/repo#123` and `owner/repo@abc1234` for a citation of a different, resolvable repository, across every such surface. `canon gate run` fails a push on a bare reference there, and a line whose bare form is the point carries `canon-allow-reference: <reason>` on itself or on the line above.
72
72
 
73
- Choose the number over the sha where the citation names a decided change, since a pull request number resolves to the diff and the review behind it. Take the sha only for a tree or measurement state, the `Measured at <sha>` shape `.claude/ARCHITECTURE.md` already uses. The choice holds for both spellings this section fixes, the bare form a remote auto-links and the qualified form a cross-repository citation carries.
73
+ Choose the number over the sha where the citation names a decided change, since a pull request number resolves to the diff and the review behind it. Take the sha only for a tree or measurement state, the `Measured at <sha>` shape `canon/ARCHITECTURE.md` already uses. The choice holds for both spellings this section fixes, the bare form a remote auto-links and the qualified form a cross-repository citation carries.
74
74
 
75
75
  A commit message takes the bare form even though it is also read through the log, where nothing links. The remote is what the form is chosen for, since a reader in the log loses only a link that plain text never carried.
76
76
 
@@ -46,7 +46,7 @@ Scoped to the README at a repository root. A nested README documenting a folder,
46
46
  - Do not include license text. Reference the `LICENSE` file.
47
47
  - Do not include detailed contribution guidelines. Reference `CONTRIBUTING.md`.
48
48
  - Do not include extensive troubleshooting guides. Use a wiki or separate documentation.
49
- - A README that points to the project's own context entries instead of restating them satisfies the required list by routing rather than carrying. A repository documented in `docs/` or `.claude/context/` names the entry point and the listing command, then stops. The reader is one hop away, the same way `## Badges` treats zero as complete.
49
+ - A README that points to the project's own context entries instead of restating them satisfies the required list by routing rather than carrying. A repository documented in `docs/` or `canon/context/` names the entry point and the listing command, then stops. The reader is one hop away, the same way `## Badges` treats zero as complete.
50
50
  - A README missing an H1, or whose headings restate the tool that scaffolded it rather than the project, is unedited generator output rather than a page anyone wrote. Draft over it. Nothing here asks a session to preserve a section a scaffold wrote and nobody replaced.
51
51
 
52
52
  ### Badges
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: Requirements reference
3
- description: Shape and content rules for .claude/REQUIREMENTS.md
3
+ description: Shape and content rules for canon/REQUIREMENTS.md
4
4
  ---
5
5
 
6
6
  # Requirements reference
7
7
 
8
- Applies to `.claude/REQUIREMENTS.md`. Describes what the product does and why, not how it works. Update when scope changes, goals shift, or a non-goal is promoted to a feature.
8
+ Applies to `canon/REQUIREMENTS.md`. Describes what the product does and why, not how it works. Update when scope changes, goals shift, or a non-goal is promoted to a feature.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs the product-scope document at `.claude/REQUIREMENTS.md`: problem, goals, non-goals, MVP features, distribution, stack, and constraints.
12
+ Governs the product-scope document at `canon/REQUIREMENTS.md`: problem, goals, non-goals, MVP features, distribution, stack, and constraints.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -45,7 +45,7 @@ Later scope arrives as a new section rather than as an extension of the MVP list
45
45
 
46
46
  Include `## Distribution` only when the project ships to consumers outside its own repository. An internal service or a monorepo application has nothing to put in it, and a section every project is told to fill is one most projects pad. Place it after `## MVP features`.
47
47
 
48
- State each entry as an outcome the consumer reaches, never as the mechanism that delivers it. A registry name, a manifest format, a version scheme, or a release tool is implementation and belongs in `.claude/ARCHITECTURE.md`. Distribution pulls harder toward mechanism than any other section, which is why the rule is repeated here.
48
+ State each entry as an outcome the consumer reaches, never as the mechanism that delivers it. A registry name, a manifest format, a version scheme, or a release tool is implementation and belongs in `canon/ARCHITECTURE.md`. Distribution pulls harder toward mechanism than any other section, which is why the rule is repeated here.
49
49
 
50
50
  ## Template
51
51
 
@@ -210,7 +210,7 @@ Without this skill, a session <observed failure>, <observed failure>.
210
210
  ### Output and tuning
211
211
 
212
212
  - Skill success lines emit the full relative path from the project root (`<dir>/<file>`) for any file written, updated, or deleted. A bare filename names a file the reader cannot open. The `## Output` section of the project's instruction file sets the form that path takes, so a skill body states which path is emitted and leaves the form to that section.
213
- - Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `memory/`, `groundwork/`, `intake/`, `proposals/`, `diagrams/`, or `teach/`, with `tmp/` for scratch nothing else claims), never in a folder the body invents. `.claude/ARCHITECTURE.md`'s per-folder decisions are the precedent for which kind takes which folder.
213
+ - Before a skill writes anything, decide whether the output is a deliverable the project keeps or a toolkit session record. A deliverable lands among the project's own tracked files. A session record lands under `.canon/`, in the named subfolder for its kind (`tasks/`, `plans/`, `review/`, `memory/`, `groundwork/`, `intake/`, `proposals/`, `diagrams/`, or `teach/`, with `tmp/` for scratch nothing else claims), never in a folder the body invents. `canon/ARCHITECTURE.md`'s per-folder decisions are the precedent for which kind takes which folder.
214
214
  - Codify a skill's posted or generated output as a fenced template, and keep the body consistent with every capability the frontmatter description names.
215
215
  - When a skill gathers user input or pre-seeds a template, attach a concrete proposed default to every question, derived from project context. Accept "use defaults" as a bulk-confirm.
216
216
  - Separate correctness axes (routing, sourcing, escalation, decline) from shape axes (line count, formatting, variant sprawl) when tuning a skill. Tighten only on correctness regressions. Do not convert soft caps to hard caps for aesthetic drift when correctness passes.
@@ -228,7 +228,7 @@ Without this skill, a session <observed failure>, <observed failure>.
228
228
  A skill reads from two roots. Know which one a file lives under before referencing it.
229
229
 
230
230
  - Bundled skill assets (`references/`, `scripts/`, `assets/`) resolve against the skill's own directory in the source clone. Reference them with `${CLAUDE_SKILL_DIR}/<path>`, never a bare relative path, so a plugin skill running from another project still finds them.
231
- - Installed shared docs (`.claude/rules/`, `.claude/context/`) resolve against the target project cwd, where install placed them. Reference them by that path.
231
+ - Installed shared docs (`.claude/rules/`, `canon/context/`) resolve against the target project cwd, where install placed them. Reference them by that path.
232
232
  - Do not hand-copy a standard into a skill. A hand-copied file drifts from its source and belongs to no owner. If a skill must carry its own copy, generate it from the single source and reference it through `${CLAUDE_SKILL_DIR}`, so one owner keeps every copy in sync.
233
233
 
234
234
  ### Citing a standard
@@ -244,7 +244,7 @@ The line is what lets a merge close its own task. Every merge on `main` is a squ
244
244
 
245
245
  - Class names, file paths, function names, or prop names in any entry or title
246
246
  - Code-level steps or implementation detail. Behavioral specifics are fine.
247
- - Architectural reasoning that outlives the task. A finding explains why this task is shaped as it is. A decision the system keeps after the task closes belongs in `.claude/ARCHITECTURE.md`.
247
+ - Architectural reasoning that outlives the task. A finding explains why this task is shaped as it is. A decision the system keeps after the task closes belongs in `canon/ARCHITECTURE.md`.
248
248
  - Narrative of the session that produced the task. A finding states what constrains the task, so what was probed, what it cost, and who decided belongs in the groundwork folder the `Groundwork:` line names. A task with no groundwork folder cuts the narrative rather than relocating it, since the board is not the fallback destination for it.
249
249
  - "In progress" or "Blocked" headings. Note status inline on the outcome instead.
250
250
  - Sequencing rationale or which version is active. Why this task is planned before its neighbors goes on its row in `priority.md`, in the cell that already carries what it is waiting on. Rationale wider than one row has no home at all, so cut it rather than filing it here.
package/standards/wiki.md CHANGED
@@ -27,7 +27,7 @@ A page failing either is non-conforming even when it satisfies every shape rule
27
27
 
28
28
  ## Placement
29
29
 
30
- - Write a page here only when its subject is owned outside this repository. Route anything about how this repository works to `docs/`, `.claude/context/`, or a skill body instead.
30
+ - Write a page here only when its subject is owned outside this repository. Route anything about how this repository works to `docs/`, `canon/context/`, or a skill body instead.
31
31
  - File the page under `wiki/claude/`. A subject Anthropic does not own, whether a third-party tool or a vendor-neutral concept, is out of scope for this folder split. Route it to `docs/` or a skill body instead of adding a second wiki folder for it.
32
32
 
33
33
  ## Frontmatter
@@ -1,17 +1,17 @@
1
1
  ---
2
2
  title: Wireframe reference
3
- description: Shape and content rules for .claude/wireframes/<surface>.md files
3
+ description: Shape and content rules for canon/wireframes/<surface>.md files
4
4
  ---
5
5
 
6
6
  # Wireframe reference
7
7
 
8
- Applies to per-surface entries under `.claude/wireframes/`. Skip for `index.md`, which is regenerated by `canon indexes regen`.
8
+ Applies to per-surface entries under `canon/wireframes/`. Skip for `index.md`, which is regenerated by `canon indexes regen`.
9
9
 
10
- A wireframe file captures the spatial layout and interaction intent of one UI surface. It is not an implementation log. The check for any single line: would it still be true if the surface were rebuilt in a different framework? If not, it belongs in `.claude/context/`.
10
+ A wireframe file captures the spatial layout and interaction intent of one UI surface. It is not an implementation log. The check for any single line: would it still be true if the surface were rebuilt in a different framework? If not, it belongs in `canon/context/`.
11
11
 
12
12
  ## Scope
13
13
 
14
- Governs per-surface wireframe entries under `.claude/wireframes/`: layout, variants, on-screen copy, and interaction intent.
14
+ Governs per-surface wireframe entries under `canon/wireframes/`: layout, variants, on-screen copy, and interaction intent.
15
15
 
16
16
  Does not govern:
17
17
 
@@ -36,14 +36,14 @@ A wireframe regenerated from an already-built surface's own render code may carr
36
36
 
37
37
  A drafted-ahead wireframe states intent in role terms because nothing exists yet to check it against. A regenerated one is checkable against the code it mirrors, and a role label standing in for the real class name would throw that check away. The two documents answer different questions, so one set of rules cannot govern both.
38
38
 
39
- Route detail the source citation does not already carry to `.claude/context/` as usual: algorithms, event-handler code, workarounds, and rejected approaches stay out of the wireframe regardless of which mode it is written in.
39
+ Route detail the source citation does not already carry to `canon/context/` as usual: algorithms, event-handler code, workarounds, and rejected approaches stay out of the wireframe regardless of which mode it is written in.
40
40
 
41
41
  ## Frontmatter
42
42
 
43
43
  - `title` (required): sentence case, names the surface (`Header`, `Section nav`, `Footer`).
44
44
  - `description` (required): one line on when and where the surface appears.
45
45
 
46
- Both fields feed `.claude/wireframes/index.md` when regenerated.
46
+ Both fields feed `canon/wireframes/index.md` when regenerated.
47
47
 
48
48
  ## Layout
49
49
 
@@ -70,9 +70,9 @@ Both fields feed `.claude/wireframes/index.md` when regenerated.
70
70
  - State the rule, not the mechanism. `The rail tracks the active section as the visitor scrolls` is intent. The scroll handler, throttle, and observer margins are not.
71
71
  - Keep it to a short list. A Behavior section longer than the layout is a sign implementation detail has leaked in.
72
72
 
73
- ## What moves to .claude/context/
73
+ ## What moves to canon/context/
74
74
 
75
- This section does not govern a transcription wireframe's citation of its own source. See `## Transcription wireframes`. Implementation detail that answers how the surface is built belongs in a `.claude/context/` entry, not the wireframe:
75
+ This section does not govern a transcription wireframe's citation of its own source. See `## Transcription wireframes`. Implementation detail that answers how the surface is built belongs in a `canon/context/` entry, not the wireframe:
76
76
 
77
77
  - Algorithms, event-handler code, and lifecycle ordering
78
78
  - Framework component names, props, and CSS class or token names
@@ -12,7 +12,7 @@ The astro stack covers Astro + TypeScript projects: content sites, marketing sit
12
12
  2. Add React integration: `bunx astro add react`. Do not use `astro add tailwind`. That command installs the v3 integration. Tailwind v4 arrives via the web manifest.
13
13
  3. Install web tooling: `canon tooling sync web . --write`
14
14
  4. Install astro adapter: `canon tooling sync astro . --write`
15
- 5. Extend the `ci` and `development` context entries under `.claude/context/` per the web reference's extend sections plus the astro rows below.
15
+ 5. Extend the `ci` and `development` context entries under `canon/context/` per the web reference's extend sections plus the astro rows below.
16
16
  6. Run `bun run lint:fix` then `bun run check`.
17
17
 
18
18
  ## What ships as golden configs
@@ -21,7 +21,7 @@ The astro stack covers Astro + TypeScript projects: content sites, marketing sit
21
21
  - `vitest.config.ts`: uses `getViteConfig` from `astro/config` (not `mergeConfig`). jsdom, globals, setup file, `passWithNoTests: true`, v8 coverage, `**/*.astro` in coverage excludes.
22
22
  - `playwright.config.ts`: all browsers, `webServer` runs `bun run build && bun run preview` on port `4321` plus `WORKTREE_PORT_OFFSET`, `reuseExistingServer: false`. Astro's dev/prod gap is wide (MDX, island hydration, asset optimization), so E2E always tests the built `dist/`. `DIST_PREBUILT` set in the environment drops the `build` half, running `bun run preview` alone against a `dist/` a prior CI job already produced.
23
23
  - `tsconfig.json`: extends `astro/tsconfigs/strict`, adds `skipLibCheck`, `vitest/globals` and `@testing-library/jest-dom` in types, `@/` paths.
24
- - `eslint.config.js`: overrides the web layer. Adds `eslint-plugin-astro` (`.astro` parser via `astro-eslint-parser`). React-hooks scoped to `.jsx`/`.tsx` only (`.astro` is not React). The shared block's `files` selector includes `.astro`, so `check-file/filename-naming-convention` reaches `.ts`, `.tsx`, and `.astro` under `KEBAB_CASE`, overriding Astro's own PascalCase component convention deliberately, on the ground that a component's name in markup comes from the import binding rather than the filename. `.js` and `.jsx` stay out of the rule's own pattern, matching `web` and `nextjs`. `check-file/folder-naming-convention` reaches every `src/**` folder except `__tests__` and the whole `pages/` subtree, which carries its own off-block for the bracket-named dynamic routes and nested slug folders Astro's file-based routing produces. See `.claude/context/tooling.md` for the measurement.
24
+ - `eslint.config.js`: overrides the web layer. Adds `eslint-plugin-astro` (`.astro` parser via `astro-eslint-parser`). React-hooks scoped to `.jsx`/`.tsx` only (`.astro` is not React). The shared block's `files` selector includes `.astro`, so `check-file/filename-naming-convention` reaches `.ts`, `.tsx`, and `.astro` under `KEBAB_CASE`, overriding Astro's own PascalCase component convention deliberately, on the ground that a component's name in markup comes from the import binding rather than the filename. `.js` and `.jsx` stay out of the rule's own pattern, matching `web` and `nextjs`. `check-file/folder-naming-convention` reaches every `src/**` folder except `__tests__` and the whole `pages/` subtree, which carries its own off-block for the bracket-named dynamic routes and nested slug folders Astro's file-based routing produces. See `canon/context/tooling.md` for the measurement.
25
25
 
26
26
  ## Typecheck
27
27
 
@@ -57,7 +57,7 @@ Append to the `## Scripts` table:
57
57
 
58
58
  ## CI docs (extend)
59
59
 
60
- In `.claude/context/ci.md`, the Typecheck row's assertion reads: `` `astro check` passes ``. The Build row's assertion reads: `` `astro build` succeeds ``.
60
+ In `canon/context/ci.md`, the Typecheck row's assertion reads: `` `astro check` passes ``. The Build row's assertion reads: `` `astro build` succeeds ``.
61
61
 
62
62
  ## Gitignore (extend)
63
63
 
@@ -28,7 +28,7 @@ Seeds live in `tooling/base/seeds/`. Sync drops each once on first install and n
28
28
  - `.cspell/project-terms.txt` and `.cspell/tech-stack.txt`: one word per line, sorted alphabetically.
29
29
  - `.lintstagedrc`: the glob map below.
30
30
  - `.prettierignore`: created empty. Projects add their own entries.
31
- - `.claude/context/`: extend the `ci` and `development` entries with project-specific commands, workflows, or deploy steps. Canonical rationale stays in this reference.
31
+ - `canon/context/`: extend the `ci` and `development` entries with project-specific commands, workflows, or deploy steps. Canonical rationale stays in this reference.
32
32
 
33
33
  ## Tool pairing
34
34
 
@@ -42,8 +42,8 @@ Seeds live in `tooling/base/seeds/`. Sync drops each once on first install and n
42
42
  ## File layout
43
43
 
44
44
  - All shell scripts live in `scripts/`. Do not place a `.sh` file outside it.
45
- - Dictionaries live in `.cspell/`, hooks in `.husky/`, seeded context docs in `.claude/context/`.
46
- - The `.claude/context/` location matches the three-tier context model: project-wide invariants in `CLAUDE.md`, `.claude/REQUIREMENTS.md`, and `.claude/ARCHITECTURE.md`, path-scoped rules in `.claude/rules/`, and on-demand domain narrative in `.claude/context/`. Indexes stay opt-in.
45
+ - Dictionaries live in `.cspell/`, hooks in `.husky/`, seeded context docs in `canon/context/`.
46
+ - The `canon/context/` location matches the three-tier context model: project-wide invariants in `CLAUDE.md`, `canon/REQUIREMENTS.md`, and `canon/ARCHITECTURE.md`, path-scoped rules in `.claude/rules/`, and on-demand domain narrative in `canon/context/`. Indexes stay opt-in.
47
47
 
48
48
  ## Hooks
49
49