Repository navigation
feat(ci): deliver the changeset claim re-read onto the pull request (objectui#9140) - #9581
Conversation
`check-changeset-claims` calls its finding a REQUEST TO READ, and the request was addressed to a job log nobody opens on a green check: re-run over the five live instances of the shape it exists for, it named four and none of the four was acted on. The finding is now posted as a comment on the pull request, through the channel the Console Performance Budget report already uses — `actions/github-script` against the issue-comments API, on the `pull-requests: write` grant this repository already holds, declared on this job alone so the declaration gate beside it keeps a read-only token. Report-only is unchanged and pinned: exit 0 on findings, not a required context, and the comment says both in its own opening lines. One comment per pull request, updated in place. The marker it finds itself by is the first line of the body, in plain text rather than a hidden HTML comment: this repository has measured that GitHub deletes tag-shaped fragments from a stored body, first-line HTML comments included, and a marker that vanishes makes every re-run stack another comment. Quoted changeset prose is rewritten for the same sanitizer on the way out, and says so when it was. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
…deliver ⛔ Reverted in the next commit. The director's ruling requires one MEASURED delivery on a real pull request; this pull request's own diff names no file any pending changeset spells, so without a probe the new step would correctly post nothing and the measurement would be an assertion instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
|
changeset-claim-re-read ✅ Nothing pending names a file this change touchesAn earlier revision of this pull request did. That request to re-read does not apply to the current diff. This comment is updated in place on every re-run rather than posted again, so the thread does not grow one per push. Compared the checked-out tree with |
…surement ⛔ Reverted with its sibling in the next commit. It moves the finding set from 2 pending changesets to 6, so the re-run can be observed UPDATING the comment the previous run created rather than stacking a second one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
Both probes reverted. Their purpose was the ruling's "one measured delivery on a real pull request", and it is measured: the comment was CREATED on the first leg, UPDATED IN PLACE on the second (same comment id, same `created_at`, one comment on the thread), and this leg drives it to its resolved state. The diff from here is the implementation alone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
`markdown-test-inputs` reported this file as `unadjudicated-test`: its fixture named `.changeset/7165-grid-dependent-values.md`, a declaration this repository actually carries, and the scanner offers exactly the literals that EXIST in the tree. ⛔ The fix is NOT a ledger entry. `pnpm changeset:version` deletes pending declarations, so an entry naming one becomes a `stale-not-read` finding the moment that changeset ships — reddening the post-version tree validation on every scheduled release run afterwards. That is the defect objectui#9472 just removed from two other test files, and adding a third would reintroduce it. The fixtures name synthetic declarations instead, under a `fixture-` prefix belonging to neither namespace a committed name can come from: `pnpm changeset` generates adjective-animal-verb, and this repository commits issue-number-slug. The scanner now offers nothing for this file, so it leaves the candidate set entirely and no ledger entry is owed or can go stale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015h79niBMyoB1xcaQje3uiz
⛔ RED —
|
Fixes #9140
Director ruling, comment
5682891844(batch #136 item 2, letter B, maintainer 「同意」):check-changeset-claimsfindings are delivered, not archived. On a pull request CI runs thegate against the PR's merge base and head and, when it names a pending changeset the diff may have
falsified, posts the finding as a comment on that PR — through the channel the Console Performance
Budget report already uses.
⛔ Report-only did not move. Exit 0 on findings, not a required context, nothing blocks. Letter
C stays fenced, letter A stays refused, and the
--auditcensus from PR objectui#9410 isuntouched — the coordinate is ⛔ not widened. Delivery changes only where the finding is read.
What landed
scripts/check-changeset-claims.mjs--json FILEhand-off: this run's finding set, written once, by the run that printed the logscripts/render-changeset-claims-comment.mjs.github/workflows/changeset-presence.ymlpull-requests: write, a render step and a delivery stepscripts/__tests__/render-changeset-claims-comment.test.tsscripts/__tests__/check-changeset-claims.test.tscontent/docs/guide/ci-cd-pipeline.mdThe three measurements the ruling asked for
1. The
pull-requests: writegrant is the existing one, ⛔ not a new permission. It is thesame
GITHUB_TOKENscopeperformance-budget.ymlposts the budget report with; four otherworkflows here hold it too (
labeler.yml,changeset-release.yml,cross-repo-issue-closer.yml,dependabot-auto-merge.yml). No new secret, no personal token, no GitHub App, and ⛔ nopull_request_target— pinned by a test.permissions:per workflow and per job, so there is no repository-wide grant to inherit and this is a new
line in
changeset-presence.yml. What the ruling fenced — a permission this repository does notalready give a gate job — is not required. It is declared on the
changeset-claimsjob alone, sothe declaration gate beside it keeps its read-only token.
2. "Against the PR's merge base and head" was free. The gate already resolves its base as the
merge base with the target branch and already accepts an explicit pair;
actions/checkouton apull_requestevent checks out the merge result. Nothing in the tree resolution changed. ⇒ the"is this a redesign" fork in the dispatch did not open.
3. The budget report is the channel, and only the channel. It posts with
actions/github-scriptandgithub.rest.issues.createComment— and it always creates: nomarker, no update, one comment per run. So the ruling's "one comment per PR, updated in place,
⛔ not stacked" is an addition here, ⛔ not a copy. What is reused is the channel, the retry and
continue-on-errorshape, and the render-in-a-script-so-it-can-be-unit-tested discipline.⛔ Why the marker is plain text and not a hidden HTML comment
The usual shape for "find my own previous comment" is a hidden HTML-comment marker. In this
repository that shape is measured not to work: AGENTS.md records that GitHub deletes tag-shaped
fragments from a stored body, that backticks and fenced blocks do not protect them, and that an
HTML comment alone on the first line is eaten with them.
A marker that vanishes does not degrade gracefully — every re-run fails to find its predecessor and
posts again, which is exactly the stacking the ruling forbids. So the marker is the first line of
the body in plain text, it renders visibly, and the workflow reads it off the body it is about to
post rather than carrying a second copy.
Same sanitizer, second half: the comment quotes a paragraph of somebody else's changeset, and that
prose routinely names components in angle brackets. Those spans are rewritten to
ANGLE-BRACKETS(name)on the way out, and the comment says so — but only when the rewrite actuallyfired, so a standing disclaimer never teaches readers to discount a verbatim quote.
The probe commits, and why they are here
This pull request's own diff names no file any of the 1,597 pending changesets spells, so the new
step would correctly post nothing — and the ruling requires one measured delivery, not an
assertion. Commit 2 is a one-shot probe: six comment lines appended to
scripts/check-changeset-presence.mjs, a file two pending changesets name in backticks. Commit 3reverts it, and the revert is itself the second measurement — the same comment updated in place to
its resolved state, ⛔ not a second comment.
⇒ The delivered comment on this pull request is the measurement. The run-by-run reading (comment
id, comment count per leg) is in the report comment on issue objectui#9140; this body is written
once and ⛔ not edited afterwards, because a
PATCHhere drops the session reference from thefooter and appends a second one.
Local verification
npx vitest runover the seven test files that read a file this diff touches — 288 passed,including the 59 across the two files that own this gate.
pnpm type-check:scriptsexit 0;--listFilesconfirms both new files are in that program(⛔ not excluded as tests).
pnpm lint:rootexit 0, 0 errors.check:changeset-claims,check:required-check-set,check:action-ref-convention,check:control-bytes,check:unreferenced-sources.node scripts/check-governed-queue-guard.mjs --test— NOT GOVERNED, 4 paths, none matched.node scripts/check-changeset-presence.mjs— no changeset owed; nothing published moved, whichis the measurement behind
skip-changesetrather than a judgement call.check:doc-snippetsandcheck:doc-examplesare NOT MEASURED locally: both refuse to runwithout a full package build (
PREREQUISITE NOT MET), and this diff adds no fenced snippet.Declared to CI.
Acceptance notes
render-budget-comment.mjsstacks one comment per run on everypackages/**pull request, withno marker and no in-place update. Out of scope here and ⛔ not filed: noted only, since this
change now puts a working in-place mechanism next to it in the same repository.
runGateincheck-changeset-claims.test.tsdropped stderr on the success path, so a harnessreading a green run could not see a warning the gate prints. Fixed in place — it is the same
defect class as this card and one line of the same file.
Generated by Claude Code