@erclx/canon 4.118.0 → 4.120.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 +2 -2
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/canon-rollout/SKILL.md +2 -2
- package/claude/skills/create-skill/SKILL.md +2 -1
- package/claude/skills/design-extract/SKILL.md +1 -1
- package/claude/skills/docs-fold/SKILL.md +2 -2
- package/claude/skills/draft-ready/REQUIREMENT.md +1 -1
- package/claude/skills/draft-ready/SKILL.md +1 -1
- package/claude/skills/draft-screencast/SKILL.md +1 -1
- package/claude/skills/git-pr/REQUIREMENT.md +1 -0
- package/claude/skills/git-pr/SKILL.md +39 -7
- package/claude/skills/memory-capture/SKILL.md +3 -3
- package/claude/skills/memory-review/SKILL.md +3 -3
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/review-branch/SKILL.md +1 -1
- package/claude/skills/review-pr/SKILL.md +13 -242
- package/claude/skills/review-pr/references/close-out.md +30 -0
- package/claude/skills/review-pr/references/post.md +145 -0
- package/claude/skills/review-pr/references/scope.md +82 -0
- package/claude/skills/role-orchestrator/REQUIREMENT.md +9 -16
- package/claude/skills/role-orchestrator/SKILL.md +9 -153
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +4 -193
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +22 -0
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +85 -0
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +61 -0
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +56 -0
- package/claude/skills/role-orchestrator/references/orchestrator-review-fallback.md +18 -0
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +1 -1
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +1 -1
- package/claude/skills/role-worker/REQUIREMENT.md +1 -1
- package/claude/skills/role-worker/SKILL.md +10 -41
- package/claude/skills/seed-sync/SKILL.md +1 -1
- package/claude/skills/session-compact/SKILL.md +1 -1
- package/claude/skills/session-map/SKILL.md +1 -1
- package/claude/skills/session-relay/REQUIREMENT.md +7 -1
- package/claude/skills/session-relay/SKILL.md +4 -7
- package/claude/skills/session-worktree/REQUIREMENT.md +5 -1
- package/claude/skills/session-worktree/SKILL.md +7 -1
- package/claude/skills/session-worktree/references/main-root-writes.md +24 -0
- package/claude/skills/task-board/SKILL.md +4 -3
- package/claude/skills/teach-workspace/SKILL.md +4 -4
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +1 -1
- package/claude/skills/ux-measure/SKILL.md +1 -1
- package/claude/skills/ux-walkthrough/references/relay.md +1 -1
- package/docs/agents/commands.md +4 -3
- package/docs/agents/counts.md +1 -1
- package/docs/agents/index.md +8 -3
- package/docs/agents/install-and-sync.md +11 -6
- package/docs/agents/pr-evidence.md +19 -3
- package/docs/agents/pr-local.md +102 -0
- package/docs/agents/pr-preview.md +2 -2
- package/docs/agents/records-push.md +61 -0
- package/docs/agents/records-validate.md +73 -0
- package/docs/agents/records.md +3 -119
- package/docs/agents/sessions-transfer.md +91 -0
- package/docs/agents/sessions.md +3 -82
- package/docs/agents/skills-audit.md +2 -2
- package/docs/agents/tasks.md +4 -4
- package/docs/agents/teach-authoring.md +112 -0
- package/docs/agents/teach.md +3 -103
- package/docs/target-projects.md +2 -2
- package/docs/workflow/ai-workflow.md +10 -10
- package/docs/workflow/visual-design-workflow.md +2 -2
- package/governance/renames.toml +13 -0
- package/governance/rules/claude/570-skill.md +2 -1
- package/governance/rules/core/085-worktrees.md +2 -8
- package/package.json +1 -1
- package/scripts/core/check-ignore-parity.sh +1 -1
- package/scripts/lib/sandbox-git.sh +1 -1
- package/src/claude/cases/workflow.ts +10 -0
- package/src/commands/pr.ts +324 -2
- package/src/commands/sync.ts +11 -3
- package/src/commands/tasks.ts +9 -8
- package/src/context/classify/extract.ts +2 -2
- package/src/counts/scan.ts +1 -1
- package/src/design/base.css +19 -19
- package/src/design/board.ts +18 -7
- package/src/design/neutral.ts +127 -0
- package/src/design/regen.ts +6 -4
- package/src/design/tokens.ts +6 -3
- package/src/gate/stages.ts +6 -6
- package/src/gov/adapter.ts +51 -1
- package/src/gov/install.ts +13 -3
- package/src/gov/renames.ts +76 -0
- package/src/gov/stacks.ts +5 -1
- package/src/pr/evidence.ts +42 -2
- package/src/pr/local.ts +125 -0
- package/src/sync/check.ts +19 -4
- package/src/sync/engine.ts +67 -3
- package/src/tasks/archive.ts +28 -7
- package/src/tasks/record.ts +16 -9
- package/src/tasks/validate.ts +3 -1
- package/standards/index.md +1 -0
- package/standards/skill-requirement.md +72 -0
- package/standards/skill.md +34 -152
- package/standards/tasks.md +5 -3
- package/tooling/astro/reference.md +1 -1
- package/tooling/base/configs/.github/workflows/pr-local-preview.yml +32 -0
- package/governance/rules/core/091-channel.md +0 -13
package/README.md
CHANGED
|
@@ -162,8 +162,8 @@ Each domain carries an entry written for someone maintaining the toolkit rather
|
|
|
162
162
|
- [Governance rules](canon/context/governance/index.md)
|
|
163
163
|
- [Standards](canon/context/standards/index.md)
|
|
164
164
|
- [Snippets](canon/context/snippets.md)
|
|
165
|
-
- [Tooling stacks](canon/context/tooling.md)
|
|
166
|
-
- [Design system](canon/context/design.md)
|
|
165
|
+
- [Tooling stacks](canon/context/tooling/index.md)
|
|
166
|
+
- [Design system](canon/context/design/index.md)
|
|
167
167
|
- [Slides](canon/context/slides.md)
|
|
168
168
|
- [Transcripts](canon/context/transcripts.md)
|
|
169
169
|
- [Sandbox](canon/context/sandbox/index.md)
|
|
@@ -104,11 +104,11 @@ One session, one target, from the worktree entry to the merge of the branch it o
|
|
|
104
104
|
3. Check what this target holds. Invoke `canon:target-check`, which reports per domain what the target carries against what the toolkit ships and repairs nothing. It runs before any repair so the wave reads one stated set of domains per target rather than whatever each session decided to examine.
|
|
105
105
|
4. Diagnose and repair. Invoke `canon:canon-operator`, which reads `canon sync --check . --json` and routes each finding to the command or the skill that owns it. Do not restate that routing here and do not edit a managed file by hand.
|
|
106
106
|
5. Commit and open the pull request through `canon:git-commit` and `canon:git-pr`, handing each the fixed shape above rather than taking the title the generator derives from the diff.
|
|
107
|
-
6. Announce as the pull request opens, carrying its URL, its number, and the branch, to whoever dispatched this session
|
|
107
|
+
6. Announce as the pull request opens, carrying its URL, its number, and the branch, to whoever dispatched this session, sending it through `canon:session-relay`. That transition is the one moment only this session can observe.
|
|
108
108
|
7. Answer the review. Invoke `canon:review-address`, which pulls the findings and the CI state on this branch's open pull request, fixes each in the working tree, replies, and pushes. Answer every finding whatever its severity.
|
|
109
109
|
8. Stop there. Do not mark the pull request ready, do not merge, and do not declare the review closed. A narrow re-review posts `## Review closed`.
|
|
110
110
|
|
|
111
|
-
Send a block out
|
|
111
|
+
Send a block out through `canon:session-relay` before it becomes an interactive prompt, which states why the order matters.
|
|
112
112
|
|
|
113
113
|
Refuse an instruction this target's tree contradicts and carry the evidence with the refusal, naming the commands read and what complying would cost. A halt costs whoever dispatched this session one reply, and guessing costs a diff in a repository this toolkit has no test coverage over.
|
|
114
114
|
|
|
@@ -8,6 +8,7 @@ description: Creates a new `SKILL.md` in `.claude/skills/`. Use when asked to "c
|
|
|
8
8
|
Read these files in parallel:
|
|
9
9
|
|
|
10
10
|
- `${CLAUDE_SKILL_DIR}/../../standards/skill.md`: skill structure, skill types, frontmatter fields, invocation rules
|
|
11
|
+
- `${CLAUDE_SKILL_DIR}/../../standards/skill-requirement.md`: what `REQUIREMENT.md` must answer, its sections, and its template
|
|
11
12
|
- `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for skill body text
|
|
12
13
|
- The `write-human` skill: voice, rhythm, and sentence construction for skill body text
|
|
13
14
|
|
|
@@ -22,7 +23,7 @@ Read these files in parallel:
|
|
|
22
23
|
- Does the body carry a procedure a session would get wrong from first principles? A one-line wrapper around a single command needs no skill.
|
|
23
24
|
- Will anything invoke it other than the author typing its name? Carry this one into the drafted `REQUIREMENT.md`'s `Must not` section as a review criterion instead, since nothing can answer it before the skill has run.
|
|
24
25
|
2. Draft the full `SKILL.md` from the user's description, stating the current rule alone. An incident and the date it happened belong in the requirement's `Gap`, not in the body or a reference.
|
|
25
|
-
3. Draft the sibling `REQUIREMENT.md` from what the skill is for, in the shape the standard states. Write the gaps from the user's description rather than from the drafted body, since a requirement derived from the body records whatever the draft overfitted to.
|
|
26
|
+
3. Draft the sibling `REQUIREMENT.md` from what the skill is for, in the shape the requirement standard states. Write the gaps from the user's description rather than from the drafted body, since a requirement derived from the body records whatever the draft overfitted to.
|
|
26
27
|
4. Confirm the skill name and both files with the user before writing
|
|
27
28
|
5. Write to `.claude/skills/<name>/SKILL.md` and `.claude/skills/<name>/REQUIREMENT.md`
|
|
28
29
|
6. Run `canon claude skills audit --json` and read `findings.datedProvenance` for rows under `.claude/skills/<name>/`. Move each row's incident into `REQUIREMENT.md` under `Gap`, cut the date from the file the row names, and re-run until no row names the folder.
|
|
@@ -77,7 +77,7 @@ Anchor every proposal to a signal, never to a default. "Calm and dense" pins mut
|
|
|
77
77
|
- **Traced cells**: when Step 2 matched a `design-handoff.md` file, fill only the fields it actually states, no tag, the same traced-versus-proposed distinction the source path draws for a stylesheet value.
|
|
78
78
|
- The handoff carries hex and family and size, never Weight, Line height, or a color's Intent. Those cells, every field of a role the handoff never names, and Motion and Iconography regardless, still follow the proposal rules below, tag included.
|
|
79
79
|
- **Personality**: transcribe the `## Personality` paragraph from `canon/REQUIREMENTS.md` verbatim. This is the one section that is not a proposal. No tag.
|
|
80
|
-
- **Color**: one row per role. Rewrite the Intent cell in personality language, for example `
|
|
80
|
+
- **Color**: one row per role. Rewrite the Intent cell in personality language, for example `near-white page canvas` instead of the seed default `page canvas`. Propose hex values matching the personality. Dense and calm gives low saturation and high text contrast. Playful gives saturated accents. Every Intent and Value cell gets `? verify`.
|
|
81
81
|
- **Typography**: one row per role. Propose families fitting the platform, system UI for web, monospaced for CLI tools, serif for editorial, and a harmonious scale. Every cell gets `? verify`.
|
|
82
82
|
- **Spacing**: propose a base unit matching density intent. Dense gives a 4px base, roomy gives 8px. Keep the Multiplier column as the seed ships it, no tag. Only the Value column gets `? verify`.
|
|
83
83
|
- **Borders**: propose radius and width per role. Sharp and technical gives a small radius, soft gives a larger one. Every Radius and Width cell gets `? verify`.
|
|
@@ -100,7 +100,7 @@ For each doc with relevant changes, apply updates following these rules. Read a
|
|
|
100
100
|
- Do not touch task files this session did not change.
|
|
101
101
|
- Never hand-edit `.canon/tasks/index.md`. A hook regenerates it.
|
|
102
102
|
|
|
103
|
-
The verb resolves the board at the main worktree root in-process, which is the route
|
|
103
|
+
The verb resolves the board at the main worktree root in-process, which is the route `session-worktree` states for an edit inside an existing main-root file.
|
|
104
104
|
|
|
105
105
|
Read `ok` and `reason` out of that record rather than the exit. An operator's shell profile may wrap `canon` in a function that runs the binary and then a second command and takes the second status, which flattens every non-zero exit to zero. A refusal arriving as success leaves the outcome unmarked while the chain moves on, so the board reports shipped work as open and the next session re-plans it.
|
|
106
106
|
|
|
@@ -216,7 +216,7 @@ Report a block left unfolded rather than dropping it:
|
|
|
216
216
|
|
|
217
217
|
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.
|
|
218
218
|
|
|
219
|
-
Every delete below is a
|
|
219
|
+
Every delete below is a plain `rm`, one per call, routed the way `session-worktree` states.
|
|
220
220
|
|
|
221
221
|
Plans are not swept here. A plan is settled by the merge rather than by an outcome this run marked, and `canon tasks archive` moves it with the task the `post-merge` hook archives. Sweeping it from this step read a closure Step 3 had written moments earlier and moved a plan the branch was still building from.
|
|
222
222
|
|
|
@@ -28,7 +28,7 @@ Without this skill, a session holding finished files that hands them to a worker
|
|
|
28
28
|
- Copy each finished file whole to its destination path inside the folder, and carry nothing else into it.
|
|
29
29
|
- Write the plan and the task through `canon tasks plan-link`, `canon records validate plans`, and `canon markdown audit` rather than by restating what those verbs check.
|
|
30
30
|
- Place the task's row by the three branches `task-board` Step 4 states, so a solo project never ends with a task file on no surface.
|
|
31
|
-
- Route a write at the main root from a linked worktree through `Bash`,
|
|
31
|
+
- Route a write at the main root from a linked worktree through `Bash`, the way `session-worktree` routes it.
|
|
32
32
|
- Name the archive move in the closing report, since the skill writes a folder that stays live until someone moves it.
|
|
33
33
|
|
|
34
34
|
## Must not
|
|
@@ -53,7 +53,7 @@ install -D -m 0644 <source> <main-root>/.canon/ready/<nn>-<slug>/<destination pa
|
|
|
53
53
|
|
|
54
54
|
- Copy whole and edit nothing. A change wanted now is made in the source file first and copied after.
|
|
55
55
|
- Carry no notes, alternates, or drafts into the folder. Anything else belongs in the plan or the pull request body.
|
|
56
|
-
- Write each of these at the main root
|
|
56
|
+
- Write each of these at the main root, routed the way `session-worktree` states. Create a whole new file with a heredoc.
|
|
57
57
|
|
|
58
58
|
## Step 5: write the thin plan
|
|
59
59
|
|
|
@@ -43,7 +43,7 @@ Build a 2-to-4-word kebab-case slug from the topic and discovery answers. Exampl
|
|
|
43
43
|
|
|
44
44
|
Create `.canon/tmp/screencast/<slug>.md` at the main worktree root. Create the directory if it does not exist. The file is gitignored.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
The draft is a main-root write, so it goes out as a heredoc, routed the way `session-worktree` states.
|
|
47
47
|
|
|
48
48
|
Write all eight sections. Pre-seed every section with concrete content so the draft is shippable as-is. The user edits down rather than fills blanks.
|
|
49
49
|
|
|
@@ -30,6 +30,7 @@ A lookup that resolves by head branch alone carries its own failure. A branch na
|
|
|
30
30
|
- Report a refused label, since a warning nothing surfaces leaves the run indistinguishable from one that labelled
|
|
31
31
|
- Put a preview address on a pull request that changes a rendered surface when the project's deploy can mint one, since screenshots and a checklist leave a reviewer nothing to click into before merging
|
|
32
32
|
- Bound the wait on that preview and finish the chain without the link on a timeout, since a slow deploy must not hold the ship
|
|
33
|
+
- Put the branch's running local server on the same pull request when this worktree is serving one, and remove it when the pull request closes, since a reviewer on the operator's machine can interact with the branch and a link that outlives it points at whatever runs there next
|
|
33
34
|
|
|
34
35
|
## Must not
|
|
35
36
|
|
|
@@ -178,15 +178,35 @@ When it exists, scan it against `${CLAUDE_SKILL_DIR}/../../standards/publish.md`
|
|
|
178
178
|
|
|
179
179
|
Where it lands is decided by the evidence step below rather than here, since a checklist reads next to the screenshots it annotates and posting it on its own is the fallback for a branch that changed no screenshot.
|
|
180
180
|
|
|
181
|
+
### Find the local server
|
|
182
|
+
|
|
183
|
+
A reviewer on the operator's machine can open the branch's running dev server, which screenshots and a checklist cannot stand in for. Ask the verb for the server this worktree is running before the evidence step, so the first evidence comment already carries the link:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
canon pr local --json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The verb reads the listening sockets on this machine, keeps those whose process runs inside this worktree, and reports the lowest port serving an HTML page. A server in another worktree or in the main checkout is never reported, since it shows a different branch. `canon docs pr-local` states the contract. Read `reason` on the record rather than the exit code.
|
|
190
|
+
|
|
191
|
+
- `ok`: hold the record's `url` for the evidence step below.
|
|
192
|
+
- `no-server` or `no-listener-reader`: hold the reason for the closing report, pass no link, and move on. Do not start a server here, since one started inside the ship chain has no owner to stop it.
|
|
193
|
+
- Anything else, including no record at all: move on silently. An installed binary older than the verb answers with an unknown-subcommand error, which is a skip rather than a stop.
|
|
194
|
+
|
|
195
|
+
Pass `--local` to the evidence step only on an `ok` here. The binary answering `ok` is the one carrying the flag, so a binary lacking the verb never meets a flag it would reject.
|
|
196
|
+
|
|
197
|
+
With both `--checklist` and `--local`, a diff carrying no evidence image still renders `ok`, with the link opening a comment the checklist closes, so a reviewer gets both in one place. A local link with neither an evidence image nor a checklist still reports `no-evidence`, which keeps a branch that changed no rendered surface from getting a comment holding a link and nothing else.
|
|
198
|
+
|
|
199
|
+
A seeded workflow replaces the line with a note once the pull request closes, so the link does not outlive the branch it points at.
|
|
200
|
+
|
|
181
201
|
### Post the evidence comparison
|
|
182
202
|
|
|
183
|
-
Run the verb once against the number the pull request step above resolved
|
|
203
|
+
Run the verb once against the number the pull request step above resolved. Pass `--checklist` when the checklist step found a file, and `--local` when the step above returned `ok`. Leave each flag off otherwise:
|
|
184
204
|
|
|
185
205
|
```bash
|
|
186
|
-
canon pr evidence <number> --checklist <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --json
|
|
206
|
+
canon pr evidence <number> --checklist <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --local <url> --json
|
|
187
207
|
```
|
|
188
208
|
|
|
189
|
-
One call answers both questions because a checklist does not decide `no-evidence`. The verb reports `no-evidence` on a diff carrying no evidence image whether or not a checklist came with it, so the branch below reads the same `reason` it would have read without the flag, and the checklist is folded in only on the path that has a comparison to fold it into.
|
|
209
|
+
One call answers both questions because a checklist does not decide `no-evidence`. The verb reports `no-evidence` on a diff carrying no evidence image whether or not a checklist came with it, so the branch below reads the same `reason` it would have read without the flag, and the checklist is folded in only on the path that has a comparison to fold it into. The local link is the one exception, stated in the step above.
|
|
190
210
|
|
|
191
211
|
Pass `--checklist` only for a file that exists. The verb refuses as `unreadable-checklist` on a path it cannot read or one holding nothing, which is a caller bug rather than a transient failure, so stop and repair the path rather than posting a body with the checklist silently dropped.
|
|
192
212
|
|
|
@@ -211,7 +231,7 @@ Any other `reason` is one of the mirrored git refusals (`gh-missing`, `gh-failed
|
|
|
211
231
|
|
|
212
232
|
### Post the UI checklist alone
|
|
213
233
|
|
|
214
|
-
Run this step only when the evidence step above did not carry the checklist, meaning it reported `no-evidence` or one of the git refusals, and a checklist file exists. Post it as its own comment on `<number>`:
|
|
234
|
+
Run this step only when the evidence step above did not carry the checklist, meaning it reported `no-evidence` or one of the git refusals, and a checklist file exists. A local link sends the checklist through the evidence step instead, so this step runs on a branch with no evidence image only when the local step found no server. Post it as its own comment on `<number>`:
|
|
215
235
|
|
|
216
236
|
```bash
|
|
217
237
|
gh pr comment <number> --body-file <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md
|
|
@@ -219,7 +239,7 @@ gh pr comment <number> --body-file <main-root>/.canon/tmp/handoff/ui-checklist/<
|
|
|
219
239
|
|
|
220
240
|
Run the cleanup below only once the call that carried the checklist reports success, whichever of the two steps that was. On a failure, stop and leave the file in place: a retry needs the checklist to still be there, and deleting it on a failed post loses the only copy with nothing landed on the pull request.
|
|
221
241
|
|
|
222
|
-
|
|
242
|
+
The cleanup is a main-root delete, so it goes out as a plain `rm` and then a plain `rmdir`, the file and then the folder, routed the way `session-worktree` states:
|
|
223
243
|
|
|
224
244
|
```bash
|
|
225
245
|
rm <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md
|
|
@@ -251,6 +271,8 @@ The verb dispatches the project's Pages deploy on the pull request's branch and
|
|
|
251
271
|
canon pr evidence <number> --preview <url> --json
|
|
252
272
|
```
|
|
253
273
|
|
|
274
|
+
The hosted address takes the first line and a local link already on the comment moves to the second, carried forward with no flag.
|
|
275
|
+
|
|
254
276
|
- `no-deploy`: the project deploys nothing a dispatch can start. Say nothing and move on.
|
|
255
277
|
- Any other `reason`, being `unfenced`, `no-alias`, `run-failed`, `timeout`, or a mirrored `gh` refusal: report it with the record's `message` and move on without stopping the chain. A missing link costs the reviewer a click, and a held ship costs the whole chain.
|
|
256
278
|
|
|
@@ -266,9 +288,11 @@ canon tasks pull-request <number> --plan feature-<slug> --json
|
|
|
266
288
|
|
|
267
289
|
The slug is a guess at which plan this branch carries rather than a fact about the task, which is why the verb re-checks it against the board and refuses instead of writing on a near miss. A branch whose slug names no plan file falls to the silent skip below, the same as one whose plan no task cites.
|
|
268
290
|
|
|
269
|
-
The verb resolves the board at the main worktree root in-process, adds `Pull request: #NNN` under the `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` lines the task already carries, and corrects the number in place when the line exists. This is the route because the write is an edit inside an existing file, which
|
|
291
|
+
The verb resolves the board at the main worktree root in-process, adds `Pull request: #NNN` under the `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` lines the task already carries, and corrects the number in place when the line exists. This is the route because the write is an edit inside an existing main-root file, which `session-worktree` routes through a verb. That root is the one `session-worktree` resolves on entry.
|
|
292
|
+
|
|
293
|
+
The correction reaches only a line that does not read as a list of `#NNN` entries. A line that does takes the new number appended rather than replaced, reported as `appended`, so a task shipped in slices keeps every pull request.
|
|
270
294
|
|
|
271
|
-
Skip this silently when the record is `ok: false` and `reason` is `no-board`, `no-match`, or `ambiguous`. Those are the three cases a guessed write would compound: no board, no task naming the plan, or more than one. One
|
|
295
|
+
Skip this silently when the record is `ok: false` and `reason` is `no-board`, `no-match`, or `ambiguous`. Those are the three cases a guessed write would compound: no board, no task naming the plan, or more than one. One pull request names one task, and a wrong match archives the wrong task unattended once the branch merges. Report any other refusal rather than swallowing it.
|
|
272
296
|
|
|
273
297
|
The number is what lets the merge close the task. Every merge on `main` is a squash carrying it in the subject, so the number survives where a branch name does not, and `post-merge` reads it back to call `canon tasks archive`. Writing it here rather than at worktree time is what makes it a pull request number rather than a branch the squash discards.
|
|
274
298
|
|
|
@@ -296,4 +320,12 @@ Add a line when the preview step returned an address:
|
|
|
296
320
|
|
|
297
321
|
`🔗 Preview: <url>`
|
|
298
322
|
|
|
323
|
+
Add a line when the evidence step posted the local link:
|
|
324
|
+
|
|
325
|
+
`🖥️ Local preview: <url>`
|
|
326
|
+
|
|
327
|
+
Add a line instead when the local step refused as `no-server` or `no-listener-reader` and the evidence or checklist step posted something, since that pull request changes a rendered surface and a reviewer could have used the link. To add it later, start the server, run `canon pr local --json`, then run `canon pr evidence <number> --local <url> --json`, adding `--checklist` when one is still owed, and post the body the way the evidence step does. `git-followup` only carries a line forward, so it cannot add one the comment never had:
|
|
328
|
+
|
|
329
|
+
`🖥️ No local preview: <reason>`
|
|
330
|
+
|
|
299
331
|
Do not add any other text.
|
|
@@ -14,7 +14,7 @@ The filename and its type prefix, the frontmatter, the body shape each type carr
|
|
|
14
14
|
## Guards
|
|
15
15
|
|
|
16
16
|
- All `.canon/memory/` reads and writes resolve at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does.
|
|
17
|
-
-
|
|
17
|
+
- Every path below sits at the main root, so each write in this skill goes out as a heredoc, routed the way `session-worktree` states. A memory entry holds one fact and this session has read it, so an update rewrites the whole file with a heredoc rather than editing a line inside it.
|
|
18
18
|
- If `.canon/memory/` does not exist at the main worktree root, create it, along with an `index.md` carrying `title` and `subtitle` frontmatter. `canon claude init` seeds both, and a project predating that seed has neither. Regeneration errors without the index, so the first write into a bare folder would report a frontmatter failure against a file that is fine.
|
|
19
19
|
- If the session produced no user corrections, confirmations, or context disclosures worth persisting, stop: `✅ Nothing worth capturing.`
|
|
20
20
|
- Routing edits a tracked file, so it runs only where the caller commits. When the session is in the main worktree, or the caller states it does not commit, skip Step 3 and write every candidate as a memory file. `role-orchestrator` is the caller this covers.
|
|
@@ -44,7 +44,7 @@ For each project candidate, match its subject against `canon/context/index.md`.
|
|
|
44
44
|
|
|
45
45
|
Fail closed. A project candidate matching no entry stays a memory file, and so does one matching two entries where neither is clearly the owner. The residue is what the folder is for, and a fact filed under the wrong entry is worse than one in memory because a context entry is a surface sessions trust.
|
|
46
46
|
|
|
47
|
-
Do not edit a context entry here. `docs-fold` owns those edits and folds the routed facts in on its own pass, or two skills write one file at the same step. Write each routed fact to `.canon/tmp/handoff/memory-routing/<slug>.md` at the main worktree root instead, appending when the file exists. Name the heading with the entry's own path from `canon/context/index.md`, flat or the nested `index.md`, since that heading is what tells `docs-fold`'s routed-facts fold which file to open. An append is a whole-file operation
|
|
47
|
+
Do not edit a context entry here. `docs-fold` owns those edits and folds the routed facts in on its own pass, or two skills write one file at the same step. Write each routed fact to `.canon/tmp/handoff/memory-routing/<slug>.md` at the main worktree root instead, appending when the file exists. Name the heading with the entry's own path from `canon/context/index.md`, flat or the nested `index.md`, since that heading is what tells `docs-fold`'s routed-facts fold which file to open. An append is a whole-file operation, so send it as a heredoc:
|
|
48
48
|
|
|
49
49
|
A flat domain takes:
|
|
50
50
|
|
|
@@ -78,7 +78,7 @@ Two of its rules are the ones a capture pass gets wrong under time pressure. Sta
|
|
|
78
78
|
|
|
79
79
|
Do not edit the index. `.canon/memory/index.md` is generated from sibling frontmatter by a `PostToolUse` hook, the same way the task board's index is, so a hand-appended row is drift the next regeneration discards.
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
A shell write skips that hook, as `session-worktree` states. Regenerate the index once after the last write when the entries went out through `Bash`:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
84
|
canon indexes regen --no-stage --root <main-root> <main-root>/.canon/memory/index.md
|
|
@@ -26,7 +26,7 @@ If the user re-pings the skill with no new phrase and a receipt exists, default
|
|
|
26
26
|
- If `.canon/memory/` contains no top-level `*.md` entries other than `index.md`, stop: `✅ No memory entries to review.` The pen holds two subfolders now, `review/` and `archive/`, and neither is a memory entry, so this count and every entry read below stay at the top level and never recurse into either.
|
|
27
27
|
- Cleanup is exempt from the two stops above. It works on receipts in `.canon/review/`, and a drained pen is the normal state once Apply has run, so a pen-shaped stop would strand the receipt it exists to delete.
|
|
28
28
|
- Resolve the main root via `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, falling back to `pwd`. All review and memory reads anchor here.
|
|
29
|
-
-
|
|
29
|
+
- Every main-root write below goes out as a heredoc, routed the way `session-worktree` states. The receipt and a memory entry are both short and this session has read them whole, so a rewrite replaces the file with a heredoc rather than editing a line inside it. Promotion targets are tracked files at `pwd` and keep taking `Edit`.
|
|
30
30
|
|
|
31
31
|
## Propose phase
|
|
32
32
|
|
|
@@ -156,7 +156,7 @@ Action by action type:
|
|
|
156
156
|
- **Hand off**: do not edit governance. Archive the memory file only if the user confirmed the handoff explicitly. Otherwise leave it in place.
|
|
157
157
|
- **Retire**: archive the memory file.
|
|
158
158
|
|
|
159
|
-
Archiving means creating `.canon/memory/archive/` at the main worktree root and moving the file there under its original name, overwriting any file already at that name. Send the `mkdir -p` and
|
|
159
|
+
Archiving means creating `.canon/memory/archive/` at the main worktree root and moving the file there under its original name, overwriting any file already at that name. Send the `mkdir -p` and a plain `mv`, routed the way `session-worktree` states for a main-root move. Never delete a memory entry. Nothing recovers one from a gitignored folder.
|
|
160
160
|
|
|
161
161
|
Do not hand-edit `.canon/memory/index.md`. Once every archive move is done, regenerate it instead:
|
|
162
162
|
|
|
@@ -164,7 +164,7 @@ Do not hand-edit `.canon/memory/index.md`. Once every archive move is done, rege
|
|
|
164
164
|
canon indexes regen --no-stage --root <main-root> <main-root>/.canon/memory/index.md
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
An archive move is a shell `mv`, which skips the index hook the way `session-worktree` states. Without this call the index keeps a row per archived entry and drifts exactly the way the hand-appended one did. Run it once after the last move rather than per item.
|
|
168
168
|
|
|
169
169
|
Apply promotion edits one at a time via `Edit`. Claude Code's tool permission dialog is the confirmation gate per edit. Never rewrite a whole promotion target.
|
|
170
170
|
|
|
@@ -101,7 +101,7 @@ Omit empty sections. Do not print `None identified.` in chat.
|
|
|
101
101
|
|
|
102
102
|
Derive a 2-to-4-word kebab-case slug from the feature description. Write the full plan to `.canon/plans/feature-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does. Create the directory if it does not exist.
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
The plan is a main-root write, from a linked worktree and from a background session sitting at the main root with none entered alike, so it goes out as a heredoc, routed the way `session-worktree` states.
|
|
105
105
|
|
|
106
106
|
The file follows the template in `${CLAUDE_SKILL_DIR}/../../standards/plan.md`. Copy the shape from there rather than from this body, so one edit to the standard moves every plan.
|
|
107
107
|
|
|
@@ -116,7 +116,7 @@ Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to
|
|
|
116
116
|
|
|
117
117
|
Write the full report directly to `.canon/review/branch-<slug>.md` at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does. Create the directory if it does not exist. Always overwrite.
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
The report is a main-root write, so it goes out as a heredoc, routed the way `session-worktree` states.
|
|
120
120
|
|
|
121
121
|
If there are no findings, write `✅ No findings.` to the file with a timestamp.
|
|
122
122
|
|