@erclx/canon 5.32.0 → 5.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/REQUIREMENT.md +1 -2
- package/claude/skills/api-design/SKILL.md +2 -3
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/auto-ship/SKILL.md +1 -1
- package/claude/skills/auto-ship/references/worktree-name.md +1 -1
- package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
- package/claude/skills/backlog-triage/SKILL.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +16 -13
- package/claude/skills/canon-cli/SKILL.md +75 -32
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -0
- package/claude/skills/canon-feedback/SKILL.md +11 -29
- package/claude/skills/canon-feedback/references/template.md +53 -0
- package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +2 -2
- package/claude/skills/{canvas → canvas-board}/SKILL.md +6 -3
- package/claude/skills/{canvas → canvas-board}/references/canvas.md +26 -3
- package/{standards → claude/skills/canvas-board/references}/design.md +11 -2
- package/claude/skills/code-craft/REQUIREMENT.md +1 -1
- package/claude/skills/code-craft/SKILL.md +0 -1
- package/claude/skills/context-fold/REQUIREMENT.md +25 -33
- package/claude/skills/context-fold/SKILL.md +25 -70
- package/claude/skills/context-fold/references/classify.md +3 -3
- package/claude/skills/context-fold/references/completion-report.md +4 -4
- package/claude/skills/context-fold/references/context-refresh.md +5 -5
- package/{standards → claude/skills/context-fold/references}/context.md +16 -5
- package/claude/skills/context-fold/references/unusable-baseline.md +3 -5
- package/claude/skills/create-rule/SKILL.md +3 -3
- package/{standards → claude/skills/create-rule/references}/rule.md +15 -6
- package/claude/skills/create-skill/SKILL.md +2 -2
- package/{standards → claude/skills/create-skill/references}/skill.md +18 -15
- package/claude/skills/design-taste/REQUIREMENT.md +3 -3
- package/claude/skills/design-taste/SKILL.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +1 -1
- package/claude/skills/docs-sync/SKILL.md +3 -3
- package/{standards → claude/skills/docs-sync/references}/docs.md +11 -0
- package/{standards → claude/skills/docs-sync/references}/readme.md +9 -2
- package/claude/skills/draft-and-pick/SKILL.md +5 -5
- package/claude/skills/draft-doc/SKILL.md +6 -6
- package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
- package/claude/skills/draft-figure/SKILL.md +2 -2
- package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +1 -1
- package/claude/skills/draft-identity/REQUIREMENT.md +2 -2
- package/claude/skills/draft-identity/SKILL.md +2 -2
- package/claude/skills/draft-ready/SKILL.md +1 -1
- package/claude/skills/git-branch/SKILL.md +1 -1
- package/{standards → claude/skills/git-branch/references}/branch.md +1 -1
- package/claude/skills/git-commit/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-issue/SKILL.md +1 -1
- package/claude/skills/git-issue/references/issue.md +4 -1
- package/claude/skills/git-pr/SKILL.md +13 -13
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-pr/references/final-command.md +38 -14
- package/claude/skills/git-pr/references/labels.md +5 -1
- package/{standards → claude/skills/git-pr/references}/pr.md +19 -9
- package/{standards → claude/skills/git-pr/references}/publish.md +4 -2
- package/claude/skills/git-pr/references/task-number.md +1 -1
- package/claude/skills/git-ship/SKILL.md +15 -14
- package/claude/skills/git-split/SKILL.md +3 -3
- package/claude/skills/git-stage/SKILL.md +1 -1
- package/claude/skills/plan-feature/REQUIREMENT.md +1 -1
- package/claude/skills/review-address/SKILL.md +1 -1
- package/claude/skills/review-address/references/post-review-findings.md +1 -1
- package/claude/skills/review-craft/references/ui.md +1 -1
- package/claude/skills/review-pr/REQUIREMENT.md +1 -1
- package/claude/skills/review-pr/SKILL.md +3 -3
- package/claude/skills/review-pr/references/body-variants.md +2 -2
- package/claude/skills/review-pr/references/key-changes.md +3 -3
- package/claude/skills/review-pr/references/post.md +4 -2
- package/claude/skills/review-ui/REQUIREMENT.md +1 -1
- package/claude/skills/review-ui/SKILL.md +8 -6
- package/claude/skills/review-ui/references/driving.md +8 -8
- package/claude/skills/review-ui/references/post.md +53 -17
- package/claude/skills/role-orchestrator/REQUIREMENT.md +3 -0
- package/claude/skills/role-orchestrator/SKILL.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +8 -5
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +32 -1
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +3 -0
- package/claude/skills/role-planner/REQUIREMENT.md +2 -1
- package/claude/skills/role-planner/SKILL.md +13 -2
- package/claude/skills/role-reviewer/SKILL.md +1 -1
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +9 -1
- package/claude/skills/session-map/SKILL.md +1 -1
- package/claude/skills/session-resume/REQUIREMENT.md +2 -2
- package/claude/skills/session-worktree/SKILL.md +5 -5
- package/claude/skills/target-setup/SKILL.md +10 -4
- package/claude/skills/target-setup/references/detect.md +20 -3
- package/claude/skills/task-board/REQUIREMENT.md +7 -12
- package/claude/skills/task-board/SKILL.md +5 -17
- package/claude/skills/task-board/references/tasks.md +2 -2
- package/claude/skills/task-complete/REQUIREMENT.md +47 -0
- package/claude/skills/task-complete/SKILL.md +86 -0
- package/claude/skills/{task-board → task-complete}/references/archive.md +4 -4
- package/claude/skills/{context-fold → task-complete}/references/receipt-sweep.md +5 -5
- package/claude/skills/task-complete/references/unusable-baseline.md +19 -0
- package/claude/skills/teach-workspace/REQUIREMENT.md +6 -2
- package/claude/skills/teach-workspace/SKILL.md +8 -4
- package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
- package/claude/skills/{context-fold/references/promoted-pages.md → teach-workspace/references/promotion-fold.md} +3 -3
- package/claude/skills/teach-workspace/references/promotion.md +3 -3
- package/claude/skills/test-craft/REQUIREMENT.md +2 -3
- package/claude/skills/test-craft/SKILL.md +15 -3
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +1 -1
- package/claude/skills/ux-measure/SKILL.md +1 -1
- package/docs/agents/canvas.md +6 -2
- package/docs/agents/commands.md +4 -3
- package/docs/agents/context-audit-checks.md +4 -4
- package/docs/agents/gov-detect.md +47 -0
- package/docs/agents/index.md +7 -4
- package/docs/agents/indexes.md +1 -1
- package/docs/agents/install-and-sync.md +10 -11
- package/docs/agents/key-changes.md +5 -5
- package/docs/agents/label-coverage.md +11 -0
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/pr-evidence-layout.md +70 -0
- package/docs/agents/pr-evidence.md +8 -9
- package/docs/agents/pr-frames.md +7 -2
- package/docs/agents/pr-lift.md +132 -0
- package/docs/agents/records-push.md +2 -2
- package/docs/agents/records-stale.md +12 -47
- package/docs/agents/records-validate.md +3 -7
- package/docs/agents/records.md +5 -27
- package/docs/agents/rule-citations.md +1 -1
- package/docs/agents/sandbox.md +4 -4
- package/docs/agents/scripting.md +2 -1
- package/docs/agents/skills-audit.md +1 -1
- package/docs/agents/tasks-plans.md +2 -2
- package/docs/agents/tasks.md +2 -2
- package/docs/target/migrations.md +10 -2
- package/docs/target/projects.md +4 -4
- package/docs/target/sync.md +1 -1
- package/docs/workflow/operating-model.md +2 -2
- package/docs/workflow/parallel-features.md +7 -7
- package/docs/workflow/skill-map-on-request.md +9 -9
- package/docs/workflow/skill-map.md +12 -11
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/governance/detect.toml +201 -0
- package/governance/renames.toml +0 -11
- package/governance/rules/canon/context.md +13 -0
- package/governance/rules/claude/skill.md +17 -0
- package/governance/rules/code/000-code.md +1 -13
- package/governance/rules/code/010-testing.md +2 -30
- package/governance/rules/ui/400-ui.md +1 -1
- package/governance/rules/ui/480-canvas.md +13 -0
- package/governance/stacks/base.toml +2 -4
- package/package.json +4 -4
- package/scripts/core/install-check.sh +3 -3
- package/scripts/core/regen-hero.ts +0 -6
- package/scripts/lib/ui.sh +0 -168
- package/src/audits/catalog.ts +0 -1
- package/src/canvas/arrange.ts +66 -0
- package/src/canvas/capture.ts +20 -6
- package/src/canvas/content.ts +39 -0
- package/src/canvas/fit.ts +238 -0
- package/src/canvas/tokens.ts +28 -10
- package/src/capture/frame-values.ts +2 -32
- package/src/claude/cases/misc.ts +1 -1
- package/src/claude/cases/setup.ts +4 -0
- package/src/claude/cases/workflow.ts +6 -1
- package/src/claude/seeds.ts +1 -1
- package/src/claude/skills-audit.ts +2 -2
- package/src/cli/help.ts +3 -1
- package/src/cli/ui.ts +2 -3
- package/src/commands/canvas.ts +179 -1
- package/src/commands/claude.ts +1 -1
- package/src/commands/gov.ts +146 -16
- package/src/commands/labels.ts +326 -7
- package/src/commands/migrate.ts +6 -1
- package/src/commands/pr.ts +377 -2
- package/src/commands/records.ts +13 -399
- package/src/commands/sandbox.ts +3 -6
- package/src/commands/tasks.ts +3 -3
- package/src/context/audit.ts +5 -5
- package/src/context/folders.ts +1 -1
- package/src/design/budget.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/regen.ts +1 -1
- package/src/design/render.ts +1 -1
- package/src/feedback/body.ts +26 -5
- package/src/gate/measures.ts +59 -45
- package/src/gate/sequencer.ts +56 -1
- package/src/gate/stages.ts +4 -11
- package/src/gov/detect.ts +301 -0
- package/src/gov/install.ts +2 -3
- package/src/gov/list.ts +23 -2
- package/src/gov/stacks.ts +10 -1
- package/src/hooks/post-merge.ts +1 -1
- package/src/labels/apply.ts +39 -0
- package/src/labels/format.ts +3 -3
- package/src/labels/phase.ts +3 -3
- package/src/labels/sections.ts +43 -0
- package/src/migrate/skill-names.ts +20 -1
- package/src/pr/evidence.ts +218 -45
- package/src/pr/frames.ts +23 -3
- package/src/pr/lift.ts +418 -0
- package/src/pr/paths.ts +4 -4
- package/src/pr/rest.ts +3 -0
- package/src/pr/review-scope.ts +76 -0
- package/src/records/backup.ts +16 -6
- package/src/records/stale-canonical.ts +31 -1
- package/src/records/validate.ts +2 -188
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/coverage.ts +2 -6
- package/src/sandbox/equivalence.ts +19 -51
- package/src/sandbox/expect.ts +4 -4
- package/src/sandbox/provision.ts +13 -36
- package/src/sandbox/scenario.ts +26 -48
- package/src/sandbox/tree.ts +2 -6
- package/src/standards/read.ts +14 -1
- package/src/sync/git.ts +1 -1
- package/src/tasks/archive.ts +5 -5
- package/src/tasks/branch.ts +3 -3
- package/src/tasks/label.ts +1 -1
- package/src/tasks/record.ts +2 -2
- package/src/tasks/validate.ts +1 -1
- package/standards/index.md +0 -13
- package/standards/standard.md +1 -7
- package/tooling/base/reference.md +1 -1
- package/tooling/base/seeds/.github/pull_request_template.md +2 -2
- package/tooling/claude/reference.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +9 -1
- package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +171 -0
- package/tooling/claude/seeds/.claude/settings.json +9 -0
- package/governance/rules/standards/context.md +0 -14
- package/governance/rules/standards/design.md +0 -12
- package/governance/rules/standards/readme.md +0 -12
- package/governance/rules/standards/rule.md +0 -13
- package/governance/rules/standards/skill.md +0 -21
- package/governance/rules/standards/standard.md +0 -13
- package/scripts/config.sh +0 -11
- package/scripts/lib/gov.sh +0 -14
- package/scripts/lib/sandbox-fixtures.sh +0 -191
- package/scripts/lib/sandbox-git.sh +0 -125
- package/scripts/lib/sandbox-path.sh +0 -50
- package/scripts/sandbox-hook.sh +0 -99
- package/src/gov/standard-rules.ts +0 -179
- package/src/records/migrate.ts +0 -78
- package/src/records/stale.ts +0 -243
- package/src/sandbox/hooks.ts +0 -128
- /package/{standards → claude/skills/draft-figure/references}/figures.md +0 -0
- /package/{standards → claude/skills/git-branch/references}/slug.md +0 -0
- /package/{standards → claude/skills/git-commit/references}/commit.md +0 -0
- /package/{standards → claude/skills/git-commit/references}/versioning.md +0 -0
|
@@ -5,11 +5,10 @@ description: Validating the session records and the standards corpus, the per-ki
|
|
|
5
5
|
|
|
6
6
|
# Records validate
|
|
7
7
|
|
|
8
|
-
`canon records validate <kind>` reports where a file and the standard governing it disagree.
|
|
8
|
+
`canon records validate <kind>` reports where a file and the standard governing it disagree. Four kinds are gitignored folders under the record root, resolved at `.canon/` first: `plans`, `groundwork`, `intake`, and `teach`. The fifth is `standards`, the authoring corpus, which is tracked and installed rather than scratch.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
canon records validate plans
|
|
12
|
-
canon records validate memory
|
|
13
12
|
canon records validate standards
|
|
14
13
|
canon records validate intake --json
|
|
15
14
|
```
|
|
@@ -23,7 +22,7 @@ It reads and never writes, and the reason splits by kind. A session record is pe
|
|
|
23
22
|
|
|
24
23
|
`standards` reads the authoring root at `standards/` where it exists and a copy at `.claude/standards/` otherwise. The authoring root wins because it is the only tree anyone authors in and the only one the resolver answers from, so a finding fixed anywhere else is fixed where nothing reads it. No repository generates the second candidate any more, which leaves it as a floor under a target holding a copy an older toolkit installed. The walk stays flat, matching the catalog.
|
|
25
24
|
|
|
26
|
-
Nothing fires it automatically. The
|
|
25
|
+
Nothing fires it automatically. The four record folders are gitignored, so the standards-audit hook exits early on them and any check reading changed files from git never lists one. The corpus is tracked and still unreached, since the markdown audit reads content across the files git lists and rules on no filename. The verb runs at the moment a session claims the record is finished, which is the same placement `canon tasks validate` takes over the board.
|
|
27
26
|
|
|
28
27
|
The two record roots every kind resolves at are in `records.md`.
|
|
29
28
|
|
|
@@ -34,15 +33,12 @@ The two record roots every kind resolves at are in `records.md`.
|
|
|
34
33
|
| `plans` | A filename that is not `feature-<slug>.md`, a missing `# Feature:` heading, a missing required section, a files-to-touch entry naming no file or saying nothing about one, a question carrying no suggestion or no answer slot, and a batch still staged with a `**Batch N**` sub-heading inside the one file rather than split into its own plan |
|
|
35
34
|
| `groundwork` | A track with no `README.md` or no `01-current-state.md`, a file missing `title` or `description`, a `README.md` with no `date` as `YYYY-MM-DD`, an unnumbered file, and a track holding a decision without its handoff or the reverse |
|
|
36
35
|
| `intake` | A dump with no `00-overview.md`, the same frontmatter and numbering checks, an item missing any of `Problem`, `Fix`, `Worth it`, or `You`, and an item carrying `Open` with no `Suggested` |
|
|
37
|
-
| `memory` | A filename whose prefix names none of the four types, an entry missing `title`, `description`, or `category`, a `category` disagreeing with that prefix, a title repeating the filename, and a rule-bearing body missing a part |
|
|
38
36
|
| `standards` | A standard missing `title` or `description`, an absent `## Scope` section, a scope section carrying no `Does not govern:` list, a statement anchoring nothing, and a filename naming no part of the path the statement governs |
|
|
39
37
|
| `teach` | A workspace folder carrying no two-digit ordinal, an absent `MISSION.md`, `RESOURCES.md`, or `GLOSSARY.md`, a file missing `title` or `description`, a mission with no `date` as `YYYY-MM-DD` or no `## Success looks like` section, an unnumbered learning record, and a reference page opening with an ordinal |
|
|
40
38
|
|
|
41
39
|
The half-closed track is the groundwork check a reader cannot run by eye. A folder holding `06` without `07` reads as closed to anyone scanning filenames while the file a returning session actually opens is absent.
|
|
42
40
|
|
|
43
|
-
The item check skips `00-overview.md` and `99-next-session.md`, since neither holds items and running it over the handoff would report every heading it carries.
|
|
44
|
-
|
|
45
|
-
A memory `category` is compared against the sentence-case form of the filename prefix rather than checked field by field, so one finding covers a prefix outside the four types, a field disagreeing with the prefix, and a casing drift that would open a second group in the catalog. The body check runs on `feedback` and `project` entries alone, because a `user` or `reference` entry is a single sentence by design and has no rule to apply.
|
|
41
|
+
The item check skips `00-overview.md` and `99-next-session.md`, since neither holds items and running it over the handoff would report every heading it carries.
|
|
46
42
|
|
|
47
43
|
The standards filename check derives a word from the governed path rather than counting words in the name. Every member of the corpus is named for the artifact its scope statement governs, and one word is what that produces rather than the rule itself, so a check keyed on word count would pass a conforming single word naming the wrong artifact. Each path segment offers its own word, a dotted container segment offers none, a hyphenated segment offers its parts, and the singular and the plural both match.
|
|
48
44
|
|
package/docs/agents/records.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Records
|
|
3
|
-
description: The two roots a record folder resolves at,
|
|
3
|
+
description: The two roots a record folder resolves at, claiming the ordinal intake and groundwork share, reading each folder's size and growth, pruning stale scratch, and where validation, the canonical review count, and the private-remote backup are described
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Records
|
|
@@ -19,28 +19,6 @@ A refusal names every root it looked at, so a message reading `no-folder` says w
|
|
|
19
19
|
|
|
20
20
|
`canon records validate <kind>` reports where a record folder or the standards corpus disagrees with the standard governing it. Its flags, the per-kind checks, and the refusals are in `records-validate.md`.
|
|
21
21
|
|
|
22
|
-
## Migrate
|
|
23
|
-
|
|
24
|
-
`canon records migrate <kind>` rewrites the records a `validate` finding names a transform for. A standard that redefines its own required frontmatter breaks every record already written to the old shape, and this is the repair `validate` could only report until now.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
canon records migrate memory
|
|
28
|
-
canon records migrate memory --write
|
|
29
|
-
canon records migrate memory --json
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
| Option | Behavior |
|
|
33
|
-
| --------------- | ------------------------------------------------------------------- |
|
|
34
|
-
| `--json` | Add a machine-readable record on stdout |
|
|
35
|
-
| `--write` | Rewrite every record a transform can repair |
|
|
36
|
-
| `--root <path>` | Project root, defaulting to the main worktree except on `standards` |
|
|
37
|
-
|
|
38
|
-
It writes nothing until `--write` is passed, matching the write-flag contract `canon tooling sync` carries: a session record has no history to undo a wrong repair from, so naming a kind is not consent to rewrite every record inside it. A dry run reports which records it would touch and exits non-zero either way, headless or not, since there is nothing to prompt for.
|
|
39
|
-
|
|
40
|
-
A transform runs only where the missing value is recoverable from the file itself. The one shipped today repairs a memory record missing `category` alone, deriving it from the same filename prefix `checkMemory` already reads it from. `title` and `description` are prose nobody wrote down, so a finding naming either carries no transform and stays for a session to fix by hand, and `validate` keeps reporting it. The transform re-reads the file rather than trusting a value captured at validate time, so a check and its repair cannot disagree about the same record.
|
|
41
|
-
|
|
42
|
-
Exit codes: `0` nothing carried a known transform, or `--write` repaired everything it found. `1` refused for a reason `validate` shares, every candidate it found failed to repair, or `--write` repaired only some of them. `2` a record carries a known transform and `--write` was not passed.
|
|
43
|
-
|
|
44
22
|
## Ordinal
|
|
45
23
|
|
|
46
24
|
`canon records ordinal <kind> <slug>` reports the next ordinal `intake` and `groundwork` share, or claims it with `--claim`. The two kinds share one sequence, per `claude/skills/plan-intake/references/intake.md` and `claude/skills/plan-groundwork/references/groundwork.md`, so this reads both `.canon/intake/` and `.canon/groundwork/` regardless of which kind was asked for.
|
|
@@ -81,9 +59,9 @@ Ordering by weight is what makes the reading worth taking. A folder listed alpha
|
|
|
81
59
|
|
|
82
60
|
The reading carries two windows rather than one, at 7 and 30 days. A single window cannot separate a folder growing steadily from one that took a single batch: a folder whose 7-day count is most of its 30-day count moved in one pass, and one where the two are proportional is growing at a rate.
|
|
83
61
|
|
|
84
|
-
Nothing fails on a number here. A record folder has no correct size, so the reading is a number to notice rather than a threshold to gate, and the point of the verb is that the next reading is taken by a command instead of by someone remembering to count the folder.
|
|
62
|
+
Nothing fails on a number here. A record folder has no correct size, so the reading is a number to notice rather than a threshold to gate, and the point of the verb is that the next reading is taken by a command instead of by someone remembering to count the folder. A pen went from 44 entries to 236 between two readings taken by hand two weeks apart, which is the measurement this replaces.
|
|
85
63
|
|
|
86
|
-
The scratch folder is read here and skipped by a backup, because deletable without loss is not the same as empty. The routing handoffs and
|
|
64
|
+
The scratch folder is read here and skipped by a backup, because deletable without loss is not the same as empty. The routing handoffs and a retired entry archive both sit there and both accumulate. `.canon/.records.git` stays out because it is the backup history rather than a record, and `.claude/worktrees/` stays out because each entry is a checkout of the project with its own removal verb, and one of them outweighs every record folder combined.
|
|
87
65
|
|
|
88
66
|
The window counts read `mtime`, so what they report is a file written inside the window rather than one created there. An entry edited long after it landed reads as recent, which overstates growth and never understates it, and these folders are append-mostly so the two readings agree on nearly every file. The one reading that is wrong rather than early is a machine restored by `canon records pull`, which resets the work tree hard and re-dates every file it writes, so a window taken there counts the restore. Nothing on the filesystem separates the two, since a restored file is new by every stamp it carries.
|
|
89
67
|
|
|
@@ -112,13 +90,13 @@ A candidate is a unit whose newest file is older than the threshold: a `tmp/<slu
|
|
|
112
90
|
|
|
113
91
|
A scratch-root name `canon migrate record-layout` or `canon migrate scratch-evidence` moves out of scratch for good, such as `memory-archive`, is skipped the same way on a project that has not yet run that migration, naming the verb to run. The retired-entry archive `memory-archive` holds is never deleted, per the memory standard, so it stays skipped rather than aging into an offer.
|
|
114
92
|
|
|
115
|
-
It writes nothing until `--write` is passed,
|
|
93
|
+
It writes nothing until `--write` is passed, since a session record has no history to undo a wrong delete from. It reads `mtime` the way `canon records size` does, so a machine restored by `canon records pull` reads its whole tree as new and fails safe by offering nothing.
|
|
116
94
|
|
|
117
95
|
Exit codes: `0` nothing to prune, or `--write` deleted every candidate. `1` refused, sharing `no-folder` with `size`, or a delete failed. `2` candidates exist and `--write` was not passed.
|
|
118
96
|
|
|
119
97
|
## Stale
|
|
120
98
|
|
|
121
|
-
`canon records stale
|
|
99
|
+
`canon records stale canonical` reports when the requirements record was last reviewed and how many releases have shipped since. How the release count is taken and the refusals are in `records-stale.md`.
|
|
122
100
|
|
|
123
101
|
## Push and pull
|
|
124
102
|
|
|
@@ -49,7 +49,7 @@ A `path` is anchored on the whole backticked span rather than on a trailing patt
|
|
|
49
49
|
A rule body is full of backticked spans carrying a slash, and almost none of them names a file in this tree. The stage declines four shapes outright.
|
|
50
50
|
|
|
51
51
|
- A placeholder or glob segment describes a shape rather than naming a file: `canon/context/<domain>.md`, `standards/<name>.md`, `app/**/route.ts`, `${CLAUDE_SKILL_DIR}/../../standards/<name>.md`.
|
|
52
|
-
- A bare filename names a convention: `route.ts`, `manifest.toml`, `components.json`, `playwright.config.ts`. A bare name is read as a citation only when it matches a rule filename, which is how one authored rule would point at a sibling such as `605-worktrees.md`.
|
|
52
|
+
- A bare filename names a convention: `route.ts`, `manifest.toml`, `components.json`, `playwright.config.ts`. A bare name is read as a citation only when it matches a rule filename, which is how one authored rule would point at a sibling such as `605-worktrees.md`.
|
|
53
53
|
- A span carrying no file extension is a folder or a module specifier: `src/pages/`, `next/font`, `try/except`, `react-hooks/set-state-in-effect`, `oven-sh/setup-bun@v2`, `@/lib/utils`.
|
|
54
54
|
- A fenced block displays a path rather than pointing at one.
|
|
55
55
|
|
package/docs/agents/sandbox.md
CHANGED
|
@@ -9,7 +9,7 @@ description: Scenario routing, the expectation scoring surface, and the coverage
|
|
|
9
9
|
|
|
10
10
|
## Scenarios
|
|
11
11
|
|
|
12
|
-
Scenarios live under `sandbox/`, one folder per category and one file per command,
|
|
12
|
+
Scenarios live under `sandbox/`, one folder per category and one file per command, each a TypeScript module. `sandbox/fixtures/` is the exception, holding file content that scenarios stage rather than scenarios of its own, so the picker and the coverage report both filter it out. That tree sits outside `files` in `package.json`, so an installed `canon` carries the command, reports it as toolkit-only on one line, and exits 1 rather than failing on the missing directory. Route non-interactively with `SANDBOX_SCENARIO`:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
SANDBOX_SCENARIO=sync canon sandbox infra:tooling
|
|
@@ -47,7 +47,7 @@ Exit 0 means `pass` or `unchecked`. Exit 1 means `fail`, or a caller error: a ma
|
|
|
47
47
|
|
|
48
48
|
## Headless runs
|
|
49
49
|
|
|
50
|
-
`canon sandbox run` provisions a scenario, drives one `claude -p` session over it, and scores the result with `canon sandbox check`.
|
|
50
|
+
`canon sandbox run` provisions a scenario, drives one `claude -p` session over it, and scores the result with `canon sandbox check`.
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
canon sandbox run <category>:<command> "<prompt>" [arm]
|
|
@@ -93,7 +93,7 @@ The baseline is a detached worktree with full history, removed on exit including
|
|
|
93
93
|
|
|
94
94
|
The record lists per arm `identical`, `differs` with the manifest keys that differ, `red-on-base` when both sides fail the same way, or `skipped-anchor`. It also carries `canonVersion`, `baseCommit`, `masksApplied`, `errors`, and `counts`. A declared arm adds a `check` entry from `canon sandbox check` on the head tree, whose `asserted` count shows its `expect.toml` resolved from `sandbox/fixtures/`.
|
|
95
95
|
|
|
96
|
-
Exit 0 means every compared arm is identical or red the same way on both sides. Exit 1 means any `differs`, a base and head exit that disagree, an armed arm that `canon sandbox coverage` lists and enumeration lacks,
|
|
96
|
+
Exit 0 means every compared arm is identical or red the same way on both sides. Exit 1 means any `differs`, a base and head exit that disagree, an armed arm that `canon sandbox coverage` lists and enumeration lacks, or a `.ts` scenario that fails to load.
|
|
97
97
|
|
|
98
98
|
## Scenario coverage
|
|
99
99
|
|
|
@@ -115,7 +115,7 @@ The record carries every scenario with the arms that declare, plus `totalScenari
|
|
|
115
115
|
|
|
116
116
|
`--skills` answers what the scenario count cannot, which is whether anything can fail a given skill. It adds `skills`, `totalSkills`, `asserted`, `shouldBeAsserted`, `exempt`, `staleExemptions`, and `supersededExemptions` to the record, and keeps the scenario view rather than replacing it. The two denominators disagree on purpose: an armed scenario under `infra/` or `tooling/` exercises a CLI domain and pairs with no skill at all.
|
|
117
117
|
|
|
118
|
-
A skill pairs to a scenario by filename, `<category>-<command>` first and bare `<command>` second, so `claude/target-setup.
|
|
118
|
+
A skill pairs to a scenario by filename, `<category>-<command>` first and bare `<command>` second, so `claude/target-setup.ts` reaches the `target-setup` skill. `should-be-asserted` is the default rather than a queue to drain, and which of those skills earns an arm is a project decision the census does not make.
|
|
119
119
|
|
|
120
120
|
`exempt` means no arm should be written and holds only with a reason, declared in `sandbox/exempt.toml` and limited to a harness limit the checker cannot reach past or a skill that writes no artifact. An armed arm outranks an exemption. An exemption naming no shipped skill, or naming one an arm now asserts, exits 1 without `--strict`. Each armed arm reports as `<category>:<command>/<arm>`, so two same-named arms under different scenarios stay distinct.
|
|
121
121
|
|
package/docs/agents/scripting.md
CHANGED
|
@@ -15,7 +15,8 @@ Use these to discover what's available instead of hardcoding names.
|
|
|
15
15
|
| --------------------------------- | ---------------------------------------------------------------- |
|
|
16
16
|
| `canon tooling list --json` | Stacks, extends chain, dep and script counts |
|
|
17
17
|
| `canon standards list --json` | Standards docs and the paths each governs |
|
|
18
|
-
| `canon gov list --json` | Governance stacks, rule sets, and unreferenced rules
|
|
18
|
+
| `canon gov list --json` | Governance stacks, rule sets, evidence, and unreferenced rules |
|
|
19
|
+
| `canon gov detect --json` | Opt-in rules a target's dependencies and paths propose |
|
|
19
20
|
| `canon claude seeds list --json` | Seed doc sources with content |
|
|
20
21
|
| `canon claude skills list --json` | Plugin skills, descriptions, requirement flag, family vocabulary |
|
|
21
22
|
| `canon docs list --json` | Consumer docs plus per-domain context |
|
|
@@ -5,7 +5,7 @@ description: Measuring both skill corpora against the skill standards, the check
|
|
|
5
5
|
|
|
6
6
|
# Skill audit
|
|
7
7
|
|
|
8
|
-
`canon claude skills audit [path]` reports both skill corpora against the rules `
|
|
8
|
+
`canon claude skills audit [path]` reports both skill corpora against the rules `claude/skills/create-skill/references/skill.md`, `claude/skills/create-skill/references/skill-requirement.md`, and `claude/skills/create-skill/references/skill-practice.md` state mechanically. It reads and reports. Fixing what it finds is separate work.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
canon claude skills audit
|
|
@@ -83,7 +83,7 @@ The record carries `type`, `slug`, `branch`, `words`, and `conforms`. Exit codes
|
|
|
83
83
|
|
|
84
84
|
`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.
|
|
85
85
|
|
|
86
|
-
`conforms` reads both caps `
|
|
86
|
+
`conforms` reads both caps `claude/skills/git-branch/references/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.
|
|
87
87
|
|
|
88
88
|
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.
|
|
89
89
|
|
|
@@ -118,7 +118,7 @@ It reads only what is written down, so it inherits the dispatch runbook's blindn
|
|
|
118
118
|
|
|
119
119
|
A claim is only as current as the folder it was read from, and the live folder holds a plan whose work already shipped until something archives it. `canon tasks archive` moves a plan on merge, so a plan stranded by a run that never reached the archive keeps claiming its files against every branch afterwards. Check whether the holder is actually in flight before treating a claim as a collision: the first run of this verb on its own branch reported five paths held by a plan whose verb had already merged, and the whole reading came of a file nobody archived. `canon tasks validate` is what reports the stranded plan itself.
|
|
120
120
|
|
|
121
|
-
`canon:git-ship` runs it at step
|
|
121
|
+
`canon:git-ship` runs it at step 5, after `git add -A` and before the commit grouping. That is the first point the branch is whole and the last before a pull request exists to carry the answer.
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
124
|
canon tasks plan-reach dispatch-answer-gate --json | jq -r '.claimed[] | "\(.path) held by \([.holders[].name] | join(", "))"'
|
package/docs/agents/tasks.md
CHANGED
|
@@ -27,7 +27,7 @@ Exit codes: `0` derived, `1` refused with `no-board`, `2` refused with `label-co
|
|
|
27
27
|
|
|
28
28
|
The minor digit rolls from 9 to 0 on the next major rather than growing a second digit, which is the single-digit-minor shape every phase label already takes. `canon tasks archive` moves a task's file from the live folder into the archive without renumbering it, so the same label counts toward the maximum wherever it currently sits, and a label claimed by two different files folds into the same scan without a dedicated check.
|
|
29
29
|
|
|
30
|
-
A claim is an exclusive `mkdir` at `.canon/ordinal-locks/<label>`, and the scan counts every reservation beside the task files, since the file lands after the verb returns. Reservations never expire, so a claim that died leaves a gap, which `
|
|
30
|
+
A claim is an exclusive `mkdir` at `.canon/ordinal-locks/<label>`, and the scan counts every reservation beside the task files, since the file lands after the verb returns. Reservations never expire, so a claim that died leaves a gap, which `claude/skills/git-commit/references/versioning.md` permits. A bare read still reports without reserving, and it does not count reservations either, so it can return a label a claim already holds until that claim's task file lands. Two bare reads in the same second can also take the same answer.
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
canon tasks next-label --json | jq -r '.label'
|
|
@@ -60,7 +60,7 @@ canon tasks pull-request 673 --plan worktree-scratch-routing --json
|
|
|
60
60
|
|
|
61
61
|
A plan is matched on the token both spellings share, so `worktree-scratch-routing`, `feature-worktree-scratch-routing`, and `.canon/plans/feature-worktree-scratch-routing.md` all select the same task. The `action` field reports `added`, `appended`, `corrected`, or `unchanged`, which makes a rerun against the same number safe.
|
|
62
62
|
|
|
63
|
-
Run from a branch other than `main` or `master`, the verb also drops that branch from the task's `Pending branch:` line, along with every name its reflog says it was renamed from, and removes the line once it is empty. The renamed names matter because `git-ship` renames a nonconforming branch after `
|
|
63
|
+
Run from a branch other than `main` or `master`, the verb also drops that branch from the task's `Pending branch:` line, along with every name its reflog says it was renamed from, and removes the line once it is empty. The renamed names matter because `git-ship` renames a nonconforming branch after `task-complete` wrote the marker. It does so on an `unchanged` run too, so a rerun repairs a marker left behind. The `pending` field lists the branches still on the line after the write.
|
|
64
64
|
|
|
65
65
|
Exit codes: `0` recorded, `1` refused. The `reason` field carries `no-board`, `no-match`, or `ambiguous`. `git-pr` skips silently on those three, because each is a case where a guessed write would archive the wrong task once the branch merges.
|
|
66
66
|
|
|
@@ -64,9 +64,11 @@ Twenty-five plugin skills dropped their `claude-` prefix for two-word names, so
|
|
|
64
64
|
|
|
65
65
|
The same sweep carries the merge of the five per-kind document drafters into `draft-doc`, so a citation of any one of them lands on `canon:draft-doc`.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
The one skill that took a two-word name from a single word is `canvas`, now `canvas-board`. A bare `canvas` is ordinary prose and the name of a verb, so the sweep rewrites only the forms the skill alone spells, `canon:canvas` and `skills/canvas`. A prose mention of the skill by its bare name stays, so replace it by hand. <!-- canon-keep-retired -->
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
Fourteen skills, one verb, and one rule were retired without a rename, so the sweep has nothing to map them to and leaves a citation of one as it stands. `design-extract` and `sketch-design` are replaced by `canon:canvas-board`, which carries a picked direction into `canon/DESIGN.md`. `review-branch`, `seed-sync`, `restate-plainly`, `bash-cli-script`, `canon-operator`, `canon-rollout`, `create-standard`, `markdown-propose`, `memory-review`, `project-commands`, `repo-metadata`, and `ux-walkthrough` have no successor. `canon repo metadata` went with `repo-metadata`, and `canon autoship` went with `review-branch`, whose review step it served. The `120-bash` rule left the `base` stack, so `canon gov sync` removes its installed copy. Replace each citation by hand, or delete the sentence naming a skill that has no successor. <!-- canon-keep-retired -->
|
|
70
|
+
|
|
71
|
+
The memory system retired the same way. `memory-capture`, the `603-memory` rule, and the `memory` standard have no successor, and a citation of any one is replaced by hand or deleted. Ship chains no longer capture a session's lessons, so a lesson goes to the context entry that owns the fact, or to a task's findings. The `memory` record kind left `canon records` with it, and so did `canon records migrate`, whose one transform repaired a memory record. `canon records validate memory` and `canon records stale memory` now refuse as an unknown kind, and `canon records migrate` is an unknown command. A target that upgrades the CLI while a pre-retirement plugin still runs `memory-review` gets that refusal, which is the intended outcome. A `.canon/memory/` folder a target holds is still backed up by `canon records push`. <!-- canon-keep-retired -->
|
|
70
72
|
|
|
71
73
|
An installed target keeps its `.canon/memory/` folder and the memory arms of its seeded `records-index.sh` and `standards-audit.sh` hooks, since `canon claude sync` writes only a seed a target lacks. Both are inert: nothing writes the folder, and the hooks match no file. `canon gov sync` removes the installed `603-memory` rule and the generated `memory` standard rule.
|
|
72
74
|
|
|
@@ -85,6 +87,12 @@ Run the second line once per stack the project holds, since the two hooks above
|
|
|
85
87
|
|
|
86
88
|
The order carries the reason. A sync replaces each toolkit-owned copy with one already carrying the new names, and the sweep afterwards reaches the prose the project wrote itself. Sweeping first rewrites those installed files in place, which moves them off the hash the install recorded, so the next sync reads them as edited by the project and leaves them alone.
|
|
87
89
|
|
|
90
|
+
## Rename the pull request template headings, once
|
|
91
|
+
|
|
92
|
+
The pull request section headings moved to sentence case, so the template seeds `## Key changes` and `## Technical context`. `canon labels scan` now fails a body whose level-two heading is outside the closed list, and it compares case exactly, so a body written under the old `## Key Changes` heading fails the pull request gate.
|
|
93
|
+
|
|
94
|
+
A project scaffolded earlier holds the old template at `.github/pull_request_template.md`, and a sync writes only a seed a target lacks. Rename the two headings in that file by hand, or delete it and run `canon tooling sync base . --write` to take the new seed. Do it ahead of the first pull request after `canon upgrade`. `canon pr key-changes` reads either casing, so a body already open keeps parsing, and only the scan needs the rename on its next edit.
|
|
95
|
+
|
|
88
96
|
## Move the surfaces off `.claude/`, once
|
|
89
97
|
|
|
90
98
|
Tracked surfaces moved out of `.claude/` and into a root of their own. `context/`, `wireframes/`, the three loose documents (`ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`), and the install stamp folder, respelled `canon/config/`, now live under `canon/`, and `rules/`, `skills/`, `hooks/`, and `settings.json` stay put since Claude Code reads those by path.
|
package/docs/target/projects.md
CHANGED
|
@@ -51,7 +51,7 @@ claude --plugin-dir <toolkit>/claude
|
|
|
51
51
|
Two steps, in order:
|
|
52
52
|
|
|
53
53
|
1. Run the framework's own scaffold if the project needs one, such as `bun init`, `npm create vite`, or `npm create astro`. The toolkit does not wrap framework scaffolding.
|
|
54
|
-
2. Invoke `canon:target-setup` in Claude Code. The skill detects the stack,
|
|
54
|
+
2. Invoke `canon:target-setup` in Claude Code. The skill detects the stack, asks `canon gov detect` which opt-in rules the project's evidence proposes, previews the full chain with those proposals for you to confirm, and runs it end-to-end.
|
|
55
55
|
|
|
56
56
|
The chain is:
|
|
57
57
|
|
|
@@ -72,7 +72,7 @@ Keep the `## Scripts` table in `canon/context/development.md` current as scripts
|
|
|
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 `canon/REQUIREMENTS.md`. The seed asks for the problem in one line, then goals and non-goals, and the scope is yours to write. The seed states its own cap of 600 words, and `canon context audit` gates on it. Edit the number in the record to loosen it. A decision about how the project is built goes in the `canon/context/` entry of the domain it constrains.
|
|
75
|
-
2. For a UI project, write `canon/DESIGN.md` from the seed template, or work the direction out with `canon:canvas` and carry the pick in. Skip for non-UI projects.
|
|
75
|
+
2. For a UI project, write `canon/DESIGN.md` from the seed template, or work the direction out with `canon:canvas-board` and carry the pick in. Skip for non-UI projects.
|
|
76
76
|
3. Optionally invoke `canon:draft-figure` naming an architecture view, such as system context or components, and the document it belongs in. It draws the view from the context index, the folder layout, and the requirements and renders it 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
|
|
|
@@ -88,7 +88,7 @@ Escalate only for real web apps. The `target-setup` skill reads `package.json` a
|
|
|
88
88
|
|
|
89
89
|
In a monorepo the skill reads each folder holding a `package.json`, `pyproject.toml`, `go.mod`, `composer.json`, or `Cargo.toml` to depth two, skipping what git ignores. Each of those folders gets its own tooling stack and a `canon tooling sync <stack> <folder> --skip base` in the preview. Governance still installs once at the root, since a rule's `paths:` globs reach every subfolder, so a subfolder's language rules join the root install through `--add`.
|
|
90
90
|
|
|
91
|
-
`node-server` is named rather than detected. It carries the server-side security and persistence rules for a project writing request handlers or a persistence layer in TypeScript, and the detect step matches a runtime or a framework against stack names, so
|
|
91
|
+
`node-server` is named rather than detected. It carries the server-side security and persistence rules for a project writing request handlers or a persistence layer in TypeScript, and the detect step matches a runtime or a framework against stack names, so the stack never resolves on its own. `canon gov detect` proposes its two rules from a server framework or database client in the manifest, which you confirm in the preview. Pass the stack deliberately with `canon init --stack node-server` or `canon gov install node-server <target>`.
|
|
92
92
|
|
|
93
93
|
Markdown-heavy projects, CLI tools, docs sites, research notebooks, and scripting repos stay on `base`. Escalation is a ceiling move, not a default.
|
|
94
94
|
|
|
@@ -113,7 +113,7 @@ The plugin corpus carries runtime behavior rather than reference prose alone, be
|
|
|
113
113
|
|
|
114
114
|
When a new need appears after scaffold, install the one domain without re-running `canon init`.
|
|
115
115
|
|
|
116
|
-
- Governance rule for a newly adopted library:
|
|
116
|
+
- Governance rule for a newly adopted library: run `canon gov detect <path> --json` to see what the project's evidence proposes, then `canon gov install --add <rule> <path>`, which installs the rule with no stack
|
|
117
117
|
- Project-specific rule the toolkit does not ship: invoke `canon:create-rule`. It scaffolds a rule into `.claude/rules/project/` with a non-colliding number, and `canon gov sync` leaves it untouched. A rule placed under `.claude/rules/canon/` instead is deleted on the next sync, since that folder belongs to the toolkit.
|
|
118
118
|
- Index.md system for a markdown-heavy folder that emerged: invoke `canon:target-setup indexes`
|
|
119
119
|
|
package/docs/target/sync.md
CHANGED
|
@@ -78,7 +78,7 @@ Standards take no part in that run. Nothing installed them, so there is no copy
|
|
|
78
78
|
|
|
79
79
|
- Claude seed docs such as `CLAUDE.md` and `canon/REQUIREMENTS.md`: merge by hand against the toolkit copy, section by section, keeping the project's customizations. A `stale` seed is safe to take whole.
|
|
80
80
|
- 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.
|
|
81
|
-
- Tooling configs and seeds: `canon tooling <stack> <path>` overwrites golden configs and merges seeds
|
|
81
|
+
- Tooling configs and seeds: `canon tooling <stack> <path>` overwrites golden configs and merges dictionary seeds, and drops every other seed once
|
|
82
82
|
- Reference docs for a stack: `canon tooling reference <stack>` reads and never writes, so there is nothing to sync
|
|
83
83
|
- Index regeneration after markdown edits: `canon indexes regen`
|
|
84
84
|
|
|
@@ -97,10 +97,10 @@ The human read at merge is the final gate. No layer repeats another.
|
|
|
97
97
|
The orchestrator's pass also reads the pull request body against itself, which is
|
|
98
98
|
a vantage the worker never has. This repository squash-merges, so the body
|
|
99
99
|
becomes the commit message and the record on the trunk once the branch is gone.
|
|
100
|
-
`canon pr key-changes` compares the paths the body's Key
|
|
100
|
+
`canon pr key-changes` compares the paths the body's Key changes claims against
|
|
101
101
|
its own changed-file list, and a claim the diff does not carry is a finding on
|
|
102
102
|
the body rather than on a file. See
|
|
103
|
-
[Key
|
|
103
|
+
[Key changes bijection](../agents/key-changes.md).
|
|
104
104
|
|
|
105
105
|
## The review channel
|
|
106
106
|
|
|
@@ -38,23 +38,23 @@ The plan's shape is fixed by `claude/skills/plan-feature/references/plan.md`: th
|
|
|
38
38
|
|
|
39
39
|
An execution that picks other than the suggestion rewrites the `- Suggested:` line as `overridden at execution to <pick>,` followed by the measurement that moved it, and leaves the slot blank. That fixed phrase is how a reader of the archived plan tells an override from a suggestion the execution accepted, since an authored suggestion often carries a number of its own. The same deviation takes one line in the open task's `## Findings`, which is the register that survives the plan being archived. A deviation from a question somebody already answered goes back to whoever answered it instead, since a filled slot is a decision already made.
|
|
40
40
|
|
|
41
|
-
`canon records validate plans` reports where a plan and that standard disagree: a filename that is not `feature-<slug>.md`, a missing required section, a files-to-touch entry naming no file, and a question carrying a suggestion with no answer slot. The same verb takes `groundwork`, `intake`,
|
|
41
|
+
`canon records validate plans` reports where a plan and that standard disagree: a filename that is not `feature-<slug>.md`, a missing required section, a files-to-touch entry naming no file, and a question carrying a suggestion with no answer slot. The same verb takes `groundwork`, `intake`, and `teach`, which are governed the same way and were unreachable for the same reason. Nothing fires it automatically, because all four folders are gitignored and every check the repository runs reads changed files from git. It reports and never writes, since the folders are per-machine scratch with no history to recover a wrong repair from.
|
|
42
42
|
|
|
43
43
|
`canon records push` carries these folders off the disk they live on, and `canon records pull` brings them back. Every top-level entry under `.canon/` is backed except `tmp`, `ordinal-locks`, and `.records.git`, so a folder added later enters the payload on its own rather than waiting on a name written into a list. Push names each folder it carries the first time it sees it, which is what keeps a stray folder visible instead of silently entering the payload. It refuses the whole push, naming each path, when a new or changed file is over 25 MB or carries a credential `canon secrets scan` would report. The history lives in a second git directory at `.canon/.records.git` with `.canon/` as its work tree, so every path a task file cites stays where it is.
|
|
44
44
|
|
|
45
45
|
A person points it at a private repository once and both verbs refuse until they have, and `push` refuses when that origin is also a remote of the project, since the payload is the task board and the groundwork trails. `.husky/post-merge` runs the push after its archive loop, on every merge rather than only on one that closed a task. See [records push](../agents/records-push.md) for the refusal table.
|
|
46
46
|
|
|
47
|
-
`canon records size` reports what each of these folders holds, heaviest first, along with `.canon/tmp`. Each row carries the file count, the bytes, how many files were written in the last 7 and 30 days, and the dates of the least and most recently written one. Nothing fails on a number, because a record folder has no correct size. What the verb replaces is a reading somebody had to remember to take:
|
|
47
|
+
`canon records size` reports what each of these folders holds, heaviest first, along with `.canon/tmp`. Each row carries the file count, the bytes, how many files were written in the last 7 and 30 days, and the dates of the least and most recently written one. Nothing fails on a number, because a record folder has no correct size. What the verb replaces is a reading somebody had to remember to take: a pen went from 44 entries to 236 between two counts made by hand a fortnight apart, and nothing reported the rate in between.
|
|
48
48
|
|
|
49
49
|
`canon records prune-tmp` reports scratch under `.canon/tmp` nobody has touched inside an age window, and deletes it only with `--write`. A `tmp/handoff/` folder and the live `tmp/pr/poll/` baseline are never offered, since a reader deletes a handoff once it is read and a poll baseline is state a session still needs. See [records](../agents/records.md) for the candidate shapes and the exit codes.
|
|
50
50
|
|
|
51
|
-
`canon records stale
|
|
51
|
+
`canon records stale canonical` reports when the requirements record was last reviewed and how many releases have shipped since, so a review of it starts from a count rather than from the tag list. It writes nothing. See [records stale](../agents/records-stale.md) for how the count is taken and the refusals.
|
|
52
52
|
|
|
53
53
|
A plan that ships is archived, never deleted. `canon tasks archive` moves it to `.canon/plans/archive/` alongside the task it belonged to and retargets that task's `Plan:` line at the new location, so a completed task still leads to the reasoning behind it. An archive sits inside the record folder it archives rather than beside it, so one ignore entry and one backed-folder entry cover a record and everything it has retired. The folder is gitignored, which is why a deleted plan had no recovery path. A plan cited by more than one task stays put until the last of them closes, since moving it early would strand every other pointer.
|
|
54
54
|
|
|
55
|
-
An older branch review report takes the other route and is swept rather than archived. It sits flat in `.canon/review/` as `branch-<slug>.md`, the session addressing it read it once, and the durable record of what a review found is the comment `review-pr` posts on the pull request, so `
|
|
55
|
+
An older branch review report takes the other route and is swept rather than archived. It sits flat in `.canon/review/` as `branch-<slug>.md`, the session addressing it read it once, and the durable record of what a review found is the comment `review-pr` posts on the pull request, so `canon:task-complete` deletes any report whose branch is gone. The body that writes a report owns how long it lives, which leaves the shipping branch's own report on disk through the run that cites it and collects it a branch later. What that loses is a local-only review on a branch that never opened a pull request, which is why the report says so where a reader meets it.
|
|
56
56
|
|
|
57
|
-
`canon:
|
|
57
|
+
`canon:task-complete` decides which task closed by reading the diff rather than the conversation, as the ship-chain step after `canon:context-fold`. It resolves a merge base against `origin/main`, unions the committed diff with the working tree and untracked files, then matches unchecked outcomes on the board against what shipped. A task that shipped without ever being discussed still gets marked. Decisions stay session-sourced, because a diff cannot carry a judgment, and `canon:context-fold` folds them into the context entries. The requirements record is never folded. A direction change gets one report line naming `canon:document-health`, which reviews that record only when asked.
|
|
58
58
|
|
|
59
59
|
## Shipping a fan-out
|
|
60
60
|
|
|
@@ -87,12 +87,12 @@ A hand-maintained `priority.md` sits beside the index carrying execution order a
|
|
|
87
87
|
|
|
88
88
|
Past that shape, it checks what a surviving row claims against what the tree holds: every plan pointer resolves, every task file is named by a board row or a backlog line and never by both, no task sits in two groups, and every row marked ready names its files. One check across both surfaces is what lets a task move between the board and the backlog without the move reading as a dropped file. Paths two ready rows share go to a `shared` array moving no exit code, the candidate list the orchestrator's conflict check reads. Blockers re-takes what a parked row waits on, reporting one whose cited task reached the trunk and one whose cited file nothing running still holds. A cited task settles the row by being archived, or by closing every outcome and naming a pull request the trunk carries, since the checkbox alone is marked while the branch is still in review. Both halves read a citation out of the blocker cell, so a row citing neither is reported as untested rather than counted clean, and so is a cited task the trunk could not answer for. It reports and never writes, because a row is the orchestrator's claim and a validator repairing one would assert the claim it exists to test. Nothing fires it automatically, since the board is gitignored per-machine scratch with no shared moment to hang a hook on, so the orchestrator's sweep calls it at the point the readiness claim is made and follows it with the parked re-test.
|
|
89
89
|
|
|
90
|
-
`canon:task-board`
|
|
90
|
+
`canon:task-board` creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and declines a task decided against. `canon:task-complete` marks a shipped task's outcomes and moves one the merge hook left to `.canon/tasks/archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do.
|
|
91
91
|
|
|
92
92
|
Archiving a task carries its plan with it, in the same act. The merge is what settles a plan, and the hook below reaches the archive with nobody watching, so a second call after it would be a second failure point leaving the task archived and the plan live. A task whose plan a sibling still cites archives on its own and leaves the plan live, since moving it on the first task to close strands every other pointer at a path that has gone.
|
|
93
93
|
|
|
94
94
|
Nothing chained that archive until the `post-merge` git hook landed. Every earlier step fires from `canon:auto-ship` or `canon:git-ship`, both of which finish while the pull request is still open, so a task archived there would close for work that may be abandoned. The board is gitignored, which rules out reading it from anywhere but the machine that pulled. The hook archives the task a merged pull request closed, through the same verb the base stack ships to every target, and does nothing on a project with no board.
|
|
95
95
|
|
|
96
|
-
The archive gates on a pull request number the merge carried and a closed task, because outcomes are marked on the branch and a task can read all `[x]` while its pull request is still open, so `canon:task-
|
|
96
|
+
The archive gates on a pull request number the merge carried and a closed task, because outcomes are marked on the branch and a task can read all `[x]` while its pull request is still open, so `canon:task-complete` still confirms the work reached `main` when a person archives by hand. A companion `post-rewrite` hook carries the same steps for anyone pulling with rebase, which fires that event instead of `post-merge`.
|
|
97
97
|
|
|
98
98
|
The hook archives through `canon tasks archive`, which carries the refusals above, so a task whose pull request has not merged stays where it is. Both hooks ship with the `base` tooling stack, so a target project running this workflow gets the same trigger, and `CANON_SKIP_RECLAIM`, `CANON_SKIP_UPGRADE`, and `CANON_SKIP_PLUGIN_UPDATE` turn off the three steps that act on the machine.
|
|
@@ -25,15 +25,15 @@ These two groups hold the skills no single moment in a project's life calls for,
|
|
|
25
25
|
|
|
26
26
|
## Answer a question at any point
|
|
27
27
|
|
|
28
|
-
| Skill | When to use
|
|
29
|
-
| --------------------------- |
|
|
30
|
-
| `canon:canon-cli` |
|
|
31
|
-
| `canon:youtube-transcripts` | When a video transcript is wanted in the repo as context
|
|
32
|
-
| `canon:read-frames` | To read a recorded demo back frame by frame and report what each one shows, with no verdict on whether the recording looks right
|
|
33
|
-
| `canon:teach-workspace` | To learn a subject across sessions, in a workspace that holds the progress
|
|
34
|
-
| `canon:markdown-craft` | Before a substantial markdown edit, for the format and structure rules and the audit that follows
|
|
35
|
-
| `canon:write-human` | Before drafting or revising prose, for voice, rhythm, and density
|
|
28
|
+
| Skill | When to use |
|
|
29
|
+
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| `canon:canon-cli` | To pick the `canon` verb that does a job, or before a sync or migrate, to learn which verbs can lose the project's edits |
|
|
31
|
+
| `canon:youtube-transcripts` | When a video transcript is wanted in the repo as context |
|
|
32
|
+
| `canon:read-frames` | To read a recorded demo back frame by frame and report what each one shows, with no verdict on whether the recording looks right |
|
|
33
|
+
| `canon:teach-workspace` | To learn a subject across sessions, in a workspace that holds the progress |
|
|
34
|
+
| `canon:markdown-craft` | Before a substantial markdown edit, for the format and structure rules and the audit that follows |
|
|
35
|
+
| `canon:write-human` | Before drafting or revising prose, for voice, rhythm, and density |
|
|
36
36
|
|
|
37
37
|
Every row answers a question rather than marking a point in a project's life, so filing one under a phase on the [skill map](skill-map.md) would send a reader to the wrong group.
|
|
38
38
|
|
|
39
|
-
A learning workspace produces two halves and only one of them leaves. A lesson is worked through once and stays in the workspace, and a reference page or a glossary carries no learner, so it belongs wherever the project already keeps prose on that subject. Asking `canon:teach-workspace` to promote sorts each durable page by who owns its subject, sending an Anthropic-owned subject to the wiki, an internal one to the matching context entry, and everything else, subject-neutral material included, to the public docs. It proposes and waits, because a promoted page is public prose that needs a line naming who owns the subject, and it writes nothing to a destination: each page the operator confirms goes to a handoff file that `canon:
|
|
39
|
+
A learning workspace produces two halves and only one of them leaves. A lesson is worked through once and stays in the workspace, and a reference page or a glossary carries no learner, so it belongs wherever the project already keeps prose on that subject. Asking `canon:teach-workspace` to promote sorts each durable page by who owns its subject, sending an Anthropic-owned subject to the wiki, an internal one to the matching context entry, and everything else, subject-neutral material included, to the public docs. It proposes and waits, because a promoted page is public prose that needs a line naming who owns the subject, and it writes nothing to a destination: each page the operator confirms goes to a handoff file that `canon:teach-workspace` folds in from a branch in its fold mode. A project with no wiki folder gets a refusal naming `canon wiki init` rather than a folder it never asked for.
|
|
@@ -29,8 +29,8 @@ Each row sits under the group its skill's `metadata.family` names. The landing p
|
|
|
29
29
|
| `canon:plan-groundwork` | When the state is unmeasured and more than one approach is live |
|
|
30
30
|
| `canon:decision-escalate` | When open decisions turn on your preference and want batching into one set |
|
|
31
31
|
| `canon:draft-and-pick` | When the call is taste and wants several candidates rendered side by side |
|
|
32
|
-
| `canon:canvas`
|
|
33
|
-
| `canon:task-board` | When a decided item needs a file on the board, or
|
|
32
|
+
| `canon:canvas-board` | When a direction should be drawn as frames the operator can see, select, and edit |
|
|
33
|
+
| `canon:task-board` | When a decided item needs a file on the board, or one is decided against |
|
|
34
34
|
| `canon:plan-feature` | When the approach is settled and the next step is a plan |
|
|
35
35
|
| `canon:codebase-layout` | When a plan or change adds a file and you need to decide which folder holds it |
|
|
36
36
|
|
|
@@ -63,15 +63,16 @@ Each row sits under the group its skill's `metadata.family` names. The landing p
|
|
|
63
63
|
|
|
64
64
|
## Ship it
|
|
65
65
|
|
|
66
|
-
| Skill
|
|
67
|
-
|
|
|
68
|
-
| `canon:git-ship`
|
|
69
|
-
| `canon:context-fold`
|
|
70
|
-
| `canon:
|
|
71
|
-
| `canon:
|
|
72
|
-
| `canon:git-
|
|
73
|
-
| `canon:git-
|
|
74
|
-
| `canon:git-
|
|
66
|
+
| Skill | When to use |
|
|
67
|
+
| --------------------- | ----------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `canon:git-ship` | To run the whole post-feature chain from the verify gate through open PR |
|
|
69
|
+
| `canon:context-fold` | When decisions diverged from the plan, or the diff left a context entry stale |
|
|
70
|
+
| `canon:task-complete` | After the fold, to mark the outcomes the diff shipped, or to archive a task the merge hook left |
|
|
71
|
+
| `canon:docs-sync` | When a change since main left `README.md` or `docs/` stale |
|
|
72
|
+
| `canon:git-stage` | When the staged set spans several concerns and wants one commit each |
|
|
73
|
+
| `canon:git-commit` | When the staged set is one concern, or was staged hunk by hand |
|
|
74
|
+
| `canon:git-branch` | When a branch name needs generating or renaming to conventional form |
|
|
75
|
+
| `canon:git-pr` | When a pull request needs a title and body written from the diff |
|
|
75
76
|
|
|
76
77
|
## After the pull request opens
|
|
77
78
|
|
|
@@ -20,7 +20,7 @@ Claude Code reads it and writes the implementation. Works for CLI tools, interna
|
|
|
20
20
|
|
|
21
21
|
### Seed shape
|
|
22
22
|
|
|
23
|
-
The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships a token-table template with a starting set of roles, and `
|
|
23
|
+
The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships a token-table template with a starting set of roles, and `claude/skills/canvas-board/references/design.md` carries the same tables under `## Template` with placeholder rows. The column headers are what the renderer parses, so they stay verbatim in either, while the rows and values are the project's own.
|
|
24
24
|
|
|
25
25
|
`canon design render` writes an HTML plus CSS preview to `.canon/tmp/render/design/` for eyeballing the current system without leaving Claude Code. See `canon/context/design/index.md`.
|
|
26
26
|
|
|
@@ -39,7 +39,7 @@ A cell no source anchors ends in `? verify`, and the preview shows that marker b
|
|
|
39
39
|
- `canon:ux-audit` for UX gap detection on existing surfaces
|
|
40
40
|
- `canon:ux-measure` for what a running surface costs to paint, read against published thresholds
|
|
41
41
|
- `canon:draft-and-pick` for a call settled by looking, drafting several candidates as frames on the canvas and taking your pick
|
|
42
|
-
- `canon:canvas` for a direction worked out over several turns, drawn as HTML frames you drag, select, and restyle in the browser while the session reads your changes back. Only the pick moves into `canon/DESIGN.md`, since the canvas folder is gitignored
|
|
42
|
+
- `canon:canvas-board` for a direction worked out over several turns, drawn as HTML frames you drag, select, and restyle in the browser while the session reads your changes back. Only the pick moves into `canon/DESIGN.md`, since the canvas folder is gitignored
|
|
43
43
|
- `canon:draft-identity` to draft a project's logo mark and compose it into an icon sequence and a social card, through `draft-and-pick`'s own render-and-pick loop. On an Astro project holding the card route scaffold, the card lands as a route the project keeps and is captured through a running server, so it reads the project's real stylesheet rather than typed copies of every color. Everywhere else it ships as a PNG and the run says so.
|
|
44
44
|
- Anthropic's `frontend-design` plugin optional for light visual steering
|
|
45
45
|
|