@erclx/canon 4.67.0 → 4.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/{claude-autoship → auto-ship}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-autoship → auto-ship}/SKILL.md +36 -36
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +2 -2
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback-triage/SKILL.md +3 -3
- package/claude/skills/canon-operator/REQUIREMENT.md +1 -1
- package/claude/skills/canon-operator/SKILL.md +4 -4
- package/claude/skills/canon-rollout/REQUIREMENT.md +6 -6
- package/claude/skills/canon-rollout/SKILL.md +7 -7
- package/claude/skills/{claude-design-extract → design-extract}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-design-extract → design-extract}/SKILL.md +1 -1
- package/claude/skills/{claude-docs → docs-fold}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-docs → docs-fold}/SKILL.md +14 -14
- package/claude/skills/{claude-docs → docs-fold}/references/anchor-sweep.md +1 -1
- package/claude/skills/{claude-docs → docs-fold}/references/wireframe-sweep.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +3 -3
- package/claude/skills/docs-sync/SKILL.md +1 -1
- package/claude/skills/draft-and-pick/REQUIREMENT.md +4 -4
- package/claude/skills/draft-and-pick/SKILL.md +6 -6
- package/claude/skills/draft-context/REQUIREMENT.md +2 -2
- package/claude/skills/draft-context/SKILL.md +3 -3
- package/claude/skills/{claude-diagram → draft-diagram}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-diagram → draft-diagram}/SKILL.md +3 -3
- package/claude/skills/draft-docs/REQUIREMENT.md +1 -1
- package/claude/skills/draft-wireframes/REQUIREMENT.md +1 -1
- package/claude/skills/draft-wireframes/SKILL.md +2 -2
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +1 -1
- package/claude/skills/git-pr/SKILL.md +3 -3
- package/claude/skills/git-ship/REQUIREMENT.md +2 -2
- package/claude/skills/git-ship/SKILL.md +8 -8
- package/claude/skills/git-worktree/REQUIREMENT.md +2 -2
- package/claude/skills/git-worktree/SKILL.md +3 -3
- package/claude/skills/identity/REQUIREMENT.md +2 -2
- package/claude/skills/identity/SKILL.md +3 -3
- package/claude/skills/{claude-markdown-propose → markdown-propose}/REQUIREMENT.md +8 -8
- package/claude/skills/{claude-markdown-propose → markdown-propose}/SKILL.md +5 -5
- package/claude/skills/{claude-markdown-propose → markdown-propose}/references/format.md +1 -1
- package/claude/skills/{claude-memory-capture → memory-capture}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-memory-capture → memory-capture}/SKILL.md +13 -13
- package/claude/skills/{claude-memory-review → memory-review}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-memory-review → memory-review}/SKILL.md +10 -10
- package/claude/skills/migration-context/SKILL.md +1 -1
- package/claude/skills/migration-standards-drop/REQUIREMENT.md +1 -1
- package/claude/skills/migration-superseded/REQUIREMENT.md +1 -1
- package/claude/skills/{claude-feature → plan-feature}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-feature → plan-feature}/SKILL.md +4 -4
- package/claude/skills/{claude-groundwork → plan-groundwork}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-groundwork → plan-groundwork}/SKILL.md +8 -8
- package/claude/skills/{claude-intake → plan-intake}/REQUIREMENT.md +6 -6
- package/claude/skills/{claude-intake → plan-intake}/SKILL.md +10 -10
- package/claude/skills/{claude-intake-answer → plan-intake-answer}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-intake-answer → plan-intake-answer}/SKILL.md +5 -5
- package/claude/skills/{claude-address-review → review-address}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-address-review → review-address}/SKILL.md +6 -6
- package/claude/skills/{claude-address-review → review-address}/references/rebase-conflicts.md +1 -1
- package/claude/skills/{claude-review → review-branch}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-review → review-branch}/SKILL.md +4 -4
- package/claude/skills/{claude-pr-review → review-pr}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-pr-review → review-pr}/SKILL.md +11 -11
- package/claude/skills/{claude-orchestrate → role-orchestrator}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-orchestrate → role-orchestrator}/SKILL.md +20 -20
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-dispatch.md +30 -30
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-handoff.md +2 -2
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-parked.md +8 -8
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-poll.md +8 -8
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-resume.md +1 -1
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-sweep.md +1 -1
- package/claude/skills/{claude-orchestrate → role-orchestrator}/scripts/poll.sh +6 -6
- package/claude/skills/{claude-planner → role-planner}/REQUIREMENT.md +12 -12
- package/claude/skills/{claude-planner → role-planner}/SKILL.md +4 -4
- package/claude/skills/{claude-worker → role-worker}/REQUIREMENT.md +8 -8
- package/claude/skills/{claude-worker → role-worker}/SKILL.md +6 -6
- package/claude/skills/{claude-seed-sync → seed-sync}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-seed-sync → seed-sync}/SKILL.md +3 -3
- package/claude/skills/session-map/REQUIREMENT.md +2 -2
- package/claude/skills/session-map/SKILL.md +2 -2
- package/claude/skills/session-resume/REQUIREMENT.md +2 -2
- package/claude/skills/session-resume/SKILL.md +2 -2
- package/claude/skills/{claude-worktree → session-worktree}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-worktree → session-worktree}/SKILL.md +6 -6
- package/claude/skills/setup-plugins/references/plugin-catalog.md +1 -1
- package/claude/skills/{claude-standards-audit → standards-audit}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-standards-audit → standards-audit}/SKILL.md +2 -2
- package/claude/skills/systematic-debugging/REQUIREMENT.md +1 -1
- package/claude/skills/{claude-tasks → task-board}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-tasks → task-board}/SKILL.md +7 -7
- package/claude/skills/{claude-teach → teach-workspace}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-teach → teach-workspace}/SKILL.md +4 -4
- package/claude/skills/test-first/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-ui-test → ui-test}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-ui-test → ui-test}/SKILL.md +3 -3
- package/claude/skills/{claude-ux-audit → ux-audit}/REQUIREMENT.md +6 -6
- package/claude/skills/{claude-ux-audit → ux-audit}/SKILL.md +5 -5
- package/claude/skills/{claude-ux-measure → ux-measure}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-ux-measure → ux-measure}/SKILL.md +5 -5
- package/docs/agents/commands.md +1 -0
- package/docs/agents/install-and-sync.md +1 -1
- package/docs/agents/key-changes.md +3 -3
- package/docs/agents/markdown-audit.md +1 -1
- package/docs/agents/restated.md +1 -1
- package/docs/agents/review-classification.md +1 -1
- package/docs/agents/sandbox.md +13 -10
- package/docs/agents/sessions.md +1 -1
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/targets.md +1 -1
- package/docs/agents/tasks.md +4 -4
- package/docs/agents/teach.md +1 -1
- package/docs/target-projects.md +10 -10
- package/docs/workflow/ai-workflow.md +84 -84
- package/docs/workflow/operating-model.md +17 -17
- package/docs/workflow/visual-design-workflow.md +6 -6
- package/governance/rules/core/045-memory.md +1 -1
- package/governance/rules/core/085-worktrees.md +1 -1
- package/package.json +1 -1
- package/scripts/core/regen-agent-fixture.sh +1 -1
- package/scripts/core/regen-hero.sh +7 -7
- package/scripts/lib/sandbox-dispatch.sh +8 -0
- package/snippets/claude/decision-memo.md +1 -1
- package/src/autoship/paths.ts +1 -1
- package/src/claude/cases/all.ts +2 -2
- package/src/claude/cases/{claude-workflow.ts → workflow.ts} +33 -33
- package/src/claude/plugin-update.ts +48 -0
- package/src/commands/claude.ts +281 -1
- package/src/commands/feedback.ts +15 -5
- package/src/commands/gate.ts +3 -1
- package/src/commands/sandbox.ts +13 -4
- package/src/commands/sync.ts +3 -3
- package/src/design/components.ts +12 -0
- package/src/design/tokens.ts +1 -1
- package/src/gate/measures.ts +47 -1
- package/src/gov/restated.ts +2 -2
- package/src/markdown/structure.ts +1 -1
- package/src/migrate/rename.ts +4 -3
- package/src/pr/bijection.ts +1 -1
- package/src/pr/paths.ts +2 -2
- package/src/sandbox/expect.ts +26 -1
- package/src/shipped/references.ts +1 -1
- package/src/sync/seeds-report.ts +1 -1
- package/src/targets/pulls.ts +2 -2
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +4 -4
- package/src/tasks/record.ts +2 -2
- package/src/tasks/validate.ts +1 -1
- package/src/teach/nav.ts +97 -3
- package/standards/glossary.md +8 -0
- package/standards/groundwork.md +1 -1
- package/standards/snippets.md +1 -1
- package/standards/tasks.md +3 -3
- package/standards/teach.md +2 -2
- package/tooling/base/configs/.husky/post-merge +3 -3
- package/tooling/claude/reference.md +5 -5
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +2 -2
- /package/claude/skills/{claude-memory-review → memory-review}/references/receipt-format.md +0 -0
- /package/claude/skills/{claude-orchestrate → role-orchestrator}/scripts/watch.sh +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/lesson-craft.md +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/pedagogy.md +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/promotion.md +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: teach-workspace
|
|
3
3
|
description: Opens and runs a learning workspace on one subject, holding a mission, resources, numbered lessons, reference pages, a glossary, and learning records that survive across sessions, and proposes where a durable page from one belongs once it outgrows the workspace. Use when asked to "teach me X", "open a learning workspace", "I want to learn X", "quiz me on this", "continue the lesson", "resume my workspace on X", or "promote this reference page". Do NOT use to write project documentation, which belongs to the surface owning that document, and do NOT use to answer one question, which is an ordinary reply.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
argument-hint: <subject to learn, or the topic of a workspace to resume or promote>
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Teach workspace
|
|
9
9
|
|
|
10
10
|
Run a learning workspace on one subject across sessions. The workspace holds what the learner has been through, so a session weeks later resumes from the folder rather than from the conversation.
|
|
11
11
|
|
|
@@ -213,7 +213,7 @@ Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to
|
|
|
213
213
|
|
|
214
214
|
The handoff is its own file rather than a shared one. The routed-facts file another skill writes is deleted by whichever pass folds it, so a second producer's unread work goes with it, and a sibling path costs the folding skill one more read and removes the interaction.
|
|
215
215
|
|
|
216
|
-
An append is a whole-file operation, so send it as a plain single `Bash` command carrying a heredoc, per Step 0. Then tell the operator that `/
|
|
216
|
+
An append is a whole-file operation, so send it as a plain single `Bash` command carrying a heredoc, per Step 0. Then tell the operator that `/docs-fold` folds the file in from a branch. The proposal costs nothing tracked and runs anywhere, while the page it describes is a tracked file, so the fold is a worktree operation and the workspace it came from is not.
|
|
217
217
|
|
|
218
218
|
## Output
|
|
219
219
|
|
|
@@ -236,7 +236,7 @@ A promotion pass reports its own shape instead, one line per page the operator c
|
|
|
236
236
|
|
|
237
237
|
```plaintext
|
|
238
238
|
➡️ Promoting: .canon/teach/<nn>-<topic>/reference/<slug>.md → <destination path>
|
|
239
|
-
→ Confirmed pages wait at .canon/tmp/teach-promotion/<slug>.md. Run /
|
|
239
|
+
→ Confirmed pages wait at .canon/tmp/teach-promotion/<slug>.md. Run /docs-fold from a branch to fold them in.
|
|
240
240
|
```
|
|
241
241
|
|
|
242
242
|
A pass where the operator confirmed nothing writes no handoff file and reports that alone.
|
|
@@ -30,5 +30,5 @@ Without this skill, a session implementing a planned change writes the test afte
|
|
|
30
30
|
## Out of scope
|
|
31
31
|
|
|
32
32
|
- Finding the cause of an unexplained failure: `canon:systematic-debugging`
|
|
33
|
-
- Confirming visual output after a change lands: `070-planning.md` states the order and `
|
|
34
|
-
- The mechanical audit of whether an implementation reached history ahead of its test: `canon gov test-order`, invoked from `
|
|
33
|
+
- Confirming visual output after a change lands: `070-planning.md` states the order and `ui-test` covers it
|
|
34
|
+
- The mechanical audit of whether an implementation reached history ahead of its test: `canon gov test-order`, invoked from `auto-ship`
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: ui-test
|
|
3
3
|
description: Why UI changes split into what a browser can assert and what only an eye can judge, and why the visual half is written to disk rather than printed
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UI test requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ Writing the checklist correctly to disk does not close the gap either. The file
|
|
|
37
37
|
|
|
38
38
|
## Out of scope
|
|
39
39
|
|
|
40
|
-
- Judging whether the UI is any good, which `
|
|
40
|
+
- Judging whether the UI is any good, which `ux-audit` owns
|
|
41
41
|
- Unit and component tests, which belong to implementation
|
|
42
42
|
- Deciding whether an outstanding checklist blocks the ship, which the calling pipeline gates on
|
|
43
43
|
- Performing the visual verification, which needs a person
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: ui-test
|
|
3
3
|
description: Generates and runs Playwright e2e tests for UI changes, with a manual checklist for visual-only items. Use after implementing UI changes, or when asked "what should I test", "what do I verify", or "give me a test checklist". Do NOT use in empty sessions with no implementation context.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UI test
|
|
7
7
|
|
|
8
8
|
## Guards
|
|
9
9
|
|
|
@@ -59,7 +59,7 @@ If all changes are automatable, skip the manual checklist:
|
|
|
59
59
|
|
|
60
60
|
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
|
|
61
61
|
|
|
62
|
-
When a manual checklist is produced, write it directly to `.canon/tmp/ui-checklist/<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `
|
|
62
|
+
When a manual checklist is produced, write it directly to `.canon/tmp/ui-checklist/<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does. Create the directory if it does not exist. Always overwrite. This is a handoff file rather than a deliverable: `git-pr` posts it as a pull request comment once one opens, then removes it, and nothing here talks to `gh` directly.
|
|
63
63
|
|
|
64
64
|
From a linked worktree the file-editing tools refuse that path, so the checklist goes out through `Bash`. Send the `mkdir -p` and the heredoc as two plain commands rather than joining them with `&&`, which is refused as compound.
|
|
65
65
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: ux-audit
|
|
3
3
|
description: Why UI roughness is reported against stated intent rather than taste, and why the audit observes without fixing
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UX audit requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -34,7 +34,7 @@ The pass slides into fixing what it finds, and then the audit and the change lan
|
|
|
34
34
|
## Out of scope
|
|
35
35
|
|
|
36
36
|
- Fixing what it found, which is a separate change with its own review
|
|
37
|
-
- Feature planning, which `
|
|
38
|
-
- Verifying one specific change, which `
|
|
39
|
-
- Defining the intent it audits against, which `
|
|
40
|
-
- Measuring what a running interface costs to paint, block, or shift, which `
|
|
37
|
+
- Feature planning, which `plan-feature` owns
|
|
38
|
+
- Verifying one specific change, which `ui-test` owns
|
|
39
|
+
- Defining the intent it audits against, which `design-extract` and the wireframes own
|
|
40
|
+
- Measuring what a running interface costs to paint, block, or shift, which `ux-measure` owns. Contrast stays here rather than going with it, being computable from two color values this skill already reads off the token table.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Audits the current UI for incomplete, inconsistent, or confusing patterns. Reads DESIGN.md and .claude/wireframes/ for intent, scans UI files, and outputs observations grouped by surface. Use when asked "audit the UX", "audit the UI", "UX audit", or "find UI roughness". Do NOT use for new feature planning or code changes, and do NOT use to measure what a running interface costs to paint, which is `
|
|
2
|
+
name: ux-audit
|
|
3
|
+
description: Audits the current UI for incomplete, inconsistent, or confusing patterns. Reads DESIGN.md and .claude/wireframes/ for intent, scans UI files, and outputs observations grouped by surface. Use when asked "audit the UX", "audit the UI", "UX audit", or "find UI roughness". Do NOT use for new feature planning or code changes, and do NOT use to measure what a running interface costs to paint, which is `ux-measure`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UX audit
|
|
7
7
|
|
|
8
8
|
## Guards
|
|
9
9
|
|
|
10
10
|
- If no UI files exist in the project (no JSX, TSX, Vue, Svelte, or HTML under `src/`), stop: `❌ No UI surfaces found to audit.`
|
|
11
|
-
- If the request asks what the interface costs to paint, block, or shift at runtime, run nothing and name `
|
|
11
|
+
- If the request asks what the interface costs to paint, block, or shift at runtime, run nothing and name `ux-measure`. This skill reads source and reaches no number a browser produces. Contrast is the exception and stays here, since it is computable from the two color values already in the token table.
|
|
12
12
|
|
|
13
13
|
## Step 1: read context
|
|
14
14
|
|
|
@@ -59,7 +59,7 @@ If nothing is wrong, use: `✅ No observations.`
|
|
|
59
59
|
|
|
60
60
|
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
|
|
61
61
|
|
|
62
|
-
Write the full report directly to `.canon/review/ux-audit-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `
|
|
62
|
+
Write the full report directly to `.canon/review/ux-audit-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does. Create the directory if it does not exist. Always overwrite.
|
|
63
63
|
|
|
64
64
|
From a linked worktree the file-editing tools refuse that path, so the report goes out through `Bash`. Send the `mkdir -p` and the heredoc as two plain commands rather than joining them with `&&`, which is refused as compound.
|
|
65
65
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: ux-measure
|
|
3
3
|
description: Why a rendering cost question is answered with a number against a published threshold, and why the runner is detected rather than prescribed
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UX measure requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -41,8 +41,8 @@ A session that does start one picks a runner on the spot. The reading then comes
|
|
|
41
41
|
|
|
42
42
|
## Out of scope
|
|
43
43
|
|
|
44
|
-
- Judging the interface against stated intent, which `
|
|
45
|
-
- Contrast, which is computable from two color values in the token table `
|
|
44
|
+
- Judging the interface against stated intent, which `ux-audit` owns
|
|
45
|
+
- Contrast, which is computable from two color values in the token table `ux-audit` already reads. A contrast failure from a color computed at runtime stays invisible to that reader, and the cost is accepted rather than overlooked.
|
|
46
46
|
- Network waterfall, bundle size, and accessibility, which no version of this measures
|
|
47
|
-
- Writing behavioral tests against the interface, which `
|
|
47
|
+
- Writing behavioral tests against the interface, which `ui-test` owns
|
|
48
48
|
- Fixing what the reading found
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Measures paint, processor, and layout cost against a running interface and reports numbers against published thresholds. Detects the project's existing browser harness rather than requiring one. Use when asked "how fast is this page", "measure the UI", "what does this cost to render", "check Core Web Vitals", or "profile the interface". Do NOT use to judge UI quality by reading source, which is `
|
|
2
|
+
name: ux-measure
|
|
3
|
+
description: Measures paint, processor, and layout cost against a running interface and reports numbers against published thresholds. Detects the project's existing browser harness rather than requiring one. Use when asked "how fast is this page", "measure the UI", "what does this cost to render", "check Core Web Vitals", or "profile the interface". Do NOT use to judge UI quality by reading source, which is `ux-audit`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UX measure
|
|
7
7
|
|
|
8
8
|
Report numbers. A sentence about what the source looks like is what this exists to replace, so every finding is a reading beside the threshold it is measured against.
|
|
9
9
|
|
|
10
10
|
## Guards
|
|
11
11
|
|
|
12
12
|
- If the project names no command that serves an interface and the user names no URL, stop: `❌ Nothing to serve. Name a running URL or a command that starts one.` Test for a servable interface rather than for source under a particular folder, since this measures what a browser receives and never reads the tree that produced it.
|
|
13
|
-
- If the request is about intent, consistency, missing states, or contrast, run nothing and name `
|
|
13
|
+
- If the request is about intent, consistency, missing states, or contrast, run nothing and name `ux-audit`. That skill reads source and this one runs the interface.
|
|
14
14
|
|
|
15
15
|
## Step 1: reach the interface
|
|
16
16
|
|
|
@@ -106,7 +106,7 @@ Report the reading and stop there. A remedy for a poor verdict is a change with
|
|
|
106
106
|
|
|
107
107
|
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
|
|
108
108
|
|
|
109
|
-
Write the full reading directly to `.canon/review/ux-measure-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `
|
|
109
|
+
Write the full reading directly to `.canon/review/ux-measure-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does. Create the directory if it does not exist. Always overwrite.
|
|
110
110
|
|
|
111
111
|
From a linked worktree the file-editing tools refuse that path, so the reading goes out through `Bash`. Send the `mkdir -p` and the heredoc as two plain commands rather than joining them with `&&`, which is refused as compound.
|
|
112
112
|
|
package/docs/agents/commands.md
CHANGED
|
@@ -68,6 +68,7 @@ Full help: `canon <command> --help`. Behavior notes for the install and sync ver
|
|
|
68
68
|
| `canon claude skills reach` | Report the bodies in either skill corpus citing a toolkit path no target project receives, exiting 2 on an unqualified one |
|
|
69
69
|
| `canon claude skills rank` | Score either skill corpus's descriptions against a case corpus by TF-IDF cosine similarity, reporting rank-one and top-three (`--cases <path>`) |
|
|
70
70
|
| `canon claude routing` | Report per `CLAUDE.md` section how many bullets name a path and how many of those a path-scoped rule already covers (`--json`) |
|
|
71
|
+
| `canon claude plugin-update` | Match the installed marketplace plugin against `claude/.claude-plugin/plugin.json`'s own name and run `claude plugin update` on it, reading the version back off `claude plugin list --json` since the update call reports none of its own (`--json`) |
|
|
71
72
|
| `canon gov test-order` | Report where an implementation reached history ahead of the test covering it (`--json`) |
|
|
72
73
|
| `canon gov superseded` | Report where the tree still asserts a value a changed convention no longer produces, keyed on the value and on the family stem behind a templated citation (`--json`) |
|
|
73
74
|
| `canon gov restated` | Report every instruction the always-loaded file or a rule shares with the seed, a shipped skill body, or another rule, classed and with its anchors named (`--json`) |
|
|
@@ -232,7 +232,7 @@ finding the rendered half withheld.
|
|
|
232
232
|
equivalent, since the domain walk lists what a target installed and cannot see a
|
|
233
233
|
file that never arrived. There is no `customized` verdict here, because that one
|
|
234
234
|
needs a stamp and seeds carry none, so a file history cannot attribute stays
|
|
235
|
-
`drifted`. Reconcile the section with `
|
|
235
|
+
`drifted`. Reconcile the section with `seed-sync`, which merges one
|
|
236
236
|
section at a time rather than replacing a file the project edits.
|
|
237
237
|
|
|
238
238
|
A markdown seed installs rewritten rather than copied, since the `stub: true`
|
|
@@ -37,7 +37,7 @@ They are reported apart because they want different tolerances.
|
|
|
37
37
|
- **`unmet`** is a whole path the body claims ahead of its bullet's first comma and the diff does not carry. This is the graded direction and it sets the exit code. A bullet naming an untouched file is wrong more often than not, and it corrupts the record that reaches the trunk.
|
|
38
38
|
- **`unnamed`** is a changed file no bullet reached that a reader might have wanted one for. Reported with no grade, since a change can be too small to describe and still be correctly absent. Grading it would fire on nearly every branch.
|
|
39
39
|
- **`incidental`** is a changed file no bullet reached that owes none: a test beside its subject, anything under a fixture or snapshot folder, and a lockfile a package manager writes. Held apart so the count above reads, and reported rather than dropped so a run still says what it set aside.
|
|
40
|
-
- **`unresolved`** is a path the reading could not judge either way. Two causes reach it: a path written partially, such as `
|
|
40
|
+
- **`unresolved`** is a path the reading could not judge either way. Two causes reach it: a path written partially, such as `role-worker/SKILL.md` for a file under `claude/skills/`, and a path past its bullet's first comma.
|
|
41
41
|
|
|
42
42
|
Each direction splits on one question, which is whether the evidence is strong enough to raise with a person. A partial path and a trailing path can each credit a changed file and can never accuse one, because nothing separates a path written short from a path written wrong, or a second claim from a file cited for context. Neither split drops anything: what comes out of `unmet` lands in `unresolved` and what comes out of `unnamed` lands in `incidental`, so a count a reader can act on never costs a file the run stayed silent about.
|
|
43
43
|
|
|
@@ -49,7 +49,7 @@ Only `## Key Changes` is read. `## Technical Context` legitimately names files a
|
|
|
49
49
|
|
|
50
50
|
Inside the section, every backticked span in a bullet is read, and the bullet's first comma outside a span divides the ones that can accuse from the ones that can only credit. That one lever was chosen by measurement. Over the 23 merged pull requests in this repository carrying the section, reading whole bullets reported 16 paths as claimed-but-untouched and every one was a file the body named for context. Cutting at the comma left 110 claims of the original 149 and took the false reports to 2. A list of sixteen clause-opening words tried beside it removed nothing the comma had not already removed, because this corpus punctuates every one of them.
|
|
51
51
|
|
|
52
|
-
The cut used to decide whether a span was read at all, and the paths past the comma fell out of the claim set into `unnamed`. That was accepted on the ground that the ungraded direction does no damage, and it did: `
|
|
52
|
+
The cut used to decide whether a span was read at all, and the paths past the comma fell out of the claim set into `unnamed`. That was accepted on the ground that the ungraded direction does no damage, and it did: `review-pr` read `unnamed` as a question to put to the branch author, so on 2026-09-01 the question went to three pull requests over bullets that had named the files all along. Reading the whole bullet as claims outright is the obvious repair and the corpus refuses it, taking `unmet` from 10 to 19 over the 40 most recent merged pull requests carrying the section, with all nine additions in the context class the cut exists to exclude. Reading the whole bullet and gating the accusation on the cut gives claims 243 to 314 and unnamed 1124 to 1058 with `unmet` identical entry for entry.
|
|
53
53
|
|
|
54
54
|
A span anywhere in the bullet has to survive all of these:
|
|
55
55
|
|
|
@@ -109,4 +109,4 @@ One class stays open and is named rather than closed. A bullet can cite where so
|
|
|
109
109
|
|
|
110
110
|
## Where it runs
|
|
111
111
|
|
|
112
|
-
`
|
|
112
|
+
`review-pr` Step 3 calls it and files an `unmet` path as a `should-fix` finding under the `**PR body**` block the stale ticked box already takes, since what both corrupt is the merge record rather than a file in the diff. A body is edited between pushes, so a finding names the head the comparison ran at. `unnamed` is read there and raised off no count, since the step's own history is a question sent over bullets that already answered it. `unresolved` and `incidental` are reported nowhere.
|
|
@@ -162,7 +162,7 @@ The target push stage reads the same exit codes `canon gate run`'s own stage rea
|
|
|
162
162
|
|
|
163
163
|
The target push stage excludes `CHANGELOG.md`, unlike every other surface here. A changelog a generator builds from commit subjects carries prose nobody wrote against the ban set, where this repository's own passes only because `release-please` builds it from subjects sessions already wrote to the rule. The stage passes an explicit file list rather than the bare invocation the other surfaces use, so a corpus with no file left once the changelog is set aside reads as a pass rather than falling back to the whole tree.
|
|
164
164
|
|
|
165
|
-
The fifth surface reads the standards directly and is not a consolidation left half done. `claude/skills/
|
|
165
|
+
The fifth surface reads the standards directly and is not a consolidation left half done. `claude/skills/standards-audit/SKILL.md` greps the banned tokens agent-side, which is a session reading prose rather than a process it can shell out to, and it ships to every target. It is the likeliest place for the next drift, since nothing compares it against the verb.
|
|
166
166
|
|
|
167
167
|
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies. It reads `bans.emptySets` out of the same record, so a set the verb shipped empty reaches the author as a check narrowed to what it could measure rather than as a clean pass.
|
|
168
168
|
|
package/docs/agents/restated.md
CHANGED
|
@@ -46,7 +46,7 @@ Every record names the anchors its match rested on, so a reader can weigh a find
|
|
|
46
46
|
|
|
47
47
|
## The three classes
|
|
48
48
|
|
|
49
|
-
- **Mirror.** Both files sit on a declared path pair whose duplication is deliberate. `CLAUDE.md` and the seed are the one pair, since the seed is authored from it and `
|
|
49
|
+
- **Mirror.** Both files sit on a declared path pair whose duplication is deliberate. `CLAUDE.md` and the seed are the one pair, since the seed is authored from it and `seed-sync` exists to reconcile the two. Excluding by pair rather than by content is the point: the duplication is a location fact this repository already records, and a content test would rediscover it on every run.
|
|
50
50
|
- **Repetition.** Two surfaces state one rule and neither is declared a copy of the other.
|
|
51
51
|
- **Contradiction.** The prohibition falls on one surface alone, on a match strong enough to read that as a disagreement. This is a polarity reading rather than a judgment about meaning, so weigh each against the surfaces it names.
|
|
52
52
|
|
|
@@ -64,7 +64,7 @@ An empty set refuses with `no-changes` rather than skipping. Both tests are univ
|
|
|
64
64
|
|
|
65
65
|
## Why it is a verb
|
|
66
66
|
|
|
67
|
-
The decision was three sentences in `
|
|
67
|
+
The decision was three sentences in `auto-ship`'s review step, applied by a session reading a bulleted list of paths. It failed three times. A driven arm on 2026-08-30 staged `.claude/skills/deploy-check/SKILL.md`, which that list names, and the chain skipped review and opened a draft pull request anyway. The rule was correct and the session did not apply it, and the two fixes before that one were each a rewrite of the same prose.
|
|
68
68
|
|
|
69
69
|
A rule a session can talk itself out of moves into a verb. That is the same argument the quiz-order draw in `canon teach lesson` was decided on: an instruction is a hope where a verb is a check.
|
|
70
70
|
|
package/docs/agents/sandbox.md
CHANGED
|
@@ -22,17 +22,18 @@ Scenario categories: `infra:*` (domain flows), `git:*`, `scaffold:*`. `create` s
|
|
|
22
22
|
`canon sandbox check <category>:<command> [arm]` scores a provisioned sandbox against the arm's `expect.toml`, printing a verdict on stderr and, with `--json`, the same verdict as a record on stdout.
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
canon sandbox check claude:docs drift --json
|
|
25
|
+
canon sandbox check claude:docs-fold drift --json
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
| Flag
|
|
29
|
-
|
|
|
30
|
-
| `--envelope <file>`
|
|
31
|
-
| `--writes <file>`
|
|
32
|
-
| `--escapes <file>`
|
|
33
|
-
| `--escapes-watched`
|
|
34
|
-
| `--
|
|
35
|
-
| `--
|
|
28
|
+
| Flag | Effect |
|
|
29
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| `--envelope <file>` | Read `is_error`, `num_turns`, denials, and the reply text |
|
|
31
|
+
| `--writes <file>` | Newline-delimited paths the session wrote, for write scope |
|
|
32
|
+
| `--escapes <file>` | Newline-delimited paths written to a watched toolkit root, for escape scope |
|
|
33
|
+
| `--escapes-watched` | At least one watched root held a target this run |
|
|
34
|
+
| `--concurrent-sessions <file>` | Newline-delimited sessions live in the registry both before and after this run, a witness for an unbounded escape |
|
|
35
|
+
| `--json` | Emit the verdict record on stdout |
|
|
36
|
+
| `--strict` | Exit 1 on `unchecked` instead of 0 |
|
|
36
37
|
|
|
37
38
|
The verdict `state` is `pass`, `fail`, or `unchecked`. An arm with no `expect.toml` is `unchecked` and exits 0, so the harness stays usable while expectations roll out. A declaration that exists but asserts nothing is a failure, since an expectation file that asserts nothing passes every run.
|
|
38
39
|
|
|
@@ -70,4 +71,6 @@ A skill pairs to a scenario by filename, `<category>-<command>` first and bare `
|
|
|
70
71
|
|
|
71
72
|
`scripts/sandbox/run.sh` calls this after a headless run and merges the verdict into the envelope it prints. It also writes that merged record to `.canon/tmp/sandbox-runs/<target>-<arm>-<timestamp>.json` with a `writes` array appended, and logs the path on stderr. Both fields are what a later re-score needs, since `--envelope` and `--writes` read files the run deletes on exit.
|
|
72
73
|
|
|
73
|
-
Two more fields ride alongside the verdict rather than inside it. `escapes` lists what the run wrote under a watched toolkit root, which the verdict cannot assert over because those files sit outside the sandbox tree. `sessions` reports the nested-dispatch bound, carrying `watched` for whether the client's session registry was there to read, `new` for the records that appeared while the run was in flight, and `reap` for what the run found in the session's process group afterwards. Neither field fails a run on its own.
|
|
74
|
+
Two more fields ride alongside the verdict rather than inside it. `escapes` lists what the run wrote under a watched toolkit root, which the verdict cannot assert over because those files sit outside the sandbox tree. `sessions` reports the nested-dispatch bound, carrying `watched` for whether the client's session registry was there to read, `new` for the records that appeared while the run was in flight, `concurrent` for the records present both before and after, and `reap` for what the run found in the session's process group afterwards. Neither field fails a run on its own.
|
|
75
|
+
|
|
76
|
+
`run.sh` passes `concurrent` through `--concurrent-sessions` to `sandbox check`, and `checkEscapeScope` appends a witness count to an `unbounded escape:` message rather than lets it soften the verdict.
|
package/docs/agents/sessions.md
CHANGED
|
@@ -42,7 +42,7 @@ A bare run reports every repository and carries a `repository` field on each row
|
|
|
42
42
|
|
|
43
43
|
The match can return more than one session. Read the count rather than the first row, since nothing stops two sessions holding one branch, and a caller that treats the result as singular picks among candidates without knowing it.
|
|
44
44
|
|
|
45
|
-
Resolution reads a session's registered `cwd`, taken at whatever `locate()` finds there rather than wherever it has since worked. That registration updates whenever the harness enters a worktree: a worker dispatched onto `main` re-registers at its own branch once `
|
|
45
|
+
Resolution reads a session's registered `cwd`, taken at whatever `locate()` finds there rather than wherever it has since worked. That registration updates whenever the harness enters a worktree: a worker dispatched onto `main` re-registers at its own branch once `auto-ship` Step 0 runs. What stays fixed is a session moved by shell command, `cd` or `git -C` against another root, with no worktree entry behind it, so it answers only for the branch its last registered `cwd` sits in.
|
|
46
46
|
|
|
47
47
|
A session whose `cwd` reflects a harness worktree entry, at launch or mid-session, resolves fully, covering every dispatched worker once Step 0 runs. A zero for a different branch it is genuinely working on is not evidence the branch is unclaimed, only that a shell-moved registration cannot see it.
|
|
48
48
|
|
|
@@ -5,7 +5,7 @@ description: Reading committed state rather than an arriving change, the shipped
|
|
|
5
5
|
|
|
6
6
|
# State-scoped risk
|
|
7
7
|
|
|
8
|
-
Every review surface a session can reach is scoped to a change. `
|
|
8
|
+
Every review surface a session can reach is scoped to a change. `review-branch` reads the branch diff, `review-pr` reads a pull request, and `code-review` takes a diff, a branch, or a path. A risk that arrived before the range under review is invisible to all three by construction, which is what these two commands answer.
|
|
9
9
|
|
|
10
10
|
| Question | Command |
|
|
11
11
|
| -------------------------------------------------------- | -------------------- |
|
package/docs/agents/targets.md
CHANGED
|
@@ -78,7 +78,7 @@ Exit codes: `0` at least one target was read, `1` refused or every target refuse
|
|
|
78
78
|
|
|
79
79
|
`checks` is `null` rather than `passing` when no check ran at all, which is not the same answer. A failure outranks a run still going, since a job that already failed cannot be cleared by one still in flight.
|
|
80
80
|
|
|
81
|
-
`review` reads the first line of the newest pass carrying `## Review` or `## Review closed`, which `
|
|
81
|
+
`review` reads the first line of the newest pass carrying `## Review` or `## Review closed`, which `review-pr` owns and posts. A target leaves a wave on `closed` rather than on a worker's reply.
|
|
82
82
|
|
|
83
83
|
A target that could not be read carries a `reason` rather than an empty pull list. Reading a failed query as no open work is what reports a target as done having read nothing, which is the failure mode of the hand-written shell loop this replaces.
|
|
84
84
|
|
package/docs/agents/tasks.md
CHANGED
|
@@ -148,9 +148,9 @@ The record carries `type`, `slug`, `branch`, `words`, and `conforms`. Exit codes
|
|
|
148
148
|
|
|
149
149
|
`slug` is the plan filename with its `feature-` prefix and its extension taken off, and `type` is the constant `feat`. Reading a type off the plan's prose was the alternative, and it is the half of the derivation that has already disagreed with itself: one dispatch checked `fix/path-form-hook` against a worker that took `feat/path-form-hook`, both sides reading one plan. What makes the constant safe is that a branch type is cosmetic. `git-stage` reads a commit's type off the staged diff and `git-pr` reads a title off the diff, so the semantics a release reads never pass through the branch name. What it costs is a worktree listing where every plan-derived branch reads `feat/`, and nothing renames it later.
|
|
150
150
|
|
|
151
|
-
`conforms` reads both caps `standards/branch.md` states, being 4 words on the description and 50 characters on the whole branch. A false reading is a row for a person rather than a name to shorten here, since a rename parts the branch slug from the plan slug that `
|
|
151
|
+
`conforms` reads both caps `standards/branch.md` states, being 4 words on the description and 50 characters on the whole branch. A false reading is a row for a person rather than a name to shorten here, since a rename parts the branch slug from the plan slug that `session-worktree` tier 1 and `git-pr`'s plan lookup both read back.
|
|
152
152
|
|
|
153
|
-
Both sides of a dispatch call it. The orchestrator's collision check derives its candidate here, and `
|
|
153
|
+
Both sides of a dispatch call it. The orchestrator's collision check derives its candidate here, and `auto-ship` Step 0 derives the worktree it enters from the same plan, so the branch a gate clears and the branch a session takes are one string by construction. They were two readings of one paragraph until 2026-09-06, when four dispatches on one plan produced three different strings.
|
|
154
154
|
|
|
155
155
|
```bash
|
|
156
156
|
canon tasks plan-branch dispatch-answer-gate --json | jq -r '.branch'
|
|
@@ -158,7 +158,7 @@ canon tasks plan-branch dispatch-answer-gate --json | jq -r '.branch'
|
|
|
158
158
|
|
|
159
159
|
## Plan link
|
|
160
160
|
|
|
161
|
-
`canon tasks plan-link <task> <plan>` writes or corrects a task's `Plan:` line, as `Plan: [<label>](<target>)` right after the H1. `
|
|
161
|
+
`canon tasks plan-link <task> <plan>` writes or corrects a task's `Plan:` line, as `Plan: [<label>](<target>)` right after the H1. `plan-feature` calls it right after a plan file lands, when Step 1 resolved an existing task for the feature, so the line is a mechanical write rather than hand-edited markdown.
|
|
162
162
|
|
|
163
163
|
Name the task by its filename stem, and the plan by its path or its slug, the same two forms `canon tasks plan-answers` accepts:
|
|
164
164
|
|
|
@@ -321,7 +321,7 @@ A task file neither surface names lands in a fourth array, on the same reasoning
|
|
|
321
321
|
}
|
|
322
322
|
```
|
|
323
323
|
|
|
324
|
-
Under the roster-checked hand-off `
|
|
324
|
+
Under the roster-checked hand-off `task-board` and `plan-groundwork` state, filing a task and placing its row are two acts a different session each may take, so a task caught between the two is ordinary rather than a finding and this array moves no exit code. It still reports, since it is the only local detector for a row a hand-edit dropped, a handoff message that never arrived, or an orchestrator that ended before placing it.
|
|
325
325
|
|
|
326
326
|
Exit codes: `0` every check passed, `1` refused, `2` at least one finding. The `reason` field carries which gate refused: `no-board`, `no-ordering`, or `no-groups`. A board grouping under headings of its own trips `no-groups` rather than being read against columns it never declared.
|
|
327
327
|
|
package/docs/agents/teach.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Listing learning workspaces with what their records schedule next,
|
|
|
5
5
|
|
|
6
6
|
# Teach
|
|
7
7
|
|
|
8
|
-
Learning workspaces sit under `.canon/teach/<nn>-<topic>/`, and `standards/teach.md` fixes their layout, naming, and file formats, apart from the glossary, whose shape `standards/glossary.md` fixes, cited from the `
|
|
8
|
+
Learning workspaces sit under `.canon/teach/<nn>-<topic>/`, and `standards/teach.md` fixes their layout, naming, and file formats, apart from the glossary, whose shape `standards/glossary.md` fixes, cited from the `teach-workspace` skill, so it travels with the file wherever a promotion lands it. Every verb here resolves that folder against the main worktree root rather than against the working directory, so a session standing in a linked worktree reaches the one workspace the learner has rather than opening a second.
|
|
9
9
|
|
|
10
10
|
That root resolution is also why the writing verbs exist at all. The file-editing tools refuse a main-root path from a linked worktree and offer a worktree copy instead, and a caller naming only the destination reports a success that did not happen. A whole-file create still goes out as a shell heredoc. Changing a line inside a file that already exists has no shell route, because the stream editors are banned, so `resource` and `glossary` are the route for the two files a running workspace edits.
|
|
11
11
|
|
package/docs/target-projects.md
CHANGED
|
@@ -72,15 +72,15 @@ Keep the `## Scripts` table in `.claude/context/development.md` current as scrip
|
|
|
72
72
|
Scaffold installs tooling and seeds. It does not fill the planning docs or the design system. Complete those before the first feature session:
|
|
73
73
|
|
|
74
74
|
1. Fill `.claude/REQUIREMENTS.md` and `.claude/ARCHITECTURE.md`. The seed provides the files, the scope and decisions are yours to write.
|
|
75
|
-
2. For a UI project, invoke `canon:
|
|
76
|
-
3. Optionally invoke `canon:
|
|
75
|
+
2. For a UI project, invoke `canon:design-extract` to draft `.claude/DESIGN.md`. With no UI code yet it takes the greenfield path and proposes tokens from the requirements and a `## Personality` section. Skip for non-UI projects.
|
|
76
|
+
3. Optionally invoke `canon:draft-diagram` to draft entries under `.canon/diagrams/` from the architecture and the requirements. One file per diagram kind, so a later refresh of one kind leaves the others untouched. It renders each diagram it writes to verify the layout, which downloads the Mermaid CLI on first use and takes about 15 seconds.
|
|
77
77
|
4. Start the feature loop. See [AI workflow](workflow/ai-workflow.md) for the per-feature sequence.
|
|
78
78
|
|
|
79
79
|
A machine without a renderer still gets the diagrams and is told which check was skipped.
|
|
80
80
|
|
|
81
|
-
Each diagram entry records the commit and date it was last verified against, and nothing maintains that record for you. The folder is redrawn on demand rather than swept on every ship, so `verified` carries the whole signal: an entry whose date sits far behind your branch is due a read, and no pass will name which one. Run `canon:
|
|
81
|
+
Each diagram entry records the commit and date it was last verified against, and nothing maintains that record for you. The folder is redrawn on demand rather than swept on every ship, so `verified` carries the whole signal: an entry whose date sits far behind your branch is due a read, and no pass will name which one. Run `canon:draft-diagram` again when the code a kind is drawn from moves.
|
|
82
82
|
|
|
83
|
-
`.claude/ARCHITECTURE.md` carries the same mechanism on the same ship. `canon:
|
|
83
|
+
`.claude/ARCHITECTURE.md` carries the same mechanism on the same ship. `canon:docs-fold` anchors a decision it amends to the paths that decision cites, and reports an anchored decision whose cited path the branch touched.
|
|
84
84
|
|
|
85
85
|
### Stack decision
|
|
86
86
|
|
|
@@ -175,7 +175,7 @@ The first line reports the plan and the second applies it, relocating each rule
|
|
|
175
175
|
|
|
176
176
|
### Rename the skill citations, once
|
|
177
177
|
|
|
178
|
-
Twenty-five plugin skills dropped their `claude-` prefix for two-word names, so `canon:
|
|
178
|
+
Twenty-five plugin skills dropped their `claude-` prefix for two-word names, so `canon:docs-fold` answers as `canon:docs-fold` and `canon:task-board` as `canon:task-board`. A project that installed governance or tooling before that release holds files naming the old ones, and the plugin answers to none of them.
|
|
179
179
|
|
|
180
180
|
Two of those files run rather than sit there. `.husky/post-merge` prints a command for a person to type, and `.claude/hooks/pr-create-log.sh` hands a session a message naming a skill, so a stale copy tells someone to invoke something that no longer exists. A rule under `.claude/rules/canon/core/` names skills too, though a rule is read rather than run.
|
|
181
181
|
|
|
@@ -202,7 +202,7 @@ The report opens by naming the binary running it. The installed version reads ag
|
|
|
202
202
|
|
|
203
203
|
#### Then the causes
|
|
204
204
|
|
|
205
|
-
A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision and `canon:
|
|
205
|
+
A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision and `canon:seed-sync` is the tool for it. A `stranded` file sits where an older toolkit installed it and the toolkit has since moved, which is a relocation the report names but no command runs.
|
|
206
206
|
|
|
207
207
|
That attribution comes from `.claude/canon/config.json`, a stamp every install and sync writes. A target stamped before that path shipped is read from the retired `.claude/canon.json` instead, reported rather than migrated. Governance records a hash per installed file, plus the stack `canon gov install` was given, and tooling records the stack chain it resolved instead of any file hash, since its install runs no per-file walk to attribute.
|
|
208
208
|
|
|
@@ -210,7 +210,7 @@ Each domain holds its own toolkit commit, so syncing governance today does not m
|
|
|
210
210
|
|
|
211
211
|
A project that has never synced under a toolkit new enough to write a stamp falls back to the toolkit's own git history. Installed content matching any version that history published proves the file untouched, so it reports `stale` naming the commit it came from, and content matching no published version stays `drifted`. That fallback needs the toolkit as a git checkout. Installed from the registry it ships source without history, and the report says attribution was unavailable rather than reading every file as a local edit.
|
|
212
212
|
|
|
213
|
-
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:
|
|
213
|
+
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.
|
|
214
214
|
|
|
215
215
|
`unmigrated` currently names no domain, since standards and snippets are the two the toolkit ever installed at the project root and both closed their install channel. A target still holding a root `standards/` or `snippets/` folder from an older toolkit is carrying its own authoring surface now, not an unfinished install, and nothing proposes moving either.
|
|
216
216
|
|
|
@@ -258,7 +258,7 @@ Standards take no part in that run. Nothing installed them, so there is no copy
|
|
|
258
258
|
|
|
259
259
|
### Targeted
|
|
260
260
|
|
|
261
|
-
- Claude seed docs such as `CLAUDE.md` and `.claude/REQUIREMENTS.md`: invoke `canon:
|
|
261
|
+
- Claude seed docs such as `CLAUDE.md` and `.claude/REQUIREMENTS.md`: invoke `canon:seed-sync`. The skill splits each file into a preamble (between the H1 and the first H2) plus one part per `##` section, then diffs part by part and proposes per-part edits. User customizations are preserved.
|
|
262
262
|
- Governance rules already installed: `canon gov sync <path>` diffs and applies, and never adds new rules. A rule your recorded stack lists reports as `missing` instead.
|
|
263
263
|
- Tooling configs and seeds: `canon tooling <stack> <path>` overwrites golden configs and merges seeds
|
|
264
264
|
- Reference docs for a stack: `canon tooling reference <stack>` reads and never writes, so there is nothing to sync
|
|
@@ -281,7 +281,7 @@ claude
|
|
|
281
281
|
|
|
282
282
|
In the session, invoke `canon:setup-init`. The skill detects no framework and resolves tooling to `base` and governance to `base`. The preview marks both stacks as fallbacks, since neither came from a match, then the chain runs `canon init`.
|
|
283
283
|
|
|
284
|
-
Ongoing: run `canon sync --check .` to see what has drifted, then invoke `canon:
|
|
284
|
+
Ongoing: run `canon sync --check .` to see what has drifted, then invoke `canon:seed-sync` for seed drift or `canon sync .` for a catch-all refresh.
|
|
285
285
|
|
|
286
286
|
### Web application
|
|
287
287
|
|
|
@@ -295,7 +295,7 @@ Invoke `canon:setup-init`. The skill reads `package.json` and the Vite config, r
|
|
|
295
295
|
Ongoing maintenance:
|
|
296
296
|
|
|
297
297
|
- What has drifted: `canon sync --check .`
|
|
298
|
-
- Seed drift: invoke `canon:
|
|
298
|
+
- Seed drift: invoke `canon:seed-sync`
|
|
299
299
|
- Catch-all sync: `canon sync .`
|
|
300
300
|
- Governance rule refresh only: `canon gov sync .`
|
|
301
301
|
- Layer a new rule on top, for example `260-shadcn` after adopting shadcn: `canon gov install react --add 260-shadcn .`
|