@erclx/canon 5.41.0 → 5.43.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/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +24 -4
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
- package/claude/skills/ci-workflow/SKILL.md +12 -2
- package/claude/skills/ci-workflow/references/workflows.md +12 -9
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +10 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/decision-escalate/SKILL.md +1 -2
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +55 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-doc/references/wiki.md +1 -1
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +9 -5
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +29 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +58 -21
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
- package/claude/skills/pr-evidence/SKILL.md +53 -0
- package/claude/skills/pr-evidence/references/evidence.md +150 -0
- package/claude/skills/review-address/references/post-review-findings.md +10 -3
- package/claude/skills/review-address/references/rebase-conflicts.md +15 -7
- package/claude/skills/review-address/references/rest-reads.md +3 -1
- package/claude/skills/review-craft/references/adopted.md +35 -18
- package/claude/skills/review-craft/references/security.md +42 -7
- package/claude/skills/review-craft/references/ui.md +23 -8
- package/claude/skills/review-pr/SKILL.md +6 -6
- package/claude/skills/review-pr/references/body-variants.md +29 -9
- package/claude/skills/review-pr/references/close-out.md +20 -5
- package/claude/skills/review-pr/references/key-changes.md +27 -3
- package/claude/skills/review-pr/references/post.md +83 -31
- package/claude/skills/review-pr/references/scope.md +54 -19
- package/claude/skills/review-ui/references/close-out.md +7 -5
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -15
- package/claude/skills/role-orchestrator/SKILL.md +2 -0
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -40
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +16 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +3 -3
- package/claude/skills/role-worker/REQUIREMENT.md +3 -0
- package/claude/skills/role-worker/SKILL.md +34 -2
- package/claude/skills/search-craft/REQUIREMENT.md +1 -1
- package/claude/skills/search-craft/SKILL.md +2 -2
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/agents/audits.md +1 -0
- package/docs/agents/migrate.md +11 -8
- package/docs/target/migrations.md +11 -0
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/governance/detect.toml +4 -0
- package/governance/rules/canon/context.md +2 -1
- package/governance/rules/canon/plan.md +3 -5
- package/governance/rules/canon/scratch.md +3 -1
- package/governance/rules/canon/task-scope.md +2 -1
- package/governance/rules/canon/tasks.md +2 -1
- package/governance/rules/canon/worktrees.md +5 -2
- package/governance/rules/claude/output.md +7 -4
- package/governance/rules/claude/skill.md +6 -4
- package/governance/rules/tooling/ci-workflow.md +6 -39
- package/governance/rules/ui/design-reference.md +37 -0
- package/governance/rules/writing/markdown.md +2 -1
- package/package.json +6 -6
- package/src/audits/catalog.ts +42 -0
- package/src/claude/cases/workflow.ts +5 -0
- package/src/claude/settings.ts +8 -4
- package/src/commands/claude.ts +11 -1
- package/src/commands/gov.ts +198 -0
- package/src/commands/migrate.ts +121 -2
- package/src/commands/pr.ts +146 -105
- package/src/commands/tooling.ts +3 -3
- package/src/commands/worktrees.ts +49 -0
- package/src/gate/stages.ts +15 -0
- package/src/gov/audit.ts +440 -0
- package/src/listeners/belongs.ts +21 -0
- package/src/listeners/machine.ts +93 -0
- package/src/listeners/parse.ts +41 -0
- package/src/markdown/scope.ts +144 -0
- package/src/migrate/session-defaults.ts +138 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/local.ts +4 -69
- package/src/pr/review-state.ts +182 -0
- package/src/sync/check.ts +15 -0
- package/src/tooling/stamp.ts +56 -12
- package/src/worktrees/stop.ts +92 -0
- package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
- package/tooling/base/configs/commitlint.config.js +0 -20
- package/tooling/base/reference.md +1 -1
- package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
- package/tooling/claude/reference.md +13 -7
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- package/tooling/claude/user/settings.template.json +0 -4
- package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
- package/tooling/public/configs/.github/dependabot.yml +12 -0
- package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
- package/tooling/public/manifest.toml +8 -0
- package/tooling/public/reference.md +53 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
- package/tooling/public/seeds/.release-please-manifest.json +3 -0
- package/tooling/public/seeds/CONTRIBUTING.md +50 -0
- package/tooling/public/seeds/LICENSE +21 -0
- package/tooling/public/seeds/SECURITY.md +13 -0
- package/tooling/public/seeds/release-please-config.json +12 -0
- package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
- package/tooling/web/configs/.github/workflows/verify.yml +15 -12
- package/claude/skills/git-pr/references/evidence.md +0 -124
|
@@ -7,23 +7,29 @@ description: How teach-workspace's fold mode lands each page a teach promotion h
|
|
|
7
7
|
|
|
8
8
|
The fold mode of `teach-workspace`, run from a branch in a worktree. The session reads this file when the invocation asks to fold confirmed promotions in.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Read the handoff
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`, falling back to `latest` on an empty result, and read `.canon/tmp/handoff/teach-promotion/<slug>.md` at the main worktree root.
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
14
|
+
- `teach-workspace` writes it, one H2 per destination naming the path, a source line under the heading, and the page body fenced below that
|
|
15
|
+
- Read the body out of the fence rather than off the heading level, since a reference page carries headings of its own and only the fence separates them from the next destination
|
|
16
|
+
- Stop when the file is absent, reporting `❌ No promotion handoff at .canon/tmp/handoff/teach-promotion/<slug>.md. Run the promotion step from the workspace first.`
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
## Land each block
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
Each block is a page an operator already confirmed a destination for, so this step lands it rather than judging it again. Write to the destination the heading names at `pwd` rather than the main root, since every destination is a tracked file that commits with the branch.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
- A wiki page and a public doc arrive as a whole file. Write it as the block gives it, and leave the block unfolded when the destination holds a file, since overwriting another's page is not a fold.
|
|
23
|
+
- A context entry is merged into rather than created. Fold the body into the sections it belongs under, and never add an entry the catalog does not already carry.
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
Then delete the handoff file so a later run does not fold it twice, and regenerate the index of any folder that carries one.
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
## Output
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
One line per page landed, one naming the handoff when one was consumed, and one per block left unfolded rather than dropped.
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
```plaintext
|
|
32
|
+
✅ Promoted: <destination path>
|
|
33
|
+
🧹 Folded: .canon/tmp/handoff/teach-promotion/<slug>.md
|
|
34
|
+
⚠ Skipped: <destination path> already exists. Merge by hand.
|
|
35
|
+
```
|
|
@@ -6,9 +6,11 @@ Which surface a durable page from a learning workspace belongs to, and what to d
|
|
|
6
6
|
|
|
7
7
|
Only the durable half. A reference page under `reference/` and `GLOSSARY.md` carry no learner and are ordinary reference prose about a subject, so they sort under the routing test like anything else.
|
|
8
8
|
|
|
9
|
-
A lesson is never promoted, at any age and on any request. It is generated markup
|
|
9
|
+
A lesson is never promoted, at any age and on any request. It is generated markup worked through once, carrying a quiz and a second person, and nothing downstream cites it.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- Promoting one puts ungated markup into a corpus every other page passed a gate to enter
|
|
12
|
+
- A reference page carrying a quiz, a second person, or an instruction to the learner is a lesson wearing the wrong extension
|
|
13
|
+
- Say so, and propose rewriting that page in place before promotion rather than repairing it at the destination
|
|
12
14
|
|
|
13
15
|
## The routing test
|
|
14
16
|
|
|
@@ -31,9 +33,13 @@ The folder has two spellings and a project carries whichever its scaffold wrote:
|
|
|
31
33
|
|
|
32
34
|
Read which one exists rather than composing either. A project carrying both keeps its pages at the root, so propose the root spelling and say the other folder is there.
|
|
33
35
|
|
|
36
|
+
### Neither spelling
|
|
37
|
+
|
|
34
38
|
A project carrying neither gets a refusal rather than a scaffold:
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
```plaintext
|
|
41
|
+
❌ No wiki folder. Run canon wiki init to create one, then promote again.
|
|
42
|
+
```
|
|
37
43
|
|
|
38
44
|
Creating the folder as a side effect of promoting one page hands the project a surface it never chose, and the refusal is one command from resolved.
|
|
39
45
|
|
|
@@ -63,7 +69,11 @@ Still owed: <what the destination expects that the page does not carry yet>
|
|
|
63
69
|
|
|
64
70
|
Then stop and let the operator strike, redirect, or confirm each block.
|
|
65
71
|
|
|
66
|
-
|
|
72
|
+
### Record the handoff
|
|
73
|
+
|
|
74
|
+
Write nothing to a destination here. One skill owns the durable writes, and two skills editing one file at one step is the failure that rule exists against.
|
|
75
|
+
|
|
76
|
+
Record each confirmed block in `.canon/tmp/handoff/teach-promotion/<slug>.md` at the main worktree root instead, appending when the file exists. Each destination takes one H2 naming its path, the source page beneath it, and the page body fenced:
|
|
67
77
|
|
|
68
78
|
````markdown
|
|
69
79
|
## <destination path>
|
|
@@ -75,13 +85,26 @@ Source: .canon/teach/<nn>-<topic>/reference/<slug>.md
|
|
|
75
85
|
```
|
|
76
86
|
````
|
|
77
87
|
|
|
78
|
-
The body is fenced rather than written bare because a reference page carries headings of its own, and the reader splits this file on its H2 lines. An unfenced body turns every section heading in the page into a destination naming no path. Open the body fence with four backticks so a page carrying a fenced code block of its own still closes where it should, and widen both fences together if it carries a four-backtick fence.
|
|
79
|
-
|
|
80
88
|
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. Fall back to `latest` on an empty result.
|
|
81
89
|
|
|
82
|
-
|
|
90
|
+
### Why the fence
|
|
91
|
+
|
|
92
|
+
A reference page carries headings of its own, and the reader splits this file on its H2 lines. An unfenced body turns every section heading in the page into a destination naming no path.
|
|
93
|
+
|
|
94
|
+
- Open the body fence with four backticks, so a page carrying a fenced code block still closes where it should
|
|
95
|
+
- Widen both fences together if the page carries a four-backtick fence
|
|
96
|
+
|
|
97
|
+
### Why a file of its own
|
|
98
|
+
|
|
99
|
+
The routed-facts file another skill writes is deleted by whichever pass folds it, so a second producer's unread work would go with it. A sibling path costs the folding skill one more read and removes the interaction.
|
|
100
|
+
|
|
101
|
+
### Sending and reporting
|
|
102
|
+
|
|
103
|
+
An append is a whole-file operation, so send it as a heredoc, per the skill's Step 0. Then tell the operator that `/teach-workspace fold` folds the file in from a branch.
|
|
104
|
+
|
|
105
|
+
The proposal costs nothing tracked and runs anywhere. The page it describes is a tracked file, so the fold is a worktree operation and the workspace it came from is not.
|
|
83
106
|
|
|
84
|
-
|
|
107
|
+
### Output
|
|
85
108
|
|
|
86
109
|
A promotion pass reports this shape in place of the skill's Output block, one line per page the operator confirmed and one naming the handoff:
|
|
87
110
|
|
|
@@ -15,8 +15,14 @@ Then write `## Revisit`, one bullet per item, in the shape `${CLAUDE_SKILL_DIR}/
|
|
|
15
15
|
- **<what comes back up>**: due <YYYY-MM-DD>, rung <n>
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Where the date comes from
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Take both the date and the rung from the `due` entry Step 1 already read. Copy `hit` for an item the learner retrieved unaided and `miss` for one they did not, with the rung stepped the same way.
|
|
21
|
+
|
|
22
|
+
- Do not compute a date from the ladder. A session told to widen a gap still picks the number by judgment, which is why the verb reports both dates.
|
|
23
|
+
- An item never scheduled has no `due` entry. Open it at rung 1, dated the day after this session, the ladder's floor and the one number this body states.
|
|
24
|
+
- Every later date for that item comes from the verb
|
|
25
|
+
|
|
26
|
+
## Writing the shape exactly
|
|
21
27
|
|
|
22
28
|
An entry outside this shape schedules nothing and nothing reports that it was skipped, so write the shape exactly. A later record naming the same item supersedes an earlier entry, so revise a schedule by writing the new bullet rather than editing the record it was set in.
|
|
@@ -73,7 +73,10 @@ A workspace failing these is non-conforming even when it satisfies every shape r
|
|
|
73
73
|
| `lessons/` | Numbered lessons, generated and disposable | Optional |
|
|
74
74
|
| `assets/` | Files several lessons share, including the stylesheet | Optional |
|
|
75
75
|
|
|
76
|
-
Only the markdown half answers to a conformance check: `MISSION.md`, `RESOURCES.md`, `GLOSSARY.md`, `NOTES.md`, the markdown under `reference/`, and `learning-records/`.
|
|
76
|
+
Only the markdown half answers to a conformance check: `MISSION.md`, `RESOURCES.md`, `GLOSSARY.md`, `NOTES.md`, the markdown under `reference/`, and `learning-records/`.
|
|
77
|
+
|
|
78
|
+
- A lesson is generated markup nothing downstream cites, so this standard fixes its filename and location and nothing about its contents
|
|
79
|
+
- A rendered reference page is the same kind of output, rewritten from its markdown on every `nav` run
|
|
77
80
|
|
|
78
81
|
## Frontmatter
|
|
79
82
|
|
|
@@ -125,15 +128,18 @@ Write one bullet per item, in this shape and no other:
|
|
|
125
128
|
- **<what comes back up>**: due <YYYY-MM-DD>, rung <n>
|
|
126
129
|
```
|
|
127
130
|
|
|
128
|
-
The rung is
|
|
131
|
+
The rung is the item's place on the spacing ladder. It travels in the record rather than being counted from records naming the item, since a miss drops it back and a count only climbs.
|
|
129
132
|
|
|
130
|
-
|
|
133
|
+
- A later record naming the item supersedes an earlier one, so revise by writing a new entry rather than editing the old record
|
|
134
|
+
- Take the date and rung from what the driving surface reports. An entry outside this shape schedules nothing, silently.
|
|
131
135
|
|
|
132
136
|
## GLOSSARY.md
|
|
133
137
|
|
|
134
|
-
Required
|
|
138
|
+
Required at the root of every workspace, one entry per term the subject defines. The glossary reference the `canon:teach-workspace` skill carries fixes the entry shape, order, grouping, and which terms it holds.
|
|
135
139
|
|
|
136
|
-
|
|
140
|
+
- That reference ships with the plugin rather than installing here, since a promoted glossary keeps its shape wherever it lands
|
|
141
|
+
- With no plugin to read it from, say so and stop rather than working the shape from memory
|
|
142
|
+
- Name the lesson or reference page a term first appears in, which a workspace always has
|
|
137
143
|
|
|
138
144
|
## RESOURCES.md
|
|
139
145
|
|
|
@@ -143,7 +149,7 @@ Splits what was read from what was found.
|
|
|
143
149
|
- List under a leads heading any source found and not opened, and never cite one
|
|
144
150
|
- Say which claims in the workspace rest on which source
|
|
145
151
|
|
|
146
|
-
|
|
152
|
+
An unread source is a lead because a link to a page nobody opened is worse than none. Listing it stops a later session searching again.
|
|
147
153
|
|
|
148
154
|
### Choosing sources
|
|
149
155
|
|
|
@@ -155,6 +161,8 @@ Rest each general claim on the highest rung that covers it:
|
|
|
155
161
|
|
|
156
162
|
A subject nobody owns, such as a mathematical topic or a craft, has no first rung, so its list starts at the second and is not missing anything. Record a third-rung source with the claim it covers and why no higher rung does, since that reason is what a later session checks the choice against.
|
|
157
163
|
|
|
164
|
+
### What never counts
|
|
165
|
+
|
|
158
166
|
The learner's own projects and material specific to one employer or organization are never a source for a general claim. Either may appear in the workspace as a worked application labeled with whose it is, and neither stands in `RESOURCES.md` as proof of what the subject says.
|
|
159
167
|
|
|
160
168
|
A source reachable only through a paywall or a summary stays a lead until it is opened. A review or summary of a book is a different source from the book, so list the summary as read on its own rung and the book as a lead.
|
|
@@ -170,9 +178,9 @@ A source reachable only through a paywall or a summary stays a lead until it is
|
|
|
170
178
|
- **The mission with no test.** Success stated as understanding rather than as a task leaves nothing able to say the mission is finished.
|
|
171
179
|
- **The lesson filed as reference.** A page written to be worked through once sits in `lessons/`, and putting it in `reference/` puts disposable output in the half that gets promoted.
|
|
172
180
|
- **The record that counts errors.** A tally of how many were missed carries none of the misconception, which is the only part a later session can act on.
|
|
173
|
-
- **The revisit note with no date.** A line naming what to come back to and not when
|
|
174
|
-
- **The date left in the body.** A frontmatter field and a sentence both claiming the opening date resolve to whichever a reader
|
|
175
|
-
- **The first search result as the source list.** A workspace resting on
|
|
181
|
+
- **The revisit note with no date.** A line naming what to come back to and not when schedules nothing, so the next session picks from the last record alone, the state the section exists to end.
|
|
182
|
+
- **The date left in the body.** A frontmatter field and a sentence both claiming the opening date resolve to whichever a reader hits, and a walker reads only one.
|
|
183
|
+
- **The first search result as the source list.** A workspace resting on the first search hit teaches the weakest account of the subject, and nothing in the folder says a stronger one went unsought.
|
|
176
184
|
- **The renumbered folder.** Closing a gap in the ordinals moves every name a reader or a record already cited.
|
|
177
185
|
|
|
178
186
|
## Template
|
|
@@ -11,36 +11,70 @@ External sources were read and filtered rather than imported. This file is the r
|
|
|
11
11
|
|
|
12
12
|
### Choosing the layer
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Three sources settle which layer a test belongs at and how the decision table reads.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
| Adopted | Source |
|
|
17
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| The smallest-layer rule | Fowler, "push your tests as far down the test pyramid as you can" ([Practical Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html)) |
|
|
19
|
+
| Sizing by what a test touches | Google's small, medium, and large sizes ([Software Engineering at Google, ch. 11](https://abseil.io/resources/swe-book/html/ch11.html)) |
|
|
20
|
+
| The component layer carrying UI weight | Kent C. Dodds's trophy ([Write tests](https://kentcdodds.com/blog/write-tests)) and Testing Library's [guiding principles](https://testing-library.com/docs/guiding-principles) |
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
- Fowler writes a lower test when a higher one catches what no lower one did. It is the body's layer rule and the decision table's reason.
|
|
23
|
+
- Google's sizes name what a test may touch rather than cover. The table keys on the same, so it transfers across stacks without naming a runner.
|
|
24
|
+
- Testing Library holds that tests resembling use give more confidence
|
|
25
|
+
|
|
26
|
+
The scope names unit, component, and end to end stay as the labels, since a reader and a file suffix already use them. The pyramid and the trophy are one rule applied to different code, since a component's logic is its rendered behavior and its lowest layer is a rendered test.
|
|
19
27
|
|
|
20
28
|
### Judging a test
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
The opening question and final filter come from `obra/superpowers@5bf4e78`, `skills/test-driven-development/writing-good-tests.md`. It names the production change that makes a test fail and whether it is a bug or a decision.
|
|
31
|
+
|
|
32
|
+
- It then cuts mirror assertions, change detectors, assertions on mocks, and framework tests, and runs the mutation check
|
|
33
|
+
- Adopted as the body's opening question and final filter, with the fixed pause added from the end to end incidents
|
|
34
|
+
|
|
35
|
+
### Doubles in preference order and DAMP over DRY
|
|
36
|
+
|
|
37
|
+
From `addyosmani/agent-skills@c004a74`, `skills/test-driven-development/SKILL.md`, which orders real, fake, stub, then mock, and prefers descriptive test bodies over shared helpers. Adopted in `unit.md`.
|
|
38
|
+
|
|
39
|
+
### Kent Beck's desiderata
|
|
40
|
+
|
|
41
|
+
The twelve properties at [testdesiderata.com](https://testdesiderata.com/) trade against each other and serve as background. "Behavioral" and "structure-insensitive" together are the whole of "test behavior, not implementation", which is why the body states that pair as asserting through the public surface.
|
|
23
42
|
|
|
24
|
-
|
|
43
|
+
### Excuses, red flags, and a closing checklist
|
|
25
44
|
|
|
26
|
-
|
|
45
|
+
From `addyosmani/agent-skills@2686b620`, [`docs/skill-anatomy.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/docs/skill-anatomy.md): Common Rationalizations, Red Flags, and Verification. Adopted as the three closing sections every practice skill carries, with the final filter as the closing checklist.
|
|
27
46
|
|
|
28
|
-
|
|
47
|
+
This reverses an earlier decline of the excuses table, which objected to arguments against imagined objections. Each row here rebuts an excuse this skill's requirement records a session acting on, such as extending the open end to end spec or adding a pause for a run that flakes under load.
|
|
29
48
|
|
|
30
49
|
### Per layer
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
Each layer reference takes its rules from the tool's own guidance.
|
|
33
52
|
|
|
34
|
-
|
|
53
|
+
| Reference | Adopted | Source |
|
|
54
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `component.md` | Role queries first, user events over synthetic ones, one assertion per wait, no side effects inside a wait | [Common mistakes](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library) |
|
|
56
|
+
| `e2e.md` | Web-first assertions, actionability, config-wide reduced motion, sharding | Playwright's [best practices](https://playwright.dev/docs/best-practices), [actionability](https://playwright.dev/docs/actionability), and [TestOptions](https://playwright.dev/docs/api/class-testoptions) |
|
|
57
|
+
|
|
58
|
+
`component.md` states its rules with the library names removed. `e2e.md` names the runner, since the reference is the per-layer home for runner specifics.
|
|
35
59
|
|
|
36
60
|
## Declined
|
|
37
61
|
|
|
38
|
-
|
|
62
|
+
Each item below stays out of the skill for the reason given.
|
|
63
|
+
|
|
64
|
+
### A numeric mix
|
|
65
|
+
|
|
66
|
+
Google targets roughly 80% unit, 15% integration, 5% end to end ([same chapter](https://abseil.io/resources/swe-book/html/ch11.html)). A ratio is a codebase-wide target a session writing one test cannot act on.
|
|
67
|
+
|
|
68
|
+
web.dev's point that the shape "should fit your architecture" ([Pyramid or Crab](https://web.dev/articles/ta-strategies)) is what a motion-heavy static site needs, so the body states the rule and the budget in words instead.
|
|
69
|
+
|
|
70
|
+
### Delete the code written before its test
|
|
39
71
|
|
|
40
|
-
|
|
72
|
+
`superpowers`'s test-driven skill tells a session to delete implementation written ahead of a failing test. This toolkit audits the order after the fact with its test-order verb and reports rather than destroys, since deleting working code punishes the session without restoring the evidence the red run would have given.
|
|
41
73
|
|
|
42
|
-
|
|
74
|
+
### Other declines
|
|
43
75
|
|
|
44
|
-
|
|
76
|
+
The remaining three were declined on tone or on shape.
|
|
45
77
|
|
|
46
|
-
**
|
|
78
|
+
- **An iron law.** Both external test-driven skills carry an "Iron Law" stated as absolute. Declined for tone, since this toolkit states a rule once with its reason.
|
|
79
|
+
- **One skill per layer.** The layer has to be chosen before the right skill can load, so the choice ends up restated in all three or in a fourth skill that is this one.
|
|
80
|
+
- **A standard in place of a skill.** The guidance is judgment applied while writing, loaded on intent. Nobody checks a test file against a layer rule after the fact, which is what a standard governs.
|
|
@@ -5,7 +5,9 @@ description: Render with real children, query by role, drive with user events, w
|
|
|
5
5
|
|
|
6
6
|
# Component tests
|
|
7
7
|
|
|
8
|
-
Read this before writing the first test at the component layer. A component's logic is its rendered behavior, so the lowest layer
|
|
8
|
+
Read this before writing the first test at the component layer. A component's logic is its rendered behavior, so the lowest layer catching a break in a loading state, an interaction, or a validation message is a rendered component test rather than a whole-site browser run.
|
|
9
|
+
|
|
10
|
+
Kent C. Dodds's testing trophy makes this the widest band for UI code ([Write tests](https://kentcdodds.com/blog/write-tests)), on the principle Testing Library states: "The more your tests resemble the way your software is used, the more confidence they can give you" ([guiding principles](https://testing-library.com/docs/guiding-principles)).
|
|
9
11
|
|
|
10
12
|
## What belongs here
|
|
11
13
|
|
|
@@ -36,7 +38,8 @@ Read this before writing the first test at the component layer. A component's lo
|
|
|
36
38
|
|
|
37
39
|
A simulated DOM computes no layout, no scroll position, and no animation frame. When the behavior under test is one of those, move to a runner that renders the component in a real browser rather than promoting the test to end to end.
|
|
38
40
|
|
|
39
|
-
- Vitest browser mode runs tests "in the browser natively"
|
|
40
|
-
-
|
|
41
|
+
- Vitest browser mode runs tests "in the browser natively" through Playwright or WebdriverIO, for React, Vue, Svelte, Angular, Lit, Preact, and Qwik ([Vitest browser mode](https://vitest.dev/guide/browser/))
|
|
42
|
+
- Astro is not on that list. For a static site, test the client module driving the behavior against a fixture DOM in Vitest browser mode.
|
|
43
|
+
- Playwright component testing is stable in plain `@playwright/test` through a mount fixture ([Playwright component testing](https://playwright.dev/docs/test-components)). The experimental `-ct-*` packages were removed after 1.62.
|
|
41
44
|
|
|
42
|
-
Either runs in a real browser without navigating the whole site, which keeps the test at the component's cost while observing what only a browser computes.
|
|
45
|
+
Playwright's own claim is that "if your dev server can render it, Playwright can test it". Either runs in a real browser without navigating the whole site, which keeps the test at the component's cost while observing what only a browser computes.
|
|
@@ -11,9 +11,9 @@ Read the settle, guard, and run-scope rules in the project's end to end reliabil
|
|
|
11
11
|
|
|
12
12
|
## What earns a browser run
|
|
13
13
|
|
|
14
|
-
- A journey a user cannot lose without the product failing,
|
|
14
|
+
- A journey across routes a user cannot lose without the product failing, such as sign up or check out ([Practical Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html)).
|
|
15
15
|
- Behavior only a real browser computes across the whole page: layout at a breakpoint, scroll position, focus crossing a route, motion.
|
|
16
|
-
- Not a state a component test can reach. Loading, empty, and error states, a toggle, and a validation message belong one layer down, even
|
|
16
|
+
- Not a state a component test can reach. Loading, empty, and error states, a toggle, and a validation message belong one layer down, even on a page with other end to end coverage.
|
|
17
17
|
- Not copy. Asserting exact wording in a browser run makes every copy edit a failure across every engine the gate runs.
|
|
18
18
|
|
|
19
19
|
Suites dominated by end to end tests inflate both runtime and flake ([Google Testing Blog, 2015](https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html)). Nothing fixes a count ceiling, and the right shape depends on the architecture ([Pyramid or Crab](https://web.dev/articles/ta-strategies)). A site whose behavior is mostly layout and motion carries more browser tests than a form-heavy app, and each one still has to earn its place.
|
|
@@ -21,24 +21,42 @@ Suites dominated by end to end tests inflate both runtime and flake ([Google Tes
|
|
|
21
21
|
## Settle on conditions
|
|
22
22
|
|
|
23
23
|
- Assert with a web-first assertion that retries until the condition holds. A manual visibility check reads once and does not retry ([best practices](https://playwright.dev/docs/best-practices)).
|
|
24
|
-
- Lean on actionability for clicks and fills
|
|
24
|
+
- Lean on actionability for clicks and fills, which wait out an animation on their own ([actionability](https://playwright.dev/docs/actionability)). A read does not wait, so poll it.
|
|
25
25
|
- Never pause for a fixed duration to stand in for a condition. Reserve a fixed window for asserting that nothing happened across it.
|
|
26
26
|
- Settle a smooth scroll on the `scrollend` event. Fall back to a stillness window only when the target was already in view.
|
|
27
27
|
|
|
28
|
+
An element counts as stable once it "has maintained the same bounding box for at least two consecutive animation frames", which is why an action needs no wait of its own.
|
|
29
|
+
|
|
28
30
|
## Motion off by default
|
|
29
31
|
|
|
30
32
|
- Run with motion reduced unless the test asserts motion, and opt back in per test with `page.emulateMedia({ reducedMotion: 'no-preference' })`.
|
|
31
|
-
- Set it once in the config's `use` block as `contextOptions: { reducedMotion: 'reduce' }
|
|
33
|
+
- Set it once in the config's `use` block as `contextOptions: { reducedMotion: 'reduce' }`, since the option defaults to `'no-preference'` ([BrowserContext options](https://playwright.dev/docs/api/class-browser#browser-new-context)).
|
|
34
|
+
- A top-level `use.reducedMotion` reaches no page and type-checks nowhere, so a spec asserting the media query is what catches it
|
|
35
|
+
|
|
36
|
+
A site honoring the reduced preference then has nothing to wait out in any test that does not opt back in.
|
|
32
37
|
|
|
33
38
|
## Isolation and speed
|
|
34
39
|
|
|
35
40
|
- Give every test its own state: a fresh context, its own account or seed, nothing left behind for the next test.
|
|
36
|
-
- Speed a slow suite with parallel workers and sharding
|
|
41
|
+
- Speed a slow suite with parallel workers and sharding rather than by cutting waits ([best practices](https://playwright.dev/docs/best-practices)).
|
|
42
|
+
- A suite that fails once workers rise carries timing-sensitive assertions, and those are the tests to move down a layer
|
|
37
43
|
- Capture a trace on the first retry rather than a video on every run ([best practices](https://playwright.dev/docs/best-practices)).
|
|
38
44
|
- Count the cost before adding a test: its runtime, times every engine in the matrix, times every push. That product is what the gate charges each later change.
|
|
39
45
|
|
|
40
46
|
## Two worked failures
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
Both failures were fixed by moving the assertion down a layer rather than by tuning the browser run.
|
|
49
|
+
|
|
50
|
+
### A copy assertion in a browser run
|
|
51
|
+
|
|
52
|
+
A portfolio site's home spec asserted the exact wording of its about section. A one-line copy edit then failed three engines in continuous integration, and the deploy waited on it.
|
|
53
|
+
|
|
54
|
+
- The breaking change was a decision rather than a bug, which makes the assertion a change detector
|
|
55
|
+
- The copy belonged in a unit test beside the module holding it, and the browser run needed at most the section's presence
|
|
56
|
+
|
|
57
|
+
### A settle that narrowed a failure without removing it
|
|
58
|
+
|
|
59
|
+
A focus-ring spec replaced a fixed pause with a condition wait on a scripted focus read. The next trunk push still failed one engine on every attempt with the condition timing out, and flaked a second test in the file, which skipped the deploy.
|
|
43
60
|
|
|
44
|
-
|
|
61
|
+
- The settle was correct and the layer was wrong. An assertion whose result depends on how loaded the CI machine is keeps failing at the layer where load decides it.
|
|
62
|
+
- Moving the focus behavior to a real-browser component test takes it off the whole-site run
|
|
@@ -5,7 +5,9 @@ description: Doubles in preference order, descriptive over shared setup, table-d
|
|
|
5
5
|
|
|
6
6
|
# Unit and integration tests
|
|
7
7
|
|
|
8
|
-
Read this before writing the first test at the unit or integration layer. A unit test runs in one process with no network, no sleep, and no real I/O.
|
|
8
|
+
Read this before writing the first test at the unit or integration layer. A unit test runs in one process with no network, no sleep, and no real I/O.
|
|
9
|
+
|
|
10
|
+
An integration test may touch the local machine, such as a temporary directory or a local database, and nothing beyond it. Google's size vocabulary draws the same line by what a test may touch rather than what it covers ([Software Engineering at Google, ch. 11](https://abseil.io/resources/swe-book/html/ch11.html)).
|
|
9
11
|
|
|
10
12
|
## Doubles
|
|
11
13
|
|
|
@@ -9,13 +9,21 @@ The loop predates this ledger, so this file records the sources it matches rathe
|
|
|
9
9
|
|
|
10
10
|
## Adopted
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
### The loop itself
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Kent Beck's [Canon TDD](https://newsletter.kentbeck.com/p/canon-tdd) states it as turning one item into "an actual, concrete, runnable test", changing the code "to make the test (& all previous tests) pass", then refactoring. Adopted as steps 2, 4, 5, and 6, with the whole suite run after the pass rather than the new test alone.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
### Making it pass without designing
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
The same post warns against "mixing refactoring into making the test pass", and keeps implementation design decisions for the refactor. Adopted as step 4's smallest change and step 6's cleanup of the shortcuts that change left.
|
|
19
|
+
|
|
20
|
+
### Never faking the pass
|
|
21
|
+
|
|
22
|
+
The same post lists deleting assertions "so the test pretends to pass" and "copying actual, computed values & pasting them into the expected values" as mistakes. Adopted as step 5's rule that a pass must be the one the test was written to prove.
|
|
23
|
+
|
|
24
|
+
### Refactoring is a step, not an option
|
|
25
|
+
|
|
26
|
+
Martin Fowler's [TestDrivenDevelopment](https://martinfowler.com/bliki/TestDrivenDevelopment.html) names "neglecting the third step" as the most common way to get the practice wrong. Adopted as step 6 being mandatory where Canon TDD writes "optionally refactor".
|
|
19
27
|
|
|
20
28
|
## Declined
|
|
21
29
|
|
|
@@ -33,7 +33,7 @@ The automatable half has its own gap, and it is no longer this skill's to close
|
|
|
33
33
|
- Try to assert a visual property programmatically
|
|
34
34
|
- Repeat the full checklist in chat, which is what made it evaporate
|
|
35
35
|
- Stage or commit the checklist, which is gitignored scratch
|
|
36
|
-
- Talk to GitHub directly. Posting the checklist belongs to `
|
|
36
|
+
- Talk to GitHub directly. Posting the checklist belongs to `pr-evidence`, the sole consumer of the handoff file
|
|
37
37
|
- Move the handoff path to match this skill's name, which strands a checklist an older binary wrote
|
|
38
38
|
|
|
39
39
|
## Guards
|
|
@@ -69,7 +69,7 @@ Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. Fall
|
|
|
69
69
|
|
|
70
70
|
When a checklist is produced, write it to `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root, resolved the way `session-worktree` does, creating the directory if needed and always overwriting.
|
|
71
71
|
|
|
72
|
-
- It is a handoff file rather than a deliverable. `
|
|
72
|
+
- It is a handoff file rather than a deliverable. `pr-evidence` renders it into the evidence comment once a pull request opens, then removes it, and nothing here calls `gh`.
|
|
73
73
|
- The path names the artifact rather than this skill, so a rename moves nothing and an older binary's checklist lands where the consumer looks
|
|
74
74
|
- The checklist is a main-root write, so it goes out as a heredoc, routed the way `session-worktree` states
|
|
75
75
|
- Skip the write when there is nothing to verify visually and nothing shipping untested
|