@erclx/canon 5.39.0 → 5.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -22
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +6 -0
- package/claude/skills/auto-ship/references/fan-in.md +59 -0
- package/claude/skills/canvas-board/SKILL.md +1 -1
- package/claude/skills/create-skill/references/skill.md +1 -1
- package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
- package/claude/skills/decision-escalate/SKILL.md +1 -2
- package/claude/skills/draft-slides/SKILL.md +2 -3
- package/claude/skills/draft-slides/references/deck.md +183 -0
- package/claude/skills/git-branch/REQUIREMENT.md +17 -6
- package/claude/skills/git-branch/SKILL.md +63 -7
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-pr/references/final-command.md +1 -1
- package/claude/skills/git-pr/references/labels.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/plan-feature/references/batches.md +48 -1
- package/claude/skills/plan-feature/references/plan.md +2 -0
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
- package/claude/skills/plan-intake-answer/SKILL.md +1 -2
- package/claude/skills/review-address/references/rebase-conflicts.md +7 -0
- package/claude/skills/review-ui/SKILL.md +3 -0
- package/claude/skills/review-ui/references/close-out.md +47 -0
- package/claude/skills/review-ui/references/post.md +3 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +1 -0
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +1 -1
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +9 -0
- package/claude/skills/task-board/references/board.md +1 -1
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
- package/claude/skills/teach-workspace/SKILL.md +1 -2
- package/claude/skills/ux-measure/SKILL.md +1 -1
- package/docs/agents/audits.md +61 -60
- package/docs/agents/context-audit.md +40 -58
- package/docs/agents/index.md +5 -51
- package/docs/agents/install-and-sync.md +1 -0
- package/docs/agents/markdown-audit.md +53 -99
- package/docs/agents/records.md +37 -79
- package/docs/agents/sessions-transfer.md +26 -70
- package/docs/target/index.md +0 -1
- package/docs/target/migrations.md +57 -66
- package/docs/target/projects.md +36 -78
- package/docs/target/scenarios.md +9 -19
- package/docs/target/sync.md +27 -68
- package/docs/workflow/ai-workflow.md +22 -68
- package/docs/workflow/operating-model.md +32 -186
- package/docs/workflow/parallel-features.md +30 -66
- package/docs/workflow/skill-map-on-request.md +22 -24
- package/docs/workflow/skill-map.md +72 -76
- package/docs/workflow/visual-design-workflow.md +25 -118
- package/docs/workflow/zshrc-aliases.md +18 -37
- package/package.json +1 -1
- package/src/canvas/client/inspector/fields.css +4 -0
- package/src/canvas/index.html +6 -0
- package/src/claude/cases/git.ts +4 -0
- package/src/claude/skills-reach.ts +2 -2
- package/src/cli/ui.ts +3 -1
- package/src/commands/canvas.ts +23 -0
- package/src/commands/capture.ts +14 -0
- package/src/commands/claude.ts +13 -0
- package/src/commands/demo.ts +22 -0
- package/src/commands/deps.ts +6 -0
- package/src/commands/driver.ts +28 -2
- package/src/commands/gov.ts +52 -18
- package/src/commands/intake.ts +17 -0
- package/src/commands/labels.ts +38 -5
- package/src/commands/pr.ts +192 -52
- package/src/commands/records.ts +19 -3
- package/src/commands/secrets.ts +6 -0
- package/src/commands/sessions.ts +8 -0
- package/src/commands/tasks.ts +52 -0
- package/src/commands/teach.ts +13 -0
- package/src/commands/upstream.ts +25 -1
- package/src/commands/worktrees.ts +5 -0
- package/src/context/audit.ts +22 -4
- package/src/context/folders.ts +1 -1
- package/src/context/shape-gated.ts +5 -2
- package/src/counts/scan.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/tokens.ts +1 -1
- package/src/gate/boundaries.ts +4 -1
- package/src/gate/measures.ts +1 -1
- package/src/gate/stages.ts +7 -7
- package/src/git/env.ts +6 -0
- package/src/markdown/scope.ts +11 -19
- package/src/pr/frames.ts +53 -9
- package/src/pr/lift.ts +153 -19
- package/src/pr/painted.ts +87 -0
- package/src/records/validate.ts +1 -0
- package/src/roots/record.ts +18 -1
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/headless/run.ts +3 -2
- package/src/sandbox/headless/watch.ts +3 -4
- package/src/slides/convert/master.ts +3 -0
- package/src/sync/format.ts +46 -0
- package/src/sync/stamp.ts +6 -0
- package/src/tasks/answers.ts +79 -2
- package/src/tasks/fan-in.ts +176 -0
- package/src/tasks/stack.ts +1 -1
- package/tooling/astro/reference.md +80 -39
- package/tooling/base/reference.md +63 -32
- package/tooling/base/seeds/canon/context/ci.md +7 -15
- package/tooling/base/seeds/canon/context/development.md +14 -14
- package/tooling/claude/reference.md +40 -22
- package/tooling/cloudflare/reference.md +31 -12
- package/tooling/go/reference.md +47 -23
- package/tooling/nextjs/reference.md +52 -19
- package/tooling/php/reference.md +35 -16
- package/tooling/python/reference.md +47 -30
- package/tooling/shell/reference.md +6 -5
- package/tooling/vite-react/reference.md +49 -21
- package/tooling/web/reference.md +131 -71
- package/docs/agents/canvas.md +0 -86
- package/docs/agents/capture.md +0 -65
- package/docs/agents/census.md +0 -23
- package/docs/agents/comments.md +0 -34
- package/docs/agents/context-audit-checks.md +0 -108
- package/docs/agents/context-classify.md +0 -101
- package/docs/agents/counts.md +0 -74
- package/docs/agents/demo.md +0 -140
- package/docs/agents/driver.md +0 -103
- package/docs/agents/gate.md +0 -90
- package/docs/agents/hooks.md +0 -78
- package/docs/agents/intake.md +0 -81
- package/docs/agents/key-changes.md +0 -116
- package/docs/agents/label-coverage.md +0 -86
- package/docs/agents/markdown-audit-density.md +0 -39
- package/docs/agents/markdown-audit-weight.md +0 -83
- package/docs/agents/pr-evidence-layout.md +0 -70
- package/docs/agents/pr-evidence.md +0 -273
- package/docs/agents/pr-frames.md +0 -131
- package/docs/agents/pr-lift.md +0 -132
- package/docs/agents/pr-local.md +0 -111
- package/docs/agents/pr-preview.md +0 -155
- package/docs/agents/pr-reads.md +0 -111
- package/docs/agents/pr-tick.md +0 -72
- package/docs/agents/records-push.md +0 -61
- package/docs/agents/records-stale.md +0 -40
- package/docs/agents/records-validate.md +0 -57
- package/docs/agents/restated.md +0 -83
- package/docs/agents/routing.md +0 -61
- package/docs/agents/rule-citations.md +0 -90
- package/docs/agents/sandbox.md +0 -126
- package/docs/agents/sessions.md +0 -128
- package/docs/agents/skills-audit.md +0 -120
- package/docs/agents/skills-reach.md +0 -64
- package/docs/agents/slides.md +0 -176
- package/docs/agents/state-scoped-risk.md +0 -105
- package/docs/agents/superseded.md +0 -85
- package/docs/agents/tasks-archive.md +0 -83
- package/docs/agents/tasks-plans.md +0 -152
- package/docs/agents/tasks-validate.md +0 -133
- package/docs/agents/tasks.md +0 -123
- package/docs/agents/teach-authoring.md +0 -118
- package/docs/agents/teach.md +0 -157
- package/docs/agents/test-order.md +0 -58
- package/docs/agents/upstream.md +0 -94
- package/docs/agents/worktrees.md +0 -118
- package/docs/target/standards-moved.md +0 -34
|
@@ -1,87 +1,69 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Context audit
|
|
3
|
-
description: Running the audit, its
|
|
3
|
+
description: Running the context audit, its folder scope, the exit codes, every check with the folders it reaches and whether it gates, the seed gate, and the citation exclusions
|
|
4
|
+
kind: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Context audit
|
|
7
8
|
|
|
8
|
-
`canon context audit [path]` reports the
|
|
9
|
-
|
|
10
|
-
Findings stated over every markdown file rather than over a context entry are measured by `canon markdown audit`, described in `markdown-audit.md`. That command resolves no folder, so it reaches trees this one refuses.
|
|
9
|
+
`canon context audit [path]` reports the structure of the folders following the index-plus-entry contract, meaning a generated `index.md` beside entries carrying frontmatter, and measures `canon/REQUIREMENTS.md` beside them. It reads and reports. Findings over every markdown file belong to `canon markdown audit`, in `markdown-audit.md`.
|
|
11
10
|
|
|
12
11
|
```bash
|
|
13
12
|
canon context audit
|
|
14
13
|
canon context audit --json
|
|
15
14
|
canon context audit --citations-only
|
|
16
15
|
canon context audit --folder context,diagrams
|
|
17
|
-
canon context audit --folder docs
|
|
18
16
|
canon context audit tooling/base/seeds --gate
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
| ------------------ | ------------------------------------------------------------------------- |
|
|
23
|
-
| `--json` | Add a machine-readable record on stdout, keeping the frame |
|
|
24
|
-
| `--folder <list>` | Comma-separated folder names (default: the three below) |
|
|
25
|
-
| `--citations-only` | Run the gating citation check alone, printing nothing when it passes |
|
|
26
|
-
| `--gate` | Fail on a missing section, an off-set H2, gated shape break, or drift too |
|
|
27
|
-
|
|
28
|
-
`--citations-only` and `--gate` refuse together. The first runs the citation check alone, so the two findings the second adds are never measured, and a run honoring both would exit clean on a file short a required section.
|
|
29
|
-
|
|
30
|
-
## Folder scope
|
|
31
|
-
|
|
32
|
-
Scope defaults to `context`, `decisions`, and `diagrams`, and a folder the project does not carry is skipped rather than reported. A domain that outgrew one file and split into `<domain>/` is audited as its own folder, so a split entry measures at the same grain as a flat one.
|
|
33
|
-
|
|
34
|
-
A name passed to `--folder` resolves under the record roots first, `.canon/` ahead of `.claude/`, and at the project root last, which is what puts `docs/` and any later corpus in reach of the same engine. The root base is reached only by a name the caller passes, so the default list still resolves under a record root alone and a project holding a root folder of one of those names is not audited against a standard it never adopted. `diagrams` is the one default name that is a session record and moves with them, which is why both record roots are in the list rather than one, and `docs/agents/records.md` states the read order every verb shares. The scope line prints the resolved path, so a project carrying both spellings reads which one was taken. The JSON record carries the base per folder as `folders[].base`.
|
|
35
|
-
|
|
36
|
-
A run where no requested name resolves refuses, whichever list it read. Naming the absent ones narrows to `--folder`, since a project carrying one of the three default folders is the ordinary case and a name it never asked for is not a typo. The JSON record carries those names as `unresolvedFolders`.
|
|
37
|
-
|
|
38
|
-
## Exit codes
|
|
39
|
-
|
|
40
|
-
Exit codes are `0` for a clean run, `1` for a refusal, and `2` for a gating finding. An unresolved citation gates under every mode. A requirements record stating a word cap gates past it, on any run that measures it, which is every mode except `--citations-only`. A record stating none is reported and never gated.
|
|
41
|
-
|
|
42
|
-
`bun run check` in the toolkit repository reads every one of these rules through its own Canonical records stage as well as through this verb, whose gating stage there runs `--gate`.
|
|
19
|
+
`--gate` widens the failing set to the findings marked below. `--citations-only` runs the citation check alone, and the two refuse together.
|
|
43
20
|
|
|
44
|
-
|
|
21
|
+
`--folder` takes comma-separated names, defaulting to `context`, `decisions`, and `diagrams`. A folder the project lacks is skipped, and `folders[].base` names where each resolved.
|
|
45
22
|
|
|
46
|
-
|
|
23
|
+
## Output
|
|
47
24
|
|
|
48
|
-
|
|
25
|
+
| Check | Reports | Reaches | Finding |
|
|
26
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ----------------------------------------------------------- |
|
|
27
|
+
| Citations | A path into an audited folder that resolves nowhere | Every audited folder | Gates always |
|
|
28
|
+
| Requirements record | Words past the cap the record states as `This record holds at most 600 words.` | `canon/REQUIREMENTS.md` | Gates past a stated cap, never under `--citations-only` |
|
|
29
|
+
| Required sections | An entry missing `Overview` or `Layout`. A split folder answers by any sibling | `canon/context/` | Gates under `--gate` |
|
|
30
|
+
| Closed set | An H2 outside `Overview`, `Layout`, and `Gotchas`, under `extraSections` | `canon/context/` | Gates under `--gate` |
|
|
31
|
+
| Shape | `retired-section`, `gotcha-count`, `gotcha-heading`, `gotcha-paragraph`, `layout-heading`, `layout-bullets`, `layout-paragraphs`, `layout-depth` | `canon/context/` | Gates under `--gate` in a `SHAPE_GATED_FOLDERS` folder only |
|
|
32
|
+
| Index drift | An entry its index does not link, or a link resolving to nothing | Every audited folder | Gates under `--gate` |
|
|
33
|
+
| Reference form | A backticked bare filename matching a sibling entry, under `bareReferences` | Split folders | Reports |
|
|
34
|
+
| Length | An entry past about 150 rendered lines at 80 columns, with its `causes` | Every audited folder | Reports |
|
|
35
|
+
| Tables | Six or more body rows whose first column mostly carries a path, command, or link | Every audited folder | Reports |
|
|
36
|
+
| Provenance | A date, change number, or release label. A date after measured, verified, driven, passed, or fired is excluded | `canon/context/` | Reports |
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
A shape break is any of these:
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
The stage prints the entries it measured per root and warns on a root that measured none. A root can resolve an audited folder and hold no entry in it, which `tooling/claude/seeds` does today, so a single pass line over the set would report coverage of a tree nothing opened.
|
|
57
|
-
|
|
58
|
-
It reads the exit code rather than pass against fail, since the two failing codes mean opposite things. A root carrying a `.claude/` that resolves no audited folder refuses at 1 and warns, while a seed short a required section gates at 2 and fails the push. A new stack seeding `.claude/` alone therefore reports what it is rather than a violation it does not have.
|
|
59
|
-
|
|
60
|
-
### Exempting a skeleton
|
|
61
|
-
|
|
62
|
-
A seed that deliberately omits a required section sets `stub: true` in its frontmatter, and the section check then skips it. Every other measure still reads the file, since a stub is exempt from owing sections rather than from being well formed.
|
|
63
|
-
|
|
64
|
-
```markdown
|
|
65
|
-
---
|
|
66
|
-
title: Architecture
|
|
67
|
-
stub: true
|
|
68
|
-
---
|
|
69
|
-
```
|
|
40
|
+
- A `## Decisions` H2, or a `Gotchas` section past five bullets or holding a heading or paragraph
|
|
41
|
+
- A `Layout` H3 titled neither a code-spanned path nor `Other folders`, or a heading below H3 under `Layout`
|
|
42
|
+
- A folder H3 past five bullets or its one-paragraph lead
|
|
70
43
|
|
|
71
|
-
|
|
44
|
+
The development entry may carry a `Scripts` H3 exempt from both folder caps. `SHAPE_GATED_FOLDERS` lives in `src/context/shape-gated.ts`.
|
|
72
45
|
|
|
73
|
-
|
|
46
|
+
| Code | Meaning |
|
|
47
|
+
| ---- | ------------------------------------------ |
|
|
48
|
+
| `0` | A clean run, or findings that report |
|
|
49
|
+
| `1` | Refused, with the reason on stderr |
|
|
50
|
+
| `2` | A gating finding for the mode the run took |
|
|
74
51
|
|
|
75
|
-
|
|
52
|
+
- `bun run check` runs `--gate` against every `tooling/<stack>/seeds/` directory carrying a `.claude/` folder
|
|
53
|
+
- A root resolving no audited folder refuses with `1` and warns, a root measuring no entry warns, and a seed short a section fails with `2`
|
|
54
|
+
- A seed omitting a required section on purpose sets `stub: true` in its frontmatter. Only the value `true` counts, and both install paths strip the field.
|
|
76
55
|
|
|
77
|
-
The citation check
|
|
56
|
+
The citation check skips fenced blocks, fixture and harness trees including `*.test.ts`, and a path into a folder the project lacks.
|
|
78
57
|
|
|
79
|
-
|
|
58
|
+
Append `<!-- audit-ignore-citations: <path> -->` to a line that displays a path without pointing at it. The marker excuses only the paths it names, and a bare `<!-- audit-ignore-citations -->` excuses every citation on the line. In seeds, plugin skill bodies, and stack references, which install into a target, reword the line instead.
|
|
80
59
|
|
|
81
|
-
|
|
60
|
+
## Refusals
|
|
82
61
|
|
|
83
|
-
|
|
62
|
+
- No requested `--folder` name resolves, with the names under `unresolvedFolders`
|
|
63
|
+
- `--citations-only` together with `--gate`
|
|
64
|
+
- `--citations-only` over folders that all resolved at the project root, which is out of scope
|
|
84
65
|
|
|
85
|
-
|
|
66
|
+
## See also
|
|
86
67
|
|
|
87
|
-
|
|
68
|
+
- `markdown-audit.md`: depth and bullet weight, which this audit no longer measures
|
|
69
|
+
- `audits.md`: the aggregate that runs this audit
|
package/docs/agents/index.md
CHANGED
|
@@ -8,60 +8,14 @@ category: Agent surface
|
|
|
8
8
|
|
|
9
9
|
CLI catalog and invocation rules for agents, split by command domain. Start with overview.
|
|
10
10
|
|
|
11
|
-
- [Audits](audits.md): Running every health check as one set,
|
|
12
|
-
- [
|
|
13
|
-
- [Capture](capture.md): Rendering HTML sources to PNG, what the command asserts about fonts, and why the selector has no default
|
|
14
|
-
- [Census](census.md): Tracked-plus-untracked file count, a breakdown by extension, and a line total that skips whatever reads as binary
|
|
15
|
-
- [Comments](comments.md): Comment density by language and kind, the two structural exclusions, and how the degradation sweep finds its vocabulary
|
|
16
|
-
- [Context audit checks](context-audit-checks.md): What each non-gating check reports, the unit each checkpoint is measured in, the requirements record's word cap, which folders each check reaches, and what moved to the attribute tier
|
|
17
|
-
- [Context audit](context-audit.md): Running the audit, its flags and folder scope, the exit codes, the citation gate, and the widened gate the seed stage runs
|
|
18
|
-
- [Doc classifier](context-classify.md): Classifying canonical-doc content as keep, replace/rewrite, history, or move in diff and sweep mode, the classifier setting pair, the record shape, and the exit codes
|
|
19
|
-
- [Self-stated counts](counts.md): Reading a sentence that asserts a closed catalog's size, how a match is decided, the plausibility filter that keeps a generic word from matching a subset, and why the sweep reports rather than gates
|
|
20
|
-
- [Demo](demo.md): Compiling a screencast draft into a runnable plan, driving a served application to a recording and a still, reading numbered frames back out of a recording, the pointer the recording paints, and what each refusal reports
|
|
21
|
-
- [Driver](driver.md): Walking a page through named interactions, the probe catalog and the false finding each one carries, why viewport heights are never defaulted, and what each refusal reports
|
|
22
|
-
- [Merge gate](gate.md): Running the gate this repository verifies a branch with, what the stage table holds and what stays a script, how the changed set scopes three stages, and why a stage that cannot read its input reports rather than passing
|
|
23
|
-
- [Hooks](hooks.md): Running the post-merge steps through one verb, the order and the child call behind each, the root and working directory each step reads, the skip switches, the line each record maps to, and the reply link check
|
|
11
|
+
- [Audits](audits.md): Running every health check as one set, the verdict and exit codes, the corpus states, the retained baseline and its delta, and a catalog of every audit verb with whether a finding gates
|
|
12
|
+
- [Context audit](context-audit.md): Running the context audit, its folder scope, the exit codes, every check with the folders it reaches and whether it gates, the seed gate, and the citation exclusions
|
|
24
13
|
- [Indexes](indexes.md): How canon indexes regen and canon indexes list resolve paths, what they stage, and the record and exit codes each emits
|
|
25
14
|
- [Install and sync](install-and-sync.md): What each install and sync verb writes, refuses, or leaves alone, the drift report and its seven side sections, the rule detection record, and version skew states
|
|
26
|
-
- [
|
|
27
|
-
- [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
|
|
28
|
-
- [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
|
|
29
|
-
- [Markdown audit density](markdown-audit-density.md): The six layout limits the markdown audit measures, what each one counts, which paths take a finding, and how a folder's gate turns on
|
|
30
|
-
- [Markdown audit weight](markdown-audit-weight.md): The advisory sections 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 which of those numbers gate through density
|
|
31
|
-
- [Markdown audit](markdown-audit.md): Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, how a reference page opts into its shape check, and why bans, dead links, and density or reference shape on a gated path fail while the rest reports
|
|
15
|
+
- [Markdown audit](markdown-audit.md): Running the markdown audit over any path, each finding it reports with whether it gates, the six density limits, the advisory measures, the exit codes, and where the audit runs
|
|
32
16
|
- [Migrate](migrate.md): What each canon migrate verb moves, the markers that keep an old spelling, and what each one refuses
|
|
33
17
|
- [Output shape](output-shape.md): The framed output shape every command renders into, the JSON and color modes, the exit discipline, the runtime catalogs, and a headless invocation per domain
|
|
34
18
|
- [Overview](overview.md): What this folder covers, the invocation rules every command inherits, and how canon docs resolves a topic name
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [The pull request frame store](pr-frames.md): How canon pr frames pushes a UI review frame to a never-merged branch through the GitHub API and returns a branch-path link, which ref it writes, the pass segment that keeps an earlier image fixed, the refusal reasons it names, and how --drop and --prune rewrite the branch so a dropped frame leaves history
|
|
38
|
-
- [The pull request draft lift](pr-lift.md): How canon pr lift removes the draft mark once the reviews, evidence, standing, and CI all read clear at the head, the gate order and what each reads, the wait on a pending run, the re-read before the write, the refusal reasons it names, and what --check reports
|
|
39
|
-
- [The pull request local preview](pr-local.md): How canon pr local finds the server a worktree is running, why a server in another worktree is never reported, the refusal reasons it names, and how a close workflow drops the address line with --remove
|
|
40
|
-
- [The pull request preview deploy](pr-preview.md): How canon pr preview finds a fenced Cloudflare Pages deploy, refuses a branch its push filter does not serve, dispatches it on a pull request's branch, reads the alias the run prints, the refusal reasons it names, and why an unfenced deploy is refused before anything runs
|
|
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
|
-
- [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
|
-
- [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): Counting the releases since the requirements record was last reviewed, where the review date is read from, and the exit codes and refusals
|
|
45
|
-
- [Records validate](records-validate.md): Validating the session records, the per-kind checks, which root they default to, the exit codes, and the refusal reasons
|
|
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
|
-
- [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
|
-
- [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
|
-
- [Rule citations](rule-citations.md): Resolving every path a governance rule cites and every frontmatter glob the internal corpus declares, the one form 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
|
|
50
|
-
- [Sandbox](sandbox.md): Scenario routing, the expectation scoring surface, and the coverage census over scenarios and skills
|
|
51
|
-
- [Sessions transfer](sessions-transfer.md): Moving a session to another machine, the export bundle and its manifest, placing it with import, the refusal reasons, and what a resume on the target depends on
|
|
52
|
-
- [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds, reading which row is the caller, the liveness confidence field, what each session surface can see, and where moving a session to another machine is described
|
|
53
|
-
- [Skill audit](skills-audit.md): Measuring both skill corpora against the skill standards, the checks it reads, the requirement gate that is the only failing one, and the drift verb that names bodies rewritten since a ref
|
|
54
|
-
- [Citation reach](skills-reach.md): Reporting the skill bodies that cite a path no target project receives, which corpus the verb reads, the ownership key that decides what counts, the one-word qualifier that marks a citation as decided, and why the verb reports instead of gating
|
|
55
|
-
- [Slides](slides.md): Where a deck folder lives and what it holds, what it declares for the whole deck in deck.json, the faces it embeds, what each slide declares on its own body, transitions and entrances, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
|
|
56
|
-
- [State-scoped risk](state-scoped-risk.md): Reading committed state rather than an arriving change, the shipped-tree corpus the secret scan reads, what it keys on and how a deliberate value is exempted, the advisory check and its network failure mode, and why one gates while the other reports
|
|
57
|
-
- [Superseded values](superseded.md): Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the family stem behind a templated citation, the exemption marker, the blind spots it cannot reach, and why it reports rather than gates
|
|
19
|
+
- [Records](records.md): Backing the record folders to a private remote, restoring them on a new machine, reading folder size, and pruning stale scratch
|
|
20
|
+
- [Sessions transfer](sessions-transfer.md): Moving a session to another machine with export and import, the manifest fields, the refusal reasons, and what a resume on the target depends on
|
|
58
21
|
- [Targets](targets.md): The projects this toolkit installed into, where each answer comes from, and the cross-target pull request read
|
|
59
|
-
- [Tasks archive](tasks-archive.md): Archiving a shipped task by stem or pull request, declining one decided against, the refusal reasons each carries, and how the plan and ready folder move with the task
|
|
60
|
-
- [Tasks plans](tasks-plans.md): The five verbs that read or write a task's plan, being where it sits and who cites it, whether it waits on the operator, the branch it derives, what a branch reached against what it declared, and writing its Plan line
|
|
61
|
-
- [Tasks validate](tasks-validate.md): Validating the board against the tree, the seven checks, the five report arrays, the exit codes, and the refusal reasons
|
|
62
|
-
- [Tasks](tasks.md): Claiming the next phase label, recording a pull request number and closing an outcome, listing each task's readiness, and where archiving, the plan verbs, and board validation are described
|
|
63
|
-
- [Teach authoring](teach-authoring.md): Resolving what the next lesson needs before it is written, rendering a lesson body's blocks to HTML, and rewriting the root listing, a contents page, and each lesson's chrome and quiz stepper from its marker regions
|
|
64
|
-
- [Teach](teach.md): Listing learning workspaces with what their records schedule next, opening one with its required files, recording sources and glossary terms, viewing one with its chrome refreshed, where the lesson authoring verbs are described, the refusal reasons, and why every write here runs through a verb
|
|
65
|
-
- [Test order](test-order.md): Reading where an implementation reached history ahead of its test, how a pair is decided, the three verdicts, the coverage the pairing cannot reach, and why the check reports rather than gates
|
|
66
|
-
- [Upstream](upstream.md): The fetch, catalog, due, and advance verbs that read Claude Code releases against the toolkit, the cursor record, and each refusal reason
|
|
67
|
-
- [Worktrees](worktrees.md): Reporting which worktrees are reclaimable, removing the ones that are, the hidden verb that clears a stranded bare flag, the record a hook reads back, why the reading keys on the pull request rather than on git ancestry, the refusals it names, and the two removal shapes
|
|
@@ -16,6 +16,7 @@ Any flag skips the confirmation prompt, but the `base` default of `--stack` does
|
|
|
16
16
|
## Governance install
|
|
17
17
|
|
|
18
18
|
- `canon gov install <stack> [target]` needs the stack under `CANON_NON_INTERACTIVE=1`, else lists the valid names on stderr and exits 1
|
|
19
|
+
- `--yes` answers the install confirm with no TTY and no env var. Without it, a headless call refuses and the message names `--yes`. It does not pick a stack.
|
|
19
20
|
- It refuses the toolkit root and a missing path
|
|
20
21
|
- `--add <rules>` with no stack installs into the one positional, or the current directory, keeping the recorded chain. Pass `./node` for a target named like a stack.
|
|
21
22
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Markdown audit
|
|
3
|
-
description: Running the audit over any
|
|
3
|
+
description: Running the markdown audit over any path, each finding it reports with whether it gates, the six density limits, the advisory measures, the exit codes, and where the audit runs
|
|
4
|
+
kind: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Markdown audit
|
|
7
8
|
|
|
8
|
-
`canon markdown audit [path...]` reports any markdown file against the `markdown-craft` skill's `markdown.md
|
|
9
|
+
`canon markdown audit [path...]` reports any markdown file against the `markdown-craft` skill's `markdown.md`. It resolves no folder and needs no `index.md`, so `.claude/rules/` and `governance/` are in reach. Folder-shaped findings belong to `canon context audit`, in `context-audit.md`.
|
|
9
10
|
|
|
10
11
|
```bash
|
|
11
12
|
canon markdown audit
|
|
@@ -15,116 +16,69 @@ canon markdown audit docs/agents/install-and-sync.md
|
|
|
15
16
|
canon markdown audit 'docs/**/*.md'
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
An argument is a file, a directory, or a glob, taken against the corpus git lists. A bare run measures every tracked or untracked-and-not-ignored file. An explicit file is taken as given, so a gitignored draft can be measured, and an argument matching nothing is named on the scope line.
|
|
19
20
|
|
|
20
|
-
##
|
|
21
|
+
## Output
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
The ban set and checkpoints ship in `src/markdown/bans.ts` and `src/markdown/structure.ts`. `markdown.md` states each rule and the `write-human` skill states the cadence numbers, so move a number in both places in one change.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
| Finding | Reports | Gates |
|
|
26
|
+
| --------------- | ------------------------------------------------------------------------------------ | ------------------------- |
|
|
27
|
+
| Bans | The two characters `markdown.md` bans, outside frontmatter, fences, spans, and links | Always |
|
|
28
|
+
| Links | A relative link resolving to nothing on disk | Always |
|
|
29
|
+
| Density | The six limits below, under `density` | On a `GATED_PATHS` prefix |
|
|
30
|
+
| Reference shape | A `kind: reference` page breaking its shape, under `referenceShape` | On a `GATED_PATHS` prefix |
|
|
31
|
+
| Colons | A colon followed by more text in a prose line, under `colons` | Never |
|
|
32
|
+
| Heading case | A capital after the first word of a heading or `title`, under `headingCase` | Never |
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
A page marked `kind: reference` holds its opening, then `Output`, `Refusals`, and `See also` as H2s, each at most once and in that order. It takes no H3 and no table headed `Flag` or `Option`. An unmarked page is never measured.
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
| Density limit | Finding |
|
|
37
|
+
| ------------------- | ---------------------------------------------------------- |
|
|
38
|
+
| Paragraph length | A prose paragraph past 350 characters |
|
|
39
|
+
| Paragraphs in a row | More than 2 paragraphs with nothing else between them |
|
|
40
|
+
| Bullet length | A top-level bullet past 200 characters |
|
|
41
|
+
| Bullets in a row | More than 5 plain top-level bullets |
|
|
42
|
+
| Heading depth | Any heading past H3 |
|
|
43
|
+
| H3 opening | An H3 whose first block is neither a paragraph nor a table |
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
- A paragraph under a list item counts toward that bullet, never as a paragraph
|
|
46
|
+
- A table, fence, list, heading, or bold section marker ends a run of paragraphs
|
|
47
|
+
- A run whose every item opens with a bold label or a link is exempt, and numbered items never count
|
|
48
|
+
- Only context entries, docs, skill bodies and references, tooling seeds and stack references, the wiki, `README.md`, and `CONTRIBUTING.md` take a finding
|
|
49
|
+
- A bullet run gates everywhere those paths sit, and the rest gates under `GATED_PATHS` in `src/markdown/scope.ts`. Outside a canon checkout nothing gates.
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
Five measures report and never set the exit code on their own.
|
|
33
52
|
|
|
34
|
-
|
|
53
|
+
| Measure | Reports | Gate or report |
|
|
54
|
+
| ---------- | ------------------------------------------------------------------------------------ | -------------------------------------- |
|
|
55
|
+
| Bullets | A bullet past 200 characters | Gates through the density length |
|
|
56
|
+
| Paragraphs | A paragraph past 4 sentences or 350 characters | Gates through the density length |
|
|
57
|
+
| Cadence | 3 or more sentences with a spread of 5 words or under, or a word opening more than 2 | Reports |
|
|
58
|
+
| Depth | A run past about 40 rendered lines at 80 columns | Reports |
|
|
59
|
+
| Length | A document past 300 rendered lines, unless it carries `canon-length-exempt` | Reports, and the gate owns the verdict |
|
|
35
60
|
|
|
36
|
-
|
|
61
|
+
| Code | Meaning |
|
|
62
|
+
| ---- | ------------------------------------------------------------------ |
|
|
63
|
+
| `0` | No gating finding |
|
|
64
|
+
| `1` | Refused, with the reason on stderr |
|
|
65
|
+
| `2` | A ban, a dead link, or a gating density or reference shape finding |
|
|
66
|
+
| `3` | The shipped ban set is empty, so nothing was measured |
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
Rewrite the sentence on a ban hit rather than swapping the token. A code span clears the report only where the token is an identifier under discussion.
|
|
39
69
|
|
|
40
|
-
|
|
70
|
+
The audit runs in four places:
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
- `.claude/hooks/standards-audit.sh` after each markdown edit, handing back every finding
|
|
73
|
+
- The `Markdown` stage of `canon gate run`, over the whole corpus
|
|
74
|
+
- `scripts/verify.ts` in a scaffolded project, excluding `CHANGELOG.md` and skipping with a logged line when no `canon` is on `PATH`
|
|
75
|
+
- The seeded hook in a target
|
|
43
76
|
|
|
44
|
-
|
|
77
|
+
## Refusals
|
|
45
78
|
|
|
46
|
-
|
|
79
|
+
- `no-git` or `no-markdown`: no corpus can be built, and the gate reads it as unmeasured
|
|
47
80
|
|
|
48
|
-
|
|
81
|
+
## See also
|
|
49
82
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
A relative link's destination resolves against the filesystem, over the same corpus the ban scan reads. A destination is skipped rather than resolved when it is empty, opens with a URL scheme, opens with `#` as a same-file anchor, opens with `/` as a root-absolute reference, or carries `<` as a template placeholder such as `<slug>` or `<name>`. What remains is split on its first `#`, decoded, and resolved against the linking file's own folder, and a destination resolving to nothing on disk reports.
|
|
53
|
-
|
|
54
|
-
The placeholder exemption is the one live case the corpus needs. Every current instance is a genuine illustration rather than a literal path, and a marker-based override is available for the day a real one needs an exception instead.
|
|
55
|
-
|
|
56
|
-
### Colons and heading case
|
|
57
|
-
|
|
58
|
-
Two advisory measures report beside the bans and never fail a run.
|
|
59
|
-
|
|
60
|
-
The colon measure reports a colon followed by more text in a prose line, outside the label position. A list item's first colon, a bold or code span label, a line-final colon, a time, a URL, and anything inside a code span or a link are left alone. A heading, a table row, and a fenced line are skipped. Each finding carries the line, the column, the line's text, and the word before the colon as `lead` under `colons` in the `--json` entry.
|
|
61
|
-
|
|
62
|
-
The heading-case measure reports a heading or a frontmatter `title` with a capitalized word after its first, outside code spans and all-caps tokens, under `headingCase`. A proper noun reports as well and is left as it is.
|
|
63
|
-
|
|
64
|
-
`CHANGELOG.md` is exempt from both, since the release tool writes its headings.
|
|
65
|
-
|
|
66
|
-
### Density
|
|
67
|
-
|
|
68
|
-
The six layout limits, their scope, and their gate are in `markdown-audit-density.md`.
|
|
69
|
-
|
|
70
|
-
### Reference shape
|
|
71
|
-
|
|
72
|
-
A page opts in with `kind: reference` in its frontmatter, and an unmarked page is never measured. On a marked page, outside fences, an H2 other than `Output`, `Refusals`, or `See also` reports, as does one repeated or out of that order, any H3, and a table headed `Flag` or `Option`.
|
|
73
|
-
|
|
74
|
-
Each finding sits under `referenceShape` in the `--json` entry with `kind`, `line`, `text`, and `gating`. It gates under the prefixes density gates on.
|
|
75
|
-
|
|
76
|
-
### Weight, cadence, and length
|
|
77
|
-
|
|
78
|
-
The Bullets, Paragraphs, Cadence, Depth, and Length sections report and never set the exit. The bullet and paragraph numbers gate through the density lengths instead, and depth and cadence stay a judgment a reader settles. What each section measures and the samples behind its checkpoint are in `markdown-audit-weight.md`.
|
|
79
|
-
|
|
80
|
-
## Exit codes
|
|
81
|
-
|
|
82
|
-
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, `2` for a ban hit, a dead relative link, or a density or reference shape finding marked `gating`, and `3` for a shipped ban set that arrived empty. All three are facts a scan settles rather than a reader judging. Depth weight is a judgment a reader settles, and cadence is a distribution whose healthy range moves with the surface, so both report under every code, as do the advisory Bullets and Paragraphs sections. Length reports the same way, since the audit also runs on a plan kept out of version control, and the Document ceiling stage in `canon gate run` owns that verdict instead.
|
|
83
|
-
|
|
84
|
-
`3` is separate from `1` because the two want different responses from a caller. A refusal means no corpus was built, and the `Markdown` stage in `canon gate run` is right to report it as unmeasured rather than as a pass. An empty set means the corpus was walked and nothing was looked for, so that stage fails the push on `3` rather than skipping.
|
|
85
|
-
|
|
86
|
-
`2` rather than `1` for the gate keeps a measurement that succeeded and found something distinct from the audit declining to measure at all. A caller reading one as the other sends a reader hunting a defect that does not exist, which is the distinction `canon context audit` and the gate's own seed stage already draw between the same two codes.
|
|
87
|
-
|
|
88
|
-
A banned character is a fact rather than a judgment, which is the test that admits it to a gate. What held it back was that gating on day one against a corpus never checked mechanically fails loudly on work nobody has had a chance to fix. The order was to land the verb reporting, measure the corpus once, fix what it finds, and turn the gate on as its own change, and the gate is the last of the four.
|
|
89
|
-
|
|
90
|
-
Of the five measures a first full reading took, the ban count is the only one a gate should ever read.
|
|
91
|
-
|
|
92
|
-
The ban half reached zero, which was the precondition the gate waited on, and it was re-measured against the same corpus at the moment the gate landed. Three sweep slices then took the structural half, and the corpus reports 1 heavy bullet and 22 heavy paragraphs across 6 files on 2026-08-06, every one on a ground the triage record holds as exempt.
|
|
93
|
-
|
|
94
|
-
### What a hit asks of an author
|
|
95
|
-
|
|
96
|
-
Rewrite the sentence rather than swapping the banned token for a near-synonym. The rule is about the sense the token carries, so a swap that keeps the sense clears the report without clearing the violation.
|
|
97
|
-
|
|
98
|
-
A code span clears the report too, since the ban scan walks around one, and it is the answer only where the token is genuinely an identifier under discussion. `## Code and identifiers` in `markdown.md` reserves the span for commands, API names, file paths, and identifiers, so backticking a quoted utterance spends one rule to satisfy another and leaves the corpus no cleaner.
|
|
99
|
-
|
|
100
|
-
A hit the closed set could not separate from correct prose was the case with no third option while the set still carried words. The temporal `just` reported as the vague qualifier it happened to spell, and rewriting the sentence is what the toolkit settled on over building an exemption path, since an exemption landing in the verb and not the edit hook leaves the line failing where an author actually meets it. That class is part of why the words left the gate.
|
|
101
|
-
|
|
102
|
-
### Where the rules are enforced
|
|
103
|
-
|
|
104
|
-
Four surfaces apply the ban set and all four go through this verb. `.claude/hooks/standards-audit.sh` runs it against a single file after each markdown edit, the seed copy a project installs does the same, the `Markdown` stage in `canon gate run` runs it across the whole corpus before this repository's own push, and the same-named stage in the one verify runner every stack shares, `scripts/verify.ts`, runs it across a scaffolded project's tracked markdown before its own push. Each hook parsed its own copy of the word bans in awk before that, which left a British spelling passing at edit time and failing the push with nothing in between explaining the difference.
|
|
105
|
-
|
|
106
|
-
The seed copy moved onto the verb when the sets became data, since its awk had nothing left to parse. It resolves one runner where the toolkit copy resolves two, looking for no checkout source, and a machine carrying no `canon` gets a report naming the binary to install rather than a silent pass. The Seed independence stage of `bun run check` scopes its walk to markdown and leaves the seed hooks outside it, which its own comment records as deliberate.
|
|
107
|
-
|
|
108
|
-
The target push stage reads the same exit codes `canon gate run`'s own stage reads: 0 passes, 1 is a refusal logged as a skip, 2 is a finding, and 3 is a shipped-empty ban set. It skips and logs rather than failing when no `canon` binary is on the machine's PATH, since a scaffolded project is not guaranteed the toolkit is installed, and its skip line names the install command.
|
|
109
|
-
|
|
110
|
-
The target push stage excludes `CHANGELOG.md`, unlike every other surface here. A changelog a generator builds from commit subjects carries prose nobody wrote against the ban set, where this repository's own passes only because `release-please` builds it from subjects sessions already wrote to the rule. The stage passes an explicit file list rather than the bare invocation the other surfaces use, so a corpus with no file left once the changelog is set aside reads as a pass rather than falling back to the whole tree.
|
|
111
|
-
|
|
112
|
-
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies. It reads `bans.emptySets` out of the same record, so a set the verb shipped empty reaches the author as a check narrowed to what it could measure rather than as a clean pass.
|
|
113
|
-
|
|
114
|
-
It relays every density finding from the same record, gating or not, and the two advisory measures. A heading finding reports for the whole file, and a colon finding reports only where the word before the colon and the colon appear in the text the write carried, so an edit is never asked to answer for a colon it left untouched.
|
|
115
|
-
|
|
116
|
-
That field replaced `bans.missingStandards`, which answered a standard resolving under none of three roots. The set ships with the package now, so the state it named cannot occur and the narrowed check has one cause left, a defect in the build. The hook keeps reading a field either way, since a reader cannot tell a narrowed check from a clean one without it.
|
|
117
|
-
|
|
118
|
-
Both hooks answer an absent record as well. A completed run always writes the record and a refusal writes none, so an empty one means the verb declined to measure rather than measured and found nothing. The verb needs a git repository to build its corpus and refuses without one, which is a project the seeded hook can be installed into, and reading the findings alone reported that as a clean file.
|
|
119
|
-
|
|
120
|
-
A machine with neither runner still blocks no edit, and it says so rather than exiting clean. The push stage holds either way. An edit nobody checked and an edit carrying no violation are one silence to a reader, so the enforcement a machine lacks is reported rather than inferred.
|
|
121
|
-
|
|
122
|
-
The stage measures the whole corpus rather than the changed files. A `Do not use` bullet added to a reference bans a token retroactively, and no file in the push that adds the bullet was edited.
|
|
123
|
-
|
|
124
|
-
## What it does not cover
|
|
125
|
-
|
|
126
|
-
The verb reads the `markdown-craft` skill's reference and the `write-human` cadence numbers and nothing else. The references the `git-pr`, `git-branch`, and `git-commit` skills own, `publish.md`, `slug.md`, and `versioning.md`, govern an attribute of other artifacts, and none of them is implemented here.
|
|
127
|
-
|
|
128
|
-
`publish.md` describes a scan applying the same punctuation bans to finished text on its way out. No code implemented that scan before this command, so nothing is duplicated, and a later surface should call this verb rather than build a second one.
|
|
129
|
-
|
|
130
|
-
That reference's cross-reference rule is out of reach rather than merely unimplemented. It resolves by destination, bare where the destination auto-links a pull request or issue number and backticked where it does not, so this verb sees only the half where the backticked form is correct. A check here would report every compliant reference in the tree and reach none of the published text that goes wrong, which is why the rule holds on reading alone.
|
|
83
|
+
- `context-audit.md`: the folder-shaped findings
|
|
84
|
+
- `audits.md`: the aggregate that runs this audit
|
package/docs/agents/records.md
CHANGED
|
@@ -1,103 +1,61 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Records
|
|
3
|
-
description:
|
|
3
|
+
description: Backing the record folders to a private remote, restoring them on a new machine, reading folder size, and pruning stale scratch
|
|
4
|
+
kind: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Records
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Every verb here resolves a record folder at two roots rather than one. `.canon/<folder>` is read first, `.claude/<folder>` second, and a folder neither root carries resolves to the creation default, which is `.canon/`. The scratch folder is the one name that differs by root, spelled `.canon/tmp` and `.claude/.tmp`, since inside a dotted root the leading dot hides nothing already hidden. <!-- canon-keep-record-root -->
|
|
11
|
-
|
|
12
|
-
The read order and the creation default agree. While the record folders were moving to a root of their own, creation stayed at `.claude/` so no record landed under a root whose ignore line had yet to reach a project. The ignore line ships now, so a fresh project scaffolds `.canon/` alone, and `.claude/` stays as a read fallback for a project the move has not reached.
|
|
13
|
-
|
|
14
|
-
A caller never spells a record root by hand for the same reason. A path written as `.canon/plans/...` resolves against one root and reports nothing when it is wrong, which is the quiet failure this ordering exists to prevent: a stale binary meeting a moved layout, writing to the old path, and reporting success. Read a folder through the verb that owns it, and where a skill needs the path itself, take it from that verb's record rather than composing one.
|
|
15
|
-
|
|
16
|
-
A refusal names every root it looked at, so a message reading `no-folder` says where a write would land as well as where the read failed.
|
|
17
|
-
|
|
18
|
-
## Validate
|
|
19
|
-
|
|
20
|
-
`canon records validate <kind>` reports where a record folder disagrees with the standard governing it. Its flags, the per-kind checks, and the refusals are in `records-validate.md`.
|
|
21
|
-
|
|
22
|
-
## Ordinal
|
|
23
|
-
|
|
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.
|
|
9
|
+
`canon records` backs the record folders under `.canon/` to a private remote and reports on them. `canon hooks post-merge` runs `push` after every merge.
|
|
25
10
|
|
|
26
11
|
```bash
|
|
27
|
-
canon records
|
|
28
|
-
canon records
|
|
29
|
-
canon records ordinal groundwork my-topic --claim --json
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
| Option | Behavior |
|
|
33
|
-
| --------------- | ------------------------------------------------------ |
|
|
34
|
-
| `--json` | Add a machine-readable record on stdout |
|
|
35
|
-
| `--claim` | Create the folder atomically instead of only reporting |
|
|
36
|
-
| `--root <path>` | Project root, defaulting to the main worktree |
|
|
37
|
-
|
|
38
|
-
Without `--claim` this only reports, so two sessions reading at once can still report the same number, which is what let two sessions open two different record folders under one ordinal on the same day. `--claim` closes that: it reserves the number at a path both an `intake` claim and a `groundwork` claim resolve to identically, whichever kind is asking, and only creates the kind's own `<nn>-<slug>/` folder once that reservation is won. A losing reservation is retried against a freshly read ordinal rather than reported as a collision, bounded to five attempts before refusing as `ordinal-contended`.
|
|
39
|
-
|
|
40
|
-
Exit codes: `0` reported the next ordinal, or `--claim` created the folder. `1` refused, `unknown-kind` when the argument names neither `intake` nor `groundwork`. `2` `--claim` lost every retry to a collision.
|
|
41
|
-
|
|
42
|
-
## Size
|
|
43
|
-
|
|
44
|
-
`canon records size` reports what each record folder holds and how much of it is recent. It reads the same backed folders push carries, resolved the same way, plus the scratch folder, and it gates nothing.
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
canon records size
|
|
12
|
+
canon records push
|
|
13
|
+
canon records pull
|
|
48
14
|
canon records size --json
|
|
15
|
+
canon records prune-tmp --older-than 30
|
|
49
16
|
```
|
|
50
17
|
|
|
51
|
-
|
|
52
|
-
| --------------- | --------------------------------------------- |
|
|
53
|
-
| `--json` | Add a machine-readable record on stdout |
|
|
54
|
-
| `--root <path>` | Project root, defaulting to the main worktree |
|
|
55
|
-
|
|
56
|
-
The table carries one row per folder that exists, heaviest first, with the file count, the bytes, a count for each growth window, and the dates of the least and most recently written file. Those dates render in the machine's local time, which is the calendar day whoever wrote the file was living in, and the reading is per-machine already. Folders that do not exist are named on one line below it rather than printed as rows of zeros. At the legacy `.claude` root, the record a `--json` call emits carries every folder in the fixed list either way, each with a `present` flag, so a caller reading the record gets a stable set of keys and can tell an absent folder from one the reading skipped. At a `.canon` root, the folder set is read off the directory itself rather than off a fixed list, so an absent folder is not listed at all: nothing enumerates a name nobody has created yet.
|
|
57
|
-
|
|
58
|
-
Ordering by weight is what makes the reading worth taking. A folder listed alphabetically hides behind its neighbors, and the row a reader came for is the one that grew.
|
|
59
|
-
|
|
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.
|
|
18
|
+
Run `canon records <verb> --help` for every flag.
|
|
61
19
|
|
|
62
|
-
|
|
20
|
+
## Output
|
|
63
21
|
|
|
64
|
-
|
|
65
|
-
|
|
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.
|
|
67
|
-
|
|
68
|
-
Exit codes: `0` the reading completed, `1` refused. The one refusal is `no-folder`, raised when the project holds neither record root. A project holding a root and no records is empty rather than absent: at the legacy `.claude` root each folder's own `present` flag says which ones it carries, and at a `.canon` root the folder list itself is already the answer, since nothing absent is named.
|
|
69
|
-
|
|
70
|
-
## Prune
|
|
71
|
-
|
|
72
|
-
`canon records prune-tmp` reports scratch nobody has touched inside an age window, and deletes it only with `--write`. Nothing removed an abandoned scratch folder before this, so a spike folder from months ago sat beside the ones a session still needs.
|
|
22
|
+
Set the history up once per machine, pointed at a private repository that is not a remote of the project.
|
|
73
23
|
|
|
74
24
|
```bash
|
|
75
|
-
canon
|
|
76
|
-
canon
|
|
77
|
-
canon
|
|
25
|
+
git --git-dir=.canon/.records.git init
|
|
26
|
+
git --git-dir=.canon/.records.git remote add origin <private-repo-url>
|
|
27
|
+
printf '.canon/\n' >> .gitignore
|
|
78
28
|
```
|
|
79
29
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
| `--older-than <days>` | Age a unit's newest file must clear to be offered (default 14) |
|
|
85
|
-
| `--root <path>` | Project root, defaulting to the main worktree |
|
|
86
|
-
|
|
87
|
-
A candidate is a unit whose newest file is older than the threshold: a `tmp/<slug>/` folder, a folder one level inside `runs/`, `render/`, or `pr/`, or a single marker file inside `hooks/<hook>/`. `pr/review/` groups its body files by pull request number rather than reporting as one folder, since a review pass leaves one file per pass and a folder holding thousands of them would otherwise report as a single row nobody can prune apart. A unit holding no files, empty subfolders included, is offered whatever its age.
|
|
88
|
-
|
|
89
|
-
`tmp/handoff/` and `tmp/pr/poll/` are never offered. A reader deletes a handoff themselves once it has been read, and a poll baseline is live state rather than scratch. The pre-split names the reserved split replaced, `memory-routing/`, `teach-promotion/`, `ui-checklist/`, and `pr-poll/` at the scratch root, are skipped the same way on a project the rename never reached, naming the folder they moved to, rather than being offered as ordinary slugs. An unread handoff is the one thing a wrong delete here loses for good.
|
|
30
|
+
- `push` commits every top-level folder under `.canon/` except `tmp`, `ordinal-locks`, and `.records.git`, then pushes. New folders list under `added`.
|
|
31
|
+
- `pull` restores the folders on a new machine after the setup above. It refuses rather than overwrite records the history lacks.
|
|
32
|
+
- `size` reports one row per folder, heaviest first, with file count, bytes, and growth over 7 and 30 days. After a `pull` every file reads as new.
|
|
33
|
+
- `prune-tmp` lists scratch untouched for 14 days and deletes it only with `--write`. It never offers `tmp/handoff/` or `tmp/pr/poll/`.
|
|
90
34
|
|
|
91
|
-
|
|
35
|
+
`push` blocks a file over 25 MB or one `canon secrets scan` would report, listing it under `blocked`. Move it out of the record folders, then push again.
|
|
92
36
|
|
|
93
|
-
|
|
37
|
+
Every verb exits `0` when done and `1` when refused. `prune-tmp` exits `2` when candidates exist and `--write` was not passed.
|
|
94
38
|
|
|
95
|
-
|
|
39
|
+
## Refusals
|
|
96
40
|
|
|
97
|
-
|
|
41
|
+
Branch on `reason` in the `--json` record, not the exit code.
|
|
98
42
|
|
|
99
|
-
|
|
43
|
+
| Reason | Meaning |
|
|
44
|
+
| ------------------- | ------------------------------------------------------------------------------ |
|
|
45
|
+
| `no-folder` | The project holds neither record root, from `size` or `prune-tmp` |
|
|
46
|
+
| `split-roots` | Record folders sit under both roots. Finish the move or put them back together |
|
|
47
|
+
| `no-repository` | No `.canon/.records.git`. Run the setup above |
|
|
48
|
+
| `no-remote` | The records history has no `origin` |
|
|
49
|
+
| `remote-unreadable` | The project's own remotes could not be read |
|
|
50
|
+
| `remote-shared` | The records origin is also a remote of the project. Use a private repository |
|
|
51
|
+
| `no-remote-records` | `pull` found no branch on the records origin |
|
|
52
|
+
| `local-changes` | `pull` found records on disk that the history lacks. Run `push` first |
|
|
53
|
+
| `local-ahead` | `pull` found local commits that never reached the origin. Run `push` first |
|
|
54
|
+
| `unsafe-payload` | `push` found a file over 25 MB or carrying a credential |
|
|
55
|
+
| `git-failed` | A git call failed, with its stderr in the message |
|
|
100
56
|
|
|
101
|
-
##
|
|
57
|
+
## See also
|
|
102
58
|
|
|
103
|
-
|
|
59
|
+
- `canon records ordinal <kind> <slug> --claim`: reserve the next intake or groundwork ordinal
|
|
60
|
+
- `canon records validate <kind> --help`: where a record folder disagrees with its standard
|
|
61
|
+
- `canon records stale --help`: when the requirements record was last reviewed
|