@erclx/canon 5.32.0 → 5.33.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/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/SKILL.md +1 -1
- package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +2 -2
- package/claude/skills/{canvas → canvas-board}/SKILL.md +2 -2
- package/{standards → claude/skills/canvas-board/references}/design.md +11 -2
- 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 +2 -2
- package/{standards → claude/skills/create-rule/references}/rule.md +12 -5
- package/claude/skills/create-skill/SKILL.md +2 -2
- package/{standards → claude/skills/create-skill/references}/skill.md +17 -14
- 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-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-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 +1 -1
- package/claude/skills/review-ui/references/post.md +1 -1
- 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 +23 -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/references/detect.md +1 -1
- 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/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 +1 -1
- package/docs/agents/commands.md +3 -2
- package/docs/agents/context-audit-checks.md +4 -4
- package/docs/agents/index.md +3 -3
- package/docs/agents/indexes.md +1 -1
- package/docs/agents/install-and-sync.md +6 -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/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/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 +1 -1
- 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/renames.toml +0 -11
- package/governance/rules/canon/context.md +13 -0
- package/governance/rules/claude/skill.md +17 -0
- package/governance/stacks/base.toml +2 -4
- package/package.json +4 -4
- package/scripts/core/install-check.sh +3 -3
- package/scripts/lib/ui.sh +0 -159
- package/src/audits/catalog.ts +0 -1
- 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/claude.ts +1 -1
- package/src/commands/gov.ts +2 -15
- package/src/commands/labels.ts +326 -7
- package/src/commands/migrate.ts +6 -1
- package/src/commands/pr.ts +1 -1
- 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/gate/measures.ts +1 -1
- package/src/gate/sequencer.ts +56 -1
- package/src/gate/stages.ts +1 -7
- package/src/gov/install.ts +2 -3
- package/src/gov/stacks.ts +1 -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/paths.ts +4 -4
- 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 +5 -44
- 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/claude/skills/{canvas → canvas-board}/references/canvas.md +0 -0
- /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
|
@@ -9,7 +9,7 @@ What each finding from `canon context audit` means. The command surface, its fla
|
|
|
9
9
|
|
|
10
10
|
## Required sections
|
|
11
11
|
|
|
12
|
-
The required-section check reports what does not declare the sections its folder's standard requires. A context entry owes `## Overview` and `## Layout`, the two sections `
|
|
12
|
+
The required-section check reports what does not declare the sections its folder's standard requires. A context entry owes `## Overview` and `## Layout`, the two sections `claude/skills/context-fold/references/context.md` marks required. The lists are held in code beside the numeric checkpoints rather than parsed out of the standard, so it fails on a defect rather than on a rewrite of the wording around it. A heading at any level counts, because a domain that split into a folder carries its overview in a sibling named `overview.md` where the section is the `#` title and an `##` beneath it would repeat the filename. Matching exactly is what keeps `## Layout catalog` from satisfying `Layout`.
|
|
13
13
|
|
|
14
14
|
Which unit answers depends on the folder. Entries of the folder named under `.claude/` are one domain each, so each answers for itself and a finding names the entry. Entries of a folder a domain split into describe that one domain between them, so any sibling answers and a finding names the folder. Holding a split folder to the rule per file would report every child beside its `overview.md`, and rolling the named folder up would let one conforming entry stand in for every other domain sitting next to it.
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ It reports rather than gates by default, the closer call because a missing secti
|
|
|
19
19
|
|
|
20
20
|
## Reference form
|
|
21
21
|
|
|
22
|
-
The reference-form check reports an entry naming a sibling entry by bare filename where `
|
|
22
|
+
The reference-form check reports an entry naming a sibling entry by bare filename where `claude/skills/context-fold/references/context.md` asks for the path it sits at. A bare name resolves against whichever folder its reader is already in, so a domain that splits into subfolders strands every inbound reference and the break surfaces nowhere. A path is checkable, which is what makes the form rule worth measuring at all: once a reference spells its path, the citation gate resolves it and a split that moves the file fails the push.
|
|
23
23
|
|
|
24
24
|
A finding is a backticked filename carrying no folder, matched against the entries beside the one that wrote it. The backticks are required, since a filename in running prose is not a reference a reader follows.
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ It reports and never gates, which is the split the citation check already draws.
|
|
|
33
33
|
|
|
34
34
|
## Length
|
|
35
35
|
|
|
36
|
-
Length quotes its checkpoint from `
|
|
36
|
+
Length quotes its checkpoint from `claude/skills/context-fold/references/context.md`: roughly 150 rendered lines for an entry, applied to each of the 60 entries the audit measures, 51 of them under `canon/context/` and 9 diagram files beside them. It counts rendered lines rather than source lines, wrapping each line at 80 columns and summing the heights.
|
|
37
37
|
|
|
38
38
|
A line is wrapped at the width it renders at, so a link counts as its anchor text and a backticked path counts whole, which parts the rendered count from a source count wherever an entry cites a path in backticks rather than as a link. Entries here are authored one line per bullet, so a block of fifteen paragraph-bullets occupies fifteen source lines and renders past sixty, which source counting cannot see.
|
|
39
39
|
|
|
@@ -71,7 +71,7 @@ The audit reads `canon/REQUIREMENTS.md` under its own step rather than as a fold
|
|
|
71
71
|
|
|
72
72
|
The provenance check covers `canon/context/` alone, the reference-form check covers the split folders inside it, the required-section check covers `canon/context/` alone, and length and the table finding reach every audited folder.
|
|
73
73
|
|
|
74
|
-
What narrows the provenance check is stated in `
|
|
74
|
+
What narrows the provenance check is stated in `claude/skills/context-fold/references/context.md`, which opens its scope by handing figures to the `draft-figure` skill, and the sibling standards do not restate it. A marker reported in a diagram entry would cite a rule that entry's own standard routes elsewhere. The split is between kinds of rule rather than kinds of folder, and what decides it is which tier states the rule rather than what the check measures.
|
|
75
75
|
|
|
76
76
|
Length and the table finding generalize as judgments about how far a reader travels, so both reach wherever the audit is pointed. Required sections narrow for a plainer reason: each list is one standard's own, so it reaches the folder that standard governs. The context standard states a set, and an older install's diagrams folder has no standard to state one.
|
|
77
77
|
|
package/docs/agents/index.md
CHANGED
|
@@ -27,7 +27,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
27
27
|
- [Indexes](indexes.md): Flags, exit codes, and JSON shape for canon indexes regen and canon indexes list, plus when regen auto-stages what it rewrote
|
|
28
28
|
- [Install and sync](install-and-sync.md): What each install and sync verb writes, refuses, or leaves alone, and how drift is attributed in a target project
|
|
29
29
|
- [Intake](intake.md): Reading intake folder counts and items, the three read states an item can be in, landing a batch of selections in one cluster, the refusal reasons, and why a call is scoped to one file
|
|
30
|
-
- [Key
|
|
30
|
+
- [Key changes bijection](key-changes.md): Comparing the files a pull request body's Key changes names against its own diff, the two directions and the split inside each that decides what is worth raising, the span rules the extractor was measured into, and the three refusals that separate a clean pass from a read that produced nothing
|
|
31
31
|
- [Label coverage](label-coverage.md): Reading a changed set against the pull request label map, the two tables it matches, how a gap is separated from a decision, and why an absent map is an answer
|
|
32
32
|
- [Markdown audit weight](markdown-audit-weight.md): The structural half of the markdown audit, being bullet and paragraph weight, run depth, the two cadence numbers, and the length ceiling, with the samples behind each checkpoint and why none of them gates
|
|
33
33
|
- [Markdown audit](markdown-audit.md): Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why the ban half gates while the structural half reports
|
|
@@ -41,9 +41,9 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
41
41
|
- [Head-sensitive pull request reads](pr-reads.md): Resolving a branch tip from the remote rather than from the pull request object, reading what a review pass covered off its own marker rather than off GitHub's submission stamps, why an empty run list is not a pass, the refusal reasons each verb names, and what the remote read costs
|
|
42
42
|
- [The pull request checklist tick](pr-tick.md): How canon pr tick marks the checklist boxes a UI pass drove, the stamp that names the commit each passed at, why a render at a newer head clears a tick, the refusal reasons it names, and why a taste box is never ticked
|
|
43
43
|
- [Records push](records-push.md): Backing the record folders to a private remote and restoring them, which folders the payload carries, the one-time setup, the refusal reasons, and the hook that runs the push
|
|
44
|
-
- [Records stale](records-stale.md):
|
|
44
|
+
- [Records stale](records-stale.md): Counting the releases since the requirements record was last reviewed, where the review date is read from, and the exit codes and refusals
|
|
45
45
|
- [Records validate](records-validate.md): Validating the session records and the standards corpus, the per-kind checks, which root each kind defaults to, the exit codes, and the refusal reasons
|
|
46
|
-
- [Records](records.md): The two roots a record folder resolves at,
|
|
46
|
+
- [Records](records.md): 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
|
|
47
47
|
- [Restated instructions](restated.md): Counting the instructions the always-loaded file and every path-scoped rule share with the seed, the skill bodies, and each other, how a match is decided, the three classes, which surface a later edit starts from, and why the sweep reports rather than gates
|
|
48
48
|
- [Routing report](routing.md): Reading per CLAUDE.md section how many bullets name a path, what counts as naming one, when a rule counts as covering it, the two refusals, and why the verb reports rather than gates
|
|
49
49
|
- [Rule citations](rule-citations.md): Resolving every path a governance rule cites and every frontmatter glob the internal corpus declares, the three forms a citation is written in, the shapes that look like citations and are not, the two classes where an absent path is correct, why the glob half reads one corpus, and why this one gates
|
package/docs/agents/indexes.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Flags, exit codes, and JSON shape for canon indexes regen and canon
|
|
|
5
5
|
|
|
6
6
|
# Indexes
|
|
7
7
|
|
|
8
|
-
`canon indexes regen` rewrites `index.md` files from sibling frontmatter. With no positional paths, it walks the current directory. With paths, each resolves by walking up to the nearest indexed ancestor, bounded by `--root`.
|
|
8
|
+
`canon indexes regen` rewrites `index.md` files from sibling frontmatter, so a hand edit to a generated index is lost on the next run. With no positional paths, it walks the current directory. With paths, each resolves by walking up to the nearest indexed ancestor, bounded by `--root`.
|
|
9
9
|
|
|
10
10
|
Duplicates dedupe. The whole-repo walk prunes `.git`, `node_modules`, and anything `.gitignore` covers via `git check-ignore`.
|
|
11
11
|
|
|
@@ -28,11 +28,11 @@ applies, and the target's git diff is the record afterwards. `canon sync
|
|
|
28
28
|
--check` lists the same file as `retired` or `renamed` before any sync runs.
|
|
29
29
|
|
|
30
30
|
A rule that only routed a path to a standard ships under that standard's name,
|
|
31
|
-
but the tasks and
|
|
32
|
-
`
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
but the tasks, plan, context, and skill rules are hand-written at `canon/` and
|
|
32
|
+
`claude/skill.md`. A held copy of each syncs in place, and the groundwork,
|
|
33
|
+
intake, session, design, readme, and rule copies are deleted as retired. The
|
|
34
|
+
markdown rule is hand-written at `writing/markdown.md`, and a target holding
|
|
35
|
+
`standards/markdown.md` keeps it there as `800-prose` retires.
|
|
36
36
|
|
|
37
37
|
A project's own rules belong under `.claude/rules/project/`, where
|
|
38
38
|
`canon standards rule` reserves `900-999` for them, and a rule placed under
|
|
@@ -146,12 +146,7 @@ runs the verb again for that name.
|
|
|
146
146
|
|
|
147
147
|
`canon gov regen` is the one governance verb that runs against the toolkit root,
|
|
148
148
|
because the `.claude/rules/` it writes there is produced output rather than an
|
|
149
|
-
operator's working copy. It
|
|
150
|
-
per standard under `standards/` whose frontmatter carries `paths:`, clearing the
|
|
151
|
-
folder so a standard that drops the field loses its rule. A standard named like
|
|
152
|
-
a band folder or an authored rule, or a `paths:` or `rule:` that is not a list
|
|
153
|
-
of strings, refuses the whole run before anything is written. It then reads the
|
|
154
|
-
stack recorded in `internal/governance.toml`
|
|
149
|
+
operator's working copy. It reads the stack recorded in `internal/governance.toml`
|
|
155
150
|
into `.claude/rules/canon/`, installs anything under `internal/rules/` into a
|
|
156
151
|
separate `.claude/rules/internal/`, and clears both destinations first so a
|
|
157
152
|
rule the record stopped naming disappears. `internal/` is what this repository
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Key
|
|
3
|
-
description: Comparing the files a pull request body's Key
|
|
2
|
+
title: Key changes bijection
|
|
3
|
+
description: Comparing the files a pull request body's Key changes names against its own diff, the two directions and the split inside each that decides what is worth raising, the span rules the extractor was measured into, and the three refusals that separate a clean pass from a read that produced nothing
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Key
|
|
6
|
+
# Key changes bijection
|
|
7
7
|
|
|
8
|
-
`canon pr key-changes` reads the `## Key
|
|
8
|
+
`canon pr key-changes` reads the `## Key changes` section of a pull request body, lifts the paths its bullets claim, and compares that set against the files the pull request actually changed. This repository squash-merges, so the body becomes the commit message and the record on the trunk once the branch is gone.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
canon pr key-changes
|
|
@@ -45,7 +45,7 @@ A generated asset and a regenerated index belong in the incidental class and are
|
|
|
45
45
|
|
|
46
46
|
## What counts as a claim
|
|
47
47
|
|
|
48
|
-
Only `## Key
|
|
48
|
+
Only `## Key changes` is read. `## Technical context` legitimately names files a branch never touched, such as an install stamp inside a target, so widening the read manufactures a finding out of every argument an author made for the change.
|
|
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
|
|
|
@@ -70,6 +70,17 @@ It reports and never gates. Whether an uncovered surface deserves a label is a j
|
|
|
70
70
|
|
|
71
71
|
A project declaring no map refuses with `no-map`, which is an answer rather than a fault. Such a project is labelled silently by design, and treating the absence as a break would make the map mandatory for every target. `canon audits run` reads that one reason as an expected absence and every other refusal as a measure that did not run.
|
|
72
72
|
|
|
73
|
+
## Applying the set
|
|
74
|
+
|
|
75
|
+
`canon labels apply <number>` reads the same earned set and adds each label the open pull request lacks, so a pull request opened outside `git-pr` takes one command to label.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
canon labels apply 123 --json
|
|
79
|
+
canon labels apply 123 --check
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It binds to the pull request before anything is read or written, and refuses with `head-mismatch` unless the head is the current branch and the state is open, under `--check` as well. It adds and never removes, so a label a person applied stays. A label the remote does not carry lands in `missingOnRemote` and is never created. `--check` writes nothing and exits 2 when labels are owed. A project declaring no map adds nothing and exits 0.
|
|
83
|
+
|
|
73
84
|
## What it does not measure
|
|
74
85
|
|
|
75
86
|
A prefix reaching no path is invisible here. A row left behind by a deleted folder stays in the map forever, and this verb has nothing to say about it. That is the map going stale from the other side and a second measure rather than this one.
|
package/docs/agents/migrate.md
CHANGED
|
@@ -9,7 +9,7 @@ description: What each canon migrate verb moves and rewrites, what it refuses, t
|
|
|
9
9
|
|
|
10
10
|
`migrate rename` moves a project off the retired `aitk` name. It reports until `--write` is passed, and `--scope target` rewrites the toolkit-owned folders alone, reporting every other citation as one the project owns rather than editing prose somebody wrote. A project installing `canon` fresh never needs it.
|
|
11
11
|
|
|
12
|
-
`migrate skill-names` moves the plugin skills that carried a `claude-` prefix onto their two-word names and rewrites every citation of one. It carries two plain renames as well, where a skill carried no prefix and changed its name because the old one described a job it no longer does, landing on `ui-checklist` and `context-fold`, and one merge, where the five per-kind document drafters land on `draft-doc`. It leaves the pointer answering under the fold skill's old name in place. It shares its engine with `migrate rename` and differs in what it is scanning for: a skill name is a whole name rather than a word stem, so it matches only where the word ends, which is what keeps a longer word that merely opens with a skill name, such as `claude-worktrees`, out of it. It takes no `--scope`, since the skill folders it moves are authored in the toolkit and no target holds a copy of that catalog, which leaves a target's own citations of a renamed skill as the whole of what it rewrites there. The changelog and the eval transcripts are passed over on the argument the other sweep already carries, that each records what shipped or what a session ran under whatever name was current then.
|
|
12
|
+
`migrate skill-names` moves the plugin skills that carried a `claude-` prefix onto their two-word names and rewrites every citation of one. It carries two plain renames as well, where a skill carried no prefix and changed its name because the old one described a job it no longer does, landing on `ui-checklist` and `context-fold`, and one merge, where the five per-kind document drafters land on `draft-doc`. It carries one namespaced-only rename, `canvas` to `canvas-board`, keyed on `canon:canvas` and `skills/canvas` because a bare `canvas` key would rewrite the verb, its source folder, and its record folder. It leaves the pointer answering under the fold skill's old name in place. It shares its engine with `migrate rename` and differs in what it is scanning for: a skill name is a whole name rather than a word stem, so it matches only where the word ends, which is what keeps a longer word that merely opens with a skill name, such as `claude-worktrees`, out of it. It takes no `--scope`, since the skill folders it moves are authored in the toolkit and no target holds a copy of that catalog, which leaves a target's own citations of a renamed skill as the whole of what it rewrites there. The changelog and the eval transcripts are passed over on the argument the other sweep already carries, that each records what shipped or what a session ran under whatever name was current then. <!-- canon-keep-retired -->
|
|
13
13
|
|
|
14
14
|
`migrate records` moves a project's session records from `.claude/` to `.canon/` and rewrites every tracked file that cites one. It reports until `--write` is passed, and refuses outright when the project does not already ignore `.canon/`, since every folder it relocates is ignored where it stands and landing one under a tracked root commits the memory pen. Take the ignore entry with `canon tooling sync --write` first.
|
|
15
15
|
|
|
@@ -31,7 +31,7 @@ printf '.canon/\n' >> .gitignore
|
|
|
31
31
|
|
|
32
32
|
The ignore line is repeated here rather than left to the install, because the person running these commands is the one who creates the directory and the rule is worth reading beside the command that needs it. The claude manifest ships `.canon/` too, so a project that ran `canon tooling sync` already carries it and this line is a no-op there. One root entry covers the history and every record beside it, which is what makes the rule worth stating once rather than per folder.
|
|
33
33
|
|
|
34
|
-
Point it at a private repository, and at one that is not a remote of the project. Records carry the
|
|
34
|
+
Point it at a private repository, and at one that is not a remote of the project. Records carry the plans, the review reports, and the groundwork trails, so a public project publishes all of it to anyone who fetches all refs. `push` compares the configured origin against every remote of the project and refuses on a match. A read of that list which fails refuses as well, since an empty list clears the comparison for every origin and a gate that passes on its own failure is no gate.
|
|
35
35
|
|
|
36
36
|
## Refusals
|
|
37
37
|
|
|
@@ -58,4 +58,4 @@ The two `pull` refusals exist because the directions are not symmetric. A push o
|
|
|
58
58
|
|
|
59
59
|
## When it runs
|
|
60
60
|
|
|
61
|
-
`canon hooks post-merge`, which `.husky/post-merge` calls, runs `push` after the task archiving, on every merge rather than only on one that archived a task. A review report and a
|
|
61
|
+
`canon hooks post-merge`, which `.husky/post-merge` calls, runs `push` after the task archiving, on every merge rather than only on one that archived a task. A review report and a plan edit both land on runs that close nothing. The verb exits zero whatever the push answers, so an unreachable remote neither aborts the hook nor delays the archiving before it, and a checkout that never ran the setup reports nothing. `hooks.md` covers the verb. Anything the hook misses is covered by running the verb by hand.
|
|
@@ -1,64 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Records stale
|
|
3
|
-
description:
|
|
3
|
+
description: Counting the releases since the requirements record was last reviewed, where the review date is read from, and the exit codes and refusals
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Records stale
|
|
7
7
|
|
|
8
|
-
`canon records stale
|
|
8
|
+
`canon records stale canonical` reports when the requirements record was last reviewed and how many releases have shipped since. A skill takes the count from the verb rather than re-deriving it from the tag list.
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
canon records stale
|
|
12
|
-
canon records stale memory --json
|
|
13
|
-
canon records stale memory --days 60 --json
|
|
11
|
+
canon records stale canonical
|
|
14
12
|
canon records stale canonical --json
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
| Option | Behavior
|
|
18
|
-
| --------------- |
|
|
19
|
-
| `--json` | Add a machine-readable record on stdout
|
|
20
|
-
| `--
|
|
21
|
-
| `--root <path>` | Project root, defaulting to the main worktree for `memory` and the current worktree for `canonical` |
|
|
15
|
+
| Option | Behavior |
|
|
16
|
+
| --------------- | ----------------------------------------------------------------- |
|
|
17
|
+
| `--json` | Add a machine-readable record on stdout |
|
|
18
|
+
| `--root <path>` | Project root, defaulting to the current worktree rather than main |
|
|
22
19
|
|
|
23
|
-
`
|
|
20
|
+
`canonical` is the one kind it reads. Any other argument refuses as `unknown-kind`, including `memory`, which the verb read until the memory pen retired.
|
|
24
21
|
|
|
25
|
-
It reports and never writes
|
|
26
|
-
|
|
27
|
-
## What makes an entry due
|
|
28
|
-
|
|
29
|
-
An entry is due when its frontmatter carries no `reviewed` date, or one older than `--days`. The field is optional, and a review that keeps an entry is what writes it. A `reviewed` value that is not a `YYYY-MM-DD` calendar date reads as never reviewed, and the record carries the raw value as `invalidReviewed` so a review can see it rather than the verb throwing over one hand edit.
|
|
30
|
-
|
|
31
|
-
The field is read off the raw frontmatter block rather than a parsed value, since a YAML parser resolves a bare date to a date object on one schema and a string on another.
|
|
32
|
-
|
|
33
|
-
## Cited paths
|
|
34
|
-
|
|
35
|
-
A cited path is a backticked token holding a `/` and ending in a file extension. A trailing `:12`, `:12-20`, or `#heading` anchor is stripped before the test, since otherwise every line citation reads as missing. The path resolves against the project root and never against the entry's own folder, because an entry cites the tree it was written about.
|
|
36
|
-
|
|
37
|
-
Tokens that look like paths and cite nothing in the tree are never reported:
|
|
38
|
-
|
|
39
|
-
- Anything under `.canon/`, the scratch folder, or `.claude/worktrees/`, which no tree commits
|
|
40
|
-
- A placeholder or glob holding `<`, `*`, or `{`, a variable holding `$`, and a path elided with `...`
|
|
41
|
-
- A URL, an absolute path, a home path, and a path opening with `../`
|
|
42
|
-
|
|
43
|
-
A missing path is a proxy for an entry the tree has moved under, not a verdict. It misses a rule the tree now contradicts in prose, and in a target project it flags a toolkit path the target never held. The review judges each one rather than retiring on the flag alone.
|
|
44
|
-
|
|
45
|
-
## Order
|
|
46
|
-
|
|
47
|
-
The pen is read at its top level alone. `review/` holds receipts, `archive/` holds retirements, and `index.md` is the generated catalog, so none is an entry a review would queue.
|
|
48
|
-
|
|
49
|
-
Entries come back due first. Among the due entries, one citing a missing path leads, then the longest unreviewed, with a never-reviewed entry ahead of any dated one, then by name so two runs over one pen agree. A caller takes the first N as a batch:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
canon records stale memory --json | jq -r '[.entries[] | select(.due)][0:20][] | .name'
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
The record carries `total`, `due`, `days`, the `folder` read relative to the root, and one `entries` row per entry with `name`, `category`, `reviewed`, `due`, and `unresolved`.
|
|
22
|
+
It reports and never writes, matching `validate` and `size`.
|
|
56
23
|
|
|
57
24
|
## Canonical records
|
|
58
25
|
|
|
59
26
|
`canonical` reads `REQUIREMENTS.md` at whichever surface root carries it, `canon/` ahead of `.claude/`, and omits it when the project does not hold one. It is tracked, so `--root` defaults to the worktree the caller stands in rather than the main one, and a stamp a branch just wrote reads back from that branch.
|
|
60
27
|
|
|
61
|
-
The review point is an optional `reviewed: YYYY-MM-DD` frontmatter field, set by whoever finishes a review, per `canon standards requirements`. It is a date rather than a commit, since a commit written on a feature branch never reaches a trunk that squash-merges. The field is read the
|
|
28
|
+
The review point is an optional `reviewed: YYYY-MM-DD` frontmatter field, set by whoever finishes a review, per `canon standards requirements`. It is a date rather than a commit, since a commit written on a feature branch never reaches a trunk that squash-merges. The field is read off the raw frontmatter block rather than a parsed value, since a YAML parser resolves a bare date to a date object on one schema and a string on another. A value that is not a calendar date reads as never reviewed, and the record carries the raw value as `invalidReviewed` so a review can see it rather than the verb throwing over one hand edit.
|
|
62
29
|
|
|
63
30
|
The count is every release tag merged into `HEAD` whose creator date falls after the reviewed day. A release tag ends in a dotted version, bare as `v5.25.0` or behind a component prefix as `canon-v2.1.0`, so an eval, deploy, or snapshot tag on the trunk never inflates it. A lightweight tag's creator date is its commit's date and an annotated tag's is the tagging date, so a project mixing both counts by two clocks.
|
|
64
31
|
|
|
@@ -68,8 +35,6 @@ It gates nothing, and no hook, gate stage, or workflow runs it. `canon:document-
|
|
|
68
35
|
|
|
69
36
|
## Exit codes and refusals
|
|
70
37
|
|
|
71
|
-
Exit codes: `0` the reading completed, whatever it found, and `1` refused. A
|
|
72
|
-
|
|
73
|
-
A `reason` field carries which gate fired: `no-folder` when the project holds no memory folder at either record root, `unknown-kind` for any kind but `memory` or `canonical`, `bad-days` when `--days` is not a positive whole number or is passed to `canonical`, and `unreadable-tags` when `canonical` cannot read the tags. An empty pen is not a refusal. It reports an empty list and exits `0`.
|
|
38
|
+
Exit codes: `0` the reading completed, whatever it found, and `1` refused. A release count is a prompt for the review to judge rather than a failure, so nothing here gates.
|
|
74
39
|
|
|
75
|
-
|
|
40
|
+
A `reason` field carries which gate fired: `unknown-kind` for any kind but `canonical`, and `unreadable-tags` when the tags cannot be read.
|
|
@@ -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
|
|
|
@@ -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
|
@@ -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
|
|
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
|
|