@erclx/canon 5.40.0 → 5.42.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 +34 -17
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +2 -0
- package/claude/skills/auto-ship/SKILL.md +28 -2
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/fan-in.md +59 -0
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +9 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/decision-escalate/REQUIREMENT.md +1 -1
- package/claude/skills/decision-escalate/SKILL.md +1 -2
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +54 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/REQUIREMENT.md +17 -6
- package/claude/skills/git-branch/SKILL.md +63 -7
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +8 -0
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +28 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/batches.md +48 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +59 -20
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +1 -1
- package/claude/skills/plan-intake-answer/SKILL.md +1 -2
- package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
- package/claude/skills/pr-evidence/SKILL.md +53 -0
- package/claude/skills/pr-evidence/references/evidence.md +150 -0
- package/claude/skills/review-address/references/post-review-findings.md +10 -3
- package/claude/skills/review-address/references/rebase-conflicts.md +22 -7
- package/claude/skills/review-address/references/rest-reads.md +3 -1
- package/claude/skills/review-craft/references/adopted.md +35 -18
- package/claude/skills/review-craft/references/security.md +42 -7
- package/claude/skills/review-craft/references/ui.md +23 -8
- package/claude/skills/review-pr/SKILL.md +6 -6
- package/claude/skills/review-pr/references/body-variants.md +29 -9
- package/claude/skills/review-pr/references/close-out.md +20 -5
- package/claude/skills/review-pr/references/key-changes.md +27 -3
- package/claude/skills/review-pr/references/post.md +83 -31
- package/claude/skills/review-pr/references/scope.md +54 -19
- package/claude/skills/review-ui/SKILL.md +2 -0
- package/claude/skills/review-ui/references/close-out.md +49 -0
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -13
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +81 -40
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +12 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-worker/REQUIREMENT.md +2 -0
- package/claude/skills/role-worker/SKILL.md +17 -0
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/REQUIREMENT.md +1 -1
- package/claude/skills/teach-workspace/SKILL.md +1 -2
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/workflow/parallel-features.md +2 -1
- package/docs/workflow/skill-map.md +2 -1
- package/package.json +1 -1
- package/src/claude/cases/git.ts +4 -0
- package/src/claude/cases/workflow.ts +5 -0
- package/src/commands/pr.ts +174 -37
- package/src/commands/records.ts +11 -3
- package/src/context/shape-gated.ts +1 -0
- package/src/markdown/scope.ts +150 -2
- package/src/pr/frames.ts +53 -9
- package/src/pr/lift.ts +6 -3
- package/src/pr/review-state.ts +182 -0
- package/src/records/validate.ts +1 -0
- package/src/tasks/answers.ts +79 -2
- package/src/tasks/fan-in.ts +176 -0
- package/src/tasks/stack.ts +1 -1
- package/tooling/astro/reference.md +80 -39
- package/tooling/base/reference.md +63 -32
- package/tooling/base/seeds/canon/context/ci.md +7 -15
- package/tooling/base/seeds/canon/context/development.md +14 -14
- package/tooling/claude/reference.md +40 -22
- package/tooling/cloudflare/reference.md +31 -12
- package/tooling/go/reference.md +47 -23
- package/tooling/nextjs/reference.md +52 -19
- package/tooling/php/reference.md +35 -16
- package/tooling/python/reference.md +47 -30
- package/tooling/shell/reference.md +6 -5
- package/tooling/vite-react/reference.md +49 -21
- package/tooling/web/reference.md +130 -70
- package/claude/skills/git-pr/references/evidence.md +0 -124
package/README.md
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
|
|
14
14
|
canon is a CLI and Claude Code plugin that runs your agent's work from plan to merge, holds it to the practices that make code worth keeping, and installs the same setup in every repository.
|
|
15
|
-
|
|
16
15
|
**[See it run at canon.erclx.dev](https://canon.erclx.dev)**
|
|
17
16
|
|
|
18
17
|
</div>
|
|
@@ -21,9 +20,13 @@ That page is one real session the toolkit ran on itself, and every count on it i
|
|
|
21
20
|
|
|
22
21
|
## Why
|
|
23
22
|
|
|
24
|
-
If an agent writes code for you in more than one repository, this is for you. canon runs that work from plan to merge. A planner writes the plan, a worker builds it on its own branch, and a separate session reviews the pull request.
|
|
23
|
+
If an agent writes code for you in more than one repository, this is for you. canon runs that work from plan to merge. A planner writes the plan, a worker builds it on its own branch, and a separate session reviews the pull request.
|
|
24
|
+
|
|
25
|
+
It holds the work to a practice, with rules that load when a matching path is edited and checks that fail when a rule is ignored. Both run on one setup, installed the same way in every repository you keep.
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
### The shared setup
|
|
28
|
+
|
|
29
|
+
That shared setup is what the rest of this page describes, and it drifts without a source. Every AI coding setup accumulates the same assets. Prompts to reuse, rules agents should follow, slash commands, skills, seed docs, sync scripts. Once you have enough projects, your copies drift and your agents stop getting consistent signals.
|
|
27
30
|
|
|
28
31
|
Three design choices shape the toolkit.
|
|
29
32
|
|
|
@@ -61,17 +64,21 @@ bun install --global @erclx/canon
|
|
|
61
64
|
|
|
62
65
|
Each domain has a canonical source in this repo and a thin install or sync CLI on your side. The domains split on one line: some are copied into your project and become yours to edit, and some are never copied at all.
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
67
|
+
### Domain catalog
|
|
68
|
+
|
|
69
|
+
| Domain | What it is | How it reaches you |
|
|
70
|
+
| -------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
71
|
+
| Plugin skills | Skills that plan a feature, review a diff, sync the planning docs, and run the ship chain | Loaded live from the plugin, never copied |
|
|
72
|
+
| Governance | Coding and authoring rules that load into a Claude session when a matching path is edited | Installed per project by `canon gov install`, refreshed by sync |
|
|
73
|
+
| Tooling stacks | Golden configs, seeds, and a reference per framework | Laid down by `canon init`, reconciled by `canon tooling sync` |
|
|
74
|
+
| Design system | Ships a `DESIGN.md` intent format pointing at your stylesheet for values, a skill that drafts one, and a render command | `canon design render` |
|
|
75
|
+
| Slides | A folder of HTML slides per deck, drawn in the project's tokens and rebuilt as editable shapes | `canon slides render` writes PowerPoint |
|
|
76
|
+
| Teach | Lessons, sources, and a glossary in one workspace, rendered to a small site | `canon teach` |
|
|
77
|
+
| Canvas | Pages of HTML frames on a local pan and zoom surface, each frame drawn with the project's tokens | `canon canvas serve` |
|
|
78
|
+
| Transcripts | A YouTube transcript with metadata frontmatter | `canon transcripts <url>` writes it into any repo |
|
|
79
|
+
| Sandbox | Scenario scaffolds that provision an isolated project state for verifying each domain flow | `canon sandbox` |
|
|
80
|
+
|
|
81
|
+
### How domains reach you
|
|
75
82
|
|
|
76
83
|
Those domains reach you in three shapes. A tooling stack lands as real files under version control, because a config is something your build reads and your project owns. A plugin skill and the references it carries are never copied, so there is no copy in your repo to drift from this one.
|
|
77
84
|
|
|
@@ -117,6 +124,8 @@ The first two update the skills, the third updates the CLI, and they move indepe
|
|
|
117
124
|
|
|
118
125
|
`canon upgrade` reads the package manager off its own install path and reinstalls with that one, so you don't have to remember which put it there. It names what it detected before it runs anything, and it refuses a source checkout rather than reinstalling over your clone.
|
|
119
126
|
|
|
127
|
+
### Checking for drift
|
|
128
|
+
|
|
120
129
|
You don't have to wait until something breaks to find out you're behind. `canon sync --check` and `canon claude skills drift` both report the installed version against the newest published one, and neither changes its exit code over it, so an offline machine reads unknown rather than red.
|
|
121
130
|
|
|
122
131
|
To stop doing this by hand, turn auto-update on once under `/plugin` in the Marketplaces tab. Confirm what you are running with `canon --version` and `claude plugin list`.
|
|
@@ -127,6 +136,8 @@ Working on the toolkit starts from a clone. Running the CLI doesn't, since it in
|
|
|
127
136
|
|
|
128
137
|
### Prerequisites
|
|
129
138
|
|
|
139
|
+
Bun, Git, and a shell are required, and the GitHub CLI is optional.
|
|
140
|
+
|
|
130
141
|
- [Bun](https://bun.sh) for the CLI runtime and scripts
|
|
131
142
|
- [Git](https://git-scm.com) with worktree support
|
|
132
143
|
- [GitHub CLI](https://cli.github.com) (optional) for ship flows
|
|
@@ -141,7 +152,10 @@ bun install
|
|
|
141
152
|
bun run bootstrap
|
|
142
153
|
```
|
|
143
154
|
|
|
144
|
-
The script is idempotent, so re-run it after pulling upstream changes without duplicating anything.
|
|
155
|
+
The script is idempotent, so re-run it after pulling upstream changes without duplicating anything. It confirms the install by resolving `canon --help` on the last step.
|
|
156
|
+
|
|
157
|
+
- It leaves an alias block you already have alone rather than refreshing it, so an alias added upstream needs the block deleted and the script re-run.
|
|
158
|
+
- [Zshrc aliases](docs/workflow/zshrc-aliases.md) covers what each alias does, how to pick up a new one, and how to opt out of the block.
|
|
145
159
|
|
|
146
160
|
With the CLI linked, scaffold a fresh project.
|
|
147
161
|
|
|
@@ -151,9 +165,12 @@ git init
|
|
|
151
165
|
canon init
|
|
152
166
|
```
|
|
153
167
|
|
|
154
|
-
`canon init` installs base tooling configs, Claude seeds, and governance rules in one pass, and scaffolds a `.claude/wiki/` stub for your project's own reference pages.
|
|
168
|
+
`canon init` installs base tooling configs, Claude seeds, and governance rules in one pass, and scaffolds a `.claude/wiki/` stub for your project's own reference pages.
|
|
155
169
|
|
|
156
|
-
|
|
170
|
+
- Governance defaults to the `base` stack, so a bare init lands the workflow and doc-authoring rules in `.claude/rules/`.
|
|
171
|
+
- Each rule names the skill it loads, so no corpus is copied into your project.
|
|
172
|
+
- Pass `--stack <name>` for a language stack such as `node` or `python`, or `--skip governance` to leave rules out.
|
|
173
|
+
- Run `canon tooling list --json` to see the catalog.
|
|
157
174
|
|
|
158
175
|
For the full journey from scaffold through adding a domain later to syncing upstream drift, see [target projects](docs/target/projects.md).
|
|
159
176
|
|
|
@@ -5,36 +5,56 @@ description: Which external API design sources this skill adopted, which it decl
|
|
|
5
5
|
|
|
6
6
|
# Adopted and declined
|
|
7
7
|
|
|
8
|
-
External sources were read and filtered rather than imported. This file is the record
|
|
8
|
+
External sources were read and filtered rather than imported. This file is the record, and a later session extending the skill adds to it rather than re-arguing an item settled here.
|
|
9
9
|
|
|
10
|
-
## Adopted
|
|
10
|
+
## Adopted from the default shelf
|
|
11
11
|
|
|
12
|
-
###
|
|
12
|
+
### Observable behavior
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
[Software Engineering at Google, ch. 1](https://abseil.io/resources/swe-book/html/ch01.html) states Hyrum's Law, that with enough users, every observable behavior of a system is depended on by somebody, whatever the contract promises.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Adopted as the opening group, stated as design rules rather than as an observation, so a session decides what is observable before a caller decides it for them. Ordering and timing are named because the chapter's own examples are hash iteration order and timing.
|
|
17
17
|
|
|
18
|
-
###
|
|
18
|
+
### One version per dependency
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
[Software Engineering at Google, ch. 21](https://abseil.io/resources/swe-book/html/ch21.html) states the One-Version Rule, keeping one version of each dependency in a repository, so a change to it migrates every caller rather than leaving two versions live. Adopted under additive change for a caller that cannot pin, which is any module imported from inside one repository.
|
|
21
|
+
|
|
22
|
+
## Adopted from one external skill
|
|
23
|
+
|
|
24
|
+
From `addyosmani/agent-skills@2686b620`, [`skills/api-and-interface-design/SKILL.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/skills/api-and-interface-design/SKILL.md).
|
|
25
|
+
|
|
26
|
+
### Contract and errors
|
|
21
27
|
|
|
22
28
|
**Contract first.** Write the interface before the body. Adopted as its own group, widened from an endpoint to a signature, a flag set, an output shape, and a schema.
|
|
23
29
|
|
|
24
|
-
**One error shape.** Every failure on one surface carries the same structure. Adopted with a stable code
|
|
30
|
+
**One error shape.** Every failure on one surface carries the same structure. Adopted with a stable code for the caller to branch on, and internal details kept out of the message, since no project rule carries either for every code stack.
|
|
31
|
+
|
|
32
|
+
### Input and change
|
|
25
33
|
|
|
26
34
|
**Validation at the boundary.** Check input where it enters and trust it inside. Adopted, with a value read back from a file or another service counted as input.
|
|
27
35
|
|
|
28
|
-
**Additive change.** New fields optional, nothing removed in place. Adopted, with a change of meaning under an existing name
|
|
36
|
+
**Additive change.** New fields optional, nothing removed in place. Adopted, with a change of meaning under an existing name as its own ban, since it breaks a caller as surely as a removal and no rename shows in the diff.
|
|
37
|
+
|
|
38
|
+
### Idempotency
|
|
29
39
|
|
|
30
|
-
|
|
40
|
+
A stored key honored on retry, an atomic claim under a unique constraint, a reused key with a different body failing loudly, and retention past the longest retry. Adopted as four rules, keeping the reused-key rule, which is the one most often left out.
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
### The closing sections
|
|
43
|
+
|
|
44
|
+
The same source's skill anatomy supplies the excuses, red flags, and closing checklist, adopted toolkit-wide through `${CLAUDE_SKILL_DIR}/../create-skill/references/skill-practice.md`. Each excuse row here rebuts a reason a session gives when about to break a caller, such as "nobody depends on that field".
|
|
33
45
|
|
|
34
46
|
## Declined
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
Each item below was read and left out, with the reason it changes nothing a session does here.
|
|
49
|
+
|
|
50
|
+
### Protocol-specific guidance
|
|
51
|
+
|
|
52
|
+
The source skill carries verbs, status codes, pagination, and URL shapes for one protocol style. Declined because the body holds for a function's exports, a command's flags, and a file format as much as an endpoint, so a protocol section would route every non-network surface to rules that do not apply.
|
|
53
|
+
|
|
54
|
+
A project needing those conventions states them in its own stack rule.
|
|
55
|
+
|
|
56
|
+
### Depth and versions
|
|
37
57
|
|
|
38
|
-
**Interface depth.** Ousterhout's deep modules, after [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php), judge how much a module hides behind its surface.
|
|
58
|
+
**Interface depth.** Ousterhout's deep modules, after [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php), judge how much a module hides behind its surface. Depth is about what sits behind a boundary, and this skill owns only what crosses it, so `code-craft` carries it.
|
|
39
59
|
|
|
40
|
-
**Versioned surfaces as the default.** Shipping a new version beside the old for every breaking change.
|
|
60
|
+
**Versioned surfaces as the default.** Shipping a new version beside the old for every breaking change. Additive change avoids the break in the first place and two live versions split the callers, so the One-Version Rule covers a caller that cannot pin.
|
|
@@ -19,6 +19,8 @@ Without this skill, the run from an approved plan to an open pull request is a c
|
|
|
19
19
|
- Open the pull request as a draft before the continuous integration watch begins, since a pull request marked after it is mergeable for the length of the run
|
|
20
20
|
- Continue past a produced UI checklist rather than stopping on it, and report its unchecked boxes in the closing block, since the draft mark already holds the merge
|
|
21
21
|
- Prove the draft target's head is the current branch and its state is open before marking it, and stop with nothing marked on a mismatch, since the number is retyped between steps and a draft mark on a release pull request holds that release
|
|
22
|
+
- Stop a fan-in member after its verify and test order with a push and a done message rather than a pull request, and open an integrator's build by merging the member branches, since parallel batches sharing edge files put every open sibling into conflict on each merge
|
|
23
|
+
- Wait for both review families through `canon pr review-state --wait` once CI passes on a launch that named a controller, which alone dispatches the reviewers, bounded at the lift's own default, and hand the record to the controller on a timeout, since a worker improvising the read polled issue comments, never saw a UI close posted as a review, and stalled with both reviewers idle
|
|
22
24
|
- Name the recovery for the stop it took, since the value of stopping is that the user knows where to resume
|
|
23
25
|
|
|
24
26
|
## Must not
|
|
@@ -73,6 +73,8 @@ When this run decides against a suggestion, rewrite its line as `overridden at e
|
|
|
73
73
|
|
|
74
74
|
Load `canon:build-in-slices`, reporting it when it does not resolve, and implement only what the plan describes. Do not expand scope, refactor neighbors, or touch files outside the plan's "Files to touch" list without reason.
|
|
75
75
|
|
|
76
|
+
When the plan's `**Constraints:**` carry a `Fans in` bullet, this run is a fan-in integrator, so open this step by merging the member branches, per `${CLAUDE_SKILL_DIR}/references/fan-in.md`.
|
|
77
|
+
|
|
76
78
|
## Step 3: verify
|
|
77
79
|
|
|
78
80
|
Run the verify commands defined in `CLAUDE.md` (lint, typecheck, tests). On failure:
|
|
@@ -97,11 +99,15 @@ The verb reads git history rather than the working tree, so it catches a violati
|
|
|
97
99
|
|
|
98
100
|
Never read a missing subcommand as clean. Read `${CLAUDE_SKILL_DIR}/references/verb-absent.md` on meeting one.
|
|
99
101
|
|
|
102
|
+
### A fan-in member stops here
|
|
103
|
+
|
|
104
|
+
When the plan's `**Constraints:**` carry a `Fan-in member of` bullet, push the branch, announce it done, and stop before Step 5. A member opens no pull request, since its integrator ships the whole set. Read `${CLAUDE_SKILL_DIR}/references/fan-in.md` for the push and the message.
|
|
105
|
+
|
|
100
106
|
## Step 5: UI checklist (conditional)
|
|
101
107
|
|
|
102
108
|
If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
|
|
103
109
|
|
|
104
|
-
When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `
|
|
110
|
+
When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `pr-evidence` removes the file.
|
|
105
111
|
|
|
106
112
|
## Step 6: ship
|
|
107
113
|
|
|
@@ -113,9 +119,29 @@ This chain adds one thing. Mark the pull request as a draft as soon as `git-ship
|
|
|
113
119
|
|
|
114
120
|
- Read `${CLAUDE_SKILL_DIR}/references/draft-mark.md` on reaching that point for the one command that proves the target, marks it, and reads the flag back
|
|
115
121
|
- A `false` read stops the chain, and never re-issue the mark on it
|
|
116
|
-
-
|
|
122
|
+
- Act on the wake after the CI watch exits on `passing`, not when the turn ends on its watch line, moving to Step 7 under a named controller and to the Output block otherwise
|
|
117
123
|
- Keep `git-ship`'s own verify gate, which repeats Step 3 on a clean run, since a resumed run enters at that gate
|
|
118
124
|
|
|
125
|
+
## Step 7: wait for the reviews
|
|
126
|
+
|
|
127
|
+
Run this step only when the launch named a controlling session, since only a controller dispatches the reviewers. A hand-launched run has nobody reviewing, so it emits the Output block on the CI wake instead of waiting on a pass that cannot arrive.
|
|
128
|
+
|
|
129
|
+
Read review state through `canon pr review-state` alone, since both families post as pull request reviews, and a worker polling issue comments instead stalled with both reviewers idle. Run it in the background with the number Step 6 returned, since the wait outlasts a foreground shell call, and act on the wake.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
canon pr review-state <number> --wait 1200 --json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Branch on the record's `reason` rather than on the exit, which a shell function wrapping `canon` can flatten to zero.
|
|
136
|
+
|
|
137
|
+
| `reason` | Route |
|
|
138
|
+
| ----------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| `covered` | Emit the Output block. Invoke `canon:review-address` when `review.reason` or `ui.reason` reads open at the tip |
|
|
140
|
+
| `timeout` | Send the record to the controller per `canon:role-worker`, emit the Output block, and stop rather than waiting again |
|
|
141
|
+
| Any refusal | Report the `reason` to the controller the same way and stop, since an unread thread is not one nobody has reviewed yet |
|
|
142
|
+
|
|
143
|
+
Skip the `review-address` call when a reviewer's message already started it, since that message carries the same posted pass. A close in both families needs nothing from this session, since the reviewers run the lift on their close.
|
|
144
|
+
|
|
119
145
|
## Output
|
|
120
146
|
|
|
121
147
|
Respond with up to two lines:
|
|
@@ -19,14 +19,40 @@ gh api graphql -f query='mutation($id: ID!) { convertPullRequestToDraft(input: {
|
|
|
19
19
|
gh api repos/{owner}/{repo}/pulls/<number> --jq '{isDraft: .draft}'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## Why the mark is local-only
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
The target check and the read-back go through REST. The mark itself is a GraphQL mutation, because the REST pull request update carries no draft field.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
- A cloud session's GitHub access blocks GraphQL, so the mutation fails there and the read-back reports `false`
|
|
27
|
+
- A cloud worker's pull request therefore opens ready, and its chain stops at this step with the pull request already open
|
|
27
28
|
|
|
28
|
-
The number
|
|
29
|
+
## The number
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Name the number `git-ship`'s pull request step returned in every position rather than leaving any to resolve by branch. `${CLAUDE_SKILL_DIR}/../git-pr/REQUIREMENT.md` states why, since a lookup by branch alone can return a closed pull request sharing that head.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
The number crosses from that step's output into a command this session types, the one place a number gets authored rather than derived. A number misread there, or inferred from the newest pull request in view, would draft a stranger's pull request.
|
|
34
|
+
|
|
35
|
+
- A release pull request is the worst such target, since the mark holds the release and this role may not lift it again
|
|
36
|
+
|
|
37
|
+
### A refusal
|
|
38
|
+
|
|
39
|
+
A refusal is a stop. Report the line the shell printed, then resolve the number from the `number=` and `head=` lines of `git-pr`'s output and re-run the command by hand.
|
|
40
|
+
|
|
41
|
+
The comparison sits in the shell rather than in the session's reading of a printed value, the same split `git-pr`'s `assert_own_pr` makes. The judgment that picked a wrong number is the one that would read the check.
|
|
42
|
+
|
|
43
|
+
## The read-back
|
|
44
|
+
|
|
45
|
+
Report what the read returned rather than what the command printed, since the exit says the call ran and says nothing about the state.
|
|
46
|
+
|
|
47
|
+
- A `true` reports a draft
|
|
48
|
+
- A `false` reports the pull request as opened ready and unsupervised, and the chain stops there
|
|
49
|
+
- Never re-issue the mark on a disagreeing read, which fights whoever readied it instead of guarding anything
|
|
50
|
+
|
|
51
|
+
## Why the mark sits ahead of the watch
|
|
52
|
+
|
|
53
|
+
Marking afterwards leaves the pull request unmarked for the whole CI run, the stretch an unattended worker's branch is least supervised. What the mark buys is a reader learning the pull request has had no review yet.
|
|
54
|
+
|
|
55
|
+
It buys no bound on that stretch. Readying a pull request to merge lifts the mark, and GitHub requires it before a merge.
|
|
56
|
+
|
|
57
|
+
- The lift runs through `canon pr lift`, which a reviewer runs on its close and the controlling session runs as the fallback, or through the operator directly
|
|
58
|
+
- `role-worker` states the mirroring refusal of an instruction to ready the pull request directly, whoever sends it
|
|
@@ -7,16 +7,18 @@ description: The step an operator resumes from after each auto-ship stop point,
|
|
|
7
7
|
|
|
8
8
|
Every stop point leaves recoverable state. The user resumes manually from the appropriate step.
|
|
9
9
|
|
|
10
|
-
| Stop point | Recovery
|
|
11
|
-
| ------------------------------------------ |
|
|
12
|
-
| No plan (derived) | Run `/plan-feature` to create one
|
|
13
|
-
| No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run
|
|
14
|
-
| No task (caller-supplied) | Check the task path passed to autoship, then re-run
|
|
15
|
-
| Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run
|
|
16
|
-
| Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly.
|
|
17
|
-
| Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run
|
|
18
|
-
| 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
|
|
19
|
-
| 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.
|
|
20
|
-
| Verify fails | Read logs, fix manually, run `/git-ship`
|
|
21
|
-
| git-ship fails | Inspect hook or remote error, run again
|
|
22
|
-
| Draft target is not this branch's | Nothing was marked. Read the number and `head=` from `git-pr`'s output, confirm they match, then run the mark by hand
|
|
10
|
+
| Stop point | Recovery |
|
|
11
|
+
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
12
|
+
| No plan (derived) | Run `/plan-feature` to create one |
|
|
13
|
+
| No plan (caller-supplied) | Check the path or slug passed to autoship, then re-run |
|
|
14
|
+
| No task (caller-supplied) | Check the task path passed to autoship, then re-run |
|
|
15
|
+
| Task carries no `Plan:` line | Write the plan, point the task's `Plan:` line at it, then re-run |
|
|
16
|
+
| Task points at an archived plan | The work already shipped. Reopen the task against a live plan, or pass that plan's path directly. |
|
|
17
|
+
| Task's `Plan:` pointer resolves to nothing | Repoint the task's `Plan:` line at the plan that exists, then re-run |
|
|
18
|
+
| 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 |
|
|
19
|
+
| 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. |
|
|
20
|
+
| Verify fails | Read logs, fix manually, run `/git-ship` |
|
|
21
|
+
| git-ship fails | Inspect hook or remote error, run again |
|
|
22
|
+
| Draft target is not this branch's | Nothing was marked. Read the number and `head=` from `git-pr`'s output, confirm they match, then run the mark by hand |
|
|
23
|
+
| Review wait timed out | The record went to the controller. Once the reviewers are dispatched, re-run `canon pr review-state <number> --wait 1200 --json` in the background |
|
|
24
|
+
| Review wait refused | Fix what the `reason` names, such as an unreadable remote, then re-run `canon pr review-state <number> --wait 1200 --json` in the background |
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Fan-in member exit and integrator merge
|
|
3
|
+
description: How auto-ship stops a fan-in member after its push and how an integrator merges the member branches before its own build, so a set of parallel batches ships as one pull request
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fan-in
|
|
7
|
+
|
|
8
|
+
The session reads this file at one of two points in `auto-ship`. A member reads `## Member exit` after Step 4, and an integrator reads `## Integrator merge` at the opening of Step 2. When to fan in and how a plan declares its side are in `${CLAUDE_SKILL_DIR}/../plan-feature/references/batches.md`.
|
|
9
|
+
|
|
10
|
+
## Member exit
|
|
11
|
+
|
|
12
|
+
Step 3's verify and Step 4's test order have already run, so the branch is green and committed. The member ends here rather than at a pull request.
|
|
13
|
+
|
|
14
|
+
1. Push the branch with `git push -u origin <branch>`. The pre-push hook runs the project check, and a member that fails it stops the way Step 3 does.
|
|
15
|
+
2. Read the head with `git rev-parse HEAD` once the push returns.
|
|
16
|
+
3. Announce the batch done to the controlling session through `canon:session-relay`, carrying the branch, the head commit, the integrator the plan names, and any row this build turned up.
|
|
17
|
+
4. Stop. Run no UI checklist, no `git-ship`, and no draft mark.
|
|
18
|
+
|
|
19
|
+
The pushed branch is the done signal the integrator's gate reads, so push once, at the end, and never mid-build. The announcement carries no reach, since members of one set share files by design and the integrator's announcement carries the reach for the whole set.
|
|
20
|
+
|
|
21
|
+
A fix the integrator needs after this point lands on the integrator's branch, since a member has no pull request to fix it on.
|
|
22
|
+
|
|
23
|
+
## Integrator merge
|
|
24
|
+
|
|
25
|
+
The members are pushed before this run starts, since `canon tasks plan-answers` holds an integrator until every member branch is on origin. Confirm that before merging anything:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git fetch origin --quiet
|
|
29
|
+
canon tasks plan-answers <plan> --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Stop on `launchable: false`, reporting each `open` entry, since a `Fan-in pending` entry names a member that has not pushed and a `Fan-in set` entry names a set whose sides disagree. Then merge each member in the order the `Fans in` bullet lists:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git merge --no-ff --no-edit origin/<member branch>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Conflicts and the order
|
|
39
|
+
|
|
40
|
+
`--no-ff` keeps one merge commit per member, so `git log --first-parent` shows the reviewer one member at a time. Never squash or fast-forward a member in.
|
|
41
|
+
|
|
42
|
+
- Resolve each conflict by `## Resolving a conflict` in `${CLAUDE_SKILL_DIR}/../review-address/references/rebase-conflicts.md`
|
|
43
|
+
- Stop on a hunk needing a decision with `git merge --abort` in place of the rebase abort that file names
|
|
44
|
+
- Regenerate the indexes once, after the last merge, rather than resolving a generated file by hand at each one
|
|
45
|
+
- Run `git config rerere.enabled true` before the first merge, since a stale integrator rebases with `--rebase-merges` per the same file and that replays each merge without its recorded resolution
|
|
46
|
+
|
|
47
|
+
Continue Step 2 with the integrator plan's own `**Files to touch:**`, then the rest of the chain as an ordinary worker.
|
|
48
|
+
|
|
49
|
+
### What the pull request carries
|
|
50
|
+
|
|
51
|
+
Say in the pull request body that each member is one merge commit and name the members in merge order. Once the pull request merges, delete each member's branch on origin, its worktree, and its local branch:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git push origin --delete <member branch>
|
|
55
|
+
git worktree remove <member worktree>
|
|
56
|
+
git branch -D <member branch>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Read each member's worktree path off `git worktree list --porcelain` by its branch. The integrator holds the member list, so the deletion is its step rather than a sweep's. No member opens a pull request, so `canon worktrees reclaim` never reads a member's branch as merged and reports a leftover worktree as unmerged work on every run.
|
|
@@ -9,21 +9,42 @@ Step 1 of `auto-ship`, tier 1. The session reads this file when the invocation c
|
|
|
9
9
|
|
|
10
10
|
## Reading the pointer
|
|
11
11
|
|
|
12
|
-
One plan per task is what makes the tier 1 read unambiguous
|
|
12
|
+
One plan per task is what makes the tier 1 read unambiguous. It takes the first `Plan:` line outside a fenced sample, and never scans for a second line or reads past a second link on that one.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
- A caller who means the task already holds its path, having read it off the board, which is why a bare slug never reaches this tier
|
|
15
|
+
- Read the target out of the link's parentheses, and take the rest of the line when it carries no link, since an older task writes the target as a plain path
|
|
16
|
+
- A bare line counts its leading run of tokens carrying `/` or ending in `.md` as targets and stops at the first word that is neither, so trailing prose after one path still names a single plan
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
### Resolving the target
|
|
19
|
+
|
|
20
|
+
Resolve a relative target against the directory holding the task file rather than against `.canon/tasks/`, and take a project-root target from the root.
|
|
21
|
+
|
|
22
|
+
The archived task is what makes that base matter. The standard points its line at `../../plans/archive/feature-<slug>.md` once the task sits a folder deeper, and reading that from `.canon/tasks/` lands on a repository-root `plans/archive/` that never exists.
|
|
17
23
|
|
|
18
24
|
## When a tier fails
|
|
19
25
|
|
|
20
|
-
Tier 1 stops on four failures,
|
|
26
|
+
Tier 1 stops on four failures, each naming a different repair. Test them in the order below.
|
|
27
|
+
|
|
28
|
+
| Failure | Stop |
|
|
29
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| The line links several plans | `❌ <path> links <N> plans on its Plan: line (<every target>), so the task does not say which one this run builds. Pass one plan path directly.` |
|
|
31
|
+
| No `Plan:` line at all | `❌ <path> carries no Plan: line, so nothing there names a plan to run. Write the plan and point the task at it, or pass the plan path directly.` |
|
|
32
|
+
| Pointer into a plans archive | `❌ <path> points at an archived plan, which describes work that already shipped. Reopen the task against a live plan, or pass that plan directly.` |
|
|
33
|
+
| Pointer resolves to no file | `❌ <path> points at <target>, which does not exist. The citation is stale, so repoint the task or pass the plan path directly.` |
|
|
34
|
+
|
|
35
|
+
### Why each test sits where it does
|
|
36
|
+
|
|
37
|
+
Each row carries a reason a shortcut would get wrong.
|
|
38
|
+
|
|
39
|
+
- Test several links first, since taking the first link runs whichever plan leads the line and reports success
|
|
40
|
+
- A row still awaiting a plan is the ordinary case, so the no-line message names the missing pointer rather than the plan sections a reader would then hunt for
|
|
41
|
+
- Test the resolved path for an archive rather than the task's outcomes or its `Pull request:` line, since a stale board gets its ticks wrong and the standard fixes where a shipped pointer lands
|
|
42
|
+
|
|
43
|
+
### What counts as an archive
|
|
21
44
|
|
|
22
|
-
|
|
23
|
-
- No `Plan:` line at all. Stop: `❌ <path> carries no Plan: line, so nothing there names a plan to run. Write the plan and point the task at it, or pass the plan path directly.` A row still awaiting a plan is the ordinary case, so the message names the missing pointer rather than the missing plan sections a reader would then go hunting for.
|
|
24
|
-
- The pointer resolves into a plans archive. Stop: `❌ <path> points at an archived plan, which describes work that already shipped. Reopen the task against a live plan, or pass that plan directly.` Test the resolved path rather than the task's outcomes or its `Pull request:` line, since a stale board gets its ticks wrong and the standard fixes where a shipped pointer lands.
|
|
25
|
-
- The pointer resolves to no file. Stop: `❌ <path> points at <target>, which does not exist. The citation is stale, so repoint the task or pass the plan path directly.`
|
|
45
|
+
An archive is `.canon/plans/archive/`, plus the two older spellings `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` leaves in place for a project that archived plans before the folder nested. From a task those read `../plans-archive/` and `../.tmp/plans-archive/`.
|
|
26
46
|
|
|
27
|
-
|
|
47
|
+
- Test all three, since a shipped pointer in a project nobody migrated lands on the older two
|
|
48
|
+
- Run the archive test ahead of the existence test, so a pointer into an archive that no longer holds the file still refuses as shipped work rather than as a stale citation
|
|
28
49
|
|
|
29
|
-
Each tier fails for a different reason and says so. A supplied path resolving to nothing is a typo, a derived
|
|
50
|
+
Each tier fails for a different reason and says so. A supplied path resolving to nothing is a typo, a derived one is a plan nobody wrote, and a task pointer resolving to nothing is a stale citation the board should have caught.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: UI checklist counts
|
|
3
|
-
description: What auto-ship Step 5 holds when ui-checklist produces a checklist, so the closing block can name the unchecked visual boxes after
|
|
3
|
+
description: What auto-ship Step 5 holds when ui-checklist produces a checklist, so the closing block can name the unchecked visual boxes after pr-evidence has removed the file
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Hold the checklist counts
|
|
@@ -9,13 +9,18 @@ Step 5 of `auto-ship`. The session reads this file when `ui-checklist` has produ
|
|
|
9
9
|
|
|
10
10
|
The chain continues to Step 6 here in every run, dispatched or hand-run, since the skill cannot tell the two apart and the draft mark at Step 6 holds the merge either way.
|
|
11
11
|
|
|
12
|
+
## What to count
|
|
13
|
+
|
|
12
14
|
Count two things in `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root:
|
|
13
15
|
|
|
14
16
|
- `<N>`, the `- [ ]` lines
|
|
15
17
|
- `<M>`, how many of those end in `(taste)`
|
|
16
18
|
|
|
17
|
-
Hold both until the Output block. `
|
|
19
|
+
Hold both until the Output block. `pr-evidence` removes the file once it posts the evidence comment, so a count taken after Step 6 reads nothing.
|
|
20
|
+
|
|
21
|
+
## Reading the counts into the closing block
|
|
18
22
|
|
|
19
|
-
The Output block's second line takes both counts. When every box is a taste box, `<N>` and `<M>` match and the boxes are owed to the operator alone,
|
|
23
|
+
The Output block's second line takes both counts. When every box is a taste box, `<N>` and `<M>` match and the boxes are owed to the operator alone, so say the operator and drop the UI reviewer clause.
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
- A driver reports a taste box as needing a person's eyes rather than passing it, which is why the operator owns an all-taste set
|
|
26
|
+
- When `ui-checklist` reports nothing to verify visually, it writes no file, Step 5 holds no count, and the Output block carries no boxes line
|
|
@@ -13,9 +13,15 @@ This step runs ahead of Step 1, so what it holds is the raw invocation argument
|
|
|
13
13
|
canon tasks plan-branch <argument> --json
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
| Record | Route |
|
|
17
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `conforms: true` | Pass the record's `branch`, already `<type>/<slug>`, and invoke nothing else to derive a name |
|
|
19
|
+
| `conforms: false` | The plan's filename breaks a cap in `${CLAUDE_SKILL_DIR}/../git-branch/references/branch.md`. Pass `branch` anyway and say the cap it broke |
|
|
20
|
+
| Anything else | Invoke `canon:session-worktree` bare and let its ladder derive the name, saying the verb did not answer |
|
|
21
|
+
|
|
22
|
+
- On `conforms: false`, the alternative is a name this session shortened by hand, a second derivation and the thing this call exists to prevent. `git-branch` decides the rename at ship.
|
|
23
|
+
- Anything else covers a refusal, a record carrying no `branch` key, and an installed binary carrying no `plan-branch` subcommand
|
|
24
|
+
- Saying the verb did not answer lets a reader tell a derived name from a fallback one
|
|
19
25
|
|
|
20
26
|
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.
|
|
21
27
|
|