@erclx/canon 4.7.0 → 4.8.1
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 +55 -41
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-docs/REQUIREMENT.md +2 -2
- package/claude/skills/claude-docs/SKILL.md +7 -36
- package/claude/skills/claude-orchestrate/references/orchestrator-dispatch.md +13 -8
- package/claude/skills/claude-tasks/SKILL.md +4 -5
- package/claude/skills/claude-worker/SKILL.md +2 -2
- package/docs/agents/capture.md +17 -11
- package/docs/agents/commands.md +4 -4
- package/docs/agents/demo.md +1 -1
- package/docs/agents/driver.md +2 -2
- package/docs/agents/index.md +1 -1
- package/docs/agents/overview.md +3 -3
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/tasks.md +10 -4
- package/docs/ai-workflow.md +2 -4
- package/docs/zshrc-aliases.md +19 -7
- package/package.json +1 -2
- package/scripts/core/bootstrap.sh +4 -0
- package/scripts/core/regen-hero.sh +6 -3
- package/src/capture/render.ts +166 -0
- package/src/capture/sources.ts +42 -0
- package/src/capture/stamp.ts +52 -0
- package/src/cli.ts +1 -1
- package/src/commands/capture.ts +52 -41
- package/src/commands/tasks.ts +18 -1
- package/src/demo/drive.ts +5 -8
- package/src/driver/drive.ts +7 -8
- package/src/gate/measures.ts +1 -1
- package/src/gate/stages.ts +1 -1
- package/src/inventory/walk.ts +3 -3
- package/src/tasks/archive.ts +91 -20
- package/src/tasks/validate.ts +76 -0
- package/standards/tasks.md +4 -4
package/README.md
CHANGED
|
@@ -4,11 +4,23 @@
|
|
|
4
4
|
[](https://github.com/erclx/canon/actions/workflows/verify.yml)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
canon is a CLI and Claude Code plugin that stops your AI conventions drifting apart across repositories. It keeps one authoritative copy and installs it into each project on demand.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The counts above are read from the catalogs when the image is built, so they're what the repo actually ships today.
|
|
12
|
+
|
|
13
|
+
## Why
|
|
14
|
+
|
|
15
|
+
If you work across more than one repository and your AI setup has started to drift between them, this is for you. Every AI coding setup accumulates the same assets. Prompts to reuse, rules agents should follow, slash commands, skills, seed docs, sync scripts. Once you have enough projects, your copies drift and your agents stop getting consistent signals.
|
|
16
|
+
|
|
17
|
+
Three design choices shape the toolkit.
|
|
18
|
+
|
|
19
|
+
- Agent-first: every command has a non-interactive path and a JSON catalog. If a Claude Code skill or any other agent cannot drive the CLI without prompts, the design is wrong.
|
|
20
|
+
- Text-native: conventions, rules, and prompts are authored as markdown that you and your agents read the same way. No hidden behavior, no compiled state.
|
|
21
|
+
- One source, many consumers: this repo is the authoritative copy. Your projects install and sync on demand, never author in place.
|
|
22
|
+
|
|
23
|
+
Two limits worth knowing before you install. Claude Code is the only agent runtime the plugin targets, and the CLI needs Bun on your path.
|
|
12
24
|
|
|
13
25
|
## Install
|
|
14
26
|
|
|
@@ -31,6 +43,31 @@ bun install --global @erclx/canon
|
|
|
31
43
|
|
|
32
44
|
[Bun](https://bun.sh) is the CLI runtime and has to be on your path first. Confirm the install by resolving `canon --help`.
|
|
33
45
|
|
|
46
|
+
## What is inside
|
|
47
|
+
|
|
48
|
+
Each domain has a canonical source in this repo and a thin install or sync CLI on your side.
|
|
49
|
+
|
|
50
|
+
- Claude Code plugin: skills that plan a feature, review a diff, sync the planning docs, and run the ship chain from branch through pull request
|
|
51
|
+
- Governance rules: coding and authoring rules that load into a Claude session when a matching path is edited, installed per project and refreshed by sync
|
|
52
|
+
- Standards: authoring conventions for commits, branches, plans, tasks, and markdown, read by name with `canon standards <name>` rather than copied into your project
|
|
53
|
+
- Snippets: reusable prompts fired by `@` reference in a Claude Code session, resolved live from the plugin with no install step
|
|
54
|
+
- Tooling stacks: golden configs, seeds, and a reference per framework, laid down by `canon init` and reconciled by `canon tooling sync`
|
|
55
|
+
- Design system: a `DESIGN.md` token format, a skill that drafts one from an existing project or from scratch, and a render command
|
|
56
|
+
- Slides: a `SLIDES.md` source format with a layout catalog, rendered to PowerPoint by `canon slides render`
|
|
57
|
+
- Transcripts: `canon transcripts` pulls a YouTube transcript with metadata frontmatter into any repo
|
|
58
|
+
- Sandbox: scenario-based scaffolds that provision an isolated project state for verifying each domain flow
|
|
59
|
+
|
|
60
|
+
## Documentation
|
|
61
|
+
|
|
62
|
+
Scaffolding your first project? Start with target projects, then the AI workflow loop. Everything else answers questions that arrive later.
|
|
63
|
+
|
|
64
|
+
- [AI workflow](docs/ai-workflow.md): feature-development loop inside a toolkit-managed project
|
|
65
|
+
- [Operating model](docs/operating-model.md): orchestrator, planner, and worker roles for building across parallel sessions
|
|
66
|
+
- [Visual design workflow](docs/visual-design-workflow.md): tiered guide for design and wireframe authoring
|
|
67
|
+
- [Target projects](docs/target-projects.md): scaffold, add a domain later, sync upstream drift
|
|
68
|
+
- [Agents](docs/agents/index.md): CLI flags, exit codes, and JSON output shapes
|
|
69
|
+
- [Docs index](docs/index.md): every reference doc in this repo
|
|
70
|
+
|
|
34
71
|
## Update
|
|
35
72
|
|
|
36
73
|
Nothing refreshes on its own. Claude Code ships auto-update off for third-party marketplaces, so an installed copy serves whatever version it was installed at until you refresh it.
|
|
@@ -49,43 +86,6 @@ You don't have to wait until something breaks to find out you're behind. `canon
|
|
|
49
86
|
|
|
50
87
|
To stop doing this by hand, turn auto-update on once under `/plugin` in the Marketplaces tab. Confirm what you are running with `canon --version` and `claude plugin list`.
|
|
51
88
|
|
|
52
|
-
## Why
|
|
53
|
-
|
|
54
|
-
Every AI coding setup accumulates the same assets. Prompts to reuse, rules agents should follow, slash commands, skills, seed docs, sync scripts. Once you have enough projects, your copies drift and your agents stop getting consistent signals.
|
|
55
|
-
|
|
56
|
-
Three design choices shape the toolkit.
|
|
57
|
-
|
|
58
|
-
- Agent-first: every command has a non-interactive path and a JSON catalog. If a Claude Code skill or any other agent cannot drive the CLI without prompts, the design is wrong.
|
|
59
|
-
- Text-native: conventions, rules, and prompts are authored as markdown that you and your agents read the same way. No hidden behavior, no compiled state.
|
|
60
|
-
- One source, many consumers: this repo is the authoritative copy. Your projects install and sync on demand, never author in place.
|
|
61
|
-
|
|
62
|
-
Two limits worth knowing before you install. Claude Code is the only agent runtime the plugin targets, and the CLI needs Bun on your path. Snippets are the one surface that also travels to Gemini chat.
|
|
63
|
-
|
|
64
|
-
## What is inside
|
|
65
|
-
|
|
66
|
-
Each domain has a canonical source in this repo and a thin install or sync CLI on your side. The links run to internal narrative, written for someone maintaining the toolkit rather than installing it, so skip them on a first pass.
|
|
67
|
-
|
|
68
|
-
- [Claude Code plugin](.claude/context/claude-plugin/index.md): skills for planning, review, docs sync, and the git ship chain
|
|
69
|
-
- [Governance rules](.claude/context/governance/index.md): Claude rules and stacks, installable per project
|
|
70
|
-
- [Standards](.claude/context/standards/index.md): shared authoring conventions, read by name rather than installed
|
|
71
|
-
- [Snippets](.claude/context/snippets.md): reusable prompts for Claude and Gemini chat
|
|
72
|
-
- [Tooling stacks](.claude/context/tooling.md): golden configs, seeds, and references per framework
|
|
73
|
-
- [Design system](.claude/context/design.md): `DESIGN.md` token shape, extract skill and its two paths, render command
|
|
74
|
-
- [Slides](.claude/context/slides.md): `SLIDES.md` source, layout catalog, render command, draft skill
|
|
75
|
-
- [Transcripts](.claude/context/transcripts.md): fetch a YouTube transcript with metadata frontmatter via `canon transcripts`
|
|
76
|
-
- [Sandbox](.claude/context/sandbox/index.md): scenario-based scaffolds for verifying each domain flow
|
|
77
|
-
|
|
78
|
-
## Documentation
|
|
79
|
-
|
|
80
|
-
Scaffolding your first project? Start with target projects, then the AI workflow loop. Everything else answers questions that arrive later.
|
|
81
|
-
|
|
82
|
-
- [AI workflow](docs/ai-workflow.md): feature-development loop inside a toolkit-managed project
|
|
83
|
-
- [Operating model](docs/operating-model.md): orchestrator, planner, and worker roles for building across parallel sessions
|
|
84
|
-
- [Visual design workflow](docs/visual-design-workflow.md): tiered guide for design and wireframe authoring
|
|
85
|
-
- [Target projects](docs/target-projects.md): scaffold, add a domain later, sync upstream drift
|
|
86
|
-
- [Agents](docs/agents/index.md): CLI flags, exit codes, and JSON output shapes
|
|
87
|
-
- [Docs index](docs/index.md): every reference doc in this repo
|
|
88
|
-
|
|
89
89
|
## Development
|
|
90
90
|
|
|
91
91
|
Working on the toolkit starts from a clone. Running the CLI doesn't, since it installs from the registry. Skip this section unless you're changing the toolkit itself.
|
|
@@ -97,7 +97,7 @@ Working on the toolkit starts from a clone. Running the CLI doesn't, since it in
|
|
|
97
97
|
- [GitHub CLI](https://cli.github.com) (optional) for ship flows
|
|
98
98
|
- Shell: `zsh` or bash 4+ (`brew install bash` on macOS).
|
|
99
99
|
|
|
100
|
-
Clone the repo, then run the bootstrap script. It installs dependencies, links the CLI globally, and
|
|
100
|
+
Clone the repo, then run the bootstrap script. It installs dependencies, links the CLI globally, and appends a marked block of Claude Code shell aliases to your `~/.zshrc`.
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
103
|
git clone https://github.com/erclx/canon.git
|
|
@@ -106,7 +106,7 @@ bun install
|
|
|
106
106
|
bun run bootstrap
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
The script is idempotent, so re-run it after pulling upstream changes without duplicating anything. It confirms the install by resolving `canon --help` on the last step. See [zshrc aliases](docs/zshrc-aliases.md) for what each alias does.
|
|
109
|
+
The script is idempotent, so re-run it after pulling upstream changes without duplicating anything. That also means it leaves an alias block you already have alone rather than refreshing it, so an alias added upstream needs the block deleted and the script re-run. It confirms the install by resolving `canon --help` on the last step. See [zshrc aliases](docs/zshrc-aliases.md) for what each alias does, how to pick up a new one, and how to opt out of the block.
|
|
110
110
|
|
|
111
111
|
With the CLI linked, scaffold a fresh project.
|
|
112
112
|
|
|
@@ -120,6 +120,20 @@ canon init
|
|
|
120
120
|
|
|
121
121
|
For the full journey from scaffold through adding a domain later to syncing upstream drift, see [target projects](docs/target-projects.md).
|
|
122
122
|
|
|
123
|
+
### Internal narrative
|
|
124
|
+
|
|
125
|
+
Each domain carries an entry written for someone maintaining the toolkit rather than installing it. These paths resolve in a clone only. The published package ships `docs` and not `.claude`, so an installed copy does not carry them.
|
|
126
|
+
|
|
127
|
+
- [Claude Code plugin](.claude/context/claude-plugin/index.md)
|
|
128
|
+
- [Governance rules](.claude/context/governance/index.md)
|
|
129
|
+
- [Standards](.claude/context/standards/index.md)
|
|
130
|
+
- [Snippets](.claude/context/snippets.md)
|
|
131
|
+
- [Tooling stacks](.claude/context/tooling.md)
|
|
132
|
+
- [Design system](.claude/context/design.md)
|
|
133
|
+
- [Slides](.claude/context/slides.md)
|
|
134
|
+
- [Transcripts](.claude/context/transcripts.md)
|
|
135
|
+
- [Sandbox](.claude/context/sandbox/index.md)
|
|
136
|
+
|
|
123
137
|
## Contributing
|
|
124
138
|
|
|
125
139
|
Portfolio project. Issues are welcome. Pull requests are accepted by invitation only, so open an issue rather than a branch. Read the [contributing guidelines](CONTRIBUTING.md) for the local loop, the authoring split, and the commit convention before you file anything.
|
|
@@ -38,10 +38,10 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
|
|
|
38
38
|
## Must not
|
|
39
39
|
|
|
40
40
|
- Infer a new task from the diff. Only outcomes already on the board get marked.
|
|
41
|
-
- Touch task files the session did not change
|
|
41
|
+
- Touch task files the session did not change
|
|
42
42
|
- Widen what a writing step reads when the baseline is unusable. Widening a read is safe and widening a write stubs a surface for every file in the repository.
|
|
43
43
|
- Edit `CLAUDE.md` inline. Every change there goes through a diff-and-approve gate, so this skill only flags.
|
|
44
|
-
- Create a context entry or delete a plan
|
|
44
|
+
- Create a context entry, or move or delete a plan. A plan is settled by the merge, and `canon tasks archive` carries it.
|
|
45
45
|
- Overwrite a file a promotion block routes to. A destination that already holds a page is a merge for a person, and folding over it discards work this skill never read.
|
|
46
46
|
- Write an anchor onto a decision the run did not amend, or refresh one without re-reading the number. A date from a pass that measured nothing is the false confidence the marker exists to prevent.
|
|
47
47
|
- Anchor an entry written before the rule, which dates it by blame rather than by a read
|
|
@@ -51,7 +51,7 @@ Read these in parallel from the current worktree root (`pwd`), not the main work
|
|
|
51
51
|
|
|
52
52
|
Read the task board from the main worktree root instead, per Worktrees in `CLAUDE.md`. It is gitignored scratch and never commits with the branch:
|
|
53
53
|
|
|
54
|
-
- `.canon/tasks/index.md` first, then the task files this session touched. That narrow read serves the marking step
|
|
54
|
+
- `.canon/tasks/index.md` first, then the task files this session touched. That narrow read serves the marking step, which is the only step here that opens a task file.
|
|
55
55
|
|
|
56
56
|
## Step 2: identify what changed
|
|
57
57
|
|
|
@@ -102,7 +102,7 @@ For each doc with relevant changes, apply updates following these rules. Read a
|
|
|
102
102
|
|
|
103
103
|
The verb resolves the board at the main worktree root in-process, which is the route because this is an edit inside an existing file and the file-editing tools refuse that path from a linked worktree.
|
|
104
104
|
|
|
105
|
-
Read `ok` and `reason` out of that record rather than the exit
|
|
105
|
+
Read `ok` and `reason` out of that record rather than the exit. An operator's shell profile may wrap `canon` in a function that runs the binary and then a second command and takes the second status, which flattens every non-zero exit to zero. A refusal arriving as success leaves the outcome unmarked while the chain moves on, so the board reports shipped work as open and the next session re-plans it.
|
|
106
106
|
|
|
107
107
|
**REQUIREMENTS.md, ARCHITECTURE.md, DESIGN.md, `.claude/wireframes/<surface>.md`**
|
|
108
108
|
|
|
@@ -208,40 +208,13 @@ Report a block left unfolded rather than dropping it:
|
|
|
208
208
|
|
|
209
209
|
`⚠ Skipped: <destination path> already exists. Merge by hand.`
|
|
210
210
|
|
|
211
|
-
## Step 9: sweep consumed
|
|
211
|
+
## Step 9: sweep consumed receipts
|
|
212
212
|
|
|
213
|
-
Sweep
|
|
213
|
+
Sweep the review and memory receipts this session consumed. Resolve all paths at the main worktree root, not the current worktree. See Worktrees in `CLAUDE.md`.
|
|
214
214
|
|
|
215
|
-
Every
|
|
215
|
+
Every delete below is a shell operation, so send each as a plain single `Bash` command rather than joining two with `&&`, which is refused as compound from a linked worktree.
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
Scan every file in `.canon/tasks/`, not only the ones this session touched. For each task file whose outcomes are now all `[x]`, check for a `Plan:` line directly under the title and parse the target.
|
|
220
|
-
|
|
221
|
-
The line carries a markdown link, so read the target out of the parentheses rather than taking the rest of the line. A task still carrying the older bare-path form parses the same way once the link is absent, so accept both. Resolve the target against `.canon/tasks/` before routing on it, which lands `../plans/x.md` and `.canon/plans/x.md` on the same file.
|
|
222
|
-
|
|
223
|
-
The bullets below name resolved locations, so an unresolved target falls to the last one and no plan is ever archived. Never delete a plan. `${CLAUDE_SKILL_DIR}/../../standards/plan.md` owns the archive destination and why a shipped plan is moved rather than removed.
|
|
224
|
-
|
|
225
|
-
Board-wide scope is the one place this sweep reaches past Step 3's rule against touching task files the session did not change. A board carrying a task that closed while an earlier run missed its archive is the defect this exists to clear, and skipping those tasks would preserve it. Reaching them is safe because the archive moves the plan and points the task at the new path, so a task from unrelated work ends up with a working pointer rather than a broken one.
|
|
226
|
-
|
|
227
|
-
Before moving anything, count the other citations. Scan every `.canon/tasks/*.md` file except the one being processed for a `Plan:` line naming the same plan. Compare the resolved target from the parse above, never the raw target string and never the filename alone.
|
|
228
|
-
|
|
229
|
-
A board carrying one task written `../plans/x.md` and another written `.canon/plans/x.md` cites one plan, and a raw string comparison reads two, counts zero, and archives the file out from under a live task. Comparing filenames swaps that for the opposite error, since a live plan and an archived one share a basename whenever a closed task still points into `.canon/plans/archive/`, and the count then reads a citation that does not exist and archives nothing.
|
|
230
|
-
|
|
231
|
-
Exclude the closing task explicitly. It sits on the board and cites the plan itself, so a scan that counts it never reaches zero and no plan is ever archived.
|
|
232
|
-
|
|
233
|
-
`canon tasks plan-citations <stem> --json` answers this same question, and the archive gate already reads it. This body states the rule anyway rather than calling the verb, because a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes, so a target whose installed `canon` predates the verb gets no record back and routes on nothing. Measured against the `claude:docs` `board-sweep` arm, where calling the verb archived neither plan and created no `.canon/plans/archive/`.
|
|
234
|
-
|
|
235
|
-
Nothing in the exit code reports that. Branch on the record's `ok` and `reason` fields and never on the exit, which is the rule every task verb already carries: an operator's shell profile may wrap `canon` in a function that runs the binary and then another command, taking its status from the second, and one measured here masks every non-zero exit rather than only an absent verb. The binary itself exits 1 for an unknown subcommand and 1 for an ordinary refusal alike. Switching this body to the verb needs a release that carries it and a read of the record rather than the exit, which together retire the duplication.
|
|
236
|
-
|
|
237
|
-
A plan can serve more than one task, and archiving on the first task to close strands every other task's pointer at a path that has moved. `.canon/plans/` is gitignored, so that retarget would be the only record and there is nothing to recover it from.
|
|
238
|
-
|
|
239
|
-
- Target resolves inside `.canon/plans/`, the file exists, and no other task file cites it: create `.canon/plans/archive/`, move the file there under its original name, overwriting any file already sitting at that name. Then rewrite the task file's `Plan:` line to the archive path, so a completed task still leads to the reasoning behind it.
|
|
240
|
-
- Target resolves inside `.canon/plans/` and at least one other task file cites it: leave the plan where it is and retarget nothing. Report the shared citation.
|
|
241
|
-
- Target resolves inside `.canon/plans/archive/`: skip silently. The plan was archived by an earlier pass and the task file is already correct.
|
|
242
|
-
- Any other resolved target outside `.canon/plans/`: warn and skip.
|
|
243
|
-
|
|
244
|
-
Write the retarget as a markdown link, `Plan: [feature-<slug>](../plans/archive/feature-<slug>.md)`, updating both halves so the text and the target stay in step. This branch is the only writer that produces a `Plan:` line nobody authored by hand, so a retarget that emits a bare path converts every task to the old form as it closes and drifts the board back to two shapes on its own.
|
|
217
|
+
Plans are not swept here. A plan is settled by the merge rather than by an outcome this run marked, and `canon tasks archive` moves it with the task the `post-merge` hook archives. Sweeping it from this step read a closure Step 3 had written moments earlier and moved a plan the branch was still building from.
|
|
245
218
|
|
|
246
219
|
### Reviews
|
|
247
220
|
|
|
@@ -253,7 +226,7 @@ Sweep the branch reports this session never opened. List `.canon/review/branch/r
|
|
|
253
226
|
|
|
254
227
|
What that removes is a local-only review on a branch deleted before it opened a pull request. `claude-review` says so where a reader meets the report, and the sweep runs anyway rather than keeping every report against the one case, since nothing else ever clears them.
|
|
255
228
|
|
|
256
|
-
Memory receipts sweep board-wide
|
|
229
|
+
Memory receipts sweep board-wide rather than by slug. Scan every `.canon/review/memory/memory-review-*.md`, not only the one matching this slug. `claude-memory-review` writes its receipt after this skill has run in every ship chain, so a sweep keyed on the current slug looks for a file that does not exist yet, and no later branch looks for it either because a slug is unique per feature. Scanning the folder is what makes the sweep fire at all.
|
|
257
230
|
|
|
258
231
|
For each receipt, count the H2 items still marked 📝 pending:
|
|
259
232
|
|
|
@@ -266,8 +239,6 @@ Do not sweep `ui-checklist-*.md` (pending human verification), `ux-audit-*.md`,
|
|
|
266
239
|
|
|
267
240
|
Output one line per file swept:
|
|
268
241
|
|
|
269
|
-
- `📦 Archived: <path>` for a plan moved into `.canon/plans/archive/`
|
|
270
|
-
- `⏭ Kept: <path>, still cited by <task-file>` for a plan another live task shares
|
|
271
242
|
- `🧹 Deleted: <path>, branch gone` for a branch report whose branch no longer exists
|
|
272
243
|
- `🧹 Deleted: <path>, folded <n> skips` for a swept memory receipt
|
|
273
244
|
- `⏭ Kept: <path>, <n> items pending` for a memory receipt still holding decisions
|
|
@@ -73,13 +73,17 @@ Name `<model>` on the launch, and pick it against the task rather than copying w
|
|
|
73
73
|
## Dispatch
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
claude --bg --model <model> -n "worker-<slug>" "Run /canon:claude-worktree <type>/<slug>, then /canon:claude-autoship <plan>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the pull request opens, carrying the number, the branch, the head sha, the CI state, and every point you departed from the plan on, and message it again if you stop on a question."
|
|
76
|
+
claude --bg --model <model> -n "worker-<project>-<slug>" "Run /canon:claude-worktree <type>/<slug>, then /canon:claude-autoship <plan>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the pull request opens, carrying the number, the branch, the head sha, the CI state, and every point you departed from the plan on, and message it again if you stop on a question."
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
`--bg, --background` starts the session as a background agent and returns immediately, `-n, --name` sets the display name that tells a self-dispatched worker from an operator's own launch in `canon sessions list`, and `--model` overrides the inheritance the section above measured. Pass `-n` on every dispatch rather than letting the client derive one. A launch that omits it leaves the session named for a fragment of its own identifier, which is both its address on the send channel and the whole of what the operator sees for it in agent view.
|
|
80
80
|
|
|
81
81
|
The prefix reads `worker-` because that is the role it marks. It read `orchestrator-` until 2026-08-31, and no controlling session ever carried it, so a worker filtering the roster for that string found a sibling or itself on every row. Nothing matches the prefix programmatically, which is what kept the rename down to three strings.
|
|
82
82
|
|
|
83
|
+
`<project>` is the basename of the main worktree root, not of wherever the dispatcher happens to be running. Resolve the main root first, the way `claude-worktree` Step 1 does, since a bare `git rev-parse --show-toplevel` inside a linked worktree returns the worktree path rather than the project's. See Worktrees in `CLAUDE.md`.
|
|
84
|
+
|
|
85
|
+
`claude agents` lists every session on the machine with no path column and no per-project filter, so `<project>` in the name is the only thing left telling two fleets apart, and a session named off the worktree path instead would carry the branch folder rather than the project. Two projects each dispatching a bare `worker-page-driver` used to read as one row in that view.
|
|
86
|
+
|
|
83
87
|
Read `<dispatcher-id>` with `canon sessions list --self --json` and interpolate the `sessionId` that row carries. Carry the id rather than the name. A name is derived from whatever the session turned out to be doing, and across the 181 records stamping both fields, nine were renamed after launch at a median of 5.4 minutes and a maximum of 509. Three landed more than ten minutes in, which is inside the window a worker announces its pull request in, so a name written into the prompt is aimed at a send that happens after it goes stale.
|
|
84
88
|
|
|
85
89
|
Where the installed CLI answers `--self` with an unknown option, that flag is newer than the release the target holds. Read the `sessionId` from the record the client writes for this session under its configuration directory, and say which route answered so the reader knows whether the id was read or inferred.
|
|
@@ -165,11 +169,11 @@ directly with `Bash`, `Read`, and `Edit` instead of retrying the tool, which
|
|
|
165
169
|
is the route two workers already took today on two different branches.
|
|
166
170
|
|
|
167
171
|
```bash
|
|
168
|
-
claude --bg --model <model> -n "worker-<slug>" "Enter the worktree for <branch> at .claude/worktrees/<slug>/, creating it from that branch if the folder is gone. Run /canon:claude-worker, then /canon:claude-address-review. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the address pass finishes, carrying what was addressed and the PR's CI state, and message it again if you stop on a question."
|
|
172
|
+
claude --bg --model <model> -n "worker-<project>-<slug>" "Enter the worktree for <branch> at .claude/worktrees/<slug>/, creating it from that branch if the folder is gone. Run /canon:claude-worker, then /canon:claude-address-review. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the address pass finishes, carrying what was addressed and the PR's CI state, and message it again if you stop on a question."
|
|
169
173
|
```
|
|
170
174
|
|
|
171
|
-
`<dispatcher-id
|
|
172
|
-
them above.
|
|
175
|
+
`<dispatcher-id>`, `<model>`, and `<project>` resolve the same way the build
|
|
176
|
+
shape resolves them above.
|
|
173
177
|
|
|
174
178
|
Take this shape wherever a review needs answering and no live session already
|
|
175
179
|
holds the branch. Where one does, message it to run `claude-address-review`
|
|
@@ -196,14 +200,15 @@ gitignored file at the main worktree root, so this shape names the row's task
|
|
|
196
200
|
file rather than a branch and opens with the role instead of a worktree call.
|
|
197
201
|
|
|
198
202
|
```bash
|
|
199
|
-
claude --bg --model <model> -n "planner-<slug>" "Run /canon:claude-planner, then /canon:claude-feature <task>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the plan lands, carrying the path and what the task file got wrong, and message it again if you stop on a question."
|
|
203
|
+
claude --bg --model <model> -n "planner-<project>-<slug>" "Run /canon:claude-planner, then /canon:claude-feature <task>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the plan lands, carrying the path and what the task file got wrong, and message it again if you stop on a question."
|
|
200
204
|
```
|
|
201
205
|
|
|
202
206
|
`<task>` is the row's task file path and `<slug>` the slug its plan will take,
|
|
203
207
|
resolved off the row the way the build shape resolves one off a plan.
|
|
204
|
-
`<dispatcher-id
|
|
205
|
-
reads `planner-` for the reason the worker's reads `worker-`,
|
|
206
|
-
marks the role of the session it names rather than the one
|
|
208
|
+
`<dispatcher-id>`, `<model>`, and `<project>` resolve the same way they do
|
|
209
|
+
above. The prefix reads `planner-` for the reason the worker's reads `worker-`,
|
|
210
|
+
which is that it marks the role of the session it names rather than the one
|
|
211
|
+
that launched it.
|
|
207
212
|
|
|
208
213
|
None of the three checks above binds this shape. The branch check has no
|
|
209
214
|
candidate to read, and the disjointness gate has nothing to compare, since a
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-tasks
|
|
3
|
-
description: Creates a task file in `.canon/tasks/` with the filename, phase label, and frontmatter the standard requires, and archives a shipped one out of the folder. Use when asked to "add a task", "create a task", "queue this", "put this on the board", "archive that task", or "close out a shipped task". Do NOT use to mark an outcome `[x]
|
|
3
|
+
description: Creates a task file in `.canon/tasks/` with the filename, phase label, and frontmatter the standard requires, and archives a shipped one out of the folder. Use when asked to "add a task", "create a task", "queue this", "put this on the board", "archive that task", or "close out a shipped task". Do NOT use to mark an outcome `[x]`. That is `claude-docs`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Claude tasks
|
|
7
7
|
|
|
8
|
-
Owns the two operations that bring a task file into existence and take it out of the folder. `claude-docs` edits the contents of a task that already exists, marking outcomes `[x]
|
|
8
|
+
Owns the two operations that bring a task file into existence and take it out of the folder. `claude-docs` edits the contents of a task that already exists, marking outcomes `[x]`. Do not mark outcomes here, and do not move a plan by hand: the archive carries it.
|
|
9
9
|
|
|
10
10
|
Read `${CLAUDE_SKILL_DIR}/../../standards/tasks.md` before writing any file. It holds the filename convention, the frontmatter contract, and the file format. Do not work them from memory.
|
|
11
11
|
|
|
@@ -104,19 +104,18 @@ canon tasks archive <stem> --json
|
|
|
104
104
|
|
|
105
105
|
The command refuses rather than reports, and the refusal reaches this skill through the record rather than through the exit. Branch on `ok`, then on `reason`. An operator's shell profile may wrap `canon` in a function that runs the binary and then a second command and takes the second status, which masks every non-zero exit rather than only an absent verb. The binary exits 1 for an unknown subcommand and 1 for an ordinary refusal alike, so the record is the only signal that survives the wrapper.
|
|
106
106
|
|
|
107
|
-
On success the record carries `from`, `to`, `priorityRowRemoved`, and `indexRegenerated`, which is what moved, what row it cleared, and whether the index changed.
|
|
107
|
+
On success the record carries `from`, `to`, `priorityRowRemoved`, and `indexRegenerated`, which is what moved, what row it cleared, and whether the index changed. It also carries `plan` when the task was the last live citation of a live plan, holding the `from` and `to` of the plan moved alongside it. A `plan` of `null` means the task cited no live plan, or that a sibling still holds it.
|
|
108
108
|
|
|
109
109
|
### Step 3: route on a refusal
|
|
110
110
|
|
|
111
111
|
Each reason has one resolution and none of them is to archive around it:
|
|
112
112
|
|
|
113
113
|
- `open-outcomes`: the named outcomes are unmarked or genuinely open. Run `claude-docs` when the work shipped and nothing marked it. Leave the task on the board when the outcome is real. Cut the outcomes first when the work is being abandoned, so the board records what was dropped.
|
|
114
|
-
- `plan-unswept`: stop and route to `claude-docs`, which owns the plans sweep and the last-live-citation rule. `❌ Plan not yet swept. Run /claude-docs first, then archive.`
|
|
115
114
|
- `ambiguous`: two tasks name one pull request, which is the misfile `${CLAUDE_SKILL_DIR}/../../standards/tasks.md` rules out. Resolve the citation by hand, since no sweep repairs it.
|
|
116
115
|
- `no-match`: the stem or number names nothing on the board. Check the name against the listed stems.
|
|
117
116
|
- `bad-input`: the command line was wrong rather than the board. Read the message, fix the arguments, and run it again. Nothing on the board needs repair, which is what separates this from the two above.
|
|
118
117
|
|
|
119
|
-
Do not move a plan from this skill.
|
|
118
|
+
Do not move a plan by hand from this skill. The command carries the plan with the task when no other live task cites it, and retargets the archived task's `Plan:` line at the new path. A second mover drifts into relocating the same file differently.
|
|
120
119
|
|
|
121
120
|
Leave `TASK-ARCHIVE.md` alone when it is present in the archive folder. It records the single-file era in the shape that era used, and splitting it would fabricate per-task files nobody wrote.
|
|
122
121
|
|
|
@@ -72,8 +72,8 @@ Infer only where no operator is present. Read `canon sessions list --json` and
|
|
|
72
72
|
take the sessions holding no feature branch as the candidates, since a
|
|
73
73
|
controlling session holds none. Say the addressee was inferred so the reader can
|
|
74
74
|
correct it. Never filter that roster by name prefix: every self-dispatched
|
|
75
|
-
worker is named `worker-<slug>`, so a prefix scan returns a sibling or
|
|
76
|
-
session itself, which is the defect that sent messages owed to a controller
|
|
75
|
+
worker is named `worker-<project>-<slug>`, so a prefix scan returns a sibling or
|
|
76
|
+
this session itself, which is the defect that sent messages owed to a controller
|
|
77
77
|
somewhere else.
|
|
78
78
|
|
|
79
79
|
Report a resolution that returns nothing rather than falling back to a guess.
|
package/docs/agents/capture.md
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Capture
|
|
3
|
-
description: Rendering
|
|
3
|
+
description: Rendering HTML sources to PNG, what the command asserts about fonts, and why the selector has no default
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Capture
|
|
7
7
|
|
|
8
|
-
`canon capture [source]
|
|
8
|
+
`canon capture [source] --selector <sel>` renders HTML sources to PNG, which is how a generated documentation image is rebuilt from the markup it was generated out of. The source defaults to `assets/`, where a directory expands to every `.html` directly inside it, so adding a capture means dropping a file beside the first one and running the same command.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
canon capture
|
|
12
|
-
canon capture assets/install.html
|
|
13
|
-
canon capture assets --out .canon/review/captures
|
|
11
|
+
canon capture --selector .window
|
|
12
|
+
canon capture assets/install.html --selector .window
|
|
13
|
+
canon capture assets --selector .window --out .canon/review/captures
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
`
|
|
16
|
+
`--selector` is required and every example above passes it. The element a capture crops to belongs to the page, not to the command, so there is no value that could be right for an arbitrary project's markup. `.window` is what this repository's own two sources declare, and a project renders its own pages by naming whatever theirs declare.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
`assets/` here holds two sources, so one run over the folder rebuilds both. `install.html` is hand-authored and its text came from a real run. `hero.html` is generated by `scripts/core/regen-hero.sh` from the CLI catalogs and must not be edited by hand, since `bun run check` regenerates it and fails on the difference.
|
|
19
|
+
|
|
20
|
+
Only the HTML is asserted for drift. The PNG is a chromium render whose bytes move with the browser version, so rebuild it with `canon capture assets/hero.html --selector .window` when the check reports the HTML changed.
|
|
19
21
|
|
|
20
22
|
Every render writes a stamp beside its PNG, `hero.png` next to `hero.stamp`, holding the source filename, a `source-sha256` over the markup bytes it read, and an `image-sha256` over the image bytes it wrote. Both digests are what `bun run check` compares, so a markup edit committed without a capture and a PNG swapped under unchanged markup each fail. The stamp is tracked and commits alongside the pair. Nothing hand-edits it, and a capture that cannot write it reports that source as failed and exits 1, so an image whose stamp never landed is reported rather than passed over.
|
|
21
23
|
|
|
22
24
|
| Option | Behavior |
|
|
23
25
|
| ------------------ | ------------------------------------------------- |
|
|
24
26
|
| `--out <dir>` | Write every PNG here instead of beside its source |
|
|
25
|
-
| `--selector <sel>` | Element to capture
|
|
27
|
+
| `--selector <sel>` | Element to capture, required and never defaulted |
|
|
26
28
|
|
|
27
29
|
## What the command asserts
|
|
28
30
|
|
|
@@ -30,8 +32,12 @@ Each source renders at `deviceScaleFactor` 2 with a transparent background, and
|
|
|
30
32
|
|
|
31
33
|
What is asserted is the font. The command reads the first family the captured element declares and fails when the browser did not resolve it, because a fallback face rewraps the block and silently changes the output. Sources therefore name a real font rather than relying on `monospace`. A source that cannot render reports its own line and exits 1 without dropping the rest of the batch.
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
A run refuses before it reads anything else when `--selector` is absent, naming the flag and pointing at `--help`. Ordering it first is what keeps the message about the invocation: the source defaults to `assets`, so checking that first would answer `assets not found` from whatever directory the caller happened to be in and say nothing about the flag that was actually missing.
|
|
36
|
+
|
|
37
|
+
The browser binary installs separately from the package. A first run does `bunx playwright install chromium` once, and a run that cannot launch one reports the engine's own remediation inside the frame and exits 1 rather than escaping as a stack trace.
|
|
38
|
+
|
|
39
|
+
The command ships to targets, alongside `demo`, `inventory`, and `drive`. It was held back while its only caller was this repository regenerating its own committed images, which described the caller rather than the render. A project has generated pages of its own, and the command that would show them rendering and prove their fonts resolved was the one it could not run.
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
Shipping it also fixed what the exclusion was hiding. The render module imported the `@playwright/test` development dependency, which no published tarball carries. Every browser reference still sits behind a dynamic import, so a browser loads for this command rather than in front of every other one.
|
|
36
42
|
|
|
37
|
-
`
|
|
43
|
+
`demo.md` and `driver.md` cover two of the other three browser commands. What separates this one is that a capture renders a single state from a file on disk, where the rest drive a running application.
|
package/docs/agents/commands.md
CHANGED
|
@@ -26,7 +26,7 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
26
26
|
| `canon slides list` | List the available slide layouts (`--json` for the catalog) |
|
|
27
27
|
| `canon feedback` | Write toolkit feedback from stdin to `.canon/review/feedback/`, or open a GitHub issue with `--github` |
|
|
28
28
|
| `canon transcripts <url>` | Fetch a YouTube transcript with metadata frontmatter (needs `yt-dlp`) |
|
|
29
|
-
| `canon tasks archive` | Move a shipped task off the board, clear its ordering row, and regenerate the index
|
|
29
|
+
| `canon tasks archive` | Move a shipped task and its plan off the board, clear its ordering row, and regenerate the index |
|
|
30
30
|
| `canon tasks pull-request` | Record a pull request number on the task a branch closes, by stem or `--plan` (`--json`) |
|
|
31
31
|
| `canon tasks outcome` | Mark outcomes `[x]` on a task by position, repeating `--close` (`--json`) |
|
|
32
32
|
| `canon tasks validate` | Report board rows whose shape, order, plan, task file, group, file set, or blocker does not hold (`--json`) |
|
|
@@ -72,11 +72,11 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
72
72
|
| `canon gate run` | Run every stage that guards a branch here, scoping shell, types, and tests to the changed set (`--all`, `--no-write`, `--nested`, `--json`) |
|
|
73
73
|
| `canon inventory [subject]` | Walk every route a project declares and group its elements by the property each computes, as a listing rather than a gate (`--json`) |
|
|
74
74
|
| `canon drive <url> <run>` | Walk a page through named interactions and measure each state it reaches, reporting findings rather than gating (`--json`) |
|
|
75
|
-
| `canon capture [source]` | Render HTML
|
|
75
|
+
| `canon capture [source]` | Render HTML sources to PNG and prove the font each one declares resolved (`--selector` required, `--out`) |
|
|
76
76
|
| `canon serve [dir]` | Serve a directory on the loopback interface and print the link that opens it, running until interrupted (`--port`, `--entry`, `--json`) |
|
|
77
77
|
| `canon upgrade` | Reinstall the CLI globally with the package manager the install path names (`--json`) |
|
|
78
78
|
|
|
79
|
-
`canon serve`
|
|
79
|
+
`canon serve` drives no browser, which is what separates it from the four that do. All four ship now that `capture` does, so the line between them is the engine rather than the package. A generated page loses its stylesheet and its script to an editor preview and to a `file://` open, so the link is the delivery rather than a convenience, and every generated surface here reaches a reader through one. It binds `127.0.0.1` and never a wildcard, because what it is pointed at is routinely a gitignored record tree. It sends `cache-control: no-store`, since a preview exists to be edited and reloaded and a cached stylesheet reads as a fix that did not work.
|
|
80
80
|
|
|
81
81
|
A port already in use is the ordinary case rather than a refusal, so it walks forward to the next free one and reports which it took. That is why a caller reads `url` off the `--json` record instead of composing one from the port it asked for. Only contention is walked past. Any other bind failure refuses as `bind-failed` carrying the error's code, rather than being retried twenty times and reported as a range being full, which names a cause nothing checked.
|
|
82
82
|
|
|
@@ -96,7 +96,7 @@ routes = ["/", "/pricing", "/docs"]
|
|
|
96
96
|
query = "button, a[href], input, select, textarea, [tabindex]"
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
`canon drive` is the fourth and ships for the same reason the
|
|
99
|
+
`canon drive` is the fourth and ships for the same reason the three before it do. What separates it from all three is the axis rather than the destination: `capture` and `inventory` each answer about a page as it loads, and every defect that exists only after a menu opens or the page scrolls is invisible to both. It takes a JSON run file naming the viewport, the probes, and the interaction sequence, since a route catalog is state a project holds and an interaction sequence is a script written for one question. Viewport heights are never defaulted, because the heights a defect hides at belong to the layout rather than to this command. It reports findings and never gates, since every probe it ships carries a class of false finding a throwaway version already produced. See `driver.md`.
|
|
100
100
|
|
|
101
101
|
## Domain commands
|
|
102
102
|
|
package/docs/agents/demo.md
CHANGED
|
@@ -75,7 +75,7 @@ Every refusal exits 1 and names its reason in the `--json` record, so a skill br
|
|
|
75
75
|
|
|
76
76
|
## The browser reaches every target
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
This command was the first browser command to ship, and `canon capture` has since joined it. Capture was held back because its only caller was this repository regenerating its own committed images, which was a fact about that caller rather than about the render.
|
|
79
79
|
|
|
80
80
|
The cost is stated rather than hidden: the browser binary installs separately, so a target runs `bunx playwright install chromium` once before a recording works at all. A run that cannot launch reports that command inside the frame and exits 1.
|
|
81
81
|
|
package/docs/agents/driver.md
CHANGED
|
@@ -49,7 +49,7 @@ Every step names what it did, and that name is carried onto each finding it prod
|
|
|
49
49
|
|
|
50
50
|
Probes run after a step and never on arrival, so a run reaches the load state by opening with a `wait` step of its own, as the example above does. Nothing probes before the first step runs, which makes that leading step the only way to measure the page as it first painted, and naming it is what puts the load state on its own findings rather than under whatever ran next.
|
|
51
51
|
|
|
52
|
-
Write one
|
|
52
|
+
Write one wherever no capture runs against the page. `canon capture` renders a single state from a source on disk, so where it runs it already answers about arrival and a leading `wait` duplicates it. Where it does not, this command is the only thing measuring the page at all, and a run without that step reports every driven state and nothing about the one a visitor sees first.
|
|
53
53
|
|
|
54
54
|
Each height is driven in a context of its own from a fresh navigation, rather than by resizing the page the previous height already drove, since a sweep asks the same question of each height rather than a later question of an already-driven page.
|
|
55
55
|
|
|
@@ -98,6 +98,6 @@ It reports findings and never gates, and the exit code says only whether the dri
|
|
|
98
98
|
|
|
99
99
|
An unreachable page refuses rather than returning an empty report, since nothing measured and nothing found read the same to anything counting findings.
|
|
100
100
|
|
|
101
|
-
The browser binary installs separately from the package, once, with `bunx playwright install chromium`. The command ships to targets like `demo
|
|
101
|
+
The browser binary installs separately from the package, once, with `bunx playwright install chromium`. The command ships to targets like `demo`, `inventory`, and `capture`, because its whole purpose is measuring a page inside someone else's project. It reaches nothing under `src/capture/`, so the two surfaces move independently.
|
|
102
102
|
|
|
103
103
|
See `commands.md` for where this sits among the browser commands, and `capture.md` for the single-state render it adds an axis to.
|
package/docs/agents/index.md
CHANGED
|
@@ -9,7 +9,7 @@ category: Agent surface
|
|
|
9
9
|
CLI catalog and invocation rules for agents, split by command domain. Start with overview.
|
|
10
10
|
|
|
11
11
|
- [Audits](audits.md): Running every health check as one set, what the single verdict means, the exit code each outcome takes, the retained baseline and the delta it reports, and which corpora are kept out of the record
|
|
12
|
-
- [Capture](capture.md): Rendering
|
|
12
|
+
- [Capture](capture.md): Rendering HTML sources to PNG, what the command asserts about fonts, and why the selector has no default
|
|
13
13
|
- [Census](census.md): Tracked-plus-untracked file count, a breakdown by extension, and a line total that skips whatever reads as binary
|
|
14
14
|
- [Command catalog](commands.md): Every project-level command and every domain subcommand, plus the shape each domain exposes
|
|
15
15
|
- [Comments](comments.md): Comment density by language and kind, the two structural exclusions, and how the degradation sweep finds its vocabulary
|
package/docs/agents/overview.md
CHANGED
|
@@ -5,9 +5,9 @@ description: What this folder covers, the invocation rules every command inherit
|
|
|
5
5
|
|
|
6
6
|
# Overview
|
|
7
7
|
|
|
8
|
-
CLI catalog and invocation rules for
|
|
8
|
+
CLI catalog and invocation rules for an agent driving the `canon` CLI, in this repository or in any project that installed it.
|
|
9
9
|
|
|
10
|
-
This folder is an index of what an agent can run and how to run it cleanly from a script. It does not cover domain behavior. Read `CLAUDE.md` for
|
|
10
|
+
This folder is an index of what an agent can run and how to run it cleanly from a script. It does not cover domain behavior. Read the project's own `CLAUDE.md` for that. The `.claude/skills/internal-*` skills carry the per-domain editing guidance and live in the toolkit checkout alone, so a reader who installed the package resolves none of them.
|
|
11
11
|
|
|
12
12
|
## Invocation rules
|
|
13
13
|
|
|
@@ -22,5 +22,5 @@ See `CLAUDE.md` design principles. They apply to every command in this folder.
|
|
|
22
22
|
## Related
|
|
23
23
|
|
|
24
24
|
- `CLAUDE.md`: project behaviors and design principles
|
|
25
|
-
- `.claude/skills/internal-*`: domain-scoped guidance for editing work
|
|
25
|
+
- `.claude/skills/internal-*`: domain-scoped guidance for editing work, in the toolkit checkout only
|
|
26
26
|
- `docs/index.md`: full docs directory
|
|
@@ -30,7 +30,7 @@ Three root files are read whether or not the field names them, being `package.js
|
|
|
30
30
|
|
|
31
31
|
### What the corpus leaves out
|
|
32
32
|
|
|
33
|
-
The corpus answers what the package publishes, which is narrower than what the repository holds. Measured against this repository on 2026-08-21, the scan read 544 files and left 593 of the 1139 git lists unread. Those include everything under `.claude/`, `wiki/`, and `internal/`, the workflow definitions under `.github/`, and the trees the publish negations remove, being `scripts/sandbox/`, `scripts/eval/`, `src/capture
|
|
33
|
+
The corpus answers what the package publishes, which is narrower than what the repository holds. Measured against this repository on 2026-08-21, the scan read 544 files and left 593 of the 1139 git lists unread. Those include everything under `.claude/`, `wiki/`, and `internal/`, the workflow definitions under `.github/`, and the trees the publish negations remove, being `scripts/sandbox/`, `scripts/eval/`, and every test file. `src/capture/` was a fourth negation when that reading was taken and is not one now. The folder holds 5 tracked files, 2 of them tests the publish still excludes, so the corpus is 3 wider than the numbers above describe and the unread count is 3 smaller.
|
|
34
34
|
|
|
35
35
|
A public repository makes that gap readable by anyone, so a clean run means no credential in the published tree rather than none in the repository. The run states the number on every pass, including a clean one, so the bound travels with the verdict. Widening the corpus to every tracked file is a separate decision, since the row this implements puts the shipped tree first on the record's rule that content leaving the repository gates harder than content that stays.
|
|
36
36
|
|