@erclx/canon 5.34.0 → 5.36.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 +15 -17
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/REQUIREMENT.md +1 -1
- package/claude/skills/auto-ship/references/draft-mark.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +12 -12
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +2 -2
- package/claude/skills/canvas-board/references/design.md +53 -36
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -1
- package/claude/skills/codebase-layout/SKILL.md +2 -2
- package/claude/skills/create-rule/REQUIREMENT.md +6 -8
- package/claude/skills/create-rule/SKILL.md +8 -8
- package/claude/skills/create-rule/references/rule.md +11 -23
- package/claude/skills/create-skill/SKILL.md +2 -1
- package/claude/skills/create-skill/references/skill-paths.md +12 -15
- package/{standards/standard.md → claude/skills/create-skill/references/skill-reference.md} +50 -45
- package/claude/skills/create-skill/references/skill.md +9 -3
- package/claude/skills/design-taste/REQUIREMENT.md +6 -6
- package/claude/skills/design-taste/SKILL.md +2 -2
- package/claude/skills/design-taste/references/craft.md +1 -1
- package/claude/skills/design-taste/references/preflight.md +2 -2
- package/claude/skills/design-taste/references/tells.md +1 -1
- package/claude/skills/draft-and-pick/SKILL.md +1 -1
- package/claude/skills/draft-identity/SKILL.md +3 -2
- package/claude/skills/git-commit/references/versioning.md +13 -13
- package/claude/skills/git-pr/SKILL.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/markdown-craft/references/markdown.md +3 -2
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/review-address/REQUIREMENT.md +1 -1
- package/claude/skills/review-address/SKILL.md +2 -2
- package/claude/skills/review-craft/references/ui.md +1 -1
- package/claude/skills/review-pr/SKILL.md +3 -3
- package/claude/skills/review-pr/references/post.md +1 -1
- package/claude/skills/review-ui/REQUIREMENT.md +1 -1
- package/claude/skills/review-ui/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +2 -2
- package/claude/skills/role-orchestrator/SKILL.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +3 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -8
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +10 -4
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +11 -12
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +12 -15
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +6 -4
- package/claude/skills/role-orchestrator/scripts/poll.ts +50 -1
- package/claude/skills/role-reviewer/REQUIREMENT.md +17 -7
- package/claude/skills/role-reviewer/SKILL.md +17 -10
- package/claude/skills/role-worker/REQUIREMENT.md +1 -1
- package/claude/skills/role-worker/SKILL.md +6 -6
- package/claude/skills/session-compact/references/handoff-note.md +1 -1
- package/claude/skills/target-setup/SKILL.md +2 -2
- package/claude/skills/target-setup/references/detect.md +3 -3
- package/claude/skills/test-craft/SKILL.md +2 -2
- package/claude/skills/ux-audit/REQUIREMENT.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +2 -2
- package/claude/skills/ux-measure/REQUIREMENT.md +1 -1
- package/claude/skills/write-human/references/machine-tells.md +12 -0
- package/docs/agents/audits.md +1 -1
- package/docs/agents/commands.md +14 -13
- package/docs/agents/comments.md +1 -1
- package/docs/agents/counts.md +5 -6
- package/docs/agents/drift-surfaces.md +15 -19
- package/docs/agents/gov-detect.md +1 -1
- package/docs/agents/index.md +2 -3
- package/docs/agents/install-and-sync.md +10 -34
- package/docs/agents/markdown-audit.md +22 -12
- package/docs/agents/migrate.md +1 -1
- package/docs/agents/output-shape.md +1 -1
- package/docs/agents/overview.md +2 -2
- package/docs/agents/records-stale.md +1 -1
- package/docs/agents/records-validate.md +11 -23
- package/docs/agents/records.md +1 -1
- package/docs/agents/routing.md +1 -1
- package/docs/agents/rule-citations.md +9 -17
- package/docs/agents/scripting.md +2 -20
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/tasks-validate.md +1 -1
- package/docs/agents/teach.md +1 -1
- package/docs/target/index.md +1 -0
- package/docs/target/migrations.md +4 -0
- package/docs/target/projects.md +10 -10
- package/docs/target/scenarios.md +5 -6
- package/docs/target/standards-moved.md +32 -0
- package/docs/target/sync.md +5 -5
- package/docs/workflow/ai-workflow.md +1 -1
- package/docs/workflow/operating-model.md +16 -18
- package/docs/workflow/skill-map.md +1 -1
- package/docs/workflow/visual-design-workflow.md +3 -3
- package/governance/detect.toml +32 -36
- package/governance/renames.toml +44 -1
- package/governance/rules/lib/{305-e2e-reliability.md → e2e-reliability.md} +1 -1
- package/governance/rules/lib/{306-test-scope.md → test-scope.md} +2 -2
- package/governance/rules/ui/{410-a11y.md → a11y.md} +1 -1
- package/governance/rules/ui/{440-surface-capture.md → surface-capture.md} +3 -3
- package/governance/stacks/base.toml +15 -8
- package/governance/stacks/go.toml +2 -0
- package/governance/stacks/node.toml +1 -1
- package/governance/stacks/php.toml +2 -0
- package/governance/stacks/python.toml +1 -1
- package/package.json +1 -4
- package/scripts/core/install-check.sh +4 -10
- package/src/audits/catalog.ts +0 -9
- package/src/capture/frame-values.ts +3 -6
- package/src/claude/routing.ts +1 -1
- package/src/claude/skills-reach.ts +4 -6
- package/src/cli/help-all.ts +96 -0
- package/src/cli/help.ts +29 -29
- package/src/cli.ts +8 -3
- package/src/commands/claude.ts +29 -0
- package/src/commands/design.ts +22 -1
- package/src/commands/gov.ts +29 -11
- package/src/commands/init.ts +10 -1
- package/src/commands/labels.ts +4 -44
- package/src/commands/markdown.ts +96 -3
- package/src/commands/migrate.ts +1 -1
- package/src/commands/records.ts +5 -21
- package/src/commands/sync.ts +11 -0
- package/src/commands/tooling.ts +10 -4
- package/src/counts/catalogs.ts +0 -6
- package/src/design/budget.ts +14 -10
- package/src/design/document.ts +5 -5
- package/src/design/parse.ts +21 -4
- package/src/design/render.ts +3 -3
- package/src/gate/boundaries.ts +2 -2
- package/src/gate/measures.ts +7 -29
- package/src/gate/sequencer.ts +51 -2
- package/src/gate/stages.ts +0 -18
- package/src/gov/citations.ts +16 -71
- package/src/gov/stacks.ts +3 -3
- package/src/inventory/subjects.ts +1 -1
- package/src/markdown/bans.ts +1 -1
- package/src/markdown/ceiling.ts +6 -1
- package/src/markdown/colons.ts +86 -0
- package/src/markdown/gate.ts +15 -0
- package/src/markdown/heading-case.ts +74 -0
- package/src/migrate/scratch-evidence.ts +2 -2
- package/src/records/validate.ts +6 -194
- package/src/sandbox/provision.ts +0 -5
- package/src/secrets/shipped.ts +1 -2
- package/src/serve/static.ts +1 -2
- package/src/shipped/references.ts +42 -93
- package/src/sync/check.ts +18 -14
- package/src/sync/copy.ts +4 -5
- package/src/tooling/inject.ts +6 -37
- package/src/tooling/read.ts +2 -3
- package/src/tooling/scan.ts +4 -17
- package/src/tooling/subfolder.ts +2 -66
- package/tooling/astro/manifest.toml +0 -1
- package/tooling/astro/reference.md +0 -8
- package/tooling/base/configs/scripts/verify.json +1 -1
- package/tooling/base/configs/scripts/verify.ts +22 -17
- package/tooling/base/manifest.toml +7 -7
- package/tooling/base/reference.md +19 -32
- package/tooling/base/seeds/.github/workflows/verify.yml +0 -9
- package/tooling/base/seeds/.lintstagedrc +2 -4
- package/tooling/base/seeds/canon/context/ci.md +4 -6
- package/tooling/base/seeds/canon/context/development.md +2 -2
- package/tooling/claude/reference.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +13 -1
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +1 -1
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +27 -2
- package/tooling/claude/seeds/CLAUDE.md +1 -1
- package/tooling/claude/seeds/canon/DESIGN.md +24 -37
- package/tooling/go/reference.md +1 -1
- package/tooling/php/reference.md +1 -1
- package/tooling/python/reference.md +2 -2
- package/tooling/shell/configs/.github/workflows/shell.yml +30 -0
- package/tooling/shell/manifest.toml +12 -0
- package/tooling/shell/reference.md +46 -0
- package/tooling/vite-react/manifest.toml +0 -1
- package/tooling/vite-react/reference.md +0 -8
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +3 -5
- package/tooling/web/configs/.github/workflows/verify.yml +0 -9
- package/tooling/web/manifest.toml +1 -2
- package/tooling/web/reference.md +4 -6
- package/docs/agents/standards-audit.md +0 -40
- package/governance/rules/tooling/765-spelling.md +0 -19
- package/governance/stacks/astro.toml +0 -2
- package/governance/stacks/nextjs.toml +0 -2
- package/governance/stacks/node-server.toml +0 -2
- package/governance/stacks/python-fastapi.toml +0 -2
- package/governance/stacks/react.toml +0 -2
- package/src/commands/standards.ts +0 -278
- package/src/labels/spelling.ts +0 -120
- package/src/standards/audit.ts +0 -146
- package/src/standards/list.ts +0 -33
- package/src/standards/read.ts +0 -177
- package/src/standards/scope.ts +0 -56
- package/standards/index.md +0 -10
- package/tooling/base/configs/.vscode/extensions.json +0 -9
- package/tooling/base/configs/.vscode/settings.json +0 -3
- package/tooling/base/configs/scripts/verify.sh +0 -2
- package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +0 -25
- package/tooling/base/seeds/cspell.json +0 -20
- package/tooling/go/seeds/.cspell/tech-stack.txt +0 -16
- package/tooling/nextjs/seeds/.cspell/tech-stack.txt +0 -3
- package/tooling/php/seeds/.cspell/tech-stack.txt +0 -5
- package/tooling/python/seeds/.cspell/tech-stack.txt +0 -18
- package/tooling/vite-react/seeds/.cspell/project-terms.txt +0 -1
- package/tooling/vite-react/seeds/.cspell/tech-stack.txt +0 -2
- package/tooling/web/configs/.vscode/extensions.json +0 -13
- package/tooling/web/configs/.vscode/settings.json +0 -10
- package/tooling/web/seeds/.cspell/tech-stack.txt +0 -21
- /package/governance/rules/canon/{606-git.md → git.md} +0 -0
- /package/governance/rules/canon/{611-indexes.md → indexes.md} +0 -0
- /package/governance/rules/canon/{604-scratch.md → scratch.md} +0 -0
- /package/governance/rules/canon/{602-tasks.md → task-scope.md} +0 -0
- /package/governance/rules/canon/{605-worktrees.md → worktrees.md} +0 -0
- /package/governance/rules/claude/{566-output.md → output.md} +0 -0
- /package/governance/rules/code/{000-code.md → routing.md} +0 -0
- /package/governance/rules/code/{010-testing.md → testing.md} +0 -0
- /package/governance/rules/framework/{210-astro.md → astro.md} +0 -0
- /package/governance/rules/framework/{220-fastapi.md → fastapi.md} +0 -0
- /package/governance/rules/framework/{230-nextjs.md → nextjs.md} +0 -0
- /package/governance/rules/framework/{200-react.md → react.md} +0 -0
- /package/governance/rules/framework/{260-shadcn.md → shadcn.md} +0 -0
- /package/governance/rules/framework/{250-tailwind.md → tailwind.md} +0 -0
- /package/governance/rules/lang/{130-go.md → go.md} +0 -0
- /package/governance/rules/lang/{140-php.md → php.md} +0 -0
- /package/governance/rules/lang/{110-python.md → python.md} +0 -0
- /package/governance/rules/lang/{100-typescript.md → typescript.md} +0 -0
- /package/governance/rules/lib/{370-database.md → database.md} +0 -0
- /package/governance/rules/lib/{340-pydantic.md → pydantic.md} +0 -0
- /package/governance/rules/lib/{360-security-server.md → security-server.md} +0 -0
- /package/governance/rules/lib/{350-security-web.md → security-web.md} +0 -0
- /package/governance/rules/lib/{320-tanstack-query.md → tanstack-query.md} +0 -0
- /package/governance/rules/lib/{335-testing-go.md → testing-go.md} +0 -0
- /package/governance/rules/lib/{336-testing-php.md → testing-php.md} +0 -0
- /package/governance/rules/lib/{330-testing-py.md → testing-py.md} +0 -0
- /package/governance/rules/lib/{300-testing-ts.md → testing-ts.md} +0 -0
- /package/governance/rules/lib/{310-zod.md → zod.md} +0 -0
- /package/governance/rules/tooling/{700-ci-workflow.md → ci-workflow.md} +0 -0
- /package/governance/rules/tooling/{790-code-comments.md → code-comments.md} +0 -0
- /package/governance/rules/tooling/{780-config-comments.md → config-comments.md} +0 -0
- /package/governance/rules/tooling/{775-dependencies.md → dependencies.md} +0 -0
- /package/governance/rules/ui/{480-canvas.md → canvas.md} +0 -0
- /package/governance/rules/ui/{400-ui.md → copy.md} +0 -0
- /package/governance/rules/ui/{460-design-taste.md → design-taste.md} +0 -0
- /package/governance/rules/ui/{420-forms.md → forms.md} +0 -0
- /package/governance/rules/ui/{465-interface-casing.md → interface-casing.md} +0 -0
- /package/governance/rules/ui/{450-link-behavior.md → link-behavior.md} +0 -0
- /package/governance/rules/ui/{470-motion.md → motion.md} +0 -0
- /package/governance/rules/ui/{430-ux-completeness.md → ux-completeness.md} +0 -0
- /package/tooling/{base → shell}/configs/.editorconfig +0 -0
- /package/tooling/{base → shell}/configs/.shellcheckrc +0 -0
package/docs/target/sync.md
CHANGED
|
@@ -30,7 +30,7 @@ A project that has never synced under a toolkit new enough to write a stamp fall
|
|
|
30
30
|
|
|
31
31
|
Further causes sit outside the per-domain scan, each naming something that walk cannot see. A seed the project edited is reported under `seeds` and merged by hand, since no sync command touches a seed. A file a newer seed folder replaced is reported under `superseded`, such as `.claude/TASKS.md` against the `.canon/tasks/` that now ships, and nothing moves it because the content is the project's own. A domain sitting at the root layout with nothing under `.claude/` is reported under `unmigrated`, and no command moves it either. The project moves the content itself. A surface still at its `.claude/` spelling with nothing under `canon/`, such as `.claude/REQUIREMENTS.md`, is reported under `unmovedSurfaces`, since rules glob the `canon/` spelling alone, and `canon migrate surface-roots` moves it. <!-- canon-keep-surface-root -->
|
|
32
32
|
|
|
33
|
-
`unmigrated` currently names no domain, since
|
|
33
|
+
`unmigrated` currently names no domain, since snippets is the one the toolkit ever installed at the project root, and it retired outright. A leftover `.claude/snippets/` reports under `reverse` below instead.
|
|
34
34
|
|
|
35
35
|
### Rules you never received
|
|
36
36
|
|
|
@@ -40,7 +40,9 @@ Take a clean section as reporting rather than as delivering. Nothing here instal
|
|
|
40
40
|
|
|
41
41
|
Since `canon gov install` records the stack you gave it, the list is read by comparing that stack's current rules against what you hold right now, with no date involved at all. That is what lets it name a rule the toolkit shipped before you last synced: nothing here depends on when you installed. A target stamped before this recording shipped falls back to the older read below.
|
|
42
42
|
|
|
43
|
-
The fallback filters to what your stack can receive, read off the rule folders you already carry plus the folders
|
|
43
|
+
The fallback filters to what your stack can receive, read off the rule folders you already carry plus the folders holding a base rule. A rule under `lang/` or `ui/` belongs to some stacks and not others, so an unfiltered list would name rules you can never install. A target with neither a recorded stack nor a governance anchor reports nothing at all, since there is no date to measure against either.
|
|
44
|
+
|
|
45
|
+
A target recorded on a stack the toolkit retired, such as `react` or `astro`, reads as having no recorded stack and takes this fallback, so it keeps receiving updates to the rules it holds and is offered new rules only in the rule folders it already carries. Run `canon gov detect . --stack node --json` to see which rules its manifests propose beyond those.
|
|
44
46
|
|
|
45
47
|
In the fallback, an empty section is not proof either way when the toolkit running the check is not a full git clone. The read needs history to reach your anchor, and an install from the registry ships none, so the section goes quiet rather than saying it could not measure. Run the check from a clone before reading a clean result as a complete one. The stack-based read above is untouched by this, since it consults no history.
|
|
46
48
|
|
|
@@ -72,13 +74,11 @@ Reconcile the configs with `canon tooling diff <stack> <path>` to read which fil
|
|
|
72
74
|
|
|
73
75
|
It never touches user-owned seed files. Governance rules in `.claude/rules/` and tooling configs refresh in place. Stale `.claude/GOV.md` from earlier installs is removed.
|
|
74
76
|
|
|
75
|
-
Standards take no part in that run. Nothing installed them, so there is no copy to reconcile and no `canon standards sync` to reach for.
|
|
76
|
-
|
|
77
77
|
## Targeted
|
|
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
|
|
81
|
+
- Tooling configs and seeds: `canon tooling <stack> <path>` overwrites golden configs and copies each seed once, leaving an existing file alone
|
|
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
|
|
|
@@ -17,7 +17,7 @@ Project docs split across three roots at the project root. What the project auth
|
|
|
17
17
|
```plaintext
|
|
18
18
|
canon/
|
|
19
19
|
├── REQUIREMENTS.md ← problem, goals, non-goals
|
|
20
|
-
├── DESIGN.md ← visual intent
|
|
20
|
+
├── DESIGN.md ← visual intent, pointing at the stylesheet (UI projects)
|
|
21
21
|
└── context/ ← per-domain narrative loaded on demand via index.md
|
|
22
22
|
|
|
23
23
|
.claude/
|
|
@@ -18,12 +18,12 @@ This page covers the roles and the loop. For merge order and fan-out rules, see
|
|
|
18
18
|
|
|
19
19
|
The split is by vantage, not by capability. All four are Claude Code sessions.
|
|
20
20
|
|
|
21
|
-
| Role | Session | Owns
|
|
22
|
-
| ------------ | ------------------------------------- |
|
|
23
|
-
| Orchestrator | One warm, long-lived session | The cross-feature call,
|
|
24
|
-
| Reviewer | One cold session per pull request |
|
|
25
|
-
| Planner | One session per row, warm or cold | Measure the row against the tree, write one plan
|
|
26
|
-
| Worker | One cold worktree session per feature | Implement, self-check, open PR, answer the
|
|
21
|
+
| Role | Session | Owns | Does not |
|
|
22
|
+
| ------------ | ------------------------------------- | ---------------------------------------------------- | ---------------------------------- |
|
|
23
|
+
| Orchestrator | One warm, long-lived session | The cross-feature call, review dispatch, merge order | Review in place, edit, merge PRs |
|
|
24
|
+
| Reviewer | One cold session per pull request | One PR's read through `review-pr`, the lift on close | Fix findings, ready by hand, merge |
|
|
25
|
+
| Planner | One session per row, warm or cold | Measure the row against the tree, write one plan | Enter a worktree, write the board |
|
|
26
|
+
| Worker | One cold worktree session per feature | Implement, self-check, open PR, answer the reviewer | Write the shared board, merge |
|
|
27
27
|
|
|
28
28
|
Each role is asserted explicitly rather than inferred. The orchestrator loads
|
|
29
29
|
`role-orchestrator` at the start of its session, a worker loads `role-worker`,
|
|
@@ -72,9 +72,9 @@ One feature travels this path end to end.
|
|
|
72
72
|
|
|
73
73
|
1. The next feature is planned with `plan-feature`, writing a plan to `.canon/plans/`. The orchestrator runs it warm when the row turns on a contract other features consume or a dependency on another row, and dispatches a planner under `role-planner` otherwise. A cold planner measures the row against the tree rather than trusting what the row claims, and it reads what is in flight by composing the live session roster with open pull requests. A bare branch or worktree is not evidence on its own, since this repository leaves both behind after a squash merge.
|
|
74
74
|
2. Orchestrator checks the plan waits on nobody, checks the branch is unclaimed, and checks no conflict holds the plan behind a track in flight, then dispatches a background worker with `claude --bg` against the plan, naming the branch and the model on the launch rather than leaving the worker to derive either. No count caps how many run at once. The branch travels as the argument to the worker's own worktree call, which is the one place the name is read rather than inferred. It falls back to naming the invocation for a human to run through `session-worktree` and `auto-ship` when the plan still waits on an answer only the operator can give, the branch check refuses, or a conflict holds the plan behind a track already in flight. Either way, the worker enters its own worktree, builds, self-checks, opens a PR, and stops at the PR boundary.
|
|
75
|
-
3.
|
|
76
|
-
4.
|
|
77
|
-
5.
|
|
75
|
+
3. Orchestrator dispatches a reviewer under `role-reviewer` for every pull request but a release one, which posts `review-pr` findings, and `review-ui` drives any visual checklist beside it.
|
|
76
|
+
4. The reviewer tells the session holding that branch to run `review-address` once the pass posted a finding at any severity, resolving it with `canon sessions list --branch` and falling back to the orchestrator when none is live. The worker addresses the findings, rebases onto `origin/main` when a sibling landed first on a file it writes, then pushes a follow-up. A pass carrying only minor findings dispatches too, since the grade runs low often enough that a floor at should-fix loses fixes a worker would have made. `review-pr` states that threshold and the heading follows it, so an open heading is itself the signal to send.
|
|
77
|
+
5. The worker asks that reviewer for the re-review directly, and the reviewer closes the review out with `review-pr` again. The second pass reads only the commits the follow-up added, or the worker's response alone when the follow-up added none, and posts under `## Review` when it finds anything and under `## Review closed` when it finds nothing, so a reader learns from the heading whether work is still owed and takes the merge decision from the counts on the line under it. A pass finding nothing where a close-out already stands rewrites that comment to cover what it read rather than posting a second one, so the thread carries one live verdict. Repeat from step 4 until a pass closes the review. Each reviewer then runs `canon pr lift`, which lifts the draft mark once every gate it reads is clear.
|
|
78
78
|
6. The human reads the result and merges. After each merge, the orchestrator tells any trailing worker whose files the merged diff touches to run `review-address`, which rebases whether or not the review left anything open.
|
|
79
79
|
|
|
80
80
|
There is no loop construct here. Each worker is a single build that halts at the
|
|
@@ -86,11 +86,11 @@ from merging promptly so the next PR does not rot against a moving main.
|
|
|
86
86
|
|
|
87
87
|
The worker's chain carries no review step. The session that wrote the code is
|
|
88
88
|
structurally blind to its own misreadings, because the same misreading wrote
|
|
89
|
-
both the code and any review of it, so the first review a change gets is
|
|
90
|
-
|
|
89
|
+
both the code and any review of it, so the first review a change gets is a
|
|
90
|
+
dispatched reviewer's.
|
|
91
91
|
|
|
92
92
|
- Worker gate, inside `auto-ship`: the session that wrote the code. Its job is "did I build the plan and does it pass?" The verify commands and the test order read decide whether the PR opens, and the draft mark holds the merge.
|
|
93
|
-
-
|
|
93
|
+
- Reviewer pass, via `review-pr`: a fresh session holding one pull request, briefed with the cross-feature facts the orchestrator's wave pass found (a sibling PR in flight, a shared file, the merge order). Its job is "is this right and does it fit?" It can question the plan itself. This is the merge gate.
|
|
94
94
|
|
|
95
95
|
The human read at merge is the final gate. No layer repeats another.
|
|
96
96
|
|
|
@@ -190,7 +190,7 @@ coordination costs more than the change it was too small.
|
|
|
190
190
|
|
|
191
191
|
Two tiers hold work at different altitudes.
|
|
192
192
|
|
|
193
|
-
- Tasks (`.canon/tasks/`): the active few pulled into the current turn, one file each. Gitignored, high churn. Shape governed by `
|
|
193
|
+
- Tasks (`.canon/tasks/`): the active few pulled into the current turn, one file each. Gitignored, high churn. Shape governed by the `task-board` skill. `priority.md` beside them carries execution order, and `backlog.md` carries what nobody is scheduling, both shaped by the same skill.
|
|
194
194
|
- Edits: a few lines, done immediately with no ceremony.
|
|
195
195
|
|
|
196
196
|
Nothing above these sequences work into versions. Scope is stated in
|
|
@@ -202,11 +202,9 @@ before another is carried nowhere at all.
|
|
|
202
202
|
|
|
203
203
|
Review attention binds, and no number caps worker tracks, so stop adding once you cannot review every output. A row waits only on a conflict a merge cannot settle, which the `role-orchestrator` dispatch runbook states once. A shared file is not one: both rows build, and the branch merging second resolves any conflict in its own session after the first lands, since no practice source serializes on a file. [Fowler](https://martinfowler.com/articles/branching-patterns.html) has whoever integrates second check health "even if it's a clean merge", and [DORA](https://dora.dev/capabilities/trunk-based-development/) keeps branches to hours with no integration phase.
|
|
204
204
|
|
|
205
|
-
Review splits by vantage. A reviewer under `role-reviewer` takes
|
|
206
|
-
request's read
|
|
207
|
-
|
|
208
|
-
rule body. Prose stays with the orchestrator, which keeps one cross-branch pass
|
|
209
|
-
per wave over file sets, the board, and merge order.
|
|
205
|
+
Review splits by vantage. A reviewer under `role-reviewer` takes every pull
|
|
206
|
+
request's read but a release one's and trades each round with the worker. The
|
|
207
|
+
orchestrator keeps one cross-branch pass per wave over file sets and merge order.
|
|
210
208
|
|
|
211
209
|
Inbound turns cost the controlling session as well, so weigh the spend before
|
|
212
210
|
widening. A message from one of your other sessions arrives as a new turn
|
|
@@ -90,7 +90,7 @@ Each row sits under the group its skill's `metadata.family` names. The landing p
|
|
|
90
90
|
|
|
91
91
|
| Skill | When to use |
|
|
92
92
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
93
|
-
| `canon:role-orchestrator` | To assert the control session that owns the queue and
|
|
93
|
+
| `canon:role-orchestrator` | To assert the control session that owns the queue and dispatches a reviewer for each worker's PR |
|
|
94
94
|
| `canon:role-planner` | To assert the thinking role for a cold session writing a plan, a groundwork track, or an intake pass |
|
|
95
95
|
| `canon:role-reviewer` | To assert the reviewing role for a cold session dispatched to review one pull request |
|
|
96
96
|
| `canon:role-worker` | To assert the worker role for a cold session building one branch under one plan |
|
|
@@ -14,19 +14,19 @@ The tier framework sits alongside [Claude Design](../../wiki/claude/design.md),
|
|
|
14
14
|
|
|
15
15
|
## Tier 0: prose only
|
|
16
16
|
|
|
17
|
-
The default. `canon/DESIGN.md` holds visual intent
|
|
17
|
+
The default. `canon/DESIGN.md` holds visual intent, being one Overview paragraph, at most three one-line rules a section, and a table naming what each color and shape role is for. Its lead names the stylesheet the values live in, since a hand-typed copy of them drifts from the CSS.
|
|
18
18
|
|
|
19
19
|
Claude Code reads it and writes the implementation. Works for CLI tools, internal dashboards, admin panels, and backend-focused projects.
|
|
20
20
|
|
|
21
21
|
### Seed shape
|
|
22
22
|
|
|
23
|
-
The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships
|
|
23
|
+
The toolkit seed in `tooling/claude/seeds/canon/DESIGN.md` ships an intent template with a starting set of roles, each naming its custom property, and `claude/skills/canvas-board/references/design.md` carries the same tables under `## Template` with placeholder rows. The column headers are what the parser reads, so they stay verbatim in either, while the rows are the project's own. The seed's lead asks for the project's own stylesheet, such as `src/styles/tokens.css` or a Tailwind `@theme` block, and falls back to `.claude/design/project/` only when the project has none.
|
|
24
24
|
|
|
25
25
|
`canon design render` writes an HTML plus CSS preview to `.canon/tmp/render/design/` for eyeballing the current system without leaving Claude Code. See `canon/context/design/index.md`.
|
|
26
26
|
|
|
27
27
|
A project wanting a neutral starting point to override runs `canon design install`, which copies one stylesheet to `.claude/design/base.css` carrying an achromatic token set as custom properties and two components built on them. Greys run from near-black to near-white and the accent is monochrome, so the only palette the project renders is one it writes itself. That file is toolkit-owned and `canon design sync` refreshes it, so a project overrides a value in `.claude/design/project/` instead, which sync never touches. Nothing arrives without that install, and the two channels are independent: a record the project wrote is its own, and the installed stylesheet is the toolkit's.
|
|
28
28
|
|
|
29
|
-
A cell no source anchors ends in `? verify`, and the preview shows that marker beside the value rather than folding it in, so a swatch and a font sample stay built from the value alone. A confidence line above the sections names how many cells are anchored against how many are tagged, which is what tells a reader whether they are looking at a record of the code or a proposal about it. It reads the columns a source could anchor and leaves out the row names, so the ratio is not diluted by cells no tag could ever reach. The proposal path tags nearly all of them, so that count reads low on day one by design.
|
|
29
|
+
A record generated from a token source carries the values in tables instead, which is the shape this toolkit's own record takes. There a cell no source anchors ends in `? verify`, and the preview shows that marker beside the value rather than folding it in, so a swatch and a font sample stay built from the value alone. A confidence line above the sections names how many cells are anchored against how many are tagged, which is what tells a reader whether they are looking at a record of the code or a proposal about it. It reads the columns a source could anchor and leaves out the row names, so the ratio is not diluted by cells no tag could ever reach. The proposal path tags nearly all of them, so that count reads low on day one by design.
|
|
30
30
|
|
|
31
31
|
### Tools
|
|
32
32
|
|
package/governance/detect.toml
CHANGED
|
@@ -21,71 +21,67 @@
|
|
|
21
21
|
deps = []
|
|
22
22
|
files = [".claude/skills", "claude/skills"]
|
|
23
23
|
|
|
24
|
-
["
|
|
24
|
+
["ci-workflow"]
|
|
25
25
|
deps = []
|
|
26
26
|
files = [".github/workflows"]
|
|
27
27
|
|
|
28
|
-
["
|
|
29
|
-
deps = ["cspell"]
|
|
30
|
-
files = [".cspell", "cspell.json", ".cspell.json", "cspell.config.*"]
|
|
31
|
-
|
|
32
|
-
["775-dependencies"]
|
|
28
|
+
["dependencies"]
|
|
33
29
|
deps = []
|
|
34
30
|
files = ["**/package.json", "**/pyproject.toml", "**/go.mod", "**/composer.json"]
|
|
35
31
|
|
|
36
|
-
["
|
|
32
|
+
["config-comments"]
|
|
37
33
|
deps = []
|
|
38
34
|
files = [".editorconfig", "**/Dockerfile*", "**/*.config.*", "**/.env.example"]
|
|
39
35
|
|
|
40
|
-
["
|
|
36
|
+
["code-comments"]
|
|
41
37
|
deps = []
|
|
42
38
|
files = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.sh", "**/*.py"]
|
|
43
39
|
|
|
44
|
-
["
|
|
40
|
+
["go"]
|
|
45
41
|
deps = []
|
|
46
42
|
files = ["**/go.mod"]
|
|
47
43
|
|
|
48
|
-
["
|
|
44
|
+
["php"]
|
|
49
45
|
deps = []
|
|
50
46
|
files = ["**/composer.json"]
|
|
51
47
|
|
|
52
|
-
["
|
|
48
|
+
["react"]
|
|
53
49
|
deps = ["react"]
|
|
54
50
|
files = []
|
|
55
51
|
|
|
56
|
-
["
|
|
52
|
+
["astro"]
|
|
57
53
|
deps = ["astro"]
|
|
58
54
|
files = ["**/astro.config.*"]
|
|
59
55
|
|
|
60
|
-
["
|
|
56
|
+
["fastapi"]
|
|
61
57
|
deps = ["fastapi"]
|
|
62
58
|
files = []
|
|
63
59
|
|
|
64
|
-
["
|
|
60
|
+
["nextjs"]
|
|
65
61
|
deps = ["next"]
|
|
66
62
|
files = ["**/next.config.*"]
|
|
67
63
|
|
|
68
|
-
["
|
|
64
|
+
["tailwind"]
|
|
69
65
|
deps = ["tailwindcss", "@tailwindcss/vite", "@tailwindcss/postcss"]
|
|
70
66
|
files = ["**/tailwind.config.*"]
|
|
71
67
|
|
|
72
|
-
["
|
|
68
|
+
["shadcn"]
|
|
73
69
|
deps = []
|
|
74
70
|
files = ["**/components.json"]
|
|
75
71
|
|
|
76
|
-
["
|
|
72
|
+
["e2e-reliability"]
|
|
77
73
|
deps = ["@playwright/test", "playwright", "cypress"]
|
|
78
74
|
files = ["**/e2e"]
|
|
79
75
|
|
|
80
|
-
["
|
|
76
|
+
["test-scope"]
|
|
81
77
|
deps = ["@playwright/test", "playwright", "cypress"]
|
|
82
78
|
files = ["**/e2e"]
|
|
83
79
|
|
|
84
|
-
["
|
|
80
|
+
["zod"]
|
|
85
81
|
deps = ["zod"]
|
|
86
82
|
files = []
|
|
87
83
|
|
|
88
|
-
["
|
|
84
|
+
["tanstack-query"]
|
|
89
85
|
deps = [
|
|
90
86
|
"@tanstack/react-query",
|
|
91
87
|
"@tanstack/vue-query",
|
|
@@ -95,23 +91,23 @@ deps = [
|
|
|
95
91
|
]
|
|
96
92
|
files = []
|
|
97
93
|
|
|
98
|
-
["
|
|
94
|
+
["testing-go"]
|
|
99
95
|
deps = []
|
|
100
96
|
files = ["**/go.mod"]
|
|
101
97
|
|
|
102
|
-
["
|
|
98
|
+
["testing-php"]
|
|
103
99
|
deps = ["phpunit/phpunit", "pestphp/pest"]
|
|
104
100
|
files = ["**/phpunit.xml", "**/phpunit.xml.dist"]
|
|
105
101
|
|
|
106
|
-
["
|
|
102
|
+
["pydantic"]
|
|
107
103
|
deps = ["pydantic"]
|
|
108
104
|
files = []
|
|
109
105
|
|
|
110
|
-
["
|
|
106
|
+
["security-web"]
|
|
111
107
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
112
108
|
files = ["index.html", "*/index.html"]
|
|
113
109
|
|
|
114
|
-
["
|
|
110
|
+
["security-server"]
|
|
115
111
|
deps = [
|
|
116
112
|
"express",
|
|
117
113
|
"fastify",
|
|
@@ -133,7 +129,7 @@ deps = [
|
|
|
133
129
|
]
|
|
134
130
|
files = []
|
|
135
131
|
|
|
136
|
-
["
|
|
132
|
+
["database"]
|
|
137
133
|
deps = [
|
|
138
134
|
"prisma",
|
|
139
135
|
"@prisma/client",
|
|
@@ -160,42 +156,42 @@ deps = [
|
|
|
160
156
|
]
|
|
161
157
|
files = ["**/migrations", "**/schema.prisma", "**/*.sql"]
|
|
162
158
|
|
|
163
|
-
["
|
|
159
|
+
["copy"]
|
|
164
160
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
165
161
|
files = ["index.html", "*/index.html"]
|
|
166
162
|
|
|
167
|
-
["
|
|
163
|
+
["a11y"]
|
|
168
164
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
169
165
|
files = ["index.html", "*/index.html"]
|
|
170
166
|
|
|
171
|
-
["
|
|
167
|
+
["forms"]
|
|
172
168
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
173
169
|
files = ["index.html", "*/index.html"]
|
|
174
170
|
|
|
175
|
-
["
|
|
171
|
+
["ux-completeness"]
|
|
176
172
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
177
173
|
files = ["index.html", "*/index.html"]
|
|
178
174
|
|
|
179
|
-
["
|
|
175
|
+
["surface-capture"]
|
|
180
176
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
181
177
|
files = ["index.html", "*/index.html"]
|
|
182
178
|
|
|
183
|
-
["
|
|
179
|
+
["link-behavior"]
|
|
184
180
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
185
181
|
files = ["index.html", "*/index.html"]
|
|
186
182
|
|
|
187
|
-
["
|
|
183
|
+
["design-taste"]
|
|
188
184
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
189
185
|
files = ["canon/DESIGN.md", "index.html", "*/index.html"]
|
|
190
186
|
|
|
191
|
-
["
|
|
187
|
+
["interface-casing"]
|
|
192
188
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
193
189
|
files = ["index.html", "*/index.html"]
|
|
194
190
|
|
|
195
|
-
["
|
|
191
|
+
["motion"]
|
|
196
192
|
deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
|
|
197
193
|
files = ["index.html", "*/index.html"]
|
|
198
194
|
|
|
199
|
-
["
|
|
195
|
+
["canvas"]
|
|
200
196
|
deps = []
|
|
201
197
|
files = [".canon/canvas"]
|
package/governance/renames.toml
CHANGED
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"555-tasks" = "655-tasks"
|
|
25
25
|
"558-plan" = "658-plan"
|
|
26
26
|
"501-markdown" = "801-markdown"
|
|
27
|
-
"065-spelling" = "765-spelling"
|
|
28
27
|
"075-dependencies" = "775-dependencies"
|
|
29
28
|
"080-config-comments" = "780-config-comments"
|
|
30
29
|
"090-code-comments" = "790-code-comments"
|
|
@@ -33,3 +32,47 @@
|
|
|
33
32
|
"655-tasks" = "tasks"
|
|
34
33
|
"570-skill" = "skill"
|
|
35
34
|
"801-markdown" = "markdown"
|
|
35
|
+
"602-tasks" = "task-scope"
|
|
36
|
+
"604-scratch" = "scratch"
|
|
37
|
+
"605-worktrees" = "worktrees"
|
|
38
|
+
"606-git" = "git"
|
|
39
|
+
"611-indexes" = "indexes"
|
|
40
|
+
"566-output" = "output"
|
|
41
|
+
"000-code" = "routing"
|
|
42
|
+
"010-testing" = "testing"
|
|
43
|
+
"200-react" = "react"
|
|
44
|
+
"210-astro" = "astro"
|
|
45
|
+
"220-fastapi" = "fastapi"
|
|
46
|
+
"230-nextjs" = "nextjs"
|
|
47
|
+
"250-tailwind" = "tailwind"
|
|
48
|
+
"260-shadcn" = "shadcn"
|
|
49
|
+
"100-typescript" = "typescript"
|
|
50
|
+
"110-python" = "python"
|
|
51
|
+
"130-go" = "go"
|
|
52
|
+
"140-php" = "php"
|
|
53
|
+
"300-testing-ts" = "testing-ts"
|
|
54
|
+
"305-e2e-reliability" = "e2e-reliability"
|
|
55
|
+
"306-test-scope" = "test-scope"
|
|
56
|
+
"310-zod" = "zod"
|
|
57
|
+
"320-tanstack-query" = "tanstack-query"
|
|
58
|
+
"330-testing-py" = "testing-py"
|
|
59
|
+
"335-testing-go" = "testing-go"
|
|
60
|
+
"336-testing-php" = "testing-php"
|
|
61
|
+
"340-pydantic" = "pydantic"
|
|
62
|
+
"350-security-web" = "security-web"
|
|
63
|
+
"360-security-server" = "security-server"
|
|
64
|
+
"370-database" = "database"
|
|
65
|
+
"700-ci-workflow" = "ci-workflow"
|
|
66
|
+
"775-dependencies" = "dependencies"
|
|
67
|
+
"780-config-comments" = "config-comments"
|
|
68
|
+
"790-code-comments" = "code-comments"
|
|
69
|
+
"400-ui" = "copy"
|
|
70
|
+
"410-a11y" = "a11y"
|
|
71
|
+
"420-forms" = "forms"
|
|
72
|
+
"430-ux-completeness" = "ux-completeness"
|
|
73
|
+
"440-surface-capture" = "surface-capture"
|
|
74
|
+
"450-link-behavior" = "link-behavior"
|
|
75
|
+
"460-design-taste" = "design-taste"
|
|
76
|
+
"465-interface-casing" = "interface-casing"
|
|
77
|
+
"470-motion" = "motion"
|
|
78
|
+
"480-canvas" = "canvas"
|
|
@@ -20,5 +20,5 @@ paths:
|
|
|
20
20
|
|
|
21
21
|
- Answer a question about the running page with a script against the dev server rather than with the suite.
|
|
22
22
|
- Do not enable `fullyParallel` in `playwright.config.ts`.
|
|
23
|
-
- Follow `.claude/rules/canon/ui/
|
|
24
|
-
- Follow `.claude/rules/canon/lib/
|
|
23
|
+
- Follow `.claude/rules/canon/ui/surface-capture.md` for capture scope.
|
|
24
|
+
- Follow `.claude/rules/canon/lib/e2e-reliability.md` for waits and guards.
|
|
@@ -60,4 +60,4 @@ paths:
|
|
|
60
60
|
|
|
61
61
|
- Let content reflow at a viewport 320 CSS pixels wide with no loss of content or function and no two-dimensional scrolling. Only content whose meaning depends on both axes, such as a data table, a map, or a diagram, may scroll sideways (WCAG Reflow, 1.4.10, Level AA).
|
|
62
62
|
- Treat 320 as the criterion's own test condition rather than a device width. It is equivalent to a 1280 pixel window at 400 percent zoom, so a layout that breaks there breaks for a person who zooms.
|
|
63
|
-
- Hold the same 320 floor for the content region beside persistent chrome a person can resize. The criterion measures the viewport, so this extension is this rule's own rather than the criterion's: a panel widened to 480 in a 768 window leaves 288 for the content, under the floor at a window the criterion passes. `
|
|
63
|
+
- Hold the same 320 floor for the content region beside persistent chrome a person can resize. The criterion measures the viewport, so this extension is this rule's own rather than the criterion's: a panel widened to 480 in a 768 window leaves 288 for the content, under the floor at a window the criterion passes. `surface-capture` states where the frame for it gets taken.
|
|
@@ -26,12 +26,12 @@ paths:
|
|
|
26
26
|
## What a capture covers
|
|
27
27
|
|
|
28
28
|
- Capture the full page. Do not capture a component in isolation.
|
|
29
|
-
- Declare the widths a layout case captures. Always include 320, the reflow floor from the reflow criterion in `
|
|
29
|
+
- Declare the widths a layout case captures. Always include 320, the reflow floor from the reflow criterion in `a11y`, then add each breakpoint bucket the project writes rules for, read from the `## Layout` section of `DESIGN.md`.
|
|
30
30
|
- Fall back to the 320 floor alone when the project has no `DESIGN.md` or its record carries no `## Layout` section. Do not impose another project's breakpoints.
|
|
31
31
|
- Add a layout case at each bound when a surface renders persistent chrome a person can resize, such as a draggable sidebar or a split pane, one with the chrome at its narrowest and one at its widest. Take both at the narrowest declared width where the chrome stays persistent rather than collapsing, since a frame where it has turned into an overlay shows none of the width it takes.
|
|
32
|
-
- Read those bounds from the code that clamps the chrome, since `## Layout` has no slot for them. Judge each frame by the content width left beside the chrome rather than by the window width, against the 320 floor `
|
|
32
|
+
- Read those bounds from the code that clamps the chrome, since `## Layout` has no slot for them. Judge each frame by the content width left beside the chrome rather than by the window width, against the 320 floor `a11y` holds for that region.
|
|
33
33
|
- Apply the declaration to a case that covers layout only. A case driving a menu open or an answer chosen tests a state, so it takes one width rather than the full set.
|
|
34
|
-
- Read a capture at 320 as proof that a frame was taken there, not that the page reflows correctly. The criterion is stated in `
|
|
34
|
+
- Read a capture at 320 as proof that a frame was taken there, not that the page reflows correctly. The criterion is stated in `a11y` and nothing here enforces it.
|
|
35
35
|
- Write the capture into a folder named `evidence`. The image is collected for the pull request comment when any segment of its path is literally `evidence` and its filename carries an image extension, so the folder name is fixed and its position in the tree is the project's own.
|
|
36
36
|
- Several `evidence/` folders in one project is the ordinary shape rather than a problem to consolidate. One per surface is how a project with more than one rendered surface ends up.
|
|
37
37
|
- Drive a state a screenshot cannot reach. An initial render reports nothing about a menu that opens, an answer that is chosen, or a rail that tracks scrolling.
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
extends = ""
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
# `canon
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
# Named rule by rule rather than by folder, so a rule authored later under
|
|
3
|
+
# `canon` or `claude` reaches no project until it is added here or proposed by
|
|
4
|
+
# `canon gov detect`. Every other rule is opt-in.
|
|
5
|
+
rules = [
|
|
6
|
+
"output",
|
|
7
|
+
"task-scope",
|
|
8
|
+
"scratch",
|
|
9
|
+
"worktrees",
|
|
10
|
+
"git",
|
|
11
|
+
"indexes",
|
|
12
|
+
"context",
|
|
13
|
+
"tasks",
|
|
14
|
+
"plan",
|
|
15
|
+
"markdown",
|
|
16
|
+
]
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
extends = "base"
|
|
2
|
-
rules = ["code", "
|
|
2
|
+
rules = ["code", "typescript", "testing-ts"]
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
extends = "base"
|
|
2
|
-
rules = ["code", "
|
|
2
|
+
rules = ["code", "python", "testing-py"]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erclx/canon",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.36.0",
|
|
5
5
|
"description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"src",
|
|
12
12
|
"scripts",
|
|
13
|
-
"standards",
|
|
14
13
|
"governance",
|
|
15
14
|
"tooling",
|
|
16
15
|
"claude",
|
|
@@ -25,7 +24,6 @@
|
|
|
25
24
|
"access": "public"
|
|
26
25
|
},
|
|
27
26
|
"scripts": {
|
|
28
|
-
"check:spell": "cspell '**' '.*/**' '.*' --no-progress --color --show-context",
|
|
29
27
|
"format": "prettier --write --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --write --indent 2 scripts/ tooling/ claude/",
|
|
30
28
|
"check:format": "prettier --check --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --diff --indent 2 scripts/ tooling/ claude/",
|
|
31
29
|
"check:shell": "find scripts tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
|
|
@@ -71,7 +69,6 @@
|
|
|
71
69
|
"@types/bun": "^1.2.10",
|
|
72
70
|
"@types/micromatch": "^4.0.10",
|
|
73
71
|
"astro": "^6.1.9",
|
|
74
|
-
"cspell": "^8.17.1",
|
|
75
72
|
"happy-dom": "^20.14.5",
|
|
76
73
|
"husky": "^9.1.7",
|
|
77
74
|
"micromatch": "^4.0.8",
|
|
@@ -97,23 +97,17 @@ log_step "Assert scaffold"
|
|
|
97
97
|
# catches a failed domain, and the gate stays green while the target is
|
|
98
98
|
# missing everything that domain provides.
|
|
99
99
|
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
# the toolkit rather than a copy this gate could assert on. The two
|
|
100
|
+
# Authoring references name no path because they ship inside the plugin's
|
|
101
|
+
# skills rather than installing into a target. The two
|
|
103
102
|
# rule paths stand for the `claude` and `canon` groups `base` takes whole.
|
|
104
103
|
for path in "CLAUDE.md" ".claude/wiki/index.md" ".claude" "canon/context/index.md" \
|
|
105
|
-
".prettierrc" ".
|
|
106
|
-
".claude/rules/canon/claude/
|
|
104
|
+
".prettierrc" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.ts" \
|
|
105
|
+
".claude/rules/canon/claude/output.md" ".claude/rules/canon/canon/scratch.md"; do
|
|
107
106
|
if [ ! -e "$TARGET_DIR/$path" ]; then
|
|
108
107
|
log_error "Missing after canon init: $path"
|
|
109
108
|
fi
|
|
110
109
|
log_info "Found: $path"
|
|
111
110
|
done
|
|
112
111
|
|
|
113
|
-
if [ ! -x "$TARGET_DIR/scripts/verify.sh" ]; then
|
|
114
|
-
log_error "Not executable after canon init: scripts/verify.sh"
|
|
115
|
-
fi
|
|
116
|
-
log_info "Executable: scripts/verify.sh"
|
|
117
|
-
|
|
118
112
|
log_step "Verification passed"
|
|
119
113
|
log_info "Manual check still needed: bun link and global canon invocation"
|
package/src/audits/catalog.ts
CHANGED
|
@@ -468,7 +468,6 @@ const RECORD_KINDS: readonly (readonly [string, Corpus])[] = [
|
|
|
468
468
|
['plans', 'per-machine'],
|
|
469
469
|
['groundwork', 'per-machine'],
|
|
470
470
|
['intake', 'per-machine'],
|
|
471
|
-
['standards', 'tracked'],
|
|
472
471
|
['teach', 'per-machine'],
|
|
473
472
|
]
|
|
474
473
|
|
|
@@ -588,14 +587,6 @@ export const AUDITS: readonly AuditSpec[] = [
|
|
|
588
587
|
argv: ['records', 'validate', kind, '--json'],
|
|
589
588
|
gatingExits: [],
|
|
590
589
|
corpus,
|
|
591
|
-
// `standards` is the one tracked kind here, so it takes none of the
|
|
592
|
-
// per-machine default the other five inherit from their corpus. A target
|
|
593
|
-
// reads standards through `canon standards` rather than a copy in its own
|
|
594
|
-
// tree, so carrying no standards folder at all is the
|
|
595
|
-
// ordinary state of every project but this repository.
|
|
596
|
-
...(kind === 'standards' && {
|
|
597
|
-
absentReasons: ['no-folder'] satisfies RecordRefusal[],
|
|
598
|
-
}),
|
|
599
590
|
counts: findingsOnly,
|
|
600
591
|
})),
|
|
601
592
|
{
|
|
@@ -121,9 +121,6 @@ const plural = (count: number, noun: string): string =>
|
|
|
121
121
|
const frameRow = (cells: string): string =>
|
|
122
122
|
`<span class="frame">│</span> <span class="ok">✓</span> ${cells}`
|
|
123
123
|
|
|
124
|
-
/** Rule names carry a numeric prefix that orders the load, not the identity. */
|
|
125
|
-
const slug = (name: string): string => name.replace(/^\d+-/, '')
|
|
126
|
-
|
|
127
124
|
/** Indented to the depth a rule inside the `<style>` block sits at. */
|
|
128
125
|
const indentTokens = (css: string): string =>
|
|
129
126
|
css
|
|
@@ -194,13 +191,13 @@ export function buildFrameValues(catalogs: FrameCatalogs): FrameValues {
|
|
|
194
191
|
}
|
|
195
192
|
|
|
196
193
|
const tokenCss = indentTokens(catalogs.tokenCss)
|
|
197
|
-
const rules = gov.rules.map((entry) =>
|
|
194
|
+
const rules = gov.rules.map((entry) => entry.name)
|
|
198
195
|
// A rule no stack names is opt-in behind `--add`, so featuring one advertises
|
|
199
196
|
// an entry no ordinary `canon gov install` delivers. The column samples the
|
|
200
197
|
// stack-reached subset while its count and remainder describe the whole.
|
|
201
198
|
const stacked = new Set(gov.stacks.flatMap((stack) => stack.rules))
|
|
202
199
|
const deliveredEntries = gov.rules.filter((entry) => stacked.has(entry.name))
|
|
203
|
-
const deliveredRules = deliveredEntries.map((entry) =>
|
|
200
|
+
const deliveredRules = deliveredEntries.map((entry) => entry.name)
|
|
204
201
|
|
|
205
202
|
for (const [label, list] of [
|
|
206
203
|
['skills', skills],
|
|
@@ -236,7 +233,7 @@ export function buildFrameValues(catalogs: FrameCatalogs): FrameValues {
|
|
|
236
233
|
const scope =
|
|
237
234
|
globs.length > 0 ? clip(globs.join(' '), GLOB_WIDTH) : 'every session'
|
|
238
235
|
return frameRow(
|
|
239
|
-
`<span class="name">${escape(pad(
|
|
236
|
+
`<span class="name">${escape(pad(entry.name, 24))}</span>` +
|
|
240
237
|
`<span class="domain">${escape(pad(`[${entry.domain}]`, 12))}</span>` +
|
|
241
238
|
`<span class="muted">${escape(scope)}</span>`,
|
|
242
239
|
)
|
package/src/claude/routing.ts
CHANGED
|
@@ -16,7 +16,7 @@ const PATH_TOKEN = /^[.A-Za-z0-9_][A-Za-z0-9._/-]*$/
|
|
|
16
16
|
/** A placeholder segment, which a shape carries and a real path does not. */
|
|
17
17
|
const SHAPE = /<[^>]*>/
|
|
18
18
|
|
|
19
|
-
/** An alphabetic extension, which separates `
|
|
19
|
+
/** An alphabetic extension, which separates `tsconfig.json` from `3.6.0`. */
|
|
20
20
|
const EXTENSION = /\.[a-z]{2,5}$/
|
|
21
21
|
|
|
22
22
|
/** Extensions a folder is probed with, so a glob narrowed by type still hits. */
|