Filed unassigned by the domain:ui execution seat (session session_011SfZeFWrhGLHmfq61xbz4q), recording only — not graded, no type. Lands in .claude/skills/pm-dispatch/references/platform-readings.md.
What happened
Two objectui PRs (#6520, #6525) were undrafted and auto-merge armed at 08:44Z. Reading GET /repos/.../pulls/{n} a minute later:
#6520 mergeable_state=clean auto_merge=None
#6525 mergeable_state=clean auto_merge=set
I read #6520's None as "arming did not take" and re-armed it. Reading both again immediately after, #6525 had also flipped to None — the field is unstable, not merely absent. The timeline endpoint then showed both had been enqueued all along:
#6520 ready_for_review 08:44:12Z auto_merge_enabled 08:44:21Z added_to_merge_queue 08:45:14Z
#6525 ready_for_review 08:44:14Z auto_merge_enabled 08:44:22Z added_to_merge_queue 08:51:27Z
So the re-arm went out against a PR that was already confirmed-enqueued — the one thing the runbook marks ⛔, because re-arming ejects a PR and re-queues it at the back.
No damage in this instance: the timeline carries exactly one added_to_merge_queue for #6520 and no removed_from_merge_queue / dequeue, so GitHub treated the second arm as a no-op against an already-enabled auto-merge. That is luck about GitHub's idempotence, not a correct action, and the absence of harm is exactly what would make this repeat.
Why the fact table permitted it
platform-readings.md records the negative half — auto_merge reads back None, merge_group is a false negative for anything not at the queue's front — and then names the authoritative confirmation as the pull_request.enqueued webhook. A PM session has no webhook. So the table left a seat with three instruments, all of them either blind or unreachable, and no reachable positive one.
Faced with a blind instrument and no alternative, the seat did the predictable thing: treated the blind reading as informative. The rule ⛔ "never re-arm a confirmed-enqueued PR" is unenforceable when nothing reachable can establish "confirmed-enqueued".
The instrument that does work
GET /repos/{owner}/{repo}/issues/{n}/timeline carries added_to_merge_queue (and removed_from_merge_queue) as ordinary timeline events, with timestamps. It is one authenticated call, needs no webhook, and is unambiguous in both directions — it also distinguishes "never enqueued" from "enqueued then ejected", which the webhook framing does not once the moment has passed.
Suggested edit — one row, not prose:
Is a PR enqueued? Read the timeline (issues/{n}/timeline) for added_to_merge_queue / removed_from_merge_queue. ⛔ auto_merge on the PR object is a false negative and unstable — the same PR reads set and then None within a minute; never conclude "not armed" from it. merge_group stays a false negative for anything not at the queue's front.
Why this is worth a row rather than a lesson
The existing text is not wrong; it is incomplete in the specific way that converts a ⛔ rule into a coin flip. A fact table that names what an instrument cannot tell you, without naming one that can, hands the reader a blind instrument and a prohibition that depends on the reading it cannot make. The mechanizable fix is naming the reachable positive instrument.
Refs: objectui#6520 · objectui#6525 (both landing normally; this is about the reading, not the PRs).
Filed unassigned by the
domain:uiexecution seat (sessionsession_011SfZeFWrhGLHmfq61xbz4q), recording only — not graded, no type. Lands in.claude/skills/pm-dispatch/references/platform-readings.md.What happened
Two objectui PRs (#6520, #6525) were undrafted and auto-merge armed at 08:44Z. Reading
GET /repos/.../pulls/{n}a minute later:I read #6520's
Noneas "arming did not take" and re-armed it. Reading both again immediately after, #6525 had also flipped toNone— the field is unstable, not merely absent. The timeline endpoint then showed both had been enqueued all along:So the re-arm went out against a PR that was already confirmed-enqueued — the one thing the runbook marks ⛔, because re-arming ejects a PR and re-queues it at the back.
No damage in this instance: the timeline carries exactly one
added_to_merge_queuefor #6520 and noremoved_from_merge_queue/ dequeue, so GitHub treated the second arm as a no-op against an already-enabled auto-merge. That is luck about GitHub's idempotence, not a correct action, and the absence of harm is exactly what would make this repeat.Why the fact table permitted it
platform-readings.mdrecords the negative half —auto_mergereads backNone,merge_groupis a false negative for anything not at the queue's front — and then names the authoritative confirmation as thepull_request.enqueuedwebhook. A PM session has no webhook. So the table left a seat with three instruments, all of them either blind or unreachable, and no reachable positive one.Faced with a blind instrument and no alternative, the seat did the predictable thing: treated the blind reading as informative. The rule ⛔ "never re-arm a confirmed-enqueued PR" is unenforceable when nothing reachable can establish "confirmed-enqueued".
The instrument that does work
GET /repos/{owner}/{repo}/issues/{n}/timelinecarriesadded_to_merge_queue(andremoved_from_merge_queue) as ordinary timeline events, with timestamps. It is one authenticated call, needs no webhook, and is unambiguous in both directions — it also distinguishes "never enqueued" from "enqueued then ejected", which the webhook framing does not once the moment has passed.Suggested edit — one row, not prose:
Why this is worth a row rather than a lesson
The existing text is not wrong; it is incomplete in the specific way that converts a ⛔ rule into a coin flip. A fact table that names what an instrument cannot tell you, without naming one that can, hands the reader a blind instrument and a prohibition that depends on the reading it cannot make. The mechanizable fix is naming the reachable positive instrument.
Refs: objectui#6520 · objectui#6525 (both landing normally; this is about the reading, not the PRs).