@erclx/canon 4.94.0 → 4.96.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.
@@ -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.94.0",
4
+ "version": "4.96.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -123,7 +123,7 @@ If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`),
123
123
 
124
124
  If `ui-test` produces a manual checklist, stop: `❌ UI requires visual verification. Checklist at .canon/tmp/handoff/ui-checklist/<slug>.md, which reaches the pull request once /git-ship runs. Verify manually, then run /git-ship.`
125
125
 
126
- If all UI changes are covered by e2e tests, continue.
126
+ If all UI changes are covered by tests, continue.
127
127
 
128
128
  ## Step 6: review
129
129
 
@@ -20,6 +20,7 @@ A request written under `## For the reviewer` also reached no reader. The author
20
20
  - Detect the pass from the thread rather than taking it from the caller, matching the heading for equality so a neighboring comment cannot be read as a prior pass
21
21
  - Scope a later pass to the commits added since the prior one, once that commit is confirmed to still reach the head
22
22
  - Apply the integration, contract, and consumer lenses a self-review structurally cannot
23
+ - Read each test the branch added or changed against `canon:test-craft`'s final filter, scoped to those files and never the suite
23
24
  - Post the closing pass even with nothing to report, since a review left unanswered reads as one nobody closed
24
25
  - State a withdrawal or a regrade on the thread with the fact that settled it, since a finding dropped in silence reads the same as one nobody answered
25
26
  - Key the body file on the pull request number and the head commit, and on the response it answers once the head repeats, so no two passes overwrite each other
@@ -135,6 +135,8 @@ Review the diff and files for the same axes as `review-branch` (bugs, edge cases
135
135
  - Contract: does a contract downstream features depend on land correctly, and should the plan itself be questioned?
136
136
  - Consumers: when the change touches a resource with more than one consumer, enumerate them and check the rule against each. A rule written for the consumer the change targets can be wrong for a sibling that writes.
137
137
 
138
+ Read each test file the branch added or changed against the final filter in `canon:test-craft`, which owns what the filter asks. Scope it to those files rather than the suite. A fixed-pause wait is a `should-fix`, since the end to end rules already forbid it, and a test sitting at a higher layer than it needs is `minor` unless it is flaky or slows the gate measurably. Report it rather than proceeding silently when the skill does not resolve.
139
+
138
140
  Then read the description's `## Testing` section, which is the one part of a pull request body this session is positioned to falsify. The branch author cannot see what a sibling branch drove the same day, and the arm list is what settles the claim rather than the diff.
139
141
 
140
142
  Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/../../standards/pr.md`, which reserves an unchecked box for a capability the agent lacks. Raise the box when it names no human at all, when the human it names is a live agent session, or when it names a person for a step the repository ships a harness for, `scripts/sandbox/run.sh` and `scripts/eval/run.sh` being the two. Cost alone is not an answer, since authorizing a spend is the operator's and performing the run is not. A refusal the author actually met is an answer, and it names which one.
@@ -9,13 +9,17 @@ description: Why UI changes split into what a browser can assert and what only a
9
9
 
10
10
  Without this skill, UI work ships on the confidence of the session that wrote it. What verification does happen mixes the two kinds without noticing, so a checklist item about spacing sits beside one about a form submission, and neither is done properly because they need different work from different people. Tests get written against a config the project does not use, or duplicate what a component test already covers.
11
11
 
12
+ The automatable half fails the other way. Sending every interaction, state, and form to Playwright leaves the layers unrouted, so a loading state lands in a full browser run and the end to end suite grows on each UI change. A state a component test reaches costs a browser to check, and the cost recurs on every later run.
13
+
12
14
  The visual half is where the record is lost. A checklist printed into chat scrolls away before anyone verifies it, so the ship step has nothing to gate on and the work reads as verified because a list was produced. Written from a linked worktree against `pwd`, the file lands where the caller does not look.
13
15
 
14
16
  Writing the checklist correctly to disk does not close the gap either. The file sits under a gitignored folder on the machine that authored it, so a pull request reviewer, on that machine or another, never sees it. A record that only the author can open reads as verified for the same reason a record that never existed does.
15
17
 
16
18
  ## Must
17
19
 
18
- - Split every change into automatable and visual-only before writing anything
20
+ - Split every change into visual-only and automatable before writing anything, then route each automatable one to its layer through `test-craft`
21
+ - Write end to end only for a journey or a behavior only a real browser renders, and component or unit tests for the rest
22
+ - Name a missing component runner in the output and put the state on the checklist
19
23
  - Read the project's existing test config and patterns before writing a test against them
20
24
  - Assert a user action and its outcome per test, covering the happy path and the key edge cases
21
25
  - Run the tests after writing them and fix what fails
@@ -26,6 +30,7 @@ Writing the checklist correctly to disk does not close the gap either. The file
26
30
 
27
31
  - Try to assert a visual property programmatically
28
32
  - Re-test what unit or component tests written during implementation already cover
33
+ - Route a state a component test reaches into end to end, or fall back to end to end silently when no runner exists
29
34
  - Repeat the full checklist in chat, which is what made it evaporate
30
35
  - Stage or commit the checklist, which is gitignored scratch
31
36
  - Talk to GitHub directly. Posting the checklist to a pull request belongs to `git-pr`, the sole consumer of the handoff file
@@ -38,6 +43,6 @@ Writing the checklist correctly to disk does not close the gap either. The file
38
43
  ## Out of scope
39
44
 
40
45
  - Judging whether the UI is any good, which `ux-audit` owns
41
- - Unit and component tests, which belong to implementation
46
+ - The rules for choosing a layer, which `test-craft` owns
42
47
  - Deciding whether an outstanding checklist blocks the ship, which the calling pipeline gates on
43
48
  - Performing the visual verification, which needs a person
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ui-test
3
- description: Generates and runs Playwright e2e tests for UI changes, with a manual checklist for visual-only items. Use after implementing UI changes, or when asked "what should I test", "what do I verify", or "give me a test checklist". Do NOT use in empty sessions with no implementation context.
3
+ description: Routes each UI change to the test layer that can catch its break, writes end to end tests only for journeys and browser-only behavior, and produces a manual checklist for visual-only items. Use after implementing UI changes, or when asked "what should I test", "what do I verify", or "give me a test checklist". Do NOT use in empty sessions with no implementation context.
4
4
  ---
5
5
 
6
6
  # UI test
@@ -8,26 +8,35 @@ description: Generates and runs Playwright e2e tests for UI changes, with a manu
8
8
  ## Guards
9
9
 
10
10
  - If no implementation context exists in the session, stop: `❌ No implementation context. Describe what you built first.`
11
+ - Load `canon:test-craft` before writing any test, and report it rather than proceeding silently when it does not resolve.
11
12
 
12
13
  ## Analysis
13
14
 
14
- Review the session to identify what was built or changed. Categorize each change:
15
+ Review the session to identify what was built or changed. Categorize each change, then route it:
15
16
 
16
- - **Automatable:** interactions, state transitions, form submissions, keyboard navigation, conditional rendering, error states, empty states, loading states. These become Playwright e2e tests.
17
17
  - **Visual-only:** spacing, alignment, color, typography, layout proportions, animation timing. These become a manual checklist.
18
+ - **Journey or browser-only:** a flow across routes, a route change, or a behavior only a real browser renders, such as scroll, focus order across pages, or layout. These become end to end tests.
19
+ - **Everything else:** interactions, state transitions, form submissions, keyboard handling, conditional rendering, loading, empty, and error states. Route these through the `test-craft` layer table to a component test, or to a unit test when the logic renders nothing.
18
20
 
19
- Exclude anything already covered by unit or component tests written during implementation.
21
+ Never write an end to end test for a state a component test reaches. Exclude anything already covered by tests written during implementation.
22
+
23
+ ## Component and unit tests
24
+
25
+ - Read the project's test config and an existing test at the layer first, and follow its runner, suffix, and placement.
26
+ - Read the `test-craft` component reference before the first component test.
27
+ - Assert each state through what a user sees or does, covering the happy path and the key edges.
28
+ - When the project has no component runner, write the checklist item for that state instead of an end to end test, and name the missing runner in the output. Do not fall back to end to end silently.
20
29
 
21
30
  ## E2e tests
22
31
 
23
- Write Playwright tests for all automatable changes. Follow these rules:
32
+ Write Playwright tests for journeys and browser-only behavior only. Follow these rules:
24
33
 
25
- - Add tests to the existing e2e test file. If none exists, create `e2e/ui.test.ts`.
34
+ - Read the `test-craft` end to end reference before the first one.
35
+ - Add tests to the project's existing `e2e/` layout and naming. If none exists, create `e2e/<feature>.spec.ts`.
26
36
  - Use the project's existing Playwright config and test patterns. Read them first.
27
- - Each test should perform a user action and assert the expected outcome.
28
- - Cover both happy path and key edge cases (empty state, error state, boundary input).
37
+ - Each test performs a user action across the journey and asserts the expected outcome.
29
38
  - For Chrome extensions: load the unpacked extension via Playwright's `--load-extension` flag and use the extension's sidepanel or popup URL as the test target.
30
- - Run the tests after writing them. Fix failures before finishing.
39
+ - Run every test written, at every layer. Fix failures before finishing.
31
40
 
32
41
  Test structure:
33
42
 
@@ -41,7 +50,7 @@ test('description of user flow', async ({ page }) => {
41
50
 
42
51
  ## Manual checklist
43
52
 
44
- For visual-only items that cannot be asserted programmatically, produce a checklist. Group by feature area. Use `- [ ]` checkbox syntax.
53
+ For visual-only items that cannot be asserted programmatically, and for any state left without a runner, produce a checklist. Group by feature area. Use `- [ ]` checkbox syntax.
45
54
 
46
55
  ```markdown
47
56
  **What to verify visually:**
@@ -51,9 +60,9 @@ For visual-only items that cannot be asserted programmatically, produce a checkl
51
60
  - [ ] <action> → <expected visual result>
52
61
  ```
53
62
 
54
- If all changes are automatable, skip the manual checklist:
63
+ If every change is covered by a test, skip the manual checklist:
55
64
 
56
- `✅ All changes covered by e2e tests. No manual verification needed.`
65
+ `✅ All changes covered by tests. No manual verification needed.`
57
66
 
58
67
  ### Persist the checklist
59
68
 
@@ -63,15 +72,16 @@ When a manual checklist is produced, write it directly to `.canon/tmp/handoff/ui
63
72
 
64
73
  From a linked worktree the file-editing tools refuse that path, so the checklist goes out through `Bash`. Send the `mkdir -p` and the heredoc as two plain commands rather than joining them with `&&`, which is refused as compound.
65
74
 
66
- Skip the file write when all changes are covered by e2e tests and no checklist was produced.
75
+ Skip the file write when every change is covered by tests and no checklist was produced.
67
76
 
68
77
  The `.canon/tmp/` directory is gitignored. Do not stage or commit the file.
69
78
 
70
79
  ## Output order
71
80
 
72
- 1. Write and run e2e tests (report pass/fail)
73
- 2. If a manual checklist was produced, write it to file, then output only the file path in chat:
81
+ 1. Write and run the tests, naming each one's layer (report pass/fail)
82
+ 2. Name any state left to the checklist for want of a component runner
83
+ 3. If a manual checklist was produced, write it to file, then output only the file path in chat:
74
84
  `📝 Wrote .canon/tmp/handoff/ui-checklist/<slug>.md`
75
- 3. If no checklist was needed: `✅ All changes covered by e2e tests. No manual verification needed.`
85
+ 4. If no checklist was needed: `✅ All changes covered by tests. No manual verification needed.`
76
86
 
77
87
  Do not repeat the full checklist in chat.
@@ -58,7 +58,7 @@ Work in Claude Code directly. It reads `CLAUDE.md` automatically and has full fi
58
58
  - When the current state is unmeasured and more than one approach is live, invoke `canon:plan-groundwork` first. It opens a track folder under `.canon/groundwork/<nn>-<slug>/` and ends in a decision, which may be to do nothing. Skip it when the approach is already settled.
59
59
  - Invoke `canon:plan-feature` to scan for code-level conflicts and ambiguities, confirm approach before proceeding
60
60
  - Implement the feature, then Claude Code runs the commands defined in `CLAUDE.md`, fixes failures, and iterates until all pass
61
- - For UI changes, invoke `canon:ui-test` to generate and run Playwright e2e tests
61
+ - For UI changes, invoke `canon:ui-test` to route each change to its test layer and run the tests it writes, with Playwright kept for journeys
62
62
  End the session once the feature works and tests pass. Invoke `canon:docs-fold` to capture any decisions made during implementation before closing.
63
63
 
64
64
  The routing test is whether the repository can answer an item today. A session grepping handles the yes, and a groundwork track handles the no.
@@ -174,7 +174,7 @@ The receipt is collected once every item on it has been decided, and it survives
174
174
 
175
175
  ### UI polish
176
176
 
177
- Verify the change manually in the browser. Invoke `canon:ui-test` if you need e2e tests and a visual verification checklist for the session. For the fix itself, describe the change in Claude Code directly.
177
+ Verify the change manually in the browser. Invoke `canon:ui-test` if you need tests at the right layer and a visual verification checklist for the session. For the fix itself, describe the change in Claude Code directly.
178
178
 
179
179
  ### Quick fix
180
180
 
@@ -234,7 +234,7 @@ This section is the corpus the coverage claim is measured against: every name `c
234
234
  | `canon:test-first` | Before implementing a planned change, to run its test red, green, then refactor |
235
235
  | `canon:test-craft` | When writing or changing any test, to pick its layer and filter what it asserts |
236
236
  | `canon:systematic-debugging` | When a test fails or a bug surfaces, to force root cause first |
237
- | `canon:ui-test` | After a UI change, to generate e2e tests and a visual checklist |
237
+ | `canon:ui-test` | After a UI change, to generate layered tests and a visual checklist |
238
238
 
239
239
  ### Check the work before it leaves the branch
240
240
 
@@ -31,13 +31,13 @@ A cell no source anchors ends in `? verify`, and the preview shows that marker b
31
31
  ### Tools
32
32
 
33
33
  - None beyond Claude Code itself
34
- - Playwright CLI optional for verifying form submissions and interactive surfaces. See [`ui-test`](../../claude/skills/ui-test/SKILL.md).
34
+ - Playwright CLI optional for verifying journeys across routes and browser-only behavior. See [`ui-test`](../../claude/skills/ui-test/SKILL.md).
35
35
 
36
36
  ### Skills
37
37
 
38
38
  - `canon:sketch-design` to trace a design direction from reference images or URLs, before `design-extract`'s greenfield path proposes from a personality paragraph alone
39
39
  - `canon:design-extract` to draft `canon/DESIGN.md`, from existing project signals or from requirements alone on day one
40
- - `canon:ui-test` for e2e test generation after UI changes
40
+ - `canon:ui-test` for layered test generation after UI changes
41
41
  - `canon:ux-audit` for UX gap detection on existing surfaces
42
42
  - `canon:ux-measure` for what a running surface costs to paint, read against published thresholds
43
43
  - `canon:draft-and-pick` for a call settled by looking, drafting several candidates onto one page and taking your pick
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "4.94.0",
4
+ "version": "4.96.0",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {