@erclx/canon 4.80.0 → 4.82.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.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/design-extract/SKILL.md +5 -1
- package/claude/skills/sketch-design/REQUIREMENT.md +38 -0
- package/claude/skills/sketch-design/SKILL.md +92 -0
- package/claude/skills/teach-workspace/SKILL.md +23 -1
- package/claude/skills/teach-workspace/references/lesson-craft.md +11 -0
- package/docs/agents/commands.md +11 -5
- package/docs/agents/context-audit.md +1 -1
- package/docs/agents/context-classify.md +99 -0
- package/docs/agents/design-board.md +13 -11
- package/docs/agents/index.md +2 -1
- package/docs/agents/teach.md +16 -0
- package/docs/target-projects.md +15 -0
- package/docs/workflow/ai-workflow.md +4 -2
- package/docs/workflow/visual-design-workflow.md +1 -0
- package/governance/rules/claude/545-decisions.md +12 -0
- package/package.json +1 -1
- package/src/claude/cases/misc.ts +5 -0
- package/src/claude/seeds.ts +1 -0
- package/src/commands/claude.ts +26 -5
- package/src/commands/context.ts +425 -0
- package/src/commands/design.ts +24 -8
- package/src/commands/teach.ts +118 -0
- package/src/context/classify/extract.ts +450 -0
- package/src/context/classify/ollama.ts +172 -0
- package/src/context/classify/patterns.ts +114 -0
- package/src/context/classify/prompts.ts +73 -0
- package/src/context/classify/run.ts +348 -0
- package/src/context/classify/settings.ts +196 -0
- package/src/context/folders.ts +1 -0
- package/src/design/board.ts +130 -47
- package/src/project-root.ts +16 -0
- package/src/surface-root.ts +1 -0
- package/src/teach/render.ts +126 -0
- package/standards/decisions.md +100 -0
- package/standards/index.md +1 -0
- package/tooling/claude/reference.md +1 -0
- package/tooling/claude/seeds/CLAUDE.md +1 -0
- package/tooling/claude/seeds/canon/decisions/index.md +8 -0
|
@@ -17,7 +17,7 @@ Step 1 carries two more stops that apply to one path only. Do not evaluate them
|
|
|
17
17
|
Check the project root for UI surfaces: `src/ui.ts`, `src/ui.tsx`, `src/components/**`, `scripts/lib/ui.sh`, and any `*.css`, `tailwind.config.*`, or `theme.*`.
|
|
18
18
|
|
|
19
19
|
- Any match takes the source path. Existing code defines the system, so every filled cell traces to a value already in the tree.
|
|
20
|
-
- No match takes the greenfield path. Nothing anchors a value, so
|
|
20
|
+
- No match takes the greenfield path. Nothing anchors a value there unless a picked reference does, so name `sketch-design` as the first move: a picked reference anchors a cell where a paragraph alone cannot. A direct run of this skill still falls through to the proposal-from-personality rules in Step 4, tag included, so this skill stays runnable on its own with nothing rendered yet.
|
|
21
21
|
|
|
22
22
|
The project decides this, never a user flag or an argument. Announce which path ran in one line before Step 2, since the two produce different-looking output from the same skill.
|
|
23
23
|
|
|
@@ -39,6 +39,8 @@ On the source path, also read the UI surfaces matched in Step 1 plus `canon docs
|
|
|
39
39
|
|
|
40
40
|
On the greenfield path, also read `canon/ARCHITECTURE.md` for platform, tech stack, and surface type. Do not scan `src/`, stylesheets, or UI modules. Step 1 already established they hold nothing.
|
|
41
41
|
|
|
42
|
+
On the greenfield path, also check `.canon/review/evidence/*/design-handoff.md` for a file the `sketch-design` skill wrote, taking the most recently modified match when more than one exists. Read it when found. Its presence is what Step 4 traces cells from instead of proposing them.
|
|
43
|
+
|
|
42
44
|
Run these reads in parallel. Do not speculatively recurse into every directory.
|
|
43
45
|
|
|
44
46
|
## Step 3: fetch the seed template
|
|
@@ -72,6 +74,8 @@ On the source path, the tag marks the exception. On the greenfield path it marks
|
|
|
72
74
|
|
|
73
75
|
Anchor every proposal to a signal, never to a default. "Calm and dense" pins muted grays and tight spacing. A requirements non-goal of "no motion" makes Motion read `No animation.` with no tag. A CLI-only surface leans Typography monospaced and keeps Borders minimal.
|
|
74
76
|
|
|
77
|
+
- **Traced cells**: when Step 2 matched a `design-handoff.md` file, fill only the fields it actually states, no tag, the same traced-versus-proposed distinction the source path draws for a stylesheet value.
|
|
78
|
+
- The handoff carries hex and family and size, never Weight, Line height, or a color's Intent. Those cells, every field of a role the handoff never names, and Motion and Iconography regardless, still follow the proposal rules below, tag included.
|
|
75
79
|
- **Personality**: transcribe the `## Personality` paragraph from `canon/REQUIREMENTS.md` verbatim. This is the one section that is not a proposal. No tag.
|
|
76
80
|
- **Color**: one row per role. Rewrite the Intent cell in personality language, for example `warm off-white page canvas` instead of the seed default `page canvas`. Propose hex values matching the personality. Dense and calm gives low saturation and high text contrast. Playful gives saturated accents. Every Intent and Value cell gets `? verify`.
|
|
77
81
|
- **Typography**: one row per role. Propose families fitting the platform, system UI for web, monospaced for CLI tools, serif for editorial, and a harmonious scale. Every cell gets `? verify`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sketch-design
|
|
3
|
+
description: Why a greenfield design value needs a render behind it before it reaches DESIGN.md, and where the reference loop stops short of writing that file itself
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sketch design requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, a session asked to match a look an operator has in mind either invents token values from a personality paragraph alone, which is what `design-extract`'s greenfield path already does and states plainly as a proposal rather than a fact, or builds a one-off render-and-pick comparison by hand for each request, restating `draft-and-pick`'s candidate page, hand-off, and pick mechanics from scratch with nothing comparing the copy to the shipped one. Neither path lets an operator point at a reference image or a live page and have the values that follow trace back to what was actually looked at and picked.
|
|
11
|
+
|
|
12
|
+
## Must
|
|
13
|
+
|
|
14
|
+
- Take at least two operator-supplied references, each a path to an image on disk or a URL to render, and gather them through this skill's own Step 1 prompt rather than a caller-supplied argument
|
|
15
|
+
- Render every URL reference before drafting, and report a capture refusal naming an unrecognized source as a version gap rather than a broken reference
|
|
16
|
+
- Follow `draft-and-pick`'s candidate page, render, hand-off, structured pick, and archival capture mechanics rather than restating them
|
|
17
|
+
- Trace the picked reference's color, type, and spacing by reading its render, and carry the operator's own stated reason for the pick forward as written
|
|
18
|
+
- Write the handoff one field per line, grouped under the section names `standards/design.md` already fixes for `canon/DESIGN.md`, so `design-extract` can read it mechanically
|
|
19
|
+
- Resolve the handoff file and the archival capture against the main worktree root, never against a linked worktree this run happens to be building in
|
|
20
|
+
|
|
21
|
+
## Must not
|
|
22
|
+
|
|
23
|
+
- Write to `canon/DESIGN.md`. Tracing values into the handoff is this skill's whole output. Filling the design document from them is `design-extract`'s Step 2, kept as the one place that file is written.
|
|
24
|
+
- Take the pick on the operator's behalf. That call is theirs on every arm that is defensible, the same boundary `draft-and-pick` states for itself.
|
|
25
|
+
- Restate `draft-and-pick`'s render, hand-off, pick, or loop mechanics, or `canon capture`'s render mechanics
|
|
26
|
+
- Assume this skill's own invocation frequency needs no check. `design-extract` Step 1 points to it as the first move on the greenfield path, and an operator can also type its name directly, so whether anything else reaches for it has an answer only after a review pass reads usage back, rather than at creation time.
|
|
27
|
+
|
|
28
|
+
## Guards
|
|
29
|
+
|
|
30
|
+
- `canon` not on PATH: stop, since the render loop and the capture calls both need it
|
|
31
|
+
- Fires on a direct request or on `design-extract`'s own pointer, never on the model's own read that a project could use a design direction
|
|
32
|
+
|
|
33
|
+
## Out of scope
|
|
34
|
+
|
|
35
|
+
- `design-extract` reads the handoff this skill writes and fills `canon/DESIGN.md` from it. That fill, and the seed template it starts from, stay entirely that skill's own.
|
|
36
|
+
- `draft-and-pick` owns the render, hand-off, pick, and loop mechanics this skill invokes rather than reimplements
|
|
37
|
+
- `canon capture` and `canon serve` own the render and the address mechanics
|
|
38
|
+
- Auditing an implemented UI against its tokens, which `ux-audit` owns
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sketch-design
|
|
3
|
+
description: Runs a reference-and-pick loop against operator-supplied images and URLs, then writes the picked reference's traced color, type, and spacing values to a handoff file `design-extract` reads. Use when asked to "sketch a design direction", "compare these reference sites", "pick a look before we build DESIGN.md", "show me a few design directions", or as the first move on `design-extract`'s greenfield path when nothing has been rendered yet. Do NOT use when a value is already anchored to running code or a stylesheet, which is `design-extract`'s source path, or to draft the design system document itself, which stays `design-extract`'s job.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sketch design
|
|
7
|
+
|
|
8
|
+
`design-extract`'s greenfield path proposes color, type, and spacing from a personality paragraph alone, with no render behind any value. This skill puts operator-supplied references in front of a render instead, so the values `design-extract` fills are traced to a picked reference rather than invented from prose.
|
|
9
|
+
|
|
10
|
+
## Guards
|
|
11
|
+
|
|
12
|
+
- If `canon` is not on PATH, stop: `❌ canon CLI not found.`
|
|
13
|
+
- Draft no comparison for a reference set the operator has not supplied. This skill fires on a direct request or on `design-extract` pointing at it, never on the model's own read that a project could use one.
|
|
14
|
+
|
|
15
|
+
## Step 1: gather the references and render what needs it
|
|
16
|
+
|
|
17
|
+
Ask the operator, in this step's own prompt, for the references to compare: a path to an image already on disk for each one already rendered somewhere, and a full URL for each live page to render. Take at least two.
|
|
18
|
+
|
|
19
|
+
Follow `${CLAUDE_SKILL_DIR}/../draft-and-pick/SKILL.md` Step 1 items 2 through 5 to name the decision and derive `<dest>`, with the decision fixed rather than derived: "which of these references the project's design should draw from." Arm 0 is the current state when `canon/DESIGN.md` already carries filled Color, Typography, or Spacing cells. Arms start at 1 otherwise, since a greenfield project asking for this loop has nothing shipped yet to anchor a baseline arm against.
|
|
20
|
+
|
|
21
|
+
Render every URL reference before drafting, one call per reference since each targets its own file:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
canon capture <url> --selector body --out <dest>/refs/arm-<id>.png
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`--selector body` is the right choice here, unlike inside `draft-and-pick`'s own arms: the page belongs to someone else, so nothing on it is a wrapper this skill can name, and a full-page render is what a reference comparison needs. An operator-supplied image needs no render. Reference it directly from `<dest>/refs/` by copying it there under the same `arm-<id>` naming, so every arm resolves through one path shape regardless of source.
|
|
28
|
+
|
|
29
|
+
`canon capture <url>` reaches a target only once a release ships the URL-source capability. Report a refusal naming an unrecognized source as that gap rather than a broken reference, and name upgrading the installed `canon` as the repair.
|
|
30
|
+
|
|
31
|
+
## Step 2: author the candidate set as one page
|
|
32
|
+
|
|
33
|
+
Follow `${CLAUDE_SKILL_DIR}/../draft-and-pick/SKILL.md` Step 2, with one substitution: each arm is an `<img>` of the file `<dest>/refs/arm-<id>.png` produced in Step 1, not markup drafted from scratch. Wrap each in the shared class that skill's Step 2 fixes, label it with its id and its cost, and inline everything else the page needs, per that step's rules.
|
|
34
|
+
|
|
35
|
+
## Step 3: render, hand off, and take the pick
|
|
36
|
+
|
|
37
|
+
Follow `${CLAUDE_SKILL_DIR}/../draft-and-pick/SKILL.md` Steps 3 and 4 unchanged: render the combined page, hand over the address, and put the choice to the operator through the structured question surface. Take whatever reason the operator's answer already states, whether through the surface's own free-text escape or in the surrounding turn, as the reason Step 5 records. The surface takes the pick and the reason in one turn when the operator gives both together, rather than needing a second one.
|
|
38
|
+
|
|
39
|
+
## Step 4: loop, when the operator asks for a change
|
|
40
|
+
|
|
41
|
+
The arms here are fixed references rather than drafted markup, so nothing about a picked arm's own content can be revised. A loop here narrows the set instead: drop an arm the operator rules out, or add a new reference by returning to Step 1 for it alone. Return to Step 2 with the adjusted set and repeat Step 3. Stop when the operator says the pick is right, the same rule `draft-and-pick` Step 5 states, never when the set stops changing.
|
|
42
|
+
|
|
43
|
+
## Step 5: trace and write the handoff
|
|
44
|
+
|
|
45
|
+
1. Carry forward the reason Step 3's pick already stated, as written rather than paraphrased. Ask the operator to state, in their own words, why the picked reference won only when the pick arrived with no reason attached.
|
|
46
|
+
2. Read the picked arm's render at `<dest>/refs/arm-<id>.png` and trace its color, type, and spacing by looking, the same reading a person does against a screenshot. Name a role only where the reference actually shows it. Leave one out rather than guessing.
|
|
47
|
+
3. Write `.canon/review/evidence/<slug>/design-handoff.md`, resolved against the main worktree root rather than the linked worktree this run may be building in, since shared session scratch always resolves there. One field per line, grouped under the section names `${CLAUDE_SKILL_DIR}/../../standards/design.md` fixes, so `design-extract` reads it mechanically:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# Design handoff
|
|
51
|
+
|
|
52
|
+
Picked: arm-<id> (<label>)
|
|
53
|
+
Reason: <the operator's own sentence from item 1>
|
|
54
|
+
|
|
55
|
+
## Color
|
|
56
|
+
|
|
57
|
+
- <role>: <hex>
|
|
58
|
+
|
|
59
|
+
## Typography
|
|
60
|
+
|
|
61
|
+
- <role>: <family>, <size>
|
|
62
|
+
|
|
63
|
+
## Spacing
|
|
64
|
+
|
|
65
|
+
- base unit: <value>
|
|
66
|
+
|
|
67
|
+
## Borders
|
|
68
|
+
|
|
69
|
+
- <role>: <radius>, <width>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Write only the sections and roles the trace actually names. A role or a whole section with nothing traced is left out rather than written empty, since `design-extract` Step 2 treats an absent line as untraced and an empty one as a claim about the source.
|
|
73
|
+
|
|
74
|
+
4. Batch-capture the final round's arm files, the same directory-batch convention `draft-and-pick` Step 6 uses: `canon capture <dest>/arms --selector <wrapper-class> --out .canon/review/evidence/<slug>/`, naming Step 2's chosen class, so every arm considered, not only the winner, survives past the pick as a revert record.
|
|
75
|
+
5. Delete `<dest>` and everything in it, now that the handoff and the arms both sit at the durable path above. Report the path as still standing when the delete is refused, rather than closing on a report the tree contradicts.
|
|
76
|
+
|
|
77
|
+
## Response format
|
|
78
|
+
|
|
79
|
+
```plaintext
|
|
80
|
+
📝 Wrote .canon/review/evidence/<slug>/design-handoff.md
|
|
81
|
+
📝 Wrote .canon/review/evidence/<slug>/arm-<id>.png (and every other arm considered)
|
|
82
|
+
|
|
83
|
+
Picked arm-<id>: <label>. Run /canon:design-extract to fill canon/DESIGN.md from the trace.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## What this delegates
|
|
87
|
+
|
|
88
|
+
Cite these rather than restating them. A step reimplemented here rots against the skill that owns it.
|
|
89
|
+
|
|
90
|
+
- `draft-and-pick` owns the candidate page, the render and hand-off, the structured pick, and the archival capture convention, cited above
|
|
91
|
+
- `design-extract` reads the handoff file this skill writes and fills `canon/DESIGN.md` from it. This skill never writes that file itself.
|
|
92
|
+
- `canon capture` owns the render mechanics, including the URL source and its font refusal
|
|
@@ -113,7 +113,29 @@ Write each option as a `<label class="opt" data-k="<letter>">` holding a radio `
|
|
|
113
113
|
|
|
114
114
|
Then carry a teach-back block beside the quiz. A quiz is recognition and the pedagogy prefers production, so a lesson offering only a quiz tests the weak form. Ask for an explanation to a named audience, and carry a `<details>` listing what a complete explanation covers, closed by default, so a learner reading with no session in the room can grade themselves. The reference states both shapes in full.
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Compose the quiz and the teach-back block as one string. Below, that string is the block list's trailing `raw` entry, rather than markup written into the file by hand.
|
|
117
|
+
|
|
118
|
+
### Building the lesson body
|
|
119
|
+
|
|
120
|
+
Write the chrome as four empty marker pairs rather than composing it by hand: `<!-- canon:teach:style -->`/`<!-- /canon:teach:style -->` inside `<head>`, and `<!-- canon:teach:header -->`, `<!-- canon:teach:footnav -->`, and `<!-- canon:teach:scripts -->` each with its own close marker, in that order in `<body>`.
|
|
121
|
+
|
|
122
|
+
Build the authored `<h1>`, lede, body, and quiz as a JSON array of blocks rather than composing markup by hand, and render it through the verb rather than through a component import:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
echo '[
|
|
126
|
+
{"type":"heading","level":1,"text":"<title>"},
|
|
127
|
+
{"type":"paragraph","lede":true,"text":"<the dek>"},
|
|
128
|
+
{"type":"paragraph","text":"<a body paragraph>"},
|
|
129
|
+
{"type":"list","ordered":true,"items":["<step one>","<step two>"]},
|
|
130
|
+
{"type":"raw","html":"<the quiz and teach-back block composed above>"}
|
|
131
|
+
]' | canon teach render --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
A `heading`, a `paragraph` (`lede: true` for the dek), and a `list` cover the structural body. Reach for `raw` only where none of the three can carry the content, never as a shortcut around composing one, and give the quiz and teach-back block the array's trailing `raw` entry every time, since their fixed contract is not a components concern. Take the call's `html` field and write it between the header's close marker and the footnav's open marker, and nothing else anywhere in the file.
|
|
135
|
+
|
|
136
|
+
Report it rather than proceeding silently when the verb does not resolve, which is an installed CLI predating it, and never compose the lesson body by hand as a fallback. That is the state this section exists to end, and a target holds this skill body before it holds the verb, since a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes.
|
|
137
|
+
|
|
138
|
+
Then run:
|
|
117
139
|
|
|
118
140
|
```bash
|
|
119
141
|
canon teach nav <topic> --json
|
|
@@ -71,6 +71,17 @@ The quiz shape is a contract rather than a convention. `canon teach nav` splices
|
|
|
71
71
|
|
|
72
72
|
The stepper hides and shows and sets nothing else, so how a selected option looks, and whether a wrong one is marked as wrong, is the workspace stylesheet's to grow. Name the correct option in the feedback text for that reason: it is what a learner reads to find out whether they were right.
|
|
73
73
|
|
|
74
|
+
## The block list
|
|
75
|
+
|
|
76
|
+
`canon teach render` takes a JSON array of blocks and renders it through the same components the fixture lesson is generated from. Four types, and every structural body composes from them:
|
|
77
|
+
|
|
78
|
+
- `{"type":"heading","level":1|2,"text":"<text>"}`: an `<h1>` or `<h2>`.
|
|
79
|
+
- `{"type":"paragraph","text":"<text>","lede":true}`: a `<p>`, marked `lede` for the dek that opens the lesson.
|
|
80
|
+
- `{"type":"list","items":["<text>", ...],"ordered":true}`: a `<ul>` or, with `ordered`, an `<ol>`.
|
|
81
|
+
- `{"type":"raw","html":"<markup>"}`: the escape hatch, passed through unescaped.
|
|
82
|
+
|
|
83
|
+
The quiz and the teach-back block above are the one case `raw` is always needed for, since their fixed contract is not a components concern. Give them the array's trailing entry rather than reaching for `raw` anywhere the other three could carry the content instead.
|
|
84
|
+
|
|
74
85
|
## Teach back
|
|
75
86
|
|
|
76
87
|
A quiz is recognition and a teach-back is production, which is the form retrieval practice prefers. Carry both: the quiz places the learner against options someone could hold, and the teach-back is where the learner finds out what they cannot say without help.
|
package/docs/agents/commands.md
CHANGED
|
@@ -24,7 +24,7 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
24
24
|
| `canon docs [topic]` | Emit toolkit reference docs (`list`, or a topic by name) |
|
|
25
25
|
| `canon design render` | Render `canon/DESIGN.md` tokens to HTML and CSS |
|
|
26
26
|
| `canon design regen` | Rewrite this repository's `canon/DESIGN.md` and `src/design/base.css` from `src/design/tokens.ts` |
|
|
27
|
-
| `canon design board` | Generate a static page set indexing tokens, surfaces, wireframes, past candidates,
|
|
27
|
+
| `canon design board` | Generate a static page set indexing tokens, surfaces, wireframes, past candidates, components, and references against a caller-resolved `--root` (`--out`), defaulting to the main worktree |
|
|
28
28
|
| `canon design css` | Emit the design tokens and components as CSS on stdout (`--no-components` for properties alone) |
|
|
29
29
|
| `canon design install` | Install the base stylesheet into a project at `.claude/design/base.css` |
|
|
30
30
|
| `canon design sync` | Update a base stylesheet already installed under `.claude/design/` |
|
|
@@ -45,8 +45,10 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
45
45
|
| `canon teach open` | Open a workspace at the next ordinal with its mission, resources, and glossary files (`--json`) |
|
|
46
46
|
| `canon teach resource` | Record sources and leads in a workspace, repeating `--read` or `--lead` as `<title>=<url>` (`--json`) |
|
|
47
47
|
| `canon teach glossary` | Add terms to a workspace glossary alphabetically, repeating `--term <term>=<definition>` (`--json`) |
|
|
48
|
+
| `canon teach lesson` | Resolve the numbered path, shared stylesheet, mission success lines, and one quiz option order per question for the next lesson, writing nothing (`--json`) |
|
|
48
49
|
| `canon teach stylesheet` | Seed a workspace stylesheet from the design source, leaving an existing one alone without `--force` (`--json`) |
|
|
49
50
|
| `canon teach nav` | Rewrite the teach-root listing, a workspace's contents page, and each lesson's chrome from its four marker regions (`--json`) |
|
|
51
|
+
| `canon teach render` | Render a JSON block list (heading, paragraph, list, raw) from stdin to HTML through the shared components, refusing `bad-input` by block index (`--json`) |
|
|
50
52
|
| `canon records validate` | Report a session record or a standard against the standard governing it, per kind (`--json`) |
|
|
51
53
|
| `canon records migrate` | Rewrite the records a validate finding names a recoverable transform for (`--write`, `--json`) |
|
|
52
54
|
| `canon records ordinal` | Report or claim the next ordinal `intake` and `groundwork` share, creating the folder atomically (`--claim`, `--json`) |
|
|
@@ -56,7 +58,7 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
56
58
|
| `canon migrate rename` | Rewrite every unprotected `aitk` token to `canon` and move the paths that carry the name, reporting the plan without `--write` (`--scope`, `--json`) |
|
|
57
59
|
| `canon migrate skill-names` | Move the prefixed skill folders onto their two-word names and rewrite every citation, reporting the plan without `--write` (`--root`, `--json`) |
|
|
58
60
|
| `canon migrate records` | Move the gitignored session records to `.canon/` and repoint every tracked citation, reporting the plan without `--write` (`--root`, `--json`) |
|
|
59
|
-
| `canon migrate surface-roots` | Move the tracked surfaces (`context/`, `wireframes/`, the three loose documents, and the install stamp folder) from `.claude/` to `canon/` with `git mv` and repoint every tracked citation, reporting the plan without `--write` (`--root`, `--json`)
|
|
61
|
+
| `canon migrate surface-roots` | Move the tracked surfaces (`context/`, `decisions/`, `wireframes/`, the three loose documents, and the install stamp folder) from `.claude/` to `canon/` with `git mv` and repoint every tracked citation, reporting the plan without `--write` (`--root`, `--json`) |
|
|
60
62
|
| `canon migrate record-tree` | Repoint the old-root citations inside the records themselves, scoped to the live folders and reporting every line without `--write` (`--root`, `--json`) |
|
|
61
63
|
| `canon migrate rule-layout` | Move a target's installed rules from the flat `.claude/rules/<subdir>/` layout to `.claude/rules/canon/<subdir>/`, reporting the plan without `--write` (`--root`, `--json`) |
|
|
62
64
|
| `canon migrate scratch-evidence` | Move a folder under `.tmp/` that a durable record cites as evidence to `.canon/review/evidence/`, repointing every citation live or archived, reporting the plan without `--write` (`--root`, `--json`) |
|
|
@@ -65,6 +67,10 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
65
67
|
| `canon worktrees reclaim` | Remove every reclaimable worktree and the branch behind it, reporting without acting under `--dry-run` (`--json`) |
|
|
66
68
|
| `canon comments scan` | Measure comment density by language and comment kind, with a trend recomputed from git |
|
|
67
69
|
| `canon context audit` | Report required sections, length, cited paths, reference form, catalog tables, provenance, superseded-decision narration, and index drift |
|
|
70
|
+
| `canon context classify diff` | Classify the chunks a git range changed, each with its enclosing section, as keep, replace, history, or move (`--base`, `--doc-types`, `--json`) |
|
|
71
|
+
| `canon context classify sweep` | Classify every section of the five canonical doc types, split at H3, as keep, rewrite, or move (`--doc-types`, `--json`) |
|
|
72
|
+
| `canon context classifier show` | Report the resolved classifier backend and model and which source decided them (`--json`) |
|
|
73
|
+
| `canon context classifier set` | Write the project classifier setting to `canon/config/classifier.toml` (`--backend`, `--model`, `--json`) |
|
|
68
74
|
| `canon markdown audit` | Fail any markdown path on a banned character, word, or spelling, or a dead relative link, and report the structural checkpoints |
|
|
69
75
|
| `canon claude skills audit` | Report both skill corpora against the mechanical rules in `standards/skill.md` |
|
|
70
76
|
| `canon standards audit` | Report the corpus against the success-criterion gate `standards/standard.md` states, failing only on a standard new to the branch (`--json`, `--arrivals-only`) |
|
|
@@ -139,9 +145,9 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
|
|
|
139
145
|
| `slides` | `render`, `list` |
|
|
140
146
|
| `tasks` | `archive`, `validate` |
|
|
141
147
|
| `intake` | `list`, `answer` |
|
|
142
|
-
| `teach` | `list`, `open`, `resource`, `glossary`, `lesson`, `stylesheet`, `nav`
|
|
148
|
+
| `teach` | `list`, `open`, `resource`, `glossary`, `lesson`, `stylesheet`, `nav`, `render` |
|
|
143
149
|
| `comments` | `scan` |
|
|
144
|
-
| `context` | `audit`
|
|
150
|
+
| `context` | `audit`, `classify diff`, `classify sweep`, `classifier show`, `classifier set` |
|
|
145
151
|
| `markdown` | `audit` |
|
|
146
152
|
| `secrets` | `scan` |
|
|
147
153
|
| `deps` | `audit` |
|
|
@@ -167,7 +173,7 @@ Common patterns:
|
|
|
167
173
|
|
|
168
174
|
A record folder already present at the destination is a refusal rather than a merge, and a line carrying `canon-keep-record-root`, or the nearest non-blank line below it, keeps the old spelling for prose that dates a decision. The records themselves are never swept: everything under `.canon/` and every `.claude/` record folder is passed over and reported as a count on its own line, which is what keeps the run that follows the ignore collapse touching the same files as one before it. Running it twice rewrites nothing, which is the check that the exclusions, the markers, and that skip all fired.
|
|
169
175
|
|
|
170
|
-
`migrate surface-roots` moves the tracked surfaces from `.claude/` to `canon/`: `context/`, `wireframes/`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`, and the install stamp folder, respelled `canon/config/` since a project under `canon/` reserves the bare `canon` name for the CLI's own install. Every path is tracked, so each file moves with `git mv` and its history follows it, and every tracked citation of one is rewritten in the same run. `rules/`, `skills/`, `hooks/`, and `settings.json` stay where Claude Code reads them. It reports until `--write` is passed, and a destination already present under `canon/` refuses the whole plan rather than splitting a surface across both roots.
|
|
176
|
+
`migrate surface-roots` moves the tracked surfaces from `.claude/` to `canon/`: `context/`, `decisions/`, `wireframes/`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`, and the install stamp folder, respelled `canon/config/` since a project under `canon/` reserves the bare `canon` name for the CLI's own install. Every path is tracked, so each file moves with `git mv` and its history follows it, and every tracked citation of one is rewritten in the same run. `rules/`, `skills/`, `hooks/`, and `settings.json` stay where Claude Code reads them. It reports until `--write` is passed, and a destination already present under `canon/` refuses the whole plan rather than splitting a surface across both roots.
|
|
171
177
|
|
|
172
178
|
A line carrying `canon-keep-surface-root`, or the nearest non-blank line above it, keeps the old spelling. A rule's frontmatter `paths:` glob, a citation shaped like a path into another repository, and one inside a dated paragraph are reported by file and line and left alone. Running it twice rewrites nothing, which is the idempotence check. A project that never runs it keeps resolving each surface under `.claude/`, since every reader takes whichever root holds the entry.
|
|
173
179
|
|
|
@@ -29,7 +29,7 @@ canon context audit tooling/base/seeds --gate
|
|
|
29
29
|
|
|
30
30
|
## Folder scope
|
|
31
31
|
|
|
32
|
-
Scope defaults to `context`, `diagrams`, and `wireframes`, and a folder the project does not carry is skipped rather than reported. A domain that outgrew one file and split into `<domain>/` is audited as its own folder, so a split entry measures at the same grain as a flat one.
|
|
32
|
+
Scope defaults to `context`, `decisions`, `diagrams`, and `wireframes`, and a folder the project does not carry is skipped rather than reported. A domain that outgrew one file and split into `<domain>/` is audited as its own folder, so a split entry measures at the same grain as a flat one.
|
|
33
33
|
|
|
34
34
|
A name passed to `--folder` resolves under the record roots first, `.canon/` ahead of `.claude/`, and at the project root last, which is what puts `docs/` and any later corpus in reach of the same engine. The root base is reached only by a name the caller passes, so the default list still resolves under a record root alone and a project holding a root `wireframes/` is not audited against a standard it never adopted. `diagrams` is the one default name that is a session record and moves with them, which is why both record roots are in the list rather than one, and `docs/agents/records.md` states the read order every verb shares. The scope line prints the resolved path, so a project carrying both spellings reads which one was taken. The JSON record carries the base per folder as `folders[].base`.
|
|
35
35
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Doc classifier
|
|
3
|
+
description: Classifying canonical-doc content as keep, replace/rewrite, history, or move in diff and sweep mode, the classifier setting pair, the record shape, and the exit codes
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Doc classifier
|
|
7
|
+
|
|
8
|
+
`canon context classify` reads content from the five canonical doc types (`context/<domain>.md`, `ARCHITECTURE.md`, `wireframes/<surface>.md`, `DESIGN.md`, `REQUIREMENTS.md`) and reports whether each piece states the project as it stands or should be rewritten, narrated elsewhere, or moved to another surface. It reports and never gates: a finding is a judgment for a writer to act on, not a fact a push fails over. Wiring it into `docs-fold`, the merge gate, or `canon context audit` is separate work this verb does not do.
|
|
9
|
+
|
|
10
|
+
Two modes read different units. Diff mode reads the chunks a git range changed, each with the section it landed in, which is what a session checks right after an edit. Sweep mode reads every section of the five doc types, split at H3, which is what a cleanup pass or a periodic re-scan runs over a whole corpus.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
canon context classify diff
|
|
14
|
+
canon context classify diff --base origin/main --json
|
|
15
|
+
canon context classify diff --doc-types context,wireframes
|
|
16
|
+
canon context classify sweep
|
|
17
|
+
canon context classify sweep --doc-types design,requirements --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Option | Behavior |
|
|
21
|
+
| -------------------- | -------------------------------------------------------------- |
|
|
22
|
+
| `--base <ref>` | Diff mode only. Far side of the range, defaulting to the trunk |
|
|
23
|
+
| `--doc-types <list>` | Comma-separated canonical doc types (default: all five) |
|
|
24
|
+
| `--backend <name>` | Override the resolved model backend for this run |
|
|
25
|
+
| `--model <name>` | Override the resolved model name for this run |
|
|
26
|
+
| `--json` | Add a machine-readable record on stdout |
|
|
27
|
+
|
|
28
|
+
## Two layers
|
|
29
|
+
|
|
30
|
+
The regex layer always runs. It is free, needs nothing installed, and catches narration (a branch name, "closed on", "did not survive") and a source file path named inside a wireframe. It never answers REPLACE in diff mode, since telling a restated figure from a genuinely new one needs the section a hunk landed in, which the model layer reads and the regex layer does not.
|
|
31
|
+
|
|
32
|
+
The local Ollama layer runs only when configured, through `canon context classifier`. When it runs, its call is one chunk or section per request, never batched: the groundwork measurement behind this verb found that batching 16 hunks into one call returned KEEP for every one of them. Thinking is always off, since it was measured to catch nothing thinking-off missed while running roughly five times slower and, in sweep mode, losing three real flags by reasoning past them.
|
|
33
|
+
|
|
34
|
+
A finding carries both layers' readings when the model ran. The `verdict` field takes the model's reading when it ran and parsed, and falls back to the regex reading otherwise, since the model catches shapes the regex layer cannot reach structurally. `decidedBy` names which one won.
|
|
35
|
+
|
|
36
|
+
A configured-but-unreachable backend warns on stderr and falls back to the regex layer alone. The run still exits clean: the record's `modelLayer` field names why the model layer did not run (`off`, `skipped-no-model`, `skipped-unreachable`, or `ran`), so a clean regex-only report never reads as a clean model pass.
|
|
37
|
+
|
|
38
|
+
## The classifier setting
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
canon context classifier show
|
|
42
|
+
canon context classifier show --json
|
|
43
|
+
canon context classifier set --backend ollama --model qwen3.8:27b
|
|
44
|
+
canon context classifier set --backend off
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The backend and model resolve independently through the same four-tier precedence: a flag on the verb, then `CANON_CLASSIFIER_BACKEND` / `CANON_CLASSIFIER_MODEL`, then `canon/config/classifier.toml`, then off. `classifier show` reports the resolved backend and model and which tier decided them, without running a classification. There is no default model name: a model that resolves on one machine means nothing on another, so a backend configured with no model reports `no-model` from `show` and runs the regex layer alone from `classify`.
|
|
48
|
+
|
|
49
|
+
`classifier set` writes `canon/config/classifier.toml`, creating `canon/config/` when a project does not carry it yet:
|
|
50
|
+
|
|
51
|
+
```toml
|
|
52
|
+
[classifier]
|
|
53
|
+
backend = "ollama"
|
|
54
|
+
model = "qwen3.8:27b"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`--backend off` writes a file with no `model` line, which reads back as `off` at the same tier a missing file would default to, but with a source line saying the file decided it rather than the default.
|
|
58
|
+
|
|
59
|
+
## The record
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"decision": "ok",
|
|
64
|
+
"mode": "diff",
|
|
65
|
+
"backend": "ollama",
|
|
66
|
+
"model": "qwen3.8:27b",
|
|
67
|
+
"modelLayer": "ran",
|
|
68
|
+
"settingsSource": "file",
|
|
69
|
+
"findings": [
|
|
70
|
+
{
|
|
71
|
+
"file": "canon/context/retrieval.md",
|
|
72
|
+
"docType": "context",
|
|
73
|
+
"regex": {
|
|
74
|
+
"verdict": "KEEP",
|
|
75
|
+
"quote": "",
|
|
76
|
+
"reason": "no narration or wrong-surface pattern"
|
|
77
|
+
},
|
|
78
|
+
"model": {
|
|
79
|
+
"verdict": "REPLACE",
|
|
80
|
+
"quote": "the count moved",
|
|
81
|
+
"reason": "restates a figure the section already carries"
|
|
82
|
+
},
|
|
83
|
+
"verdict": "REPLACE",
|
|
84
|
+
"decidedBy": "model"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Sweep mode's findings carry a `heading` field alongside `file` and use the sweep vocabulary (KEEP, REWRITE, MOVE) rather than diff mode's four (KEEP, REPLACE, HISTORY, MOVE). REWRITE stands in for both REPLACE and HISTORY, matching the sweep prompt's own three-verdict vocabulary: a whole section already shows its own history in view, so there is no diff-mode split left to make.
|
|
91
|
+
|
|
92
|
+
## Exit codes
|
|
93
|
+
|
|
94
|
+
| Code | Meaning |
|
|
95
|
+
| ---- | ------------------------------------------------------------- |
|
|
96
|
+
| `0` | the run completed, whatever the findings say |
|
|
97
|
+
| `1` | refused: a bad range, an unreadable file, or a malformed flag |
|
|
98
|
+
|
|
99
|
+
Findings never set a failing exit code, in either mode. Diff mode refuses on a git range it cannot resolve. Both modes refuse on a file the run could not read.
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Design board
|
|
3
|
-
description: Generating a static index over
|
|
3
|
+
description: Generating a static index over a project's design surfaces, what each panel reads, and which two stay toolkit-checkout-only
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Design board
|
|
7
7
|
|
|
8
|
-
`canon design board [--out <path>]` generates a static page set indexing
|
|
8
|
+
`canon design board [--out <path>] [--root <path>]` generates a static page set indexing six design surfaces and reports the path a reader opens with `canon serve`. `--root` defaults to the main worktree the same way `canon teach`'s verbs resolve their own root. The surfaces panel's landing-page half and the whole components panel render only when that root is this toolkit's own checkout, since both read this repository's own build output rather than anything a target project produces. Running the installed CLI from inside a checkout of this project prints a mismatch warning when the caller's working directory disagrees with the root it resolved.
|
|
9
9
|
|
|
10
|
-
Each panel reads what is already on disk and reports its own missing source rather than failing the run, so an absent build
|
|
10
|
+
Each panel reads what is already on disk and reports its own missing source rather than failing the run, so an absent build, an empty corpus, or a toolkit-only gate renders an empty-state message instead of a broken frame.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
canon design board
|
|
14
14
|
canon serve .canon/review/board
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
| Option | Default | Behavior
|
|
18
|
-
| ------------------ | --------------------- |
|
|
19
|
-
| `-o, --out <path>` | `.canon/review/board` | Output directory
|
|
17
|
+
| Option | Default | Behavior |
|
|
18
|
+
| ------------------ | --------------------- | --------------------------------------------- |
|
|
19
|
+
| `-o, --out <path>` | `.canon/review/board` | Output directory |
|
|
20
|
+
| `--root <path>` | The main worktree | Project root the board reads its sources from |
|
|
20
21
|
|
|
21
22
|
## Panels
|
|
22
23
|
|
|
23
|
-
- **Tokens** renders `
|
|
24
|
-
- **Surfaces** iframes the built landing page from
|
|
25
|
-
- **Wireframes**
|
|
26
|
-
- **Past candidates** lists an arm capture image per folder under
|
|
27
|
-
- **Components** iframes the gallery built by `bun run web:gallery`, a second Astro config at `web/gallery.config.mjs` reading `web/gallery-src/` and writing `web/gallery-dist/`. That config's `srcDir` is never read by `web:build`'s own config, so the gallery never reaches the published `web/dist/`. The gallery page renders every component under `web/src/components/` except two whose props carry no defaults, which it names rather than filling with invented data. Reports a
|
|
24
|
+
- **Tokens** renders `DESIGN.md` through the same renderer `canon design render` uses, rather than a second one, reading `<root>/canon/DESIGN.md` or `<root>/.claude/DESIGN.md` for a target that has not run `canon migrate surface-roots`.
|
|
25
|
+
- **Surfaces** iframes the built landing page from `<root>/web/dist/` and a teach workspace from `<root>/.canon/teach/`, copying each whole into the board's own tree. The landing-page half reports a toolkit-only notice outside this toolkit's own checkout, and either half reports its own missing build or absent workspace rather than rendering a broken frame.
|
|
26
|
+
- **Wireframes** reads every `**/*.md` under `<root>/canon/wireframes/` or `<root>/.claude/wireframes/`, excluding `index.md` at any depth, and renders each file as-is inside a `<pre>`, labeled from its own `description` frontmatter field. Reports the whole panel empty rather than per file when the directory is absent or holds nothing to render.
|
|
27
|
+
- **Past candidates** lists an arm capture image per folder under `<root>/.canon/review/evidence/`, and states the corpus carries none rather than rendering an empty grid.
|
|
28
|
+
- **Components** iframes the gallery built by `bun run web:gallery`, a second Astro config at `web/gallery.config.mjs` reading `web/gallery-src/` and writing `web/gallery-dist/`. That config's `srcDir` is never read by `web:build`'s own config, so the gallery never reaches the published `web/dist/`. The gallery page renders every component under `web/src/components/` except two whose props carry no defaults, which it names rather than filling with invented data. Reports a toolkit-only notice outside this toolkit's own checkout, and a missing gallery build otherwise.
|
|
29
|
+
- **References** lists whatever image an operator has dropped flat under `<root>/.canon/review/references/`, with no fetching and no second token source: a reference is an image, nothing more. Reports the folder as absent or as present but carrying no image rather than rendering an empty grid.
|
|
28
30
|
|
|
29
31
|
## What it does not do
|
|
30
32
|
|
package/docs/agents/index.md
CHANGED
|
@@ -15,9 +15,10 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
15
15
|
- [Comments](comments.md): Comment density by language and kind, the two structural exclusions, and how the degradation sweep finds its vocabulary
|
|
16
16
|
- [Context audit checks](context-audit-checks.md): What each non-gating check reports, the unit each checkpoint is measured in, the architecture record's length gate and claim coverage, which folders each check reaches, and what moved to the attribute tier
|
|
17
17
|
- [Context audit](context-audit.md): Running the audit, its flags and folder scope, the exit codes, the citation gate, and the widened gate the seed stage runs
|
|
18
|
+
- [Doc classifier](context-classify.md): Classifying canonical-doc content as keep, replace/rewrite, history, or move in diff and sweep mode, the classifier setting pair, the record shape, and the exit codes
|
|
18
19
|
- [Self-stated counts](counts.md): Reading a sentence that asserts a closed catalog's size, how a match is decided, the plausibility filter that keeps a generic word from matching a subset, and why the sweep reports rather than gates
|
|
19
20
|
- [Demo](demo.md): Compiling a screencast draft into a runnable plan, driving a served application to a recording and a still, reading numbered frames back out of a recording, the pointer the recording paints, and what each refusal reports
|
|
20
|
-
- [Design board](design-board.md): Generating a static index over
|
|
21
|
+
- [Design board](design-board.md): Generating a static index over a project's design surfaces, what each panel reads, and which two stay toolkit-checkout-only
|
|
21
22
|
- [Docs](docs.md): How canon docs resolves the toolkit's own reference surface from an install root, and how a split domain is named
|
|
22
23
|
- [Driver](driver.md): Walking a page through named interactions, the probe catalog and the false finding each one carries, why viewport heights are never defaulted, and what each refusal reports
|
|
23
24
|
- [Merge gate](gate.md): Running the gate this repository verifies a branch with, what the stage table holds and what stays a script, how the changed set scopes three stages, and why a stage that cannot read its input reports rather than passing
|
package/docs/agents/teach.md
CHANGED
|
@@ -137,6 +137,22 @@ Each `quiz` entry carries `order`, the authored option indices in presentation o
|
|
|
137
137
|
|
|
138
138
|
The order is drawn here rather than instructed, and that is the point of the verb. An author told to vary the position still varies it by judgment, and the judgment settles on the first slot, which is the defect this design departs from. The draw is uniform over the options, so the position carries no information about which answer is correct.
|
|
139
139
|
|
|
140
|
+
## Render
|
|
141
|
+
|
|
142
|
+
`canon teach render` renders a lesson body's structural blocks to HTML, through the same components the fixture lesson under `examples/teach/00-fixture/` is generated from. It takes no topic and no `--root`, since the verb is a stateless transform reading nothing off a workspace on disk.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
echo '[{"type":"heading","level":1,"text":"Compass bearings"}]' | canon teach render --json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| Option | Behavior |
|
|
149
|
+
| -------- | ---------------------------------------- |
|
|
150
|
+
| `--json` | Emit a machine-readable record on stdout |
|
|
151
|
+
|
|
152
|
+
It reads a JSON array of blocks from stdin, each a `heading`, `paragraph`, `list`, or `raw` block, and reports `{ ok: true, html }` on `--json` or the bare rendered HTML on stdout otherwise. Content none of the three components can express takes a `raw` block, carrying its own HTML verbatim and unescaped, which is the shape the quiz and the teach-back block travel in.
|
|
153
|
+
|
|
154
|
+
It refuses `bad-input` on empty stdin, on malformed JSON, on stdin that does not parse to an array, and on a block carrying an unrecognized `type` or a field of the wrong shape for its type, naming the block's index in the message.
|
|
155
|
+
|
|
140
156
|
## Nav
|
|
141
157
|
|
|
142
158
|
`canon teach nav` rewrites the teach-root listing, a workspace's contents page, and each of its lessons' chrome, from what the workspace holds on disk.
|
package/docs/target-projects.md
CHANGED
|
@@ -196,6 +196,21 @@ Run the second line once per stack the project holds, since the two hooks above
|
|
|
196
196
|
|
|
197
197
|
The order carries the reason. A sync replaces each toolkit-owned copy with one already carrying the new names, and the sweep afterwards reaches the prose the project wrote itself. Sweeping first rewrites those installed files in place, which moves them off the hash the install recorded, so the next sync reads them as edited by the project and leaves them alone.
|
|
198
198
|
|
|
199
|
+
### Move the surfaces off `.claude/`, once
|
|
200
|
+
|
|
201
|
+
Tracked surfaces moved out of `.claude/` and into a root of their own. `context/`, `decisions/`, `wireframes/`, the three loose documents (`ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`), and the install stamp folder, respelled `canon/config/`, now live under `canon/`, and `rules/`, `skills/`, `hooks/`, and `settings.json` stay put since Claude Code reads those by path.
|
|
202
|
+
|
|
203
|
+
Run `canon upgrade` first if you have not, then run this from inside the project:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
canon migrate surface-roots --json
|
|
207
|
+
canon migrate surface-roots --write --json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The first line reports the plan and the second applies it, moving each surface with `git mv` so its history follows and repointing every tracked citation of one in the same run. See `canon docs agents` for the full file list rather than reading it here.
|
|
211
|
+
|
|
212
|
+
Neither `canon sync --check` nor any other command notices a surface still sitting at `.claude/`, so running this is on you rather than on a prompt from the toolkit.
|
|
213
|
+
|
|
199
214
|
### Check first
|
|
200
215
|
|
|
201
216
|
`canon sync --check <path>` reports what has drifted without writing anything. It splits each difference by cause, which is the question that decides what to do next.
|
|
@@ -20,7 +20,8 @@ canon/
|
|
|
20
20
|
├── ARCHITECTURE.md ← technical design decisions
|
|
21
21
|
├── DESIGN.md ← visual intent and token decisions (UI projects)
|
|
22
22
|
├── wireframes/ ← ASCII wireframes: layout, UI copy, and interaction rules (UI projects)
|
|
23
|
-
|
|
23
|
+
├── context/ ← per-domain narrative loaded on demand via index.md
|
|
24
|
+
└── decisions/ ← decision history a canonical doc points at, never loaded eagerly
|
|
24
25
|
|
|
25
26
|
.claude/
|
|
26
27
|
└── rules/ ← path-scoped governance rules, written by canon gov install
|
|
@@ -33,7 +34,7 @@ canon/
|
|
|
33
34
|
└── tmp/ ← deletable scratch, safe to remove without loss
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. `canon migrate records` moves one project across and repoints what cites it, and `canon migrate record-tree` follows it to reach the citations inside the records themselves, which the first verb passes over because it enumerates through git. A project scaffolded before the surface move keeps its context, wireframes, and loose documents under `.claude/` the same way, and `canon migrate surface-roots` moves those to `canon/` with the history following each file.
|
|
37
|
+
A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. `canon migrate records` moves one project across and repoints what cites it, and `canon migrate record-tree` follows it to reach the citations inside the records themselves, which the first verb passes over because it enumerates through git. A project scaffolded before the surface move keeps its context, decisions, wireframes, and loose documents under `.claude/` the same way, and `canon migrate surface-roots` moves those to `canon/` with the history following each file.
|
|
37
38
|
|
|
38
39
|
Three tiers of context load with different cost: always-loaded (root `CLAUDE.md`, `canon/REQUIREMENTS.md`, `canon/ARCHITECTURE.md`), path-scoped lazy (`.claude/rules/<scope>.md` with `paths:` glob), and on-demand lookup (`canon/context/<domain>.md`, or `canon/context/<domain>/` once a domain outgrows one file, discovered via `canon/context/index.md`). See [the context model](../../canon/context/context-model.md) for the full picture.
|
|
39
40
|
|
|
@@ -204,6 +205,7 @@ This section is the corpus the coverage claim is measured against: every name `c
|
|
|
204
205
|
| `canon:setup-plugins` | On a new machine, to install the community and official plugins user-scoped |
|
|
205
206
|
| `canon:setup-verify` | After the agent generates configs, to run the installed scripts and report pass or fail |
|
|
206
207
|
| `canon:setup-smoke` | After `setup-verify` passes, to check the dev and preview servers, end-to-end tests, and the screenshot harness |
|
|
208
|
+
| `canon:sketch-design` | Before `design-extract`'s greenfield path, to trace a design direction from reference images or URLs |
|
|
207
209
|
| `canon:design-extract` | Before the first UI feature, to draft `canon/DESIGN.md` |
|
|
208
210
|
| `canon:draft-diagram` | Once the architecture is written, to draft per-kind entries under `.canon/diagrams/` |
|
|
209
211
|
| `canon:repo-metadata` | When the GitHub About text, homepage, or topics may have drifted, to reconcile them against the README |
|
|
@@ -35,6 +35,7 @@ A cell no source anchors ends in `? verify`, and the preview shows that marker b
|
|
|
35
35
|
|
|
36
36
|
### Skills
|
|
37
37
|
|
|
38
|
+
- `canon:sketch-design` to trace a design direction from reference images or URLs, before `design-extract`'s greenfield path proposes from a personality paragraph alone
|
|
38
39
|
- `canon:design-extract` to draft `canon/DESIGN.md`, from existing project signals or from requirements alone on day one
|
|
39
40
|
- `canon:ui-test` for e2e test generation after UI changes
|
|
40
41
|
- `canon:ux-audit` for UX gap detection on existing surfaces
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Route canon/decisions/ edits to the decisions standard for record shape and lifecycle
|
|
3
|
+
paths:
|
|
4
|
+
- 'canon/decisions/**'
|
|
5
|
+
- '.claude/decisions/**'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Decisions standards
|
|
9
|
+
|
|
10
|
+
## Authority
|
|
11
|
+
|
|
12
|
+
- Follow the decisions standard for folder layout, the ordinal filename, frontmatter, record sections, and the append-only lifecycle. It is the single source. Read it with `canon standards decisions`.
|