@erclx/canon 5.31.0 → 5.32.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 +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +1 -1
- package/claude/skills/auto-ship/REQUIREMENT.md +4 -16
- package/claude/skills/auto-ship/SKILL.md +13 -58
- package/claude/skills/auto-ship/references/draft-mark.md +2 -2
- package/claude/skills/auto-ship/references/failure-recovery.md +1 -5
- package/claude/skills/auto-ship/references/tier-failures.md +1 -1
- package/claude/skills/auto-ship/references/ui-checklist.md +2 -2
- package/claude/skills/auto-ship/references/verb-absent.md +3 -27
- package/claude/skills/backlog-triage/SKILL.md +1 -1
- package/claude/skills/canon-cli/REQUIREMENT.md +4 -6
- package/claude/skills/canon-cli/SKILL.md +2 -2
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback/SKILL.md +10 -13
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +13 -14
- package/claude/skills/canon-feedback-triage/SKILL.md +49 -30
- package/claude/skills/canvas/REQUIREMENT.md +3 -4
- package/claude/skills/canvas/SKILL.md +5 -5
- package/{standards → claude/skills/canvas/references}/canvas.md +12 -1
- package/claude/skills/ci-workflow/REQUIREMENT.md +0 -1
- package/claude/skills/context-fold/REQUIREMENT.md +8 -20
- package/claude/skills/context-fold/SKILL.md +20 -44
- package/claude/skills/context-fold/references/classify.md +7 -8
- package/claude/skills/context-fold/references/completion-report.md +2 -6
- package/claude/skills/context-fold/references/context-refresh.md +5 -15
- package/claude/skills/context-fold/references/promoted-pages.md +3 -3
- package/claude/skills/context-fold/references/receipt-sweep.md +6 -17
- package/claude/skills/context-fold/references/unusable-baseline.md +4 -6
- package/claude/skills/create-rule/REQUIREMENT.md +0 -1
- package/claude/skills/create-skill/REQUIREMENT.md +6 -4
- package/claude/skills/create-skill/SKILL.md +8 -7
- package/{standards → claude/skills/create-skill/references}/skill-paths.md +1 -0
- package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
- package/claude/skills/decision-escalate/SKILL.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +0 -2
- package/claude/skills/design-taste/SKILL.md +1 -3
- package/claude/skills/design-taste/references/vocabulary.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +3 -3
- package/claude/skills/document-health/REQUIREMENT.md +2 -2
- package/claude/skills/document-health/SKILL.md +4 -5
- package/claude/skills/document-health/references/axes.md +4 -6
- package/claude/skills/draft-and-pick/REQUIREMENT.md +16 -14
- package/claude/skills/draft-and-pick/SKILL.md +40 -32
- package/claude/skills/draft-and-pick/references/live-arms.md +9 -9
- package/claude/skills/draft-doc/REQUIREMENT.md +5 -5
- package/claude/skills/draft-doc/SKILL.md +9 -10
- package/claude/skills/draft-doc/references/requirements.md +61 -0
- package/claude/skills/draft-doc/references/wiki-kind.md +53 -0
- package/claude/skills/draft-doc/references/wiki.md +50 -30
- package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
- package/claude/skills/draft-figure/SKILL.md +4 -4
- package/claude/skills/draft-figure/references/architecture-set.md +4 -4
- package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +55 -0
- package/claude/skills/draft-figure/references/mermaid.md +43 -34
- package/claude/skills/draft-identity/REQUIREMENT.md +1 -1
- package/claude/skills/draft-identity/SKILL.md +9 -7
- package/claude/skills/draft-ready/REQUIREMENT.md +1 -1
- package/claude/skills/draft-ready/SKILL.md +6 -6
- package/claude/skills/draft-ready/references/assembly.md +1 -1
- package/{standards → claude/skills/draft-ready/references}/ready.md +13 -5
- package/claude/skills/git-issue/references/issue.md +3 -3
- package/claude/skills/git-ship/REQUIREMENT.md +0 -2
- package/claude/skills/git-ship/SKILL.md +16 -24
- package/claude/skills/plan-feature/SKILL.md +2 -6
- package/{standards → claude/skills/plan-feature/references}/plan.md +9 -10
- package/claude/skills/plan-groundwork/SKILL.md +5 -6
- package/{standards → claude/skills/plan-groundwork/references}/groundwork.md +17 -4
- package/claude/skills/plan-intake/SKILL.md +2 -3
- package/{standards → claude/skills/plan-intake/references}/intake.md +17 -2
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
- package/claude/skills/plan-intake-answer/SKILL.md +1 -1
- package/claude/skills/review-address/SKILL.md +1 -1
- package/claude/skills/review-craft/REQUIREMENT.md +3 -3
- package/claude/skills/review-craft/SKILL.md +2 -2
- package/claude/skills/review-craft/references/ui.md +4 -4
- package/claude/skills/review-pr/REQUIREMENT.md +1 -1
- package/claude/skills/review-pr/SKILL.md +5 -7
- package/claude/skills/review-ui/REQUIREMENT.md +0 -1
- package/claude/skills/review-ui/SKILL.md +1 -1
- package/claude/skills/role-orchestrator/REQUIREMENT.md +0 -3
- package/claude/skills/role-orchestrator/SKILL.md +8 -8
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +3 -3
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +7 -10
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +0 -3
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +1 -1
- package/claude/skills/role-planner/SKILL.md +2 -2
- package/claude/skills/role-reviewer/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +2 -2
- package/claude/skills/session-compact/REQUIREMENT.md +1 -4
- package/claude/skills/session-compact/SKILL.md +3 -13
- package/claude/skills/session-compact/references/handoff-note.md +2 -2
- package/claude/skills/session-map/REQUIREMENT.md +1 -9
- package/claude/skills/session-map/SKILL.md +8 -16
- package/{standards → claude/skills/session-map/references}/session.md +17 -11
- package/claude/skills/session-relay/REQUIREMENT.md +1 -1
- package/claude/skills/session-resume/REQUIREMENT.md +4 -6
- package/claude/skills/session-resume/SKILL.md +3 -9
- package/claude/skills/session-worktree/SKILL.md +1 -1
- package/claude/skills/session-worktree/references/main-root-writes.md +2 -2
- package/claude/skills/systematic-debugging/REQUIREMENT.md +0 -1
- package/claude/skills/target-check/REQUIREMENT.md +3 -3
- package/claude/skills/target-check/SKILL.md +1 -1
- package/claude/skills/target-check/references/domains.md +1 -1
- package/claude/skills/target-setup/REQUIREMENT.md +4 -4
- package/claude/skills/target-setup/SKILL.md +3 -3
- package/claude/skills/target-setup/references/detect.md +1 -1
- package/claude/skills/task-board/SKILL.md +4 -4
- package/claude/skills/task-board/references/archive.md +1 -1
- package/{standards → claude/skills/task-board/references}/board.md +9 -0
- package/claude/skills/task-board/references/decline.md +1 -1
- package/{standards → claude/skills/task-board/references}/tasks.md +13 -8
- package/claude/skills/teach-workspace/SKILL.md +1 -1
- package/claude/skills/teach-workspace/references/revisit.md +1 -1
- package/{standards → claude/skills/teach-workspace/references}/teach.md +17 -5
- package/claude/skills/ux-audit/REQUIREMENT.md +2 -2
- package/claude/skills/ux-audit/SKILL.md +2 -3
- package/claude/skills/write-human/REQUIREMENT.md +0 -1
- package/claude/skills/write-human/SKILL.md +1 -1
- package/docs/agents/audits.md +1 -1
- package/docs/agents/canvas.md +1 -1
- package/docs/agents/commands.md +1 -6
- package/docs/agents/context-audit-checks.md +9 -23
- package/docs/agents/context-audit.md +7 -15
- package/docs/agents/context-classify.md +5 -5
- package/docs/agents/counts.md +5 -5
- package/docs/agents/drift-surfaces.md +2 -2
- package/docs/agents/index.md +3 -5
- package/docs/agents/install-and-sync.md +6 -6
- package/docs/agents/intake.md +1 -1
- package/docs/agents/records-stale.md +5 -5
- package/docs/agents/records-validate.md +1 -1
- package/docs/agents/records.md +2 -2
- package/docs/agents/restated.md +1 -1
- package/docs/agents/rule-citations.md +1 -1
- package/docs/agents/skills-audit.md +2 -2
- package/docs/agents/state-scoped-risk.md +2 -2
- package/docs/agents/superseded.md +2 -2
- package/docs/agents/tasks-plans.md +1 -1
- package/docs/agents/tasks-validate.md +1 -1
- package/docs/agents/tasks.md +1 -1
- package/docs/agents/teach.md +1 -1
- package/docs/agents/upstream.md +26 -2
- package/docs/target/migrations.md +24 -0
- package/docs/target/projects.md +5 -7
- package/docs/target/scenarios.md +2 -2
- package/docs/target/sync.md +3 -3
- package/docs/workflow/ai-workflow.md +7 -38
- package/docs/workflow/index.md +1 -1
- package/docs/workflow/operating-model.md +8 -8
- package/docs/workflow/parallel-features.md +7 -7
- package/docs/workflow/skill-map-on-request.md +12 -15
- package/docs/workflow/skill-map.md +20 -32
- package/docs/workflow/visual-design-workflow.md +11 -14
- package/governance/renames.toml +0 -19
- package/governance/rules/canon/605-worktrees.md +1 -1
- package/governance/rules/{standards → canon}/plan.md +4 -5
- package/governance/rules/canon/tasks.md +18 -0
- package/governance/stacks/base.toml +1 -1
- package/package.json +1 -1
- package/scripts/core/install-check.sh +1 -1
- package/scripts/core/regen-web-previews.ts +1 -1
- package/src/audits/catalog.ts +5 -97
- package/src/claude/cases/authoring.ts +0 -18
- package/src/claude/cases/misc.ts +0 -13
- package/src/claude/cases/setup.ts +3 -20
- package/src/claude/cases/workflow.ts +0 -33
- package/src/claude/seeds.ts +1 -7
- package/src/claude/skills-audit.ts +1 -1
- package/src/cli/help.ts +1 -4
- package/src/cli.ts +0 -4
- package/src/commands/claude.ts +8 -14
- package/src/commands/context.ts +18 -280
- package/src/commands/feedback.ts +22 -91
- package/src/commands/records.ts +5 -5
- package/src/commands/sync.ts +5 -3
- package/src/commands/upstream.ts +135 -0
- package/src/context/audit.ts +5 -14
- package/src/context/classify/extract.ts +6 -13
- package/src/context/classify/patterns.ts +2 -41
- package/src/context/classify/prompts.ts +2 -6
- package/src/context/classify/run.ts +3 -3
- package/src/context/folders.ts +7 -12
- package/src/context/gate.ts +11 -91
- package/src/context/requirements.ts +13 -4
- package/src/counts/scan.ts +3 -3
- package/src/design/components.ts +2 -2
- package/src/feedback/body.ts +0 -12
- package/src/gate/measures.ts +6 -57
- package/src/gov/citations.ts +9 -3
- package/src/gov/restated.ts +3 -3
- package/src/markdown/structure.ts +2 -2
- package/src/migrate/record-layout.ts +3 -3
- package/src/records/ordinal.ts +1 -1
- package/src/records/prune.ts +2 -1
- package/src/records/stale-canonical.ts +2 -2
- package/src/roots/record.ts +1 -1
- package/src/sandbox/scenario.ts +115 -11
- package/src/shipped/references.ts +3 -3
- package/src/standards/read.ts +31 -0
- package/src/sync/seeds-report.ts +1 -1
- package/src/tasks/reach.ts +2 -2
- package/src/tasks/validate.ts +1 -1
- package/src/teach/workspace.ts +1 -1
- package/src/upstream/cursor.ts +1 -1
- package/src/upstream/due.ts +128 -0
- package/src/upstream/releases.ts +2 -1
- package/standards/context.md +3 -5
- package/standards/design.md +2 -3
- package/standards/index.md +0 -22
- package/standards/publish.md +1 -1
- package/standards/skill.md +1 -1
- package/tooling/base/reference.md +1 -1
- package/tooling/claude/reference.md +6 -20
- package/tooling/claude/seeds/.claude/hooks/records-index.sh +8 -20
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +3 -3
- package/tooling/claude/seeds/CLAUDE.md +1 -3
- package/tooling/claude/seeds/canon/REQUIREMENTS.md +2 -9
- package/tooling/web/configs/e2e/screenshot.ts +0 -1
- package/claude/skills/auto-ship/references/review-findings.md +0 -20
- package/claude/skills/bash-cli-script/REQUIREMENT.md +0 -43
- package/claude/skills/bash-cli-script/SKILL.md +0 -53
- package/claude/skills/bash-cli-script/references/template.md +0 -19
- package/claude/skills/canon-operator/REQUIREMENT.md +0 -62
- package/claude/skills/canon-operator/SKILL.md +0 -113
- package/claude/skills/canon-rollout/REQUIREMENT.md +0 -59
- package/claude/skills/canon-rollout/SKILL.md +0 -140
- package/claude/skills/canon-rollout/references/failure-recovery.md +0 -20
- package/claude/skills/context-fold/references/anchor-sweep.md +0 -58
- package/claude/skills/context-fold/references/wireframe-sweep.md +0 -45
- package/claude/skills/create-standard/REQUIREMENT.md +0 -33
- package/claude/skills/create-standard/SKILL.md +0 -31
- package/claude/skills/design-extract/REQUIREMENT.md +0 -42
- package/claude/skills/design-extract/SKILL.md +0 -108
- package/claude/skills/draft-and-pick/references/frame.html +0 -118
- package/claude/skills/draft-doc/references/wireframes.md +0 -48
- package/claude/skills/markdown-propose/REQUIREMENT.md +0 -47
- package/claude/skills/markdown-propose/SKILL.md +0 -122
- package/claude/skills/markdown-propose/references/format.md +0 -118
- package/claude/skills/memory-capture/REQUIREMENT.md +0 -50
- package/claude/skills/memory-capture/SKILL.md +0 -117
- package/claude/skills/memory-review/REQUIREMENT.md +0 -52
- package/claude/skills/memory-review/SKILL.md +0 -129
- package/claude/skills/memory-review/references/later-phases.md +0 -118
- package/claude/skills/memory-review/references/receipt-format.md +0 -64
- package/claude/skills/project-commands/REQUIREMENT.md +0 -42
- package/claude/skills/project-commands/SKILL.md +0 -87
- package/claude/skills/repo-metadata/REQUIREMENT.md +0 -37
- package/claude/skills/repo-metadata/SKILL.md +0 -54
- package/claude/skills/restate-plainly/REQUIREMENT.md +0 -41
- package/claude/skills/restate-plainly/SKILL.md +0 -41
- package/claude/skills/review-branch/REQUIREMENT.md +0 -40
- package/claude/skills/review-branch/SKILL.md +0 -137
- package/claude/skills/seed-sync/REQUIREMENT.md +0 -45
- package/claude/skills/seed-sync/SKILL.md +0 -158
- package/claude/skills/sketch-design/REQUIREMENT.md +0 -38
- package/claude/skills/sketch-design/SKILL.md +0 -94
- package/claude/skills/ux-walkthrough/REQUIREMENT.md +0 -56
- package/claude/skills/ux-walkthrough/SKILL.md +0 -53
- package/claude/skills/ux-walkthrough/references/builds.md +0 -15
- package/claude/skills/ux-walkthrough/references/candidate-pages.md +0 -11
- package/claude/skills/ux-walkthrough/references/measuring.md +0 -22
- package/claude/skills/ux-walkthrough/references/record.md +0 -36
- package/claude/skills/ux-walkthrough/references/relay.md +0 -25
- package/docs/agents/architecture-record.md +0 -36
- package/docs/agents/review-classification.md +0 -76
- package/governance/rules/canon/603-memory.md +0 -11
- package/governance/rules/lang/120-bash.md +0 -18
- package/governance/rules/standards/architecture.md +0 -13
- package/governance/rules/standards/groundwork.md +0 -13
- package/governance/rules/standards/intake.md +0 -12
- package/governance/rules/standards/memory.md +0 -12
- package/governance/rules/standards/ready.md +0 -13
- package/governance/rules/standards/requirements.md +0 -12
- package/governance/rules/standards/session.md +0 -13
- package/governance/rules/standards/tasks.md +0 -15
- package/governance/rules/standards/teach.md +0 -14
- package/governance/rules/standards/wiki.md +0 -13
- package/governance/rules/standards/wireframes.md +0 -13
- package/src/autoship/classify.ts +0 -75
- package/src/autoship/paths.ts +0 -50
- package/src/commands/autoship.ts +0 -129
- package/src/commands/repo.ts +0 -393
- package/src/context/architecture.ts +0 -654
- package/src/context/wireframe-states.ts +0 -238
- package/src/repo/metadata.ts +0 -206
- package/standards/architecture.md +0 -127
- package/standards/memory.md +0 -158
- package/standards/mermaid.md +0 -64
- package/standards/requirements.md +0 -79
- package/standards/wiki.md +0 -77
- package/standards/wireframes.md +0 -143
- package/tooling/claude/seeds/.claude/memory/index.md +0 -8
- package/tooling/claude/seeds/canon/ARCHITECTURE.md +0 -23
- package/tooling/claude/seeds/canon/wireframes/index.md +0 -8
- /package/{standards → claude/skills/create-skill/references}/skill-practice.md +0 -0
- /package/{standards → claude/skills/create-skill/references}/skill-requirement.md +0 -0
- /package/{standards → claude/skills/plan-feature/references}/plan-lifecycle.md +0 -0
- /package/{standards → claude/skills/plan-groundwork/references}/groundwork-spikes.md +0 -0
- /package/{standards → claude/skills/task-board/references}/tasks-decline.md +0 -0
- /package/{standards → claude/skills/teach-workspace/references}/glossary.md +0 -0
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Wrapper template
|
|
2
|
-
|
|
3
|
-
Copy this skeleton for a small non-interactive wrapper. Keep only the parts the task needs, and stop at 100 lines.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
#!/usr/bin/env bash
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
log() { printf '%s\n' "$*" >&2; }
|
|
10
|
-
|
|
11
|
-
die() {
|
|
12
|
-
printf 'error: %s\n' "$*" >&2
|
|
13
|
-
exit 1
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
[ $# -ge 1 ] || die "usage: script.sh <arg>"
|
|
17
|
-
|
|
18
|
-
log "starting"
|
|
19
|
-
```
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: canon-operator
|
|
3
|
-
description: Why the toolkit has one front door, what orienting on live catalogs prevents, and where it hands off
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Canon operator requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, using the toolkit means knowing which skill to pick, and the user who most needs it is the one who cannot. A plain-language intent has no obvious owner among a dozen setup and sync skills, so the session guesses a command instead of resolving one, and a wrong guess installs into a project rather than reporting a mismatch.
|
|
11
|
-
|
|
12
|
-
Two failures come from acting on memory. A session that names a stack or rule from what it remembers rather than from the live catalog runs against an entry that has been renamed or removed. And a session that edits a managed file by hand produces a change the next sync overwrites, which reads as the toolkit undoing work rather than as the edit having been made in the wrong place.
|
|
13
|
-
|
|
14
|
-
The third failure is duplication. A front door that answers everything itself reimplements first-time detection and seed diffing inline, badly, beside the skills that already do both. The value of a router is that it stops at the handoff.
|
|
15
|
-
|
|
16
|
-
A fourth failure sits between the router and what it runs. This skill executes the install and sync commands whose effect on an existing file is invisible from the command line, and the reference stating that effect per surface is named in the boundary below, which Claude Code never loads. The router therefore overwrites a customized golden config with the answer sitting one skill away and unread.
|
|
17
|
-
|
|
18
|
-
The fifth failure is writing without re-checking. A domain sync brought a stricter standard into a target and left ten of its eleven context entries non-compliant in the same moment, and the run reported success because reporting the command was where its work ended. A person found the breakage afterwards by running an audit by hand. The audit that would have caught it is built and reachable from nothing the router offers, so one session held both the defect and its detector and connected neither to the other.
|
|
19
|
-
|
|
20
|
-
The last failure is a section no route reaches. `## Route` maps an intent or a diagnostic finding to one lifecycle phase, so audit offers sitting below that table with no row naming them are unreachable by a correct reading. Two runs asked what the toolkit could measure and both took the scaffold handoff, the row the table declares. A route in settles half of it, since a project carrying a context folder and no installed domain fires the scaffold row and two audit conditions at once, and a body ranking neither leaves the choice to whichever the session read last.
|
|
21
|
-
|
|
22
|
-
## Must
|
|
23
|
-
|
|
24
|
-
- Orient on the toolkit's own docs and the live catalogs before acting
|
|
25
|
-
- Map the stated intent to one lifecycle phase, then either run the simplest command that satisfies it or hand off
|
|
26
|
-
- Resolve every stack, rule, and standard name from a catalog at runtime
|
|
27
|
-
- Run the CLI non-interactively and report the command run, what changed, and the full path of anything written
|
|
28
|
-
- Read the overwrite contract from the body before any install or sync, and name each surface it lists as overwritten before running one
|
|
29
|
-
- Read the reverse walk beside the forward sections, so a folder the toolkit stopped shipping reaches the user
|
|
30
|
-
- Read `unmovedSurfaces` from the report itself, since the drift status ignores it by design, and name `canon migrate surface-roots` without running either form
|
|
31
|
-
- Name an unmigrated domain's root and install path for the user to move themselves, since no skill covers the move
|
|
32
|
-
- Route a measurement intent to the audit offers from the route table itself, rather than leaving the section reachable only by reading past the table
|
|
33
|
-
- Rank a lifecycle row against the audit offers where the route table itself states it, so a session acting on the lifecycle row reads the ranking without opening the section being ranked
|
|
34
|
-
- Offer every audit whose surface the target carries, and offer none whose surface it lacks
|
|
35
|
-
- Hand off an audit that is a skill rather than a command, since the execute contract governs a CLI run and says nothing about a skill's own guards
|
|
36
|
-
- Re-check the target after any operation that wrote, and report what those writes changed against the state read before acting
|
|
37
|
-
|
|
38
|
-
## Must not
|
|
39
|
-
|
|
40
|
-
- Edit a managed file by hand instead of running the CLI that owns it
|
|
41
|
-
- Reimplement a flow another skill owns
|
|
42
|
-
- Hardcode a catalog name
|
|
43
|
-
- Move, delete, or name a command against a folder in `unclaimed`. The toolkit stopped claiming the path and only the user knows whether the project owns what sits there
|
|
44
|
-
- Run an audit the user did not pick, which turns a front door into a full sweep
|
|
45
|
-
- Refuse to finish an operation over an audit finding, since every audit reports judgments beside facts and a router that stops on one is a router a target works around
|
|
46
|
-
- Auto-trigger. It is a door the user opens, and a router that fires on its own routes requests nobody made.
|
|
47
|
-
|
|
48
|
-
## Guards
|
|
49
|
-
|
|
50
|
-
- An intent matching a deep flow hands off rather than running a shallow version of it, since a partial scaffold is harder to recover from than none
|
|
51
|
-
- An ignore-only fix on an unmeasured tooling report stops, names which cause applies, and names the command answering that cause. Unmeasured has several causes and they do not share a remedy, so one suggested command is wrong for at least one of them. No cause asks the user to supply a stack name, and none reads the zero counts under an unmeasured report as a clean target.
|
|
52
|
-
- A re-check with no earlier report to compare against says the write ran without a baseline, rather than describing the target from scratch
|
|
53
|
-
- A report missing a field this skill reads names the CLI version as the cause and reports that section as unread. Neither an absent key nor a hand-rolled substitute for it may be reported as a finding, since the first reads as a clean target and the second reaches a verdict only the field's attribution can make
|
|
54
|
-
|
|
55
|
-
## Out of scope
|
|
56
|
-
|
|
57
|
-
- First-time scaffold of a fresh project: `target-setup`
|
|
58
|
-
- Seed and preamble drift in installed files: `seed-sync`
|
|
59
|
-
- Governance rule install and index bootstrap: `target-setup`, on its `gov` and `indexes` phases
|
|
60
|
-
- What a given sync overwrites once it runs: `canon-cli`
|
|
61
|
-
|
|
62
|
-
That last contract carries no row for the governance install this skill routes to, so the overwrite `Must` above reads nothing at one of its own destinations. The row belongs to the skill owning the table. This file records the silence rather than answering it, since a rule written here for a silent contract teaches a session that silence means safe.
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: canon-operator
|
|
3
|
-
description: Front door to the toolkit in a target project. Orients on the toolkit's own docs and live `canon` catalogs, then runs or routes any toolkit operation from a plain-language intent. Use when you want one entry point instead of picking a specific setup or sync skill, or when asked to "use the toolkit", "what can the toolkit do", "sync my standards", "install rules", or "help me set up this project". User-invoked only. Defers first-time scaffold to setup and seed drift to seed-sync.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
metadata:
|
|
6
|
-
family: setup
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Canon operator
|
|
10
|
-
|
|
11
|
-
Front door to the toolkit. Orient first, then run the simplest operation that satisfies the intent or hand off to the owning skill. Never bypass `canon` to edit managed files by hand.
|
|
12
|
-
|
|
13
|
-
## Orient
|
|
14
|
-
|
|
15
|
-
Run these from the target project root, in parallel, before acting:
|
|
16
|
-
|
|
17
|
-
- `canon docs list`: the index of toolkit reference docs
|
|
18
|
-
- `canon docs agents`: the CLI command catalog and invocation contract
|
|
19
|
-
- `canon docs projects`: the scaffold, add-a-domain, and sync lifecycle
|
|
20
|
-
|
|
21
|
-
Load a domain doc with `canon docs <topic>` only when the intent touches that domain. Read the live catalog for any domain you act on with `canon <domain> list --json`. Never hardcode stack, rule, or standards names.
|
|
22
|
-
|
|
23
|
-
## Diagnose
|
|
24
|
-
|
|
25
|
-
Run `canon sync --check . --json` before routing. It reports what a target is behind on across every surface, so the intent comes from the project state rather than from the user having to know it already. Skip only when the user named a single operation to run.
|
|
26
|
-
|
|
27
|
-
Read eight fields off the report and carry each to `## Route`:
|
|
28
|
-
|
|
29
|
-
- `unmigrated`: a domain sitting at the root layout with nothing under `.claude/`. The most urgent finding, because that domain reports no drift of its own while being entirely behind
|
|
30
|
-
- `superseded`: a file a newer seed folder replaced. No command moves it, since the content is the project's own, so this routes to `canon:target-check` for the full per-domain reading rather than ending at the report
|
|
31
|
-
- `unmovedSurfaces`: a surface held only at its `.claude/` spelling, each entry carrying `rel` and `movesTo`. Every other field reads clean for such a target, and the report's drift status ignores it by design, so read the array itself rather than an exit status
|
|
32
|
-
- `seeds`: entries are `matching`, `stale`, `drifted`, or `missing`. Anything but `matching` needs the seed handoff
|
|
33
|
-
- `domains[].entries`: per-file `stale`, `customized`, `stranded`, and `orphaned` as before, plus `retired` for a rule the toolkit no longer ships, which the next sync deletes
|
|
34
|
-
- `reverse`: what the target holds that no live catalog claims. `unclaimed` lists folders at roots the toolkit stopped shipping, each with an `attribution` of `dropped`, `unattributed`, or `project`. Act on the first two and leave `project` alone, which history proved the project owns
|
|
35
|
-
- `historyUnavailable` on a domain, on `seeds`, or on `reverse`: nothing could be dated, so treat every difference as unverified and say so rather than reporting a file as untouched. It is set on `reverse` when the toolkit itself ships without history, which is the registry-install case, so the walk found nothing rather than finding a clean target
|
|
36
|
-
- `tooling`: read `measured` first. Every count under it is zero when it is false, which is an absence of measurement rather than a measured zero. Past that, `chain` names the stacks the install resolved, nearest first, and `counts.gitignore` counts the managed ignore entries the target is missing.
|
|
37
|
-
|
|
38
|
-
State what the report found in one line per finding before acting on any of it.
|
|
39
|
-
|
|
40
|
-
An `unmovedSurfaces` key the report does not carry at all is likewise a CLI predating the field rather than a target with nothing to move. Say the section was unread and name the installed CLI version as the cause.
|
|
41
|
-
|
|
42
|
-
A `reverse` key the report does not carry at all is a CLI predating the field rather than a target with nothing unclaimed. Say the walk did not run and name the CLI version as the cause. Reading the absent key as an empty answer reports a clean target to a project nobody has looked at, and answering it from a filesystem walk of your own is worse, since that reaches a verdict the attribution the field carries is the only thing entitled to make.
|
|
43
|
-
|
|
44
|
-
## Route
|
|
45
|
-
|
|
46
|
-
Map the stated intent, or what `## Diagnose` found, to one lifecycle phase, then act.
|
|
47
|
-
|
|
48
|
-
The two can name different rows, and a reply answers both rather than picking one. Run or hand off what the finding names, then answer the intent in the same reply. A measurement intent therefore reaches the audit offers below even on a target whose diagnostic found scaffold work, which is the case a session leaving from the scaffold row would otherwise never read.
|
|
49
|
-
|
|
50
|
-
- A domain in `unmigrated`: name it, the root path, and the install path. No command moves it, so the user runs the relocation themselves
|
|
51
|
-
- Anything in `superseded`: name which files and what replaced them, then hand off to `canon:target-check`, which reports and never moves or deletes the file
|
|
52
|
-
- Anything in `unmovedSurfaces`: name `canon migrate surface-roots`, which only reports its plan until `--write` is passed, with each entry's `rel` and `movesTo`, and run neither form, since the move rewrites tracked paths
|
|
53
|
-
- A folder in `unclaimed`: name it and the attribution it carries. No command moves it and the content may be the project's own, so the decision is the user's
|
|
54
|
-
|
|
55
|
-
- First-time scaffold of a fresh project: hand off to `target-setup`
|
|
56
|
-
- Governance rules for the project stack: hand off to `target-setup`, which installs them alone on its `gov` phase
|
|
57
|
-
- Bootstrap the `index.md` system: hand off to `target-setup`, which bootstraps it on its `indexes` phase
|
|
58
|
-
- Seed or standards drift in `CLAUDE.md` or `.claude/` preambles: hand off to `seed-sync`
|
|
59
|
-
- Install one rule: run the domain `install` command
|
|
60
|
-
- Sync one domain or every installed domain: run `canon <domain> sync` or `canon sync`
|
|
61
|
-
- Fix only the ignore entries of the installed stack: run `canon tooling inject --gitignore <stack>`
|
|
62
|
-
- Measure a surface without changing it: offer the audits under `### Audits`
|
|
63
|
-
- Browse what is available: run `canon <domain> list`
|
|
64
|
-
|
|
65
|
-
### The ignore-only row
|
|
66
|
-
|
|
67
|
-
The ignore-only row runs on a measured tooling report alone, so `measured` decides before `chain` is read at all. A false one splits three ways. Report tooling as unmeasured in each, name the cause, and run nothing, since the zero counts underneath are unmeasured rather than clean:
|
|
68
|
-
|
|
69
|
-
- An empty `chain` at a workspace root, which carries `pnpm-workspace.yaml` or a `workspaces` key in `package.json`: no chain is recorded there by design, since one would guess at what the packages hold. Name `canon tooling sync <stack> <path>` against a package.
|
|
70
|
-
- An empty `chain` anywhere else: no tooling install is recorded, so name `canon tooling sync` as the command that records one rather than asking the user for a stack.
|
|
71
|
-
- A `chain` carrying names: this toolkit no longer ships those stacks. Name them, since injecting would write against a retired name.
|
|
72
|
-
|
|
73
|
-
On a measured report, take `<stack>` from the first name in `tooling.chain`, which records the stack nearest the target. Inject re-resolves that leaf's own chain, so a target whose recorded chain is shorter receives the entries from the layer its install skipped. Say so before running it.
|
|
74
|
-
|
|
75
|
-
### Audits
|
|
76
|
-
|
|
77
|
-
Five audits measure a surface without changing it. Offer the ones whose surface the target carries, list them together, and let the user pick. Run none of them unasked, and never treat a finding as a reason to abandon the operation the user asked for, since each reports judgments beside facts.
|
|
78
|
-
|
|
79
|
-
A lifecycle row and these offers fire together on a project carrying a context folder and no installed domain, which is the ranking the preamble states. Scaffold work on a target with nothing installed is real work, so an audit offered instead of it answers a question nobody asked, while an audit dropped in favor of it loses the one the user did.
|
|
80
|
-
|
|
81
|
-
- `canon/context/` present: offer `canon context audit`
|
|
82
|
-
- A record folder present under `.claude/`, one of `plans`, `groundwork`, `intake`, or `memory`: offer `canon records validate <kind>` for each one found
|
|
83
|
-
- Markdown that git lists: offer `canon markdown audit`
|
|
84
|
-
- TypeScript or shell source present: offer `canon comments scan`
|
|
85
|
-
- A `package.json` script that serves an interface, one of `dev`, `preview`, `serve`, or `start`: offer `ux-measure`
|
|
86
|
-
|
|
87
|
-
An audit offered against a surface the target lacks reports an empty run as a finding, which is the same defect as never offering it at all. Check the surface before naming the command.
|
|
88
|
-
|
|
89
|
-
The markdown row is the one every target satisfies, since a project with no markdown is not one this reaches. Its condition is stated so the five rows read alike, and the row needs no gate beyond it.
|
|
90
|
-
|
|
91
|
-
The last row is a skill handoff rather than a command, so `## Execute` does not govern it. Hand it off and stop, the way a lifecycle row hands off. Its condition reads a serving command rather than a source folder, since that skill measures what a browser receives and never opens the tree behind it. It carries a second condition this skill cannot read, which is a browser harness the project already installed, and the skill itself reports what it needs when it finds none. Testing for that here would put the detection in two places and let this one answer stale.
|
|
92
|
-
|
|
93
|
-
## Execute
|
|
94
|
-
|
|
95
|
-
For operations this skill runs directly:
|
|
96
|
-
|
|
97
|
-
- Read the catalog first with `canon <domain> list --json`, then match against project context
|
|
98
|
-
- Read the `canon-cli` skill before any install or sync, and warn the user by name about each surface it lists as overwritten. A command name says nothing about what it does to a file already there, and this skill is the one running it.
|
|
99
|
-
- Run the CLI with `CANON_NON_INTERACTIVE=1` so it skips prompts. The tool permission dialog is the confirmation gate.
|
|
100
|
-
- Report the command run and what changed. Emit the full relative path for any file written.
|
|
101
|
-
- Re-run `canon sync --check . --json` after any operation that wrote, and compare it against the report `## Diagnose` read before acting
|
|
102
|
-
- Report the fields that moved and name the write that moved each one. Do not restate the second report, since the value sits in the difference alone.
|
|
103
|
-
- State a field that moved the wrong way and leave it for the user to decide on. The re-check reports and never repairs.
|
|
104
|
-
|
|
105
|
-
A write can leave a target worse in a field the write never named, which stays silent while the operation itself succeeds. The re-check is what makes that visible, so it runs before the operation is reported as done.
|
|
106
|
-
|
|
107
|
-
The comparison needs the earlier report. When `## Diagnose` was skipped because the user named a single operation, say the write ran with no baseline rather than describing the target from scratch, which would attribute differences another session made to this run.
|
|
108
|
-
|
|
109
|
-
## Boundaries
|
|
110
|
-
|
|
111
|
-
- Run `canon`. Never reimplement its install or sync logic, and never edit managed files like rules, configs, or seeds by hand.
|
|
112
|
-
- Hand off the deep flows. Do not duplicate `target-setup` detection or `seed-sync` part-diffing inline.
|
|
113
|
-
- Resolve names from catalogs at runtime. A hardcoded name is a bug.
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: canon-rollout
|
|
3
|
-
description: Why one skill carries both roles of an outbound wave, and where its boundary sits against the seven skills that operate inside a target
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Canon rollout requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a toolkit change reaches its consuming projects by hand. One measured pass across four targets took four hand-written `cd <path> && claude --bg` invocations, each carrying a brief composed by hand from that project's review. Nothing enumerated the targets, nothing derived the brief, and nothing applied a convention across the set.
|
|
11
|
-
|
|
12
|
-
The conventions were already settled and reached none of the four. The branch and title shape was answered and reconfirmed, and the four pull requests carried four titles across two scopes, neither of them the settled one, with three naming the toolkit in the half of the shape that withholds it. A convention nothing applies holds only where somebody remembers it.
|
|
13
|
-
|
|
14
|
-
The return leg dead-ends outside this repository. A review that posts a finding on a target's pull request has to reach the session holding that branch, and every dispatch guessed instead. All four sessions that opened those pull requests were still alive holding their worktrees hours later, two fresh addressers were sent over them, one refused on the worktree lock, and one cut a second worktree on the same branch, which would have put two sessions pushing to one ref.
|
|
15
|
-
|
|
16
|
-
A wave ends without telling the operator what to do. Reading where four targets stood took a hand-written shell loop over four repositories, re-run three times as reviews landed, and every status line it produced named a repository and a number and no link. Merging is the one act only the operator performs, and they reached each result by navigating to it by hand.
|
|
17
|
-
|
|
18
|
-
A worker's reply reads as done when it is not. One pull request's fix for two minor findings closed both and introduced four more, all in prose the fix added, including a claim about a workflow that runs on a trigger it does not declare. A loop that closes a target on the worker's word merges that.
|
|
19
|
-
|
|
20
|
-
## Must
|
|
21
|
-
|
|
22
|
-
- Enumerate the targets from the record the install writes, with the sweep as the fallback and its stated bound read before any count is trusted, since a hand census of this population was wrong in both directions at once
|
|
23
|
-
- Write the branch and the title from a fixed shape rather than leaving either to the dispatched session, since the settled convention reached none of four hand-driven repairs
|
|
24
|
-
- Carry one line in each target's body naming the toolkit as the source and where to change the content upstream, since a reader in that repository has no other route to the fact that a local edit is lost at the next wave
|
|
25
|
-
- Name no toolkit version in any target's body, since the install stamp in that target already records `syncedAt` and a sha256 per synced file and a version string is the copy that goes stale
|
|
26
|
-
- Dispatch one worker per target, with the branch checked as unclaimed in that target before the launch
|
|
27
|
-
- Branch from the clone that is current rather than from whichever the record names first, since a working copy answers what that machine last pulled rather than what the target holds
|
|
28
|
-
- Resolve who holds a branch before dispatching an addresser, and dispatch a fresh one only where the resolver reports the owning session gone
|
|
29
|
-
- Address every finding whatever its severity, and close a target only when a narrow re-review posts `## Review closed`
|
|
30
|
-
- Name a pull request URL on every line that reports a target, at dispatch and at hand-back both
|
|
31
|
-
- Close a wave by naming every target with its URL, review heading, CI state, and what is owed, the targets needing nothing included
|
|
32
|
-
|
|
33
|
-
## Must not
|
|
34
|
-
|
|
35
|
-
- Merge anything, in either role, at any size. The operator holds that gate over every role rather than as a setting on a wave.
|
|
36
|
-
- Reimplement what `canon targets list`, `canon targets pulls`, or `canon sessions list --repository` already answers. Each is a shipped verb this body reads under `CANON_NON_INTERACTIVE=1`.
|
|
37
|
-
- Restate the in-target diagnosis and routing that `canon-operator` owns, or the review, address, and worktree procedures the three skills named below own
|
|
38
|
-
- Read or write this repository's task board. The board is `role-orchestrator`'s subject and a wave is not a row on it.
|
|
39
|
-
- Bound the review and address loop with a count. The bound was declined with its failure mode stated, and what guards the loop is the orchestrator reviewing every round itself.
|
|
40
|
-
- Edit a managed file in a target by hand rather than through the `canon` verb that owns it
|
|
41
|
-
- Be a skill nothing invokes but its author typing the name. Nothing else routes to it, since it carries `disable-model-invocation: true` and no sibling body names it, so a wave that only ever runs when somebody types the name is the signal that the loop never replaced the hand-driven pass it was built against.
|
|
42
|
-
|
|
43
|
-
## Guards
|
|
44
|
-
|
|
45
|
-
- `gh` absent: stop, since no target's pull request can be read or opened
|
|
46
|
-
- The target index reads as unknown with no sweep behind it: stop and name the reason, rather than reporting a population of zero
|
|
47
|
-
- The claim check refuses or comes back with either readability flag false: treat the target as unverified rather than clear and hand it to the operator
|
|
48
|
-
- Every clone of a target is behind its remote: refuse that target rather than branching from a stale base
|
|
49
|
-
- More than one session holds a target's branch: report the ambiguity and stop, rather than sending findings to whichever row came first
|
|
50
|
-
|
|
51
|
-
## Out of scope
|
|
52
|
-
|
|
53
|
-
- This repository's own board, queue, and worker dispatch, which `role-orchestrator` holds
|
|
54
|
-
- The role a session building one branch under one plan in this repository takes, which `role-worker` holds. A rollout worker does not take it, since that body resolves session scratch against a main worktree root a target does not carry.
|
|
55
|
-
- Entering the worktree, which `session-worktree` owns, including the branch collision tests it runs before entry
|
|
56
|
-
- Diagnosing what a target is behind on and routing each finding to its command, which `canon-operator` owns
|
|
57
|
-
- Posting a review to a pull request and moving its heading, which `review-pr` owns
|
|
58
|
-
- Answering a posted review inside the target, which `review-address` owns
|
|
59
|
-
- The commit and the pull request mechanics, which the `git-*` family owns
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: canon-rollout
|
|
3
|
-
description: Takes one toolkit change out to every consuming project and brings each to a mergeable pull request. Carries an orchestrator role that enumerates the targets, dispatches a worker into each, reviews every pull request, and routes what each review posts, and a worker role that builds inside one target and answers its review. Use when asked to "roll this out to the targets", "take this change to every project", "run a rollout wave", "update the consuming projects", or when a session was dispatched into a target by a wave. Do NOT use for this repository's own board, which is `role-orchestrator`, and merge nothing.
|
|
4
|
-
disable-model-invocation: true
|
|
5
|
-
metadata:
|
|
6
|
-
family: upkeep
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Canon rollout
|
|
10
|
-
|
|
11
|
-
This skill runs outward. Every other skill for operating on a target assumes the session already sits inside it, and this one starts in the toolkit and reaches the projects the toolkit installed into.
|
|
12
|
-
|
|
13
|
-
One wave takes one toolkit change to every target and ends with a pull request per target for a person to merge. Two roles carry three phases over one target list. The orchestrator enumerates, dispatches, reviews, and routes. The worker holds one target from the worktree entry to the merge of the branch it opened.
|
|
14
|
-
|
|
15
|
-
`role-orchestrator` owns this repository's own board and is a different subject. Read nothing from `.canon/tasks/` here and write nothing to it.
|
|
16
|
-
|
|
17
|
-
## Take a role before anything else
|
|
18
|
-
|
|
19
|
-
- The invocation or the launch prompt names the worker role, a target path, or both: worker. Skip to `## The worker role` and run no phase above it.
|
|
20
|
-
- Neither is named: orchestrator. Run the three phases in order.
|
|
21
|
-
|
|
22
|
-
The role is read off the prompt because nothing else carries it. A test on the working directory answers the same for a worker in a target and an operator who invoked this from one, and reading the role wrong starts a second wave from inside a consuming project.
|
|
23
|
-
|
|
24
|
-
Do not invoke `canon:role-worker` from either role. That body states the role for a session building one branch under one plan in this repository, and it resolves session scratch against a main worktree root a target does not carry, so a rollout worker reading it hunts for a plan nobody wrote.
|
|
25
|
-
|
|
26
|
-
## Guards
|
|
27
|
-
|
|
28
|
-
- `gh` absent from the path: stop. `❌ gh is not installed, so no target's pull request can be read or opened.`
|
|
29
|
-
- `canon targets list` refuses, or reports the index as unknown with no `--sweep` behind it: stop and name the reason. A count of zero taken from an index nothing read is a confident wrong answer.
|
|
30
|
-
- Read a record's own `reason` field rather than a command's exit status. An operator's shell profile may wrap `canon` in a function whose status comes from a trailing command, which reports every refusal as success.
|
|
31
|
-
- Neither role merges anything, at any size and with no proportionality exception. A wave ends by handing the operator a list to merge from, and merging is the one act only they perform.
|
|
32
|
-
|
|
33
|
-
## The fixed shape every target receives
|
|
34
|
-
|
|
35
|
-
Every target in every wave takes the same branch and the same title, written from here rather than chosen per session.
|
|
36
|
-
|
|
37
|
-
- Branch: `chore/agents`, in every target and every wave.
|
|
38
|
-
- Title: `chore(agents): <what changed in that target>`.
|
|
39
|
-
- Body: the sections `${CLAUDE_SKILL_DIR}/../../standards/pr.md` fixes, describing what that target received.
|
|
40
|
-
- Body, one line: name this toolkit as the source of the changed files and where to change the content upstream. A reader in that repository months later has no other route to the fact that these files are toolkit-managed and that a local edit is lost at the next wave.
|
|
41
|
-
- Body, no version number anywhere in it. `${CLAUDE_SKILL_DIR}/../../standards/versioning.md` permits a semver tag only where the pull request cuts a release, and `canon/config/config.json` in the target already records `syncedAt` and a sha256 per synced file. A version in the body is a second copy of a fact the target holds canonically, and it is the copy that goes stale while the pull request sits open.
|
|
42
|
-
|
|
43
|
-
The title withholds the source and the body supplies it, because the two have different audiences. `agents` says what changed without saying where it came from, which is what a target's own history wants, and the source line is for a reader inside that repository rather than for whoever merges.
|
|
44
|
-
|
|
45
|
-
One branch name across every target is also what lets the return leg resolve. `canon sessions list --branch chore/agents --repository <clone>` answers about that project rather than the working one, and a branch each session named for itself gives that read nothing to match.
|
|
46
|
-
|
|
47
|
-
## Phase 1: enumerate and dispatch
|
|
48
|
-
|
|
49
|
-
### Read the population
|
|
50
|
-
|
|
51
|
-
1. Pin the wave. Record the commit of this repository that the wave carries and name it in this session's own reports. Name it in no target's body.
|
|
52
|
-
2. Enumerate. Run `canon targets list --json` under `CANON_NON_INTERACTIVE=1`, adding `--sweep <root...>` to reach targets installed before the index existed. Read the `bound` object back before treating any count as the population, since it names the roots walked, the depth, where the walk stopped, and what it could not read. The bound a sweep can never state is the machine, so a target on another one sits outside every answer it gives.
|
|
53
|
-
3. Pick the clone that is current. A row carries every checkout of that project under `paths` and leads with the one a sync ran in, which records where an install happened rather than what the checkout holds today. Fetch each candidate, compare it against the origin's default branch, and dispatch into one that is level. Refuse one that is behind rather than branching from a stale base, since a stale clone reads as still owing a repair its remote already carries.
|
|
54
|
-
|
|
55
|
-
### Check, then dispatch
|
|
56
|
-
|
|
57
|
-
4. Check the branch is unclaimed in that target. Run `canon sessions list --branch chore/agents --repository <clone> --json` and read `claimed` off the record.
|
|
58
|
-
- `claimed: true`: something already holds it. Report what does, `worktree` when it names a path, `sessions` when it carries a row, and `refs` when the branch already exists, then leave that target out of the wave rather than colliding.
|
|
59
|
-
- `claimed: false` with `sessionsReadable` and `refsReadable` both true: dispatch.
|
|
60
|
-
- Anything else, a refusal or a record carrying no `claimed` key included: treat the target as unverified rather than clear, name which reading could not be taken, and hand it to the operator to launch by hand. Dispatching on a check that could not be read reproduces the collision the check exists to prevent.
|
|
61
|
-
5. Dispatch one worker per target, one session each.
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
cd <clone> && claude --bg --model <model> -n "rollout-<target>" "Run /canon:canon-rollout in the worker role against the target at <clone>. <what the wave carries>"
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`--bg` returns immediately, `-n` sets the name that separates a wave's worker from an operator's own launch in the roster, and `--model` overrides the inheritance that otherwise spends this session's model on every worker. Keep the `rollout-` prefix.
|
|
68
|
-
|
|
69
|
-
Running the targets in turn is the alternative and it puts every target's diff through one session's context. A wave's spend scales with the target count instead, and nothing caps it, so weigh the count before widening rather than after.
|
|
70
|
-
|
|
71
|
-
Report each dispatch by naming the target, the clone, the branch, the model, and the session name. Carry the pull request URL into every later report from the moment its worker announces one.
|
|
72
|
-
|
|
73
|
-
## Phase 2: review every pull request
|
|
74
|
-
|
|
75
|
-
1. Poll. Run `canon targets pulls --json`, naming the wave's clones as arguments to read those alone. A target comes back as `read` with a `pulls` array or as `refused` with a `reason`, and a refusal is not a target with no work. Reading a failed query as no open work reports a target as done having read nothing.
|
|
76
|
-
2. Review here, in this session. Invoke `canon:review-pr` and redirect every call that body makes, since it resolves a pull request from the repository the session stands in and this session stands in the toolkit. Every call takes a redirect, and the ones that silently answer about the wrong repository are worse than the ones that fail:
|
|
77
|
-
- `--repo <owner>/<name>` on `gh pr view`, `gh pr diff`, and `gh pr review`, where it is a global flag.
|
|
78
|
-
- `-C <clone>` on `git fetch origin pull/<n>/head`, `git merge-base`, `git diff`, `git log`, `git show`, and `git grep`.
|
|
79
|
-
- `GH_REPO=<owner>/<name>` on any `gh api repos/{owner}/{repo}/...` call, which is the close-out route. `gh api` takes no `--repo` flag and fills those placeholders from the working directory or from that variable, so the one call a flag cannot redirect is the one that edits a review in place.
|
|
80
|
-
- That project's own root file, rules, and context, read from under the clone.
|
|
81
|
-
|
|
82
|
-
A missed redirect reports rather than fails. A pass that redirects the `gh` half and leaves a `git` call alone reads this repository's history against a target's diff and reports a delta, which is a finding nobody can trace back to the call that produced it.
|
|
83
|
-
|
|
84
|
-
This session wrote none of these diffs, so reviewing them costs nothing in independence.
|
|
85
|
-
|
|
86
|
-
3. Dispatch a reviewer into the target when a diff is too large for this session to hold. That is the fallback rather than the default. Dispatching one per target was measured and what it saved was reading four diffs, not reading four sets of findings, and that second half reaches this session either way, since routing a finding back means composing the brief from it.
|
|
87
|
-
4. Read the heading each pass posted. `canon targets pulls` reports `review` as `open`, `closed`, or `null` when no pass has landed, and reports `reviewReadable` as `false` when the query failed, which leaves `review` covering nothing.
|
|
88
|
-
|
|
89
|
-
## Phase 3: route every finding and close each target
|
|
90
|
-
|
|
91
|
-
1. Address every finding whatever its severity. A minor is a finding, and a reviewer calling one non-blocking does not close the pass that raised it.
|
|
92
|
-
2. Resolve who holds the branch before dispatching anybody. Run `canon sessions list --branch chore/agents --repository <clone> --json` and read the count rather than the first row.
|
|
93
|
-
- A live session holds it: send that session the findings and name `canon:review-address` for it to run, which is step 7 of `## The worker role` and the step that session already stands at. Never name this skill in that message. This body carries `disable-model-invocation: true`, which blocks the `Skill` tool rather than only suppressing an auto-trigger, and a session acting on an inbound message reaches a skill that way and no other, so a message naming this one halts the address leg with the branch built and the findings unread. A launch prompt is the one route to a flagged body, which is why the dispatch above names this skill and this message must not. Never assume the worker is gone, since a fresh addresser sent over a live one either refuses on the worktree lock or cuts a second worktree on the same branch.
|
|
94
|
-
- No live session holds it: dispatch a fresh worker into that clone and brief it with the findings, since it holds none of the reasoning behind the diff.
|
|
95
|
-
- More than one row: report the ambiguity and stop rather than picking among candidates.
|
|
96
|
-
3. Re-review when the answer lands, scoped to the commits added since. A worker's reply never closes a target, since a fix can introduce findings of its own in the prose it adds.
|
|
97
|
-
4. A target leaves the wave when a pass posts `## Review closed` and not before.
|
|
98
|
-
5. Run until every target closes. No count bounds the loop. What guards it is this session reviewing every round itself, so it holds what each pass found and can see a target failing to converge, where a dispatched reviewer reads one pass and knows nothing of the one before it. A worker introducing a finding per fix has nothing mechanical stopping it, which is accepted rather than overlooked.
|
|
99
|
-
|
|
100
|
-
## The worker role
|
|
101
|
-
|
|
102
|
-
One session, one target, from the worktree entry to the merge of the branch it opened. It diagnoses, implements, opens the pull request, and answers what the review posts. It reviews nothing and it merges nothing.
|
|
103
|
-
|
|
104
|
-
1. Confirm the clone is current. Fetch, then compare against the origin's default branch. Report a checkout that is behind and stop, rather than branching from a stale base.
|
|
105
|
-
2. Enter a worktree. Invoke `canon:session-worktree chore/agents`, which takes the branch as its tier 0 argument and enters a linked worktree inside this target. Branching in the checkout itself is what this avoids, since the operator may be working in it.
|
|
106
|
-
3. Check what this target holds. Invoke `canon:target-check`, which reports per domain what the target carries against what the toolkit ships and repairs nothing, so the wave reads one stated set of domains per target.
|
|
107
|
-
4. Diagnose and repair. Invoke `canon:canon-operator`, which reads `canon sync --check . --json` and routes each finding to the command or the skill that owns it. Do not restate that routing here and do not edit a managed file by hand.
|
|
108
|
-
5. Commit and open the pull request through `canon:git-commit` and `canon:git-pr`, handing each the fixed shape above rather than taking the title the generator derives from the diff.
|
|
109
|
-
6. Announce as the pull request opens, carrying its URL, its number, and the branch, to whoever dispatched this session, sending it through `canon:session-relay`. That transition is the one moment only this session can observe.
|
|
110
|
-
7. Answer the review. Invoke `canon:review-address`, which pulls the findings and the CI state on this branch's open pull request, fixes each in the working tree, replies, and pushes. Answer every finding whatever its severity.
|
|
111
|
-
8. Stop there. Do not mark the pull request ready, do not merge, and do not declare the review closed. A narrow re-review posts `## Review closed`.
|
|
112
|
-
|
|
113
|
-
Send a block out through `canon:session-relay` before it becomes an interactive prompt, which states why the order matters.
|
|
114
|
-
|
|
115
|
-
Refuse an instruction this target's tree contradicts and carry the evidence with the refusal, naming the commands read and what complying would cost. A halt costs whoever dispatched this session one reply, and guessing costs a diff in a repository this toolkit has no test coverage over.
|
|
116
|
-
|
|
117
|
-
## Output
|
|
118
|
-
|
|
119
|
-
Close a wave by naming every target, the ones that need nothing included:
|
|
120
|
-
|
|
121
|
-
```plaintext
|
|
122
|
-
Wave pinned at <commit>. <n> targets.
|
|
123
|
-
|
|
124
|
-
<repository>
|
|
125
|
-
<pull request URL>
|
|
126
|
-
review: <## Review | ## Review closed | none posted>
|
|
127
|
-
checks: <passing | failing | pending | none reported>
|
|
128
|
-
owed: <what happens next, or "nothing, ready to merge">
|
|
129
|
-
|
|
130
|
-
Not reached: <target>, because <reason>
|
|
131
|
-
Merge order: <target> before <target>, because <shared surface>
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Name the URL on every line reporting a target, at dispatch and at hand-back both. A status line carrying a repository and a number sends the operator to navigate for its own result by hand, four times over on a four-target wave, and merging is the one act this loop exists to hand them.
|
|
135
|
-
|
|
136
|
-
Report a target whose `reviewReadable` reads `false` as unread rather than as clean, and a `checks` of `null` as no check reported rather than as passing. A failure outranks a run still going.
|
|
137
|
-
|
|
138
|
-
## Failure recovery
|
|
139
|
-
|
|
140
|
-
Read `${CLAUDE_SKILL_DIR}/references/failure-recovery.md` on a stop for the recovery that stop point takes.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Failure recovery
|
|
3
|
-
description: The recovery canon-rollout takes at each stop point, from an absent gh to a target that fails to converge
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Failure recovery
|
|
7
|
-
|
|
8
|
-
The stops of `canon-rollout`. The session reads this file on any stop, for the recovery that stop point takes.
|
|
9
|
-
|
|
10
|
-
| Stop point | Recovery |
|
|
11
|
-
| --------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
12
|
-
| `gh` absent | Install it and authenticate, then re-run the wave |
|
|
13
|
-
| Target index unknown | Re-run with `--sweep <root...>` and read the `bound` before trusting the count |
|
|
14
|
-
| Every clone of a target is behind | Pull that clone, or name a current one, then dispatch that target alone |
|
|
15
|
-
| Claim check refuses or reads unverified | Launch that target's worker by hand and report that it went out outside the check |
|
|
16
|
-
| Branch already claimed in a target | Resolve what holds `chore/agents` there, then dispatch that target alone |
|
|
17
|
-
| A target refuses the pull read | Read the `reason`, repair it, and re-poll that target. Never record it as having no work |
|
|
18
|
-
| Diff too large to review here | Dispatch a reviewer into that clone and route its findings back through Phase 3 |
|
|
19
|
-
| Two sessions hold one branch | Report both and stop. Sending findings to either puts two sessions on one ref |
|
|
20
|
-
| A target fails to converge | Stop that target's loop, report the rounds it took and what each pass found, and hand it over |
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Architecture anchor staleness sweep
|
|
3
|
-
description: How an anchored decision's cited paths are collected, the finding the diff fires, and the report line
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Architecture anchor staleness sweep
|
|
7
|
-
|
|
8
|
-
Mechanics for Step 5 of `context-fold`. The body owns the skip conditions, the report-only constraint, and the standard citation, and this file owns what the sweep does once the diff touches a path an anchored decision cites.
|
|
9
|
-
|
|
10
|
-
## Anchored entries
|
|
11
|
-
|
|
12
|
-
Read `canon/ARCHITECTURE.md` and take the H3 entries under `## Key technical decisions`. An entry is anchored when its reasoning closes on the marker the standard fixes:
|
|
13
|
-
|
|
14
|
-
```plaintext
|
|
15
|
-
Measured at <short-sha> on <YYYY-MM-DD>.
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Skip every entry without one. An unanchored entry either predates the rule or cites no measured number, and the standard calls both correct, so the sweep has nothing to say about either.
|
|
19
|
-
|
|
20
|
-
For each anchored entry, collect the backticked code paths its reasoning cites. Same read the diagram sweep runs over an explanation, against a paragraph instead of a diagram.
|
|
21
|
-
|
|
22
|
-
Most of these name a folder rather than a file, because the number an entry anchors is usually a count over a tree. Match accordingly:
|
|
23
|
-
|
|
24
|
-
- A citation naming a file matches when the diff carries that file, wherever it sits. A file at the repository root such as `CLAUDE.md` is a file citation like any other.
|
|
25
|
-
- A folder citation, which is one ending in a slash, matches when the diff carries any path under it.
|
|
26
|
-
- A folder citation of a single segment matches nothing and is skipped.
|
|
27
|
-
|
|
28
|
-
The third rule reaches folders alone, which is what keeps it off `CLAUDE.md`. Breadth is the whole reason it exists, and a root file has none: it names one path the diff either carries or does not.
|
|
29
|
-
|
|
30
|
-
What it does stop is a citation of `.claude/` matching every branch. `src/`, `scripts/`, and `.claude/` each name a tree a project organizes most of its work under, so a prefix match on one fires constantly and rebuilds the ignored warning this sweep exists to avoid. Measured against this repository's record, the skip drops 13 of the 26 folder citations and keeps the ones carrying a signal, among them `src/tooling/`, `.claude/rules/`, and `governance/rules/`.
|
|
31
|
-
|
|
32
|
-
A decision whose folder citations are all a single segment, and which cites no file, therefore never fires. That is the correct outcome rather than a gap: a count over a whole tree moves on nearly every branch, so flagging it every time tells a reader that time has passed and nothing else.
|
|
33
|
-
|
|
34
|
-
## The finding
|
|
35
|
-
|
|
36
|
-
Report an entry when the diff touches one of its cited paths, however it was touched. A delete, a rename, and an edit inside the file all move a count of what sits under that path, and the entry's number was read before any of them landed. The diagram sweep narrows to deletes because a diagram survives a body edit, and a number does not.
|
|
37
|
-
|
|
38
|
-
The anchor's own SHA settles nothing here. A branch is compared against its merge base rather than against the commit the anchor names, so an entry anchored at a commit this branch already contains is still due a read once the branch moves what it counted.
|
|
39
|
-
|
|
40
|
-
Report an entry once however many of its cited paths the diff carries. Name the first as the evidence and leave the rest, since the reader opens the entry either way and a line per path buries the entry it is about.
|
|
41
|
-
|
|
42
|
-
What this misses is a claim whose number moved with no matching citation in the diff, whether because the branch never touched the tree it counts or because the entry cites nothing narrower than one segment. That is the recall this trades for precision, and the alternative is re-running an arbitrary measurement read out of prose, which no sweep does reliably.
|
|
43
|
-
|
|
44
|
-
## What the sweep never does
|
|
45
|
-
|
|
46
|
-
- Write into the entry. The anchor is a sentence rather than a frontmatter field, so the marker and the claim share one paragraph and an edit reaching one reaches the other.
|
|
47
|
-
- Refresh an anchor. Re-reading the number is the act the marker records, so a date written by a pass that measured nothing is the false confidence the marker exists to prevent.
|
|
48
|
-
- Flag an unanchored entry. The standard scopes the rule forward, and an entry written before it is dated by blame rather than by a read.
|
|
49
|
-
|
|
50
|
-
The session amending a decision writes its anchor, which Step 3 already requires. Step 3 holds the writer, and the two never meet. Anchoring fires when this run amends a decision, and this sweep fires when the diff moves a path under one, so a single step covering both would gate the anchor obligation on a signal that has nothing to do with it.
|
|
51
|
-
|
|
52
|
-
## Output
|
|
53
|
-
|
|
54
|
-
Output one line per finding:
|
|
55
|
-
|
|
56
|
-
`⚠ Anchor stale: "<decision name>" cites <path>, which this branch changed. Re-measure and refresh the anchor.`
|
|
57
|
-
|
|
58
|
-
If no anchored entry cites a changed path, skip silently. A record carrying no anchored entry produces no output on any branch, which is every project until a decision is written or amended under the rule.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Wireframe coverage sweep
|
|
3
|
-
description: Slug derivation from a UI-affecting path, the contradicted and uncovered findings, the surface stub, and the report lines
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Wireframe coverage sweep
|
|
7
|
-
|
|
8
|
-
Mechanics for Step 4 of `context-fold`. The body owns the skip conditions and the UI-path filter, and this file owns what the sweep does once a UI-affecting path survives that filter.
|
|
9
|
-
|
|
10
|
-
## Deriving a candidate slug
|
|
11
|
-
|
|
12
|
-
For each UI-affecting path, derive a candidate surface slug from the file's basename and parent folder (e.g. `web/src/features/mock/MockDemoStrip.tsx` → `mock-demo-strip` or `mock`). Cross-reference against every surface file in `canon/wireframes/`, including one nested inside a grouped surface's own subfolder (`canon/wireframes/<group>/<surface>.md`), by walking the tree rather than globbing the top level alone.
|
|
13
|
-
|
|
14
|
-
## Findings
|
|
15
|
-
|
|
16
|
-
**Contradicted sections.** When a surface file exists for a path in the diff and the diff renames or removes a literal string that appears in the wireframe prose (e.g. provider name, button label, copy string), output a one-line report entry and stop. Do not auto-rewrite prose. Operator resolves.
|
|
17
|
-
|
|
18
|
-
**Uncovered surfaces.** When a UI-affecting path has no matching surface file by slug, write `canon/wireframes/<slug>.md` with this stub:
|
|
19
|
-
|
|
20
|
-
```markdown
|
|
21
|
-
---
|
|
22
|
-
title: <Slug as title case>
|
|
23
|
-
description: TODO: describe the surface.
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
# <Slug as title case>
|
|
27
|
-
|
|
28
|
-
TODO: describe when and where this surface appears.
|
|
29
|
-
|
|
30
|
-
## Behavior
|
|
31
|
-
|
|
32
|
-
- TODO
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Skip the write when the slug would collide with an existing file, flat or nested (different surface, same slug). Surface the collision in the report instead.
|
|
36
|
-
|
|
37
|
-
## Output
|
|
38
|
-
|
|
39
|
-
Output one line per finding:
|
|
40
|
-
|
|
41
|
-
- `⚠ Wireframe drift in canon/wireframes/<surface>.md: <contradicted string>`
|
|
42
|
-
- `📝 Stubbed: canon/wireframes/<surface>.md`
|
|
43
|
-
- `⚠ Slug collision: <slug> matches existing <existing-surface>.md, review and rename`
|
|
44
|
-
|
|
45
|
-
If the sweep finds nothing, skip silently.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: create-standard
|
|
3
|
-
description: Why a standard needs its shape read from the meta-standard before anything is drafted, and why the follow-up depends on who owns the folder it landed in
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Create standard requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a standard is written from memory of what other standards look like. It arrives without the scope section that says what the file does not govern, so the next author cannot tell whether a rule belongs to it or to a sibling, and two standards end up claiming the same subject with no way to settle which one wins.
|
|
11
|
-
|
|
12
|
-
The second write surface is the second failure. A standard put under `.claude/standards/` looks like a correct file and reaches no resolver, since nothing installs the corpus into a project and no repository generates a copy there. One write surface removes the choice: `standards/` is what the resolver reads first and what every author writes to, in the toolkit and in a project alike.
|
|
13
|
-
|
|
14
|
-
A standard written and left there is the third. The index entry and the context table are both generated or maintained downstream of the write, so a file that ships without them is catalogued nowhere and reached only by whoever already knew the path.
|
|
15
|
-
|
|
16
|
-
## Must
|
|
17
|
-
|
|
18
|
-
- Read the meta-standard before drafting, since the shape is what makes the file arguable against a sibling
|
|
19
|
-
- Write to `standards/`, creating it when absent, since it is the one root the resolver reads and the only surface either kind of author has
|
|
20
|
-
- Confirm the slug and the full body with the user before writing
|
|
21
|
-
- Emit the written path in full, so the terminal can resolve it
|
|
22
|
-
- State what the write implies for whoever owns the folder, since a toolkit standard needs the index regenerated and a project-local one needs copying to the toolkit to ship
|
|
23
|
-
|
|
24
|
-
## Must not
|
|
25
|
-
|
|
26
|
-
- Work the standard's shape or frontmatter from memory
|
|
27
|
-
- Write into `.claude/standards/`, which no repository generates and no resolver reads
|
|
28
|
-
|
|
29
|
-
## Out of scope
|
|
30
|
-
|
|
31
|
-
- Editing a standard that already exists
|
|
32
|
-
- A path-scoped coding rule, which `create-rule` owns
|
|
33
|
-
- Reading a standard the toolkit ships, which `canon standards <name>` owns
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: create-standard
|
|
3
|
-
description: Creates a new standard file in `standards/`. Use when asked to "create a standard", add a standard, or write a new authoring convention. Do NOT use to edit an existing standard.
|
|
4
|
-
metadata:
|
|
5
|
-
family: generate
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Create standard
|
|
9
|
-
|
|
10
|
-
Creates one standard file. Read these files in parallel:
|
|
11
|
-
|
|
12
|
-
- `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md`: punctuation and formatting for all generated text
|
|
13
|
-
- The `write-human` skill: voice, rhythm, and sentence construction for all generated text
|
|
14
|
-
- `${CLAUDE_SKILL_DIR}/../../standards/standard.md`: the meta-standard for shape, frontmatter, and structure
|
|
15
|
-
|
|
16
|
-
## Steps
|
|
17
|
-
|
|
18
|
-
1. Draft the content from the user's description. The meta-standard governs frontmatter, headings, and structure.
|
|
19
|
-
2. Confirm the slug and full content with the user before writing
|
|
20
|
-
3. Write the file to `standards/<slug>.md`, creating the folder when it is absent
|
|
21
|
-
|
|
22
|
-
`standards/` is the one write surface. It is the toolkit's authoring source in this repository and a project's own folder anywhere else, and both are the root `canon standards <name>` resolves against first. No corpus installs into a project, so there is no second surface to pick between and no guard on a folder the skill can create itself.
|
|
23
|
-
|
|
24
|
-
## After writing
|
|
25
|
-
|
|
26
|
-
Emit the full path on its own line.
|
|
27
|
-
|
|
28
|
-
- In the toolkit: this is the authoring source. Remind the user to run `bun run check` to regenerate the consumed copy under `.claude/`. That pass also regenerates the `standards/index.md` entry, and the user adds a row to the standards table in `canon/context/standards/overview.md`. <!-- canon-allow-reference: audience-branched, only a toolkit-repo reader reaches this line and that reader can open the path -->
|
|
29
|
-
- In a project: the file is project-local and no toolkit command touches it. Remind the user to copy it to the toolkit repo, under `standards/<slug>.md`, if it should ship to every project.
|
|
30
|
-
|
|
31
|
-
Separate the two by whether the folder already held toolkit-authored standards before this write, since a project authoring its own uses the same path.
|