@erclx/canon 4.126.0 → 5.1.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/README.md +5 -7
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/references/verb-absent.md +0 -1
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback/SKILL.md +2 -2
- package/claude/skills/canon-operator/REQUIREMENT.md +2 -2
- package/claude/skills/canon-operator/SKILL.md +3 -3
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -0
- package/claude/skills/codebase-layout/SKILL.md +6 -0
- package/claude/skills/create-rule/REQUIREMENT.md +1 -1
- package/claude/skills/create-standard/REQUIREMENT.md +0 -2
- package/claude/skills/decision-escalate/REQUIREMENT.md +1 -2
- package/claude/skills/draft-context/REQUIREMENT.md +1 -1
- package/claude/skills/draft-docs/REQUIREMENT.md +1 -1
- package/claude/skills/draft-wireframes/REQUIREMENT.md +1 -1
- package/claude/skills/git-pr/references/task-number.md +2 -0
- package/claude/skills/plan-intake/SKILL.md +1 -1
- package/claude/skills/target-setup/REQUIREMENT.md +2 -2
- package/claude/skills/target-setup/SKILL.md +1 -1
- package/claude/skills/target-setup/references/detect.md +1 -1
- package/claude/skills/target-setup/references/indexes.md +1 -5
- package/claude/skills/task-board/references/archive.md +1 -0
- package/docs/agents/commands.md +1 -3
- package/docs/agents/counts.md +1 -2
- package/docs/agents/docs.md +1 -1
- package/docs/agents/drift-surfaces.md +6 -4
- package/docs/agents/index.md +1 -1
- package/docs/agents/indexes.md +1 -1
- package/docs/agents/install-and-sync.md +1 -8
- package/docs/agents/markdown-audit.md +2 -2
- package/docs/agents/restated.md +7 -5
- package/docs/agents/review-classification.md +1 -2
- package/docs/agents/scripting.md +2 -3
- package/docs/agents/skills-reach.md +3 -3
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/tasks-archive.md +1 -1
- package/docs/agents/tasks.md +4 -0
- package/docs/target/index.md +4 -4
- package/docs/target/{target-migrations.md → migrations.md} +17 -1
- package/docs/target/{target-projects.md → projects.md} +5 -7
- package/docs/target/{target-scenarios.md → scenarios.md} +1 -1
- package/docs/target/{target-sync.md → sync.md} +4 -2
- package/docs/workflow/ai-workflow.md +3 -7
- package/docs/workflow/operating-model.md +4 -4
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -2
- package/docs/workflow/visual-design-workflow.md +5 -5
- package/docs/workflow/zshrc-aliases.md +1 -1
- package/package.json +1 -2
- package/scripts/core/check-plugin-boundary.sh +1 -1
- package/scripts/core/install-check.sh +3 -4
- package/scripts/core/regen-hero.sh +2 -9
- package/src/autoship/paths.ts +3 -5
- package/src/claude/cases/authoring.ts +1 -5
- package/src/claude/skills-reach.ts +1 -2
- package/src/cli.ts +0 -2
- package/src/commands/feedback-format.ts +0 -1
- package/src/commands/gov.ts +8 -7
- package/src/commands/labels.ts +3 -3
- package/src/commands/markdown.ts +2 -2
- package/src/commands/tasks.ts +82 -2
- package/src/counts/catalogs.ts +0 -16
- package/src/counts/scan.ts +1 -1
- package/src/docs/read.ts +25 -25
- package/src/gate/measures.ts +52 -0
- package/src/gate/stages.ts +9 -0
- package/src/gov/restated.ts +60 -22
- package/src/help.ts +0 -2
- package/src/init/steps.ts +1 -1
- package/src/labels/format.ts +2 -2
- package/src/migrate/skill-names.ts +4 -5
- package/src/secrets/shipped.ts +2 -2
- package/src/serve/static.ts +1 -2
- package/src/shipped/references.ts +7 -8
- package/src/sync/engine.ts +2 -2
- package/src/tasks/archive.ts +30 -0
- package/src/tasks/record.ts +106 -9
- package/standards/commit.md +1 -1
- package/standards/context.md +2 -0
- package/standards/docs.md +1 -0
- package/standards/index.md +0 -1
- package/standards/pr.md +1 -1
- package/standards/skill.md +1 -2
- package/standards/tasks.md +2 -2
- package/standards/wiki.md +2 -1
- package/tooling/base/reference.md +2 -2
- package/tooling/claude/reference.md +1 -1
- package/claude/skills/create-snippet/REQUIREMENT.md +0 -39
- package/claude/skills/create-snippet/SKILL.md +0 -30
- package/scripts/snippets/create.sh +0 -156
- package/snippets/align.md +0 -12
- package/snippets/claude/decision-memo.md +0 -39
- package/snippets/claude/feature-recap.md +0 -19
- package/snippets/claude/figma-steps.md +0 -24
- package/snippets/compact-summary.md +0 -5
- package/snippets/decision-help.md +0 -6
- package/snippets/meta-prompt.md +0 -14
- package/snippets/research-prompt.md +0 -7
- package/snippets/session-notes.md +0 -11
- package/snippets/snippets.toml +0 -5
- package/snippets/step-by-step.md +0 -10
- package/snippets/web-research.md +0 -21
- package/src/commands/snippets.ts +0 -90
- package/src/snippets/categories.ts +0 -66
- package/src/snippets/list.ts +0 -32
- package/src/snippets/presets.ts +0 -50
- package/standards/snippets.md +0 -76
package/docs/agents/tasks.md
CHANGED
|
@@ -60,6 +60,8 @@ canon tasks pull-request 673 --plan worktree-scratch-routing --json
|
|
|
60
60
|
|
|
61
61
|
A plan is matched on the token both spellings share, so `worktree-scratch-routing`, `feature-worktree-scratch-routing`, and `.canon/plans/feature-worktree-scratch-routing.md` all select the same task. The `action` field reports `added`, `appended`, `corrected`, or `unchanged`, which makes a rerun against the same number safe.
|
|
62
62
|
|
|
63
|
+
Run from a branch other than `main` or `master`, the verb also drops that branch from the task's `Pending branch:` line, along with every name its reflog says it was renamed from, and removes the line once it is empty. The renamed names matter because `git-ship` renames a nonconforming branch after `context-fold` wrote the marker. It does so on an `unchanged` run too, so a rerun repairs a marker left behind. The `pending` field lists the branches still on the line after the write.
|
|
64
|
+
|
|
63
65
|
Exit codes: `0` recorded, `1` refused. The `reason` field carries `no-board`, `no-match`, or `ambiguous`. `git-pr` skips silently on those three, because each is a case where a guessed write would archive the wrong task once the branch merges.
|
|
64
66
|
|
|
65
67
|
A malformed argument refuses as `bad-input` instead, which sits outside that set on purpose. `git-pr` derives the number by slicing whatever `gh pr create` printed, so a non-numeric value is reachable, and folding it into the swallowed set would lose the number with nothing reporting it.
|
|
@@ -82,6 +84,8 @@ canon tasks outcome --plan worktree-scratch-routing --close 2 --json
|
|
|
82
84
|
|
|
83
85
|
An outcome already closed comes back under `alreadyClosed` rather than refusing, so a rerun against the same positions changes nothing. A position past the end of the list refuses as `out-of-range`, since a caller counting wrong should hear about it rather than mark a neighbor.
|
|
84
86
|
|
|
87
|
+
A close that ticks at least one box from a branch other than `main` or `master` names that branch on a `Pending branch:` line, read from `git branch --show-current` in the working directory. The line holds the task against `canon tasks archive --pull-request` until `canon tasks pull-request` records that branch's own number. A detached HEAD, a trunk checkout, or a failed git read writes no line and refuses nothing. The `pending` field lists the branches on the line after the write.
|
|
88
|
+
|
|
85
89
|
Positions skip fenced blocks. A checkbox inside a sample a task displays is not an outcome the task claims, and counting one would shift every position after it. `canon tasks archive` reads the list through the same walker, so the two verbs cannot disagree about which checkboxes are outcomes.
|
|
86
90
|
|
|
87
91
|
Exit codes: `0` closed, `1` refused. The `reason` field adds `no-outcomes`, `out-of-range`, and `bad-input` to the three above.
|
package/docs/target/index.md
CHANGED
|
@@ -10,7 +10,7 @@ Scaffold, sync, and migrate a toolkit-managed project, with worked setups for th
|
|
|
10
10
|
|
|
11
11
|
## Agent surface
|
|
12
12
|
|
|
13
|
-
- [Target migrations](
|
|
14
|
-
- [Target projects](
|
|
15
|
-
- [Target scenarios](
|
|
16
|
-
- [Target sync](
|
|
13
|
+
- [Target migrations](migrations.md): One-time moves a project scaffolded under an older toolkit runs before its next sync
|
|
14
|
+
- [Target projects](projects.md): Scaffold, add domains later, and sync upstream drift in a toolkit-managed project
|
|
15
|
+
- [Target scenarios](scenarios.md): Worked setups for a markdown-heavy project, a web application, and a monorepo
|
|
16
|
+
- [Target sync](sync.md): Check what drifted in a toolkit-managed project and pull it in, per domain or all at once
|
|
@@ -6,7 +6,7 @@ category: Agent surface
|
|
|
6
6
|
|
|
7
7
|
# Target migrations
|
|
8
8
|
|
|
9
|
-
Each section below is a move a project runs once, when it was scaffolded before the change the section names. Run `canon upgrade` first, so the verb doing the move is the current one. For the recurring sync that follows, see [target sync](
|
|
9
|
+
Each section below is a move a project runs once, when it was scaffolded before the change the section names. Run `canon upgrade` first, so the verb doing the move is the current one. For the recurring sync that follows, see [target sync](sync.md).
|
|
10
10
|
|
|
11
11
|
## Move the records first, once
|
|
12
12
|
|
|
@@ -91,3 +91,19 @@ canon migrate surface-roots --write --json
|
|
|
91
91
|
The first line reports the plan and the second applies it, moving each surface with `git mv` so its history follows and repointing every tracked citation of one in the same run. See `canon docs agents` for the full file list rather than reading it here.
|
|
92
92
|
|
|
93
93
|
Neither `canon sync --check` nor any other command notices a surface still sitting at `.claude/`, so running this is on you rather than on a prompt from the toolkit.
|
|
94
|
+
|
|
95
|
+
## Delete the retired snippets, once
|
|
96
|
+
|
|
97
|
+
The toolkit retired snippets, deleting the catalog, the `canon snippets` verb, and the `create-snippet` skill. A project scaffolded while the domain still installed may hold a `.claude/snippets/` folder, which nothing reads any more. Find it with the reverse walk:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
canon sync --check . --json | jq '.reverse'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The walk checks both `.claude/snippets` and a root `snippets/`, since a toolkit old enough installed at the project root. Act on each entry by its verdict, whichever path it sits at:
|
|
104
|
+
|
|
105
|
+
- `dropped` is the toolkit's copy, unchanged, and deleting the folder is safe
|
|
106
|
+
- `unattributed` holds files the toolkit shipped under those names with content it never published, which is usually a copy the project edited, so read what changed before deleting anything
|
|
107
|
+
- `project` is content the project wrote under the same name, which the retirement does not reach, so leave it alone
|
|
108
|
+
|
|
109
|
+
The walk reads the toolkit's own history, so it needs a cloned toolkit. Installed from the registry it reports `historyUnavailable` and names nothing, so check for `.claude/snippets/` and a root `snippets/` by hand there, and treat what you find as `unattributed`.
|
|
@@ -104,8 +104,6 @@ Run `canon tooling list --json` and `canon gov list --json` to see the current c
|
|
|
104
104
|
|
|
105
105
|
No standard is written into the project. Each governance rule's authority line names `canon standards <name>`, which answers from the corpus inside the CLI's own package, and every toolkit skill names the copy in its own plugin root. `canon markdown audit` needs no standard at all, its ban set and checkpoints shipping with the package as data.
|
|
106
106
|
|
|
107
|
-
No snippet is written into the project either. `claude/snippets` in the plugin cache symlinks to the toolkit's own `snippets/`, so a session reaches one at its `@` reference with no install step, the same live resolution `claude/standards` gives a rule's authority line.
|
|
108
|
-
|
|
109
107
|
`governance` and `wiki` are skippable:
|
|
110
108
|
|
|
111
109
|
- `--skip governance`: leave `.claude/rules/` empty, so no coding standard loads on a file match. The preview names any `--add` rules the skip drops, and the run prints the `canon gov install <stack> <path>` command to add rules afterward, carrying those extras so one paste restores what the skip declined.
|
|
@@ -121,22 +119,22 @@ When a new need appears after scaffold, install the one domain without re-runnin
|
|
|
121
119
|
- Project-specific rule the toolkit does not ship: invoke `canon:create-rule`. It scaffolds a rule into `.claude/rules/project/` with a non-colliding number, and `canon gov sync` leaves it untouched. A rule placed under `.claude/rules/canon/` instead is deleted on the next sync, since that folder belongs to the toolkit.
|
|
122
120
|
- Index.md system for a markdown-heavy folder that emerged: invoke `canon:target-setup indexes`
|
|
123
121
|
|
|
124
|
-
Standards
|
|
122
|
+
Standards are not on that list, and there is nothing to add for them. They install into no project, by default or by flag, so a session reads one with `canon standards <name>`, resolving against the toolkit rather than a project copy. A project holding a `.claude/standards/` folder from an older toolkit is carrying a stale artifact nothing reads, and deleting it is safe. The toolkit retired snippets entirely, and [target migrations](migrations.md) covers the `.claude/snippets/` folder an older one left behind.
|
|
125
123
|
|
|
126
124
|
Per-domain mechanics live in the corresponding `docs/<domain>.md`. The skill body in `claude/skills/<skill>/SKILL.md` covers detection and preview.
|
|
127
125
|
|
|
128
126
|
## Sync upstream drift
|
|
129
127
|
|
|
130
|
-
When the toolkit updates, a target pulls changes per domain. A project scaffolded before a layout move runs the one-time moves in [target migrations](
|
|
128
|
+
When the toolkit updates, a target pulls changes per domain. A project scaffolded before a layout move runs the one-time moves in [target migrations](migrations.md) first. [Target sync](sync.md) then covers reading what drifted, the catch-all and targeted entry points, verifying a sync in the sandbox, and running one from an agent session.
|
|
131
129
|
|
|
132
130
|
## Scenarios
|
|
133
131
|
|
|
134
|
-
[Target scenarios](
|
|
132
|
+
[Target scenarios](scenarios.md) walks a markdown-heavy project, a web application, and a monorepo with several language roots from the first session through ongoing maintenance.
|
|
135
133
|
|
|
136
134
|
## Related
|
|
137
135
|
|
|
138
136
|
- [agents](../agents/index.md): CLI flags, exit codes, and JSON output shapes
|
|
139
|
-
- [target migrations](
|
|
137
|
+
- [target migrations](migrations.md), [target sync](sync.md), [target scenarios](scenarios.md): the one-time moves, the recurring sync, and worked setups
|
|
140
138
|
- [AI workflow](../workflow/ai-workflow.md): feature-development loop inside a toolkit-managed project
|
|
141
|
-
- [tooling](../../canon/context/tooling/index.md), [governance](../../canon/context/governance/index.md), [claude plugin](../../canon/context/claude-plugin/index.md), [indexes](../../canon/context/
|
|
139
|
+
- [tooling](../../canon/context/tooling/index.md), [governance](../../canon/context/governance/index.md), [claude plugin](../../canon/context/claude-plugin/index.md), [indexes](../../canon/context/context-model/indexes.md), [standards](../../canon/context/standards/index.md): per-domain mechanics
|
|
142
140
|
- [sandbox](../../canon/context/sandbox/index.md): scenario catalog for verifying domain flows
|
|
@@ -6,7 +6,7 @@ category: Agent surface
|
|
|
6
6
|
|
|
7
7
|
# Target scenarios
|
|
8
8
|
|
|
9
|
-
Three worked setups, each from the first session through ongoing maintenance. [Target projects](
|
|
9
|
+
Three worked setups, each from the first session through ongoing maintenance. [Target projects](projects.md) carries the lifecycle they walk.
|
|
10
10
|
|
|
11
11
|
## Markdown-heavy project
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@ category: Agent surface
|
|
|
6
6
|
|
|
7
7
|
# Target sync
|
|
8
8
|
|
|
9
|
-
When the toolkit updates, a target project pulls changes per domain. There is one catch-all and several targeted entry points. A project scaffolded before a layout move runs the one-time moves in [target migrations](
|
|
9
|
+
When the toolkit updates, a target project pulls changes per domain. There is one catch-all and several targeted entry points. A project scaffolded before a layout move runs the one-time moves in [target migrations](migrations.md) first.
|
|
10
10
|
|
|
11
11
|
## Check first
|
|
12
12
|
|
|
@@ -30,7 +30,7 @@ A project that has never synced under a toolkit new enough to write a stamp fall
|
|
|
30
30
|
|
|
31
31
|
Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and reconciled with `canon:seed-sync`, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.canon/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself.
|
|
32
32
|
|
|
33
|
-
`unmigrated` currently names no domain, since standards and snippets are the two the toolkit ever installed at the project root
|
|
33
|
+
`unmigrated` currently names no domain, since standards and snippets are the two the toolkit ever installed at the project root, standards closed its install channel, and snippets retired outright. A target still holding a root `standards/` folder from an older toolkit is carrying its own authoring surface now, not an unfinished install, and nothing proposes moving it. A leftover `.claude/snippets/` reports under `reverse` below instead.
|
|
34
34
|
|
|
35
35
|
### Rules you never received
|
|
36
36
|
|
|
@@ -56,6 +56,8 @@ Each entry carries a verdict, since a dropped folder and one the project wrote a
|
|
|
56
56
|
- `unattributed` means the toolkit shipped that path and the content matches no version it published
|
|
57
57
|
- `project` means the folder only shares a retired name
|
|
58
58
|
|
|
59
|
+
A `.claude/snippets/` folder an older toolkit installed is the case this walk exists for, since the toolkit retired the domain and deleted its `snippets/` root. It reports as `dropped`, and [target migrations](migrations.md) says what to do with it.
|
|
60
|
+
|
|
59
61
|
Nothing acts on any of them, and the verdict is what makes the list safe to read.
|
|
60
62
|
|
|
61
63
|
Add `--json` for the machine-readable report, and `--exit-code` to fail a CI job when a target falls behind. Files the project authored itself never count toward that exit code, and neither do superseded artifacts, seed drift, tooling, or anything the reverse walk reports, since each names content the project is expected to edit or place itself. An unmigrated domain does count, because running the relocation closes it.
|
|
@@ -36,7 +36,7 @@ canon/
|
|
|
36
36
|
|
|
37
37
|
A project scaffolded before the move keeps its records under `.claude/`, and every command reads either root. `canon migrate records` moves one project across and repoints what cites it, and `canon migrate record-tree` follows it to reach the citations inside the records themselves, which the first verb passes over because it enumerates through git. A project scaffolded before the surface move keeps its context, decisions, wireframes, and loose documents under `.claude/` the same way, and `canon migrate surface-roots` moves those to `canon/` with the history following each file.
|
|
38
38
|
|
|
39
|
-
Three tiers of context load with different cost: always-loaded (root `CLAUDE.md`, `canon/REQUIREMENTS.md`, `canon/ARCHITECTURE.md`), path-scoped lazy (`.claude/rules/<scope>.md` with `paths:` glob), and on-demand lookup (`canon/context/<domain>.md`, or `canon/context/<domain>/` once a domain outgrows one file, discovered via `canon/context/index.md`). See [the context model](../../canon/context/context-model.md) for the full picture.
|
|
39
|
+
Three tiers of context load with different cost: always-loaded (root `CLAUDE.md`, `canon/REQUIREMENTS.md`, `canon/ARCHITECTURE.md`), path-scoped lazy (`.claude/rules/<scope>.md` with `paths:` glob), and on-demand lookup (`canon/context/<domain>.md`, or `canon/context/<domain>/` once a domain outgrows one file, discovered via `canon/context/index.md`). See [the context model](../../canon/context/context-model/overview.md) for the full picture.
|
|
40
40
|
|
|
41
41
|
Run `canon init` to seed the `.claude/` directory, a root `CLAUDE.md` file, and `.claude/rules/` in one pass. `canon init` chains claude init and governance install. Claude Code auto-loads every file in `.claude/rules/` at session start, applying always-on rules unconditionally and path-scoped rules to files matching their `paths:` glob.
|
|
42
42
|
|
|
@@ -44,7 +44,7 @@ Run `canon init` to seed the `.claude/` directory, a root `CLAUDE.md` file, and
|
|
|
44
44
|
|
|
45
45
|
### Bootstrap a new project
|
|
46
46
|
|
|
47
|
-
See [target projects](../target/
|
|
47
|
+
See [target projects](../target/projects.md) for the scaffold decision, core domains and skips, and the full lifecycle across scaffold, add-a-domain-later, and upstream sync.
|
|
48
48
|
|
|
49
49
|
### New feature
|
|
50
50
|
|
|
@@ -95,7 +95,7 @@ For features on a mature stack, chain the post-plan pipeline in one session. App
|
|
|
95
95
|
|
|
96
96
|
Review findings split by origin before severity is read. One the branch inherited stops the chain, and one the run itself caused is repaired in place at any severity, bounded at a single pass. Origin is causation rather than authorship, so staleness the run induced in a file it never opened counts as its own and the plan's file list bounds what it builds rather than what it may repair.
|
|
97
97
|
|
|
98
|
-
Review is skipped when the diff is prose that only informs: every changed file matches `*.md` or `*.txt`, and none sits under a behavior path. Behavior paths cover skills and rules in both the authoring and the installed spelling, so the list matches whether a repository authors those surfaces or consumed them from the toolkit. Standards,
|
|
98
|
+
Review is skipped when the diff is prose that only informs: every changed file matches `*.md` or `*.txt`, and none sits under a behavior path. Behavior paths cover skills and rules in both the authoring and the installed spelling, so the list matches whether a repository authors those surfaces or consumed them from the toolkit. Standards, `internal/`, and `tooling/` carry the authoring spelling alone, since none of the three reaches a session through a `.claude/` copy, and root `CLAUDE.md` is named as a file because a path prefix reaches nothing sitting in no folder.
|
|
99
99
|
|
|
100
100
|
Markdown under one states what an agent does, so a branch touching it reaches review while `docs/` and `wiki/` still skip and stay gated by `docs-sync`, `standards-audit`, and pre-push hooks.
|
|
101
101
|
|
|
@@ -146,7 +146,3 @@ verify fails → Session 1 (it has implementation context)
|
|
|
146
146
|
design fails → new Claude chat session (planning problem)
|
|
147
147
|
review finds → Session 2 (fix alongside review, before ship)
|
|
148
148
|
```
|
|
149
|
-
|
|
150
|
-
## Snippets
|
|
151
|
-
|
|
152
|
-
For the full list of snippets that complement this workflow, see `canon/context/snippets.md`.
|
|
@@ -12,7 +12,7 @@ cross-feature call and reviews. Planning runs there or in a session of its own.
|
|
|
12
12
|
Cold worker sessions build. The human launches workers and merges.
|
|
13
13
|
|
|
14
14
|
This page covers the roles and the loop. For the worktree mechanism (isolation, merge
|
|
15
|
-
order, port collisions), see [Claude Code and git worktrees](../../wiki/claude/
|
|
15
|
+
order, port collisions), see [Claude Code and git worktrees](../../wiki/claude/worktrees.md).
|
|
16
16
|
|
|
17
17
|
## Four roles
|
|
18
18
|
|
|
@@ -226,11 +226,11 @@ A dev server, an end-to-end run, and a screenshot run alongside each other on a
|
|
|
226
226
|
web stack, since every worktree derives its own port. Singleton resources (one
|
|
227
227
|
local model server, one GPU) still serialize, as does any port a stack fixes by
|
|
228
228
|
hand. See
|
|
229
|
-
[Claude Code and git worktrees](../../wiki/claude/
|
|
229
|
+
[Claude Code and git worktrees](../../wiki/claude/worktrees.md) for merge order and the
|
|
230
230
|
port-collision detail.
|
|
231
231
|
|
|
232
232
|
## Related
|
|
233
233
|
|
|
234
|
-
- [Claude Code and git worktrees](../../wiki/claude/
|
|
235
|
-
- [Claude Code subagents](../../wiki/claude/
|
|
234
|
+
- [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for the isolation and fan-out mechanics
|
|
235
|
+
- [Claude Code subagents](../../wiki/claude/subagents.md) for in-session parallelism without worktrees
|
|
236
236
|
- `canon/context/claude-plugin/skill-strategy/overview.md` for how the skills in the loop are categorized
|
|
@@ -32,7 +32,7 @@ A constraint naming a track in flight carries the same problem past the handoff,
|
|
|
32
32
|
|
|
33
33
|
## Records at the main root
|
|
34
34
|
|
|
35
|
-
`.canon/plans/`, `.canon/review/`, and `.canon/memory/` all resolve at the main worktree root, so artifacts created in any session are visible from any sibling worktree. A session inside a worktree reads them directly, since the file-editing tools refuse a main-root path but `Read` resolves normally. It writes a whole file through the shell and makes a change inside an existing file through a `canon` verb, which resolves the main root in-process. See [Claude Code and git worktrees](../../wiki/claude/
|
|
35
|
+
`.canon/plans/`, `.canon/review/`, and `.canon/memory/` all resolve at the main worktree root, so artifacts created in any session are visible from any sibling worktree. A session inside a worktree reads them directly, since the file-editing tools refuse a main-root path but `Read` resolves normally. It writes a whole file through the shell and makes a change inside an existing file through a `canon` verb, which resolves the main root in-process. See [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for the full rule and the domain-level fan-out guidance.
|
|
36
36
|
|
|
37
37
|
The plan's shape is fixed by `standards/plan.md`: the section list, the filename, the lifecycle, and the contract its questions keep. Every question carries a `- Suggested:` line and an empty `- Answer:` slot, and a blank answer accepts the suggestion at execution time. That default is what makes a plan decision-ready in one pass, and it is the opposite of the contract an intake folder keeps, where an empty slot means nobody reached the item.
|
|
38
38
|
|
|
@@ -6,7 +6,7 @@ category: Workflow
|
|
|
6
6
|
|
|
7
7
|
# Skill map
|
|
8
8
|
|
|
9
|
-
Groups run in the order a project meets them, so a reader at a known point scans to that group and reads across. The set reconciles the scenarios in [AI workflow](ai-workflow.md) with the lifecycle [target projects](../target/
|
|
9
|
+
Groups run in the order a project meets them, so a reader at a known point scans to that group and reads across. The set reconciles the scenarios in [AI workflow](ai-workflow.md) with the lifecycle [target projects](../target/projects.md) describes, rather than inventing a third vocabulary beside those two, so a group name matches neither source exactly and every moment either one names has a group. Each row says when to reach for the skill. What it does is the skill's own description.
|
|
10
10
|
|
|
11
11
|
This page is the corpus the coverage claim is measured against: every name `canon claude skills list --names` reports takes exactly one row here. A skill serving two moments sits at the earlier one, and a mention on any other page is prose rather than routing.
|
|
12
12
|
|
|
@@ -115,7 +115,6 @@ This page is the corpus the coverage claim is measured against: every name `cano
|
|
|
115
115
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
116
116
|
| `canon:create-rule` | For a project-specific governance rule the toolkit does not ship |
|
|
117
117
|
| `canon:create-skill` | For a new `SKILL.md` |
|
|
118
|
-
| `canon:create-snippet` | For a reusable prompt |
|
|
119
118
|
| `canon:create-standard` | For a new authoring convention |
|
|
120
119
|
| `canon:draft-docs` | For a brand-new `docs/*.md` page, drafted against `standards/docs.md` |
|
|
121
120
|
| `canon:draft-ready` | For finished files a worker should copy, written as a ready folder with its overview, thin plan, and task |
|
|
@@ -8,9 +8,9 @@ category: Workflow
|
|
|
8
8
|
|
|
9
9
|
Three tiers cover the range from prose-only design docs to a fully graphical design source of truth. Pick one per project based on how UI-heavy the work is, whether stakeholders review visuals, and whether a designer is involved. Tiers stack, so moving up does not invalidate work done at a lower tier.
|
|
10
10
|
|
|
11
|
-
The tier framework sits alongside [Claude Design](../../wiki/claude/
|
|
11
|
+
The tier framework sits alongside [Claude Design](../../wiki/claude/design.md), the one catalog page in this range. Stitch, Excalidraw, and the surrounding MCP and skill ecosystem are named inline below rather than catalogued separately. This page decides when to reach for what.
|
|
12
12
|
|
|
13
|
-
Two tools anchor tier 1 and tier 2. Stitch is the agent-addressable default through its MCP server at `stitch.googleapis.com/mcp`, with a free tier of 400 daily credits that covers daily iteration. [Claude Design](../../wiki/claude/
|
|
13
|
+
Two tools anchor tier 1 and tier 2. Stitch is the agent-addressable default through its MCP server at `stitch.googleapis.com/mcp`, with a free tier of 400 daily credits that covers daily iteration. [Claude Design](../../wiki/claude/design.md), released 2026-04-17 and priced inside Claude subscriptions, is the ceiling tool reserved for codebase extraction and the richly annotated handoff bundle. Each covers a different job, they are not swappable.
|
|
14
14
|
|
|
15
15
|
## Tier 0: prose only
|
|
16
16
|
|
|
@@ -74,7 +74,7 @@ Impeccable, if installed, keeps its own root `DESIGN.md` and `PRODUCT.md` in the
|
|
|
74
74
|
- Excalidraw canvas server on localhost plus the community [`yctimlin/mcp_excalidraw`](https://github.com/yctimlin/mcp_excalidraw) MCP shim, for projects that need an agent to draw, read back, and revise a canvas. MIT-licensed, plaintext JSON scene format. `describe_scene` and `get_canvas_screenshot` let the agent verify its own layout before claiming it is correct.
|
|
75
75
|
- Playwright MCP ([`microsoft/playwright-mcp`](https://github.com/microsoft/playwright-mcp)) for browser-side verification, driven off the accessibility tree rather than screenshots.
|
|
76
76
|
- Chrome DevTools MCP ([`ChromeDevTools/chrome-devtools-mcp`](https://github.com/ChromeDevTools/chrome-devtools-mcp)) for live frontend debugging: performance traces, network inspection, and DOM and CSS inspection.
|
|
77
|
-
- Claude Design as the ceiling option for codebase extraction or polished handoff bundles. See [Claude Design](../../wiki/claude/
|
|
77
|
+
- Claude Design as the ceiling option for codebase extraction or polished handoff bundles. See [Claude Design](../../wiki/claude/design.md).
|
|
78
78
|
|
|
79
79
|
### Skills
|
|
80
80
|
|
|
@@ -111,7 +111,7 @@ Design happens in a graphical tool. `canon/DESIGN.md` either regenerates from th
|
|
|
111
111
|
### Tools
|
|
112
112
|
|
|
113
113
|
- Figma desktop app with the official [Figma Dev Mode MCP](https://www.figma.com/blog/introducing-claude-code-to-figma/) for teams with a dedicated designer already on Figma. Bidirectional sync and Code to Canvas capture of a running Claude Code UI into editable Figma frames.
|
|
114
|
-
- Claude Design with its Claude Code handoff bundle for teams without an existing Figma investment and for solo founders or PMs driving design themselves. One-way handoff, no bidirectional sync. See [Claude Design](../../wiki/claude/
|
|
114
|
+
- Claude Design with its Claude Code handoff bundle for teams without an existing Figma investment and for solo founders or PMs driving design themselves. One-way handoff, no bidirectional sync. See [Claude Design](../../wiki/claude/design.md).
|
|
115
115
|
- Stitch via MCP as a low-cost complement to either, used for bulk screen generation driven by Claude Code.
|
|
116
116
|
- Playwright and Chrome DevTools MCPs as in tier 1
|
|
117
117
|
|
|
@@ -149,7 +149,7 @@ Resist over-tiering early. Moving up is cheap because tiers stack. Moving down m
|
|
|
149
149
|
|
|
150
150
|
## References
|
|
151
151
|
|
|
152
|
-
- [Claude Design](../../wiki/claude/
|
|
152
|
+
- [Claude Design](../../wiki/claude/design.md): first-party hosted design product and handoff bundle
|
|
153
153
|
- `canon/context/claude-plugin/skill-strategy/overview.md`: how to decide between workflow and domain-knowledge skills
|
|
154
154
|
- [`microsoft/playwright-mcp`](https://github.com/microsoft/playwright-mcp): browser automation MCP used in tier 1 and tier 2
|
|
155
155
|
- [`ChromeDevTools/chrome-devtools-mcp`](https://github.com/ChromeDevTools/chrome-devtools-mcp): live frontend debugging MCP used in tier 1 and tier 2
|
|
@@ -68,7 +68,7 @@ Use `clp` in any other repository where you want the toolkit skills available. W
|
|
|
68
68
|
|
|
69
69
|
Use `cls` or `clps` to save Opus usage on routine sessions. Switch mid-session with `/model` to avoid restarting.
|
|
70
70
|
|
|
71
|
-
Use `clw <name>` for features that will take more than one session. A worktree isolates the branch, the transcripts, and the `/resume` history. See [Claude Code and git worktrees](../../wiki/claude/
|
|
71
|
+
Use `clw <name>` for features that will take more than one session. A worktree isolates the branch, the transcripts, and the `/resume` history. See [Claude Code and git worktrees](../../wiki/claude/worktrees.md) for fan-out rules.
|
|
72
72
|
|
|
73
73
|
Use `clc` to resume the last session without a picker. Use `clr` when you have several sessions and need to pick by name or recency. Reach for `clpc` over `clc` wherever the resumed session needs the plugin, inside the toolkit repository as well as outside it, since neither resume re-runs discovery.
|
|
74
74
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erclx/canon",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "5.1.0",
|
|
5
5
|
"description": "Infrastructure and quality tooling for developer workflows",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"src",
|
|
12
12
|
"scripts",
|
|
13
13
|
"standards",
|
|
14
|
-
"snippets",
|
|
15
14
|
"governance",
|
|
16
15
|
"tooling",
|
|
17
16
|
"claude",
|
|
@@ -24,7 +24,7 @@ if ! command -v realpath >/dev/null 2>&1; then
|
|
|
24
24
|
exit 1
|
|
25
25
|
fi
|
|
26
26
|
|
|
27
|
-
# The plugin reaches `standards/`
|
|
27
|
+
# The plugin reaches `standards/` through a symlink, which an
|
|
28
28
|
# installer dereferences with no code in the path to filter. Walking the plugin
|
|
29
29
|
# tree with symlinks followed is what an install actually copies, so resolving
|
|
30
30
|
# each file and rejecting anything under `internal/` asserts the boundary at the
|
|
@@ -88,10 +88,9 @@ log_step "Assert scaffold"
|
|
|
88
88
|
# catches a failed domain, and the gate stays green while the target is
|
|
89
89
|
# missing everything that domain provides.
|
|
90
90
|
#
|
|
91
|
-
# Standards
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# against the toolkit rather than a copy this gate could assert on. The two
|
|
91
|
+
# Standards name no path because that corpus never installs into a target. A
|
|
92
|
+
# scaffold reads a standard through `canon standards <name>`, resolving against
|
|
93
|
+
# the toolkit rather than a copy this gate could assert on. The two
|
|
95
94
|
# rule paths stand for the `claude` and `canon` groups `base` takes whole.
|
|
96
95
|
for path in "CLAUDE.md" ".claude/wiki/index.md" ".claude" "canon/context/index.md" "canon/wireframes/index.md" ".canon/diagrams/index.md" \
|
|
97
96
|
".prettierrc" ".editorconfig" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.sh" \
|
|
@@ -94,10 +94,9 @@ COUNTS_JSON="$(catalog gov counts || true)"
|
|
|
94
94
|
SKILLS_JSON="$(catalog claude skills list)"
|
|
95
95
|
GOV_JSON="$(catalog gov list)"
|
|
96
96
|
STANDARDS_JSON="$(catalog standards list)"
|
|
97
|
-
SNIPPETS_JSON="$(catalog snippets list)"
|
|
98
97
|
TOOLING_JSON="$(catalog tooling list)"
|
|
99
98
|
|
|
100
|
-
for payload in "$COUNTS_JSON" "$SKILLS_JSON" "$GOV_JSON" "$STANDARDS_JSON" "$
|
|
99
|
+
for payload in "$COUNTS_JSON" "$SKILLS_JSON" "$GOV_JSON" "$STANDARDS_JSON" "$TOOLING_JSON"; do
|
|
101
100
|
if [ -z "$payload" ]; then
|
|
102
101
|
echo "regen-hero: a catalog returned nothing, refusing to write a zeroed hero" >&2
|
|
103
102
|
exit 1
|
|
@@ -115,7 +114,6 @@ printf '%s' "$COUNTS_JSON" >"$PAYLOAD_DIR/counts.json"
|
|
|
115
114
|
printf '%s' "$SKILLS_JSON" >"$PAYLOAD_DIR/skills.json"
|
|
116
115
|
printf '%s' "$GOV_JSON" >"$PAYLOAD_DIR/gov.json"
|
|
117
116
|
printf '%s' "$STANDARDS_JSON" >"$PAYLOAD_DIR/standards.json"
|
|
118
|
-
printf '%s' "$SNIPPETS_JSON" >"$PAYLOAD_DIR/snippets.json"
|
|
119
117
|
printf '%s' "$TOOLING_JSON" >"$PAYLOAD_DIR/tooling.json"
|
|
120
118
|
printf '%s' "$TOKEN_CSS" >"$PAYLOAD_DIR/tokens.css"
|
|
121
119
|
|
|
@@ -141,7 +139,6 @@ const COUNTS_JSON = payload("counts")
|
|
|
141
139
|
const SKILLS_JSON = payload("skills")
|
|
142
140
|
const GOV_JSON = payload("gov")
|
|
143
141
|
const STANDARDS_JSON = payload("standards")
|
|
144
|
-
const SNIPPETS_JSON = payload("snippets")
|
|
145
142
|
const TOOLING_JSON = payload("tooling")
|
|
146
143
|
|
|
147
144
|
const listed = Number(LISTED)
|
|
@@ -157,9 +154,6 @@ const rules = gov.rules.map(slug)
|
|
|
157
154
|
const stacked = new Set(gov.stacks.flatMap((stack) => stack.rules))
|
|
158
155
|
const deliveredRules = gov.rules.filter((entry) => stacked.has(entry.name)).map(slug)
|
|
159
156
|
const standards = JSON.parse(STANDARDS_JSON).standards.map((entry) => entry.name)
|
|
160
|
-
const snippets = new Set(
|
|
161
|
-
JSON.parse(SNIPPETS_JSON).categories.flatMap((category) => category.entries),
|
|
162
|
-
)
|
|
163
157
|
const toolingStacks = JSON.parse(TOOLING_JSON).stacks
|
|
164
158
|
const commandCount = JSON.parse(COUNTS_JSON).catalogs.commands
|
|
165
159
|
if (!commandCount) {
|
|
@@ -247,7 +241,7 @@ const remaining = (names) => String(Math.max(0, names.length - listed))
|
|
|
247
241
|
// frame claiming the domain has nothing in it.
|
|
248
242
|
for (const [label, list] of [
|
|
249
243
|
["skills", skills], ["rules", rules], ["standards", standards],
|
|
250
|
-
["
|
|
244
|
+
["tooling stacks", toolingStacks], ["gov stacks", gov.stacks],
|
|
251
245
|
["stack-delivered rules", deliveredRules],
|
|
252
246
|
]) {
|
|
253
247
|
if (list.length === 0) {
|
|
@@ -354,7 +348,6 @@ const values = {
|
|
|
354
348
|
SKILL_COUNT: String(skills.length),
|
|
355
349
|
RULE_COUNT: String(rules.length),
|
|
356
350
|
STANDARD_COUNT: String(standards.length),
|
|
357
|
-
SNIPPET_COUNT: String(snippets.size),
|
|
358
351
|
GOV_STACK_COUNT: String(gov.stacks.length),
|
|
359
352
|
TOOLING_STACK_COUNT: String(toolingStacks.length),
|
|
360
353
|
COMMAND_COUNT: String(commandCount),
|
package/src/autoship/paths.ts
CHANGED
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Most carry two spellings, the one a surface authors at and the one it reaches
|
|
18
18
|
* a session at, so the rule reads the same in this toolkit and in a project
|
|
19
|
-
* that consumed one. `standards/`
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* name.
|
|
19
|
+
* that consumed one. `standards/` carries one: it never installs into a
|
|
20
|
+
* project, reaching a reader by resolution, so no `.claude/` spelling exists
|
|
21
|
+
* to name.
|
|
23
22
|
*/
|
|
24
23
|
export const BEHAVIOR_PREFIXES = [
|
|
25
24
|
'claude/skills/',
|
|
@@ -27,7 +26,6 @@ export const BEHAVIOR_PREFIXES = [
|
|
|
27
26
|
'governance/rules/',
|
|
28
27
|
'.claude/rules/',
|
|
29
28
|
'standards/',
|
|
30
|
-
'snippets/',
|
|
31
29
|
'internal/',
|
|
32
30
|
'tooling/',
|
|
33
31
|
] as const
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SkillCase } from '@/claude/skills-rank'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Script, skill,
|
|
4
|
+
* Script, skill, standard, and doc authoring, plus the two prose
|
|
5
5
|
* skills that revise rather than generate.
|
|
6
6
|
*/
|
|
7
7
|
export const AUTHORING_CASES: readonly SkillCase[] = [
|
|
@@ -24,10 +24,6 @@ export const AUTHORING_CASES: readonly SkillCase[] = [
|
|
|
24
24
|
prompt: 'Scaffold a brand-new SKILL.md for this capability.',
|
|
25
25
|
expect: 'create-skill',
|
|
26
26
|
},
|
|
27
|
-
{
|
|
28
|
-
prompt: 'I need a new reusable prompt snippet added to the corpus.',
|
|
29
|
-
expect: 'create-snippet',
|
|
30
|
-
},
|
|
31
27
|
{
|
|
32
28
|
prompt: 'Write a fresh authoring convention as a new standard file.',
|
|
33
29
|
expect: 'create-standard',
|
|
@@ -7,7 +7,7 @@ import { SURFACE_ROOTS } from '@/surface-root'
|
|
|
7
7
|
* The authoring roots this repository owns and no install channel delivers.
|
|
8
8
|
*
|
|
9
9
|
* Every entry is a folder a target never holds under that spelling. Standards
|
|
10
|
-
*
|
|
10
|
+
* install nowhere and are reached through the plugin corpus,
|
|
11
11
|
* rules install under `.claude/rules/`, and the rest are this repository's
|
|
12
12
|
* own source, docs, and catalogs.
|
|
13
13
|
*
|
|
@@ -28,7 +28,6 @@ const AUTHORING_ROOTS = [
|
|
|
28
28
|
'docs/agents/',
|
|
29
29
|
'governance/',
|
|
30
30
|
'internal/',
|
|
31
|
-
'snippets/',
|
|
32
31
|
'standards/',
|
|
33
32
|
'tooling/',
|
|
34
33
|
'wiki/',
|
package/src/cli.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { register as sandbox } from '@/commands/sandbox'
|
|
|
6
6
|
import { register as sync } from '@/commands/sync'
|
|
7
7
|
import { register as gov } from '@/commands/gov'
|
|
8
8
|
import { register as standards } from '@/commands/standards'
|
|
9
|
-
import { register as snippets } from '@/commands/snippets'
|
|
10
9
|
import { register as tooling } from '@/commands/tooling'
|
|
11
10
|
import { register as claude } from '@/commands/claude'
|
|
12
11
|
import { register as wiki } from '@/commands/wiki'
|
|
@@ -67,7 +66,6 @@ sandbox(program)
|
|
|
67
66
|
sync(program)
|
|
68
67
|
gov(program)
|
|
69
68
|
standards(program)
|
|
70
|
-
snippets(program)
|
|
71
69
|
tooling(program)
|
|
72
70
|
claude(program)
|
|
73
71
|
wiki(program)
|
|
@@ -98,7 +98,6 @@ const DOMAIN_LABELS: readonly { pattern: RegExp; label: string }[] = [
|
|
|
98
98
|
{ pattern: /\b(?:cli)s?\b/, label: 'cli' },
|
|
99
99
|
{ pattern: /\b(?:tooling|seeds?)\b/, label: 'tooling' },
|
|
100
100
|
{ pattern: /\b(?:governance)s?\b/, label: 'governance' },
|
|
101
|
-
{ pattern: /\bsnippets?\b/, label: 'snippets' },
|
|
102
101
|
]
|
|
103
102
|
|
|
104
103
|
/**
|
package/src/commands/gov.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
type RestatedRefusal,
|
|
28
28
|
type RestatedReport,
|
|
29
29
|
readRestated,
|
|
30
|
-
|
|
30
|
+
PROJECT_SKILLS_REL,
|
|
31
31
|
SEED_REL,
|
|
32
32
|
SHIPPED_SKILLS_REL,
|
|
33
33
|
} from '@/gov/restated'
|
|
@@ -123,7 +123,7 @@ interface CountsOptions {
|
|
|
123
123
|
/** What a reader does about each way the sweep produced no reading. */
|
|
124
124
|
const RESTATED_REFUSALS: Record<RestatedRefusal, string> = {
|
|
125
125
|
'no-instructions': `No ${INSTRUCTIONS_REL} here, or it carries no bullet, so there is no instruction corpus to sweep.`,
|
|
126
|
-
'no-surfaces': `None of ${SEED_REL}, ${SHIPPED_SKILLS_REL}/,
|
|
126
|
+
'no-surfaces': `None of ${SEED_REL}, ${SHIPPED_SKILLS_REL}/, ${PROJECT_SKILLS_REL}/, ${RULE_DIRS.join('/, or ')}/ is here, so no further surface exists to match against.`,
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
const COUNTS_REFUSALS: Record<CountsRefusal, string> = {
|
|
@@ -275,8 +275,8 @@ export function register(program: Command): void {
|
|
|
275
275
|
'members a closed catalog holds, then compares the stated figure',
|
|
276
276
|
'against what the tree actually counts.',
|
|
277
277
|
'',
|
|
278
|
-
'Catalogs read: skills, governance rules, standards,
|
|
279
|
-
'
|
|
278
|
+
'Catalogs read: skills, governance rules, standards, CLI commands,',
|
|
279
|
+
'and audit ids. Closed rather than derived, so widening the',
|
|
280
280
|
'set is a deliberate change rather than a side effect of a new list',
|
|
281
281
|
'command shipping elsewhere.',
|
|
282
282
|
'',
|
|
@@ -469,8 +469,9 @@ export function register(program: Command): void {
|
|
|
469
469
|
[
|
|
470
470
|
'',
|
|
471
471
|
`Matches every bullet in ${INSTRUCTIONS_REL} and every rule under`,
|
|
472
|
-
`${
|
|
473
|
-
|
|
472
|
+
`${RULE_DIRS.join('/ and ')}/ against ${SEED_REL},`,
|
|
473
|
+
`every ${SHIPPED_SKILLS_REL}/*/SKILL.md and ${PROJECT_SKILLS_REL}/*/SKILL.md body,`,
|
|
474
|
+
'and every other rule. Matching is',
|
|
474
475
|
'recall-first, keyed on distinctive tokens two statements share rather',
|
|
475
476
|
'than on a phrase they spell the same way, because the case this exists',
|
|
476
477
|
'for was one rule written three different ways.',
|
|
@@ -564,7 +565,7 @@ function reportRestated(
|
|
|
564
565
|
// also says how wide the corpus behind it was.
|
|
565
566
|
logStep('Corpus')
|
|
566
567
|
logInfo(
|
|
567
|
-
`${report.corpus.instructions} always-loaded instruction(s) and ${report.corpus.rules} rule file(s) against ${report.corpus.candidates} statement(s) from the seed, ${report.corpus.bodies}
|
|
568
|
+
`${report.corpus.instructions} always-loaded instruction(s) and ${report.corpus.rules} rule file(s) against ${report.corpus.candidates} statement(s) from the seed, ${report.corpus.bodies} skill body/bodies, and every rule again, in ${root}`,
|
|
568
569
|
)
|
|
569
570
|
logInfo(
|
|
570
571
|
`matched on ${report.matcher.anchors} weighted anchor(s), dropping any token in more than ${report.matcher.common} statements`,
|
package/src/commands/labels.ts
CHANGED
|
@@ -25,7 +25,7 @@ interface ScanOptions {
|
|
|
25
25
|
|
|
26
26
|
/** What a reader does about each way `checkTitleFormat` graded a title as broken. */
|
|
27
27
|
const TITLE_FORMAT_MESSAGES: Record<TitleFormatIssue, string> = {
|
|
28
|
-
structure: 'does not match <type>(<scope>): <subject>',
|
|
28
|
+
structure: 'does not match <type>(<scope>)[!]: <subject>',
|
|
29
29
|
'casing-type': 'the type is not lowercase',
|
|
30
30
|
'casing-scope': 'the scope is not lowercase',
|
|
31
31
|
'casing-subject': 'the first word of the subject is not lowercase',
|
|
@@ -153,7 +153,7 @@ export function register(program: Command): void {
|
|
|
153
153
|
'forcing a new dependency.',
|
|
154
154
|
'',
|
|
155
155
|
"It also grades the title alone against standards/pr.md's ## Title",
|
|
156
|
-
'section: the `<type>(<scope>): <subject>` structure, lowercase casing',
|
|
156
|
+
'section: the `<type>(<scope>)[!]: <subject>` structure, lowercase casing',
|
|
157
157
|
'for the type, the scope, and the first subject word, and a 72-',
|
|
158
158
|
'character length cap. A scan given no title, whether from a review',
|
|
159
159
|
'or from a bare --body or --body-file invocation, skips this check',
|
|
@@ -374,7 +374,7 @@ async function runScan(opts: ScanOptions): Promise<number> {
|
|
|
374
374
|
logInfo('the scan carries no title, so there is no format to grade')
|
|
375
375
|
} else if (titleFormat.conforms) {
|
|
376
376
|
logInfo(
|
|
377
|
-
'the title matches <type>(<scope>): <subject> and its casing and length rules',
|
|
377
|
+
'the title matches <type>(<scope>)[!]: <subject> and its casing and length rules',
|
|
378
378
|
)
|
|
379
379
|
} else {
|
|
380
380
|
logWarn(
|
package/src/commands/markdown.ts
CHANGED
|
@@ -108,14 +108,14 @@ export function register(program: Command): void {
|
|
|
108
108
|
'out of a standards file, so a project that installed no standards is',
|
|
109
109
|
'measured the same as one that did. markdown.md still states every rule',
|
|
110
110
|
'for a reader. No folder has to resolve and no index.md has',
|
|
111
|
-
'to exist, so .claude/rules
|
|
111
|
+
'to exist, so .claude/rules/ and governance/ are in reach.',
|
|
112
112
|
'',
|
|
113
113
|
'Examples:',
|
|
114
114
|
' canon markdown audit',
|
|
115
115
|
' canon markdown audit --json',
|
|
116
116
|
' canon markdown audit .claude/rules governance',
|
|
117
117
|
' canon markdown audit docs/agents/commands.md',
|
|
118
|
-
" canon markdown audit '
|
|
118
|
+
" canon markdown audit 'standards/**/*.md'",
|
|
119
119
|
'',
|
|
120
120
|
].join('\n'),
|
|
121
121
|
)
|