@erclx/canon 4.94.0 → 4.95.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/SKILL.md +1 -1
- package/claude/skills/review-pr/REQUIREMENT.md +1 -0
- package/claude/skills/review-pr/SKILL.md +2 -0
- package/claude/skills/ui-test/REQUIREMENT.md +7 -2
- package/claude/skills/ui-test/SKILL.md +26 -16
- package/docs/workflow/ai-workflow.md +3 -3
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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
|
-
-
|
|
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:
|
|
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
|
|
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
|
|
32
|
+
Write Playwright tests for journeys and browser-only behavior only. Follow these rules:
|
|
24
33
|
|
|
25
|
-
-
|
|
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
|
|
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
|
|
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
|
|
63
|
+
If every change is covered by a test, skip the manual checklist:
|
|
55
64
|
|
|
56
|
-
`✅ All changes covered by
|
|
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
|
|
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
|
|
73
|
-
2.
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|