@erclx/canon 5.41.0 → 5.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +22 -2
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +9 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +54 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +8 -0
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +28 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +57 -20
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/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/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 +12 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +8 -0
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/package.json +1 -1
- package/src/claude/cases/workflow.ts +5 -0
- package/src/commands/pr.ts +142 -28
- package/src/markdown/scope.ts +144 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/review-state.ts +182 -0
- package/claude/skills/git-pr/references/evidence.md +0 -124
package/src/markdown/scope.ts
CHANGED
|
@@ -42,41 +42,113 @@ export const GATED_PATHS: readonly string[] = [
|
|
|
42
42
|
'canon/context/context-model.md',
|
|
43
43
|
'canon/context/index.md',
|
|
44
44
|
'claude/skills/api-design/SKILL.md',
|
|
45
|
+
'claude/skills/api-design/references/adopted.md',
|
|
45
46
|
'claude/skills/auto-ship/SKILL.md',
|
|
47
|
+
'claude/skills/auto-ship/references/draft-mark.md',
|
|
48
|
+
'claude/skills/auto-ship/references/failure-recovery.md',
|
|
49
|
+
'claude/skills/auto-ship/references/fan-in.md',
|
|
50
|
+
'claude/skills/auto-ship/references/tier-failures.md',
|
|
51
|
+
'claude/skills/auto-ship/references/ui-checklist.md',
|
|
52
|
+
'claude/skills/auto-ship/references/verb-absent.md',
|
|
53
|
+
'claude/skills/auto-ship/references/worktree-name.md',
|
|
46
54
|
'claude/skills/backlog-triage/SKILL.md',
|
|
47
55
|
'claude/skills/backlog-triage/references/apply.md',
|
|
48
56
|
'claude/skills/build-in-slices/SKILL.md',
|
|
57
|
+
'claude/skills/build-in-slices/references/adopted.md',
|
|
49
58
|
'claude/skills/canon-cli/SKILL.md',
|
|
50
59
|
'claude/skills/canon-feedback-triage/SKILL.md',
|
|
51
60
|
'claude/skills/canon-feedback/SKILL.md',
|
|
61
|
+
'claude/skills/canon-feedback/references/template.md',
|
|
52
62
|
'claude/skills/canvas-board/SKILL.md',
|
|
63
|
+
'claude/skills/canvas-board/references/canvas.md',
|
|
64
|
+
'claude/skills/canvas-board/references/design.md',
|
|
53
65
|
'claude/skills/ci-workflow/SKILL.md',
|
|
66
|
+
'claude/skills/ci-workflow/references/workflows.md',
|
|
54
67
|
'claude/skills/code-craft/SKILL.md',
|
|
68
|
+
'claude/skills/code-craft/references/adopted.md',
|
|
55
69
|
'claude/skills/codebase-layout/SKILL.md',
|
|
70
|
+
'claude/skills/codebase-layout/references/adopted.md',
|
|
71
|
+
'claude/skills/codebase-layout/references/frontend.md',
|
|
72
|
+
'claude/skills/codebase-layout/references/tests.md',
|
|
56
73
|
'claude/skills/context-fold/SKILL.md',
|
|
74
|
+
'claude/skills/context-fold/references/classify.md',
|
|
75
|
+
'claude/skills/context-fold/references/completion-report.md',
|
|
76
|
+
'claude/skills/context-fold/references/context-refresh.md',
|
|
77
|
+
'claude/skills/context-fold/references/context.md',
|
|
78
|
+
'claude/skills/context-fold/references/unusable-baseline.md',
|
|
57
79
|
'claude/skills/create-rule/SKILL.md',
|
|
80
|
+
'claude/skills/create-rule/references/rule.md',
|
|
58
81
|
'claude/skills/create-skill/SKILL.md',
|
|
82
|
+
'claude/skills/create-skill/references/skill-disclosure.md',
|
|
83
|
+
'claude/skills/create-skill/references/skill-frontmatter.md',
|
|
84
|
+
'claude/skills/create-skill/references/skill-paths.md',
|
|
85
|
+
'claude/skills/create-skill/references/skill-practice.md',
|
|
86
|
+
'claude/skills/create-skill/references/skill-reference.md',
|
|
87
|
+
'claude/skills/create-skill/references/skill-requirement.md',
|
|
88
|
+
'claude/skills/create-skill/references/skill.md',
|
|
59
89
|
'claude/skills/decision-escalate/SKILL.md',
|
|
60
90
|
'claude/skills/deploy-app/SKILL.md',
|
|
91
|
+
'claude/skills/deploy-app/references/cloudflare.md',
|
|
92
|
+
'claude/skills/deploy-app/references/vercel.md',
|
|
61
93
|
'claude/skills/deprecation-migration/SKILL.md',
|
|
94
|
+
'claude/skills/deprecation-migration/references/adopted.md',
|
|
62
95
|
'claude/skills/design-taste/SKILL.md',
|
|
96
|
+
'claude/skills/design-taste/references/adopted.md',
|
|
97
|
+
'claude/skills/design-taste/references/craft.md',
|
|
98
|
+
'claude/skills/design-taste/references/kinds.md',
|
|
99
|
+
'claude/skills/design-taste/references/preflight.md',
|
|
100
|
+
'claude/skills/design-taste/references/systems.md',
|
|
101
|
+
'claude/skills/design-taste/references/tells.md',
|
|
102
|
+
'claude/skills/design-taste/references/vocabulary.md',
|
|
63
103
|
'claude/skills/docs-sync/SKILL.md',
|
|
104
|
+
'claude/skills/docs-sync/references/docs.md',
|
|
105
|
+
'claude/skills/docs-sync/references/readme.md',
|
|
64
106
|
'claude/skills/document-health/SKILL.md',
|
|
107
|
+
'claude/skills/document-health/references/axes.md',
|
|
65
108
|
'claude/skills/draft-and-pick/SKILL.md',
|
|
109
|
+
'claude/skills/draft-and-pick/references/live-arms.md',
|
|
66
110
|
'claude/skills/draft-doc/SKILL.md',
|
|
111
|
+
'claude/skills/draft-doc/references/context.md',
|
|
112
|
+
'claude/skills/draft-doc/references/docs.md',
|
|
113
|
+
'claude/skills/draft-doc/references/readme.md',
|
|
114
|
+
'claude/skills/draft-doc/references/readme/agent-facing.md',
|
|
115
|
+
'claude/skills/draft-doc/references/readme/application.md',
|
|
116
|
+
'claude/skills/draft-doc/references/readme/cli.md',
|
|
117
|
+
'claude/skills/draft-doc/references/readme/library.md',
|
|
118
|
+
'claude/skills/draft-doc/references/readme/plugin.md',
|
|
119
|
+
'claude/skills/draft-doc/references/requirements.md',
|
|
120
|
+
'claude/skills/draft-doc/references/wiki-kind.md',
|
|
121
|
+
'claude/skills/draft-doc/references/wiki.md',
|
|
67
122
|
'claude/skills/draft-figure/SKILL.md',
|
|
123
|
+
'claude/skills/draft-figure/references/architecture-set.md',
|
|
124
|
+
'claude/skills/draft-figure/references/figures.md',
|
|
125
|
+
'claude/skills/draft-figure/references/hand-drawn.md',
|
|
126
|
+
'claude/skills/draft-figure/references/mermaid-path.md',
|
|
127
|
+
'claude/skills/draft-figure/references/mermaid.md',
|
|
68
128
|
'claude/skills/draft-identity/SKILL.md',
|
|
69
129
|
'claude/skills/draft-identity/references/card-route.md',
|
|
70
130
|
'claude/skills/draft-ready/SKILL.md',
|
|
131
|
+
'claude/skills/draft-ready/references/assembly.md',
|
|
132
|
+
'claude/skills/draft-ready/references/ready.md',
|
|
71
133
|
'claude/skills/draft-screencast/SKILL.md',
|
|
72
134
|
'claude/skills/draft-screencast/references/beats-template.md',
|
|
73
135
|
'claude/skills/draft-slides/SKILL.md',
|
|
74
136
|
'claude/skills/draft-slides/references/deck.md',
|
|
75
137
|
'claude/skills/git-branch/SKILL.md',
|
|
138
|
+
'claude/skills/git-branch/references/branch.md',
|
|
139
|
+
'claude/skills/git-branch/references/slug.md',
|
|
76
140
|
'claude/skills/git-commit/SKILL.md',
|
|
141
|
+
'claude/skills/git-commit/references/commit.md',
|
|
142
|
+
'claude/skills/git-commit/references/versioning.md',
|
|
77
143
|
'claude/skills/git-followup/SKILL.md',
|
|
78
144
|
'claude/skills/git-issue/SKILL.md',
|
|
145
|
+
'claude/skills/git-issue/references/issue.md',
|
|
79
146
|
'claude/skills/git-pr/SKILL.md',
|
|
147
|
+
'claude/skills/git-pr/references/final-command.md',
|
|
148
|
+
'claude/skills/git-pr/references/labels.md',
|
|
149
|
+
'claude/skills/git-pr/references/pr.md',
|
|
150
|
+
'claude/skills/git-pr/references/publish.md',
|
|
151
|
+
'claude/skills/git-pr/references/task-number.md',
|
|
80
152
|
'claude/skills/git-ship/SKILL.md',
|
|
81
153
|
'claude/skills/git-ship/references/ci-watch.md',
|
|
82
154
|
'claude/skills/git-split/SKILL.md',
|
|
@@ -86,45 +158,117 @@ export const GATED_PATHS: readonly string[] = [
|
|
|
86
158
|
'claude/skills/git-worktree/SKILL.md',
|
|
87
159
|
'claude/skills/git-worktree/references/cleanup.md',
|
|
88
160
|
'claude/skills/markdown-craft/SKILL.md',
|
|
161
|
+
'claude/skills/markdown-craft/references/markdown.md',
|
|
89
162
|
'claude/skills/plan-feature/SKILL.md',
|
|
90
163
|
'claude/skills/plan-feature/references/batches.md',
|
|
164
|
+
'claude/skills/plan-feature/references/plan-lifecycle.md',
|
|
165
|
+
'claude/skills/plan-feature/references/plan.md',
|
|
91
166
|
'claude/skills/plan-groundwork/SKILL.md',
|
|
167
|
+
'claude/skills/plan-groundwork/references/groundwork-spikes.md',
|
|
168
|
+
'claude/skills/plan-groundwork/references/groundwork.md',
|
|
92
169
|
'claude/skills/plan-groundwork/references/output.md',
|
|
93
170
|
'claude/skills/plan-intake-answer/SKILL.md',
|
|
94
171
|
'claude/skills/plan-intake/SKILL.md',
|
|
172
|
+
'claude/skills/plan-intake/references/intake.md',
|
|
173
|
+
'claude/skills/pr-evidence/SKILL.md',
|
|
174
|
+
'claude/skills/pr-evidence/references/evidence.md',
|
|
95
175
|
'claude/skills/read-frames/SKILL.md',
|
|
96
176
|
'claude/skills/record-screencast/SKILL.md',
|
|
97
177
|
'claude/skills/review-address/SKILL.md',
|
|
178
|
+
'claude/skills/review-address/references/post-review-findings.md',
|
|
179
|
+
'claude/skills/review-address/references/rebase-conflicts.md',
|
|
98
180
|
'claude/skills/review-address/references/rebase-only.md',
|
|
181
|
+
'claude/skills/review-address/references/rest-reads.md',
|
|
99
182
|
'claude/skills/review-craft/SKILL.md',
|
|
183
|
+
'claude/skills/review-craft/references/adopted.md',
|
|
184
|
+
'claude/skills/review-craft/references/security.md',
|
|
185
|
+
'claude/skills/review-craft/references/ui.md',
|
|
100
186
|
'claude/skills/review-pr/SKILL.md',
|
|
187
|
+
'claude/skills/review-pr/references/body-variants.md',
|
|
188
|
+
'claude/skills/review-pr/references/close-out.md',
|
|
189
|
+
'claude/skills/review-pr/references/key-changes.md',
|
|
190
|
+
'claude/skills/review-pr/references/post.md',
|
|
191
|
+
'claude/skills/review-pr/references/scope.md',
|
|
101
192
|
'claude/skills/review-ui/SKILL.md',
|
|
193
|
+
'claude/skills/review-ui/references/close-out.md',
|
|
194
|
+
'claude/skills/review-ui/references/driving.md',
|
|
102
195
|
'claude/skills/review-ui/references/hosted-preview.md',
|
|
196
|
+
'claude/skills/review-ui/references/post.md',
|
|
197
|
+
'claude/skills/review-ui/references/tick.md',
|
|
103
198
|
'claude/skills/role-orchestrator/SKILL.md',
|
|
199
|
+
'claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md',
|
|
200
|
+
'claude/skills/role-orchestrator/references/orchestrator-dispatch.md',
|
|
104
201
|
'claude/skills/role-orchestrator/references/orchestrator-filing.md',
|
|
202
|
+
'claude/skills/role-orchestrator/references/orchestrator-handback.md',
|
|
203
|
+
'claude/skills/role-orchestrator/references/orchestrator-handoff.md',
|
|
204
|
+
'claude/skills/role-orchestrator/references/orchestrator-inbound.md',
|
|
205
|
+
'claude/skills/role-orchestrator/references/orchestrator-launch.md',
|
|
206
|
+
'claude/skills/role-orchestrator/references/orchestrator-output.md',
|
|
207
|
+
'claude/skills/role-orchestrator/references/orchestrator-parked.md',
|
|
208
|
+
'claude/skills/role-orchestrator/references/orchestrator-poll.md',
|
|
209
|
+
'claude/skills/role-orchestrator/references/orchestrator-refill.md',
|
|
210
|
+
'claude/skills/role-orchestrator/references/orchestrator-resume.md',
|
|
211
|
+
'claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md',
|
|
212
|
+
'claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md',
|
|
213
|
+
'claude/skills/role-orchestrator/references/orchestrator-sweep.md',
|
|
214
|
+
'claude/skills/role-orchestrator/references/orchestrator-watch.md',
|
|
105
215
|
'claude/skills/role-planner/SKILL.md',
|
|
106
216
|
'claude/skills/role-reviewer/SKILL.md',
|
|
107
217
|
'claude/skills/role-worker/SKILL.md',
|
|
108
218
|
'claude/skills/search-craft/SKILL.md',
|
|
219
|
+
'claude/skills/search-craft/references/adopted.md',
|
|
109
220
|
'claude/skills/session-compact/SKILL.md',
|
|
221
|
+
'claude/skills/session-compact/references/handoff-note.md',
|
|
110
222
|
'claude/skills/session-map/SKILL.md',
|
|
223
|
+
'claude/skills/session-map/references/session.md',
|
|
111
224
|
'claude/skills/session-relay/SKILL.md',
|
|
112
225
|
'claude/skills/session-resume/SKILL.md',
|
|
113
226
|
'claude/skills/session-worktree/SKILL.md',
|
|
227
|
+
'claude/skills/session-worktree/references/install-command.md',
|
|
228
|
+
'claude/skills/session-worktree/references/main-root-writes.md',
|
|
114
229
|
'claude/skills/systematic-debugging/SKILL.md',
|
|
230
|
+
'claude/skills/systematic-debugging/references/adopted.md',
|
|
115
231
|
'claude/skills/target-check/SKILL.md',
|
|
232
|
+
'claude/skills/target-check/references/domains.md',
|
|
116
233
|
'claude/skills/target-setup/SKILL.md',
|
|
234
|
+
'claude/skills/target-setup/references/detect.md',
|
|
235
|
+
'claude/skills/target-setup/references/indexes.md',
|
|
236
|
+
'claude/skills/target-setup/references/verify.md',
|
|
117
237
|
'claude/skills/task-board/SKILL.md',
|
|
238
|
+
'claude/skills/task-board/references/board.md',
|
|
118
239
|
'claude/skills/task-board/references/create-report.md',
|
|
240
|
+
'claude/skills/task-board/references/decline.md',
|
|
241
|
+
'claude/skills/task-board/references/tasks-decline.md',
|
|
242
|
+
'claude/skills/task-board/references/tasks.md',
|
|
119
243
|
'claude/skills/task-complete/SKILL.md',
|
|
244
|
+
'claude/skills/task-complete/references/archive.md',
|
|
245
|
+
'claude/skills/task-complete/references/receipt-sweep.md',
|
|
246
|
+
'claude/skills/task-complete/references/unusable-baseline.md',
|
|
120
247
|
'claude/skills/teach-workspace/SKILL.md',
|
|
248
|
+
'claude/skills/teach-workspace/references/glossary.md',
|
|
249
|
+
'claude/skills/teach-workspace/references/lesson-build.md',
|
|
250
|
+
'claude/skills/teach-workspace/references/lesson-craft.md',
|
|
251
|
+
'claude/skills/teach-workspace/references/pedagogy.md',
|
|
252
|
+
'claude/skills/teach-workspace/references/promotion-fold.md',
|
|
253
|
+
'claude/skills/teach-workspace/references/promotion.md',
|
|
254
|
+
'claude/skills/teach-workspace/references/revisit.md',
|
|
255
|
+
'claude/skills/teach-workspace/references/teach.md',
|
|
121
256
|
'claude/skills/test-craft/SKILL.md',
|
|
257
|
+
'claude/skills/test-craft/references/adopted.md',
|
|
258
|
+
'claude/skills/test-craft/references/component.md',
|
|
259
|
+
'claude/skills/test-craft/references/e2e.md',
|
|
260
|
+
'claude/skills/test-craft/references/unit.md',
|
|
122
261
|
'claude/skills/test-first/SKILL.md',
|
|
262
|
+
'claude/skills/test-first/references/adopted.md',
|
|
123
263
|
'claude/skills/ui-checklist/SKILL.md',
|
|
124
264
|
'claude/skills/ux-audit/SKILL.md',
|
|
125
265
|
'claude/skills/ux-measure/SKILL.md',
|
|
126
266
|
'claude/skills/video-craft/SKILL.md',
|
|
267
|
+
'claude/skills/video-craft/references/adopted.md',
|
|
127
268
|
'claude/skills/write-human/SKILL.md',
|
|
269
|
+
'claude/skills/write-human/references/adopted.md',
|
|
270
|
+
'claude/skills/write-human/references/density.md',
|
|
271
|
+
'claude/skills/write-human/references/machine-tells.md',
|
|
128
272
|
'claude/skills/youtube-transcripts/SKILL.md',
|
|
129
273
|
'.claude/skills/internal-',
|
|
130
274
|
'docs/',
|
package/src/pr/lift.ts
CHANGED
|
@@ -144,7 +144,10 @@ function fail(gate: GateName, reason: LiftRefusal): GateResult {
|
|
|
144
144
|
* since the commit it covers is a stamp GitHub wrote at submission, which the
|
|
145
145
|
* marker exists to replace.
|
|
146
146
|
*/
|
|
147
|
-
function reviewGate(
|
|
147
|
+
export function reviewGate(
|
|
148
|
+
reviews: readonly ReviewRow[],
|
|
149
|
+
head: string,
|
|
150
|
+
): GateResult {
|
|
148
151
|
const scope = resolveReviewScope({ reviews })
|
|
149
152
|
if (scope.state === 'none') return fail('review', 'review-missing')
|
|
150
153
|
if (scope.state === 'open') return fail('review', 'review-open')
|
|
@@ -175,8 +178,8 @@ function carried(gates: readonly GateResult[]): {
|
|
|
175
178
|
* checklist the reviewer drove as true as it was. A close that is not an
|
|
176
179
|
* ancestor, which a force-push or a rebase leaves, never carries.
|
|
177
180
|
*/
|
|
178
|
-
async function uiGate(
|
|
179
|
-
api: LiftApi,
|
|
181
|
+
export async function uiGate(
|
|
182
|
+
api: Pick<LiftApi, 'readChanged'>,
|
|
180
183
|
painted: PaintedPatterns,
|
|
181
184
|
reviews: readonly ReviewRow[],
|
|
182
185
|
head: string,
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHECKS_POLL_MS,
|
|
3
|
+
type GateResult,
|
|
4
|
+
type LiftApi,
|
|
5
|
+
type LiftRefusal,
|
|
6
|
+
reviewGate,
|
|
7
|
+
uiGate,
|
|
8
|
+
} from '@/pr/lift'
|
|
9
|
+
import { DEFAULT_PAINTED, type PaintedPatterns } from '@/pr/painted'
|
|
10
|
+
import {
|
|
11
|
+
coversHead,
|
|
12
|
+
type ReviewRow,
|
|
13
|
+
type ReviewScope,
|
|
14
|
+
resolveReviewScope,
|
|
15
|
+
resolveUiScope,
|
|
16
|
+
type UiScope,
|
|
17
|
+
} from '@/pr/review-scope'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The reads the verb makes, a subset of the lift's so a worker waiting here and
|
|
21
|
+
* a reviewer lifting read one answer. A read that failed returns undefined, and
|
|
22
|
+
* the verb refuses `gh-failed` rather than reading absence as no pass.
|
|
23
|
+
*/
|
|
24
|
+
export type ReviewStateApi = Pick<
|
|
25
|
+
LiftApi,
|
|
26
|
+
'readReviews' | 'readEvidence' | 'readChanged' | 'sleep' | 'now'
|
|
27
|
+
> & {
|
|
28
|
+
/** The branch tip from the remote, which is what a pass has to cover. */
|
|
29
|
+
readTip(): Promise<string | undefined>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** One family's standing at the tip. */
|
|
33
|
+
export interface FamilyState {
|
|
34
|
+
/** The lift's refusal for this family, absent when its gate passes. */
|
|
35
|
+
readonly reason?: LiftRefusal
|
|
36
|
+
/**
|
|
37
|
+
* Whether a pass covers the tip, which is what a waiting worker reads. True
|
|
38
|
+
* when the gate passes, or when the newest pass, open or unmarked, names the
|
|
39
|
+
* tip. The reason alone cannot answer it, since the lift reads an open pass
|
|
40
|
+
* before it reads currency.
|
|
41
|
+
*/
|
|
42
|
+
readonly isCovered: boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface UiState extends UiScope, FamilyState {
|
|
46
|
+
/** Whether the evidence comment carries a checklist, which binds the family. */
|
|
47
|
+
readonly isBound: boolean
|
|
48
|
+
readonly carriedFrom?: string
|
|
49
|
+
readonly paintedPaths?: readonly string[]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ReviewStateRecord {
|
|
53
|
+
readonly head: string
|
|
54
|
+
readonly scope: ReviewScope
|
|
55
|
+
readonly review: FamilyState
|
|
56
|
+
readonly ui: UiState
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ReviewStateRead =
|
|
60
|
+
| { readonly kind: 'read'; readonly record: ReviewStateRecord }
|
|
61
|
+
| { readonly kind: 'refused'; readonly reason: 'gh-failed' }
|
|
62
|
+
|
|
63
|
+
export type ReviewWait =
|
|
64
|
+
| {
|
|
65
|
+
readonly kind: 'read'
|
|
66
|
+
readonly reason: 'covered' | 'timeout'
|
|
67
|
+
readonly record: ReviewStateRecord
|
|
68
|
+
readonly waitedSeconds: number
|
|
69
|
+
}
|
|
70
|
+
| {
|
|
71
|
+
readonly kind: 'refused'
|
|
72
|
+
readonly reason: 'gh-failed'
|
|
73
|
+
readonly waitedSeconds: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface WaitOptions {
|
|
77
|
+
readonly waitSeconds: number
|
|
78
|
+
readonly pollMs?: number
|
|
79
|
+
readonly painted?: PaintedPatterns
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function familyOf(gate: GateResult, commit: string | undefined, tip: string) {
|
|
83
|
+
return {
|
|
84
|
+
...(gate.reason !== undefined && { reason: gate.reason }),
|
|
85
|
+
isCovered: gate.isOk || (commit !== undefined && coversHead(commit, tip)),
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Both families at the tip through the lift's own gates, so a worker and the
|
|
91
|
+
* lift never disagree on a reason. The evidence is read by the caller, since a
|
|
92
|
+
* wait reads it once rather than once per poll.
|
|
93
|
+
*/
|
|
94
|
+
async function readAt(
|
|
95
|
+
api: ReviewStateApi,
|
|
96
|
+
hasChecklist: boolean,
|
|
97
|
+
painted: PaintedPatterns,
|
|
98
|
+
): Promise<ReviewStateRead> {
|
|
99
|
+
const [tip, reviews] = await Promise.all([api.readTip(), api.readReviews()])
|
|
100
|
+
if (tip === undefined || reviews === undefined) {
|
|
101
|
+
return { kind: 'refused', reason: 'gh-failed' }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const listing: { reviews: readonly ReviewRow[] } = { reviews }
|
|
105
|
+
const scope = resolveReviewScope(listing)
|
|
106
|
+
const uiScope = resolveUiScope(listing)
|
|
107
|
+
const ui = await uiGate(api, painted, reviews, tip, hasChecklist)
|
|
108
|
+
if (ui.reason === 'gh-failed') return { kind: 'refused', reason: 'gh-failed' }
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
kind: 'read',
|
|
112
|
+
record: {
|
|
113
|
+
head: tip,
|
|
114
|
+
scope,
|
|
115
|
+
review: familyOf(reviewGate(reviews, tip), scope.commit, tip),
|
|
116
|
+
ui: {
|
|
117
|
+
...uiScope,
|
|
118
|
+
...familyOf(ui, uiScope.commit, tip),
|
|
119
|
+
isBound: hasChecklist,
|
|
120
|
+
...(ui.carriedFrom !== undefined && { carriedFrom: ui.carriedFrom }),
|
|
121
|
+
...(ui.paintedPaths !== undefined && { paintedPaths: ui.paintedPaths }),
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export async function readReviewState(
|
|
128
|
+
api: ReviewStateApi,
|
|
129
|
+
painted: PaintedPatterns = DEFAULT_PAINTED,
|
|
130
|
+
): Promise<ReviewStateRead> {
|
|
131
|
+
const evidence = await api.readEvidence()
|
|
132
|
+
if (evidence === undefined) return { kind: 'refused', reason: 'gh-failed' }
|
|
133
|
+
return readAt(api, evidence.hasChecklist, painted)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Holds until every bound family has a pass covering the tip, or the deadline
|
|
138
|
+
* passes. The tip is read again every poll, so a push during the wait moves
|
|
139
|
+
* what a pass has to cover. The evidence is read once, since a checklist
|
|
140
|
+
* appearing mid-wait is a ship-chain write the waiting worker made before it
|
|
141
|
+
* started.
|
|
142
|
+
*/
|
|
143
|
+
export async function waitForReviews(
|
|
144
|
+
api: ReviewStateApi,
|
|
145
|
+
opts: WaitOptions,
|
|
146
|
+
): Promise<ReviewWait> {
|
|
147
|
+
const pollMs = opts.pollMs ?? CHECKS_POLL_MS
|
|
148
|
+
const painted = opts.painted ?? DEFAULT_PAINTED
|
|
149
|
+
const started = api.now()
|
|
150
|
+
const deadline = started + opts.waitSeconds * 1000
|
|
151
|
+
const waited = () => Math.round((api.now() - started) / 1000)
|
|
152
|
+
|
|
153
|
+
const evidence = await api.readEvidence()
|
|
154
|
+
if (evidence === undefined) {
|
|
155
|
+
return { kind: 'refused', reason: 'gh-failed', waitedSeconds: waited() }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
for (;;) {
|
|
159
|
+
const read = await readAt(api, evidence.hasChecklist, painted)
|
|
160
|
+
if (read.kind === 'refused') {
|
|
161
|
+
return { ...read, waitedSeconds: waited() }
|
|
162
|
+
}
|
|
163
|
+
const { record } = read
|
|
164
|
+
if (record.review.isCovered && record.ui.isCovered) {
|
|
165
|
+
return {
|
|
166
|
+
kind: 'read',
|
|
167
|
+
reason: 'covered',
|
|
168
|
+
record,
|
|
169
|
+
waitedSeconds: waited(),
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (api.now() + pollMs > deadline) {
|
|
173
|
+
return {
|
|
174
|
+
kind: 'read',
|
|
175
|
+
reason: 'timeout',
|
|
176
|
+
record,
|
|
177
|
+
waitedSeconds: waited(),
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
await api.sleep(pollMs)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Rendered-surface evidence
|
|
3
|
-
description: How git-pr 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 rendered-surface step of `git-pr`, reached after the final command printed the pull request number. The step runs on every pull request, with no test on the diff ahead of it. `no-evidence` is the silent branch, so a pull request that changes no rendered surface posts nothing.
|
|
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. Resolve the main root the way `session-worktree` does (`git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, falling back to `pwd`) and check for the file there. A missing file means no checklist was produced, and the two steps below each skip their checklist half.
|
|
21
|
-
|
|
22
|
-
When it exists, scan it against `${CLAUDE_SKILL_DIR}/references/publish.md` before either step posts it, the same as the pull request body in the skill's pre-publish scan.
|
|
23
|
-
|
|
24
|
-
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 refused render.
|
|
25
|
-
|
|
26
|
-
## Find the local server
|
|
27
|
-
|
|
28
|
-
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:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
canon pr local --json
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
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 pr local --help` states the contract. Read `reason` on the record rather than the exit code.
|
|
35
|
-
|
|
36
|
-
- `ok`: hold the record's `url` for the evidence step below.
|
|
37
|
-
- `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.
|
|
38
|
-
- 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.
|
|
39
|
-
|
|
40
|
-
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.
|
|
41
|
-
|
|
42
|
-
With a checklist, a diff carrying no evidence image still renders `ok`, and a local link rides in the same comment on the address line under `## Evidence`, above the checklist, 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.
|
|
43
|
-
|
|
44
|
-
A seeded workflow drops the whole address line once the pull request closes, hosted and local segments together and with no note in their place, so neither link outlives the branch it points at.
|
|
45
|
-
|
|
46
|
-
## Post the evidence comparison
|
|
47
|
-
|
|
48
|
-
Run the verb once against the number the skill's final command printed. Pass `--checklist` when the checklist step found a file, and `--local` when the step above returned `ok`. Leave each flag off otherwise:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
canon pr evidence <number> --checklist <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --local <url> --json
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
One call answers both questions because a checklist decides `no-evidence`. The verb renders `ok` on a diff carrying a checklist and no evidence image, with a marked body holding the checklist, so the checklist always lands in the one comment a later call finds and edits. Without a checklist, a diff carrying no evidence image reports `no-evidence`.
|
|
55
|
-
|
|
56
|
-
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.
|
|
57
|
-
|
|
58
|
-
Read `reason` on the record rather than the exit code.
|
|
59
|
-
|
|
60
|
-
- `no-evidence`: nothing changed under an `evidence/` segment and no checklist was passed, so no body was rendered. Say nothing about the evidence and move on.
|
|
61
|
-
- `ok`: write `body` to `.canon/tmp/pr/evidence/body-<number>.md` at the main worktree root (resolved the way `session-worktree` does), then post or update the comment:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md --silent
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Both posts in this file go through the REST issue-comments endpoint, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. `git-followup` mints a preview through this file, so a GraphQL post here would break the cloud review-address leg.
|
|
68
|
-
|
|
69
|
-
When the record carries a `commentId`, edit that comment in place instead of posting a second one, reading the body field from the tmp file with `@`, which needs the typed-field flag `-F` because the raw-string flag `-f` posts the path itself as the body:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
gh api -X PATCH repos/{owner}/{repo}/issues/comments/<commentId> -F body=@<main-root>/.canon/tmp/pr/evidence/body-<number>.md
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Delete the handoff file once that call reports success, per the cleanup below, since the checklist now lives on the pull request. Clean up the tmp body file the same way.
|
|
76
|
-
|
|
77
|
-
Any other `reason` is one of the mirrored git refusals (`gh-missing`, `gh-failed`, `no-base`, `unreadable-changes`, `would-empty`). Report it and move on without stopping the chain: a branch that carries no evidence images most of the time should not fail here on a transient git or `gh` read. Fall through to the checklist step, which posts the checklist alone rather than losing it to a transient read.
|
|
78
|
-
|
|
79
|
-
## Post the UI checklist alone
|
|
80
|
-
|
|
81
|
-
Run this step only as the fallback, when the evidence step above reported one of the git refusals and a checklist file exists, since every other branch with a checklist rendered `ok` and carried it. The comment this posts carries no marker, so a later `canon pr evidence` call reports no `checklist` for it. Post it as its own comment on `<number>`:
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@<main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md --silent
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
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.
|
|
88
|
-
|
|
89
|
-
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:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
rm <main-root>/.canon/tmp/handoff/ui-checklist/<slug>.md
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
rmdir <main-root>/.canon/tmp/handoff/ui-checklist 2>/dev/null || true
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
The `rmdir` is a no-op when another branch's pending checklist still sits in the folder, which keeps this step from deleting a handoff that is not its own.
|
|
100
|
-
|
|
101
|
-
Deleting the file is what makes the later re-render safe. `git-followup` re-runs `canon pr evidence` with no `--checklist`, and the verb carries the checklist forward out of the comment it is editing, so the checklist survives the push. A tick survives a render at the head its stamp names and is cleared by one at a newer head, which leaves the next UI pass to earn it again.
|
|
102
|
-
|
|
103
|
-
## Post the preview address
|
|
104
|
-
|
|
105
|
-
Run this step when the evidence step above returned `ok`, a checklist was posted by the fallback, or `canon pr evidence <number> --check --json` lists `preview` in `owed`. 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. The third is how `git-ship` reaches this step alone when an earlier run's deploy timed out, so no evidence step ran in the current one. Otherwise skip it silently.
|
|
106
|
-
|
|
107
|
-
The evidence comment is already posted, so the reviewer has the screenshots while the deploy runs. Mint the preview against the same `<number>`:
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
canon pr preview <number> --json
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
The verb dispatches the project's Pages deploy on the pull request's branch and waits on the run for up to 15 minutes. It refuses before dispatching anything when the deploy command passes no `--branch`, since that deploy would publish the branch to production, and when the workflow's own push path filter matches no path the pull request changed, since a dispatch ignores that filter and the site it published would show none of the change. `canon pr preview --help` states the contract. Read `reason` on the record rather than the exit code.
|
|
114
|
-
|
|
115
|
-
- `ok`: re-render the evidence body with the address on the line under `## Evidence`, then post or update it exactly as the evidence step does, through the same tmp file and the `commentId` the record carries:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
canon pr evidence <number> --preview <url> --json
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
The hosted address opens the address line and a local link already on the comment follows it on the same line, carried forward with no flag.
|
|
122
|
-
|
|
123
|
-
- `no-deploy` or `unserved`: the project deploys nothing a dispatch can start, or nothing this branch changed is something its site builds from. Say nothing and move on.
|
|
124
|
-
- 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.
|