@erclx/canon 5.39.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/canvas-board/SKILL.md +1 -1
- package/claude/skills/draft-slides/SKILL.md +2 -3
- package/claude/skills/draft-slides/references/deck.md +183 -0
- package/claude/skills/git-pr/references/evidence.md +2 -2
- package/claude/skills/git-pr/references/final-command.md +1 -1
- package/claude/skills/git-pr/references/labels.md +1 -1
- package/claude/skills/git-pr/references/publish.md +1 -1
- package/claude/skills/review-ui/SKILL.md +1 -0
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +1 -1
- package/claude/skills/task-board/references/board.md +1 -1
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/ux-measure/SKILL.md +1 -1
- package/docs/agents/audits.md +61 -60
- package/docs/agents/context-audit.md +40 -58
- package/docs/agents/index.md +5 -51
- package/docs/agents/install-and-sync.md +1 -0
- package/docs/agents/markdown-audit.md +53 -99
- package/docs/agents/records.md +37 -79
- package/docs/agents/sessions-transfer.md +26 -70
- package/docs/target/index.md +0 -1
- package/docs/target/migrations.md +57 -66
- package/docs/target/projects.md +36 -78
- package/docs/target/scenarios.md +9 -19
- package/docs/target/sync.md +27 -68
- package/docs/workflow/ai-workflow.md +22 -68
- package/docs/workflow/operating-model.md +32 -186
- package/docs/workflow/parallel-features.md +29 -66
- package/docs/workflow/skill-map-on-request.md +22 -24
- package/docs/workflow/skill-map.md +72 -76
- package/docs/workflow/visual-design-workflow.md +25 -118
- package/docs/workflow/zshrc-aliases.md +18 -37
- package/package.json +1 -1
- package/src/canvas/client/inspector/fields.css +4 -0
- package/src/canvas/index.html +6 -0
- package/src/claude/skills-reach.ts +2 -2
- package/src/cli/ui.ts +3 -1
- package/src/commands/canvas.ts +23 -0
- package/src/commands/capture.ts +14 -0
- package/src/commands/claude.ts +13 -0
- package/src/commands/demo.ts +22 -0
- package/src/commands/deps.ts +6 -0
- package/src/commands/driver.ts +28 -2
- package/src/commands/gov.ts +52 -18
- package/src/commands/intake.ts +17 -0
- package/src/commands/labels.ts +38 -5
- package/src/commands/pr.ts +160 -43
- package/src/commands/records.ts +8 -0
- package/src/commands/secrets.ts +6 -0
- package/src/commands/sessions.ts +8 -0
- package/src/commands/tasks.ts +52 -0
- package/src/commands/teach.ts +13 -0
- package/src/commands/upstream.ts +25 -1
- package/src/commands/worktrees.ts +5 -0
- package/src/context/audit.ts +22 -4
- package/src/context/folders.ts +1 -1
- package/src/context/shape-gated.ts +4 -2
- package/src/counts/scan.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/tokens.ts +1 -1
- package/src/gate/boundaries.ts +4 -1
- package/src/gate/measures.ts +1 -1
- package/src/gate/stages.ts +7 -7
- package/src/git/env.ts +6 -0
- package/src/markdown/scope.ts +5 -17
- package/src/pr/lift.ts +153 -19
- package/src/pr/painted.ts +87 -0
- package/src/roots/record.ts +18 -1
- package/src/sandbox/census.ts +1 -1
- package/src/sandbox/headless/run.ts +3 -2
- package/src/sandbox/headless/watch.ts +3 -4
- package/src/slides/convert/master.ts +3 -0
- package/src/sync/format.ts +46 -0
- package/src/sync/stamp.ts +6 -0
- package/tooling/astro/reference.md +2 -2
- package/tooling/base/reference.md +1 -1
- package/tooling/go/reference.md +1 -1
- package/tooling/nextjs/reference.md +1 -1
- package/tooling/php/reference.md +1 -1
- package/tooling/python/reference.md +1 -1
- package/tooling/vite-react/reference.md +1 -1
- package/tooling/web/reference.md +1 -1
- package/docs/agents/canvas.md +0 -86
- package/docs/agents/capture.md +0 -65
- package/docs/agents/census.md +0 -23
- package/docs/agents/comments.md +0 -34
- package/docs/agents/context-audit-checks.md +0 -108
- package/docs/agents/context-classify.md +0 -101
- package/docs/agents/counts.md +0 -74
- package/docs/agents/demo.md +0 -140
- package/docs/agents/driver.md +0 -103
- package/docs/agents/gate.md +0 -90
- package/docs/agents/hooks.md +0 -78
- package/docs/agents/intake.md +0 -81
- package/docs/agents/key-changes.md +0 -116
- package/docs/agents/label-coverage.md +0 -86
- package/docs/agents/markdown-audit-density.md +0 -39
- package/docs/agents/markdown-audit-weight.md +0 -83
- package/docs/agents/pr-evidence-layout.md +0 -70
- package/docs/agents/pr-evidence.md +0 -273
- package/docs/agents/pr-frames.md +0 -131
- package/docs/agents/pr-lift.md +0 -132
- package/docs/agents/pr-local.md +0 -111
- package/docs/agents/pr-preview.md +0 -155
- package/docs/agents/pr-reads.md +0 -111
- package/docs/agents/pr-tick.md +0 -72
- package/docs/agents/records-push.md +0 -61
- package/docs/agents/records-stale.md +0 -40
- package/docs/agents/records-validate.md +0 -57
- package/docs/agents/restated.md +0 -83
- package/docs/agents/routing.md +0 -61
- package/docs/agents/rule-citations.md +0 -90
- package/docs/agents/sandbox.md +0 -126
- package/docs/agents/sessions.md +0 -128
- package/docs/agents/skills-audit.md +0 -120
- package/docs/agents/skills-reach.md +0 -64
- package/docs/agents/slides.md +0 -176
- package/docs/agents/state-scoped-risk.md +0 -105
- package/docs/agents/superseded.md +0 -85
- package/docs/agents/tasks-archive.md +0 -83
- package/docs/agents/tasks-plans.md +0 -152
- package/docs/agents/tasks-validate.md +0 -133
- package/docs/agents/tasks.md +0 -123
- package/docs/agents/teach-authoring.md +0 -118
- package/docs/agents/teach.md +0 -157
- package/docs/agents/test-order.md +0 -58
- package/docs/agents/upstream.md +0 -94
- package/docs/agents/worktrees.md +0 -118
- package/docs/target/standards-moved.md +0 -34
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: The pull request evidence comparison
|
|
3
|
-
description: What canon pr evidence compares, the marker that lets it edit its own comment rather than duplicate it, the refusal reasons it names, what the --check read reports as owed, and why the comparison anchors at the merge base rather than the previous push
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# The pull request evidence comparison
|
|
7
|
-
|
|
8
|
-
`canon pr evidence` renders one comment naming every changed image under an
|
|
9
|
-
`evidence/` path segment, comparing each against the pull request's merge base.
|
|
10
|
-
`git-pr` posts it when a pull request opens or is edited, and `git-followup`
|
|
11
|
-
posts it again after every later push, so a reviewer never has to open Files
|
|
12
|
-
Changed to see what a case looked like before and after.
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
canon pr evidence
|
|
16
|
-
canon pr evidence 1341 --json
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Why the comparison anchors at the merge base
|
|
20
|
-
|
|
21
|
-
The comparison is always base against the current head, never the previous
|
|
22
|
-
push against the new one. A follow-up only ever moves the after side of the
|
|
23
|
-
comment, so what the comment claims can only grow to match what the branch
|
|
24
|
-
actually shows, and a reviewer who opens it midway through a review round
|
|
25
|
-
never reads a stale before image describing an intermediate commit nobody is
|
|
26
|
-
looking at anymore.
|
|
27
|
-
|
|
28
|
-
## What counts as evidence
|
|
29
|
-
|
|
30
|
-
A changed path qualifies when one of its segments is literally `evidence` and
|
|
31
|
-
its filename carries an image extension (`png`, `jpg`, `jpeg`, `gif`, `webp`,
|
|
32
|
-
`avif`, `svg`). The second half of that test exists because an `evidence/`
|
|
33
|
-
folder holds whatever else a project keeps beside its captures. This
|
|
34
|
-
repository's own tree carries eight `.md` files, two `.sh` scripts, a `.tsv`,
|
|
35
|
-
a `.json`, and an `.html` file against a single `.png`, and every one of them
|
|
36
|
-
would render as a broken image embed without the extension filter.
|
|
37
|
-
|
|
38
|
-
## What the record carries
|
|
39
|
-
|
|
40
|
-
The record groups every evidence path by state, the remainder of its
|
|
41
|
-
directory under the `evidence/` segment, and within a state by filename stem,
|
|
42
|
-
so a `before/hero.png` and an `after/hero.png` naming the same case group as
|
|
43
|
-
one entry, not two files. Each entry carries whether it existed at the base
|
|
44
|
-
commit, so the comment shows a base image or marks it new. Each `<img>` takes
|
|
45
|
-
its PNG width, at most 1000. `canon docs pr-evidence-layout` covers how the body
|
|
46
|
-
groups those entries by view.
|
|
47
|
-
|
|
48
|
-
`reason` on the record is what a caller branches on, not the exit code:
|
|
49
|
-
|
|
50
|
-
| Reason | What it means |
|
|
51
|
-
| ---------------------- | --------------------------------------------------------------------------------------- |
|
|
52
|
-
| `ok` | A body was rendered. `commentId` is set when a marked comment already exists. |
|
|
53
|
-
| `no-evidence` | No `evidence/` segment in the diff and no `--checklist` or `--preview`. A silent no-op. |
|
|
54
|
-
| `unreadable-checklist` | `--checklist` named a path that could not be read, or one holding nothing. |
|
|
55
|
-
| `gh-missing` | `gh` is not on the path, so no pull request could be resolved. |
|
|
56
|
-
| `gh-failed` | `gh` could not answer for this repository or branch, or read its comments. |
|
|
57
|
-
| `no-branch` | The pull request carries no head branch name. |
|
|
58
|
-
| `no-object-head` | The pull request object reported no head commit. |
|
|
59
|
-
| `no-base` | GitHub reported no merge base for the pull request. |
|
|
60
|
-
| `unreadable-changes` | GitHub could not list what the pull request changed. |
|
|
61
|
-
| `would-empty` | The render holds no cases and the marked comment holds some. No body. |
|
|
62
|
-
| `check-writes` | `--check` was passed with `--preview`, `--local`, or `--checklist`. |
|
|
63
|
-
|
|
64
|
-
`no-evidence` is not a refusal a caller reports. A project on a stack that
|
|
65
|
-
carries no evidence path, such as `base` or `python`, hits this reason on
|
|
66
|
-
every pull request and posts nothing, which is the correct behavior rather
|
|
67
|
-
than a gap.
|
|
68
|
-
|
|
69
|
-
Both `ok` and `no-evidence` also report what the marked comment already
|
|
70
|
-
shows a reviewer, each field present only when that comment holds it:
|
|
71
|
-
|
|
72
|
-
| Field | What it carries |
|
|
73
|
-
| ----------- | ----------------------------------------------------------------- |
|
|
74
|
-
| `preview` | The hosted `**Preview:**` address on the comment's address line. |
|
|
75
|
-
| `local` | The `**Local preview:**` address beside it. |
|
|
76
|
-
| `checklist` | The checklist between its delimiters, with any ticked boxes kept. |
|
|
77
|
-
| `boxes` | Each box's `number`, `text`, tick, `stamp`, and `isTaste`. |
|
|
78
|
-
|
|
79
|
-
These come from the comment already posted, never from the flags the call
|
|
80
|
-
passed, so a skill driving a review reads which address and which checklist a
|
|
81
|
-
reviewer has without parsing the comment itself. A checklist posted raw, which
|
|
82
|
-
only the fallback for a refused render does now, carries no marker, so the
|
|
83
|
-
record reports none of the three for it. Reading
|
|
84
|
-
them means the thread is read before the `no-evidence` answer too, so an
|
|
85
|
-
unreadable thread refuses as `gh-failed` on both reasons rather than
|
|
86
|
-
reporting the fields absent.
|
|
87
|
-
|
|
88
|
-
`ok` also carries `states`, the comparison the body renders as data: each
|
|
89
|
-
state's items with `path`, `stem`, `added`, and `width` and `baseWidth` when
|
|
90
|
-
read. `review-ui` matches a frame against it so it publishes no image the
|
|
91
|
-
worker's evidence already shows. `canon docs pr-frames` covers that store.
|
|
92
|
-
`widthUnread` lists a failed read as `head:<path>` or `base:<path>`.
|
|
93
|
-
|
|
94
|
-
## What `[number]` selects, and what it does not
|
|
95
|
-
|
|
96
|
-
Naming a number picks the pull request the whole record describes: its head
|
|
97
|
-
commit, its merge base, its changed set, and the marked comment to edit in
|
|
98
|
-
place. The changed paths and whether each was added or modified come from the
|
|
99
|
-
pull request's files endpoint, paged to the end, and the merge base comes from
|
|
100
|
-
the compare endpoint, so the record is the same from any checkout. A run from
|
|
101
|
-
the main worktree against a branch built elsewhere renders that branch's
|
|
102
|
-
comparison.
|
|
103
|
-
|
|
104
|
-
The trade is that the verb no longer sees evidence that is uncommitted or
|
|
105
|
-
unpushed, which the comment's head-pinned image links could not show anyway.
|
|
106
|
-
A path the pull request renamed or copied counts as added, since the new path
|
|
107
|
-
has no counterpart at the merge base, so a rename loses its before image and
|
|
108
|
-
reads as new. A path the pull request removed is dropped, since it has no
|
|
109
|
-
head image to show. A failed files read refuses as `unreadable-changes` rather
|
|
110
|
-
than rendering a short set, and a missing merge base refuses as `no-base`.
|
|
111
|
-
|
|
112
|
-
## A render never empties a comment that carries cases
|
|
113
|
-
|
|
114
|
-
When the render holds no cases and the marked comment holds some, the verb
|
|
115
|
-
refuses `would-empty` and prints no body. A render with no cases cannot tell a
|
|
116
|
-
case removed on purpose from a short read, so the destructive direction needs a
|
|
117
|
-
person: they edit the comment directly. The record keeps `commentId` and the
|
|
118
|
-
carried fields, so the caller can still find the comment. A comment holding
|
|
119
|
-
only a preview or a checklist has no cases to lose and still re-renders `ok`.
|
|
120
|
-
`no-evidence` without a flag returns before any render, so the guard touches
|
|
121
|
-
only `--preview`, `--local`, and `--checklist` calls.
|
|
122
|
-
|
|
123
|
-
## One comment, found by its own marker
|
|
124
|
-
|
|
125
|
-
Every body this verb renders ends with a trailing marker naming the head it
|
|
126
|
-
describes:
|
|
127
|
-
|
|
128
|
-
```markdown
|
|
129
|
-
<!-- pr-evidence: head=<sha> -->
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
`canon pr evidence` reads that marker back off every comment on the pull
|
|
133
|
-
request, the same way `canon pr review-state` reads its own marker off a
|
|
134
|
-
review body, and reports the REST id of whichever comment carries it as
|
|
135
|
-
`commentId`. A caller with no `commentId` posts a new comment. A caller
|
|
136
|
-
holding one edits that comment in place with a `PATCH` rather than posting a
|
|
137
|
-
second one.
|
|
138
|
-
|
|
139
|
-
Putting the lookup here, in the one place both `git-pr` and `git-followup`
|
|
140
|
-
call, is what keeps two close-out comments from landing beside each other the
|
|
141
|
-
way `review-pr` once posted, before that skill's own guard existed. It is
|
|
142
|
-
also why this verb renders the whole comment body rather than handing each
|
|
143
|
-
skill a record to format on its own: a fix to the table shape or the
|
|
144
|
-
details wrapper lands once, not twice.
|
|
145
|
-
|
|
146
|
-
## The preview line
|
|
147
|
-
|
|
148
|
-
Every body opens with `## Evidence`. Under it sits one address line carrying
|
|
149
|
-
whichever previews apply, joined by a middle dot:
|
|
150
|
-
|
|
151
|
-
```plaintext
|
|
152
|
-
## Evidence
|
|
153
|
-
|
|
154
|
-
**Preview:** <url> · **Local preview:** <url>
|
|
155
|
-
|
|
156
|
-
**Base:** [`<base>`](<base-commit-url>) · **Head:** [`<head>`](<head-commit-url>)
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
The Base and Head line follows only when the comment carries screenshots.
|
|
160
|
-
|
|
161
|
-
`--preview <url>` puts the branch's hosted address on that line, and a run
|
|
162
|
-
without it carries forward the address the marked comment already holds. With
|
|
163
|
-
no evidence in the diff and an address in hand, the body is the heading, the
|
|
164
|
-
address line, and the marker alone, reported as `ok`. `canon docs pr-preview`
|
|
165
|
-
covers where the address comes from.
|
|
166
|
-
|
|
167
|
-
A carried hosted address is dropped when a deploy workflow resolves and its
|
|
168
|
-
push path filter matches no path the pull request changed, since the site it
|
|
169
|
-
links shows none of the change. An explicit `--preview` is always kept.
|
|
170
|
-
|
|
171
|
-
The carry-forward reads every line above the commit line, the checklist, and
|
|
172
|
-
the comparison for each prefix, wherever it sits. A comment posted before the
|
|
173
|
-
heading opened the body, with each address on a line of its own at the top,
|
|
174
|
-
reads the same way, so an open pull request keeps its links on its first
|
|
175
|
-
re-render.
|
|
176
|
-
|
|
177
|
-
## The checklist line
|
|
178
|
-
|
|
179
|
-
`--checklist <path>` closes the body with a visual checklist, below the
|
|
180
|
-
comparison it annotates, so one comment carries the preview address, the
|
|
181
|
-
screenshots, and what a reviewer has to look at. The file is what
|
|
182
|
-
`canon:ui-checklist` writes to `.canon/tmp/handoff/ui-checklist/<slug>.md`, and
|
|
183
|
-
`git-pr` passes it here rather than posting it as a second comment.
|
|
184
|
-
|
|
185
|
-
A run without the option carries forward whatever checklist the marked comment
|
|
186
|
-
already holds, the same way the preview address is carried. That is what keeps
|
|
187
|
-
`git-followup`'s re-render after a push from dropping the checklist, since
|
|
188
|
-
`git-pr` deletes the handoff once the first post reports success and no later
|
|
189
|
-
call has a file to pass. `canon docs pr-tick` covers what a tick carries.
|
|
190
|
-
|
|
191
|
-
The option decides `no-evidence` on its own. A branch with a checklist and no
|
|
192
|
-
changed evidence image renders `ok` with a marked body holding the checklist,
|
|
193
|
-
so the checklist always lands in the one comment a later call finds and edits.
|
|
194
|
-
The raw post survives only as the caller's fallback when the render is refused.
|
|
195
|
-
A path that cannot be read, or one holding nothing, refuses as
|
|
196
|
-
`unreadable-checklist` rather than rendering without it: the caller deletes the
|
|
197
|
-
handoff once a post succeeds, so a silently dropped checklist is the only copy
|
|
198
|
-
gone.
|
|
199
|
-
|
|
200
|
-
## The local preview line
|
|
201
|
-
|
|
202
|
-
`--local <url>` adds `**Local preview:** <url>` to the address line, after the
|
|
203
|
-
hosted segment when there is one and alone when there is not. A run without the
|
|
204
|
-
option carries forward the local address the marked comment already holds, the
|
|
205
|
-
same as the other two.
|
|
206
|
-
|
|
207
|
-
The option does not turn `no-evidence` into `ok` on its own. A branch with a
|
|
208
|
-
dev server running and no rendered change would otherwise get a comment holding
|
|
209
|
-
a link and nothing else. Together with `--checklist` the link and the
|
|
210
|
-
checklist land in one comment.
|
|
211
|
-
`canon docs pr-local` covers where the address comes from and how the line is
|
|
212
|
-
removed at close.
|
|
213
|
-
|
|
214
|
-
## What a pull request is still owed
|
|
215
|
-
|
|
216
|
-
`--check` reads the same changed set and the same thread, renders no body, and
|
|
217
|
-
reports which steps of the ship chain that run after the pull request opens
|
|
218
|
-
never landed on it. It reads the pull request rather than any session's account
|
|
219
|
-
of what it ran, so a session that stopped after opening the pull request leaves
|
|
220
|
-
a branch the check can tell apart from one that needed neither step.
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
canon pr evidence 1341 --check --json
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
| Reason | What it means |
|
|
227
|
-
| --------- | ------------------------------------------------------------------ |
|
|
228
|
-
| `settled` | Nothing is owed. `owed` is empty. |
|
|
229
|
-
| `owed` | `owed` lists `evidence`, `preview`, or both, always in that order. |
|
|
230
|
-
|
|
231
|
-
- `evidence` is owed when the changed set carries an evidence image and no
|
|
232
|
-
comment carries the marker.
|
|
233
|
-
- `preview` is owed when the pull request has a marked comment or an evidence
|
|
234
|
-
change, a deploy workflow resolves in the checkout the verb runs from, its
|
|
235
|
-
push path filter matches a path the pull request changed, and the marked
|
|
236
|
-
comment carries no `**Preview:**` address. A `**Local preview:**` address
|
|
237
|
-
does not satisfy it. A project deploying nothing is never owed a preview,
|
|
238
|
-
and neither is a branch its deploy does not build from.
|
|
239
|
-
|
|
240
|
-
The record carries `owed`, `commentId` when a marked comment exists, and the
|
|
241
|
-
same `preview`, `local`, and `checklist` fields the other reasons carry, so a
|
|
242
|
-
caller reads one shape. It never carries `body`, so a writer branching on `ok`
|
|
243
|
-
and posting `body` cannot act on a check record. Passing `--preview`, `--local`,
|
|
244
|
-
or `--checklist` with it refuses as `check-writes` before any `gh` call, since
|
|
245
|
-
those ask a read to write.
|
|
246
|
-
|
|
247
|
-
The thread cannot separate a skipped preview step from a failed one. A pull
|
|
248
|
-
request whose deploy failed or timed out reads as owing a preview, and the
|
|
249
|
-
session that ran it holds the cause. A checklist-only branch posts a marked
|
|
250
|
-
comment, so it reads as owing a preview once that comment exists and a deploy
|
|
251
|
-
workflow resolves. The deploy workflow is read from the checkout rather than
|
|
252
|
-
the pull request's head, so one adding or removing its own reads trunk's.
|
|
253
|
-
|
|
254
|
-
An unreadable thread refuses as `gh-failed` rather than reporting `settled` off
|
|
255
|
-
a thread it never read. The check skips the merge base read, which only the
|
|
256
|
-
render needs, so it never refuses `no-base`. The orchestrator's draft lift is
|
|
257
|
-
the caller, and lifts only on `settled`, so a refusal holds it the same as
|
|
258
|
-
`owed` does.
|
|
259
|
-
|
|
260
|
-
## When the comment opens
|
|
261
|
-
|
|
262
|
-
The comment opens every block while it carries six images or fewer and closes
|
|
263
|
-
every block past that. A line under `## Evidence` names the compared base and
|
|
264
|
-
head as linked short shas, which tells a reader whether the images match the
|
|
265
|
-
latest push. `canon docs pr-evidence-layout` covers the count and the blocks.
|
|
266
|
-
|
|
267
|
-
## What the comment still leaves to GitHub
|
|
268
|
-
|
|
269
|
-
GitHub already draws its own before-and-after comparison on the Files Changed
|
|
270
|
-
tab for any tracked image that changed. This comment does not make that view
|
|
271
|
-
redundant. The diff view shows what moved between two commits a reader has
|
|
272
|
-
already opened, and the comment is what lets a reader see the same comparison
|
|
273
|
-
without opening it at all.
|
package/docs/agents/pr-frames.md
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: The pull request frame store
|
|
3
|
-
description: How canon pr frames pushes a UI review frame to a never-merged branch through the GitHub API and returns a branch-path link, which ref it writes, the pass segment that keeps an earlier image fixed, the refusal reasons it names, and how --drop and --prune rewrite the branch so a dropped frame leaves history
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# The pull request frame store
|
|
7
|
-
|
|
8
|
-
`canon pr frames` gives a review comment an image it can embed. `review-ui`
|
|
9
|
-
drives a pull request's checklist and captures a frame per box, and a frame
|
|
10
|
-
on the reviewer's disk resolves for nobody else. The verb pushes one frame to
|
|
11
|
-
the `canon/frames` branch and returns a link to its path there.
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
canon pr frames 1341 --add frames/3.png --box 3 --head <sha> --pass 20261002T154450Z --json
|
|
15
|
-
canon pr frames 1341 --add frames/3-dark.png --box 3 --theme dark --head <sha> --pass 20261002T154450Z --json
|
|
16
|
-
canon pr frames 1341 --drop --json
|
|
17
|
-
canon pr frames --prune 30 --json
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## What it writes
|
|
21
|
-
|
|
22
|
-
An add writes `refs/heads/canon/frames` and no other ref. Every call goes
|
|
23
|
-
through the GitHub git data API, being blobs, trees, commits, and that one ref,
|
|
24
|
-
so nothing is checked out, no worktree is entered, and neither `main` nor any
|
|
25
|
-
branch a pull request holds is touched. The branch never merges.
|
|
26
|
-
|
|
27
|
-
A frame lands at `pr-<number>/<short-head>/<pass>/box-<n>.png`, or at
|
|
28
|
-
`box-<n>-<theme>.png` when `--theme` names `dark` or `light`, so two shots of
|
|
29
|
-
one box in one pass never take the same path. A frame without `--theme` keeps
|
|
30
|
-
the plain form. `--head` names
|
|
31
|
-
the commit the pass drove, 7 to 40 lowercase hex characters, and defaults to
|
|
32
|
-
the head the pull request object reports. `--pass` is the instant the pass
|
|
33
|
-
started, in compact UTC as `date -u +%Y%m%dT%H%M%SZ` prints it, which
|
|
34
|
-
`review-ui` records once at its first step. A second pass at the same head and
|
|
35
|
-
box therefore writes a new file rather than replacing the image an earlier
|
|
36
|
-
comment shows, which matters when a preview is minted again at one head.
|
|
37
|
-
|
|
38
|
-
`link` uses the same `blob/<ref>/<path>?raw=true` form as the evidence comment,
|
|
39
|
-
naming the `canon/frames` branch rather than a commit. Every drop rewrites the
|
|
40
|
-
branch, and a link pinned to a commit would stop resolving for every other pull
|
|
41
|
-
request's frames once GitHub collects the commit it names. A path link lives
|
|
42
|
-
exactly as long as its file, so it survives every rewrite that drops another
|
|
43
|
-
pull request and ends only when its own is dropped.
|
|
44
|
-
|
|
45
|
-
The first `--add` creates the branch with a root commit holding the
|
|
46
|
-
frame, so a project needs no setup. An add only fast-forwards the ref. When
|
|
47
|
-
another writer moved it between the read and the move, the add rebuilds on the
|
|
48
|
-
new tip, up to three times, before refusing as `ref-conflict`.
|
|
49
|
-
|
|
50
|
-
Only a frame of the address the pass drove belongs here. The branch is as
|
|
51
|
-
public as the repository, so a frame of a private or pre-release state would
|
|
52
|
-
be published with it.
|
|
53
|
-
|
|
54
|
-
## What the record carries
|
|
55
|
-
|
|
56
|
-
`reason` on the record is what a caller branches on, not the exit code:
|
|
57
|
-
|
|
58
|
-
| Reason | What it means |
|
|
59
|
-
| ------------------ | -------------------------------------------------------------------------------- |
|
|
60
|
-
| `ok` | An add pushed, or a drop or prune finished, including one that removed nothing. |
|
|
61
|
-
| `bad-mode` | Not exactly one of `--add`, `--drop`, `--prune`, or a number with `--prune`. |
|
|
62
|
-
| `no-number` | `--add` or `--drop` named no pull request. |
|
|
63
|
-
| `bad-box` | `--add` carried no positive `--box`. |
|
|
64
|
-
| `bad-head` | `--head`, or the head the pull request reported, is not a 7 to 40 character sha. |
|
|
65
|
-
| `bad-pass` | `--add` carried no `--pass` stamp in compact UTC. |
|
|
66
|
-
| `bad-theme` | `--theme` is neither `dark` nor `light`, or came without `--add`. |
|
|
67
|
-
| `bad-days` | `--prune` carried no positive number of days. |
|
|
68
|
-
| `unreadable-frame` | The `--add` file is missing, empty, or not a PNG. Nothing is called. |
|
|
69
|
-
| `read-only` | GitHub refused a write with 403 or 404, which is what a fork's token gets. |
|
|
70
|
-
| `unreadable-tip` | The branch exists and could not be read. |
|
|
71
|
-
| `push-failed` | A write failed partway and the ref did not move. |
|
|
72
|
-
| `ref-conflict` | Another writer kept moving the ref through every attempt. |
|
|
73
|
-
| `no-object-head` | No `--head` and the pull request reported none. |
|
|
74
|
-
| `gh-missing` | `gh` is not on the path. |
|
|
75
|
-
| `gh-failed` | `gh` could not name the repository or read the pull request. |
|
|
76
|
-
|
|
77
|
-
An add's `ok` record carries `link`, `commit`, `path`, `box`, `theme` when one was passed, `head`, `pass`,
|
|
78
|
-
and `created`, which is true when the add made the branch. A drop's carries
|
|
79
|
-
`removed`, the pull requests whose folders went, plus `commit` for the rewrite
|
|
80
|
-
or `deleted` when it emptied the branch. A prune adds `kept` and `unread`.
|
|
81
|
-
|
|
82
|
-
`review-ui` reads every reason but `ok` as a cue to describe the frame in words
|
|
83
|
-
and name the reason, so a refused push never fails the pass.
|
|
84
|
-
|
|
85
|
-
## Dropping frames
|
|
86
|
-
|
|
87
|
-
A plain delete commit would keep every image reachable through history, so
|
|
88
|
-
`--drop` and `--prune` write one root commit holding everything else and
|
|
89
|
-
force-move the ref to it. A rewrite that leaves the branch empty deletes it,
|
|
90
|
-
and the next add recreates it. Dropping a pull request with no frames, or on a
|
|
91
|
-
missing branch, reports `ok` with nothing removed, so a scheduled run never
|
|
92
|
-
fails on an empty branch.
|
|
93
|
-
|
|
94
|
-
`--prune <days>` reads every `pr-<n>/` folder, asks GitHub for each pull
|
|
95
|
-
request's state, and drops every one reading closed with a close date more
|
|
96
|
-
than that many days ago, in a single rewrite. It keeps one still open, one
|
|
97
|
-
reopened after closing, one closed exactly the given days ago, and one whose
|
|
98
|
-
state could not be read, listing that last kind under `unread`.
|
|
99
|
-
|
|
100
|
-
## The legacy branch
|
|
101
|
-
|
|
102
|
-
Frames lived on `canon-frames` before the rename to `canon/frames`. An add
|
|
103
|
-
never writes it. `--drop` and `--prune` also run against it after the
|
|
104
|
-
current branch, remove only, and delete it once empty. `--prune` drains it
|
|
105
|
-
as its pull requests expire, and `--drop` clears one pull request at once.
|
|
106
|
-
The record carries `legacy: true` when that
|
|
107
|
-
pass changed the ref, and its `removed` list folds both branches in, naming
|
|
108
|
-
a pull request once. A missing or unreadable legacy ref never fails a run
|
|
109
|
-
the current branch finished.
|
|
110
|
-
|
|
111
|
-
A link minted before the rename points at `blob/canon-frames/...` and keeps
|
|
112
|
-
resolving until its pull request has been closed 30 days or `--drop` runs.
|
|
113
|
-
|
|
114
|
-
This repository runs `--prune 30` daily from
|
|
115
|
-
`.github/workflows/pr-frames-cleanup.yml`. A frame's file stays on the branch
|
|
116
|
-
until its own pull request has been closed for 30 days, so a link in a review
|
|
117
|
-
comment keeps resolving for about a month after its pull request closes,
|
|
118
|
-
whatever other pull requests the branch drops in between. A target project
|
|
119
|
-
carries no such workflow yet and keeps its frames until someone runs `--drop`.
|
|
120
|
-
|
|
121
|
-
## What a rewrite does not do
|
|
122
|
-
|
|
123
|
-
A force-move leaves the old commits unreachable without purging them. GitHub
|
|
124
|
-
serves an unreachable commit by sha until it collects it, so a dropped frame
|
|
125
|
-
stays reachable to anyone holding a sha from an earlier record, and a frame
|
|
126
|
-
holding sensitive content needs a purge request to GitHub. Its path link stops
|
|
127
|
-
resolving at the drop, since the branch no longer carries the file.
|
|
128
|
-
|
|
129
|
-
A drop racing an add can lose the add's frame, since GitHub's ref update has no
|
|
130
|
-
compare-and-swap for a force-move. The drop builds from the tip it reads, and
|
|
131
|
-
the window is the length of one rewrite.
|
package/docs/agents/pr-lift.md
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: The pull request draft lift
|
|
3
|
-
description: How canon pr lift removes the draft mark once the reviews, evidence, standing, and CI all read clear at the head, the gate order and what each reads, the wait on a pending run, the re-read before the write, the refusal reasons it names, and what --check reports
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# The pull request draft lift
|
|
7
|
-
|
|
8
|
-
`canon pr lift` takes a pull request out of draft. It reads the gate itself, so
|
|
9
|
-
any session that closes a review can run it, and nobody has to judge whether a
|
|
10
|
-
message asking for the lift came from someone entitled to ask.
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
canon pr lift 1341 --json
|
|
14
|
-
canon pr lift 1341 --check --json
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
With no number it resolves the one open pull request on the checked-out branch.
|
|
18
|
-
The ship chain marks every pull request a draft, and this is the verb that
|
|
19
|
-
undoes it.
|
|
20
|
-
|
|
21
|
-
## What it reads
|
|
22
|
-
|
|
23
|
-
Five gates, read in this order. The first four need no wait, so they all run
|
|
24
|
-
before the check runs are read.
|
|
25
|
-
|
|
26
|
-
| Gate | Clear when |
|
|
27
|
-
| ---------- | --------------------------------------------------------------------------------------------- |
|
|
28
|
-
| `review` | The newest `## Review` pass is closed, and its marker names the head. |
|
|
29
|
-
| `ui` | The newest `## UI review` verdict is closed at the head. Binds only where a checklist exists. |
|
|
30
|
-
| `evidence` | `canon pr evidence --check` reads `settled`, meaning no post-pull-request step is owed. |
|
|
31
|
-
| `standing` | The head merges into the freshly fetched base, and the base moved no path the branch writes. |
|
|
32
|
-
| `ci` | Every check run on the branch tip concluded and none failed. |
|
|
33
|
-
|
|
34
|
-
The head is the branch tip read from the remote, not the pull request object's
|
|
35
|
-
head, which trails a push by up to a minute. A review marker names the commit
|
|
36
|
-
the reviewer read, and it covers the head when it is that commit or a prefix of
|
|
37
|
-
it.
|
|
38
|
-
|
|
39
|
-
The UI gate binds only when `canon pr evidence --check --json` carries a
|
|
40
|
-
`checklist` field. The verb branches on that field and not on the exit, so a
|
|
41
|
-
branch with no rendered surface owes no UI review.
|
|
42
|
-
|
|
43
|
-
A review pass with no read-time marker refuses as `review-unmarked`. Its covered
|
|
44
|
-
commit would be the stamp GitHub wrote at submission, which the marker exists to
|
|
45
|
-
replace, and lifting on it reintroduces the defect `canon pr review-state`
|
|
46
|
-
documents.
|
|
47
|
-
|
|
48
|
-
## The wait
|
|
49
|
-
|
|
50
|
-
A pending CI run is waited on rather than refused. `--wait <seconds>` bounds it,
|
|
51
|
-
defaulting to 1200, and the check runs are read every 30 seconds until one of
|
|
52
|
-
four things happens:
|
|
53
|
-
|
|
54
|
-
- every run passed, and the verb goes on to the write
|
|
55
|
-
- a run failed, which refuses `ci-failing` at once
|
|
56
|
-
- the branch conflicts with its base, which refuses `ci-conflicted` at once,
|
|
57
|
-
since no run starts for a conflicted branch and the wait could not end
|
|
58
|
-
- the deadline passed, which refuses `ci-timeout`
|
|
59
|
-
|
|
60
|
-
A refusal on any of the first four gates comes before the wait starts. A code
|
|
61
|
-
reviewer whose UI partner is still driving refuses `ui-open` immediately
|
|
62
|
-
instead of holding a turn through a CI run.
|
|
63
|
-
|
|
64
|
-
## The re-read
|
|
65
|
-
|
|
66
|
-
A push during the wait moves the head off the commit every earlier gate
|
|
67
|
-
cleared. After the wait, and immediately before the write, the verb reads the
|
|
68
|
-
pull request, the branch tip, and the reviews again. A tip that moved refuses
|
|
69
|
-
`head-moved`, and a review that opened refuses with its own reason. The
|
|
70
|
-
standing is read again as well, so a sibling merging during the wait refuses
|
|
71
|
-
`standing-stale` instead of lifting a branch that read fresh before it. A pull
|
|
72
|
-
request already out of draft by then reports `already-ready`.
|
|
73
|
-
|
|
74
|
-
Two reviewers closing within seconds of each other can each read the other's
|
|
75
|
-
review as still open and both refuse. The re-read narrows that window and does
|
|
76
|
-
not close it, so a draft whose reviews both read closed is the controlling
|
|
77
|
-
session's to lift.
|
|
78
|
-
|
|
79
|
-
## The write
|
|
80
|
-
|
|
81
|
-
The lift is the `markPullRequestReadyForReview` GraphQL mutation, because the
|
|
82
|
-
REST pull request update carries no draft field. It is the one GraphQL call the
|
|
83
|
-
verb makes, and every read stays on REST. The verb reads `isDraft` back from the
|
|
84
|
-
mutation's answer, and a response that does not say `false` refuses `gh-failed`
|
|
85
|
-
rather than reporting a lift.
|
|
86
|
-
|
|
87
|
-
A cloud session's proxy refuses GraphQL, so a reviewer running there reaches
|
|
88
|
-
`gh-failed` on the write and hands the lift to the controlling session.
|
|
89
|
-
|
|
90
|
-
## What it reports
|
|
91
|
-
|
|
92
|
-
`reason` on the record is what a caller branches on. Exit 0 covers `lifted` and
|
|
93
|
-
`already-ready`, so the second of two reviewers to close owes nobody a message.
|
|
94
|
-
Every other reason exits 1.
|
|
95
|
-
|
|
96
|
-
| Reason | What it means |
|
|
97
|
-
| ------------------- | ---------------------------------------------------------------------- |
|
|
98
|
-
| `lifted` | The mark came off. |
|
|
99
|
-
| `already-ready` | The pull request was not a draft. Nothing is written. |
|
|
100
|
-
| `clear` | Under `--check`, every gate reads clear. |
|
|
101
|
-
| `pull-closed` | The pull request is closed. |
|
|
102
|
-
| `review-missing` | The thread carries no code review. |
|
|
103
|
-
| `review-open` | The newest code review is open. |
|
|
104
|
-
| `review-unmarked` | The newest code review carries no marker. |
|
|
105
|
-
| `review-behind` | The newest code review closed on an earlier commit than the head. |
|
|
106
|
-
| `ui-missing` | A checklist exists and no UI review has been posted. |
|
|
107
|
-
| `ui-open` | The newest UI review is open. |
|
|
108
|
-
| `ui-unmarked` | The newest UI review carries no head marker. |
|
|
109
|
-
| `ui-behind` | The newest UI review closed on an earlier commit than the head. |
|
|
110
|
-
| `evidence-owed` | The evidence check reads `owed`. |
|
|
111
|
-
| `standing-stale` | The base moved under a path the branch writes. |
|
|
112
|
-
| `standing-conflict` | The head does not merge cleanly into the base. |
|
|
113
|
-
| `standing-unknown` | The head or base did not resolve, which a fork or deleted head leaves. |
|
|
114
|
-
| `ci-pending` | Under `--check`, a run has yet to conclude. |
|
|
115
|
-
| `ci-failing` | A check run failed. |
|
|
116
|
-
| `ci-conflicted` | The branch conflicts, so no run will start. |
|
|
117
|
-
| `ci-timeout` | A run was still pending when `--wait` ran out. |
|
|
118
|
-
| `head-moved` | A push landed during the wait. |
|
|
119
|
-
| `gh-failed` | A read or the write was refused, so nothing is reported as lifted. |
|
|
120
|
-
|
|
121
|
-
`standing-unknown` waits on a person, matching the orchestrator poll's own rule
|
|
122
|
-
for a head it cannot resolve.
|
|
123
|
-
|
|
124
|
-
## `--check`
|
|
125
|
-
|
|
126
|
-
`--check` reports every gate and writes nothing. It reads the check runs once
|
|
127
|
-
and does not wait, so a pending run reports `ci-pending`. The record carries a
|
|
128
|
-
`gates` array with each gate's name, whether it is clear, and its reason, so a
|
|
129
|
-
caller sees every gate that blocks and not the first alone.
|
|
130
|
-
|
|
131
|
-
The orchestrator's poll and a session deciding whether to run the verb read the
|
|
132
|
-
same answer this way, rather than each restating the gate.
|
package/docs/agents/pr-local.md
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: The pull request local preview
|
|
3
|
-
description: How canon pr local finds the server a worktree is running, why a server in another worktree is never reported, the refusal reasons it names, and how a close workflow drops the address line with --remove
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# The pull request local preview
|
|
7
|
-
|
|
8
|
-
`canon pr local` reports the `localhost` address of the dev server the current
|
|
9
|
-
worktree is running. `git-pr` calls it ahead of the evidence comparison and
|
|
10
|
-
passes the address through `canon pr evidence --local`, so a reviewer on the
|
|
11
|
-
same machine gets the running branch to click into beside the screenshots and
|
|
12
|
-
the checklist. A workflow on the pull request's `closed` event calls it again
|
|
13
|
-
with `--remove`, which drops the address line and leaves nothing in its place.
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
canon pr local --json
|
|
17
|
-
canon pr local 1341 --remove --json
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## How it finds the server
|
|
21
|
-
|
|
22
|
-
The verb reads every TCP socket in `LISTEN` with the process that owns it. It
|
|
23
|
-
keeps a socket when that process's working directory sits inside the
|
|
24
|
-
worktree's toplevel, including a subfolder, since some tools change into one
|
|
25
|
-
before they listen. It then requests `/` on each kept port and reports the
|
|
26
|
-
lowest one serving an HTML page.
|
|
27
|
-
|
|
28
|
-
The HTML test is there because a working tree often holds more than one
|
|
29
|
-
listener. A test runner's own server, or a dev server's reload socket, answers
|
|
30
|
-
HTTP too, and a reviewer opening either gets a bare 404 rather than the branch.
|
|
31
|
-
|
|
32
|
-
Sockets are read from `/proc/net/tcp` and `/proc/net/tcp6` wherever they exist,
|
|
33
|
-
matched against each process's `fd` table, and through `lsof` on a machine
|
|
34
|
-
without them. Linux reads `/proc` even with `lsof` installed, since `lsof` 4.95
|
|
35
|
-
drops a process whose truncated name holds an unmatched `(`, which is what
|
|
36
|
-
Next's `next-server (vX.Y.Z)` title is cut down to. A machine with neither
|
|
37
|
-
refuses as `no-listener-reader`.
|
|
38
|
-
|
|
39
|
-
The port is never derived from the worktree. A port helper needs a per-stack
|
|
40
|
-
base port the toolkit cannot know, and a server started by hand or by an
|
|
41
|
-
earlier session would not match it anyway.
|
|
42
|
-
|
|
43
|
-
## Why another worktree's server is never reported
|
|
44
|
-
|
|
45
|
-
A server running in a different worktree shows a different branch, and a link
|
|
46
|
-
to it on this pull request would show a reviewer the wrong code.
|
|
47
|
-
|
|
48
|
-
- A sibling linked worktree sits outside this one's toplevel, so its process
|
|
49
|
-
never matches.
|
|
50
|
-
- The main checkout's server, read from a linked worktree, sits outside the
|
|
51
|
-
linked worktree's toplevel for the same reason.
|
|
52
|
-
- A linked worktree's server, read from the main checkout, sits inside the main
|
|
53
|
-
toplevel. The verb excludes everything under `.claude/worktrees/` for that
|
|
54
|
-
case alone.
|
|
55
|
-
|
|
56
|
-
## What the record carries
|
|
57
|
-
|
|
58
|
-
`reason` on the record is what a caller branches on, not the exit code:
|
|
59
|
-
|
|
60
|
-
| Reason | What it means |
|
|
61
|
-
| -------------------- | --------------------------------------------------------------------- |
|
|
62
|
-
| `ok` | A server answered. `url` carries the address and `port` the port. |
|
|
63
|
-
| `no-server` | Nothing inside this worktree served an HTML page. |
|
|
64
|
-
| `no-listener-reader` | Neither `lsof` nor `/proc` is available, so no socket could be read. |
|
|
65
|
-
| `removed` | `--remove` dropped the address line from the evidence comment. |
|
|
66
|
-
| `no-comment` | `--remove` found no comment carrying the evidence marker. |
|
|
67
|
-
| `no-line` | `--remove` found the comment but no address line on it. |
|
|
68
|
-
| `gh-missing` | `--remove` needs `gh` and it is not on the path. |
|
|
69
|
-
| `gh-failed` | `--remove` could not read the comments or could not edit the comment. |
|
|
70
|
-
|
|
71
|
-
The exit is 0 on `ok` and on every `--remove` outcome that finished, including
|
|
72
|
-
the two no-ops, and 1 on every refusal. A caller on an older binary gets an
|
|
73
|
-
unknown-subcommand error instead of a record, which `git-pr` reads as a skip.
|
|
74
|
-
|
|
75
|
-
## Removing the link at close
|
|
76
|
-
|
|
77
|
-
The link goes dead once the branch's server stops, and nothing on the pull
|
|
78
|
-
request says so. `--remove` runs on the pull request's `closed` event, merged or
|
|
79
|
-
abandoned, from a workflow seeded into every target:
|
|
80
|
-
|
|
81
|
-
```yaml
|
|
82
|
-
on:
|
|
83
|
-
pull_request:
|
|
84
|
-
types: [closed]
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
It reads the comment carrying the `pr-evidence` marker, drops the address line
|
|
88
|
-
under `## Evidence`, the hosted `**Preview:**` segment and the
|
|
89
|
-
`**Local preview:**` segment together, and edits the comment itself through
|
|
90
|
-
`gh api`. The hosted link goes too because the deploy workflow deletes the
|
|
91
|
-
branch's preview deployments on the same close. No note replaces the line, and
|
|
92
|
-
the blank line it sat on goes with it so no gap doubles under the heading. A
|
|
93
|
-
comment in the older layout, with each address on its own line at the top,
|
|
94
|
-
loses both lines the same way.
|
|
95
|
-
|
|
96
|
-
The verb writes here rather than handing a body back, because its caller is a
|
|
97
|
-
workflow with no session to post one. Every other byte of the comment stays as
|
|
98
|
-
it was, which keeps the marker, the checklist delimiters, and any ticked box
|
|
99
|
-
intact. A second run finds no line and reports `no-line`.
|
|
100
|
-
|
|
101
|
-
A fork pull request gets a read-only token, so the workflow skips the edit with
|
|
102
|
-
a notice rather than failing the close.
|
|
103
|
-
|
|
104
|
-
## What this does not cover
|
|
105
|
-
|
|
106
|
-
The link can still go dead while the pull request is open, such as when the
|
|
107
|
-
session holding the server retires. Only the close is covered, and a re-render
|
|
108
|
-
after a push carries the line forward whether the server still answers or not.
|
|
109
|
-
|
|
110
|
-
`canon docs pr-preview` covers how the hosted address is minted and when it is
|
|
111
|
-
refused.
|