@erclx/canon 4.67.0 → 4.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/{claude-autoship → auto-ship}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-autoship → auto-ship}/SKILL.md +36 -36
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +2 -2
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback-triage/SKILL.md +3 -3
- package/claude/skills/canon-operator/REQUIREMENT.md +1 -1
- package/claude/skills/canon-operator/SKILL.md +4 -4
- package/claude/skills/canon-rollout/REQUIREMENT.md +6 -6
- package/claude/skills/canon-rollout/SKILL.md +7 -7
- package/claude/skills/{claude-design-extract → design-extract}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-design-extract → design-extract}/SKILL.md +1 -1
- package/claude/skills/{claude-docs → docs-fold}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-docs → docs-fold}/SKILL.md +14 -14
- package/claude/skills/{claude-docs → docs-fold}/references/anchor-sweep.md +1 -1
- package/claude/skills/{claude-docs → docs-fold}/references/wireframe-sweep.md +1 -1
- package/claude/skills/docs-sync/REQUIREMENT.md +3 -3
- package/claude/skills/docs-sync/SKILL.md +1 -1
- package/claude/skills/draft-and-pick/REQUIREMENT.md +4 -4
- package/claude/skills/draft-and-pick/SKILL.md +6 -6
- package/claude/skills/draft-context/REQUIREMENT.md +2 -2
- package/claude/skills/draft-context/SKILL.md +3 -3
- package/claude/skills/{claude-diagram → draft-diagram}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-diagram → draft-diagram}/SKILL.md +3 -3
- package/claude/skills/draft-docs/REQUIREMENT.md +1 -1
- package/claude/skills/draft-wireframes/REQUIREMENT.md +1 -1
- package/claude/skills/draft-wireframes/SKILL.md +2 -2
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +1 -1
- package/claude/skills/git-pr/SKILL.md +3 -3
- package/claude/skills/git-ship/REQUIREMENT.md +2 -2
- package/claude/skills/git-ship/SKILL.md +8 -8
- package/claude/skills/git-worktree/REQUIREMENT.md +2 -2
- package/claude/skills/git-worktree/SKILL.md +3 -3
- package/claude/skills/identity/REQUIREMENT.md +2 -2
- package/claude/skills/identity/SKILL.md +3 -3
- package/claude/skills/{claude-markdown-propose → markdown-propose}/REQUIREMENT.md +8 -8
- package/claude/skills/{claude-markdown-propose → markdown-propose}/SKILL.md +5 -5
- package/claude/skills/{claude-markdown-propose → markdown-propose}/references/format.md +1 -1
- package/claude/skills/{claude-memory-capture → memory-capture}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-memory-capture → memory-capture}/SKILL.md +13 -13
- package/claude/skills/{claude-memory-review → memory-review}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-memory-review → memory-review}/SKILL.md +10 -10
- package/claude/skills/migration-context/SKILL.md +1 -1
- package/claude/skills/migration-standards-drop/REQUIREMENT.md +1 -1
- package/claude/skills/migration-superseded/REQUIREMENT.md +1 -1
- package/claude/skills/{claude-feature → plan-feature}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-feature → plan-feature}/SKILL.md +4 -4
- package/claude/skills/{claude-groundwork → plan-groundwork}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-groundwork → plan-groundwork}/SKILL.md +8 -8
- package/claude/skills/{claude-intake → plan-intake}/REQUIREMENT.md +6 -6
- package/claude/skills/{claude-intake → plan-intake}/SKILL.md +10 -10
- package/claude/skills/{claude-intake-answer → plan-intake-answer}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-intake-answer → plan-intake-answer}/SKILL.md +5 -5
- package/claude/skills/{claude-address-review → review-address}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-address-review → review-address}/SKILL.md +6 -6
- package/claude/skills/{claude-address-review → review-address}/references/rebase-conflicts.md +1 -1
- package/claude/skills/{claude-review → review-branch}/REQUIREMENT.md +4 -4
- package/claude/skills/{claude-review → review-branch}/SKILL.md +4 -4
- package/claude/skills/{claude-pr-review → review-pr}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-pr-review → review-pr}/SKILL.md +11 -11
- package/claude/skills/{claude-orchestrate → role-orchestrator}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-orchestrate → role-orchestrator}/SKILL.md +20 -20
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-dispatch.md +30 -30
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-handoff.md +2 -2
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-parked.md +8 -8
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-poll.md +8 -8
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-resume.md +1 -1
- package/claude/skills/{claude-orchestrate → role-orchestrator}/references/orchestrator-sweep.md +1 -1
- package/claude/skills/{claude-orchestrate → role-orchestrator}/scripts/poll.sh +6 -6
- package/claude/skills/{claude-planner → role-planner}/REQUIREMENT.md +12 -12
- package/claude/skills/{claude-planner → role-planner}/SKILL.md +4 -4
- package/claude/skills/{claude-worker → role-worker}/REQUIREMENT.md +8 -8
- package/claude/skills/{claude-worker → role-worker}/SKILL.md +6 -6
- package/claude/skills/{claude-seed-sync → seed-sync}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-seed-sync → seed-sync}/SKILL.md +3 -3
- package/claude/skills/session-map/REQUIREMENT.md +2 -2
- package/claude/skills/session-map/SKILL.md +2 -2
- package/claude/skills/session-resume/REQUIREMENT.md +2 -2
- package/claude/skills/session-resume/SKILL.md +2 -2
- package/claude/skills/{claude-worktree → session-worktree}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-worktree → session-worktree}/SKILL.md +6 -6
- package/claude/skills/setup-plugins/references/plugin-catalog.md +1 -1
- package/claude/skills/{claude-standards-audit → standards-audit}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-standards-audit → standards-audit}/SKILL.md +2 -2
- package/claude/skills/systematic-debugging/REQUIREMENT.md +1 -1
- package/claude/skills/{claude-tasks → task-board}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-tasks → task-board}/SKILL.md +7 -7
- package/claude/skills/{claude-teach → teach-workspace}/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-teach → teach-workspace}/SKILL.md +4 -4
- package/claude/skills/test-first/REQUIREMENT.md +2 -2
- package/claude/skills/{claude-ui-test → ui-test}/REQUIREMENT.md +3 -3
- package/claude/skills/{claude-ui-test → ui-test}/SKILL.md +3 -3
- package/claude/skills/{claude-ux-audit → ux-audit}/REQUIREMENT.md +6 -6
- package/claude/skills/{claude-ux-audit → ux-audit}/SKILL.md +5 -5
- package/claude/skills/{claude-ux-measure → ux-measure}/REQUIREMENT.md +5 -5
- package/claude/skills/{claude-ux-measure → ux-measure}/SKILL.md +5 -5
- package/docs/agents/install-and-sync.md +1 -1
- package/docs/agents/key-changes.md +3 -3
- package/docs/agents/markdown-audit.md +1 -1
- package/docs/agents/restated.md +1 -1
- package/docs/agents/review-classification.md +1 -1
- package/docs/agents/sessions.md +1 -1
- package/docs/agents/state-scoped-risk.md +1 -1
- package/docs/agents/targets.md +1 -1
- package/docs/agents/tasks.md +4 -4
- package/docs/agents/teach.md +1 -1
- package/docs/target-projects.md +10 -10
- package/docs/workflow/ai-workflow.md +84 -84
- package/docs/workflow/operating-model.md +17 -17
- package/docs/workflow/visual-design-workflow.md +6 -6
- package/governance/rules/core/045-memory.md +1 -1
- package/governance/rules/core/085-worktrees.md +1 -1
- package/package.json +1 -1
- package/scripts/core/regen-agent-fixture.sh +1 -1
- package/scripts/core/regen-hero.sh +7 -7
- package/snippets/claude/decision-memo.md +1 -1
- package/src/autoship/paths.ts +1 -1
- package/src/claude/cases/all.ts +2 -2
- package/src/claude/cases/{claude-workflow.ts → workflow.ts} +33 -33
- package/src/commands/sync.ts +3 -3
- package/src/design/tokens.ts +1 -1
- package/src/gov/restated.ts +2 -2
- package/src/markdown/structure.ts +1 -1
- package/src/migrate/rename.ts +4 -3
- package/src/pr/bijection.ts +1 -1
- package/src/pr/paths.ts +2 -2
- package/src/shipped/references.ts +1 -1
- package/src/sync/seeds-report.ts +1 -1
- package/src/targets/pulls.ts +2 -2
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +4 -4
- package/src/tasks/record.ts +2 -2
- package/src/tasks/validate.ts +1 -1
- package/standards/groundwork.md +1 -1
- package/standards/snippets.md +1 -1
- package/standards/tasks.md +3 -3
- package/standards/teach.md +2 -2
- package/tooling/base/configs/.husky/post-merge +3 -3
- package/tooling/claude/reference.md +5 -5
- package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +2 -2
- /package/claude/skills/{claude-memory-review → memory-review}/references/receipt-format.md +0 -0
- /package/claude/skills/{claude-orchestrate → role-orchestrator}/scripts/watch.sh +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/lesson-craft.md +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/pedagogy.md +0 -0
- /package/claude/skills/{claude-teach → teach-workspace}/references/promotion.md +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: auto-ship
|
|
3
3
|
description: What the post-plan pipeline is for, the gaps it closes, and why every stop leaves the work recoverable
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Auto ship requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -47,6 +47,6 @@ Review is the step that varies most. It gets skipped on a diff that needed one,
|
|
|
47
47
|
|
|
48
48
|
## Out of scope
|
|
49
49
|
|
|
50
|
-
- Writing the plan, which `
|
|
50
|
+
- Writing the plan, which `plan-feature` owns. This chain starts from one already approved.
|
|
51
51
|
- The behavior of each step, owned by the skill invoked. This skill owns the order and the stop conditions.
|
|
52
52
|
- The ship sequence and the resume path after a stop, both of which `git-ship` owns. That skill is the tail of this chain, invoked at Step 8 rather than copied into it, so the overlap is one body reached two ways rather than two bodies stating one order.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: auto-ship
|
|
3
3
|
description: Chains implement → verify → review → ship after a feature plan is approved. Reads the plan the caller names, the plan a named task points at, or the plan for the current branch when none is named, runs the full pipeline in one session, and stops on any failure or non-minor review finding. Use when asked to "autoship", "ship this feature end to end", or "run the chain". Do NOT auto-trigger. Requires an approved plan file.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# Auto ship
|
|
8
8
|
|
|
9
9
|
Chain the post-plan pipeline in a single run. Every step has a stop condition. State is always recoverable on stop: code lives on the branch, review output on disk, plan still linked.
|
|
10
10
|
|
|
11
11
|
## Guards
|
|
12
12
|
|
|
13
|
-
- All `.canon/plans/` and `.canon/review/` reads resolve at the main worktree root, not the current worktree. Resolve that root the way `
|
|
14
|
-
- Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. This skill takes the stop rather than the `latest` fallback, since it commits and opens a pull request. If empty, stop: `❌ Detached HEAD. Checkout the feature branch first.` This slug is provisional. It is superseded once `
|
|
13
|
+
- All `.canon/plans/` and `.canon/review/` reads resolve at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does.
|
|
14
|
+
- Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. This skill takes the stop rather than the `latest` fallback, since it commits and opens a pull request. If empty, stop: `❌ Detached HEAD. Checkout the feature branch first.` This slug is provisional. It is superseded once `session-worktree` runs, whether at Step 0 or before this chain began. Every later step keys its output on the slug that run resolves, being the worktree, the review receipt, the branch, and the memory proposal, regardless of which plan Step 1 reads.
|
|
15
15
|
- Resolve `<plan>` in Step 1, ahead of any other read.
|
|
16
16
|
- If the working tree has uncommitted changes unrelated to the plan, stop: `❌ Uncommitted changes outside the plan. Commit or stash before autoshipping.`
|
|
17
17
|
|
|
@@ -31,11 +31,11 @@ The base equalling HEAD stays usable here, unlike in the four read-only siblings
|
|
|
31
31
|
|
|
32
32
|
## Step 0: take the role, then enter a worktree
|
|
33
33
|
|
|
34
|
-
Invoke `canon:
|
|
34
|
+
Invoke `canon:role-worker` first, whatever the worktree state. This session is about to build one branch under one plan, and that skill states the boundaries, the lifetime, and the channel obligations the role carries. A dispatched worker reaches the role here and nowhere else, since the launch names this chain rather than the role, and a hand-launched one reaches it on the same path.
|
|
35
35
|
|
|
36
|
-
Report it rather than proceeding silently when `canon:
|
|
36
|
+
Report it rather than proceeding silently when `canon:role-worker` does not resolve. It ships with the plugin, so a session running this chain from a project holding the CLI alone builds with no role asserted.
|
|
37
37
|
|
|
38
|
-
If `git rev-parse --git-dir` equals `git rev-parse --git-common-dir`, the session is in the main worktree. Invoke `canon:
|
|
38
|
+
If `git rev-parse --git-dir` equals `git rev-parse --git-common-dir`, the session is in the main worktree. Invoke `canon:session-worktree` before continuing, carrying the argument the subsection below derives. The wrapper handles branch alignment. Do not call `EnterWorktree` directly.
|
|
39
39
|
|
|
40
40
|
If neither command resolves, stop: `❌ Not a git repository. Autoship needs git or a WorktreeCreate hook.`
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ If the two commands differ, the session is already in a linked worktree. Continu
|
|
|
43
43
|
|
|
44
44
|
### Name the worktree from the plan rather than leaving it to be derived
|
|
45
45
|
|
|
46
|
-
This step runs ahead of Step 1, so what it holds is the raw invocation argument rather than a resolved plan. When that argument is a plan path or a bare slug, run the verb on it and hand the result to `canon:
|
|
46
|
+
This step runs ahead of Step 1, so what it holds is the raw invocation argument rather than a resolved plan. When that argument is a plan path or a bare slug, run the verb on it and hand the result to `canon:session-worktree` as its tier 0 argument:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
49
|
canon tasks plan-branch <argument> --json
|
|
@@ -51,19 +51,19 @@ canon tasks plan-branch <argument> --json
|
|
|
51
51
|
|
|
52
52
|
- `conforms: true`: pass the record's `branch`, which is already `<type>/<slug>`, and invoke nothing else to derive a name.
|
|
53
53
|
- `conforms: false`: the plan's own filename breaks a cap in `${CLAUDE_SKILL_DIR}/../../standards/branch.md`. Pass `branch` anyway and say the cap it broke, since the alternative is a name this session shortened by hand, which is a second derivation and the thing this call exists to prevent. `git-branch` decides the rename at ship.
|
|
54
|
-
- Anything else, including a refusal, a record carrying no `branch` key, and an installed binary carrying no `plan-branch` subcommand: invoke `canon:
|
|
54
|
+
- Anything else, including a refusal, a record carrying no `branch` key, and an installed binary carrying no `plan-branch` subcommand: invoke `canon:session-worktree` bare and let its ladder derive the name. Say the verb did not answer, so a reader can tell a derived name from a fallback one.
|
|
55
55
|
|
|
56
56
|
The dispatch runbook runs the same verb on the same plan to pick the branch its collision check clears, so calling it here is what makes the checked branch and the taken branch one string. Deriving a name from `<plan>` by reading it was the alternative, and it is what produced three strings for one plan across four dispatches on 2026-09-05.
|
|
57
57
|
|
|
58
|
-
A caller that supplied a task path, or supplied nothing at all, has no plan to hand the verb here, since resolving either is Step 1's work and Step 1 has not run. Invoke `canon:
|
|
58
|
+
A caller that supplied a task path, or supplied nothing at all, has no plan to hand the verb here, since resolving either is Step 1's work and Step 1 has not run. Invoke `canon:session-worktree` bare in both cases. That is the ladder unchanged rather than a regression, and it leaves the hole open: a dispatched worker reaching this step through a task path derives its name from a tier rather than from the plan the dispatcher checked.
|
|
59
59
|
|
|
60
60
|
## Step 1: read the plan
|
|
61
61
|
|
|
62
62
|
Resolve `<plan>` in this order, stopping at the first match:
|
|
63
63
|
|
|
64
64
|
1. **Caller-supplied task.** The invocation carried a path under `.canon/tasks/`. If it does not resolve to a file, stop: `❌ No task at <path>. Path was supplied, not derived, so check it and re-run.` Read that task's first `Plan:` line and take what it names as `<plan>`, per `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`.
|
|
65
|
-
2. **Caller-supplied plan.** The invocation carried something else. Accept it as a plan path or a bare slug, in the same position `
|
|
66
|
-
3. **Derived.** `.canon/plans/feature-<slug>.md`, from the `<slug>` the Guards derived. If it does not exist, stop: `❌ No approved plan at .canon/plans/feature-<slug>.md, where <slug> was derived from the current branch, <branch>. The invocation carried no argument, so pass a plan or a task path, or run /
|
|
65
|
+
2. **Caller-supplied plan.** The invocation carried something else. Accept it as a plan path or a bare slug, in the same position `session-worktree` tier 0 accepts its name. A bare slug resolves to `.canon/plans/feature-<slug>.md`, and a path is taken as given from the main worktree root. If it does not resolve to a file, stop: `❌ No plan at <path>. Path was supplied, not derived, so check it and re-run.`
|
|
66
|
+
3. **Derived.** `.canon/plans/feature-<slug>.md`, from the `<slug>` the Guards derived. If it does not exist, stop: `❌ No approved plan at .canon/plans/feature-<slug>.md, where <slug> was derived from the current branch, <branch>. The invocation carried no argument, so pass a plan or a task path, or run /plan-feature first.`
|
|
67
67
|
|
|
68
68
|
Only a path reaches tier 1, and a bare slug is read as a plan's throughout. The two would collide on any similar name, and a caller who means the task holds its path already, having read it off the board. One plan per task is what makes the tier 1 read unambiguous, so it takes the first `Plan:` line and never scans for a second.
|
|
69
69
|
|
|
@@ -119,9 +119,9 @@ The verb ships with the CLI and this body ships with the plugin, matching Step 6
|
|
|
119
119
|
|
|
120
120
|
## Step 5: UI test (conditional)
|
|
121
121
|
|
|
122
|
-
If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:
|
|
122
|
+
If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-test`.
|
|
123
123
|
|
|
124
|
-
If `
|
|
124
|
+
If `ui-test` produces a manual checklist, stop: `❌ UI requires visual verification. Checklist at .canon/tmp/ui-checklist/<slug>.md, which reaches the pull request once /git-ship runs. Verify manually, then run /git-ship.`
|
|
125
125
|
|
|
126
126
|
If all UI changes are covered by e2e tests, continue.
|
|
127
127
|
|
|
@@ -136,7 +136,7 @@ canon autoship classify --json <path>...
|
|
|
136
136
|
The verb reads names only and touches git not at all, so the set stays the one this step already computed and no second baseline resolves to disagree with the first. Branch on the record's `decision` rather than on the exit code, which a shell function wrapping `canon` can flatten to zero.
|
|
137
137
|
|
|
138
138
|
- `skip`. Every path reads as prose and none states agent behavior. Skip review entirely and continue to Step 8.
|
|
139
|
-
- `review`. Invoke `canon:
|
|
139
|
+
- `review`. Invoke `canon:review-branch`. The record names the `file` that decided it and the `test` it failed, `extension` for a path that is not prose and `behavior-path` for prose that states what an agent does.
|
|
140
140
|
- `refused`, carrying reason `no-changes`. The changed set was empty, so take the stop below.
|
|
141
141
|
|
|
142
142
|
Say in the run which of the two decided, the verb or the written fallback, since a reader otherwise cannot tell a classification from a judgment.
|
|
@@ -151,7 +151,7 @@ The verb ships with the CLI and this body ships with the plugin, so a target hol
|
|
|
151
151
|
|
|
152
152
|
Never read an absent subcommand as a skip. Failing open is the exact defect the verb closes, and a shell that answers `command not found` reaching a body that skips on anything other than a `skip` record would ship every branch unreviewed.
|
|
153
153
|
|
|
154
|
-
The skip needs both tests to pass: every changed file matches `*.md` or `*.txt`, and no changed file sits under a behavior path. On a pass, skip review entirely and continue to Step 8. Otherwise invoke `canon:
|
|
154
|
+
The skip needs both tests to pass: every changed file matches `*.md` or `*.txt`, and no changed file sits under a behavior path. On a pass, skip review entirely and continue to Step 8. Otherwise invoke `canon:review-branch`.
|
|
155
155
|
|
|
156
156
|
Behavior paths carry two spellings, the one a surface authors at and the one it reaches a session at, so the rule reads the same in a toolkit and in a project that consumed one:
|
|
157
157
|
|
|
@@ -164,7 +164,7 @@ Behavior paths carry two spellings, the one a surface authors at and the one it
|
|
|
164
164
|
|
|
165
165
|
Markdown under one of them states what an agent does, so a change there is a behavior change wearing a prose extension. Everything outside them is informational, which keeps `docs/`, `README.md`, and `CHANGELOG.md` skipping without naming them. One behavior file sends the whole branch to review, since documentation shipped beside a behavior change does not cancel it.
|
|
166
166
|
|
|
167
|
-
Informational prose is already gated by `docs-sync`, `
|
|
167
|
+
Informational prose is already gated by `docs-sync`, `standards-audit`, and pre-push hooks. Running a code-style review on it burns tokens with no signal.
|
|
168
168
|
|
|
169
169
|
The list covers this toolkit's authoring layout and the layout it installs, which is not every layout. A project keeping executable prose where neither spelling reaches adds the path, and until it does every branch touching it skips review silently.
|
|
170
170
|
|
|
@@ -182,7 +182,7 @@ Read origin as causation rather than authorship. Staleness this run induced in a
|
|
|
182
182
|
|
|
183
183
|
Bound the repair at one pass, the way Step 3 bounds verify. When that re-read shows the finding still standing, stop: `❌ A self-introduced finding survived one fix pass. See .canon/review/branch/review-<slug>.md. Fix and run /git-ship.`
|
|
184
184
|
|
|
185
|
-
This chain owns the receipt's lifetime, which is what makes the Output block's citation resolve on a run that reaches it. `
|
|
185
|
+
This chain owns the receipt's lifetime, which is what makes the Output block's citation resolve on a run that reaches it. `docs-fold` used to delete the current slug's receipt while running under Step 8 below, so the closing line named a file the same run had already removed. That sweep now reaches only reports whose branch is gone, which collects this one a branch later rather than during the run that wrote it. The cost is one receipt per live branch left in `.canon/review/branch/`, bounded by the branch count rather than by the lifetime of the checkout.
|
|
186
186
|
|
|
187
187
|
## Step 8: ship
|
|
188
188
|
|
|
@@ -217,7 +217,7 @@ Respond with up to five lines:
|
|
|
217
217
|
|
|
218
218
|
`<state>` is whatever the Step 8 read returned, being `draft` or `ready, unsupervised`, rather than the state the undo asked for. Writing the word `draft` there unconditionally is what this line used to do, and it named a state no step had read.
|
|
219
219
|
|
|
220
|
-
Omit the second line if there were no minor findings, and the third if nothing routed. Omit the fourth and fifth if `
|
|
220
|
+
Omit the second line if there were no minor findings, and the third if nothing routed. Omit the fourth and fifth if `memory-capture` wrote no memory file this session, since an empty pen means no scoped review and no proposal. A run that routes every fact and writes none is the shape to expect, and it reports three lines.
|
|
221
221
|
|
|
222
222
|
This block replaces the one `git-ship` closes on rather than following it. The two carry the same three trailing lines and differ on the two above them, since the first names the state the read returned and the second reports the minor findings Step 7 kept, neither of which that body has a counterpart for. Emitting both reports one run twice and buries the state under a `✅ Shipped` that does not name it.
|
|
223
223
|
|
|
@@ -225,20 +225,20 @@ This block replaces the one `git-ship` closes on rather than following it. The t
|
|
|
225
225
|
|
|
226
226
|
Every stop point leaves recoverable state. The user resumes manually from the appropriate step.
|
|
227
227
|
|
|
228
|
-
| Stop point | Recovery
|
|
229
|
-
| ------------------------------------------ |
|
|
230
|
-
| No plan (derived) | Run `/
|
|
231
|
-
| No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run
|
|
232
|
-
| No task (caller-supplied) | Check the task path passed to autoship, then re-run
|
|
233
|
-
| Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run
|
|
234
|
-
| Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly.
|
|
235
|
-
| Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run
|
|
236
|
-
| Resolved file carries no plan shape | Point autoship at a plan under `.canon/plans/feature-<slug>.md` or at a task under `.canon/tasks/`, then re-run
|
|
237
|
-
| No diff baseline | Fetch origin so a merge base resolves against `main`, then re-run autoship
|
|
238
|
-
| Empty changed-file list | Re-run once the plan produces tracked output. Ship gitignored output outside the chain, never by tracking it.
|
|
239
|
-
| Branch collision on worktree entry | `
|
|
240
|
-
| Verify fails | Read logs, fix manually, run `/git-ship`
|
|
241
|
-
| UI checklist | Verify visually, run `/git-ship`
|
|
242
|
-
| Inherited review findings | Fix findings, run `/git-ship`
|
|
243
|
-
| Self-introduced finding survived | Read the receipt for what the one repair pass left open, fix it, run `/git-ship`
|
|
244
|
-
| git-ship fails | Inspect hook or remote error, run again
|
|
228
|
+
| Stop point | Recovery |
|
|
229
|
+
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
230
|
+
| No plan (derived) | Run `/plan-feature` to create one |
|
|
231
|
+
| No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run |
|
|
232
|
+
| No task (caller-supplied) | Check the task path passed to autoship, then re-run |
|
|
233
|
+
| Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run |
|
|
234
|
+
| Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly. |
|
|
235
|
+
| Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run |
|
|
236
|
+
| Resolved file carries no plan shape | Point autoship at a plan under `.canon/plans/feature-<slug>.md` or at a task under `.canon/tasks/`, then re-run |
|
|
237
|
+
| No diff baseline | Fetch origin so a merge base resolves against `main`, then re-run autoship |
|
|
238
|
+
| Empty changed-file list | Re-run once the plan produces tracked output. Ship gitignored output outside the chain, never by tracking it. |
|
|
239
|
+
| Branch collision on worktree entry | `session-worktree` Step 5 found `<slug>` already as a local branch. Resolve manually (rename or delete the stale branch), then re-run autoship. |
|
|
240
|
+
| Verify fails | Read logs, fix manually, run `/git-ship` |
|
|
241
|
+
| UI checklist | Verify visually, run `/git-ship` |
|
|
242
|
+
| Inherited review findings | Fix findings, run `/git-ship` |
|
|
243
|
+
| Self-introduced finding survived | Read the receipt for what the one repair pass left open, fix it, run `/git-ship` |
|
|
244
|
+
| git-ship fails | Inspect hook or remote error, run again |
|
|
@@ -15,7 +15,7 @@ The inverse failure is quieter. A session that assumes a sync will pick up a cha
|
|
|
15
15
|
|
|
16
16
|
Being reachable is a separate problem from being right. This is a pure reference whose moment happens inside another skill's run, so nothing brings it up unless a body names it. Three sibling requirement files named it and routed nothing, because Claude Code loads `SKILL.md` as the entry and never opens the sibling. A route lives in a body or it does not exist, and a fourth requirement mention would repeat the same defect.
|
|
17
17
|
|
|
18
|
-
The two bodies now carrying an inline pointer are `
|
|
18
|
+
The two bodies now carrying an inline pointer are `seed-sync` and `canon-operator`, each at the point it runs or prints an overwriting command.
|
|
19
19
|
|
|
20
20
|
A third gap sits beside the first two, aimed at a different question. `canon --help` lists every top-level verb and `canon docs` emits the toolkit's own reference corpus, but no reference skill pointed a session at either. The one skill that does, `canon-operator`, is user-invoked only and reaches them as a side effect of its own orientation step. A session guessing at a verb's name, or restating what a doc already answers, is the same missing-fact failure the overwrite gap names.
|
|
21
21
|
|
|
@@ -40,6 +40,6 @@ A third gap sits beside the first two, aimed at a different question. `canon --h
|
|
|
40
40
|
## Out of scope
|
|
41
41
|
|
|
42
42
|
- Executing the sync, which the user runs or `canon-operator` routes
|
|
43
|
-
- Reconciling a customized seed section by section: `
|
|
43
|
+
- Reconciling a customized seed section by section: `seed-sync`
|
|
44
44
|
- Deciding which stack, rule, or standard a project should install, which the setup skills resolve from live catalogs
|
|
45
45
|
- Diagnosing what a project is behind on, or executing the fix: `canon-operator`
|
|
@@ -107,11 +107,11 @@ Run `canon tooling sync <stack> <target> --check` for the list resolved against
|
|
|
107
107
|
- An interactive run still prompts. `--write` skips the prompt, and `--check` refuses to write even with a TTY.
|
|
108
108
|
- Seeds are user-owned. Dictionary `.txt` files merge and sort. Other seeds are copy-once, so re-seeding a structured file means deleting it and syncing again.
|
|
109
109
|
- No command writes a standard into a project. A `.claude/standards/` folder from an older toolkit is inert, and deleting it costs nothing.
|
|
110
|
-
- For section-level customizations of a seed doc, use the `
|
|
110
|
+
- For section-level customizations of a seed doc, use the `seed-sync` skill, not `canon ... sync`. It diffs per section and preserves edits.
|
|
111
111
|
|
|
112
112
|
## CLAUDE.md
|
|
113
113
|
|
|
114
|
-
- `CLAUDE.md` is a copy-once seed. No `canon` sync command ever updates it. Reconcile it with the `
|
|
114
|
+
- `CLAUDE.md` is a copy-once seed. No `canon` sync command ever updates it. Reconcile it with the `seed-sync` skill, which diffs the preamble and each section and preserves customizations by default.
|
|
115
115
|
|
|
116
116
|
## Source of truth
|
|
117
117
|
|
|
@@ -36,5 +36,5 @@ The queue also fails to drain even when the work ships. A fix merged with no lin
|
|
|
36
36
|
## Out of scope
|
|
37
37
|
|
|
38
38
|
- Filing new feedback: `canon-feedback-file`
|
|
39
|
-
- Writing the plan a plan-worthy issue needs: `
|
|
39
|
+
- Writing the plan a plan-worthy issue needs: `plan-feature`
|
|
40
40
|
- Triage of issues carrying any other label, which surface here by design only under the feedback label
|
|
@@ -36,7 +36,7 @@ gh issue view <n> --json title,body,labels --jq '"\(.title)\n\n\(.body)"'
|
|
|
36
36
|
Classify against the toolkit's own surfaces. Score in this order and stop at the first match:
|
|
37
37
|
|
|
38
38
|
1. **Direct fix.** One surface, one file, no architectural choice. A typo, a stale reference, a one-line rule or doc correction, a single wording fix. Route straight to the edit.
|
|
39
|
-
2. **Plan-worthy.** Multiple files, a new skill or rule, a behavior change, or a cross-surface move. Route to `
|
|
39
|
+
2. **Plan-worthy.** Multiple files, a new skill or rule, a behavior change, or a cross-surface move. Route to `plan-feature`.
|
|
40
40
|
3. **Needs clarification.** The observed and expected behavior conflict or the surface is unnamed. Comment on the issue asking for the missing detail, then skip it.
|
|
41
41
|
|
|
42
42
|
State the class and the one-line reason per issue before routing. Do not batch unrelated fixes into one branch.
|
|
@@ -44,7 +44,7 @@ State the class and the one-line reason per issue before routing. Do not batch u
|
|
|
44
44
|
## Step 3: route
|
|
45
45
|
|
|
46
46
|
- Direct fix: rename the branch to a conventional name (invoke `git-branch`), make the edit, then open the PR with `git-pr`.
|
|
47
|
-
- Plan-worthy: invoke `
|
|
47
|
+
- Plan-worthy: invoke `plan-feature` with the issue body as the feature description. Let it write the plan and stop. Hand the plan slug back to the user. Do not implement.
|
|
48
48
|
- Needs clarification: run the scan in `${CLAUDE_SKILL_DIR}/../../standards/publish.md` against the question first, since it reaches the remote with nothing else checking it and this scan is the only gate. Then `gh issue comment <n> --body "<one question>"`, and move on.
|
|
49
49
|
|
|
50
50
|
Match one issue to one branch and one PR. A single feedback issue is a single unit of work.
|
|
@@ -60,4 +60,4 @@ Link every fix back to its issue so the queue drains on merge.
|
|
|
60
60
|
## Notes
|
|
61
61
|
|
|
62
62
|
- The `feedback` label is what `canon feedback --github` and the `toolkit-feedback.yml` issue form both apply. An issue without it does not surface here by design.
|
|
63
|
-
- This skill routes, it does not reimplement. `
|
|
63
|
+
- This skill routes, it does not reimplement. `plan-feature` owns planning, `git-pr` owns the PR body, `git-branch` owns the branch name. Do not duplicate their logic.
|
|
@@ -54,7 +54,7 @@ The last failure is a section no route reaches. `## Route` maps an intent or a d
|
|
|
54
54
|
## Out of scope
|
|
55
55
|
|
|
56
56
|
- First-time scaffold of a fresh project: `setup-init`
|
|
57
|
-
- Seed and preamble drift in installed files: `
|
|
57
|
+
- Seed and preamble drift in installed files: `seed-sync`
|
|
58
58
|
- Governance rule install and index bootstrap: `setup-gov` and `setup-indexes`
|
|
59
59
|
- What a given sync overwrites once it runs: `canon-cli`
|
|
60
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
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-init and seed drift to
|
|
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-init and seed drift to seed-sync.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -50,7 +50,7 @@ The two can name different rows, and a reply answers both rather than picking on
|
|
|
50
50
|
- First-time scaffold of a fresh project: hand off to `setup-init`
|
|
51
51
|
- Governance rules for the project stack: hand off to `setup-gov`
|
|
52
52
|
- Bootstrap the `index.md` system: hand off to `setup-indexes`
|
|
53
|
-
- Seed or standards drift in `CLAUDE.md` or `.claude/` preambles: hand off to `
|
|
53
|
+
- Seed or standards drift in `CLAUDE.md` or `.claude/` preambles: hand off to `seed-sync`
|
|
54
54
|
- Install one snippet, standard, or rule: run the domain `install` command
|
|
55
55
|
- Sync one domain or every installed domain: run `canon <domain> sync` or `canon sync`
|
|
56
56
|
- Fix only the ignore entries of the installed stack: run `canon tooling inject --gitignore <stack>`
|
|
@@ -77,7 +77,7 @@ A lifecycle row and these offers fire together on a project carrying a context f
|
|
|
77
77
|
- A record folder present under `.claude/`, one of `plans`, `groundwork`, `intake`, or `memory`: offer `canon records validate <kind>` for each one found
|
|
78
78
|
- Markdown that git lists: offer `canon markdown audit`
|
|
79
79
|
- TypeScript or shell source present: offer `canon comments scan`
|
|
80
|
-
- A `package.json` script that serves an interface, one of `dev`, `preview`, `serve`, or `start`: offer `
|
|
80
|
+
- A `package.json` script that serves an interface, one of `dev`, `preview`, `serve`, or `start`: offer `ux-measure`
|
|
81
81
|
|
|
82
82
|
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.
|
|
83
83
|
|
|
@@ -104,5 +104,5 @@ The comparison needs the earlier report. When `## Diagnose` was skipped because
|
|
|
104
104
|
## Boundaries
|
|
105
105
|
|
|
106
106
|
- Run `canon`. Never reimplement its install or sync logic, and never edit managed files like rules, configs, or seeds by hand.
|
|
107
|
-
- Hand off the deep flows. Do not duplicate `setup-init` detection or `
|
|
107
|
+
- Hand off the deep flows. Do not duplicate `setup-init` detection or `seed-sync` part-diffing inline.
|
|
108
108
|
- Resolve names from catalogs at runtime. A hardcoded name is a bug.
|
|
@@ -35,7 +35,7 @@ A worker's reply reads as done when it is not. One pull request's fix for two mi
|
|
|
35
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
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
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 `
|
|
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
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
40
|
- Edit a managed file in a target by hand rather than through the `canon` verb that owns it
|
|
41
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.
|
|
@@ -50,10 +50,10 @@ A worker's reply reads as done when it is not. One pull request's fix for two mi
|
|
|
50
50
|
|
|
51
51
|
## Out of scope
|
|
52
52
|
|
|
53
|
-
- This repository's own board, queue, and worker dispatch, which `
|
|
54
|
-
- The role a session building one branch under one plan in this repository takes, which `
|
|
55
|
-
- Entering the worktree, which `
|
|
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
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 `
|
|
58
|
-
- Answering a posted review inside the target, which `
|
|
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
59
|
- The commit and the pull request mechanics, which the `git-*` family owns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
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 `
|
|
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
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ This skill runs outward. Every other skill for operating on a target assumes the
|
|
|
10
10
|
|
|
11
11
|
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.
|
|
12
12
|
|
|
13
|
-
`
|
|
13
|
+
`role-orchestrator` owns this repository's own board and is a different subject. Read nothing from `.canon/tasks/` here and write nothing to it.
|
|
14
14
|
|
|
15
15
|
## Take a role before anything else
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ One wave takes one toolkit change to every target and ends with a pull request p
|
|
|
19
19
|
|
|
20
20
|
The role is read off the prompt because nothing else carries it. A dispatched worker starts in the target's own checkout, which is a repository like any other from the session's side, so a test on the working directory answers the same for a worker in a target and an operator who invoked this from one. Reading the role wrong in that direction starts a second wave from inside a consuming project, which is why the dispatch below names the role and the path both rather than relying on either alone.
|
|
21
21
|
|
|
22
|
-
Do not invoke `canon:
|
|
22
|
+
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.
|
|
23
23
|
|
|
24
24
|
## Guards
|
|
25
25
|
|
|
@@ -71,7 +71,7 @@ Report each dispatch by naming the target, the clone, the branch, the model, and
|
|
|
71
71
|
## Phase 2: review every pull request
|
|
72
72
|
|
|
73
73
|
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.
|
|
74
|
-
2. Review here, in this session. Invoke `canon:
|
|
74
|
+
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:
|
|
75
75
|
- `--repo <owner>/<name>` on `gh pr view`, `gh pr diff`, and `gh pr review`, where it is a global flag.
|
|
76
76
|
- `-C <clone>` on `git fetch origin pull/<n>/head`, `git merge-base`, `git diff`, `git log`, `git show`, and `git grep`.
|
|
77
77
|
- `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.
|
|
@@ -88,7 +88,7 @@ Report each dispatch by naming the target, the clone, the branch, the model, and
|
|
|
88
88
|
|
|
89
89
|
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.
|
|
90
90
|
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.
|
|
91
|
-
- A live session holds it: send that session the findings and name `canon:
|
|
91
|
+
- A live session holds it: send that session the findings and name `canon:review-address` for it to run, which is step 6 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. Assuming the worker was gone is what one hand-driven pass got wrong. All four sessions that opened those pull requests were still alive holding their worktrees hours later, and of two fresh addressers 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.
|
|
92
92
|
- 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.
|
|
93
93
|
- More than one row: report the ambiguity and stop rather than picking among candidates.
|
|
94
94
|
3. Re-review when the answer lands, scoped to the commits added since. A worker's reply never closes a target. One fix for two minor findings closed both and introduced four more, every one of them in prose that fix added, and a loop trusting the reply merges that.
|
|
@@ -100,11 +100,11 @@ Report each dispatch by naming the target, the clone, the branch, the model, and
|
|
|
100
100
|
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.
|
|
101
101
|
|
|
102
102
|
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.
|
|
103
|
-
2. Enter a worktree. Invoke `canon:
|
|
103
|
+
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.
|
|
104
104
|
3. 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.
|
|
105
105
|
4. 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.
|
|
106
106
|
5. Announce as the pull request opens, carrying its URL, its number, and the branch, to whoever dispatched this session. That transition is the one moment only this session can observe.
|
|
107
|
-
6. Answer the review. Invoke `canon:
|
|
107
|
+
6. 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.
|
|
108
108
|
7. 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`.
|
|
109
109
|
|
|
110
110
|
Send a block out as a message before it becomes an interactive prompt. A session already waiting on input never reaches the tool round an inbound message drains at, so an answer relayed afterwards arrives under the open question and changes nothing.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: design-extract
|
|
3
3
|
description: Why a design system is drafted from what the tree already holds, and how a proposed value is kept distinguishable from a sourced one
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Design extract requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -38,5 +38,5 @@ The greenfield case is the one that fails quietly. A project with no UI code sti
|
|
|
38
38
|
|
|
39
39
|
- Mutating an existing design system, which is a direct edit of the file rather than a skill
|
|
40
40
|
- Producing the HTML and CSS preview, which `canon design render` owns
|
|
41
|
-
- Auditing the implemented UI against the tokens, which `
|
|
42
|
-
- Architecture and flow diagrams, which `
|
|
41
|
+
- Auditing the implemented UI against the tokens, which `ux-audit` owns
|
|
42
|
+
- Architecture and flow diagrams, which `draft-diagram` owns
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: design-extract
|
|
3
3
|
description: Drafts `.claude/DESIGN.md` from a project's existing prose and shell UI surfaces, or proposes token values from `REQUIREMENTS.md` and a `## Personality` section when no UI code exists yet. Use when asked to "extract the design system", "draft DESIGN.md", "bootstrap design tokens", "capture the visual system", "propose a design system", "bootstrap DESIGN.md from scratch", "draft tokens for a greenfield project", or "replace Claude Design onboarding". Do NOT use to mutate an existing `.claude/DESIGN.md`.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: docs-fold
|
|
3
3
|
description: What the planning-doc reconcile is for, the gaps it closes, and why the diff decides completion alone
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Docs fold requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -53,7 +53,7 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
|
|
|
53
53
|
|
|
54
54
|
## Out of scope
|
|
55
55
|
|
|
56
|
-
- Creating a task file or moving one off the board, which `
|
|
56
|
+
- Creating a task file or moving one off the board, which `task-board` owns
|
|
57
57
|
- Public-facing docs, which `docs-sync` owns, apart from landing a page a promotion handoff already carries a confirmed destination for. This skill reconciles the `.claude/` planning surface, and both descriptions name their corpus in the trigger so a request saying only "sync the docs" lands on one of the pair rather than on either.
|
|
58
58
|
- Deciding where a promoted page belongs, which is settled with the operator by the surface that produced the page
|
|
59
59
|
- Regenerating the task index, owned by a hook
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Updates `.claude/` planning docs to reflect decisions made during the session, marks outcomes the diff shipped `[x]`, and archives the plans those tasks cite. Use when asked to "sync the .claude docs", when design or requirements changed mid-cycle, after discussing a pivot, or before shipping. Do NOT use to create a task file or move one out of the live folder. That is `
|
|
2
|
+
name: docs-fold
|
|
3
|
+
description: Updates `.claude/` planning docs to reflect decisions made during the session, marks outcomes the diff shipped `[x]`, and archives the plans those tasks cite. Use when asked to "sync the .claude docs", when design or requirements changed mid-cycle, after discussing a pivot, or before shipping. Do NOT use to create a task file or move one out of the live folder. That is `task-board`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Docs fold
|
|
7
7
|
|
|
8
8
|
## Guards
|
|
9
9
|
|
|
@@ -49,7 +49,7 @@ Read these in parallel from the current worktree root (`pwd`), not the main work
|
|
|
49
49
|
- `.claude/DESIGN.md`
|
|
50
50
|
- `.claude/wireframes/index.md` and every surface file it links to, following a grouped surface's own `index.md` and the siblings it lists rather than stopping at the top-level folder
|
|
51
51
|
|
|
52
|
-
Read the task board from the main worktree root instead, resolving that root the way `
|
|
52
|
+
Read the task board from the main worktree root instead, resolving that root the way `session-worktree` does. It is gitignored scratch and never commits with the branch:
|
|
53
53
|
|
|
54
54
|
- `.canon/tasks/index.md` first, then the task files this session touched. That narrow read serves the marking step, which is the only step here that opens a task file.
|
|
55
55
|
|
|
@@ -84,7 +84,7 @@ The steps that follow reach past the session, so each earns the reach separately
|
|
|
84
84
|
|
|
85
85
|
- Step 4 stubs against the diff. That is why the skip is not a stop. A session that changed no docs is exactly when an uncovered surface goes unnoticed.
|
|
86
86
|
- Step 5 reads the architecture record against the diff. A run that amended no decision is the one where an anchored number moves under a reasoning nobody reread, which is the case the marker exists to surface.
|
|
87
|
-
- Step 7 rewrites context entries against the diff and against the facts `
|
|
87
|
+
- Step 7 rewrites context entries against the diff and against the facts `memory-capture` routed. The Diff baseline section above groups its diff half with Steps 4 and 5 as a scoped-set step, so a quiet session is no different from any other for it. The routed half reads a named file and runs whatever the diff shows.
|
|
88
88
|
- The scratch sweep reads the board rather than the session. Its board-wide scan exists to clear a plan an earlier run stranded, and a run that stops at Step 2 can never reach one.
|
|
89
89
|
|
|
90
90
|
This changes which steps the skill reaches. It does not widen what any of them reads. Steps 4, 5, and 7 still take the same scoped set the Diff baseline section defines, and that section's rule is about the input a step is handed rather than about which steps run.
|
|
@@ -148,7 +148,7 @@ Read `.claude/context/index.md` at `pwd` to see which domain entries exist. Skip
|
|
|
148
148
|
|
|
149
149
|
Two sources feed this step, the same split Step 2 runs on. The diff carries what the repository changed. The routed facts carry what the session learned, which a diff cannot show.
|
|
150
150
|
|
|
151
|
-
**Routed facts.** Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`, falling back to `latest` on an empty result, and read `.canon/tmp/memory-routing/<slug>.md` at the main worktree root. `
|
|
151
|
+
**Routed facts.** Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`, falling back to `latest` on an empty result, and read `.canon/tmp/memory-routing/<slug>.md` at the main worktree root. `memory-capture` writes it, one H2 per target entry naming the path, with the fact underneath. Fold each fact into the entry its heading names, which for a nested `.claude/context/<domain>/index.md` heading is the sibling file the fact belongs under rather than the generated index itself. Then delete the handoff file so a later run does not fold it twice.
|
|
152
152
|
|
|
153
153
|
This half is not diff-scoped and must not be. A gotcha a session hit while working is exactly the fact the diff never shows, and scoping it to changed files would drop the entries worth keeping. The handoff is a named input rather than a scan, so the reach stays bounded to what capture decided.
|
|
154
154
|
|
|
@@ -173,7 +173,7 @@ Grep the tree for the name that went, rather than for the paths the diff carries
|
|
|
173
173
|
|
|
174
174
|
Report each hit as an ordinary rewrite.
|
|
175
175
|
|
|
176
|
-
Do not create new entries automatically. Before treating a domain as new, confirm it holds no entry under either spelling, `.claude/context/<domain>.md` or `.claude/context/<domain>/index.md`, since a domain already split into a folder still passes a check that only looked for the flat file. New entries are a deliberate decision: the user invokes `
|
|
176
|
+
Do not create new entries automatically. Before treating a domain as new, confirm it holds no entry under either spelling, `.claude/context/<domain>.md` or `.claude/context/<domain>/index.md`, since a domain already split into a folder still passes a check that only looked for the flat file. New entries are a deliberate decision: the user invokes `docs-fold --new-context <domain>` (future flag) or hand-creates the file following `${CLAUDE_SKILL_DIR}/../../standards/context.md`. Auto-creation risks padding `.claude/context/` with low-signal entries.
|
|
177
177
|
|
|
178
178
|
Write each updated entry immediately. Output one line per file, naming the path this run actually wrote rather than always the flat template:
|
|
179
179
|
|
|
@@ -187,7 +187,7 @@ The base lint-staged config runs `canon indexes regen` on every committed `*.md`
|
|
|
187
187
|
|
|
188
188
|
## Step 8: fold promoted pages
|
|
189
189
|
|
|
190
|
-
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`, falling back to `latest` on an empty result, and read `.canon/tmp/teach-promotion/<slug>.md` at the main worktree root. `
|
|
190
|
+
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`, falling back to `latest` on an empty result, and read `.canon/tmp/teach-promotion/<slug>.md` at the main worktree root. `teach-workspace` writes it, one H2 per destination naming the path, with a source line under the heading and the page body in a fenced block below that. Read the body out of the fence rather than off the heading level, since a reference page carries headings of its own and only the fence separates them from the next destination. Skip this step silently when the file is absent, which is every run where nothing was promoted.
|
|
191
191
|
|
|
192
192
|
Each block is a page an operator already confirmed a destination for, so this step lands it rather than judging it again. Write to the destination the heading names, at `pwd` rather than at the main root, since every destination here is a tracked file that commits with the branch:
|
|
193
193
|
|
|
@@ -210,7 +210,7 @@ Report a block left unfolded rather than dropping it:
|
|
|
210
210
|
|
|
211
211
|
## Step 9: sweep consumed receipts
|
|
212
212
|
|
|
213
|
-
Sweep the review and memory receipts this session consumed. Resolve all paths at the main worktree root, not the current worktree, the way `
|
|
213
|
+
Sweep the review and memory receipts this session consumed. Resolve all paths at the main worktree root, not the current worktree, the way `session-worktree` does.
|
|
214
214
|
|
|
215
215
|
Every delete below is a shell operation, so send each as a plain single `Bash` command rather than joining two with `&&`, which is refused as compound from a linked worktree.
|
|
216
216
|
|
|
@@ -218,22 +218,22 @@ Plans are not swept here. A plan is settled by the merge rather than by an outco
|
|
|
218
218
|
|
|
219
219
|
### Reviews
|
|
220
220
|
|
|
221
|
-
Leave the current branch's review receipt where it is. `
|
|
221
|
+
Leave the current branch's review receipt where it is. `auto-ship` Step 6 keeps minor findings in `.canon/review/branch/review-<slug>.md` and its closing block hands the reader that path, so deleting it here removes the file the chain that invoked this skill is still citing. Seven runs recorded that collision across two days before a sandbox fixture asserted the receipt and could pass only on a run the chain stopped early.
|
|
222
222
|
|
|
223
223
|
The body that writes a receipt owns its lifetime. This skill sweeps on behalf of whatever called it and has no way to read whether a file is still in use, where the chain that wrote this one cites it in its own output and knows. What reaps it is the branch sweep below, one branch later, once the branch it names is gone.
|
|
224
224
|
|
|
225
|
-
Sweep the branch reports this session never opened. List `.canon/review/branch/review-*.md`, run the slug transform in `${CLAUDE_SKILL_DIR}/../../standards/slug.md` over every name `git branch --format='%(refname:short)'` prints, and delete a report whose slug matches none of them. Take the names from that format rather than from `git branch --list`, which marks the current branch with `* ` and a branch checked out in another worktree with `+ `, so a transform reading the marked lines as written turns a live branch into a slug nothing matches and sweeps a report a sibling worktree is still working from. A branch report is read once, by the session addressing it, and the durable record of what a review found is the comment `
|
|
225
|
+
Sweep the branch reports this session never opened. List `.canon/review/branch/review-*.md`, run the slug transform in `${CLAUDE_SKILL_DIR}/../../standards/slug.md` over every name `git branch --format='%(refname:short)'` prints, and delete a report whose slug matches none of them. Take the names from that format rather than from `git branch --list`, which marks the current branch with `* ` and a branch checked out in another worktree with `+ `, so a transform reading the marked lines as written turns a live branch into a slug nothing matches and sweeps a report a sibling worktree is still working from. A branch report is read once, by the session addressing it, and the durable record of what a review found is the comment `review-pr` posts on the pull request, so a report outliving its branch is holding nothing. Skipping this leaves them accumulating for the life of the checkout, since a slug is unique per feature and no later branch ever looks for one.
|
|
226
226
|
|
|
227
|
-
What that removes is a local-only review on a branch deleted before it opened a pull request. `
|
|
227
|
+
What that removes is a local-only review on a branch deleted before it opened a pull request. `review-branch` says so where a reader meets the report, and the sweep runs anyway rather than keeping every report against the one case, since nothing else ever clears them.
|
|
228
228
|
|
|
229
|
-
Memory receipts sweep board-wide rather than by slug. Scan every `.canon/review/memory/memory-review-*.md`, not only the one matching this slug. `
|
|
229
|
+
Memory receipts sweep board-wide rather than by slug. Scan every `.canon/review/memory/memory-review-*.md`, not only the one matching this slug. `memory-review` writes its receipt after this skill has run in every ship chain, so a sweep keyed on the current slug looks for a file that does not exist yet, and no later branch looks for it either because a slug is unique per feature. Scanning the folder is what makes the sweep fire at all.
|
|
230
230
|
|
|
231
231
|
For each receipt, count the H2 items still marked 📝 pending:
|
|
232
232
|
|
|
233
233
|
- No pending item: fold it per the collection rule in `${CLAUDE_SKILL_DIR}/../../standards/memory.md`, then delete the receipt.
|
|
234
234
|
- Any pending item: leave it and report the count. Pending items are decision state, and a branch shipping is not an operator deciding them.
|
|
235
235
|
|
|
236
|
-
That standard owns what a fold writes and which entry types take one. `
|
|
236
|
+
That standard owns what a fold writes and which entry types take one. `memory-review` collects a receipt on the same rule, so neither body restates it.
|
|
237
237
|
|
|
238
238
|
Do not sweep `ux-audit-*.md` or `ux-measure-*.md` (standalone deliverables). Those sit at `.canon/review/` itself rather than under a producer folder, so the two globs above never reach them.
|
|
239
239
|
|
|
@@ -5,7 +5,7 @@ description: How an anchored decision's cited paths are collected, the finding t
|
|
|
5
5
|
|
|
6
6
|
# Architecture anchor staleness sweep
|
|
7
7
|
|
|
8
|
-
Mechanics for Step 5 of `
|
|
8
|
+
Mechanics for Step 5 of `docs-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
9
|
|
|
10
10
|
## Anchored entries
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@ description: Slug derivation from a UI-affecting path, the contradicted and unco
|
|
|
5
5
|
|
|
6
6
|
# Wireframe coverage sweep
|
|
7
7
|
|
|
8
|
-
Mechanics for Step 4 of `
|
|
8
|
+
Mechanics for Step 4 of `docs-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
9
|
|
|
10
10
|
## Deriving a candidate slug
|
|
11
11
|
|