@erclx/canon 5.62.0 → 5.64.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/CHANGELOG.md +26 -0
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/context-fold/REQUIREMENT.md +2 -3
- package/claude/skills/context-fold/SKILL.md +1 -11
- package/claude/skills/context-fold/references/completion-report.md +8 -9
- package/claude/skills/create-skill/references/skill-practice.md +17 -1
- package/claude/skills/design-record/references/design.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +2 -1
- package/claude/skills/design-taste/SKILL.md +6 -5
- package/claude/skills/design-taste/references/adopted.md +56 -8
- package/claude/skills/design-taste/references/craft.md +1 -1
- package/claude/skills/design-taste/references/kinds.md +8 -2
- package/claude/skills/design-taste/references/preflight.md +3 -3
- package/claude/skills/design-taste/references/tells.md +26 -5
- package/claude/skills/document-health/REQUIREMENT.md +1 -1
- package/claude/skills/document-health/SKILL.md +3 -14
- package/claude/skills/document-health/references/axes.md +14 -16
- package/claude/skills/plan-feature/SKILL.md +2 -2
- package/claude/skills/plan-feature/references/plan.md +24 -3
- package/claude/skills/review-craft/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +2 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/ui-craft/REQUIREMENT.md +29 -0
- package/claude/skills/ui-craft/SKILL.md +44 -0
- package/{governance/rules/ui → claude/skills/ui-craft/references}/a11y.md +0 -10
- package/claude/skills/ui-craft/references/adopted.md +27 -0
- package/{governance/rules/ui/surface-capture.md → claude/skills/ui-craft/references/capture.md} +0 -10
- package/{governance/rules/ui/ux-controls.md → claude/skills/ui-craft/references/controls.md} +3 -10
- package/claude/skills/ui-craft/references/copy.md +45 -0
- package/{governance/rules/ui → claude/skills/ui-craft/references}/forms.md +0 -9
- package/{governance/rules/ui → claude/skills/ui-craft/references}/keyboard.md +0 -10
- package/{governance/rules/ui → claude/skills/ui-craft/references}/motion.md +0 -10
- package/{governance/rules/ui → claude/skills/ui-craft/references}/pointer.md +0 -10
- package/{governance/rules/ui/ux-completeness.md → claude/skills/ui-craft/references/states.md} +0 -10
- package/claude/skills/ux-audit/SKILL.md +1 -1
- package/claude/skills/write-human/references/adopted.md +4 -1
- package/docs/agents/audits.md +2 -6
- package/docs/agents/context-audit.md +1 -1
- package/docs/agents/install-and-sync.md +2 -2
- package/docs/target/migrations.md +3 -3
- package/docs/target/sync.md +3 -2
- package/docs/workflow/skill-map.md +1 -0
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/governance/detect.toml +1 -45
- package/governance/ledger/lib/test-scope.md +1 -1
- package/governance/ledger/skills/api-design/SKILL.md +62 -0
- package/governance/ledger/skills/code-craft/SKILL.md +53 -0
- package/governance/ledger/skills/deprecation-migration/SKILL.md +68 -0
- package/governance/ledger/skills/design-taste/SKILL.md +64 -0
- package/governance/ledger/skills/design-taste/craft.md +66 -0
- package/governance/ledger/skills/design-taste/kinds.md +58 -0
- package/governance/ledger/skills/design-taste/systems.md +42 -0
- package/governance/ledger/skills/design-taste/tells.md +103 -0
- package/governance/ledger/{ui → skills/ui-craft}/a11y.md +3 -3
- package/governance/ledger/{ui/surface-capture.md → skills/ui-craft/capture.md} +3 -3
- package/governance/ledger/{ui/ux-controls.md → skills/ui-craft/controls.md} +12 -7
- package/governance/ledger/skills/ui-craft/copy.md +102 -0
- package/governance/ledger/{ui → skills/ui-craft}/forms.md +3 -3
- package/governance/ledger/{ui → skills/ui-craft}/keyboard.md +3 -3
- package/governance/ledger/{ui → skills/ui-craft}/motion.md +3 -3
- package/governance/ledger/{ui → skills/ui-craft}/pointer.md +3 -3
- package/governance/ledger/{ui/ux-completeness.md → skills/ui-craft/states.md} +3 -3
- package/governance/ledger/ui/craft.md +19 -0
- package/governance/renames.toml +17 -3
- package/governance/rules/lib/test-scope.md +1 -1
- package/governance/rules/ui/craft.md +22 -0
- package/governance/splits.toml +0 -2
- package/package.json +1 -1
- package/src/audits/catalog.ts +0 -52
- package/src/claude/cases/misc.ts +5 -0
- package/src/claude/skills-audit.ts +226 -12
- package/src/cli/retired.ts +8 -0
- package/src/commands/claude.ts +15 -1
- package/src/commands/context.ts +0 -425
- package/src/commands/tooling.ts +4 -1
- package/src/context/citations.ts +9 -3
- package/src/gate/measures.ts +4 -3
- package/src/git/files.ts +8 -3
- package/src/gov/audit.ts +6 -1
- package/src/inventory/subjects.ts +1 -1
- package/src/markdown/gated.ts +1 -1
- package/src/markdown/scope.ts +0 -1
- package/src/tooling/package.ts +22 -13
- package/tooling/web/reference.md +3 -1
- package/claude/skills/context-fold/references/classify.md +0 -87
- package/governance/ledger/ui/copy.md +0 -49
- package/governance/ledger/ui/design-taste.md +0 -19
- package/governance/ledger/ui/interface-casing.md +0 -47
- package/governance/ledger/ui/link-behavior.md +0 -29
- package/governance/rules/ui/copy.md +0 -28
- package/governance/rules/ui/design-taste.md +0 -18
- package/governance/rules/ui/interface-casing.md +0 -29
- package/governance/rules/ui/link-behavior.md +0 -19
- package/src/context/classify/extract.ts +0 -443
- package/src/context/classify/ollama.ts +0 -172
- package/src/context/classify/patterns.ts +0 -75
- package/src/context/classify/prompts.ts +0 -74
- package/src/context/classify/run.ts +0 -348
- package/src/context/classify/settings.ts +0 -196
- /package/tooling/web/{configs → seeds}/e2e/home.spec.ts +0 -0
|
@@ -38,7 +38,7 @@ Read these in parallel from the project root, skipping any that do not exist:
|
|
|
38
38
|
|
|
39
39
|
Also read `canon/DESIGN.md` when the feature touches code or UI, for visual intent and component rules, with values read from the stylesheet its lead names. Skip it for prose, docs, catalog, or config-only changes. For a UI feature, read `canon/design/index.md` too, if it exists, for the surfaces with an accepted design.
|
|
40
40
|
|
|
41
|
-
Coding standards live in `.claude/rules/`. Claude Code loads them automatically, and path-scoped rules apply to the files they match. For a UI feature, load `canon:design-taste` whether or not `canon/DESIGN.md` exists.
|
|
41
|
+
Coding standards live in `.claude/rules/`. Claude Code loads them automatically, and path-scoped rules apply to the files they match. For a UI feature, load `canon:ui-craft` for how it behaves and `canon:design-taste` for how it looks, whether or not `canon/DESIGN.md` exists.
|
|
42
42
|
|
|
43
43
|
### Read the domain's context entry
|
|
44
44
|
|
|
@@ -86,7 +86,7 @@ Every `- Suggested:` line takes senior judgment, picking the best option in one
|
|
|
86
86
|
- Suggest a real default when best practice, the codebase, or prior context points to one
|
|
87
87
|
- Before `## Files to touch`, load `canon:codebase-layout` for a new path (its reason) and `canon:api-design` for a changed verb, flag, output, record shape, or endpoint. Report either if missing.
|
|
88
88
|
- Fill `## Design references` with the `canon/design/<surface>/` folder for each surface a UI file in `## Files to touch` renders, and write `None identified.` in a project with no folder
|
|
89
|
-
- Write `## Verification` as one bullet per outcome naming the test or command that proves it
|
|
89
|
+
- Write `## Verification` as one bullet per outcome naming the test or command that proves it, with a grep bullet per `## Verbatim` block of settled wording
|
|
90
90
|
- Write `## Review focus` as the inputs or states that would break the change, carrying the risk you understood to the executor and the reviewer
|
|
91
91
|
|
|
92
92
|
### Sources and size
|
|
@@ -75,6 +75,7 @@ The document opens with `# Feature: <short title>` and one paragraph stating wha
|
|
|
75
75
|
| `## Current behavior` | each command run against the thing being changed and what it showed | When the change touches something that runs |
|
|
76
76
|
| `## Constraints` | durable rules the work must respect | When supplied |
|
|
77
77
|
| `## Files to touch` | each file with a one-line reason | Always |
|
|
78
|
+
| `## Verbatim` | settled wording that lands unchanged in an existing file, one H3 per block | When wording is settled |
|
|
78
79
|
| `## Design references` | the tracked design folders the change builds against, each with its surface | When Files to touch names a rendered-surface file |
|
|
79
80
|
| `## Verification` | the test or command that proves each outcome | Always |
|
|
80
81
|
| `## Risks` | conflicts, coupling, and the tricky spots | Always |
|
|
@@ -171,6 +172,16 @@ A batch in a fan-in set declares its side in a constraint bullet, ``Fan-in membe
|
|
|
171
172
|
|
|
172
173
|
A constraint naming a `.canon/ready/` folder is a third shape beside the hold and the shared path. It makes that folder's files the verbatim source for the paths this plan's `## Files to touch` lists, per `ready.md`, so the executing session copies those paths rather than authoring them.
|
|
173
174
|
|
|
175
|
+
### Verbatim
|
|
176
|
+
|
|
177
|
+
A `## Verbatim` section carries wording someone settled, landing in an existing file exactly as written. Wording the planner only proposes stays a `- Suggested:` question, and a whole new file goes in the ready folder per `ready.md`, so the two never describe the same file.
|
|
178
|
+
|
|
179
|
+
- Give each block an H3 naming it, then a lead sentence with the action, the full path, and the anchor, then a fenced `text` block holding the wording
|
|
180
|
+
- Name the action as Add, Insert, or Replace. A Replace quotes the old line in the lead's code span.
|
|
181
|
+
- Write the block as the project's formatter leaves it, since a formatter that re-pads a table row or rewraps a line makes the grep fail on correct text
|
|
182
|
+
- Name the outcome in a grep bullet and put a command past 200 characters in a fenced `bash` block under it, since `S4` reports a longer bullet
|
|
183
|
+
- Give each block one `## Verification` bullet running `grep -cF -e` on its whole first line against its file, so a reworded line fails a check the reviewer already runs.
|
|
184
|
+
|
|
174
185
|
### Design references
|
|
175
186
|
|
|
176
187
|
A plan whose `## Files to touch` names a rendered-surface file (`.tsx`, `.jsx`, `.astro`, `.vue`, `.svelte`, `.html`, or `.css`) carries this section. It tells the building session which accepted design to open before it writes a line.
|
|
@@ -258,9 +269,9 @@ This contract inverts the one an intake folder keeps, where an empty slot means
|
|
|
258
269
|
|
|
259
270
|
## Template
|
|
260
271
|
|
|
261
|
-
Each H3 below shows where a section groups once it passes 5 bullets. A section of 5 or fewer drops its H3s and keeps its bullets flat, except `## Risks`, which
|
|
272
|
+
Each H3 below shows where a section groups once it passes 5 bullets. A section of 5 or fewer drops its H3s and keeps its bullets flat, except `## Risks` and `## Verbatim`, which take an H3 per risk or block at any count.
|
|
262
273
|
|
|
263
|
-
|
|
274
|
+
````markdown
|
|
264
275
|
# Feature: <short title>
|
|
265
276
|
|
|
266
277
|
<One paragraph on what is being built and why now.>
|
|
@@ -300,6 +311,16 @@ The files below share <the reason>.
|
|
|
300
311
|
|
|
301
312
|
- `<path/to/file>`: <reason>
|
|
302
313
|
|
|
314
|
+
## Verbatim
|
|
315
|
+
|
|
316
|
+
### <Block name>
|
|
317
|
+
|
|
318
|
+
Add as <where> in `<path/to/file>`, after <anchor>.
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
<the wording, as the formatter leaves it>
|
|
322
|
+
```
|
|
323
|
+
|
|
303
324
|
## Design references
|
|
304
325
|
|
|
305
326
|
- `canon/design/<surface>/`: <the surface it governs>
|
|
@@ -335,4 +356,4 @@ The questions below decide <what>, numbered across the whole section.
|
|
|
335
356
|
## Sources
|
|
336
357
|
|
|
337
358
|
- [<title>](url), backing <decision>: "<passage relied on>"
|
|
338
|
-
|
|
359
|
+
````
|
|
@@ -49,7 +49,7 @@ An axis whose condition the diff meets is not optional. When the security or the
|
|
|
49
49
|
Read each of these when the diff reaches what it names.
|
|
50
50
|
|
|
51
51
|
7. **Security.** Read `${CLAUDE_SKILL_DIR}/references/security.md` when the diff runs a command, writes or deletes a file, takes outside input, touches a secret, adds a dependency, or changes a default.
|
|
52
|
-
8. **Rendered output.** Read `${CLAUDE_SKILL_DIR}/references/ui.md` when the diff
|
|
52
|
+
8. **Rendered output.** Read `${CLAUDE_SKILL_DIR}/references/ui.md` when the diff paints or the pull request carries evidence. Judge behavior by `ui-craft` and the look by `design-taste`.
|
|
53
53
|
- A file that paints is markup, a stylesheet, a component, a template, or a design token
|
|
54
54
|
- A stylesheet diff says what the author changed and only the screenshot says what a user sees, so the reference opens the images and checks whether any exist
|
|
55
55
|
9. **Developer experience and operations.** Ports, hooks, scripts, config, and scaffold defaults a consumer installs.
|
|
@@ -23,6 +23,7 @@ This body states the role, the boundaries, and the channel, and starts no step o
|
|
|
23
23
|
- Resolve `.canon/plans/`, `.canon/tasks/`, `.canon/review/`, and `.canon/ready/` at the main worktree root, never the linked worktree. Being gitignored, they are absent there rather than empty.
|
|
24
24
|
- Report a plan that fails to resolve as unreadable from here, naming the main-root path. Reporting the task as having no plan is wrong about the world, and a reader cannot tell the two apart.
|
|
25
25
|
- Build the plan the launch named. Never write a second one when the path fails to resolve, since a row citing a plan already has one.
|
|
26
|
+
- Load `ui-craft` before editing a rendered surface, pointer rule or not
|
|
26
27
|
- Keep a task list from launch, one item per slice, and tick each as its slice lands. Skip it on a host that offers no list tool, since the list is for the operator watching and not a gate.
|
|
27
28
|
|
|
28
29
|
### Ready folders and the draft mark
|
|
@@ -60,7 +61,7 @@ A plan carrying a `**Design references:**` section names the accepted design for
|
|
|
60
61
|
|
|
61
62
|
- Open each cited folder's light and dark images and its frame HTML before the first edit to that surface
|
|
62
63
|
- Take sizes, spacing, and colors from the frame HTML rather than from the image
|
|
63
|
-
- Report a reference
|
|
64
|
+
- Report a missing reference by its path rather than building without it
|
|
64
65
|
- Leave `None identified.` as it stands and build without a reference
|
|
65
66
|
|
|
66
67
|
## Scope after dispatch
|
|
@@ -48,7 +48,7 @@ The checkbox stays `- [ ]` followed by the action and the result, since the evid
|
|
|
48
48
|
|
|
49
49
|
## Boxes no engine reads
|
|
50
50
|
|
|
51
|
-
The UI review runs axe over every route it reaches, so a box restating what axe checks, such as contrast, a missing name, or a page title, adds a drive and catches nothing. Derive a box instead for each behavior below that
|
|
51
|
+
The UI review runs axe over every route it reaches, so a box restating what axe checks, such as contrast, a missing name, or a page title, adds a drive and catches nothing. Derive a box instead from the `ui-craft` references the changed surface reads, for each behavior below that it carries:
|
|
52
52
|
|
|
53
53
|
- **Hover content.** Content shown on hover or focus stays while the pointer moves onto it, and Escape dismisses it, per WCAG 1.4.13.
|
|
54
54
|
- **Keyboard trap.** Tab and Shift+Tab leave every widget the change added, per WCAG 2.1.2.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-craft
|
|
3
|
+
description: Why the UI behavior practice lives in one skill every role reads by name, and where it stops beside design-taste and design-record
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# UI craft requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, the UI behavior practice reaches a session only as path rules a target has to sync, so a project holding the plugin without governance builds a component with none of it. A role that plans, builds, or reviews a rendered change has no name to load the practice by, and each one restates the part it remembers.
|
|
11
|
+
|
|
12
|
+
## Must
|
|
13
|
+
|
|
14
|
+
- Every rule the retired ui practice rules carried sits in a reference, unchanged in wording, with its source row in a ledger beside the reference
|
|
15
|
+
- A rendered change reaches accessibility, keyboard, and state coverage on every read, and the other references by the change that needs them
|
|
16
|
+
- A rendered change that is about to be handed over reaches the capture reference
|
|
17
|
+
- A planning, building, or reviewing role reaches the skill by name, with or without the governance pointer installed
|
|
18
|
+
|
|
19
|
+
## Must not
|
|
20
|
+
|
|
21
|
+
- Reword a moved rule in the move, since a wording change is a separate change with its own ledger row
|
|
22
|
+
- Restate the look, being layout, type, color, or the layer order
|
|
23
|
+
- Be reached only by an author typing its name, since the `craft` pointer rule and the planning, building, and reviewing skills are its callers
|
|
24
|
+
|
|
25
|
+
## Out of scope
|
|
26
|
+
|
|
27
|
+
- How a surface looks, which `design-taste` owns
|
|
28
|
+
- The design folder, its references, and the comparison a pull request shows, which `design-record` and the `design-reference` rule own
|
|
29
|
+
- The visual checklist a reviewer reads, which `ui-checklist` owns
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-craft
|
|
3
|
+
description: Carries the behavior practice for rendered UI, being accessibility, keyboard and pointer operation, forms, motion, controls, state coverage, interface copy, and the capture a rendered change owes, routed from the kind of change to the references it reads. Use before building or changing a component, a page, a form, or any rendered surface, when judging one in review, or when asked "is this accessible", "what states does this need", "how should this form validate", "what should the button say", or "what do I capture after this change". Do NOT use for how a surface looks, being layout, type, color, and the layer order, which is `design-taste`, or for the design folder and its references, which is `design-record`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: build
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# UI craft
|
|
9
|
+
|
|
10
|
+
A rendered change that skips this practice ships a control a keyboard cannot reach, a list with no empty state, or an error that names the fault and never the fix, and none of it fails a build. The references below carry the rules. This body routes a change to the ones it reads.
|
|
11
|
+
|
|
12
|
+
Load this before building rather than after, since a missing state or a trapped focus is cheaper to design in than to retrofit.
|
|
13
|
+
|
|
14
|
+
## Read by the change
|
|
15
|
+
|
|
16
|
+
Read every reference on the always row for any rendered change, then each row the change matches.
|
|
17
|
+
|
|
18
|
+
| The change | Read |
|
|
19
|
+
| ------------------------------------------------------------------ | ------------------------------------- |
|
|
20
|
+
| Any rendered change | `a11y.md`, `keyboard.md`, `states.md` |
|
|
21
|
+
| A click, press, drag, gesture, or popover dismissal | `pointer.md` |
|
|
22
|
+
| A form, a field, validation, or a sign-in step | `forms.md` |
|
|
23
|
+
| An animation, transition, autoplay, or carousel | `motion.md` |
|
|
24
|
+
| A destructive action, an edit cancel, or a hover or disabled state | `controls.md` |
|
|
25
|
+
| A rendered string, heading, label, or link | `copy.md` |
|
|
26
|
+
| A rendered surface has changed and is about to be handed over | `capture.md` |
|
|
27
|
+
|
|
28
|
+
Each name sits under `${CLAUDE_SKILL_DIR}/references/`. A row's reference is read whole, since its sections name the cases a change reaches without saying so.
|
|
29
|
+
|
|
30
|
+
## Hold the floor over taste
|
|
31
|
+
|
|
32
|
+
The references state a floor, and no aesthetic choice trades against it. A contrast ratio, a focus ring, or a state the design leaves out is restored before the look is judged, and `design-taste` decides the look inside that floor.
|
|
33
|
+
|
|
34
|
+
## Sources
|
|
35
|
+
|
|
36
|
+
Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidance or arguing against a rule in it. It names the authorities the references draw on and where each bullet's source row sits.
|
|
37
|
+
|
|
38
|
+
## What this delegates
|
|
39
|
+
|
|
40
|
+
- How a surface looks, being the layer order, the coherence locks, and the defaults a model reaches for: `design-taste`
|
|
41
|
+
- The accepted designs under the design folder and how a reference lands there: `design-record`
|
|
42
|
+
- The visual checklist a reviewer reads beside the screenshots: `ui-checklist`
|
|
43
|
+
- Reading source for roughness a rule does not state: `ux-audit`
|
|
44
|
+
- Prose on the surface beyond its interface copy: the `write-human` skill
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adopted and declined
|
|
3
|
+
description: The authorities the ui-craft references draw on, and where the per-bullet source rows for each reference sit
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adopted and declined
|
|
7
|
+
|
|
8
|
+
Every bullet in a reference has its own source row in a ledger outside the plugin, so this record names the authorities once and points at the rows. A reader arguing against one bullet opens its ledger, and a session extending a reference adds the row there in the same change.
|
|
9
|
+
|
|
10
|
+
## Authorities
|
|
11
|
+
|
|
12
|
+
Each field below names the source its references cite, and a house choice covers a threshold or a scope no source states.
|
|
13
|
+
|
|
14
|
+
- **Web accessibility.** The W3C's [WCAG 2.2](https://www.w3.org/TR/WCAG22/) and the [ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/) back the accessibility, keyboard, pointer, and motion references.
|
|
15
|
+
- **CSS behavior.** [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS) and the CSS specifications back the focus ring, `color-scheme`, and overflow bullets.
|
|
16
|
+
- **Native targets.** Apple's and Android's platform guidelines back the native touch target figures in `pointer.md`.
|
|
17
|
+
- **Forms and copy.** The [GOV.UK Design System](https://design-system.service.gov.uk/) and its style guide back `forms.md` and the copy and casing sections of `copy.md`.
|
|
18
|
+
- **Usability research.** The [Nielsen Norman Group](https://www.nngroup.com/articles/) backs most of `states.md`, part of `controls.md`, and the link sections of `copy.md`.
|
|
19
|
+
- **Capture.** `capture.md` is a house procedure, with its reflow width taken from the WCAG reflow criterion `a11y.md` cites.
|
|
20
|
+
|
|
21
|
+
## Where the rows sit
|
|
22
|
+
|
|
23
|
+
The rows sit in the toolkit's own repository rather than the plugin, one ledger per reference and one table row per bullet under the H2 the bullet sits under. The toolkit's skill audit fails a reference whose bullets and rows disagree in count under any heading, and a target never carries the rows.
|
|
24
|
+
|
|
25
|
+
## Declined
|
|
26
|
+
|
|
27
|
+
Each ledger carries its own `## Declined` list, recording the bullets cut or reworded when the source rules were last rewritten. The move into this skill changed no bullet's wording, so it declined nothing.
|
package/{governance/rules/ui/surface-capture.md → claude/skills/ui-craft/references/capture.md}
RENAMED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Require a capture against a running preview after a rendered surface changes
|
|
3
|
-
paths:
|
|
4
|
-
- '**/routes/**/*.{tsx,jsx,vue,svelte,astro}'
|
|
5
|
-
- '**/pages/**/*.{tsx,jsx,vue,svelte,astro}'
|
|
6
|
-
- '**/app/**/page.{tsx,jsx}'
|
|
7
|
-
- '**/components/**/*.{tsx,jsx,vue,svelte,astro}'
|
|
8
|
-
- '**/*.html'
|
|
9
|
-
---
|
|
10
|
-
|
|
11
1
|
# Surface capture standards
|
|
12
2
|
|
|
13
3
|
## What a surface is
|
package/{governance/rules/ui/ux-controls.md → claude/skills/ui-craft/references/controls.md}
RENAMED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Destructive actions, edit cancel, and element states for interactive controls
|
|
3
|
-
paths:
|
|
4
|
-
- '**/*.tsx'
|
|
5
|
-
- '**/*.jsx'
|
|
6
|
-
- '**/*.astro'
|
|
7
|
-
- '**/*.html'
|
|
8
|
-
- '**/*.css'
|
|
9
|
-
---
|
|
10
|
-
|
|
11
1
|
# UX controls standards
|
|
12
2
|
|
|
13
3
|
## Destructive actions
|
|
@@ -21,5 +11,8 @@ paths:
|
|
|
21
11
|
- Never flash an intermediate state, such as a light frame before a dark theme or a layout jump before data arrives. Reserve the space or settle it first.
|
|
22
12
|
- Say why a control is disabled, in text beside it or a tooltip, and keep it focusable through `aria-disabled` when the reason matters.
|
|
23
13
|
- Declare `color-scheme` on `:root` to match each theme, so scrollbars and form controls follow the theme instead of staying light.
|
|
14
|
+
|
|
15
|
+
## Hover and focus effects
|
|
16
|
+
|
|
24
17
|
- Keep content shown on hover or focus dismissible without moving the pointer, hoverable, and visible until the trigger leaves or the person dismisses it (WCAG 1.4.13).
|
|
25
18
|
- Change no context, such as navigating, submitting, or moving focus, when a control gains focus or changes value, unless the person was told first (WCAG 3.2.1, 3.2.2).
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# UI copy standards
|
|
2
|
+
|
|
3
|
+
## Punctuation
|
|
4
|
+
|
|
5
|
+
- Write no em dash (`—`) or semicolon in rendered copy. Use a comma or a period, or restructure the sentence.
|
|
6
|
+
- Add no trailing punctuation to a button label or a short action string.
|
|
7
|
+
|
|
8
|
+
## Button copy
|
|
9
|
+
|
|
10
|
+
- Label a button with the verb of the action it performs, such as `Save` or `Delete`, never with filler such as `Click to delete`.
|
|
11
|
+
|
|
12
|
+
## Error messages
|
|
13
|
+
|
|
14
|
+
- Tell the person how to fix the error, such as `Enter an email address` over `Email is invalid`.
|
|
15
|
+
- Keep an error message to one short sentence in plain language, with no technical jargon or error codes.
|
|
16
|
+
|
|
17
|
+
## Placeholder text
|
|
18
|
+
|
|
19
|
+
- Never use placeholder text as a label, a hint, or an example. Put a format example such as `name@example.com` in hint text under the label.
|
|
20
|
+
|
|
21
|
+
## Sentence case
|
|
22
|
+
|
|
23
|
+
- Use sentence case for rendered headings, labels, nav items, tab titles, and dialog titles, since title case on every heading reads as a template default.
|
|
24
|
+
- Keep the original casing of a proper noun or product name, such as `GitHub`, `macOS`, or `TypeScript`.
|
|
25
|
+
|
|
26
|
+
## Uppercase labels
|
|
27
|
+
|
|
28
|
+
- Keep small uppercase labels above headings to `ceil(sections / 3)`, the first screen counting as one. Delete the extra labels, since position already names a section.
|
|
29
|
+
|
|
30
|
+
## Where it applies
|
|
31
|
+
|
|
32
|
+
- Apply the same casing to interface copy kept outside the globs, such as a locale file, which this rule never fires on.
|
|
33
|
+
|
|
34
|
+
## Overriding
|
|
35
|
+
|
|
36
|
+
- Depart from sentence case only where the case needs it, such as an acronym, a brand mark, or a set-in-caps identity the design chose on purpose.
|
|
37
|
+
|
|
38
|
+
## Default target
|
|
39
|
+
|
|
40
|
+
- Open a link in the same tab. Reserve `target="_blank"` for a page the person must consult while finishing a task in the current one.
|
|
41
|
+
- Never add `target="_blank"` as a default for every external link.
|
|
42
|
+
|
|
43
|
+
## mailto: links
|
|
44
|
+
|
|
45
|
+
- Open a `mailto:` link in the same tab. It hands off to the mail client rather than replacing the page, so a new tab leaves an empty tab behind.
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Focus styles, keyboard operation, composite widgets, and focus management for rendered UI
|
|
3
|
-
paths:
|
|
4
|
-
- '**/*.tsx'
|
|
5
|
-
- '**/*.jsx'
|
|
6
|
-
- '**/*.astro'
|
|
7
|
-
- '**/*.html'
|
|
8
|
-
- '**/*.css'
|
|
9
|
-
---
|
|
10
|
-
|
|
11
1
|
# Keyboard and focus standards
|
|
12
2
|
|
|
13
3
|
## Focus styles
|
|
@@ -36,7 +36,7 @@ For each surface, look for:
|
|
|
36
36
|
3. **Inconsistencies**: spacing, tone of voice, interaction patterns, icon use, keyboard affordances
|
|
37
37
|
4. **Roughness in daily use**: friction, redundant steps, unclear affordances, ambiguous labels
|
|
38
38
|
|
|
39
|
-
Use `canon/DESIGN.md` as ground truth for intent where it exists. Observations only, no implementation suggestions or fixes. Take what consistent interaction means from the `ui`
|
|
39
|
+
Use `canon/DESIGN.md` as ground truth for intent where it exists. Observations only, no implementation suggestions or fixes. Take what consistent interaction means from the `ui-craft` skill's references.
|
|
40
40
|
|
|
41
41
|
Where Step 1 found a committed capture for this surface, judge composed output (spacing, overlap, contrast, wrapping) against it rather than inferring layout from markup. Where none exists, judge from source and say so in that surface's findings, since a source read cannot see what only a render shows.
|
|
42
42
|
|
|
@@ -5,7 +5,10 @@ description: Which external writing patterns this skill adopted, which it declin
|
|
|
5
5
|
|
|
6
6
|
# Source material
|
|
7
7
|
|
|
8
|
-
Two external writing skills were read as source material for this one.
|
|
8
|
+
Two external writing skills were read as source material for this one.
|
|
9
|
+
|
|
10
|
+
- **[humanizer](https://github.com/blader/humanizer)** catalogs 31 patterns of machine-sounding prose
|
|
11
|
+
- **An unidentified second skill** layers document mode, sentence construction, information density, and ambiguity prevention. No record of the read named it, so it carries no link.
|
|
9
12
|
|
|
10
13
|
Neither was imported wholesale, and one measurement settles why. Read this before adding a rule from outside this corpus, and extend the position below rather than deriving a second one.
|
|
11
14
|
|
package/docs/agents/audits.md
CHANGED
|
@@ -57,18 +57,15 @@ An audit that finds no corpus reports `absent`, which moves neither the verdict
|
|
|
57
57
|
|
|
58
58
|
**In `bun run check`.**
|
|
59
59
|
|
|
60
|
-
`bun run check` runs `--corpus tracked --corpus per-machine` as a reporting stage after the gating stages, and never fails on it. `summary` is a flat object of unique scalar keys that a shell stage greps without a JSON parser. `deps` runs weekly instead.
|
|
61
|
-
|
|
62
|
-
The placement entry runs pinned to `--backend off`, so its tally stays comparable across machines. Each audit runs as the CLI the caller is running, never a global `canon`.
|
|
60
|
+
`bun run check` runs `--corpus tracked --corpus per-machine` as a reporting stage after the gating stages, and never fails on it. `summary` is a flat object of unique scalar keys that a shell stage greps without a JSON parser. `deps` runs weekly instead. Each audit runs as the CLI the caller is running, never a global `canon`.
|
|
63
61
|
|
|
64
62
|
**Catalog.**
|
|
65
63
|
|
|
66
|
-
`canon audits list` reports the first
|
|
64
|
+
`canon audits list` reports the first 18 rows. The rows marked `outside` run by hand or from a skill and sit beside the aggregate.
|
|
67
65
|
|
|
68
66
|
| Id | Verb | Measures | Finding |
|
|
69
67
|
| -------------------- | ----------------------------------- | ---------------------------------------------------------------------------------- | -------------- |
|
|
70
68
|
| `context` | `canon context audit` | Context folder structure, citations, and the requirements record's word cap | Gates |
|
|
71
|
-
| `placement` | `canon context classify sweep` | Keep, rewrite, and move tally per context section, regex layer only | Reports |
|
|
72
69
|
| `markdown` | `canon markdown audit` | Bans, dead links, density, and reference shape | Gates |
|
|
73
70
|
| `skills` | `canon claude skills audit` | Both skill corpora against the skill standards | Gates |
|
|
74
71
|
| `skills-reach` | `canon claude skills reach` | Skill bodies citing a path no target receives | Reports |
|
|
@@ -90,7 +87,6 @@ The placement entry runs pinned to `--backend off`, so its tally stays comparabl
|
|
|
90
87
|
| `outside` | `canon gov superseded <old> <new>` | Where the tree still asserts a value a changed convention no longer produces | Reports |
|
|
91
88
|
| `outside` | `canon claude skills drift <ref>` | Shipped skill bodies rewritten since a ref | Reports |
|
|
92
89
|
| `outside` | `canon claude routing` | Per `CLAUDE.md` section, how many bullets name a path and whether a rule covers it | Reports |
|
|
93
|
-
| `outside` | `canon context classify diff` | Classification of the chunks a git range changed | Reports |
|
|
94
90
|
|
|
95
91
|
A deliberate secret takes a `canon-allow-secret: <reason>` marker. A deliberate citation takes `canon-allow-citation: <reason>` and a deliberate superseded value takes `canon-allow-superseded: <reason>`, each on its own line or the one above. Run any verb with `--help` for its flags and refusal reasons.
|
|
96
92
|
|
|
@@ -62,7 +62,7 @@ The exit code follows the mode the run took. The bullets cover where the gate ru
|
|
|
62
62
|
- A root resolving no audited folder refuses with `1` and warns, a root measuring no entry warns, and a seed short a section fails with `2`
|
|
63
63
|
- A seed omitting a required section on purpose sets `stub: true` in its frontmatter. Only the value `true` counts, and both install paths strip the field.
|
|
64
64
|
|
|
65
|
-
The citation check skips fenced blocks, fixture and harness trees including `*.test.ts`, and a path into a folder the project lacks.
|
|
65
|
+
The citation check skips fenced blocks, fixture and harness trees including `*.test.ts`, the install stamp at any of its spellings, and a path into a folder the project lacks.
|
|
66
66
|
|
|
67
67
|
Append `<!-- audit-ignore-citations: <path> -->` to a line that displays a path without pointing at it. The marker excuses only the paths it names, and a bare `<!-- audit-ignore-citations -->` excuses every citation on the line. In seeds, plugin skill bodies, and stack references, which install into a target, reword the line instead.
|
|
68
68
|
|
|
@@ -62,11 +62,11 @@ After a rename the new name shows as `missing` when the stamp records a stack, a
|
|
|
62
62
|
|
|
63
63
|
## Tooling
|
|
64
64
|
|
|
65
|
-
- `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference
|
|
65
|
+
- `canon tooling diff <stack> [target]` is the read-only comparison, exiting 1 on any difference, and it reads a dependency on a later major than the stack pins as `ahead`, which counts as no change
|
|
66
66
|
- A `--json` refusal answers `{ ok: false, reason, message }`, so branch on the record
|
|
67
67
|
- `withheld` entries are `{ rel, stack, present }`, hold every `.github/` file below the git root, and count toward no exit
|
|
68
68
|
- `present` marks a copy an earlier sync left, which is reported and never deleted
|
|
69
|
-
- `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1.
|
|
69
|
+
- `canon tooling sync <stack> [target]` writes only under `--write`. `--check` reports and exits 0, and a headless run with neither flag exits 1. It never installs over an `ahead` dependency.
|
|
70
70
|
|
|
71
71
|
### Drift cause and the write hold
|
|
72
72
|
|
|
@@ -187,12 +187,12 @@ A web project's `e2e/screenshot.ts` is a config. It now loads `CASES` from a see
|
|
|
187
187
|
- Evidence now defaults to `e2e/evidence/`. Set `export const EVIDENCE_ROOT = 'evidence'` in `e2e/capture/cases.ts` to keep a committed baseline at the old path.
|
|
188
188
|
- A run from a folder with no `e2e/capture/cases.ts` exits 1 and names the file.
|
|
189
189
|
|
|
190
|
-
##
|
|
190
|
+
## Fold the ui rules onto one pointer, once
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
Eleven ui rules moved unchanged into the `ui-craft` skill, being `a11y`, `keyboard`, `pointer`, `forms`, `motion`, `ux-controls`, `ux-completeness`, `surface-capture`, `copy`, `interface-casing`, and `link-behavior`. Update the plugin, then sync, which folds each one you hold and `design-taste.md` onto one `craft.md` pointer without local edits.
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
canon gov
|
|
195
|
+
canon gov sync .
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
## Group a long paths section in `CLAUDE.md`, once
|
package/docs/target/sync.md
CHANGED
|
@@ -45,6 +45,7 @@ Add `--json` for a machine-readable report and `--exit-code` to fail CI when a t
|
|
|
45
45
|
- Seed docs such as `CLAUDE.md` and `canon/REQUIREMENTS.md`: merge by hand, keeping the project's customizations
|
|
46
46
|
- Installed governance rules: `canon gov sync <path>`, which adds no new rules and reports coverage afterward
|
|
47
47
|
- Tooling configs and seeds: read differences with `canon tooling diff <stack> <path>`, then `canon tooling sync <stack> <path> --write`, which holds an edited config and copies each seed once
|
|
48
|
+
- Tooling dependencies: a dependency on a later major than the stack pins reads as `ahead`, and sync leaves it
|
|
48
49
|
- Index regeneration: `canon indexes regen`
|
|
49
50
|
|
|
50
51
|
After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:ux-audit`. `--json` writes `{ "coverage": [{ "rule", "paths", "files", "ui" }] }` to stdout, empty when nothing was copied, with `files` null outside git. The report never changes the exit code.
|
|
@@ -59,13 +60,13 @@ A project can also opt out of one golden file without leaving the stack. Each ve
|
|
|
59
60
|
|
|
60
61
|
```bash
|
|
61
62
|
canon tooling decline .github/workflows/readme-screenshot.yml --reason "no screenshots here"
|
|
62
|
-
canon tooling customize e2e/
|
|
63
|
+
canon tooling customize e2e/screenshot.ts
|
|
63
64
|
canon tooling lift .github/workflows/readme-screenshot.yml
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
- `decline` keeps sync and inject from writing the file again, and leaves a copy the project still holds in place
|
|
67
68
|
- `customize` keeps the project's copy of a config through every write, and `diff` exits 1 once the stack ships a newer golden copy
|
|
68
|
-
- A seed cannot be customized, since sync never overwrites one
|
|
69
|
+
- A seed cannot be customized, since sync never overwrites one, and the starter `e2e/home.spec.ts` is one
|
|
69
70
|
- `lift` hands the file back, so the next sync writes it
|
|
70
71
|
|
|
71
72
|
These verbs are the only writers of the record in `canon/config/config.json`, so never edit it there by hand.
|
|
@@ -45,6 +45,7 @@ Groups run in the order a project meets them. Every name `canon claude skills li
|
|
|
45
45
|
| `canon:search-craft` | Before searching outside the project |
|
|
46
46
|
| `canon:systematic-debugging` | A test fails or a bug surfaces |
|
|
47
47
|
| `canon:design-taste` | Drafting or judging an interface |
|
|
48
|
+
| `canon:ui-craft` | Building or judging a component's behavior |
|
|
48
49
|
| `canon:ui-checklist` | After a UI change, to list what to check |
|
|
49
50
|
|
|
50
51
|
## Check the work before it leaves the branch
|
|
@@ -19,8 +19,8 @@ Canon runs a UI feature through one loop. A plan cites the design, a worker buil
|
|
|
19
19
|
|
|
20
20
|
The worker opens each cited reference, light and dark, before its first edit to that surface. It takes sizes, spacing, and colors from the frame HTML rather than the image, and reports a reference that does not resolve instead of building without it.
|
|
21
21
|
|
|
22
|
-
- The
|
|
23
|
-
- The `
|
|
22
|
+
- The `craft` rule fires on the files the worker edits and loads `ui-craft` for behavior and `design-taste` for look.
|
|
23
|
+
- The `ui-craft` capture reference has the worker capture the full page in every theme the surface ships, against a preview server and never a dev server.
|
|
24
24
|
- It sets the widths too, being 320 plus each breakpoint in `canon/DESIGN.md` for a layout case, and one width for a state case.
|
|
25
25
|
|
|
26
26
|
## Self-check
|
package/governance/detect.toml
CHANGED
|
@@ -160,54 +160,10 @@ deps = [
|
|
|
160
160
|
]
|
|
161
161
|
files = ["**/migrations", "**/schema.prisma", "**/*.sql"]
|
|
162
162
|
|
|
163
|
-
["
|
|
164
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
165
|
-
files = ["index.html", "*/index.html"]
|
|
166
|
-
|
|
167
|
-
["a11y"]
|
|
168
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
169
|
-
files = ["index.html", "*/index.html"]
|
|
170
|
-
|
|
171
|
-
["keyboard"]
|
|
172
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
173
|
-
files = ["index.html", "*/index.html"]
|
|
174
|
-
|
|
175
|
-
["pointer"]
|
|
176
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
177
|
-
files = ["index.html", "*/index.html"]
|
|
178
|
-
|
|
179
|
-
["forms"]
|
|
180
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
181
|
-
files = ["index.html", "*/index.html"]
|
|
182
|
-
|
|
183
|
-
["ux-completeness"]
|
|
184
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
185
|
-
files = ["index.html", "*/index.html"]
|
|
186
|
-
|
|
187
|
-
["ux-controls"]
|
|
188
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
189
|
-
files = ["index.html", "*/index.html"]
|
|
190
|
-
|
|
191
|
-
["surface-capture"]
|
|
192
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
193
|
-
files = ["index.html", "*/index.html"]
|
|
194
|
-
|
|
195
|
-
["link-behavior"]
|
|
196
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
197
|
-
files = ["index.html", "*/index.html"]
|
|
198
|
-
|
|
199
|
-
["design-taste"]
|
|
163
|
+
["craft"]
|
|
200
164
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
201
165
|
files = ["canon/DESIGN.md", "index.html", "*/index.html"]
|
|
202
166
|
|
|
203
|
-
["interface-casing"]
|
|
204
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
205
|
-
files = ["index.html", "*/index.html"]
|
|
206
|
-
|
|
207
|
-
["motion"]
|
|
208
|
-
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
209
|
-
files = ["index.html", "*/index.html"]
|
|
210
|
-
|
|
211
167
|
["design-reference"]
|
|
212
168
|
deps = []
|
|
213
169
|
files = ["canon/design/*/"]
|
|
@@ -25,7 +25,7 @@ The field is browser test automation, and the authority is the Playwright docume
|
|
|
25
25
|
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
26
26
|
| A script, not the suite | House choice: a suite run answers a question about the page only through assertions written for another question, and costs the whole run | 2026-10-18 |
|
|
27
27
|
| No `fullyParallel` | [Parallelism](https://playwright.dev/docs/test-parallel): by default "Tests in a single file are run in order, in the same worker process", and parallel tests "cannot share any state or global variables" | 2026-10-18 |
|
|
28
|
-
| Pointer to `
|
|
28
|
+
| Pointer to `ui-craft` | House choice: a pointer to the skill that owns capture scope, claiming no practice of its own | 2026-10-18 |
|
|
29
29
|
| Pointer to `e2e-reliability` | House choice: a pointer to the rule that owns waits and guards, claiming no practice of its own | 2026-10-18 |
|
|
30
30
|
|
|
31
31
|
## Declined
|