@erclx/canon 5.12.0 → 5.14.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/REQUIREMENT.md +1 -1
- package/claude/skills/api-design/SKILL.md +4 -3
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +2 -2
- package/claude/skills/build-in-slices/REQUIREMENT.md +45 -0
- package/claude/skills/build-in-slices/SKILL.md +94 -0
- package/claude/skills/build-in-slices/references/adopted.md +41 -0
- package/claude/skills/code-craft/REQUIREMENT.md +48 -0
- package/claude/skills/code-craft/SKILL.md +107 -0
- package/claude/skills/code-craft/references/adopted.md +52 -0
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -1
- package/claude/skills/deprecation-migration/REQUIREMENT.md +62 -0
- package/claude/skills/deprecation-migration/SKILL.md +115 -0
- package/claude/skills/deprecation-migration/references/adopted.md +50 -0
- package/claude/skills/git-followup/REQUIREMENT.md +1 -0
- package/claude/skills/git-followup/SKILL.md +3 -0
- package/claude/skills/git-pr/REQUIREMENT.md +1 -0
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-ship/REQUIREMENT.md +4 -0
- package/claude/skills/git-ship/SKILL.md +13 -2
- package/claude/skills/review-craft/REQUIREMENT.md +3 -0
- package/claude/skills/review-craft/SKILL.md +1 -1
- package/claude/skills/review-craft/references/adopted.md +8 -0
- package/claude/skills/review-craft/references/security.md +5 -0
- package/claude/skills/review-ui/REQUIREMENT.md +6 -2
- package/claude/skills/review-ui/SKILL.md +23 -4
- package/claude/skills/review-ui/references/driving.md +5 -3
- package/claude/skills/review-ui/references/post.md +3 -2
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +4 -0
- package/claude/skills/test-first/REQUIREMENT.md +3 -0
- package/claude/skills/test-first/SKILL.md +2 -1
- package/docs/agents/commands.md +1 -1
- package/docs/agents/index.md +1 -0
- package/docs/agents/markdown-audit.md +1 -1
- package/docs/agents/pr-evidence.md +5 -0
- package/docs/agents/pr-frames.md +112 -0
- package/docs/agents/pr-preview.md +40 -12
- package/docs/workflow/skill-map.md +15 -12
- package/governance/rules/code/000-code.md +5 -1
- package/package.json +1 -1
- package/src/claude/cases/misc.ts +15 -0
- package/src/claude/skills-audit.ts +3 -0
- package/src/commands/pr.ts +559 -7
- package/src/commands/tooling.ts +39 -16
- package/src/context/architecture.ts +5 -2
- package/src/gate/boundaries.ts +509 -0
- package/src/gate/measures.ts +8 -19
- package/src/gate/stages.ts +12 -28
- package/src/pr/frames.ts +323 -0
- package/src/pr/preview.ts +66 -0
- package/src/tooling/manifest.ts +18 -3
- package/src/tooling/seeds.ts +37 -0
- package/src/tooling/verify-stack.ts +249 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +2 -0
- package/tooling/claude/manifest.toml +3 -3
- package/tooling/go/manifest.toml +3 -0
- package/tooling/go/reference.md +1 -0
- package/tooling/php/manifest.toml +3 -0
- package/tooling/php/reference.md +1 -0
- package/tooling/python/manifest.toml +3 -0
- package/tooling/python/reference.md +1 -1
- package/tooling/python/seeds/.cspell/tech-stack.txt +0 -1
- package/scripts/core/check-capability-seeding.sh +0 -134
- package/scripts/core/check-ignore-parity.sh +0 -141
- package/scripts/core/check-plugin-boundary.sh +0 -45
- package/scripts/core/check-seed-independence.sh +0 -62
- package/scripts/core/check-skill-paths.sh +0 -24
- package/scripts/core/list-seed-roots.sh +0 -18
- package/scripts/lib/tooling.sh +0 -37
- package/scripts/tooling/verify.sh +0 -184
package/docs/agents/index.md
CHANGED
|
@@ -36,6 +36,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
36
36
|
- [Output shape](output-shape.md): Two framed shapes every command renders into, how JSON and --names modes keep stdout clean, and the exit discipline that lets piped output drain
|
|
37
37
|
- [Overview](overview.md): What this folder covers, the invocation rules every command inherits, and where domain behavior is documented instead
|
|
38
38
|
- [The pull request evidence comparison](pr-evidence.md): What canon pr evidence compares, the marker that lets it edit its own comment rather than duplicate it, the refusal reasons it names, what the --check read reports as owed, and why the comparison anchors at the merge base rather than the previous push
|
|
39
|
+
- [The pull request frame store](pr-frames.md): How canon pr frames pushes a UI review frame to a never-merged branch through the GitHub API and returns a branch-path link, which ref it writes, the pass segment that keeps an earlier image fixed, the refusal reasons it names, and how --drop and --prune rewrite the branch so a dropped frame leaves history
|
|
39
40
|
- [The pull request local preview](pr-local.md): How canon pr local finds the server a worktree is running, why a server in another worktree is never reported, the refusal reasons it names, and how a close workflow removes the link with --remove
|
|
40
41
|
- [The pull request preview deploy](pr-preview.md): How canon pr preview finds a fenced Cloudflare Pages deploy, dispatches it on a pull request's branch, reads the alias the run prints, the refusal reasons it names, and why an unfenced deploy is refused before anything runs
|
|
41
42
|
- [Head-sensitive pull request reads](pr-reads.md): Resolving a branch tip from the remote rather than from the pull request object, reading what a review pass covered off its own marker rather than off GitHub's submission stamps, why an empty run list is not a pass, the refusal reasons each verb names, and what the remote read costs
|
|
@@ -89,7 +89,7 @@ A hit the closed set could not separate from correct prose was the case with no
|
|
|
89
89
|
|
|
90
90
|
Five surfaces apply the ban set and four of them go through this verb. `.claude/hooks/standards-audit.sh` runs it against a single file after each markdown edit, the seed copy a project installs does the same, the `Markdown bans` stage in `canon gate run` runs it across the whole corpus before this repository's own push, and the same-named stage in the one verify runner every stack shares, `scripts/verify.ts`, runs it across a scaffolded project's tracked markdown before its own push. Each hook parsed its own copy of the word bans in awk before that, which left a British spelling passing at edit time and failing the push with nothing in between explaining the difference.
|
|
91
91
|
|
|
92
|
-
The seed copy moved onto the verb when the sets became data, since its awk had nothing left to parse. It resolves one runner where the toolkit copy resolves two, looking for no checkout source, and a machine carrying no `canon` gets a report naming the binary to install rather than a silent pass. `
|
|
92
|
+
The seed copy moved onto the verb when the sets became data, since its awk had nothing left to parse. It resolves one runner where the toolkit copy resolves two, looking for no checkout source, and a machine carrying no `canon` gets a report naming the binary to install rather than a silent pass. The Seed independence stage of `bun run check` scopes its walk to markdown and leaves the seed hooks outside it, which its own comment records as deliberate.
|
|
93
93
|
|
|
94
94
|
The target push stage reads the same exit codes `canon gate run`'s own stage reads: 0 passes, 1 is a refusal logged as a skip, 2 is a finding, and 3 is a shipped-empty ban set. It skips and logs rather than failing when no `canon` binary is on the machine's PATH, since a scaffolded project is not guaranteed the toolkit is installed, and its skip line names the install command.
|
|
95
95
|
|
|
@@ -83,6 +83,11 @@ them means the thread is read before the `no-evidence` answer too, so an
|
|
|
83
83
|
unreadable thread refuses as `gh-failed` on both reasons rather than
|
|
84
84
|
reporting the fields absent.
|
|
85
85
|
|
|
86
|
+
`ok` also carries `states`, the comparison the body renders as data: each
|
|
87
|
+
state's name and its items, each with its `path`, `stem`, and whether it was
|
|
88
|
+
`added`. `review-ui` matches a frame against it so it publishes no image the
|
|
89
|
+
worker's evidence already shows. `canon docs pr-frames` covers that store.
|
|
90
|
+
|
|
86
91
|
## What `[number]` selects, and what it does not
|
|
87
92
|
|
|
88
93
|
Naming a number picks the pull request the whole record describes: its head
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: The pull request frame store
|
|
3
|
+
description: How canon pr frames pushes a UI review frame to a never-merged branch through the GitHub API and returns a branch-path link, which ref it writes, the pass segment that keeps an earlier image fixed, the refusal reasons it names, and how --drop and --prune rewrite the branch so a dropped frame leaves history
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The pull request frame store
|
|
7
|
+
|
|
8
|
+
`canon pr frames` gives a review comment an image it can embed. `review-ui`
|
|
9
|
+
drives a pull request's checklist and captures a frame per box, and a frame
|
|
10
|
+
on the reviewer's disk resolves for nobody else. The verb pushes one frame to
|
|
11
|
+
the `canon-frames` branch and returns a link to its path there.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
canon pr frames 1341 --add frames/3.png --box 3 --head <sha> --pass 20261002T154450Z --json
|
|
15
|
+
canon pr frames 1341 --drop --json
|
|
16
|
+
canon pr frames --prune 30 --json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## What it writes
|
|
20
|
+
|
|
21
|
+
The verb writes `refs/heads/canon-frames` and no other ref. Every call goes
|
|
22
|
+
through the GitHub git data API, being blobs, trees, commits, and that one ref,
|
|
23
|
+
so nothing is checked out, no worktree is entered, and neither `main` nor any
|
|
24
|
+
branch a pull request holds is touched. The branch never merges.
|
|
25
|
+
|
|
26
|
+
A frame lands at `pr-<number>/<short-head>/<pass>/box-<n>.png`. `--head` names
|
|
27
|
+
the commit the pass drove, 7 to 40 lowercase hex characters, and defaults to
|
|
28
|
+
the head the pull request object reports. `--pass` is the instant the pass
|
|
29
|
+
started, in compact UTC as `date -u +%Y%m%dT%H%M%SZ` prints it, which
|
|
30
|
+
`review-ui` records once at its first step. A second pass at the same head and
|
|
31
|
+
box therefore writes a new file rather than replacing the image an earlier
|
|
32
|
+
comment shows, which matters when a preview is minted again at one head.
|
|
33
|
+
|
|
34
|
+
`link` uses the same `blob/<ref>/<path>?raw=true` form as the evidence comment,
|
|
35
|
+
naming the `canon-frames` branch rather than a commit. Every drop rewrites the
|
|
36
|
+
branch, and a link pinned to a commit would stop resolving for every other pull
|
|
37
|
+
request's frames once GitHub collects the commit it names. A path link lives
|
|
38
|
+
exactly as long as its file, so it survives every rewrite that drops another
|
|
39
|
+
pull request and ends only when its own is dropped.
|
|
40
|
+
|
|
41
|
+
The first `--add` creates the branch with a root commit holding the
|
|
42
|
+
frame, so a project needs no setup. An add only fast-forwards the ref. When
|
|
43
|
+
another writer moved it between the read and the move, the add rebuilds on the
|
|
44
|
+
new tip, up to three times, before refusing as `ref-conflict`.
|
|
45
|
+
|
|
46
|
+
Only a frame of the address the pass drove belongs here. The branch is as
|
|
47
|
+
public as the repository, so a frame of a private or pre-release state would
|
|
48
|
+
be published with it.
|
|
49
|
+
|
|
50
|
+
## What the record carries
|
|
51
|
+
|
|
52
|
+
`reason` on the record is what a caller branches on, not the exit code:
|
|
53
|
+
|
|
54
|
+
| Reason | What it means |
|
|
55
|
+
| ------------------ | -------------------------------------------------------------------------------- |
|
|
56
|
+
| `ok` | An add pushed, or a drop or prune finished, including one that removed nothing. |
|
|
57
|
+
| `bad-mode` | Not exactly one of `--add`, `--drop`, `--prune`, or a number with `--prune`. |
|
|
58
|
+
| `no-number` | `--add` or `--drop` named no pull request. |
|
|
59
|
+
| `bad-box` | `--add` carried no positive `--box`. |
|
|
60
|
+
| `bad-head` | `--head`, or the head the pull request reported, is not a 7 to 40 character sha. |
|
|
61
|
+
| `bad-pass` | `--add` carried no `--pass` stamp in compact UTC. |
|
|
62
|
+
| `bad-days` | `--prune` carried no positive number of days. |
|
|
63
|
+
| `unreadable-frame` | The `--add` file is missing, empty, or not a PNG. Nothing is called. |
|
|
64
|
+
| `read-only` | GitHub refused a write with 403 or 404, which is what a fork's token gets. |
|
|
65
|
+
| `unreadable-tip` | The branch exists and could not be read. |
|
|
66
|
+
| `push-failed` | A write failed partway and the ref did not move. |
|
|
67
|
+
| `ref-conflict` | Another writer kept moving the ref through every attempt. |
|
|
68
|
+
| `no-object-head` | No `--head` and the pull request reported none. |
|
|
69
|
+
| `gh-missing` | `gh` is not on the path. |
|
|
70
|
+
| `gh-failed` | `gh` could not name the repository or read the pull request. |
|
|
71
|
+
|
|
72
|
+
An add's `ok` record carries `link`, `commit`, `path`, `box`, `head`, `pass`,
|
|
73
|
+
and `created`, which is true when the add made the branch. A drop's carries
|
|
74
|
+
`removed`, the pull requests whose folders went, plus `commit` for the rewrite
|
|
75
|
+
or `deleted` when it emptied the branch. A prune adds `kept` and `unread`.
|
|
76
|
+
|
|
77
|
+
`review-ui` reads every reason but `ok` as a cue to describe the frame in words
|
|
78
|
+
and name the reason, so a refused push never fails the pass.
|
|
79
|
+
|
|
80
|
+
## Dropping frames
|
|
81
|
+
|
|
82
|
+
A plain delete commit would keep every image reachable through history, so
|
|
83
|
+
`--drop` and `--prune` write one root commit holding everything else and
|
|
84
|
+
force-move the ref to it. A rewrite that leaves the branch empty deletes it,
|
|
85
|
+
and the next add recreates it. Dropping a pull request with no frames, or on a
|
|
86
|
+
missing branch, reports `ok` with nothing removed, so a scheduled run never
|
|
87
|
+
fails on an empty branch.
|
|
88
|
+
|
|
89
|
+
`--prune <days>` reads every `pr-<n>/` folder, asks GitHub for each pull
|
|
90
|
+
request's state, and drops every one reading closed with a close date more
|
|
91
|
+
than that many days ago, in a single rewrite. It keeps one still open, one
|
|
92
|
+
reopened after closing, one closed exactly the given days ago, and one whose
|
|
93
|
+
state could not be read, listing that last kind under `unread`.
|
|
94
|
+
|
|
95
|
+
This repository runs `--prune 30` daily from
|
|
96
|
+
`.github/workflows/pr-frames-cleanup.yml`. A frame's file stays on the branch
|
|
97
|
+
until its own pull request has been closed for 30 days, so a link in a review
|
|
98
|
+
comment keeps resolving for about a month after its pull request closes,
|
|
99
|
+
whatever other pull requests the branch drops in between. A target project
|
|
100
|
+
carries no such workflow yet and keeps its frames until someone runs `--drop`.
|
|
101
|
+
|
|
102
|
+
## What a rewrite does not do
|
|
103
|
+
|
|
104
|
+
A force-move leaves the old commits unreachable without purging them. GitHub
|
|
105
|
+
serves an unreachable commit by sha until it collects it, so a dropped frame
|
|
106
|
+
stays reachable to anyone holding a sha from an earlier record, and a frame
|
|
107
|
+
holding sensitive content needs a purge request to GitHub. Its path link stops
|
|
108
|
+
resolving at the drop, since the branch no longer carries the file.
|
|
109
|
+
|
|
110
|
+
A drop racing an add can lose the add's frame, since GitHub's ref update has no
|
|
111
|
+
compare-and-swap for a force-move. The drop builds from the tip it reads, and
|
|
112
|
+
the window is the length of one rewrite.
|
|
@@ -14,6 +14,7 @@ rather than screenshots and a checklist alone.
|
|
|
14
14
|
```bash
|
|
15
15
|
canon pr preview --json
|
|
16
16
|
canon pr preview 1341 --json --timeout 20
|
|
17
|
+
canon pr preview 1341 --check --json
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
## Which workflow it dispatches
|
|
@@ -61,22 +62,49 @@ keeps the match independent of the local clock.
|
|
|
61
62
|
|
|
62
63
|
`reason` on the record is what a caller branches on, not the exit code:
|
|
63
64
|
|
|
64
|
-
| Reason
|
|
65
|
-
|
|
|
66
|
-
| `ok`
|
|
67
|
-
| `no-deploy`
|
|
68
|
-
| `unfenced`
|
|
69
|
-
| `no-alias`
|
|
70
|
-
| `run-failed`
|
|
71
|
-
| `timeout`
|
|
72
|
-
| `bad-timeout`
|
|
73
|
-
| `gh-missing`
|
|
74
|
-
| `gh-failed`
|
|
75
|
-
| `no-branch`
|
|
65
|
+
| Reason | What it means |
|
|
66
|
+
| --------------- | -------------------------------------------------------------------------- |
|
|
67
|
+
| `ok` | The preview was published. `url` carries the address and `runId` the run. |
|
|
68
|
+
| `no-deploy` | No dispatchable workflow runs `pages deploy`. |
|
|
69
|
+
| `unfenced` | The deploy passes no `--branch`, so nothing was dispatched. |
|
|
70
|
+
| `no-alias` | The workflow prints no alias line, or the finished run's log carried none. |
|
|
71
|
+
| `run-failed` | The deploy run finished without succeeding. `runId` names it. |
|
|
72
|
+
| `timeout` | The run did not finish inside `--timeout` minutes, 15 by default. |
|
|
73
|
+
| `bad-timeout` | `--timeout` was not a positive number. |
|
|
74
|
+
| `gh-missing` | `gh` is not on the path. |
|
|
75
|
+
| `gh-failed` | `gh` could not read the pull request, or list or dispatch the workflow. |
|
|
76
|
+
| `no-branch` | The pull request carries no head branch name. |
|
|
77
|
+
| `check-timeout` | `--check` was combined with `--timeout`. |
|
|
76
78
|
|
|
77
79
|
The exit is 0 on `ok` and 1 on every refusal. A `timeout` leaves the run
|
|
78
80
|
going, so the preview may still land after the verb has given up on it.
|
|
79
81
|
|
|
82
|
+
## Checking which head a preview was built from
|
|
83
|
+
|
|
84
|
+
`--check` dispatches nothing and waits on nothing. It lists the branch's
|
|
85
|
+
`workflow_dispatch` runs, takes the newest successful one by creation time, and
|
|
86
|
+
compares the head it ran at with the branch tip read from the remote. The tip
|
|
87
|
+
comes from the remote rather than the pull request object's `headRefOid`, which
|
|
88
|
+
lags a push. `--check` takes no `--timeout` and refuses one as `check-timeout`.
|
|
89
|
+
|
|
90
|
+
The alias serves the newest successful deployment for the branch and names no
|
|
91
|
+
sha, so the run listing is the only record of the built head. The
|
|
92
|
+
`workflow_dispatch` filter also drops the cleanup run a closed pull request
|
|
93
|
+
fires, which concludes `success` with its deploy skipped. A project that deploys
|
|
94
|
+
on `push` to a feature branch would need that filter widened.
|
|
95
|
+
|
|
96
|
+
| Reason | What it means |
|
|
97
|
+
| ---------- | --------------------------------------------------------------------- |
|
|
98
|
+
| `fresh` | The newest successful deploy built the tip. Exit 0. |
|
|
99
|
+
| `stale` | It built an earlier head. `built` and `tip` name both. Mint again. |
|
|
100
|
+
| `building` | A deploy of the tip is still running. Wait rather than minting again. |
|
|
101
|
+
| `no-build` | No deploy of the branch has succeeded. |
|
|
102
|
+
|
|
103
|
+
The record also carries `runId` for the deploy it read. The check covers the
|
|
104
|
+
hosted address only, so a local address has no run to read and stays unverified.
|
|
105
|
+
`review-ui` runs it before driving a hosted preview and posts nothing on any
|
|
106
|
+
reason but `fresh`.
|
|
107
|
+
|
|
80
108
|
## How the address reaches the pull request
|
|
81
109
|
|
|
82
110
|
`canon pr evidence --preview <url>` puts `**Preview:** <url>` on the first line
|
|
@@ -38,18 +38,21 @@ This page is the corpus the coverage claim is measured against: every name `cano
|
|
|
38
38
|
|
|
39
39
|
## Build the feature
|
|
40
40
|
|
|
41
|
-
| Skill
|
|
42
|
-
|
|
|
43
|
-
| `canon:session-worktree`
|
|
44
|
-
| `canon:auto-ship`
|
|
45
|
-
| `canon:project-commands`
|
|
46
|
-
| `canon:test-first`
|
|
47
|
-
| `canon:test-craft`
|
|
48
|
-
| `canon:
|
|
49
|
-
| `canon:
|
|
50
|
-
| `canon:
|
|
51
|
-
| `canon:
|
|
52
|
-
| `canon:
|
|
41
|
+
| Skill | When to use |
|
|
42
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `canon:session-worktree` | At the plan-to-execute boundary, to get an isolated tree and branch, or to route a refused main-root write |
|
|
44
|
+
| `canon:auto-ship` | After plan approval, to chain implement, verify, review, draft PR |
|
|
45
|
+
| `canon:project-commands` | When the project's own command needs running |
|
|
46
|
+
| `canon:test-first` | Before implementing a planned change, to run its test red, green, then refactor |
|
|
47
|
+
| `canon:test-craft` | When writing or changing any test, to pick its layer and filter what it asserts |
|
|
48
|
+
| `canon:build-in-slices` | While building a plan, to commit each tested slice and note out-of-scope defects rather than fix them |
|
|
49
|
+
| `canon:api-design` | When changing what a caller sees, being an export, a flag, an output shape, or a retried write |
|
|
50
|
+
| `canon:deprecation-migration` | When deleting or replacing code something may still call, to migrate its callers and prove none remain |
|
|
51
|
+
| `canon:code-craft` | Before writing a function, class, or module, to pick the shape the next change needs |
|
|
52
|
+
| `canon:review-craft` | When reviewing a change, for what to look for and how much evidence a finding needs |
|
|
53
|
+
| `canon:systematic-debugging` | When a test fails or a bug surfaces, to force root cause first |
|
|
54
|
+
| `canon:design-taste` | When drafting or judging an interface, or when output reads generic, to settle which decision comes first |
|
|
55
|
+
| `canon:ui-checklist` | After a UI change, to write what to look at and name what ships untested |
|
|
53
56
|
|
|
54
57
|
## Check the work before it leaves the branch
|
|
55
58
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Code placement, dependency, error, and naming choices a model does not make by default
|
|
2
|
+
description: Code placement, shape, dependency, error, and naming choices a model does not make by default
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Code standards
|
|
@@ -10,6 +10,10 @@ description: Code placement, dependency, error, and naming choices a model does
|
|
|
10
10
|
- Prioritize native platform capabilities over third-party libraries.
|
|
11
11
|
- Ensure data and configuration reside in designated Single Source of Truth locations.
|
|
12
12
|
|
|
13
|
+
## Shape
|
|
14
|
+
|
|
15
|
+
- Load the `canon:code-craft` skill before deciding the shape of a new function, class, or module, and report it rather than proceeding silently when it does not resolve.
|
|
16
|
+
|
|
13
17
|
## Errors
|
|
14
18
|
|
|
15
19
|
- Return structured error types for recoverable failures.
|
package/package.json
CHANGED
package/src/claude/cases/misc.ts
CHANGED
|
@@ -74,6 +74,21 @@ export const MISC_CASES: readonly SkillCase[] = [
|
|
|
74
74
|
"I'm adding a field to the JSON this command prints and renaming one flag, anything to watch?",
|
|
75
75
|
expect: 'api-design',
|
|
76
76
|
},
|
|
77
|
+
{
|
|
78
|
+
prompt:
|
|
79
|
+
'The same discount rule sits in two files and I need a third variant. Should I extract it, or add a strategy class for the two cases?',
|
|
80
|
+
expect: 'code-craft',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
prompt:
|
|
84
|
+
"I've got the plan approved and it touches the parser, the command, and the docs. How should I build it so I don't end up with one giant diff?",
|
|
85
|
+
expect: 'build-in-slices',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
prompt:
|
|
89
|
+
'The old parseDate helper was replaced months ago. Can I just delete it, or could a few files still be calling it?',
|
|
90
|
+
expect: 'deprecation-migration',
|
|
91
|
+
},
|
|
77
92
|
{
|
|
78
93
|
prompt: 'Does our github about text still match what the readme says?',
|
|
79
94
|
expect: 'repo-metadata',
|
|
@@ -37,6 +37,9 @@ export const PRACTICE_SKILLS: readonly string[] = [
|
|
|
37
37
|
join(SHIPPED_CORPUS, 'review-craft'),
|
|
38
38
|
join(SHIPPED_CORPUS, 'systematic-debugging'),
|
|
39
39
|
join(SHIPPED_CORPUS, 'api-design'),
|
|
40
|
+
join(SHIPPED_CORPUS, 'code-craft'),
|
|
41
|
+
join(SHIPPED_CORPUS, 'build-in-slices'),
|
|
42
|
+
join(SHIPPED_CORPUS, 'deprecation-migration'),
|
|
40
43
|
]
|
|
41
44
|
|
|
42
45
|
/** The closing H2s a practice skill carries, matched exactly outside fences. */
|