rv
reads the branch it did not write
canon:review-pr canon is a CLI and Claude Code plugin that stops your AI conventions drifting apart across repositories. Below is one real session it ran on itself.
Install canon Read the session
your project today
whatever each repo happened to grow
after one command
in this order
and two it never copies
One repository is the authoritative copy. Every other project installs it.
operatoryou
“Add a light theme to the design tokens and ship it”
Nothing was configured for this ask.
3 of 60 rules match this path
A rule installs as a file the project owns, and it loads into a Claude session when a matching path is edited, and not before.
edited
src/design/tokens.ts
39 rules did not match it. 18 carry no glob and load every session.
Require a dependency to be declared in the manifest before it is imported
matched **/*.ts Decide when a code comment should exist and what it may claim
matched **/*.ts Enforce strict TypeScript type safety and patterns
matched **/*.ts One skill loaded, out of 87 in the catalog
Skills call the CLI and never reimplement it.
1 of 87 canon gov list --json no rule named in the body canon gov sync The skill body names no rule, no stack and no snippet. It asks, matches, and delegates.
canonplan
One plan, written once, and then the planner stops
The plan file is a planner’s only write, and it is decision-ready in one pass.
One controller, and the sessions it launches
Nothing here is one agent talking to itself. The controller holds the plan and launches a session per track.
canon:role-orchestrator canon:role-planner Asserts the planner role for a session writing one plan under one task, holding what it reads before deciding, the surfaces it may not write, and what it hands back.
canon:role-worker Asserts the worker role for a building session, holding the boundary set, the lifetime, and the two channel obligations a session owes whoever dispatched it.
A dispatch is a separate process rather than a subagent, so each session is steerable, survives the one that launched it, and opens its own pull request.
Three workers and a planner, on disjoint file sets
Each takes its own worktree, its own branch and its own pull request. No fixed number caps the tracks.
src/design/ #1699 merged web/src/styles/ #1703 merged assets/captures/ #1705 open .canon/plans/ no branch plan written, no branch Four sessions, four worktrees. The file sets are disjoint, so none of them collided, and nothing caps the number of tracks.
No behavior reaches history ahead of its test
What a worker does inside its own branch, before anything is shown to anyone.
Write the test for a behavior before the code that implements it. Confirm visual output after implementing it, not before.
governance/rules/core/070-planning.mdinstalled into every project that syncs governance
The order is enforced rather than advised. canon gov test-order reads the branch before it ships and names anything that reached history ahead of its test.
What the session learned outlives the session
The last thing a session does is decide what it learned and where that belongs.
canon:memory-captureruns at the close of a session, before anything is lost
Folded into the entry the three-tier model already loads on demand.
The pen keeps only what no context entry owns, which is what the rule calls the residue.
Routing is the point and the memory file is the fallback. A fact about a domain written to the pen instead lands in a folder nothing opens.
canonreview
Reviewing #1699 from a session that did not write it
The review attaches what the change actually looks like, as a comment on the pull request.
canon pr evidenceposted by git-pr, re-posted by git-followup#1699
99ab3bd4
78822c31
Rendered by canon design render from each side of the merge, at one viewport and one crop, so the only thing that differs is the tokens.
Reviewed by a session that did not write it
Review is an exchange rather than a verdict, and it closes.
A finding posted on the pull request outlives both sessions, which is what an orchestrator and a worker need when neither is still running at merge.
canonmerge
Merged, with every step a fact rather than a claim
A tick is something a session says. A merge is something the trunk shows.
canon tasks archive canon records push canon worktrees reclaim A tick is a claim a session makes. A merge is a fact the trunk shows, and only the second fires this.
The tokens that merge landed, as this page renders them
Rendered from canon/DESIGN.md by canon design render at build time, and embedded live rather than captured.
Four sessions built it, one reviewed it
No step was claimed by a session that did not run it.
.canon/plans/ #1699, merged #1703, merged #1705, still open the pull request Three steps to put it in a project
The CLI and the plugin install once per machine. The third step writes files your repository owns from then on.
Several skills call the canon CLI to read catalogs and run installs.
bun install --global @erclx/canon Add the marketplace, then install the Claude Code plugin.
claude plugin marketplace add https://github.com/erclx/canonclaude plugin install canon@canon canon init installs base tooling configs, Claude seeds, and governance rules in one pass.
canon init Two surfaces, and that session reached into both
The lit names are the ones it used. The rest was there and was not needed.
40 commands 8 used
87 skills 10 used
The rules and the tooling are copied into your project and become yours to edit. The skills and the standards are never copied at all, so a fix reaches every project at once and neither can drift.