labels-reconcile: the blind sweep on incubator survived the permissions fix — and the read swallows the reason #100
Replies: 4 comments
|
Outcome: accept — #101 is minted for the half that had no open question. Part (1) is now a work order: capture Part (2) stays open here, and this thread stays open with it. Nothing about the fork-visibility hypothesis has been minted, deliberately: "private repo ⇒ permissions not implied" and "private repo ⇒ the head repo is unreadable at any permission" still both fit the evidence, and #101 exists precisely so the next incubator sweep answers that off a run instead of off my inference. Minting a REST rewrite today would hand a builder the same guess that produced a merged fix for the wrong defect. Sequence from here: #101 lands and releases → incubator's caller picks it up → one sweep → triage reports the actual stderr back into this thread → (2) converges on a fact. @danmt — nothing needed from you on this one unless you disagree with the order. |
|
Status, not a new outcome — part (1) has landed and part (2)'s wait now has a #101 is closed (PR #106, merged 08:24Z). Part (2) still waits on a fact, and the fact still has to come off an So the sequence in my accept comment above reads, concretely:
Nothing to do today, and nothing new is owed by anyone — the thread simply |
|
The fact arrived, and it converges part (2). The five-step sequence above completed this evening, faster than the comment that wrote it expected:
Minted from the paste: incubator#60 — Deliberately not minted yet, on this repo: the hint text in This thread has done what it exists for — part (1) shipped the reason-printing, part (2) got a reason precise enough to mint from on first read. I close it out when incubator#60's post-merge sweep lands, with the ceremony docs issue or the reopened read question, whichever the log says. |
|
Closing as resolved — the confirming sweep landed, the log said "fixed", and the ceremony issue it gated is minted. The close-out condition from my 19:16Z comment is met:
The thread's full arc, for the record: part (1) shipped as #101 / PR #106 (the reason-printing that made part (2) answerable), part (2) converged on the run's own words rather than an inference, and the doc fix waited for the confirming sweep exactly so it would write a proven contract instead of a hypothesis. Nothing further is owed here. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Consumer-side report from heavy-duty/incubator, the family's only private consumer. Everything
below re-verified 2026-07-24 00:07–00:08Z.
#95 diagnosed incubator's permanently blank
state:*axis as the caller stub under-grantingchecks/statuses, and fixed the stub. Theconsumer half landed as incubator#48 /
PR #49, merged 2026-07-23 23:42:39Z.
The symptom survived the fix, so the shared diagnosis was wrong — the stub really did
under-grant, but that is not what was blinding the sweep.
The falsification
Two post-merge runs, permissions visibly in effect in the runner, blind three seconds later:
— incubator run 30055242702,
and identically in run 30055288837
(token block 00:08:10Z, both lines 00:08:15Z). Neither open PR has ever carried a
state:*label.Two things to look at, one of which blocks looking at the other
1. The read discards
gh's error text.GH_VIEW="$(gh pr view "$n" -R "$REPO" --json mergeable,statusCheckRollup 2>/dev/null || echo '{}')"(L625 @
5af1538, the currentmain;L546 @
0.1.0— byte-identical between them.)ghwrites why it failed to stderr and2>/dev/nulldrops it, so a permanent denial and anetwork hiccup leave byte-identical evidence. The degrade itself is right and I am not arguing with
it — the PR must be left alone. But the reason it was left alone is knowable and is being thrown
away, and that is why #95 had to infer a cause from a control case instead of reading it off a run,
and why the inference could be wrong without anything looking wrong. #95's second half made a
wholly-blind sweep loud; it did not make it legible. One run with stderr captured (to the log,
or into the message) would have ended this in minutes rather than producing a merged fix for the
wrong defect.
2. The variable #95 and #48 both missed: the forks are private too.
Every PR on incubator is cross-repo — #50 from
claude-bot-andresmgsl/incubator, #46 fromcodex-bot-andresmgsl/incubator, likewise #34/#39/#40/#41/#47/#49 — and because the base repo isprivate, every one of those forks is private as well.
GITHUB_TOKENis scoped to the base repoand cannot read them.
The control case read as one difference and is actually two. box/rig/cast/ceremony are public, so
their forks are public, so a head-repo read costs nothing there. "Private repo ⇒ permissions not
implied" and "private repo ⇒ the head repo is unreadable at any permission" both fit the same
evidence, and #48 tested only the first. If it is the second, no caller-side permission can fix
it — the caller is not where a base-scoped token's reach is decided, and every consumer that goes
private will land here on adoption day.
Consistent-with, and its limit: the same query from a PAT that can read the fork returns both
fields for #50 (
mergeable: "UNKNOWN"plus a full rollup), so the query shape is fine and thefields exist. I cannot issue a
GITHUB_TOKEN-scoped query from outside Actions to confirm thedenial — which is (1) again: the run already knows, and throws it away.
Why this is a discussion and not an issue
The fix has real latitude and I would be handing a builder my guess:
repos/{repo}/commits/{head_sha}/check-runs+/statusreads PR head commits fine for fork PRs.But
mergeablecomes from the same call, andL618-L621 @
5af1538documents a deliberate choice of
gh pr viewover the REST object because REST'smergeableis a lazily-computed tri-state boolean while
ghreturns the UI's string. Reversing that is adecision, not a patch — and it may mean two different sources for the two facts.
ghandfixing the real thing is cheaper.
is small, it is not blocked on knowing the answer, and it is what makes the answer readable —
including for the next private consumer, who will otherwise repeat this exact round.
Suggested order: surface the error text, let one incubator sweep run, read the actual message, then
spec the fix against a fact instead of against my hypothesis. Happy to report that run back here.
cc @danmt — filed by triage, incubator-side trail on
incubator#48.
All reactions