@erclx/canon 4.82.0 → 4.84.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 (41) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/docs-fold/REQUIREMENT.md +13 -0
  3. package/claude/skills/docs-fold/SKILL.md +20 -0
  4. package/claude/skills/docs-fold/references/classify.md +78 -0
  5. package/claude/skills/draft-and-pick/SKILL.md +1 -1
  6. package/claude/skills/draft-slides/SKILL.md +1 -1
  7. package/claude/skills/draft-wireframes/REQUIREMENT.md +1 -1
  8. package/claude/skills/draft-wireframes/SKILL.md +7 -4
  9. package/claude/skills/ux-walkthrough/REQUIREMENT.md +53 -0
  10. package/claude/skills/ux-walkthrough/SKILL.md +50 -0
  11. package/claude/skills/ux-walkthrough/references/builds.md +15 -0
  12. package/claude/skills/ux-walkthrough/references/candidate-pages.md +26 -0
  13. package/claude/skills/ux-walkthrough/references/measuring.md +22 -0
  14. package/claude/skills/ux-walkthrough/references/record.md +36 -0
  15. package/claude/skills/ux-walkthrough/references/relay.md +25 -0
  16. package/claude/skills/youtube-transcripts/SKILL.md +1 -1
  17. package/docs/agents/commands.md +1 -1
  18. package/docs/agents/context-audit-checks.md +22 -2
  19. package/docs/agents/context-audit.md +12 -2
  20. package/docs/agents/context-classify.md +1 -1
  21. package/docs/workflow/ai-workflow.md +2 -1
  22. package/docs/workflow/visual-design-workflow.md +2 -1
  23. package/governance/rules/claude/520-wireframes.md +1 -1
  24. package/package.json +1 -1
  25. package/src/claude/cases/workflow.ts +5 -0
  26. package/src/commands/context.ts +71 -2
  27. package/src/context/architecture.ts +73 -0
  28. package/src/context/audit.ts +18 -2
  29. package/src/context/gate.ts +44 -6
  30. package/src/context/wireframe-states.ts +238 -0
  31. package/src/record-root.ts +4 -2
  32. package/src/records/backup.ts +4 -3
  33. package/standards/architecture.md +11 -1
  34. package/standards/context.md +4 -1
  35. package/standards/design.md +6 -0
  36. package/standards/requirements.md +2 -1
  37. package/standards/skill.md +1 -1
  38. package/standards/wireframes.md +45 -29
  39. package/tooling/claude/reference.md +1 -1
  40. package/tooling/claude/seeds/CLAUDE.md +1 -1
  41. package/tooling/claude/seeds/canon/wireframes/index.md +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "4.82.0",
4
+ "version": "4.84.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -17,6 +17,8 @@ The receipt half of that sweep was missing entirely. A review receipt was delete
17
17
 
18
18
  The trigger side carries a gap of its own. "Sync the docs" names either corpus to the person saying it, so a description leaving its corpus to the opening clause alone competes with its public-facing sibling on nothing the routing field states, and the planning surface the request was about goes untouched.
19
19
 
20
+ This skill writes canonical docs at the end of a long build and never reviews what it wrote. An appended figure or a branch-narrated re-measurement lands unchecked the same way a session's own edits do, so what the fold produces carries the exact defect the standards it cites already ban.
21
+
20
22
  ## Must
21
23
 
22
24
  - Name the `.claude/` corpus in a trigger phrase rather than in the opening clause alone, so a bare request to sync the docs separates this skill from `docs-sync` on something both descriptions state
@@ -34,6 +36,10 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
34
36
  - Leave the current branch's review receipt alone, since the chain that wrote it cites it in its own closing line and this skill cannot read whether that citation is still live
35
37
  - Land each block of a promotion handoff at the destination its heading names, then delete the file so a later run does not fold it twice
36
38
  - Take a promotion destination as already decided, since the operator confirmed it where the page was produced
39
+ - Classify the fold's whole diff baseline through `canon context classify diff`, calling the verb rather than reimplementing its pattern or its prompt in the skill body, since an earlier commit on the branch carries a doc edit the fold is equally responsible for
40
+ - Apply a `REPLACE` or `HISTORY` finding, and a regex-decided `MOVE` finding, against the quote it names, report a model-decided `MOVE` finding naming the surface it belongs on rather than cutting it, or keep a finding with a one-line reason, rather than leaving a finding unanswered
41
+ - Rewrite a restated or superseded statement in place rather than appending the replacement beside it, on every canonical doc type this skill writes
42
+ - Report a refusal or a missing `context classify` subcommand as one line and continue the fold either way, since a check that cannot run is not a reason to leave the fold's own output unshipped
37
43
 
38
44
  ## Must not
39
45
 
@@ -45,6 +51,13 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
45
51
  - Overwrite a file a promotion block routes to. A destination that already holds a page is a merge for a person, and folding over it discards work this skill never read.
46
52
  - Write an anchor onto a decision the run did not amend, or refresh one without re-reading the number. A date from a pass that measured nothing is the false confidence the marker exists to prevent.
47
53
  - Anchor an entry written before the rule, which dates it by blame rather than by a read
54
+ - Pick or configure a classifier backend. The project setting decides it, and this skill reports the resolved `modelLayer` as returned.
55
+ - Stop the fold on a classify finding, a refusal, or a missing subcommand. All three report and continue.
56
+ - Apply a finding against a quote found more than once or not found at all. Report that it could not be located instead of guessing.
57
+ - Re-run the classifier after applying a finding, which loops it over its own edit
58
+ - Cut a model-decided `MOVE` finding. The model's own prompt defines `MOVE` more broadly than the regex layer does, for correct content sitting on the wrong surface rather than a deletion candidate, so cutting one can discard content that belongs elsewhere rather than removing detail that never belonged at all.
59
+ - Paste a regex-decided `MOVE` finding's content into another canonical doc after cutting it. It never belonged on the wireframe surface at all, so cutting is the whole fix, not a relocation.
60
+ - Scope Step 10 to the files Steps 3 and 7 wrote this run. An earlier commit on the branch carries a doc edit the fold is equally responsible for, and the verb's own extraction already answers whether anything in range qualifies.
48
61
 
49
62
  ## Guards
50
63
 
@@ -108,6 +108,7 @@ Read `ok` and `reason` out of that record rather than the exit. An operator's sh
108
108
 
109
109
  - Update only the sections affected by session decisions.
110
110
  - Do not rewrite sections unrelated to what changed.
111
+ - Rewrite a restated or superseded statement in place rather than appending the replacement beside it. State the fact that stands and keep the earlier reasoning only where it is the alternative that lost, per `${CLAUDE_SKILL_DIR}/../../standards/context.md` and `${CLAUDE_SKILL_DIR}/../../standards/architecture.md`.
111
112
  - Follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` and the `write-human` skill for all edits.
112
113
  - Close a decision entry in `canon/ARCHITECTURE.md` with its verification anchor whenever this run writes that entry or amends its reasoning and that reasoning cites a measured number. Re-read the number against the tree first, since the marker records the read rather than the edit. `${CLAUDE_SKILL_DIR}/../../standards/architecture.md` fixes the sentence.
113
114
  - Leave every decision entry this run did not write alone, anchored or not. The rule is scoped forward, so an entry written before it is dated by blame rather than by a read. Step 5 reports a stale anchor and no step writes one on an entry it did not amend.
@@ -160,6 +161,7 @@ Reuse the diff from the baseline above, names and content both. For each domain
160
161
 
161
162
  - Map the entry's section headings, whether they sit in one flat file or spread across a nested domain's sibling files, to the changed files. An entry is relevant when its prose references files, modules, or decisions touched by the diff.
162
163
  - For each relevant entry, rewrite only the sections affected by the diff. Same pattern as `docs-sync`. Do not touch unrelated sections. Never rewrite a split domain's own `index.md` directly, since a regen overwrites it the same way it overwrites the top-level catalog. Rewrite the sibling file the affected section actually lives in instead.
164
+ - Rewrite a restated or superseded statement in place rather than appending beside it, the same rule Step 3 applies to the other four canonical doc types.
163
165
  - Write a reference to another entry as the path that entry sits at, rather than as its bare filename. `${CLAUDE_SKILL_DIR}/../../standards/context.md` states the form, and a bare name strands the reference once a domain splits into subfolders.
164
166
 
165
167
  ### When the diff removes a capability
@@ -245,12 +247,30 @@ Output one line per file swept:
245
247
 
246
248
  If nothing qualifies, skip this step silently.
247
249
 
250
+ ## Step 10: classify the fold's diff baseline
251
+
252
+ Skip this step silently only when the Diff baseline section could not resolve a base ref at all, reporting `⚠ No diff to scope against. Skipped the classify check.` The verb needs a resolvable ref to run against, which is the one condition it cannot answer for itself.
253
+
254
+ Otherwise resolve `<base>` the way the Diff baseline section already does for Steps 2, 4, 5, and 7, and reuse it rather than resolving a second time. Run the check over the fold's whole baseline rather than scoping it to what Steps 3 and 7 wrote this run: earlier commits on the branch carry doc edits the fold is equally responsible for, and the verb's own extraction already scopes to canonical doc types and reports nothing when the range carries none.
255
+
256
+ The invocation is:
257
+
258
+ ```bash
259
+ canon context classify diff --base <base> --json
260
+ ```
261
+
262
+ Never substitute a different verb for it, such as `canon autoship classify` (a different check, over a different scope) or `canon docs <name>` (a documentation lookup, not a classification). Read `${CLAUDE_SKILL_DIR}/references/classify.md` for the record fields, applying a finding, the one-line keep reason, the unreachable and missing-subcommand lines, and the report shape. `${CLAUDE_SKILL_DIR}` names this skill's own directory, resolved once when the skill loaded, several steps before this one. If Step 10's memory of that path is uncertain, read the reference by that resolved path rather than guessing a `.claude/skills/docs-fold/references/classify.md` path from the toolkit's install-time layout, which is a different root than the one this skill's own files live under. The invocation above runs either way, whether or not that reference resolves.
263
+
264
+ Findings never stop the fold. A refusal or a missing subcommand on an older installed binary reports one line, per that reference, and the fold continues either way.
265
+
248
266
  ## After completion
249
267
 
250
268
  Output one line per file updated:
251
269
 
252
270
  `✅ Updated: .claude/<filename>`
253
271
 
272
+ Step 10 adds its own lines when it applied or reported a finding, in the exact shape `${CLAUDE_SKILL_DIR}/references/classify.md` gives them under its own Report section. Do not shorten or paraphrase those lines here or in the reply, since the quote and the reason are what a reader checks the finding against.
273
+
254
274
  If no files were updated and nothing was swept, output:
255
275
 
256
276
  `✅ No changes needed.`
@@ -0,0 +1,78 @@
1
+ ---
2
+ title: Classify the fold's diff baseline
3
+ description: The classify diff invocation, the record fields to read, applying a finding, the one-line keep reason, the unreachable and missing-subcommand lines, and the report shape
4
+ ---
5
+
6
+ # Classify the fold's diff baseline
7
+
8
+ Mechanics for Step 10 of `docs-fold`. The body owns the skip condition and the shared baseline, and this file owns the invocation, what the record carries, and what applying a finding does.
9
+
10
+ ## Invocation
11
+
12
+ Call the verb rather than reimplementing its pattern or prompt in this skill:
13
+
14
+ ```bash
15
+ canon context classify diff --base <base> --json
16
+ ```
17
+
18
+ Reuse the base the Diff baseline section already resolved. Never pick or configure a backend here. The project setting decides it, and this step reports `modelLayer` as the record returns it.
19
+
20
+ ## Reading the record
21
+
22
+ Branch on the record's `decision` field, never on the exit code, which a shell function wrapping `canon` can flatten to zero.
23
+
24
+ - `decision: 'refused'`: a bad range or a file the verb could not read. Report the record's `message` and continue. See "When the verb is absent or refused" below.
25
+ - `decision: 'ok'`: the record carries `modelLayer` (`'off'`, `'ran'`, `'skipped-no-model'`, or `'skipped-unreachable'`) and `findings`.
26
+
27
+ Each finding carries `file`, a `verdict` of `KEEP`, `REPLACE`, `HISTORY`, or `MOVE`, and `decidedBy` (`'regex'` or `'model'`) naming which layer's reading won. Take the `quote` and `reason` from whichever of the finding's `regex` or `model` fields `decidedBy` names. Skip every `KEEP` finding: nothing decided against that text.
28
+
29
+ ## Scope
30
+
31
+ Answer every non-`KEEP` finding the verb returns, not only the files Step 3 or Step 7 wrote this run. A branch carrying earlier commits from a prior session has doc edits the fold is equally responsible for, and the verb's own extraction already scopes to canonical doc types and reports nothing when the range carries none, so there is no narrower check to add here.
32
+
33
+ ## Applying a finding
34
+
35
+ Locate the finding by its `quote` in the file's current content. The quote is often a narrow fragment rather than the whole clause it sits in, since the regex layer's own match is a short pattern hit, so the edit below targets the sentence or bullet the quote sits in rather than the literal substring alone.
36
+
37
+ - **Found exactly once.** Apply the verdict:
38
+ - `REPLACE`: rewrite the sentence or bullet carrying the quote in place with the fact that now stands, per Step 3 and Step 7's rewrite-in-place rule. State what is current and drop what the quote restated, in the one edit.
39
+ - `HISTORY`: rewrite the sentence or bullet carrying the quote to drop the narration and keep any current fact the same clause states. The quote narrates how the fact arrived rather than stating the fact, which a canonical doc excludes regardless of what wrote it, and a literal cut of the fragment alone would leave the rest of the clause grammatically stranded.
40
+ - `MOVE`, regex-decided (`decidedBy: 'regex'`): cut the sentence or bullet carrying the quote and stop there. Do not also paste it into another canonical doc, however close a match the current diff makes one look. The regex layer only ever returns `MOVE` inside `canon/wireframes/`, on prose naming a source-file path, which is implementation detail a wireframe surface does not carry, so a regex-decided `MOVE` is always safe to remove outright, and removing it is the whole fix.
41
+ - `MOVE`, model-decided (`decidedBy: 'model'`): do not cut. The model's own prompt defines `MOVE` more broadly, for correct content sitting on the wrong surface, such as domain mechanism written into `canon/ARCHITECTURE.md` that belongs in a context entry. Cutting would delete content a fold with no model configured would never have flagged at all. Report the finding instead, naming the surface the `reason` names as where the content belongs, and leave the file unedited.
42
+ - **Found more than once, or not found at all.** Report that the finding could not be located rather than guessing which occurrence or rewriting nothing silently. A model verdict paraphrasing the quote it read is the ordinary way this happens.
43
+
44
+ Run the classifier once per fold. Do not re-run it after applying a finding to check the edit, since a second pass over what this step wrote is the loop the verb's own reference already warns against.
45
+
46
+ ## Keeping a finding
47
+
48
+ Keep a non-`KEEP` finding without applying it only when the quote is itself the alternative a nearby decision states and lost, or the file already carries the current fact elsewhere. State the reason in one line in the report. A keep costs one line, where an incorrect apply costs a rewrite of prose nobody asked to change.
49
+
50
+ ## When the verb is absent or refused
51
+
52
+ The verb ships with the CLI and this skill ships with the plugin, so a target holding an older installed binary carries no `context classify` subcommand. Report:
53
+
54
+ `⚠ Classify: canon context classify not available on the installed binary. Skipped.`
55
+
56
+ and continue. Never read a missing subcommand as a clean pass, which would report a run that never checked anything as one that found nothing.
57
+
58
+ A refused range reports the same way, naming the verb's own message:
59
+
60
+ `⚠ Classify: <message>`
61
+
62
+ Neither case stops the fold. This step checks what the fold wrote, and a check that cannot run is not a reason to leave the fold's own output unshipped.
63
+
64
+ ## Report
65
+
66
+ One line naming what ran:
67
+
68
+ `✅ Classify: <n> findings, regex ran, model <modelLayer>`
69
+
70
+ Then one line per non-`KEEP` finding:
71
+
72
+ - `✏ Rewrote: <file>, "<quote>" (<reason>)`
73
+ - `✂ Cut: <file>, "<quote>" (<reason>)`
74
+ - `➡ Move needed: <file>, "<quote>" (<reason>)`, for a model-decided `MOVE` this step reported rather than cut
75
+ - `⏭ Kept: <file>, "<quote>", <reason for keeping>`
76
+ - `⚠ Not located: <file>, "<quote>" not found or found more than once`
77
+
78
+ When every finding reads `KEEP`, output `✅ Classify: <n> findings, all KEEP` and nothing further.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: draft-and-pick
3
- description: Drafts several candidates for a decision judged by looking, renders them side by side on one page, hands the operator the addresses, takes the pick through the structured question surface, and loops on the pick until they stop. Use when asked to "draft some options", "show me a few versions", "try a few variations", "mock up alternatives", "give me candidates for X", or when a choice is taste rather than correctness. Do NOT use when the request already names the answer and asks for it to be built, which is `plan-feature`. Do NOT use to read source for roughness, which is `ux-audit`, to measure what a running interface costs to paint, which is `ux-measure`, to write tests for a change already made, which is `ui-test`, or to script a recording, which is `draft-screencast`.
3
+ description: Drafts several candidates for a decision judged by looking, renders them side by side on one page, hands the operator the addresses, takes the pick through the structured question surface, and loops on the pick until they stop. Use when asked to "draft some options", "show me a few versions", "try a few variations", "mock up alternatives", "give me candidates for X", or when a choice is taste rather than correctness. Do NOT use when the request already names the answer and asks for it to be built, which is `plan-feature`. Do NOT use to read source for roughness, which is `ux-audit`, to measure what a running interface costs to paint, which is `ux-measure`, to write tests for a change already made, which is `ui-test`, to script a recording, which is `draft-screencast`, or to inspect a running app across many findings, which is `ux-walkthrough`.
4
4
  ---
5
5
 
6
6
  # Draft and pick
@@ -50,7 +50,7 @@ Pass `--variant light` or `--variant dark` to override the source variant for a
50
50
  Run this once after the first render, then stop.
51
51
 
52
52
  1. Convert the deck to images: `soffice --headless --convert-to pdf <deck>.pptx` then `pdftoppm -r 90 -png <deck>.pdf slide`. If `soffice` or `pdftoppm` is missing, skip the image pass and say so. Do not fail the render.
53
- 2. Inspect the images with fresh eyes. Spawn a subagent to check every slide for overlap, overflow, low contrast, and empty regions.
53
+ 2. Open and inspect every rendered image in this session, checking each slide for overlap, overflow, low contrast, and empty regions.
54
54
  3. Fix the reported issues in `SLIDES.md` once, re-render, and stop. Do not loop indefinitely on aesthetics.
55
55
 
56
56
  ## Response
@@ -11,7 +11,7 @@ Without this skill, a session drafting a wireframe for a surface with no file ye
11
11
 
12
12
  ## Must
13
13
 
14
- - Read `standards/wireframes.md` before drafting, since the frontmatter contract, the layout and variant rules, and the Transcription-wireframes branch are what make the file arguable against a sibling
14
+ - Read `standards/wireframes.md` before drafting, since the frontmatter contract, the regions list, the states table, the exclusions section, and the Transcription-wireframes branch are what make the file arguable against a sibling
15
15
  - Walk the whole `canon/wireframes/` tree, including a grouped surface's own subfolder, before drafting, since a top-level-only check misses a nested match
16
16
  - Detect an existing higher tier from `canon/DESIGN.md` and the wireframes tree and report it, never build a companion render for it, since no shipped mechanism produces one
17
17
  - Draft in transcription mode, citing the real source, when the surface names an already-built component. Draft in role-intent mode otherwise.
@@ -11,7 +11,7 @@ A project the surface move has not reached keeps its wireframes folder under `.c
11
11
 
12
12
  Read these files in parallel:
13
13
 
14
- - `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md`: the three questions a wireframe must answer, its frontmatter, layout and variant rules, the Transcription-wireframes branch, and what moves to a context entry instead
14
+ - `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md`: the four questions a wireframe must answer, its frontmatter, the regions list and states table, the exclusions section, the Transcription-wireframes branch, and what moves to a context entry instead
15
15
  - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for the prose around the fences
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for the prose around the fences
17
17
 
@@ -25,15 +25,18 @@ This skill stays fully independent of `docs-fold`'s wireframe coverage sweep, wh
25
25
  ## Tier detection
26
26
 
27
27
  - Read `canon/DESIGN.md` and every existing `canon/wireframes/` file for a tier signal: a Stitch, Excalidraw, or Figma reference, or a marker naming one of them.
28
- - State the detected tier at the confirm step. Always draft the tier-0 ASCII file regardless of what is detected, since that is the only shape this skill or any other shipped mechanism produces. Report a higher tier rather than attempting a companion render for it.
28
+ - State the detected tier at the confirm step. Always draft the regions-and-states shape regardless of what is detected, since that is the only shape this skill or any other shipped mechanism produces, adding the ASCII sketch fence only when the layout is not built yet. Report a higher tier rather than attempting a companion render for it.
29
29
  - Default silently to tier 0 when nothing is detected.
30
30
 
31
31
  ## Draft
32
32
 
33
33
  - Decide the mode before drafting. When the surface names an already-built component or file, open that source and draft in transcription mode, citing the render function, the stylesheet rule, or the built file each region and label traces to, per the standard's Transcription-wireframes section.
34
34
  - Draft in role-intent mode otherwise: label each region by its role, never by a class name or a token value.
35
- - Draft `title` and `description` frontmatter, then one `##` heading per layout variant, each holding its own ASCII `plaintext` fence with `←` role annotations, followed by `## Copy` and `## Behavior` sections against `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md`'s template.
36
- - Add a second layout variant only when the layout itself changes across a breakpoint or state, never for a spacing difference alone.
35
+ - Draft `title` and `description` frontmatter, then a lead paragraph naming what the surface is for and what it covers, then `## Regions` as a bullet list naming every region and where it sits relative to the others.
36
+ - Draw an ASCII `plaintext` fence with `←` role annotations only when the layout is not built yet. Skip the fence in transcription mode, which already cites the built source instead.
37
+ - Draft `## States` as a table listing every state a visitor can reach, what reaches it, what it shows in words, and its evidence folder, reading `not captured` in the evidence cell until a capture lands.
38
+ - Follow with `## Copy`, `## Behavior`, and `## Not on this surface`, against `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md`'s template.
39
+ - Give a layout that changes across a breakpoint or state its own entry in the regions list, named by what triggers it, never for a spacing difference alone.
37
40
  - Leave out algorithms, event-handler code, framework prop or class names outside transcription mode, and anything else the standard sends to a context entry instead.
38
41
 
39
42
  ## Confirm
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: ux-walkthrough
3
+ description: Why a multi-finding inspection walkthrough with the operator needs its own surface beside draft-and-pick, and where the boundary against building and auditing falls
4
+ ---
5
+
6
+ # UX walkthrough requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session running an inspection walkthrough with the operator:
11
+
12
+ - Files every round's evidence into one flat shared folder, so nothing shows which walkthrough a folder came from or in what order the rounds ran.
13
+ - Hands over screenshots or file paths the operator cannot open, where a served localhost page is the one form that reaches them.
14
+ - Asks the pick question before the operator has the page, so the answer is taken from a description.
15
+ - Sends the link inside the same message as the question, where the structured question surface draws over it and the operator never sees the link.
16
+ - Draws arms as hand-written mock-ups of the app, which drift a few pixels and a few words from what ships, rather than lifting the built page's own markup and stylesheet.
17
+ - Measures the mark and not the text inside it, or the gap and not what shows above it, so a pick ships with half its condition unchecked.
18
+ - Quotes figures in a pick question from memory, and records them without reading the computed values back.
19
+ - Relays each pick as it is taken when the operator wants picks batched on their own call.
20
+ - Serves a rebuilt export from a server whose working directory was deleted by the rebuild, and measures a page that is not there.
21
+ - Applies a pick to the tracked tree, or deletes the candidate pages, because the single-decision loop it borrowed does both.
22
+ - Leaves findings, numbers and build criteria in chat, so whoever files the work does it from a summary rather than from a record.
23
+
24
+ ## Must
25
+
26
+ - Record conditions, findings with their measurements, picks with the arms they beat, evidence paths and build criteria in one walkthrough file under `.canon/walkthroughs/`.
27
+ - Measure each finding off the built page before drafting any arm.
28
+ - Build candidate pages from the app's rendered markup and built stylesheet, with a theme toggle, served on localhost.
29
+ - Capture every arm in every theme the app ships to its walkthrough's own evidence folder, and look at the captures before handing the link over.
30
+ - Number the walkthrough folder and each round's folders so they sort in the order they ran, and let a round's number match its finding's.
31
+ - Send the localhost link in its own message, ending the turn, before every pick question is asked.
32
+ - Hold picks and relay them only when the operator calls a batch, as one message, to the controller where one exists and to the operator otherwise.
33
+ - Route a finding with no visible choice into the batch as a proposed row rather than drafting arms for it.
34
+
35
+ ## Must not
36
+
37
+ - Change a tracked file, create a branch or commit, or file a task row.
38
+ - Apply a winning arm or delete the evidence.
39
+ - Draft arms for a finding the operator has not raised.
40
+ - Restate `draft-and-pick`'s arm rules or the `canon capture` and `canon serve` mechanics.
41
+ - Fire on a request naming one decision alone, which `draft-and-pick` covers.
42
+ - Review criterion, not a gate: whether anything other than the operator or a controller's launch brief invokes this skill, and which lines a second project found in its way. Read both back after it has run outside the project it was written in.
43
+
44
+ ## Guards
45
+
46
+ The refusal strings sit in the body. Two conditions stop a run: no build to measure against, and a request to change a tracked file.
47
+
48
+ ## Out of scope
49
+
50
+ - `draft-and-pick` runs one decision end to end and applies it. This runs many decisions and applies none.
51
+ - `ux-audit` reads source for roughness. This takes its findings from what the operator saw.
52
+ - `plan-feature` and a worker build a pick. This stops at the record and the batch.
53
+ - The controller, or the operator where none exists, decides rows, order and pull request boundaries. This proposes and does not file.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: ux-walkthrough
3
+ description: Runs an inspection walkthrough over a running app with the operator. Measures each finding off the built page, drafts arms as served HTML pages lifted from the app's own markup and stylesheet, hands over the localhost link before every pick question, records findings and picks with the arms they beat in one walkthrough file, and relays picks only in batches the operator calls. Use when asked to "run a first-use walkthrough", "do an operator walkthrough", "go through my findings one by one", "inspection walkthrough over the app", or "walk through everything I listed with me". Do NOT use for one decision on its own, which is `draft-and-pick`, to read source for roughness, which is `ux-audit`, or to build a pick, which is `plan-feature` and a worker.
4
+ ---
5
+
6
+ # UX walkthrough
7
+
8
+ A walkthrough turns what the operator sees in a running app into findings and picks a builder can act on without the conversation. The render is the decision and the record carries the measurements, so every pick here is taken by looking and written down with the numbers behind it.
9
+
10
+ ## Guards
11
+
12
+ - If no running build or build command exists to measure against, stop: `❌ Nothing to inspect. A walkthrough measures a running build.`
13
+ - If the session is asked to change a tracked file, stop and route it: `❌ A walkthrough records and does not build. Hand the pick to whoever dispatches the build.`
14
+ - Draft no arm for a finding the operator has not raised or agreed to take up.
15
+
16
+ ## Posture
17
+
18
+ - Write only under `.canon/`, never a tracked file, and create no branch, commit or task row.
19
+ - Stay in the checkout the session started in. Enter no worktree for a walkthrough, since nothing it writes is tracked.
20
+ - Read the `walkthrough.md` of every earlier walkthrough under `.canon/walkthroughs/` first, and raise nothing they already decided.
21
+ - Name every folder a walkthrough writes with a two-digit prefix, per `${CLAUDE_SKILL_DIR}/references/record.md`, so the walkthrough and its rounds sort in the order they ran.
22
+ - Put builds, generator scripts and logs in a scratch folder outside the tracked tree, and anything the operator opens under `.canon/tmp/`.
23
+
24
+ ## Steps
25
+
26
+ 1. **Bring up both builds and record the conditions.** Follow `${CLAUDE_SKILL_DIR}/references/builds.md`. Start the walkthrough file with the commit, the ports and the build commands before the first finding.
27
+ 2. **Take the operator's list in their order.** Name each item as a finding with the walkthrough letter and a number, such as T1, and confirm the order once rather than per item.
28
+ 3. **Measure before drafting.** Read the component behind the finding and pull the numbers off the built page, per `${CLAUDE_SKILL_DIR}/references/measuring.md`. Write the finding into the walkthrough file with those numbers before any arm exists.
29
+ 4. **Route a finding with no visible choice.** A parse defect, a stale figure or a broken invariant gets recorded as a finding with no draft and goes into the batch as a proposed row, not as a pick.
30
+ 5. **Draft three or four arms.** Follow `draft-and-pick` Steps 1 and 2 for the arms, with arm 0 the shipped state, one property varied and a cost on each. Build the page from the app's own rendered markup, per `${CLAUDE_SKILL_DIR}/references/candidate-pages.md`.
31
+ 6. **Look before handing anything over.** Capture every arm in every theme the app ships into `.canon/walkthroughs/<nn>-<slug>/evidence/<nn>-<slug>/`, with the finding's number as the prefix, open the captures, and fix what rendered wrong before the operator sees the page.
32
+ 7. **Hand the link, then ask.** Emit `http://localhost:<port>/<nn>-<slug>/candidates.html` in a message that ends the turn, confirmed with a `200`, carrying no question. Take any reply after that message as the operator having looked, an explicit "go" included, rather than holding for a stated confirmation, and only then put the choice through the structured question surface with the recommendation first.
33
+ 8. **Record the pick.** Write what won, what it beat and by which numbers, where the evidence is, and the build criteria, per `${CLAUDE_SKILL_DIR}/references/record.md`. Read every figure you quote back from the page or the data file first, and correct the record where the question quoted one wrong.
34
+ 9. **Hold picks for the batch.** Relay nothing per pick. When the operator calls the batch, send it once per `${CLAUDE_SKILL_DIR}/references/relay.md`.
35
+ 10. **Close on the operator's word.** Add the walkthrough summary table and the handoff, leave the evidence in place, and report every file written by its path.
36
+
37
+ ## Rules
38
+
39
+ - Answer a question the operator asks mid-walkthrough in prose first, with a recommendation, and offer a draft rather than drafting unasked.
40
+ - Say when a pick revises an earlier walkthrough's pick, and record it as a revision naming the pick it revises.
41
+ - Check a claim against the code or the data before an arm makes it, since an arm drawn on a wrong fact is a pick on nothing.
42
+ - Measure both halves of a pick whose condition has two, such as a gap and what shows above it.
43
+ - Keep a finding's measured numbers and the pick's build criteria in the record, never only in chat.
44
+
45
+ ## What this delegates
46
+
47
+ - `draft-and-pick` owns the arm discipline and the structured question. This walkthrough departs from its Step 2 inlining and its Step 6 apply and delete, for the reasons `${CLAUDE_SKILL_DIR}/references/candidate-pages.md` states.
48
+ - `write-human` carries the voice of every recorded passage and any copy an arm puts in front of a reader.
49
+ - `plan-feature` and whoever dispatches builds turn a batch into plans and code.
50
+ - `canon capture`, `canon serve` and `canon sessions list` own the render, the address and the roster.
@@ -0,0 +1,15 @@
1
+ # Builds and servers
2
+
3
+ Read when bringing the app up at the start of a walkthrough, and whenever a measurement returns nothing it should.
4
+
5
+ ## Bring up
6
+
7
+ - Run the live build and whatever service it calls from the checkout the session started in, and record the commit, ports and any state that changes a reading as the walkthrough file's conditions.
8
+ - Build the artifact the deploy ships in a scratch folder outside the tracked tree, so a build never touches the project.
9
+ - Serve that artifact the way the host resolves it. A plain file server can answer a clean route the host rewrites with a 404, such as `/about` for `about.html`.
10
+ - Rebuild from the current main whenever main moves mid-walkthrough, and say so in the record. Measuring a stale build reports on code that no longer ships.
11
+
12
+ ## Traps
13
+
14
+ - Restart a server after rebuilding what it serves. A server started inside an output folder the rebuild replaced keeps serving a deleted directory, and every selector comes back empty.
15
+ - Note what a build cannot show, such as live timing a recorded build does not carry or recompile pauses a dev server adds. Neither is a finding.
@@ -0,0 +1,26 @@
1
+ # Candidate pages
2
+
3
+ Read when drafting arms for a finding. Skip it for a finding with no visible choice.
4
+
5
+ ## Build from the app
6
+
7
+ - Dump the rendered markup of the surface under test from the built page, after it has loaded, into a JSON file in scratch. Strip scripts from the dump.
8
+ - Copy the built stylesheet and font files under `.canon/tmp/`, at the path the dumped markup links them from, so a candidate page renders with the stylesheet the app ships. Every arm then differs from the shipped page only by what the arm names.
9
+ - Trim a large dump to the part the finding needs, and keep the wrapper classes intact so layout rules keyed to them still resolve.
10
+ - Size each frame to the content width the finding names rather than the window width, since a container query reads the frame.
11
+ - Write copy an arm introduces with `write-human`, and take every other word from the dump.
12
+
13
+ ## The page
14
+
15
+ - Generate the page with a short script, one per round, so a shared change is one edit and a rerun.
16
+ - Put a theme button on the page that flips the app's own theme switch on the root, rather than drawing each frame once per theme. Read `?arm=<id>&theme=<name>` to strip every other arm and the button for capture. Skip the button for an app that ships one theme.
17
+ - Print each frame's measurement under it from a script in the page, so the numbers the operator reads are the browser's.
18
+ - Write an index page linking one page per arm when an arm is a whole page or a route rather than a frame, with thumbnails copied beside it.
19
+ - Name anything the preview cannot reproduce, such as an asset whose colors follow the browser rather than the page's theme button, rather than fixing the page around it.
20
+
21
+ ## Where this departs from draft-and-pick
22
+
23
+ - Capture into the walkthrough's own numbered evidence folder instead of the folder `draft-and-pick` Step 6 archives arms into, per `${CLAUDE_SKILL_DIR}/references/record.md`.
24
+ - Link the app's built stylesheet instead of inlining every asset. Lifted markup needs the real stylesheet, and an inlined copy is the drift this avoids.
25
+ - Keep `candidates.html` and never apply the winning arm. The walkthrough records and a build applies.
26
+ - Leave `.canon/tmp/<nn>-<slug>/` in place until the picks are built, and never delete the round's evidence folder.
@@ -0,0 +1,22 @@
1
+ # Measuring
2
+
3
+ Read before writing a finding and before recording a pick.
4
+
5
+ ## Off the page
6
+
7
+ - Measure on the built page in a real browser at the widths the finding names, in every theme the app ships, and record the viewport.
8
+ - Read computed styles rather than class lists. A class list names intent, and the computed value is what paints.
9
+ - Measure text contrast against the ground it sits on, and a mark's contrast against its own ground, as two numbers. A mark that sets a background and no text color inherits the browser default, and only the text reading catches it.
10
+ - Measure empty space by text extent, the union of each text node's client rects, rather than by leaf element boxes. A block element spans its row whatever its text covers.
11
+ - Measure a landing by the landed element's top against the bar's bottom edge and by whether the element before it is visible. A pick with a two-part condition needs both readings.
12
+ - Reproduce the shipped value inside the candidate page before trusting an arm's numbers. Arm 0 reading the same as the live page is what shows the page matches.
13
+
14
+ ## Off the data
15
+
16
+ - Re-derive a figure from the data file that produced it rather than from any document quoting it. Two documents can disagree, and neither is the source.
17
+ - Count a defect across the whole corpus or tree before recording its size, and say whether it sits only at the end, only in one version, or throughout.
18
+ - Test a proposed fix without editing code where the question is its effect, by patching the function in a throwaway script and comparing before and after on counts the fix could move.
19
+
20
+ ## Before quoting
21
+
22
+ - Read every figure a pick question or a record quotes back from the page or the script that computed it. Correct the record in place when the question quoted one wrong, and say so.
@@ -0,0 +1,36 @@
1
+ # The walkthrough record
2
+
3
+ Read when starting the walkthrough file, recording a finding, and recording a pick.
4
+
5
+ ## File
6
+
7
+ - Write to `.canon/walkthroughs/<nn>-<slug>/walkthrough.md`, with `<nn>-<slug>` the walkthrough's own folder.
8
+ - Open with one paragraph naming the walkthrough, the date, the commit and what landed since the last walkthrough, then `## Conditions`, `## Findings`, `## Picks`, `## Walkthrough summary` and `## Handoff`.
9
+ - Number findings with one letter per walkthrough and a counter, and never reuse a number.
10
+
11
+ ## Folder names
12
+
13
+ - With no earlier walkthrough on this topic, a fresh folder takes the next ordinal in `.canon/walkthroughs/`'s own sequence: list the folders present, take the highest `<nn>`, and increment it, starting at `01` when none exist.
14
+ - Put a round's captures at `.canon/walkthroughs/<nn>-<slug>/evidence/<nn>-<slug>/` and its candidate pages at `.canon/tmp/<nn>-<slug>/`, where the inner `<nn>` is the finding's own number, so T1's folders start `01-`.
15
+ - Leave a gap where a finding has no draft. The missing number is what maps each folder to its entry in the record.
16
+ - Take `<slug>` from the decision sentence the way `draft-and-pick` Step 1 derives it, and add only the prefix.
17
+ - Rename no folder from a walkthrough that predates this rule. Tracked documents cite those paths, and a rename breaks every citation.
18
+
19
+ ## A finding
20
+
21
+ - Head it `### T<n>: <what is wrong, as a claim>`.
22
+ - State what the operator saw, the code behind it by path and line, and the measurement in a table when it has more than two readings.
23
+ - Name an earlier pick the finding revises, and a collision with work in flight.
24
+
25
+ ## A pick
26
+
27
+ - Head it `### Pick <n>, T<n>: arm <id>, <what won>`.
28
+ - One paragraph on what the arm does and its measured result, then `It beat:` with one bullet per losing arm and the number that lost it.
29
+ - One `Evidence:` line naming the evidence folder and its file set.
30
+ - `Build criteria:` as bullets a builder checks against the built page, each measurable, including what the render shows that the prose does not.
31
+ - An answer to a question the operator asked with the pick goes under the criteria, stated as a decision with its reason.
32
+
33
+ ## Close
34
+
35
+ - `## Walkthrough summary` is one table row per finding: the finding, the pick, and the arms it beat.
36
+ - `## Handoff` proposes how the picks split into pull requests by the files each writes, and names shared files and the order they force.
@@ -0,0 +1,25 @@
1
+ # Relaying picks
2
+
3
+ Read when the operator calls a batch, and at the start of the walkthrough when a launch brief asks for collisions.
4
+
5
+ ## Where the batch goes
6
+
7
+ - Send it to the controller where the session was dispatched by one, resolved per the Channel rule, matched by name through `canon gov list --rules --json` rather than a path a target may not have installed.
8
+ - Give it to the operator as one list in the conversation where no controller exists. The walkthrough file is the handoff either way.
9
+
10
+ ## When
11
+
12
+ - Relay nothing per pick. Relay once when the operator calls the batch, covering every pick held since the last one.
13
+ - Put a finding with no visible choice in the same batch, as a proposed row.
14
+
15
+ ## The message
16
+
17
+ - Open with one line saying what the batch holds and where the record is.
18
+ - Give each pick its finding, the arm, the numbers that decided it, the arms beaten, and the files it writes.
19
+ - Close with overlaps and order: files two picks share, picks that must follow another, and collisions with open pull requests or unmerged branches.
20
+ - Name anything the operator holds that is not a row, such as a repository setting.
21
+
22
+ ## Collisions
23
+
24
+ - List open pull requests with their files, and unmerged remote branches with `git diff --stat origin/main...origin/<branch>`, and compare file sets rather than descriptions.
25
+ - Stamp an overlap with the commit it was measured against.
@@ -25,7 +25,7 @@ canon transcripts <url>
25
25
  ```
26
26
 
27
27
  - Pass `--keep-timestamps` when the user wants `[mm:ss]` markers per line instead of prose.
28
- - Pass `--out <dir>` to override the output directory. The default is `transcripts/` in the current directory.
28
+ - Pass `--out <dir>` to override the output directory, resolved against the current directory. The default is the backed `.canon/transcripts/` folder at the main worktree root, under a filename shaped `<fetch-date>--<title-slug>--<video-id>.md`.
29
29
  - The written file path prints to stdout. Surface it back to the user as a full relative path, in the form the project's instruction file sets under `## Output`.
30
30
 
31
31
  ## After the fetch
@@ -66,7 +66,7 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
66
66
  | `canon worktrees list` | Report which worktrees are reclaimable, keyed on the pull request having merged, with every refusal and the removal route named (`--json`) |
67
67
  | `canon worktrees reclaim` | Remove every reclaimable worktree and the branch behind it, reporting without acting under `--dry-run` (`--json`) |
68
68
  | `canon comments scan` | Measure comment density by language and comment kind, with a trend recomputed from git |
69
- | `canon context audit` | Report required sections, length, cited paths, reference form, catalog tables, provenance, superseded-decision narration, and index drift |
69
+ | `canon context audit` | Report required sections, length, cited paths, reference form, catalog tables, provenance, superseded-decision narration, index drift, the architecture record's word weight, and wireframe states against their evidence folders |
70
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
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
72
  | `canon context classifier show` | Report the resolved classifier backend and model and which source decided them (`--json`) |
@@ -55,6 +55,8 @@ The table check reports a catalog that grows a row per shipped thing, not a tabl
55
55
 
56
56
  The provenance check reports the markers narrating how a domain reached its shape rather than describing what it is: a date, a change number, or a release label. The standard admits a rejected alternative and the reasoning that killed it while refusing the provenance attached to it, so a marker names a line to read rather than a line to delete. Findings group by entry and sort left to right within a line, since what a reader acts on is which file to open.
57
57
 
58
+ A change number matches at any digit count, so `PR #7` and `#49` report alongside a four-digit number. Displayed spans are masked before the match runs, which is what keeps a heading's own auto-derived link destination, `(#7-open-questions)`, and a hex color in a code span, `` `#000` ``, from reading as a change reference: both are text an entry shows rather than a claim it makes. <!-- canon-allow-reference: illustrates the input shape the rule reads -->
59
+
58
60
  A date stamping a measurement is excluded, because the standard cuts a date attached to a change and permits one dating a figure. The check reads the clause in front of the date, back to the nearest sentence boundary, for one of five verbs: measured, verified, driven, passed, and fired. The noun `run` counts only where it sits against the date, so `A run on 2026-08-14` is excluded and `Runs on erclx/canon#632 and erclx/canon#634 landed 2026-08-02` reports. The set is closed, and a date it cannot place reports as a change marker rather than as a state of its own, which names one date too many rather than clearing one the rule cuts. <!-- canon-allow-reference: illustrates the input shape the rule reads -->
59
61
 
60
62
  A release label reports with or without its leading `v` at three segments, since the rule cuts the label rather than a spelling of it. Two segments still need the `v`, which keeps a dollar cost and a duration out. Another tool's version reports too, and the check cannot tell one from a release, so treat a version beside a tool name as a line to read rather than one to cut.
@@ -89,7 +91,7 @@ The JSON record carries the findings per entry as `entries[].narration` and the
89
91
 
90
92
  ## The architecture record
91
93
 
92
- Two findings read `canon/ARCHITECTURE.md` rather than a folder, and only the first is a fact.
94
+ Three findings read `canon/ARCHITECTURE.md` rather than a folder, and only the first is a fact.
93
95
 
94
96
  The length check compares the record against the ceiling it derives for itself, and only a record that states its own allowances has one. No standard sets a length rule for this document, so the numbers belong to whichever record declares them. The check reads a frame allowance and an allowance per decision out of the record's own prose and puts the ceiling at the frame plus the allowance times the decision count. The JSON record carries what it read as `architecture.allowances` and the reading as `architecture.lines` against `architecture.ceiling`.
95
97
 
@@ -103,9 +105,27 @@ Three limits are stated on every run rather than hidden. The countable signal re
103
105
 
104
106
  The report gates nothing. Deciding whether a sentence states a claim is a judgment no parser settles, so the output names candidates for a reader. This answers a different question from the verification anchors `standards/architecture.md` describes, which record that one cited number was re-read. That mechanism says whether a marked figure held, and this one says how much of the record could be checked at all.
105
107
 
108
+ The third finding is a word count, measured in words rather than lines: one figure for the whole record and one per decision. `standards/architecture.md` asks a session to judge the file's weight by reading it rather than by counting it, and reads the word figure alongside that judgment when one is available. A paragraph written one source line to a paragraph passes the rendered-line measure other checks use while still reading heavy, which is the gap a word count closes without turning into a second cap.
109
+
110
+ The `## Risks / open questions` section is weighed the same way, reported apart from the whole-record figure since the standard singles it out for holding only what is still open. This finding gates nothing under any mode. The JSON record carries the whole-record figure as `architecture.words`, the section figure as `architecture.risksWords` where the record carries the heading, and the per-decision figure as `architecture.decisions[].words`.
111
+
112
+ ## Wireframe states
113
+
114
+ Every entry under `canon/wireframes/` carrying a `## States` table is checked against its evidence folders on disk. `State` and `Evidence` are matched by header text rather than column position, since the standard's own template could still move a column during its own review. An entry with no such table is out of scope and reports nothing.
115
+
116
+ An evidence cell's path is read as written and resolved against the project root, since the standard puts the path in the cell rather than a state name a convention would have to guess at. A state whose cited path resolves to no directory is a missing folder, measured in states: one finding per row. A directory sitting under a root at least one row already cites, but named in no row itself, is an unlisted folder, measured in folders: one finding per directory.
117
+
118
+ Both are counted rather than only listed, since a count is what a reader compares run to run. A `not captured` cell is the one value the standard exempts from having a folder, and it drops out of both counts.
119
+
120
+ The third finding reads the whole entry rather than one row: whether it carries a `plaintext`-fenced sketch while a state's evidence already exists on disk. The standard asks the fence to come out the moment a layout has a capture to show instead, so a sketch surviving past that point is a boolean per entry rather than a count.
121
+
122
+ The unit here is the entry rather than the layout the standard's own rule is stated against. A table names states, not the layouts a wireframe's `## Regions` section can split into at a breakpoint, so this finding has no narrower unit to match a sketch against the evidence for its own layout alone. An entry with a captured default layout and a sketch for a breakpoint layout that is not built yet is conforming, and this finding still reports it, which is why it stays advisory under every mode rather than joining the states-mismatch gate below.
123
+
124
+ All three wireframe findings are printed under a bare run. The states-mismatch finding, missing and unlisted folders together, gates at `2` under `--gate`, alongside a missing required section and index drift. The sketch finding stays advisory under both modes, for the reason above. The JSON record carries them per entry under `wireframes[]`, as `rows`, `missingFolders`, `unlistedFolders`, and `sketchWithEvidence` alongside `sketchLine`.
125
+
106
126
  ## Which folders each check reaches
107
127
 
108
- The provenance, required-section, and narration checks cover `canon/context/` alone, the reference-form check covers the split folders inside it, and length and the table finding reach every audited folder.
128
+ The provenance, required-section, and narration checks cover `canon/context/` alone, the reference-form check covers the split folders inside it, length and the table finding reach every audited folder, and the wireframe states check covers `canon/wireframes/` alone.
109
129
 
110
130
  What narrows the three is stated in `standards/context.md`, which opens its scope by handing diagrams and wireframes to `diagrams.md` and `wireframes.md`, and the sibling standards do not restate it. A marker reported in a diagram entry would cite a rule that entry's own standard routes elsewhere, and a diagram entry carries a heading per kind rather than a run of bullets deciding anything. The split is between kinds of rule rather than kinds of folder, and what decides it is which tier states the rule rather than what the check measures.
111
131
 
@@ -37,9 +37,11 @@ A run where no requested name resolves refuses, whichever list it read. Naming t
37
37
 
38
38
  ## Exit codes
39
39
 
40
- Exit codes are `0` for a clean run, `1` for a refusal, and `2` for a gating finding. An unresolved citation gates under every mode. An architecture record that states its own line allowances gates when it is past the ceiling those derive, on any run that measures it, which is every mode except `--citations-only`, and a record stating none is reported and never gated. Entry length, reference form, table, provenance, narration, and the record's claim classification print and return `0` under every mode, because each is a judgment and failing a push on one would make the check something to route around. Narration is the weakest of the five, since whether two bullets share a subject is a call the measure approximates from structure alone, and one of the shapes it matches is the rejected alternative the standard asks an entry to keep.
40
+ Exit codes are `0` for a clean run, `1` for a refusal, and `2` for a gating finding. An unresolved citation gates under every mode. An architecture record that states its own line allowances gates when it is past the ceiling those derive, on any run that measures it, which is every mode except `--citations-only`, and a record stating none is reported and never gated.
41
41
 
42
- Required-section and index findings sit between the two. Both are answerable from the file rather than weighed, so `--gate` promotes them to failing codes while a bare run leaves them advisory. The toolkit runs the bare form against itself and the widened form against the seed tree, described below.
42
+ Entry length, reference form, table, provenance, narration, the record's claim classification, and every word figure print and return `0` under every mode, because each is a judgment or a weight read alongside one, and failing a push on either would make the check something to route around. Narration is the weakest of the printed measures, since whether two bullets share a subject is a call the measure approximates from structure alone, and one of the shapes it matches is the rejected alternative the standard asks an entry to keep.
43
+
44
+ Required-section, index, and wireframe-states findings sit between the two. All three are answerable from the file rather than weighed, so `--gate` promotes them to failing codes while a bare run leaves them advisory. Sketch-with-evidence sits with the printed measures instead, for the reason `context-audit-checks.md` states: it reads a whole entry against whether any of its states has evidence, not one layout against its own evidence, so a conforming file can still trip it. The toolkit runs the bare form against itself and the widened form against the seed tree, described below.
43
45
 
44
46
  ## The seed gate
45
47
 
@@ -81,3 +83,11 @@ Append `<!-- audit-ignore-citations: <path> -->` to the source line in either ca
81
83
  The marker itself stays out of anything that installs. A seed, a plugin skill body, and a stack reference all reach a target, so a marker there lands as toolkit bookkeeping in someone else's tree. Reword those lines to drop the path instead, and where a stop message has to spell it, move that message into a fenced block, which this check already skips.
82
84
 
83
85
  The pattern spells both record-root prefixes, so a citation into a folder that has moved still resolves and a folder resolved at the project root is measured by every other check while contributing nothing here. A pattern fixed at one root matches nothing after a move and reports nothing, which is a stale reference passing the check written to find it. Widening it to a bare `docs/x.md` would match prose that references nothing, which is a separate decision from where entries come from. A run whose folders all resolved at the root says the check is out of scope rather than reporting that zero paths resolved, and the same run under `--citations-only` refuses, because a gate exiting clean on a scope it could not build is the failure the gate exists to catch.
86
+
87
+ ## The wireframe states gate
88
+
89
+ Every entry under `canon/wireframes/` carrying a `## States` table is checked one-to-one against its evidence folders, matching the table's `State` and `Evidence` columns by header text rather than position, so a project reordering the template's own columns still resolves. An entry with no such table reports nothing, which is what leaves a project on an older wireframe shape silent until it adopts one.
90
+
91
+ An evidence cell resolves as the literal path it names, taken from the project root. A state whose cited folder does not exist is a states mismatch, and so is a folder sitting under a cited evidence root that no row names. A `not captured` cell is the one exception the standard admits, and it excuses that row from both readings. A `plaintext` sketch still carried once a state's evidence exists on disk is a third finding this check adds, reading the entry as a whole rather than one row.
92
+
93
+ The states mismatch is printed under a bare run and gates at `2` under `--gate`, alongside a missing required section and index drift. The sketch finding is printed and stays advisory under both modes: it has no way to pair a sketched layout with that layout's own evidence, only the entry with any evidence at all, so a conforming file, a captured default layout beside a sketch of a breakpoint layout nobody has built, can still trip it.