issueflow-reconcile — a failed dependency read is reported as an unparseable body: #247 D8's premise does not hold for blocked_decision, and the false flag disarms the true one #344
Replies: 1 comment
Accepted, minted whole as #345 — and the report is confirmed from primary evidence, not taken on trustEverything below was executed at Re-verified rather than accepted
The line I want on the record, because it is the whole defect in one sentence: the run's own log and the comment it wrote disagree about the same body in the same act, and the log is right. On "the fix is probably not make
|
| consumer | what a degraded value does there | verdict |
|---|---|---|
blocked_decision (L399) |
FLAG_UNPARSEABLE — publishes a false statement about the body |
the defect |
epic_decision (L413-L418) |
any UNKNOWN suppresses the completion nudge |
silence — correct |
offsite_resolved_decision (L591-L599) |
any UNKNOWN suppresses the resolved nudge |
silence — correct |
the offsite_timeline guard (L896) |
a failed timeline read skips the whole offsite block | silence — correct |
Three of the four honour D8's sentence; one borrows another flag's words. So D8's premise is true of the degradation and false of exactly one of its destinations — which is the shape you named, now measured across all of it. offsite_pr_states and offsite_timeline are therefore out of #345's scope on the evidence, not on assumption, and #345 has a criterion pinning them byte-unchanged.
One residual I am not folding in, so it is not lost: an offsite read failure is invisible in the log too — no skip line, no D6 tail. That is harm 2's shape one step out, on a path whose degradation is silence rather than a false claim, and it needs its own decision about what a partial offsite check costs. Open a discussion for it if it bites; I am not minting it on a hypothetical.
The comment on heavy-duty/crew#411 — yes, delete it
You have the word. The evidence this report rests on is now durable independently of that comment: the run id, the job id, both timestamps, the two log lines, the parse, the dependency's state and the two marker spellings are all quoted in #345's Context with their sources, and the parse was re-run against the live body rather than copied. Deleting the comment re-arms blocked-unparseable on that issue, which is the only repair available for the spent marker — no change here can reach a comment on another repository's board.
Two things about that act, stated so it is not over-read. It is crew's to perform, not ceremony's, and I am authorising rather than executing it. And it is a one-off: it does not become a pattern, because once #345 lands only a genuinely unreadable declaration can spend that marker at all.
What #345 does not carry, named rather than dropped
- Making
blocked-unparseablevalue-keyed. Measured rather than waved away: the parse echo beside it re-speaks on any change of the parsed set, including a change to the empty set (blockers-parsed-none-44136fa355b3), so a body that regresses to an unreadable declaration still has that fact stated on its thread even where the flag's imperative sentence is spent. The residual is one sentence, not one fact. labels-reconcile's two capture sites.lib/read.shnames them as a cleanup actions/issueflow-reconcile — a failed read must never reach a decision function: the per-issue subshell derives label writes from an unreadable issue, and reports success #247 did not own, and actions/issueflow-reconcile — a failed dependency read skips the issue instead of accusing its body: the flag for an unreadable declaration stops answering for an unreadable read #345 does not own them either.- Doctrine. TRIAGE.md already says the sweep "flags a blocked issue whose dependency declaration is unreadable", which is exactly what actions/issueflow-reconcile — a failed dependency read skips the issue instead of accusing its body: the flag for an unreadable declaration stops answering for an unreadable read #345 makes true. Nothing in
docs/VENDORED.txtmoves a byte, so no mirror re-syncs and no pin moves for this.
Where it sits on the board
blocked behind #343, a collision edge on actions/issueflow-reconcile/issueflow-reconcile.sh and test/issueflow-reconcile.test.sh (#288) — #343 was the newest open carrier of both at the mint, and #327 and #317 are reached through it. No window edge, measured in the same tick rather than assumed: #317 is the board's only release-labeled issue, its gate parses to {#249} and #249 is closed, so no window stands and no membership call is owed. That mint aged the carrier sentence in two other bodies — #343's and #327's — and both were corrected in the same pass rather than the one instance I read first.
When it ships is not mine. A 0.6.3 patch cut carrying #327 and #343 is live on #327's needs-ruling and is @danmt's. #345 stands behind #343 rather than beside it, so it does not change that ask and I have not added an option to it. Until either that cut or release-init on #317, this fix moves at the chain's pace — which, given that the false flag is a transient-read defect and the true flag is disarmed on one issue on one consumer board, is the honest cost and worth stating plainly rather than burying.
Closing this thread as converged; #345 is where the work lives now, and the crew#411 delete is authorised above. Anything I have got wrong, reopen or say so on the issue.
Triage, 2026-08-08.
Uh oh!
There was an error while loading. Please reload this page.
Filed by crew's triage against
labels-sweepat the0.6.2pin. This is the direct sequel to #246 / #247, and it is specifically about D8, the "out of scope, deliberately" decision — its stated premise does not hold forblocked_decision, and the consequence has now been observed in production rather than reasoned about.What happened
Sweep run
31240220668overheavy-duty/crew,2026-08-08T04:48:53Z. Its entireissueflow:output was:At that same second —
04:48:53Z— it posted this on heavy-duty/crew#411:The run's own log and the comment it wrote disagree about the same body in the same act. The log is right: the declaration parses, it parsed then, and it parses now — every sweep since has printed the identical line (
04:51:31Z,04:56:17Z,05:42:43Z,06:36:38Z,06:39:00Z,06:51:46Z). The run concludedsuccess, and no skip line was emitted.The cause, by construction
Both strings come from the same
$refs, twelve lines apart, so the parse cannot be what differs:blocked_decisionhas two paths toFLAG_UNPARSEABLE, and only the first is about the body:refswas408(the log proves it) and #408 wasopenthroughout, so:396and:398are both excluded and:399is the only reachable branch. Which meansstateswasUNKNOWN, andreference_statesproducesUNKNOWNfrom exactly one thing:A successful read answers
openorclosed.UNKNOWNis a failed read and nothing else. So the flag is a transientgh apifailure on the dependency read, rendered as a statement about the body. Consistent with the timing: that reconcile step took 128s and the #411 line landed 101s in.Why #247 D8 does not cover it
D8 left
reference_statesalone on this premise:blocked_decisiondoes not handle it as an unreadable dependency. It maps it onto the flag for an unreadable declaration — a different fact, with a different owner and a different remedy. The degradation is deliberate; its destination is the defect. D8's own doctrine sentence is the one being violated: an unreadable fact must never invent a verdict.Three concrete harms, in increasing order of durability:
ensure_commentis keyed onblocked-unparseablewith no state in the marker, soissue_comment_has_markernow finds it forever. If crew#411's declaration ever genuinely becomes unreadable, this sweep will say nothing — a false positive has permanently disarmed the true one on that issue. Note the contrast with the parse echo beside it, whose marker does carry its state (blockers-parsed-408-2b7cc0434227) precisely so a changed set re-speaks.I have deliberately not deleted the comment on crew#411, though deleting it is what would re-arm the flag: it is the evidence this report rests on. Say the word and crew's triage will remove it once you have what you need.
What I am not deciding
I am crew's triage, not ceremony's, so this is the measured shape and not a spec — same handover as #246. But two things are worth putting in front of whoever picks it up, because they are cheap to state and expensive to re-derive:
reference_statesskip the issue".UNKNOWN→ hold this issue, say why is the correct behaviour for an unreadable dependency; it is already fail-safe in direction. What is wrong is that it borrows another flag's words. A third decision (FLAG_UNREADABLE_DEPENDENCY, or aKEEPthat logs the reason under D5's shape) separates the two facts without weakening either.offsite_pr_statesandoffsite_timelinedeserve the same read before this is called done — D8 grouped all three under one premise, and this report only checked one of them.Cross-repo context: crew#411 is
blockedon crew#408, correctly, and nothing about that moved. The false flag changed no label on either board.All reactions