@erclx/canon 5.19.0 → 5.20.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 (101) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/create-skill/SKILL.md +1 -0
  3. package/claude/skills/plan-feature/SKILL.md +1 -1
  4. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  5. package/claude/skills/record-screencast/REQUIREMENT.md +2 -1
  6. package/claude/skills/record-screencast/SKILL.md +2 -2
  7. package/claude/skills/role-worker/REQUIREMENT.md +3 -1
  8. package/claude/skills/role-worker/SKILL.md +5 -3
  9. package/claude/skills/session-resume/SKILL.md +1 -1
  10. package/claude/skills/task-board/REQUIREMENT.md +1 -0
  11. package/claude/skills/task-board/SKILL.md +6 -0
  12. package/claude/skills/task-board/references/decline.md +2 -0
  13. package/claude/skills/video-craft/REQUIREMENT.md +48 -0
  14. package/claude/skills/video-craft/SKILL.md +80 -0
  15. package/claude/skills/video-craft/references/adopted.md +66 -0
  16. package/docs/agents/canvas.md +4 -0
  17. package/docs/agents/demo.md +1 -1
  18. package/docs/agents/install-and-sync.md +17 -3
  19. package/docs/agents/rule-citations.md +4 -4
  20. package/docs/agents/sandbox.md +8 -7
  21. package/docs/workflow/operating-model.md +9 -9
  22. package/docs/workflow/parallel-features.md +1 -1
  23. package/docs/workflow/skill-map.md +1 -0
  24. package/governance/renames.toml +24 -0
  25. package/governance/rules/{canon/640-architecture.md → standards/architecture.md} +3 -2
  26. package/governance/rules/standards/context.md +15 -0
  27. package/governance/rules/standards/design.md +13 -0
  28. package/governance/rules/standards/diagrams.md +17 -0
  29. package/governance/rules/standards/groundwork.md +13 -0
  30. package/governance/rules/standards/intake.md +12 -0
  31. package/governance/rules/standards/markdown.md +15 -0
  32. package/governance/rules/standards/memory.md +12 -0
  33. package/governance/rules/standards/mermaid.md +15 -0
  34. package/governance/rules/{canon/658-plan.md → standards/plan.md} +5 -9
  35. package/governance/rules/standards/readme.md +12 -0
  36. package/governance/rules/standards/ready.md +13 -0
  37. package/governance/rules/standards/requirements.md +13 -0
  38. package/governance/rules/standards/rule.md +13 -0
  39. package/governance/rules/standards/session.md +13 -0
  40. package/governance/rules/{claude/570-skill.md → standards/skill.md} +6 -10
  41. package/governance/rules/standards/standard.md +13 -0
  42. package/governance/rules/standards/tasks.md +15 -0
  43. package/governance/rules/{canon/661-teach.md → standards/teach.md} +3 -2
  44. package/governance/rules/standards/wiki.md +13 -0
  45. package/governance/rules/standards/wireframes.md +14 -0
  46. package/governance/rules/writing/800-prose.md +1 -1
  47. package/governance/stacks/base.toml +4 -2
  48. package/package.json +1 -1
  49. package/src/canvas/capture.ts +228 -15
  50. package/src/claude/cases/misc.ts +5 -0
  51. package/src/claude/routing.ts +1 -1
  52. package/src/commands/canvas.ts +76 -2
  53. package/src/commands/gov.ts +19 -4
  54. package/src/commands/sandbox.ts +7 -0
  55. package/src/gate/stages.ts +7 -1
  56. package/src/gov/citations.ts +1 -1
  57. package/src/gov/standard-rules.ts +179 -0
  58. package/src/sandbox/equivalence.ts +43 -14
  59. package/src/sandbox/stub-remote.ts +140 -0
  60. package/standards/architecture.md +5 -0
  61. package/standards/context.md +6 -0
  62. package/standards/design.md +3 -0
  63. package/standards/diagrams.md +8 -0
  64. package/standards/groundwork-spikes.md +66 -0
  65. package/standards/groundwork.md +5 -25
  66. package/standards/index.md +6 -2
  67. package/standards/intake.md +2 -0
  68. package/standards/markdown.md +6 -0
  69. package/standards/memory.md +2 -0
  70. package/standards/mermaid.md +6 -0
  71. package/standards/plan-lifecycle.md +36 -0
  72. package/standards/plan.md +13 -11
  73. package/standards/readme.md +2 -0
  74. package/standards/ready.md +4 -0
  75. package/standards/requirements.md +3 -0
  76. package/standards/rule.md +6 -1
  77. package/standards/session.md +4 -0
  78. package/standards/skill-paths.md +50 -0
  79. package/standards/skill.md +15 -23
  80. package/standards/standard.md +7 -1
  81. package/standards/tasks-decline.md +38 -0
  82. package/standards/tasks.md +8 -13
  83. package/standards/teach.md +5 -0
  84. package/standards/wiki.md +4 -0
  85. package/standards/wireframes.md +5 -0
  86. package/governance/rules/canon/610-context.md +0 -17
  87. package/governance/rules/canon/620-wireframes.md +0 -13
  88. package/governance/rules/canon/630-requirements.md +0 -12
  89. package/governance/rules/canon/650-design.md +0 -12
  90. package/governance/rules/canon/655-tasks.md +0 -13
  91. package/governance/rules/canon/656-groundwork.md +0 -11
  92. package/governance/rules/canon/657-intake.md +0 -11
  93. package/governance/rules/canon/659-memory.md +0 -11
  94. package/governance/rules/canon/660-diagrams.md +0 -19
  95. package/governance/rules/canon/662-session.md +0 -15
  96. package/governance/rules/canon/663-ready.md +0 -15
  97. package/governance/rules/claude/590-rule-authoring.md +0 -12
  98. package/governance/rules/writing/801-markdown.md +0 -14
  99. package/governance/rules/writing/802-mermaid.md +0 -14
  100. package/governance/rules/writing/880-readme.md +0 -11
  101. package/governance/rules/writing/891-standard-authoring.md +0 -12
@@ -0,0 +1,140 @@
1
+ import { execFileSync } from 'node:child_process'
2
+ import {
3
+ chmodSync,
4
+ existsSync,
5
+ mkdirSync,
6
+ readdirSync,
7
+ readFileSync,
8
+ rmSync,
9
+ writeFileSync,
10
+ } from 'node:fs'
11
+ import { join } from 'node:path'
12
+
13
+ const STUB_ORG = 'stub-org'
14
+ const ANCHOR_REPO = 'canon-sandbox'
15
+
16
+ /** The URL `sandbox_anchor_url` builds once `GITHUB_ORG` names the stub organization. */
17
+ export const STUB_ANCHOR_URL = `https://github.com/${STUB_ORG}/${ANCHOR_REPO}.git`
18
+
19
+ /** Port 9 is the discard service, which nothing listens on, so a real HTTPS attempt fails. */
20
+ const DEAD_PROXY = 'http://127.0.0.1:9'
21
+
22
+ /** Pinned so a commit id depends on its tree alone and two provisions of one tree agree. */
23
+ const PINNED_DATE = '2026-01-01T00:00:00Z'
24
+
25
+ /**
26
+ * Answers the `gh` calls the git scenarios make and fails on any other, so a new
27
+ * call reaches a reader as a red arm rather than a silent pass. Every call is
28
+ * logged as one line, quoted so an argument holding a space stays one argument.
29
+ */
30
+ const STUB_GH = `#!/usr/bin/env bash
31
+ # stub gh
32
+ dir="$STUB_GH_DIR"
33
+ line="$(printf '%q ' "$@")"
34
+ line="\${line% }"
35
+ printf '%s\\n' "$line" >>"$dir/gh.log"
36
+
37
+ case "$1" in
38
+ api) exit 0 ;;
39
+ pr)
40
+ case "$2" in
41
+ create)
42
+ count="$(cat "$dir/pr-count" 2>/dev/null || echo 0)"
43
+ count=$((count + 1))
44
+ echo "$count" >"$dir/pr-count"
45
+ echo "https://github.com/${STUB_ORG}/${ANCHOR_REPO}/pull/$count"
46
+ exit 0
47
+ ;;
48
+ close | list) exit 0 ;;
49
+ esac
50
+ ;;
51
+ esac
52
+
53
+ printf '%s\\n' "$line" >>"$dir/gh-unknown.log"
54
+ echo "stub gh: unknown call: $line" >&2
55
+ exit 1
56
+ `
57
+
58
+ /**
59
+ * Builds a local bare repository and a stub `gh` under `stubDir` and returns the
60
+ * environment that sends a provision's pushes and `gh` calls there. Nothing in
61
+ * it reaches the shared anchor: the URL rewrite turns every push into a file
62
+ * path, and the stub heads `PATH` ahead of any real `gh`.
63
+ */
64
+ export function createStubRemote(stubDir: string): Record<string, string> {
65
+ rmSync(stubDir, { recursive: true, force: true })
66
+ const bin = join(stubDir, 'bin')
67
+ const remotes = join(stubDir, 'remotes')
68
+ mkdirSync(bin, { recursive: true })
69
+ mkdirSync(remotes, { recursive: true })
70
+
71
+ execFileSync(
72
+ 'git',
73
+ ['init', '-q', '--bare', '-b', 'main', join(remotes, `${ANCHOR_REPO}.git`)],
74
+ { stdio: 'ignore' },
75
+ )
76
+
77
+ const gh = join(bin, 'gh')
78
+ writeFileSync(gh, STUB_GH)
79
+ chmodSync(gh, 0o755)
80
+
81
+ return {
82
+ PATH: `${bin}:${process.env.PATH ?? ''}`,
83
+ STUB_GH_DIR: stubDir,
84
+ GITHUB_ORG: STUB_ORG,
85
+ GIT_CONFIG_COUNT: '1',
86
+ GIT_CONFIG_KEY_0: `url.${remotes}/.insteadOf`,
87
+ GIT_CONFIG_VALUE_0: `https://github.com/${STUB_ORG}/`,
88
+ GIT_AUTHOR_DATE: PINNED_DATE,
89
+ GIT_COMMITTER_DATE: PINNED_DATE,
90
+ HTTPS_PROXY: DEAD_PROXY,
91
+ https_proxy: DEAD_PROXY,
92
+ ALL_PROXY: DEAD_PROXY,
93
+ }
94
+ }
95
+
96
+ function git(cwd: string, args: string[]): string {
97
+ return execFileSync('git', args, {
98
+ cwd,
99
+ encoding: 'utf8',
100
+ stdio: ['ignore', 'pipe', 'pipe'],
101
+ }).trimEnd()
102
+ }
103
+
104
+ function readLog(path: string): string {
105
+ return existsSync(path) ? readFileSync(path, 'utf8').trimEnd() : ''
106
+ }
107
+
108
+ /**
109
+ * Reads what a provision left in the stub: the `gh` calls, the calls it did not
110
+ * recognize, and for each bare repository every ref with its tip tree and the
111
+ * commit subjects beneath it. A tree id carries no timestamp, so it compares
112
+ * across two runs where a commit id would not.
113
+ */
114
+ export function readStubManifest(stubDir: string): Map<string, string> {
115
+ const manifest = new Map<string, string>()
116
+ manifest.set('stub:gh', readLog(join(stubDir, 'gh.log')))
117
+ manifest.set('stub:gh-unknown', readLog(join(stubDir, 'gh-unknown.log')))
118
+
119
+ const remotes = join(stubDir, 'remotes')
120
+ if (!existsSync(remotes)) return manifest
121
+
122
+ for (const entry of readdirSync(remotes).sort()) {
123
+ if (!entry.endsWith('.git')) continue
124
+ const repo = join(remotes, entry)
125
+ const name = entry.slice(0, -'.git'.length)
126
+
127
+ const refs = git(repo, ['for-each-ref', '--format=%(refname) %(tree)'])
128
+ .split('\n')
129
+ .filter((line) => line !== '')
130
+ .map((line) => {
131
+ const ref = line.split(' ')[0] ?? ''
132
+ const subjects = git(repo, ['log', '--format= %s', '--reverse', ref])
133
+
134
+ return `${line}\n${subjects}`
135
+ })
136
+ manifest.set(`stub:${name}:refs`, refs.join('\n'))
137
+ }
138
+
139
+ return manifest
140
+ }
@@ -1,6 +1,11 @@
1
1
  ---
2
2
  title: Architecture reference
3
3
  description: Shape and content rules for canon/ARCHITECTURE.md
4
+ paths:
5
+ - 'canon/ARCHITECTURE.md'
6
+ - '.claude/ARCHITECTURE.md'
7
+ rule:
8
+ - "Add a decision here only when it fills one of the standard's slots, and write any other decision into the context entry for the domain it constrains. At the record's stated cap, merge or retire an entry before adding one."
4
9
  ---
5
10
 
6
11
  # Architecture reference
@@ -1,6 +1,12 @@
1
1
  ---
2
2
  title: Context entry reference
3
3
  description: Shape and content rules for canon/context/<domain>.md entries
4
+ paths:
5
+ - 'canon/context/**'
6
+ - '.claude/context/**'
7
+ rule:
8
+ - 'Before non-trivial work in a domain, read its `canon/context/<domain>.md` entry. Use `canon/context/index.md` to find it.'
9
+ - 'Leave the entry conforming when work in its domain changes what it describes.'
4
10
  ---
5
11
 
6
12
  # Context entry reference
@@ -1,6 +1,9 @@
1
1
  ---
2
2
  title: Design reference
3
3
  description: Shape and content rules for canon/DESIGN.md
4
+ paths:
5
+ - 'canon/DESIGN.md'
6
+ - '.claude/DESIGN.md'
4
7
  ---
5
8
 
6
9
  # Design reference
@@ -1,6 +1,14 @@
1
1
  ---
2
2
  title: Diagram reference
3
3
  description: Shape and content rules for .canon/diagrams/<kind>.md files
4
+ paths:
5
+ - '.canon/diagrams/**'
6
+ - '.claude/DIAGRAMS.md'
7
+ rule:
8
+ - 'Layout, budgets, accessibility, labels, and render verification inside the fence are a separate topic. The mermaid standard routes them.'
9
+ - 'A diagram entry carries structure and flow, not implementation. Read the standard before adding or revising a kind.'
10
+ - 'Write a new diagram to `.canon/diagrams/<kind>.md`, never to `.claude/DIAGRAMS.md`'
11
+ - 'Convert a `.claude/DIAGRAMS.md` left by an older install into per-kind entries before editing it'
4
12
  ---
5
13
 
6
14
  # Diagram reference
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: Groundwork spikes reference
3
+ description: What each spike in a track's 08-spikes.md records, the sample rule, and the three folders that hold what a spike produced
4
+ ---
5
+
6
+ # Groundwork spikes reference
7
+
8
+ Applies to `08-spikes.md` inside a groundwork track at `.canon/groundwork/<nn>-<slug>/`, and to the folders beside it that hold what a spike produced. It records evidence by experiment, beside the evidence by measurement `01-current-state.md` holds.
9
+
10
+ ## Scope
11
+
12
+ Governs `08-spikes.md`, what each spike in it carries, how a spike is sized, and the `evidence/`, `scripts/`, and `clones/` folders in a track.
13
+
14
+ Does not govern:
15
+
16
+ - The track's folder layout, its other files, frontmatter, and numbering: `groundwork.md`
17
+ - Running a spike, which belongs to the surface driving the track
18
+
19
+ ## What a working spike record looks like
20
+
21
+ A spike record works when a later reader can re-run each spike and trust what it settled:
22
+
23
+ - Which open question did each spike answer, and did it close it?
24
+ - Can the method be re-run from the file, against the fixture it names?
25
+ - What did it cost, and what does the result not prove?
26
+
27
+ ## Spikes
28
+
29
+ The file is optional, since measuring what is already there settles most questions.
30
+
31
+ Each spike carries four things:
32
+
33
+ - The open question it answers, named by file and number. A spike attached to no question is a runaway.
34
+ - The method, stated fully enough for a later reader to re-run it. Name the fixture and where it lived, since an arm pointed at a fixture inside the project measured the project, plus the exact command and the repetition count.
35
+ - The result, and which question it closes. Record a spike that settles nothing too, so a later pass does not pay for it twice.
36
+ - The measured cost, even for a single read, and the caveats bounding what the result proves. Cost is a report rather than a limit, and it makes the next spike estimable.
37
+
38
+ Start a spike against a sample bounded on input size, duration, and spend, and scale up only once it shows the method works. Record the sample's bounds beside the figure for the full input.
39
+
40
+ ## What a spike produced
41
+
42
+ A file a reader opens to verify how a result was produced or what it showed lives inside the track, and bulk input such as a large fixture stays outside it. Three unnumbered subfolders carry the first kind, since a reader reaches them from the citing claim rather than in read order:
43
+
44
+ - `evidence/`: what a run produced and the record cites, being a recording, a render, or a frame pulled from one, beside the file citing it.
45
+ - `scripts/`: the arm scripts and harnesses a spike ran, which a reader opens to check the method.
46
+ - `clones/`: checkouts and copies of outside material a claim rests on, kept small enough to hold in the folder. A checkout too large to keep is cited by its address and commit instead.
47
+
48
+ Open no other subfolder: `spikes/`, `web/`, and `research/` fold into these three, with a fetched page in `clones/` and a reference-site screenshot in `evidence/`.
49
+
50
+ Reach for a test harness the project already carries before building one. An experiment no existing harness can express is a finding for the folder, not a new abstraction.
51
+
52
+ Never count transcript matches to show a file was read. An instruction naming a path puts it in the transcript whether or not anything opened it, so the check is the tool call.
53
+
54
+ ## Template
55
+
56
+ ```markdown
57
+ # Spikes
58
+
59
+ ## <nn>. <what the spike tests>
60
+
61
+ - Question: <file and number of the open question>
62
+ - Method: <fixture and where it lived, exact command, repetition count>
63
+ - Result: <what it showed, and which question it closes>
64
+ - Cost: <measured cost>, <sample bounds beside the full-input figure>
65
+ - Caveats: <what the result does not prove>
66
+ ```
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  title: Groundwork reference
3
3
  description: Folder layout, ordinal naming, reserved numbering, frontmatter and dating, required file contents, and conventions for a measurement track
4
+ paths:
5
+ - '.canon/groundwork/**'
6
+ rule:
7
+ - 'Follow the groundwork spikes standard for `08-spikes.md` and the folders holding what a spike produced. Read it with `canon standards groundwork-spikes`.'
4
8
  ---
5
9
 
6
10
  # Groundwork reference
@@ -15,6 +19,7 @@ Governs a groundwork track under `.canon/groundwork/<nn>-<slug>/`: folder layout
15
19
 
16
20
  Does not govern:
17
21
 
22
+ - `08-spikes.md`, what each spike records, and the folders holding what a spike produced: `groundwork-spikes.md`
18
23
  - A dump of many findings filed by domain, each carrying its own verdict: `intake.md`
19
24
  - The feature plan a closed track feeds, and the contract its answer slots keep: `plan.md`
20
25
  - The task file a closing track writes, and the origin line pointing back at the folder: `tasks.md`
@@ -110,31 +115,6 @@ The dropped list is what stops a future session re-proposing something already r
110
115
 
111
116
  Written to survive a compaction that loses the conversation. It repeats facts held elsewhere in the folder rather than pointing at them. That duplication is correct here and wrong everywhere else.
112
117
 
113
- ## 08-spikes.md
114
-
115
- Evidence by experiment, beside the evidence by measurement `01-current-state.md` holds. Optional, since measuring what is already there settles most questions.
116
-
117
- Each spike carries four things:
118
-
119
- - The open question it answers, named by file and number. A spike attached to no question is a runaway.
120
- - The method, stated fully enough for a later reader to re-run it. Name the fixture and where it lived, since an arm pointed at a fixture inside the project measured the project, plus the exact command and the repetition count.
121
- - The result, and which question it closes. Record a spike that settles nothing too, so a later pass does not pay for it twice.
122
- - The measured cost, even for a single read, and the caveats bounding what the result proves. Cost is a report rather than a limit, and it makes the next spike estimable.
123
-
124
- Start a spike against a sample bounded on input size, duration, and spend, and scale up only once it shows the method works. Record the sample's bounds beside the figure for the full input.
125
-
126
- A file a reader opens to verify how a result was produced or what it showed lives inside the track, and bulk input such as a large fixture stays outside it. Three unnumbered subfolders carry the first kind, since a reader reaches them from the citing claim rather than in read order:
127
-
128
- - `evidence/`: what a run produced and the record cites, being a recording, a render, or a frame pulled from one, beside the file citing it.
129
- - `scripts/`: the arm scripts and harnesses a spike ran, which a reader opens to check the method.
130
- - `clones/`: checkouts and copies of outside material a claim rests on, kept small enough to hold in the folder. A checkout too large to keep is cited by its address and commit instead.
131
-
132
- Open no other subfolder: `spikes/`, `web/`, and `research/` fold into these three, with a fetched page in `clones/` and a reference-site screenshot in `evidence/`.
133
-
134
- Reach for a test harness the project already carries before building one. An experiment no existing harness can express is a finding for the folder, not a new abstraction.
135
-
136
- Never count transcript matches to show a file was read. An instruction naming a path puts it in the transcript whether or not anything opened it, so the check is the tool call.
137
-
138
118
  ## Open questions
139
119
 
140
120
  Every open question carries a lean, wherever it appears. A bare numbered list hands the reader a quiz and defers the judgment the track exists to inform.
@@ -17,12 +17,14 @@ Reference docs for consistent authoring across the toolkit and target projects.
17
17
  - [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
18
18
  - [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
19
19
  - [Glossary reference](glossary.md): Frontmatter, entry shape, ordering, and the rules deciding which terms a glossary carries
20
+ - [Groundwork spikes reference](groundwork-spikes.md): What each spike in a track's 08-spikes.md records, the sample rule, and the three folders that hold what a spike produced
20
21
  - [Groundwork reference](groundwork.md): Folder layout, ordinal naming, reserved numbering, frontmatter and dating, required file contents, and conventions for a measurement track
21
22
  - [Intake reference](intake.md): Folder layout, ordinal naming, reserved index number, frontmatter and dating, the item template, the answer contract, and retrieval
22
23
  - [Markdown reference](markdown.md): Headings, paragraph and list structure, code spans, the date form, punctuation, emphasis, file references, American spelling, and frontmatter wording
23
24
  - [Memory reference](memory.md): Filename and type prefix, frontmatter, the body shape per type, links between entries, and the lifecycle from write to retire
24
25
  - [Mermaid reference](mermaid.md): Direction and layout, node and edge budgets, accessibility fields, label punctuation, and render verification for a Mermaid diagram
25
- - [Plan reference](plan.md): Filename and slug, required sections, the suggested-and-answer contract, and the lifecycle from the live folder to the archive
26
+ - [Plan lifecycle reference](plan-lifecycle.md): When a feature plan is written, where it lives, how it changes mid-flight, and its move to the archive
27
+ - [Plan reference](plan.md): Filename and slug, the required sections, and the suggested-and-answer contract for a feature plan
26
28
  - [Pull request reference](pr.md): Pull request title and body conventions
27
29
  - [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
30
  - [Readme reference](readme.md): Readme voice, structure, and content conventions
@@ -30,11 +32,13 @@ Reference docs for consistent authoring across the toolkit and target projects.
30
32
  - [Requirements reference](requirements.md): Shape and content rules for canon/REQUIREMENTS.md
31
33
  - [Governance rule reference](rule.md): Rule frontmatter, body shape, and voice for .claude/rules files
32
34
  - [Session map reference](session.md): Filename and location, the sections a handoff carries, the write and read procedures, and how a role extends it
35
+ - [Skill path reference](skill-paths.md): Which root a file a skill body names resolves against, and how a body cites a standard
33
36
  - [Practice skill reference](skill-practice.md): Closing sections and source ledger for a skill carrying engineering practice
34
37
  - [Skill requirement reference](skill-requirement.md): Shape and content rules for the REQUIREMENT.md beside a skill
35
- - [Claude skill reference](skill.md): Claude skill structure and authoring rules
38
+ - [Claude skill reference](skill.md): Skill structure and authoring rules for Claude Code
36
39
  - [Slug reference](slug.md): Transform from a git branch name to a slug, and the three responses to an empty result
37
40
  - [Standard reference](standard.md): Shape and content rules for authoring a standard
41
+ - [Task decline reference](tasks-decline.md): Where a task decided against moves, the Declined line it carries, and what happens to its plan and board row
38
42
  - [Tasks reference](tasks.md): Folder layout, filename convention, file format, origin lines, and archiving for task files under .canon/tasks/
39
43
  - [Teach reference](teach.md): Workspace layout, ordinal naming, frontmatter, and the mission and learning-record formats for a learning workspace
40
44
  - [Versioning reference](versioning.md): Phase label vs semver discipline across tasks, PRs, reviews, issues, commits, and tags
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  title: Intake reference
3
3
  description: Folder layout, ordinal naming, reserved index number, frontmatter and dating, the item template, the answer contract, and retrieval
4
+ paths:
5
+ - '.canon/intake/**'
4
6
  ---
5
7
 
6
8
  # Intake reference
@@ -1,6 +1,12 @@
1
1
  ---
2
2
  title: Markdown reference
3
3
  description: Headings, paragraph and list structure, code spans, the date form, punctuation, emphasis, file references, American spelling, and frontmatter wording
4
+ paths:
5
+ - '**/*.md'
6
+ rule:
7
+ - 'Read it before a substantial markdown edit. Do not work the banned characters from memory.'
8
+ - 'Run `canon markdown audit <path>` after the edit, and rewrite the sentence carrying a hit rather than swapping the token for a near-synonym.'
9
+ - 'Voice, rhythm, and sentence construction are a separate topic. `800-prose` routes them.'
4
10
  ---
5
11
 
6
12
  # Markdown reference
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  title: Memory reference
3
3
  description: Filename and type prefix, frontmatter, the body shape per type, links between entries, and the lifecycle from write to retire
4
+ paths:
5
+ - '.canon/memory/**'
4
6
  ---
5
7
 
6
8
  # Memory reference
@@ -1,6 +1,12 @@
1
1
  ---
2
2
  title: Mermaid reference
3
3
  description: Direction and layout, node and edge budgets, accessibility fields, label punctuation, and render verification for a Mermaid diagram
4
+ paths:
5
+ - '**/*.md'
6
+ rule:
7
+ - 'Apply this rule only when the edit drafts or revises a Mermaid fence. Skip it on a markdown edit carrying no diagram.'
8
+ - 'Read it before drafting the fence. Do not work the layout or the budgets from memory.'
9
+ - 'Which diagram a document carries and what question it answers is a separate topic. The diagrams standard routes it.'
4
10
  ---
5
11
 
6
12
  # Mermaid reference
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: Plan lifecycle reference
3
+ description: When a feature plan is written, where it lives, how it changes mid-flight, and its move to the archive
4
+ ---
5
+
6
+ # Plan lifecycle reference
7
+
8
+ Applies to a feature plan at `.canon/plans/feature-<slug>.md` from the session that writes it to the archive. The folder is gitignored, so nothing but this lifecycle keeps a plan's rejected alternatives readable after the work ships.
9
+
10
+ This standard governs when a plan moves and changes rather than what the file holds, so it carries no template. The plan's own template is in `plan.md`.
11
+
12
+ ## Scope
13
+
14
+ Governs when a feature plan is written, where it lives across working trees, how it is amended, and its move to `.canon/plans/archive/`.
15
+
16
+ Does not govern:
17
+
18
+ - The filename, the required sections, and the suggested-and-answer contract: `plan.md`
19
+ - The task file a plan is linked from, and how it is archived: `tasks.md`
20
+
21
+ ## What a working lifecycle looks like
22
+
23
+ A plan's lifecycle works when a later reader can still answer, from the file alone:
24
+
25
+ - What did the work set out to do, and which alternative did it reject?
26
+ - Which answer to each question is current, without reconciling two passages?
27
+
28
+ A plan lost to deletion, or carrying two answers to one question, fails both.
29
+
30
+ ## Lifecycle
31
+
32
+ - Write the plan before implementation starts, and treat it as the scope of the run that executes it. A subject that has to be measured before anyone can plan against it takes a measurement track first.
33
+ - Keep every plan at one root. A plan copied into each parallel working tree forks, and the copies answer the same question differently.
34
+ - Amend the plan in place when a decision changes mid-flight. Do not append a second passage narrating the change, which leaves a reader to work out which of two answers is current. An execution-time deviation from a suggestion is one such amendment, and the suggested-and-answer contract in `plan.md` fixes which line takes it.
35
+ - Move the plan to `.canon/plans/archive/` when the work it describes ships or is declined. Never delete it, because the plan is where the rejected alternative is written down. A flat `.claude/plans-archive/` sibling is the older layout.
36
+ - Write the plan in the same session that opens the task it serves. The session executing it later inherits reasoning it would otherwise re-derive.
package/standards/plan.md CHANGED
@@ -1,20 +1,30 @@
1
1
  ---
2
2
  title: Plan reference
3
- description: Filename and slug, required sections, the suggested-and-answer contract, and the lifecycle from the live folder to the archive
3
+ description: Filename and slug, the required sections, and the suggested-and-answer contract for a feature plan
4
+ paths:
5
+ - '.canon/plans/**'
6
+ rule:
7
+ - 'Never fill an `- Answer:` slot on behalf of the person who owns it. A blank slot accepts the suggestion at execution time.'
8
+ - 'Never ship a question without a `- Suggested:` line. Write `- Suggested: needs your call, <why>` where the answer turns on preference.'
9
+ - "Rewrite the `- Suggested:` line as `overridden at execution to <pick>,` plus the measurement when execution deviates from an unanswered question, leaving the slot blank. Put the same deviation in one line under the open task's `## Findings`."
10
+ - 'Move a shipped plan to `.canon/plans/archive/`. Never delete one.'
11
+ - 'Amend a plan in place when a decision changes. Do not append a second passage narrating the change.'
12
+ - 'Follow the plan lifecycle standard for when a plan is written, how it is amended, and its move to the archive. Read it with `canon standards plan-lifecycle`.'
4
13
  ---
5
14
 
6
15
  # Plan reference
7
16
 
8
17
  Applies to a feature plan at `.canon/plans/feature-<slug>.md`. One file holds one concern, written before implementation starts and read by whatever executes it, so it has to carry the scope without the conversation that produced it.
9
18
 
10
- The folder is gitignored, and backed by `canon records push` wherever a records remote is configured. Nothing backs a plan deleted before a push, which is why the archive step below is a move rather than a cleanup.
19
+ The folder is gitignored, and backed by `canon records push` wherever a records remote is configured. Nothing backs a plan deleted before a push, which is why the archive step is a move rather than a cleanup.
11
20
 
12
21
  ## Scope
13
22
 
14
- Governs a feature plan under `.canon/plans/feature-<slug>.md`: the filename, the required sections, what each holds, the suggested-and-answer contract, and the lifecycle from the live folder to the archive.
23
+ Governs a feature plan under `.canon/plans/feature-<slug>.md`: the filename, the required sections, what each holds, and the suggested-and-answer contract.
15
24
 
16
25
  Does not govern:
17
26
 
27
+ - When a plan is written, how it is amended, and its move to the archive: `plan-lifecycle.md`
18
28
  - One question measured in depth before anyone can plan against it: `groundwork.md`
19
29
  - A dump of many findings filed by domain, each carrying its own verdict: `intake.md`
20
30
  - The task file a plan is linked from, and the origin line pointing back at it: `tasks.md`
@@ -135,14 +145,6 @@ The plan is archived at ship, so the same deviation takes one line in the open t
135
145
 
136
146
  This contract inverts the one an intake folder keeps, where an empty slot means unread and acceptance is typed out. A plan is written and read in one sitting with every question already surfaced, so silence is a usable default here and is not one there.
137
147
 
138
- ## Lifecycle
139
-
140
- - Write the plan before implementation starts, and treat it as the scope of the run that executes it. A subject that has to be measured before anyone can plan against it takes a measurement track first.
141
- - Keep every plan at one root. A plan copied into each parallel working tree forks, and the copies answer the same question differently.
142
- - Amend the plan in place when a decision changes mid-flight. Do not append a second passage narrating the change, which leaves a reader to work out which of two answers is current. An execution-time deviation from a suggestion is one such amendment, and the contract above fixes which line takes it.
143
- - Move the plan to `.canon/plans/archive/` when the work it describes ships or is declined. Never delete it, because the plan is where the rejected alternative is written down. A flat `.claude/plans-archive/` sibling is the older layout.
144
- - Write the plan in the same session that opens the task it serves. The session executing it later inherits reasoning it would otherwise re-derive.
145
-
146
148
  ## Template
147
149
 
148
150
  ```markdown
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  title: Readme reference
3
3
  description: Readme voice, structure, and content conventions
4
+ paths:
5
+ - '**/README.md'
4
6
  ---
5
7
 
6
8
  # Readme reference
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  title: Ready reference
3
3
  description: Folder layout, ordinal naming, the overview frontmatter, the thin-plan contract, and the archive lifecycle for a finished-file handoff
4
+ paths:
5
+ - '.canon/ready/**'
6
+ rule:
7
+ - 'Load the `canon:draft-ready` skill to write a ready folder, its overview, the thin plan, and the task row. It owns the procedure. Report it rather than proceeding silently when it does not resolve, since it ships with the plugin and this rule ships with the CLI.'
4
8
  ---
5
9
 
6
10
  # Ready reference
@@ -1,6 +1,9 @@
1
1
  ---
2
2
  title: Requirements reference
3
3
  description: Shape and content rules for canon/REQUIREMENTS.md
4
+ paths:
5
+ - 'canon/REQUIREMENTS.md'
6
+ - '.claude/REQUIREMENTS.md'
4
7
  ---
5
8
 
6
9
  # Requirements reference
package/standards/rule.md CHANGED
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  title: Governance rule reference
3
3
  description: Rule frontmatter, body shape, and voice for .claude/rules files
4
+ paths:
5
+ - '.claude/rules/**/*.md'
6
+ rule:
7
+ - 'Read it before writing or editing a rule. Do not work the shape from memory.'
4
8
  ---
5
9
 
6
10
  # Governance rule reference
@@ -36,7 +40,8 @@ Write both when both apply. A rule stating the directive and a skill stating how
36
40
  - `<n>` is a number from the band reserved for the rule's source and `<slug>` is a one-to-three-word kebab topic
37
41
  - A rule the project authored itself lives at `.claude/rules/project/<subdirectory>/<n>-<slug>.md`, a sibling of `canon/` rather than nested inside it, keeping the same subdirectory names
38
42
  - This repository's own toolkit-only rules, which never ship to a target, live at `.claude/rules/internal/<subdirectory>/<n>-<slug>.md`, a second sibling of `canon/`. See "Two sources numbering into one folder" below.
39
- - Give every rule a numeric prefix. A bare-word filename reads as a folder name where a stack names its rules, so a rule without one is unreachable from a stack entry.
43
+ - Give every authored rule a numeric prefix. A bare-word filename reads as a folder name where a stack names its rules, so a rule without one is unreachable from a stack entry.
44
+ - A rule that only routes a path to a standard is generated, not authored. It lives at `governance/rules/standards/<standard>.md` under the standard's name, carries no number, and installs to `.claude/rules/canon/standards/`. Never hand-edit one. Change its globs and bullets in the standard's `paths` and `rule` frontmatter, and `canon gov regen` rewrites it. The generator refuses a standard named like a band folder, which keeps the bare-word name reachable.
40
45
 
41
46
  ## Reserved numbers
42
47
 
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  title: Session map reference
3
3
  description: Filename and location, the sections a handoff carries, the write and read procedures, and how a role extends it
4
+ paths:
5
+ - '.canon/tasks/session-*.md'
6
+ rule:
7
+ - 'Follow this rule rather than the tasks rule for a `session-` file. A handoff is not a task and carries neither `## Outcomes` nor `## Findings`.'
4
8
  ---
5
9
 
6
10
  # Session map reference
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Skill path reference
3
+ description: Which root a file a skill body names resolves against, and how a body cites a standard
4
+ ---
5
+
6
+ # Skill path reference
7
+
8
+ Applies to every path a skill body names, under `skills/<name>/`. A skill reads from two roots, so the path it writes decides whether the file is found once the skill runs from another project.
9
+
10
+ This is an attribute standard. It governs the path strings a body carries rather than a file of its own, so it carries no template.
11
+
12
+ ## Scope
13
+
14
+ Governs how a `SKILL.md` body or a file under its `references/` names a bundled asset, an installed shared doc, or a standard.
15
+
16
+ Does not govern:
17
+
18
+ - The skill folder, its frontmatter, the body rules, and the choice between skill types: `skill.md`
19
+ - Punctuation, formatting, and word choice: `markdown.md`
20
+
21
+ ## What a working path looks like
22
+
23
+ A path in a skill body works when the skill resolves it from any project it runs in:
24
+
25
+ - Does each bundled asset resolve against the skill's own directory rather than the session's working directory?
26
+ - Does each cited standard resolve in a target that installed nothing but the plugin?
27
+ - Does a procedure two skills share live in one place, with each body citing it?
28
+
29
+ A body failing any of these is non-conforming even when every path resolves in this repository.
30
+
31
+ ## Path resolution
32
+
33
+ Know which root a file lives under before referencing it.
34
+
35
+ - Bundled skill assets (`references/`, `scripts/`, `assets/`) resolve against the skill's own directory. Reference them with `${CLAUDE_SKILL_DIR}/<path>`, never a bare relative path, which resolves against the session cwd and fails when a plugin skill runs from another project.
36
+ - Installed shared docs (`.claude/rules/`, `canon/context/`) resolve against the target project cwd, where install placed them. Reference them by that path.
37
+ - Do not hand-copy a standard into a skill. 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.
38
+
39
+ ## Citing a standard
40
+
41
+ No standard installs into a project, so a body cites one place rather than choosing between two.
42
+
43
+ - Cite `${CLAUDE_SKILL_DIR}/../../standards/X.md`. The plugin ships the whole standards folder beside `skills/`, so the path resolves in every install.
44
+ - Never cite `.claude/standards/X.md` from a shipped body. A target holds no such folder. <!-- audit-ignore-citations: .claude/standards/X.md -->
45
+ - Name `canon standards X` instead where the body wants the document rather than a path to open, such as a value it captures or reports. That verb resolves `standards/` at the project root and then the corpus inside the package.
46
+ - State the path once per body, at the site that reads the standard. A later mention of a standard the body already read stays bare, since repeating the path at every mention is noise rather than instruction.
47
+ - A guard on a standard's presence names the file rather than the folder holding it, since a folder test answers for a sibling that happens to be there.
48
+ - Use `${CLAUDE_SKILL_DIR}`, never a bare `../../` and never `${CLAUDE_PLUGIN_ROOT}`, since only the first expands before the body reaches the model.
49
+ - Cite a shared procedure, never restate it. A procedure two or more skills execute gets one definition in a standard and a citation in each body.
50
+ - Keep the trigger in the body and the procedure in the standard. The citing skill states when the procedure runs and what it runs against, since that varies per skill and the standard cannot know it.