@erclx/canon 5.41.0 → 5.43.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/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +24 -4
- 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/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/ci-workflow/REQUIREMENT.md +2 -1
- package/claude/skills/ci-workflow/SKILL.md +12 -2
- package/claude/skills/ci-workflow/references/workflows.md +12 -9
- 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 +10 -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/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 +55 -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-doc/references/wiki.md +1 -1
- 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/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +9 -5
- 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 +29 -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/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +58 -21
- 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/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 +15 -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/references/close-out.md +7 -5
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -15
- package/claude/skills/role-orchestrator/SKILL.md +2 -0
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -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 +16 -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-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +3 -3
- package/claude/skills/role-worker/REQUIREMENT.md +3 -0
- package/claude/skills/role-worker/SKILL.md +34 -2
- package/claude/skills/search-craft/REQUIREMENT.md +1 -1
- package/claude/skills/search-craft/SKILL.md +2 -2
- 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/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/agents/audits.md +1 -0
- package/docs/agents/migrate.md +11 -8
- package/docs/target/migrations.md +11 -0
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/governance/detect.toml +4 -0
- package/governance/rules/canon/context.md +2 -1
- package/governance/rules/canon/plan.md +3 -5
- package/governance/rules/canon/scratch.md +3 -1
- package/governance/rules/canon/task-scope.md +2 -1
- package/governance/rules/canon/tasks.md +2 -1
- package/governance/rules/canon/worktrees.md +5 -2
- package/governance/rules/claude/output.md +7 -4
- package/governance/rules/claude/skill.md +6 -4
- package/governance/rules/tooling/ci-workflow.md +6 -39
- package/governance/rules/ui/design-reference.md +37 -0
- package/governance/rules/writing/markdown.md +2 -1
- package/package.json +6 -6
- package/src/audits/catalog.ts +42 -0
- package/src/claude/cases/workflow.ts +5 -0
- package/src/claude/settings.ts +8 -4
- package/src/commands/claude.ts +11 -1
- package/src/commands/gov.ts +198 -0
- package/src/commands/migrate.ts +121 -2
- package/src/commands/pr.ts +146 -105
- package/src/commands/tooling.ts +3 -3
- package/src/commands/worktrees.ts +49 -0
- package/src/gate/stages.ts +15 -0
- package/src/gov/audit.ts +440 -0
- package/src/listeners/belongs.ts +21 -0
- package/src/listeners/machine.ts +93 -0
- package/src/listeners/parse.ts +41 -0
- package/src/markdown/scope.ts +144 -0
- package/src/migrate/session-defaults.ts +138 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/local.ts +4 -69
- package/src/pr/review-state.ts +182 -0
- package/src/sync/check.ts +15 -0
- package/src/tooling/stamp.ts +56 -12
- package/src/worktrees/stop.ts +92 -0
- package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
- package/tooling/base/configs/commitlint.config.js +0 -20
- package/tooling/base/reference.md +1 -1
- package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
- package/tooling/claude/reference.md +13 -7
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- package/tooling/claude/user/settings.template.json +0 -4
- package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
- package/tooling/public/configs/.github/dependabot.yml +12 -0
- package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
- package/tooling/public/manifest.toml +8 -0
- package/tooling/public/reference.md +53 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
- package/tooling/public/seeds/.release-please-manifest.json +3 -0
- package/tooling/public/seeds/CONTRIBUTING.md +50 -0
- package/tooling/public/seeds/LICENSE +21 -0
- package/tooling/public/seeds/SECURITY.md +13 -0
- package/tooling/public/seeds/release-please-config.json +12 -0
- package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
- package/tooling/web/configs/.github/workflows/verify.yml +15 -12
- package/claude/skills/git-pr/references/evidence.md +0 -124
|
@@ -50,13 +50,21 @@ A plan failing these is non-conforming even when it satisfies every shape rule b
|
|
|
50
50
|
## Filename and slug
|
|
51
51
|
|
|
52
52
|
- Name the file `feature-<slug>.md`, with `<slug>` two to four kebab-case words naming the concern.
|
|
53
|
-
- Write one concern per file
|
|
54
|
-
- A staged batch is a concern of its own and takes its own file rather than a `**Batch N**` sub-heading inside one plan's `**Files to touch:**`. One plan filename derives one branch, so batches sharing a file have nothing to open a pull request against once the first merges. State a batch's dependency on the ones before it in its own `**Constraints:**`. A batch that stacks on another and shares most of its files with it folds into that batch as contiguous commits on one branch rather than taking a file, unless its constraints carry ``Judged apart from `feature-<parent>`: <reason>`` with a reason after the colon. `canon records validate plans` reports `stack-foldable` for a stacked batch that has neither.
|
|
53
|
+
- Write one concern per file, since a plan bundling two cannot be executed by two sessions or abandoned by half
|
|
55
54
|
- Derive the slug from the concern rather than from a branch, because the plan is written before the branch exists.
|
|
56
|
-
- Give the branch
|
|
55
|
+
- Give the executing branch the same slug, since a later surface finds the plan from the branch name and finds nothing when the spellings differ
|
|
57
56
|
|
|
58
57
|
A plan carries no frontmatter. Its filename is the whole of its identity, so a folder of plans is read by name rather than by a generated catalog.
|
|
59
58
|
|
|
59
|
+
### Staged batches
|
|
60
|
+
|
|
61
|
+
A staged batch is a concern of its own and takes its own file rather than a `**Batch N**` sub-heading inside one plan's `**Files to touch:**`. One plan filename derives one branch, so batches sharing a file have nothing to open a pull request against once the first merges.
|
|
62
|
+
|
|
63
|
+
- State a batch's dependency on the ones before it in its own `**Constraints:**`
|
|
64
|
+
- A batch stacking on another and sharing most of its files folds into that batch as contiguous commits on one branch, rather than taking a file
|
|
65
|
+
- It takes a file anyway when its constraints carry ``Judged apart from `feature-<parent>`: <reason>`` with a reason after the colon
|
|
66
|
+
- `canon records validate plans` reports `stack-foldable` for a stacked batch that has neither
|
|
67
|
+
|
|
60
68
|
## Sections
|
|
61
69
|
|
|
62
70
|
The document opens with `# Feature: <short title>` and one paragraph stating what is being built and why now. The sections below follow in this order.
|
|
@@ -73,62 +81,86 @@ The document opens with `# Feature: <short title>` and one paragraph stating wha
|
|
|
73
81
|
| `**Sources:**` | the outside sources a decision rests on, each with its quoted passage | When a decision rests on an outside source |
|
|
74
82
|
|
|
75
83
|
- Write each marker as the table gives it. `Summary` opens the prose a reader scans, so it takes an H2, and the others are labels over lists rather than sections of prose.
|
|
76
|
-
- A section
|
|
84
|
+
- A section in the other spelling is still that section, since `## Risks` and `**Risks:**` name one thing, and either spelling breaks a depth run
|
|
85
|
+
- Write the table's form in a new plan and leave an existing plan's spelling alone
|
|
77
86
|
- Write `None identified.` under a required section with nothing to report rather than dropping the marker. A dropped section and an unconsidered one read identically.
|
|
78
87
|
- Aim `## Summary` at a person scanning the plan, not at the session executing it. The other sections carry what execution needs.
|
|
79
88
|
|
|
80
89
|
### Files to touch entries
|
|
81
90
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
91
|
+
Give every `**Files to touch:**` entry a backticked path and something said about it. A bare path states scope and not intent, and the reason is what an executing session checks its edit against.
|
|
92
|
+
|
|
93
|
+
- Lead with the path or with a label carrying the path, whichever reads better for the entry
|
|
94
|
+
- Separate the two halves with a colon, and keep every path the entry declares ahead of it, since what sits before the colon reads as a target
|
|
95
|
+
- Both sides of a rename belong before the colon, and a file merely cited by the reason does not
|
|
96
|
+
- Read the list as what the branch sets out to write rather than a bound, since the doc syncs at ship write past it on nearly every branch
|
|
97
|
+
- `canon tasks plan-reach <plan>` reads the branch back against this list and every other live plan
|
|
85
98
|
|
|
86
99
|
### Measured claims
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
State every count and every claim about the tree as measured during the pass that wrote the plan. A figure carried in from a summary or an earlier session is the most common way a plan ships the wrong scope.
|
|
102
|
+
|
|
103
|
+
Prefer a short plan over a padded one. A section filled to look thorough costs the reader the same attention as one that matters.
|
|
90
104
|
|
|
91
105
|
### Constraints
|
|
92
106
|
|
|
93
107
|
Work in flight reaches a plan as a hold or as a shared path. A hold leaves a surface alone and says which of two acts it forbids, rather than leaving the executing session to guess. Neither act is forbidden over a shared path.
|
|
94
108
|
|
|
95
|
-
|
|
109
|
+
Write a hold only for a dependency, a contract the other track consumes, a relocation, or a sweep, which a rebase cannot settle mechanically. A bare shared file is none of these, and forbidding it sends a worker to concede a file the change needs.
|
|
110
|
+
|
|
96
111
|
- Forbid conforming that surface to whatever shape the change introduces, which keeps the branch to one concern.
|
|
97
|
-
- Never forbid retargeting a pointer the change breaks
|
|
112
|
+
- Never forbid retargeting a pointer the change breaks, since a rename, split, or deletion leaving a citation behind ships a dangling reference
|
|
98
113
|
- Decide both acts for every surface a hold names, not for one file among its siblings.
|
|
99
114
|
- Write a shared path as the track, the path, and the branch that rebases, being the one merging second. The executing session edits the file and keeps both sides on the rebase.
|
|
100
115
|
|
|
116
|
+
### Stamping a constraint
|
|
117
|
+
|
|
101
118
|
A constraint measured against work in flight expires when that work merges, as a shared-path line does, so stamp the block with what it was measured against.
|
|
102
119
|
|
|
103
120
|
- Give the stamp its own leading bullet, written as Measured against `<commit>` on <YYYY-MM-DD>. One stamp covers the whole block.
|
|
104
|
-
- Stamp the commit rather than the track names or a date alone
|
|
105
|
-
- Re-test a stamped constraint before honoring it with `git fetch origin main --quiet && git log <commit>..origin/main --oneline -- <the paths the constraint names>`. Any commit it reports means the track landed and the constraint is dead. Fetch and scope the log to the paths in the same command, since a stale ref reads a dead constraint as live and a squashed subject names no track.
|
|
121
|
+
- Stamp the commit rather than the track names or a date alone, since a date does not separate two plans written either side of a merge
|
|
106
122
|
- Read an unstamped constraint as unverified rather than as live, and confirm it against the open pull request list for the named paths.
|
|
107
123
|
|
|
124
|
+
Re-test a stamped constraint before honoring it, fetching and scoping the log in one command, since a stale ref reads a dead constraint as live and a squashed subject names no track. Any commit it reports means the track landed and the constraint is dead.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
git fetch origin main --quiet && git log <commit>..origin/main --oneline -- <the paths the constraint names>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Fan-in and ready constraints
|
|
131
|
+
|
|
108
132
|
A batch in a fan-in set declares its side in a constraint bullet, ``Fan-in member of `feature-<integrator>` `` on a member and ``Fans in `feature-<a>`, `feature-<b>` `` on the integrator. `batches.md` holds when to fan in, and `canon records validate plans` reports `fan-in-unmatched` for a set whose two sides disagree.
|
|
109
133
|
|
|
110
134
|
A constraint naming a `.canon/ready/` folder is a third shape beside the hold and the shared path. It makes that folder's files the verbatim source for the paths this plan's `**Files to touch:**` lists, per `ready.md`, so the executing session copies those paths rather than authoring them.
|
|
111
135
|
|
|
112
136
|
### Verification
|
|
113
137
|
|
|
138
|
+
Every outcome reaches the review with its proof named.
|
|
139
|
+
|
|
114
140
|
- Name, for each outcome, the test or the command that proves it, as one bullet leading with the outcome and ending on the command in backticks.
|
|
115
141
|
- Write a command a later session can run as given, from the project root. A description of what would be checked leaves the executing session to invent the check.
|
|
116
142
|
- Name the visual check where no test reaches, and say it is visual, so a reader can tell a proof from a look.
|
|
117
143
|
|
|
118
144
|
### Risks
|
|
119
145
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
-
|
|
146
|
+
Name the collision rather than the category, since a risk a reader cannot act on is padding.
|
|
147
|
+
|
|
148
|
+
- For a resource with more than one consumer, list the consumers and mark each read or write, so a policy over it holds for every writer
|
|
149
|
+
- For a changed contract another track consumes, such as an exported signature, a verb's flags or record, or a config key, name it and list each consumer
|
|
150
|
+
- The dispatcher reads that contract bullet for the hold, so a change left out reaches it as a clean shared file
|
|
123
151
|
|
|
124
152
|
### Review focus
|
|
125
153
|
|
|
154
|
+
This section is where the planner's understanding of the risk reaches the review pass.
|
|
155
|
+
|
|
126
156
|
- Name each input or state that would break the change if the implementation got it wrong, one bullet each, with what the change must do there.
|
|
127
|
-
- Write it for the reviewer rather than the builder
|
|
157
|
+
- Write it for the reviewer rather than the builder
|
|
128
158
|
- Keep it apart from `**Risks:**`. A risk is something the work might collide with, and a focus item is something the finished diff must be shown to handle.
|
|
129
159
|
|
|
130
160
|
### Sources
|
|
131
161
|
|
|
162
|
+
A source earns an entry only once someone opened it.
|
|
163
|
+
|
|
132
164
|
- Give each entry a link, the decision it backs, and the passage relied on in double quotes.
|
|
133
165
|
- Mark a source that could not be fetched `unverified` and never quote it. A quote for a page nobody opened is the failure this section exists to prevent.
|
|
134
166
|
- Cite no source that was found and not opened, following the lead rule in `groundwork.md`.
|
|
@@ -158,15 +190,20 @@ An execution that deviates rewrites the suggestion into the form below, leaving
|
|
|
158
190
|
|
|
159
191
|
### Preference questions and answers
|
|
160
192
|
|
|
193
|
+
The suggestion line is the planner's, and the answer line belongs to whoever owns the call.
|
|
194
|
+
|
|
161
195
|
- Write `- Suggested: needs your call, <why>` where the answer turns on preference rather than on a technical default. Fabricating a default there hides an open question behind an accepted answer.
|
|
162
196
|
- Never fill an `- Answer:` slot on behalf of the person who owns it. Recording the pick as the suggestion is what the suggestion line is for.
|
|
163
197
|
|
|
164
198
|
### Overrides and settled questions
|
|
165
199
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
200
|
+
A deviation from an unanswered question rewrites the `- Suggested:` line to the pick execution made and leaves the slot blank, since the prohibition above reaches the answer line alone.
|
|
201
|
+
|
|
202
|
+
- Open the rewritten text with `overridden at execution to <pick>,` and follow it with the measurement that moved the pick
|
|
203
|
+
- The fixed phrase tells an override from an authored suggestion, which routinely carries a number too
|
|
204
|
+
- Take a deviation from an answered question back to whoever answered it rather than rewriting either line
|
|
205
|
+
- A filled slot is a decision already made, and a suggestion rewritten under one leaves two picks with no default resolving them
|
|
206
|
+
- Record a pick settled in conversation on the `- Suggested:` line, naming who settled it, and leave the slot blank. A deviation from it goes back to whoever settled it.
|
|
170
207
|
|
|
171
208
|
The plan is archived at ship, so the same deviation takes one line in the open task's `## Findings` naming what shipped. The plan holds why the pick moved and the task holds what the tree now has.
|
|
172
209
|
|
|
@@ -31,7 +31,8 @@ The file is optional, since measuring what is already there settles most questio
|
|
|
31
31
|
Each spike carries four things:
|
|
32
32
|
|
|
33
33
|
- The open question it answers, named by file and number. A spike attached to no question is a runaway.
|
|
34
|
-
- The method, stated fully enough for a later reader to re-run it
|
|
34
|
+
- The method, stated fully enough for a later reader to re-run it, with the exact command and the repetition count.
|
|
35
|
+
- The fixture and where it lived, since an arm pointed at a fixture inside the project measured the project
|
|
35
36
|
- The result, and which question it closes. Record a spike that settles nothing too, so a later pass does not pay for it twice.
|
|
36
37
|
- The measured cost, even for a single read, and the caveats bounding what the result proves. Cost is a report rather than a limit, and it makes the next spike estimable.
|
|
37
38
|
|
|
@@ -47,6 +48,8 @@ A file a reader opens to verify how a result was produced or what it showed live
|
|
|
47
48
|
|
|
48
49
|
Open no other subfolder: `spikes/`, `web/`, and `research/` fold into these three, with a fetched page in `clones/` and a reference-site screenshot in `evidence/`.
|
|
49
50
|
|
|
51
|
+
### Harnesses and read checks
|
|
52
|
+
|
|
50
53
|
Reach for a test harness the project already carries before building one. An experiment no existing harness can express is a finding for the folder, not a new abstraction.
|
|
51
54
|
|
|
52
55
|
Never count transcript matches to show a file was read. An instruction naming a path puts it in the transcript whether or not anything opened it, so the check is the tool call.
|
|
@@ -44,9 +44,11 @@ Does not govern:
|
|
|
44
44
|
|
|
45
45
|
- Name the folder `<nn>-<slug>`, a two-digit ordinal and a kebab-case slug.
|
|
46
46
|
- The ordinal marks a folder per track, opened once and worked over time, unlike a file addressed by name, one with its own sorting prefix, or one overwritten on purpose.
|
|
47
|
-
- Claim the ordinal through `canon records ordinal groundwork <slug> --claim`, which reads the highest
|
|
47
|
+
- Claim the ordinal through `canon records ordinal groundwork <slug> --claim`, which reads the highest across `.canon/groundwork/` and `.canon/intake/`, since the two kinds share one order
|
|
48
|
+
- The claim creates the folder in the same atomic act, so two sessions opening at once never share a number
|
|
48
49
|
- With neither folder holding an entry, the first one opened takes `01`, whatever number a track's own files start at.
|
|
49
|
-
|
|
50
|
+
|
|
51
|
+
Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
|
|
50
52
|
|
|
51
53
|
## What a working track looks like
|
|
52
54
|
|
|
@@ -86,20 +88,15 @@ A folder missing `06` and `07` is live, and that is its only status marker.
|
|
|
86
88
|
|
|
87
89
|
## README.md
|
|
88
90
|
|
|
89
|
-
Orients
|
|
91
|
+
Orients and holds no findings. It states the phase out loud in its first three lines, in the form `Groundwork phase. Nothing here is a feature plan.`
|
|
90
92
|
|
|
91
93
|
- A one-line definition of the investigation
|
|
92
94
|
- A `## Why` section stating why the track is running now
|
|
93
95
|
- A file-map table of filename and what it holds, kept current
|
|
94
96
|
- A `## Method` section splitting internal sources from external ones, naming which were used and which were not yet done, and listing under a leads heading any external source found but not opened
|
|
97
|
+
- Closing `## Prior art` and `## Source citation` sections, the second stating the rule below so a returning session finds it in the folder
|
|
95
98
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- A `## Prior art` section
|
|
99
|
-
- A `## Source citation` section stating the rule below, so a returning session finds it in the folder
|
|
100
|
-
- The phase stated out loud in the first three lines, in the form `Groundwork phase. Nothing here is a feature plan.`
|
|
101
|
-
|
|
102
|
-
Every claim about a source outside the project carries a link to it, wherever the claim appears in the folder. Without one, a later reader cannot tell a fetched page from recall. A source found and not read is listed as a lead and is never cited, since a link to a page nobody opened is worse than no link. Listing it stops a later pass re-searching for it.
|
|
99
|
+
Every claim about a source outside the project carries a link to it, wherever the claim appears in the folder, so a later reader can tell a fetched page from recall. A source found and not read is listed as a lead and never cited, since a link to a page nobody opened is worse than none. Listing it stops a later pass re-searching for it.
|
|
103
100
|
|
|
104
101
|
Where the track supersedes an earlier plan or an earlier folder, name it and say not to go looking for it. Without that, the old reasoning keeps circulating.
|
|
105
102
|
|
|
@@ -117,11 +114,10 @@ Written when the subject is large enough to run away. Holds constraints, risks,
|
|
|
117
114
|
|
|
118
115
|
## 06-decision.md
|
|
119
116
|
|
|
120
|
-
Closes the folder. Everything above it is input. Write it from the skeleton under `## Template`, with an H3 per dropped alternative.
|
|
117
|
+
Closes the folder. Everything above it is input. Write it from the skeleton under `## Template`, with an H3 per dropped alternative, a list that stops a future session re-proposing a rejected idea.
|
|
121
118
|
|
|
122
|
-
`## Revisit when` carries the "Overturned by" line of each lean that became the decision, as written
|
|
123
|
-
|
|
124
|
-
The dropped list stops a future session re-proposing a rejected idea.
|
|
119
|
+
- `## Revisit when` carries the "Overturned by" line of each lean that became the decision, as written
|
|
120
|
+
- A lean the decision did not take carries nothing, and a track whose deciding leans carried no overturn line omits the section
|
|
125
121
|
|
|
126
122
|
## 07-next-session.md
|
|
127
123
|
|
|
@@ -158,7 +154,9 @@ A lean is weaker than a plan's suggestion: it records the current read on an ope
|
|
|
158
154
|
|
|
159
155
|
## Template
|
|
160
156
|
|
|
161
|
-
|
|
157
|
+
The orienting README comes first, then the closing decision, with an H3 per dropped alternative.
|
|
158
|
+
|
|
159
|
+
**`README.md`**
|
|
162
160
|
|
|
163
161
|
```markdown
|
|
164
162
|
---
|
|
@@ -203,7 +201,7 @@ Every claim about a source outside the project carries a link. A source found
|
|
|
203
201
|
and not read is listed as a lead and is never cited.
|
|
204
202
|
```
|
|
205
203
|
|
|
206
|
-
|
|
204
|
+
**`06-decision.md`**
|
|
207
205
|
|
|
208
206
|
```markdown
|
|
209
207
|
---
|
|
@@ -7,7 +7,7 @@ description: Folder layout, ordinal naming, reserved index number, frontmatter a
|
|
|
7
7
|
|
|
8
8
|
Applies to an intake folder at `.canon/intake/<nn>-<slug>/`. One folder holds one dump, filed by domain, and every finding in it is an item carrying a measured problem, one proposed fix, and a verdict.
|
|
9
9
|
|
|
10
|
-
The folder is gitignored
|
|
10
|
+
The folder is gitignored. Where a records remote is configured, `canon records push` and `canon records pull` protect it against losing the machine, and elsewhere they refuse with `no-remote`. Neither saves reasoning a compaction drops before a push. No check reaches its contents, so the shape below survives only by being read.
|
|
11
11
|
|
|
12
12
|
<!-- canon-length-exempt: the folder shape and the item template share one reader, and a split into a second reference is queued as its own change -->
|
|
13
13
|
|
|
@@ -41,11 +41,13 @@ Does not govern:
|
|
|
41
41
|
|
|
42
42
|
## Folder name
|
|
43
43
|
|
|
44
|
-
- Name the folder `<nn>-<slug>`, a two-digit zero-padded ordinal
|
|
44
|
+
- Name the folder `<nn>-<slug>`, a two-digit zero-padded ordinal and a kebab-case slug, distinct from the `NN-<domain>.md` numbering of its cluster files
|
|
45
45
|
- The ordinal marks a folder per track, opened once and worked over time, distinct from a file addressed by name, one already carrying its own sorting prefix, or one deliberately overwritten.
|
|
46
|
-
- Claim the ordinal through `canon records ordinal intake <slug> --claim`, which reads the highest
|
|
47
|
-
-
|
|
48
|
-
-
|
|
46
|
+
- Claim the ordinal through `canon records ordinal intake <slug> --claim`, which reads the highest across `.canon/intake/` and `.canon/groundwork/`, since the two share one creation order
|
|
47
|
+
- The claim creates the folder in the same atomic act, closing the race a read-then-create leaves open between two sessions opening at once
|
|
48
|
+
- With neither folder holding an entry, the first one opened takes `01`, never read off a dump's inner numbering, which starts at `00`
|
|
49
|
+
|
|
50
|
+
Never renumber an existing folder. The ordinal is the order it opened, and a later reader cites it by that name.
|
|
49
51
|
|
|
50
52
|
## What a working intake looks like
|
|
51
53
|
|
|
@@ -68,9 +70,8 @@ An intake failing these is non-conforming even when it satisfies every shape rul
|
|
|
68
70
|
|
|
69
71
|
`00` is the only reserved number. Everything else is read order, and the domain rides in the filename so a reader knows what `07-tooling.md` holds without opening it.
|
|
70
72
|
|
|
71
|
-
Do not reserve mid-range numbers
|
|
72
|
-
|
|
73
|
-
Let the file count follow the number of separable domains. A large dump with two domains is a small folder.
|
|
73
|
+
- Do not reserve mid-range numbers, since clusters differ per dump and a contract over `06` would force every intake into one dump's shape
|
|
74
|
+
- Let the file count follow the number of separable domains. A large dump with two domains is a small folder.
|
|
74
75
|
|
|
75
76
|
## Frontmatter and dating
|
|
76
77
|
|
|
@@ -113,35 +114,39 @@ Where an item touches a task already on the board, say so in the index rather th
|
|
|
113
114
|
```
|
|
114
115
|
|
|
115
116
|
- `Problem:`, `Fix:`, `Worth it:`, and the empty `You:` slot ship on every item. The other two are conditional.
|
|
116
|
-
- Number items per cluster file,
|
|
117
|
-
- `Suggested:` is required whenever `Open:` is present
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
Two heading levels is the right depth inside a cluster file. A third means the cluster should have been its own file.
|
|
117
|
+
- Number items per cluster file, giving a finding split later a letter suffix such as `3a` beside `3`, since renumbering moves every cited label
|
|
118
|
+
- `Suggested:` is required whenever `Open:` is present, since `ok` against two defensible options carries no information
|
|
119
|
+
- Where the answer is the operator's preference rather than a technical call, say so in that form rather than inventing a default
|
|
120
|
+
- `Overlaps:` never replaces `Worth it:`, since an item a live board task might have wrong is the one whose verdict matters most
|
|
121
121
|
|
|
122
|
-
An item may carry a bolded standalone line between the bullets where a finding needs a name of its own
|
|
122
|
+
Two heading levels is the right depth inside a cluster file. A third means the cluster should have been its own file. An item may carry a rare bolded standalone line between the bullets where a finding needs a name of its own, and everything fitting the four bullets belongs in them.
|
|
123
123
|
|
|
124
124
|
## The answer contract
|
|
125
125
|
|
|
126
|
-
`You:` belongs to the operator and ships empty on every item.
|
|
126
|
+
`You:` belongs to the operator and ships empty on every item. Empty means unread and never agreement, so accepting a verdict is typed as one token, `- **You:** ok`.
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
- Never fill a `You:` slot, and never infer a disposition from an empty one
|
|
129
|
+
- On a resume pass, report unread items by count rather than deciding them
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
### Why silence is not consent
|
|
131
132
|
|
|
132
|
-
|
|
133
|
+
This inverts the plan file's contract, where a blank slot means accept the suggestion. A plan is read in one sitting with every question already surfaced. An intake folder is read over weeks, so an empty slot more likely means nobody reached the item, and acting on it ships a change nobody approved.
|
|
133
134
|
|
|
134
|
-
|
|
135
|
+
### Filling a slot
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
The operator types into the cluster file, or answers in chat and a verb lands the selection on the item. Both put the answer on the item, which keeps retrieval working, and neither lets a session decide one.
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
- An answer given in conversation and never written back leaves the item unread, since the file is the record
|
|
140
|
+
- An item already carrying an answer is refused rather than overwritten, whichever route the second answer takes
|
|
141
|
+
- Revising a filled slot is the operator editing their own line
|
|
139
142
|
|
|
140
|
-
|
|
143
|
+
## Retrieval
|
|
141
144
|
|
|
142
|
-
|
|
145
|
+
Answers live on items, so one pass over the folder reports every touched slot. With the toolkit CLI on PATH, read the folder through `canon intake list`, the surface under test.
|
|
143
146
|
|
|
144
|
-
|
|
147
|
+
- Bare, it reports per-folder counts, `--json` gives one folder's items, and `--unread` keeps only the empty slots
|
|
148
|
+
- It skips the index and every fenced sample, which the greps below cannot do
|
|
149
|
+
- The greps stay for a reader without the CLI, and they overcount by whatever the folder displays in a fence
|
|
145
150
|
|
|
146
151
|
```bash
|
|
147
152
|
awk '/^### /{h=FILENAME": "$0} /^- \*\*You:\*\*./{print h; print " "$0}' *.md
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pr-evidence
|
|
3
|
+
description: What posting a pull request's rendered-surface evidence is for, the gaps it closes, and what it refuses to do
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PR evidence requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, the evidence a pull request carries is one step inside `git-pr`. A session refreshing the screenshots on a new head either reruns a title and body it did not mean to touch, or borrows the step's reference by path. Two skills borrowed it that way, and each copy drifted.
|
|
11
|
+
|
|
12
|
+
A session judging from the diff whether an evidence image changed cannot see a regenerated image it did not author, so the image ships with no comment. A reviewer holding screenshots and a checklist has nothing to click into, and a slow deploy holds the ship chain while it waits for an address.
|
|
13
|
+
|
|
14
|
+
## Must
|
|
15
|
+
|
|
16
|
+
- Run the evidence verb on every pull request it is given and let `no-evidence` be the skip, since asking a session to look lets an unseen image ship with no comment
|
|
17
|
+
- Run alone against an open pull request, resolving the number from the branch when none is passed, so a later head gets evidence without a body rewrite
|
|
18
|
+
- Edit the one marked comment in place on a later run, so a re-post never duplicates the thread or drops a carried checklist
|
|
19
|
+
- Put a preview address on a pull request changing a rendered surface when the project's deploy can mint one, since a reviewer needs a page to click into
|
|
20
|
+
- Bound the wait on that preview and finish without the link on a timeout, since a slow deploy must not hold the ship
|
|
21
|
+
- Link the branch's running local server when this worktree serves one, since a reviewer on the operator's machine can drive the branch
|
|
22
|
+
- Drop that link when the pull request closes, since a link outliving its branch points at whatever runs there next
|
|
23
|
+
|
|
24
|
+
## Must not
|
|
25
|
+
|
|
26
|
+
- Dispatch a deploy whose command names no branch, since Cloudflare Pages publishes such a deploy to production
|
|
27
|
+
- Create a pull request, or post against a number it guessed, since a write to a wrong number lands on another branch's thread
|
|
28
|
+
- Call a GraphQL-backed `gh` subcommand, since the cloud review-address leg runs this skill through `git-followup`
|
|
29
|
+
- Print a result line of its own, since `git-pr` prints one and its report ends with the lines this skill returns
|
|
30
|
+
- Exist only for the author to type its name. `git-pr`, `git-followup`, and `git-ship` each invoke it, and a review of the catalog drops it when none does.
|
|
31
|
+
|
|
32
|
+
## Guards
|
|
33
|
+
|
|
34
|
+
- Stop and ask for the number when none was passed and no open pull request resolves for the branch
|
|
35
|
+
|
|
36
|
+
## Out of scope
|
|
37
|
+
|
|
38
|
+
- The title, body, labels, and pre-publish scan, which `git-pr` owns
|
|
39
|
+
- Writing the checklist, which `ui-checklist` owns. This skill only consumes the handoff file and removes it after posting.
|
|
40
|
+
- Driving the checklist in the running app, which `review-ui` owns
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pr-evidence
|
|
3
|
+
description: Posts the rendered-surface evidence on an open pull request, being the screenshot comparison with the UI checklist, the checklist alone when git refuses the comparison, the local server link, and the preview address, editing the one marked comment in place on every later head. Use when asked to "post the evidence", "refresh the screenshots on the PR", or "re-post the evidence on the new head", and as the closing step of `git-pr`. Do NOT use to write a pull request's title or body, which is `git-pr`, or to write the checklist, which is `ui-checklist`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# PR evidence
|
|
9
|
+
|
|
10
|
+
The evidence a pull request carries is owed again on every new head, while its title and body are not. This skill posts it against one pull request number, so `git-pr` runs it as its last step and any session can run it alone after a push.
|
|
11
|
+
|
|
12
|
+
## Resolve the pull request
|
|
13
|
+
|
|
14
|
+
Take the number the caller passed and look nothing up. `git-pr` passes the number its final command printed, and never invokes this skill when that command refused on a head mismatch and printed none.
|
|
15
|
+
|
|
16
|
+
Run bare, resolve the open pull request for the current branch:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
canon pr head --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Read `reason` on the record rather than the exit code, since a shell function wrapping `canon` can flatten it to zero.
|
|
23
|
+
|
|
24
|
+
- A record carrying `number`: hold it for every step below
|
|
25
|
+
- Any refusal, including `gh-failed` for a branch with no open pull request, stops the run with `❌ No open pull request resolved for this branch: <message>. Pass the number and re-run.`
|
|
26
|
+
- Never create a pull request here and never guess a number, since a write to a wrong number lands on another branch's thread
|
|
27
|
+
|
|
28
|
+
## Post the evidence
|
|
29
|
+
|
|
30
|
+
Read `${CLAUDE_SKILL_DIR}/references/evidence.md` and run its sections in order against the number, being the checklist, the local server, the evidence comparison, the checklist alone, and the preview address.
|
|
31
|
+
|
|
32
|
+
- Every post and edit goes through `gh api` over REST, since a cloud session's proxy refuses the GraphQL that `gh pr` runs on
|
|
33
|
+
- Never judge from the diff whether an evidence image changed, since the verb answers `no-evidence` for a branch that changed none and a session cannot see an image it did not author
|
|
34
|
+
- A lone run on a later head edits the marked comment through the record's `commentId` and passes no `--checklist` for a handoff already deleted, since the verb carries the checklist forward
|
|
35
|
+
|
|
36
|
+
## Report
|
|
37
|
+
|
|
38
|
+
Collect only the lines below whose condition holds, and nothing when none does. A lone run prints them. A run another skill invoked hands them back to that caller and prints nothing, since `git-pr` prints its own result line and then these lines, and printing here too shows them twice.
|
|
39
|
+
|
|
40
|
+
| Condition | Line |
|
|
41
|
+
| --------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
42
|
+
| A checklist posted in the evidence comment | `📋 Posted the UI checklist to <number>, in the evidence comment.` |
|
|
43
|
+
| A checklist posted alone | `📋 Posted the UI checklist to <number>, on its own.` |
|
|
44
|
+
| The preview step returned an address | `🔗 Preview: <url>` |
|
|
45
|
+
| The evidence step posted the local link | `🖥️ Local preview: <url>` |
|
|
46
|
+
| The local step refused and evidence or a checklist posted | `🖥️ No local preview: <reason>` |
|
|
47
|
+
| A git refusal or a preview refusal the reference reports | `⚠️ <reason>: <message>` |
|
|
48
|
+
|
|
49
|
+
### The no-local-preview line
|
|
50
|
+
|
|
51
|
+
It fires when the local step refused as `no-server` or `no-listener-reader`, since that pull request changes a rendered surface and a reviewer could have used the link. A later run only carries a link forward, so it cannot add one the comment never had.
|
|
52
|
+
|
|
53
|
+
To add the link later, start the server and run this skill again, adding `--checklist` to the evidence call when one is still owed.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Rendered-surface evidence
|
|
3
|
+
description: How pr-evidence finds the UI checklist and the local server, posts the evidence comparison or the checklist alone as the fallback for a git refusal, and adds the preview address, for a change that touches a rendered surface
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Rendered-surface evidence
|
|
7
|
+
|
|
8
|
+
The procedure of `pr-evidence`, run in order against one pull request number. It runs on every pull request with no test on the diff ahead of it, since `no-evidence` is the silent branch for one that changes no rendered surface.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [Find the UI checklist](#find-the-ui-checklist)
|
|
13
|
+
- [Find the local server](#find-the-local-server)
|
|
14
|
+
- [Post the evidence comparison](#post-the-evidence-comparison)
|
|
15
|
+
- [Post the UI checklist alone](#post-the-ui-checklist-alone)
|
|
16
|
+
- [Post the preview address](#post-the-preview-address)
|
|
17
|
+
|
|
18
|
+
## Find the UI checklist
|
|
19
|
+
|
|
20
|
+
`ui-checklist` writes a visual checklist to `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root when a change needs visual verification, with `<slug>` derived per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. This skill is the file's sole consumer.
|
|
21
|
+
|
|
22
|
+
- Resolve the main root the way `session-worktree` does, `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-` falling back to `pwd`
|
|
23
|
+
- A missing file means no checklist was produced, and the two steps below each skip their checklist half
|
|
24
|
+
- Scan an existing file against `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md` before either step posts it, the same as the body
|
|
25
|
+
- The evidence step decides where it lands, since a checklist reads next to its screenshots and posting it alone is the fallback for a refused render
|
|
26
|
+
|
|
27
|
+
## Find the local server
|
|
28
|
+
|
|
29
|
+
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 before the evidence step, so the first evidence comment already carries the link:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
canon pr local --json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The verb reports the lowest port serving an HTML page whose process runs inside this worktree, never one in another worktree or the main checkout, which shows a different branch. `canon pr local --help` states the contract. Read `reason` on the record rather than the exit code.
|
|
36
|
+
|
|
37
|
+
- `ok`: hold the record's `url` for the evidence step below.
|
|
38
|
+
- `no-server` or `no-listener-reader`: hold the reason for the closing report and pass no link. Never start a server here, since the ship chain cannot own one. A worker starts one under `role-worker`.
|
|
39
|
+
- Anything else, including no record or an older binary's unknown-subcommand error: move on silently, as a skip rather than a stop.
|
|
40
|
+
|
|
41
|
+
### Where the link lands
|
|
42
|
+
|
|
43
|
+
Pass `--local` to the evidence step only on an `ok`. The binary answering `ok` is the one carrying the flag, so a binary lacking the verb never meets a flag it would reject.
|
|
44
|
+
|
|
45
|
+
- With a checklist, a diff carrying no evidence image still renders `ok`, and the link rides on the address line under `## Evidence`, above the checklist
|
|
46
|
+
- A link with neither an evidence image nor a checklist still reports `no-evidence`, so a branch changing no rendered surface gets no comment holding a link alone
|
|
47
|
+
- A seeded workflow drops the whole address line once the pull request closes, hosted and local together, so neither link outlives its branch
|
|
48
|
+
|
|
49
|
+
## Post the evidence comparison
|
|
50
|
+
|
|
51
|
+
Run the verb once against the pull request number. Pass `--checklist` when the checklist step found a file and `--local` when the step above returned `ok`, and leave each flag off otherwise:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
canon pr evidence <number> --checklist <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --local <url> --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
One call answers both questions because a checklist decides `no-evidence`. A diff carrying a checklist and no evidence image renders `ok` with the checklist in a marked body, so the checklist lands in the one comment a later call finds and edits.
|
|
58
|
+
|
|
59
|
+
- Pass `--checklist` only for a file that exists
|
|
60
|
+
- The verb refuses as `unreadable-checklist` on a path it cannot read or one holding nothing, a caller bug rather than a transient failure
|
|
61
|
+
- Stop and repair the path on that refusal rather than posting a body with the checklist silently dropped
|
|
62
|
+
|
|
63
|
+
### Reading the record
|
|
64
|
+
|
|
65
|
+
Read `reason` on the record rather than the exit code.
|
|
66
|
+
|
|
67
|
+
- `no-evidence`: nothing changed under an `evidence/` segment and no checklist was passed. Say nothing about the evidence and move on.
|
|
68
|
+
- `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root, then post or update the comment:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md --silent
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Both posts in this file use the REST issue-comments endpoint, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. `git-followup` runs this skill, so a GraphQL post here would break the cloud review-address leg.
|
|
75
|
+
|
|
76
|
+
When the record carries a `commentId`, edit that comment in place instead of posting a second. The body reads from the tmp file with `@`, which needs `-F`, since `-f` posts the path itself as the body:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Delete the handoff file and the tmp body once that call reports success, per the cleanup below, since the checklist now lives on the pull request.
|
|
83
|
+
|
|
84
|
+
### Git refusals
|
|
85
|
+
|
|
86
|
+
Any other `reason` is a mirrored git refusal, being `gh-missing`, `gh-failed`, `no-base`, `unreadable-changes`, or `would-empty`. Report it and move on without stopping the chain, since a branch that rarely carries evidence images should not fail on a transient read.
|
|
87
|
+
|
|
88
|
+
Fall through to the checklist step, which posts the checklist alone rather than losing it.
|
|
89
|
+
|
|
90
|
+
## Post the UI checklist alone
|
|
91
|
+
|
|
92
|
+
Run this step only as the fallback, when the evidence step reported a git refusal and a checklist file exists, since every other branch with a checklist rendered `ok` and carried it. The comment carries no marker, so a later `canon pr evidence` call reports no `checklist` for it.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --silent
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Cleanup
|
|
99
|
+
|
|
100
|
+
Run the cleanup only once the call that carried the checklist reports success, whichever step that was. On a failure, stop and leave the file, since a retry needs it and deleting it loses the only copy.
|
|
101
|
+
|
|
102
|
+
The cleanup is a main-root delete, so it goes out as a plain `rm` and then a plain `rmdir`, routed the way `session-worktree` states:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
rm <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
rmdir <main-root>/.canon/tmp/handoff/ui-checklist 2>/dev/null || true
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- The `rmdir` is a no-op while another branch's pending checklist sits in the folder, so this step never deletes a handoff not its own
|
|
113
|
+
- `git-followup` re-runs `canon pr evidence` with no `--checklist`, and the verb carries the checklist forward out of the comment it edits
|
|
114
|
+
- A tick survives a render at the head its stamp names and is cleared by one at a newer head, so the next UI pass earns it again
|
|
115
|
+
|
|
116
|
+
## Post the preview address
|
|
117
|
+
|
|
118
|
+
Run this step when the evidence step returned `ok`, the fallback posted a checklist, or `canon pr evidence <number> --check --json` lists `preview` in `owed`. Otherwise skip it silently.
|
|
119
|
+
|
|
120
|
+
- The first two mean the pull request changes a rendered surface, and a reviewer holding a checklist with no screenshots needs the live page most
|
|
121
|
+
- The third is how `git-ship` reaches this step alone when an earlier run's deploy timed out
|
|
122
|
+
- An evidence record carrying a `commentId` takes the third alone, since a preview already on the comment counts as settled whatever head built it, so a later push does not re-mint one
|
|
123
|
+
- The evidence comment is already posted, so the reviewer has the screenshots while the deploy runs
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
canon pr preview <number> --json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### What the verb refuses
|
|
130
|
+
|
|
131
|
+
The verb dispatches the project's Pages deploy on the pull request's branch and waits on the run for up to 15 minutes. `canon pr preview --help` states the contract. It refuses before dispatching anything in two cases.
|
|
132
|
+
|
|
133
|
+
- The deploy command passes no `--branch`, since that deploy would publish the branch to production
|
|
134
|
+
- The workflow's push path filter matches no changed path, since a dispatch ignores that filter and the site would show none of the change
|
|
135
|
+
|
|
136
|
+
### Reading the preview record
|
|
137
|
+
|
|
138
|
+
Read `reason` on the record rather than the exit code.
|
|
139
|
+
|
|
140
|
+
- `ok`: re-render the evidence body with the address under `## Evidence`, then post or update it as the evidence step does, through the same tmp file and the record's `commentId`:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
canon pr evidence <number> --preview <url> --json
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The hosted address opens the address line, and a local link already on the comment follows it, carried forward with no flag.
|
|
147
|
+
|
|
148
|
+
- `no-deploy` or `unserved`: the project deploys nothing a dispatch can start, or its site builds from nothing this branch changed. Say nothing and move on.
|
|
149
|
+
- `unfenced`, `no-alias`, `run-failed`, `timeout`, or a mirrored `gh` refusal: report the record's `message` and move on without stopping the chain
|
|
150
|
+
- A missing link costs the reviewer a click, and a held ship costs the whole chain
|