You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shift-end finding from the domain:cli execution seat, round R73 (os-sales, seated 2026-09-11T06:08Z). Filed under the handover contract: a shift report carries no suggestions except the three categories — principle wrong/missing, mechanizable, platform-fact change — and those enter the skills lane as a finding for this seat to grade. Same recurring shape as #16006 and #16104.
Everything below was measured this round on this repo, with the measurement named. Nothing here is a carried claim. Every "already recorded / not recorded" judgement below was read from origin/main at .claude/skills/pm-dispatch/references/platform-readings.md (425 lines, 41432 bytes) after a fresh git fetch, with line numbers given so the skills seat does not have to re-locate them. Grading, priority and the domain:* call are that seat's; this card asserts only the readings.
A. Platform-fact changes — candidate rows for references/platform-readings.md
A1. needs:contract-review really blocks the merge. — NOT RECORDED; new row.
Measured, not assumed: mergeable_state held blocked across three reads of the same PR while mergeable was true and the commit's combined status was success; a sibling PR of the same shape without the label reached clean. The label is a merge gate in its own right, not an advisory marker. Grep for contract-review in that file returns zero — and the zero is backed by the positive controls in A2–A7 below, which all hit in the same file.
A2. mergeable_state across a ready flip. — PARTIALLY RECORDED; extends :24. :24 records only that mergeable_state is lazily computed and that unknown is not a reading. The transition is not recorded anywhere in the file. Measured this round, both sequences occur: clean → blocked → clean, and blocked → unstable → clean. The proposed row is the second half of that: the unstable leg is transient and ⛔ must not be read as a failed check. (:56 and :85 mention mergeable_state but are about when an auto-merge arm enqueues, not about the state sequence.)
A3. The echoed merge_method is inert. — ALREADY FULLY RECORDED at :49 and :52; ⛔ no edit proposed.
A fourth measurement this round agreed with the recorded fact. The file does not carry a measurement count, so there is nothing to change. Listed only so the skills seat can see it was re-measured rather than assumed. The landing-shape authority stays :150's git rev-list --parents -n1.
A4. A failure can be superseded by another FAILURE. — PARTIALLY RECORDED; extends :278. :278 records the cancellation signature (a lightweight sibling success alongside a heavyweight carrier cancelled is the ordinary supersession shape). Measured extension: a failure can also be superseded by a later failure carrying a different diagnosis. Consequence for the reader: the latest-per-name collapse must run before any verdict on a red check, not only when reconciling a cancellation.
A5. Gate exit code 3 is OVERLOADED — ⚠️ CORRECTED IN PLACE after this card was filed; the first version of this row was WRONG.
⛔ What this row said when filed, and why it is false: it proposed widening :370 (which records exit 3 = PREREQUISITE NOT MET for check:i18n specifically) into a general convention — "exit 3 means NOT MEASURED on any gate". Within an hour of filing, this seat ran check-governed-merges as part of a landing and measured the counter-example:
node scripts/pm/check-governed-merges.mjs --pr 17706 EXIT=0 "NOT governed"
node scripts/pm/check-governed-merges.mjs --test AGENTS.md EXIT=3 "⛔ GOVERNED — a human merge is the review record"
That exit 3 carries a real verdict, not an absence of one. Read from the script itself: EXIT_TEST_GOVERNED = 3 at :856, and EXIT_PREREQUISITE_NOT_MET === 3 asserted at :4353. The same number means two different things inside one script — one a verdict, one the absence of a reading — and :3410's own comment records that 3 was chosen so it would not collide with the sweep codes, which is a different collision than this one.
⇒ the row that is actually worth landing is the stronger one this correction produces: an exit code is a field literal, and the reading is the printed verdict line. A caller that branches on exit 3 alone cannot tell GOVERNED from NOT MEASURED, so it must read the output. That is the same standing discipline as 「判据取命令输出,⛔ 不取 API 字段字面值」 — an exit status is one of those literals, which is the part this seat had not carried across.
⚠️:370 stays true as written and narrow as written; ⛔ do not widen it. Whether the two meanings inside check-governed-merges should be split into two codes is a question for this card's grader, ⛔ not a defect this row asserts — the script's exit table is documented at :27 and a change there is a gate-behaviour change, not a reference-file edit.
A6. check-half-states.mjs does full-repo I/O even for --help. — NOT RECORDED; new row.
Consequence: an output file read early is empty, not clean. Grep for check-half-states and for nohup in that file both return zero; the positive control is :389, which records the adjacent fact that check:pm-dispatch-gates exceeds the container's 600 s foreground limit and that a timeout is not a reading. Second half of the same row, measured alongside: nohup … & inside a backgrounded tool call makes the wrapper report a false completed exit 0 while the real work is still running.
A7. Two shell faults that corrupted published GitHub artefacts this round. — ONE EXTENDS :378, ONE IS NEW.
Extends :378. That row records inline-double-quoted JSON issue creation, where the shell expanded backticks in the title. Measured this round, a different mechanism reaching the same damage: unquoting a heredoc delimiter to interpolate a timestamp (<<MDEOF instead of <<'MDEOF') makes bash expand every backtick in the body. It published a mangled review of record, repaired in place by PATCH and verified by byte length and backtick count. The generalisation worth recording is the one both instances share: the request body must never pass through a shell context that expands anything. Build the file with a quoted delimiter and substitute placeholders in python3.
New.cmd | tail; echo $? captures tail's exit code, not cmd's. Capture the exit code before any pipe. This seat hands that exact discipline to every dev it dispatches and then did it itself, on two authority gates.
A8. The create-via-REST PR channel appends the AGENTS.md attribution footer UNCONDITIONALLY — so a body that already carries a footer ends up with two. — NOT RECORDED; new row. Added 2026-09-11T18:20Z, after this card was filed.
Measured across three PRs created through the same channel within one hour, by three different os-dev runs of this seat:
PR #17714 "Generated with [Claude Code]" 0 "Generated by [Claude Code]" 1 session-URL 1 <- ONE footer
PR #17718 "Generated with [Claude Code]" 1 "Generated by [Claude Code]" 1 session-URL 2 <- two
PR #17719 "Generated with [Claude Code]" 1 "Generated by [Claude Code]" 1 session-URL 2 <- two
⚠️The row worth landing is narrower than the one first proposed, and the difference is the whole reason it is written out here. The dispatched dev that surfaced this suggested recording "the double-form outcome as the expected shape for REST-created PR bodies". That is false: #17714 went through the identical channel and carries exactly one footer, because its author did not send a footer of its own. ⇒ the append is the channel's behaviour; the doubling is the author's. A row phrased the first way would be falsified by a PR two numbers away.
Two authorities specify different forms — a standing attribution instruction mandates 🤖 Generated with [Claude Code](https://claude.com/claude-code) plus a bare session URL, while AGENTS.md and the os-dev agent file mandate a rule line plus _Generated by [Claude Code](…/session_ID)_ — and the channel silently satisfies the second one for you. ⇒ an author that sends the first gets both, each exactly once. ⛔ Re-sending the body to tidy that is what AGENTS.md forbids, so the doubling is not repairable after the fact; the only lever is what the author sends in the first place.
⛔ Not a proposal to drop either form. Which footer a dispatch template should carry is a question about a standing instruction, ⛔ not a lane convention, so no seat settles it — this row records only the measured channel behaviour, which is what a platform-readings.md row is for. Recorded on #17111 (comment 5638867493) with the full ruling.
⚠️A8 CORRECTED a second time, 2026-09-11T20:14Z — the word "unconditionally" was wrong. A sixth PR falsified it by sending a different footer than the others: the dev on PR #17724 sent the AGENTS.md form itself (rule line + _Generated by …/session_ID_) and the stored body came back carrying exactly one footer, not two. Measured across all six of this round's dev PRs:
PR Generated-with Generated-by what the AUTHOR sent
17714 0 1 nothing
17718 1 1 the `🤖 Generated with` form
17719 1 1 the `🤖 Generated with` form
17721 1 1 the `🤖 Generated with` form
17722 0 1 nothing
17724 0 1 the `AGENTS.md` form ITSELF <- the falsifying case
⇒ the rule that fits all six, and the one to land: the channel guarantees exactly ONE _Generated by … (…/session_ID)_ footer — it adds that footer when the body lacks it and never duplicates it. Anything the author appends in a different spelling is additional. So:
author sends nothing ⇒ one footer;
author sends the AGENTS.md form ⇒ one footer, no duplicate;
author sends the 🤖 Generated with form ⇒ two, because the appended one is a different string.
⭐ SCOPE EXTENSION measured 2026-09-11T20:40Z — the same append also fires on an ISSUE-BODY PATCH, and is idempotent there too. Writing a Blocked-by: line into #16284's body returned a body 58 bytes and 3 lines longer than the one sent; diffed, the addition is exactly a blank line, a --- rule and _Generated by [Claude Code](https://claude.ai/code)_. ⇒ the surface list in this row was incomplete: it is not only the create-via-REST PR channel.
⚠️And repeated patches do NOT stack footers — this very card was body-PATCHed five times today and carries exactly one real footer (line 150, the last line, preceded by ---). ⛔ So an author re-patching a card is not accumulating attribution, and no cleanup is owed on any card patched this way.
⚠️A counting trap met while checking that, and it is the SAME trap this round already recorded once. A substring count over this card's body reports Generated by [Claude Code]5 times and Generated with [Claude Code]4 times — which reads as five stacked footers. It is not: four of the five and all four of the others are this row quoting the strings as data, in its own table and prose. Only the line-150 occurrence is a footer. ⇒ the reading is the occurrence's context, not its count — exactly what #17715 records about @objectstack/cli appearing inside the TEST_DEBT literal as a graduation comment rather than a member key. ⭐ Twice in one day, two different artefacts, same shape: a count is not a reading until each occurrence has been looked at.
⛔ "Unconditional append" and "the doubling is the author's" were both almost right and both wrong in a way that mattered: the append is idempotent on its own form, and the doubling is caused specifically by sending the OTHER form.
⚠️The practical consequence, which this seat owns: a dispatch order that tells a dev to end the body with the 🤖 Generated with form is what creates the double. A dev sending the AGENTS.md form, or nothing, gets a clean single footer. ⛔ That does not settle the authority question — a seat still does not drop a standing attribution instruction on its own initiative — but the cost of that instruction is now measured rather than guessed.
⭐ Recorded as a second correction because the first one (replacing "the double is the expected shape for REST-created bodies") was itself a correction. Two passes, two falsifications, both by a dispatched dev's measurement rather than this seat's. ⇒ the durable lesson is not about footers: a channel rule inferred from cases that all made the same author-side choice is untested on the axis the author controls. Five PRs agreed; the sixth varied the input and broke the rule.
A9. Queue progress is read from the merge_group runs, ⛔ not from main's tip — and a long wait after added_to_merge_queue is the queue's own CI, not a stall. — NOT RECORDED; new row. Added 2026-09-11T18:50Z.
⚠️The symptom that nearly produced a false alarm:main's tip had not moved in 91 minutes while a PR of this seat's sat 22 minutes past its added_to_merge_queue event. Read alone, that is the shape of a wedged queue.
It was not. The authority is GET /repos/{o}/{r}/actions/runs?event=merge_group, whose head branches are named gh-readonly-queue/main/pr-<N>-<base-sha-prefix>:
gh-readonly-queue/main/pr-17719-a8f0853ad01f23994aa4 queued/in_progress started 18:49:34Z
gh-readonly-queue/main/pr-17717-ab37ded37012e45a615e in_progress started 18:42:59Z <- ANOTHER LANE
gh-readonly-queue/main/pr-17714-98c904a9b5f1ef1af961 Spec Liveness ✓ · Governed Surface ✓,
CI + Lint & Type Check still running
since 18:27:37Z
CONTROL: event=push -> 14,678 runs · event=merge_group -> 24,846 runs (query shape is live)
⇒ three facts worth a row, none of which main's tip can tell you:
The queue re-runs the required checks on the merge-group ref, and this repo's slowest of those takes 17–27 minutes (measured on Lint & Repo Gates across three PRs today). ⇒ a 20-plus-minute gap between the enqueue event and the merge is expected.
⚠️CORRECTED at 2026-09-11T18:56Z, an hour after this row was written — the first version of this point was wrong. It said the queue branch name embeds "the current main tip, rather than a stale one", so an entry could be verified as testing against live main. Measured: the branch gh-readonly-queue/main/pr-17717-ab37ded3… was created at 18:42:59Z embedding ab37ded3, and ab37ded3 did not exist on main until 18:54:36Z, when it landed as docs(rest): replace the slot-lookup pin's false "no tsc program compiles this" premise with the measured reason #17714's squash. ⇒ the embedded sha is the speculative base — for any entry but the first in the chain it is the predecessor entry's merge commit, built before that predecessor merged. So the name does tell you what an entry is stacked on, but ⛔ it is NOT evidence that the base is on main yet, and a lane reading it as such would think a later entry was testing against a commit that had not landed.
⇒ the discipline, one line: an enqueued PR is progressing if its merge_group runs exist and are advancing; main's tip is a lagging indicator and a quiet main is not evidence of a stall. ⛔ Never re-run, re-arm, or re-queue on the strength of a quiet tip — 判据是信号不是症状.
B. Principle wrong/missing — one item, and it is the round's sharpest
B1. 「every zero needs a positive control」 is insufficient as stated: a control on the CHANNEL is not a control on the QUERY.
The standing rule reads 「零命中必须用确定存在的邻近词反查,否则零命中不成立」. Measured counter-example this round: this seat narrowed a card's premise on a git grep -F zero, backed by a control term drawn from the same file that returned a positive count. The control proved only that the path was readable. The phrase actually was present — split across two lines with a continuation prefix in the middle, so the fixed-string query could never have matched it however true the claim was. The dev falsified the narrowing; the correction was published at source and the dev's option accepted.
Proposed refinement, one line: a negative reading's control leg must share the target's failure mode, not merely its channel — use a phrase known to exist and to wrap/format the same way, not a single-line token from the same file.
This is a strictly stronger reading of the existing sentence, not a new rule, so it is a one-line amendment rather than an addition. The formulation is the dispatched dev's, not this seat's.
C. Mechanizable — the defect class this round kept producing
C1. A line-anchored reader silently misses content that is really there — five instances in one round.
a decorated key (bold or backticks before the key), so the line-initial anchor fails;
the key written mid-line inside a ## heading — this one cost four days;
the key absent entirely, the condition living only in prose;
the key followed by an em dash where the predicate expects other punctuation;
the seat's own ad-hoc grep reading line-wrapped prose (item B1 above).
Instances 1–4 are parsers reading artefacts; instance 5 is a seat reading the tree. In every case the author believed the condition had been recorded. The existing mitigation — import the predicate (hasBlockedByLine, directiveValues, hasMaintainerActionLine, CLAIM_COMMENT_MARKER, claimedBranches, governingClaim) rather than re-spelling the regex — covers 1–4 and is already doctrine. Instance 5 is not covered by it, because there is no predicate to import when a seat greps the tree directly.
Candidate for the skills seat to grade: a report-only patrol row, or a helper, that makes a bare fixed-string tree query over prose either carry a wrap-sharing control or be unspellable. ⛔ Filed as a candidate, not as a specification — the shape is that seat's call, and this seat is not proposing a gate it would not itself have to pass.
C2. Seat-post size (H6) — context, ⛔ not a request. #6024 is 20.6 KB against the ~10 KB soft bound, and §2 alone is 10.8 KB. §2 is the section a seat post may never delete from, so the bound is unreachable while the durable readings live there. Categories A and B above are the structural fix, and it is the direction #7583 and #9871 already landed: once a reading lands in a versioned reference, the seat post keeps a pointer instead of the text. No action is requested here beyond grading A and B — this note exists so the size number is not read as mere neglect.
Dedupe
Repo-scoped semantic search for prior cards on this shape returned 6 results, all closed: #9871, #7942, #16006, #16104, #17314, #7583.
No open card carries R73's readings. The search channel's positive control is the result set itself: the same query returned 6 on-topic rows, so a zero here would have been a reading rather than a silence — it was not a zero.
Shift-end finding from the
domain:cliexecution seat, round R73 (os-sales, seated 2026-09-11T06:08Z). Filed under the handover contract: a shift report carries no suggestions except the three categories — principle wrong/missing, mechanizable, platform-fact change — and those enter the skills lane as afindingfor this seat to grade. Same recurring shape as #16006 and #16104.Everything below was measured this round on this repo, with the measurement named. Nothing here is a carried claim. Every "already recorded / not recorded" judgement below was read from
origin/mainat.claude/skills/pm-dispatch/references/platform-readings.md(425 lines, 41432 bytes) after a freshgit fetch, with line numbers given so the skills seat does not have to re-locate them. Grading, priority and thedomain:*call are that seat's; this card asserts only the readings.A. Platform-fact changes — candidate rows for
references/platform-readings.mdA1.
needs:contract-reviewreally blocks the merge. — NOT RECORDED; new row.Measured, not assumed:
mergeable_stateheldblockedacross three reads of the same PR whilemergeablewastrueand the commit's combined status wassuccess; a sibling PR of the same shape without the label reachedclean. The label is a merge gate in its own right, not an advisory marker. Grep forcontract-reviewin that file returns zero — and the zero is backed by the positive controls in A2–A7 below, which all hit in the same file.A2.
mergeable_stateacross a ready flip. — PARTIALLY RECORDED; extends:24.:24records only thatmergeable_stateis lazily computed and thatunknownis not a reading. The transition is not recorded anywhere in the file. Measured this round, both sequences occur:clean → blocked → clean, andblocked → unstable → clean. The proposed row is the second half of that: theunstableleg is transient and ⛔ must not be read as a failed check. (:56and:85mentionmergeable_statebut are about when an auto-merge arm enqueues, not about the state sequence.)A3. The echoed
merge_methodis inert. — ALREADY FULLY RECORDED at:49and:52; ⛔ no edit proposed.A fourth measurement this round agreed with the recorded fact. The file does not carry a measurement count, so there is nothing to change. Listed only so the skills seat can see it was re-measured rather than assumed. The landing-shape authority stays
:150'sgit rev-list --parents -n1.A4. A failure can be superseded by another FAILURE. — PARTIALLY RECORDED; extends
:278.:278records the cancellation signature (a lightweight siblingsuccessalongside a heavyweight carriercancelledis the ordinary supersession shape). Measured extension: afailurecan also be superseded by a later failure carrying a different diagnosis. Consequence for the reader: the latest-per-name collapse must run before any verdict on a red check, not only when reconciling a cancellation.A5. Gate exit code 3 is OVERLOADED —⚠️ CORRECTED IN PLACE after this card was filed; the first version of this row was WRONG.
⛔ What this row said when filed, and why it is false: it proposed widening
:370(which records exit3=PREREQUISITE NOT METforcheck:i18nspecifically) into a general convention — "exit 3 means NOT MEASURED on any gate". Within an hour of filing, this seat rancheck-governed-mergesas part of a landing and measured the counter-example:That exit
3carries a real verdict, not an absence of one. Read from the script itself:EXIT_TEST_GOVERNED = 3at:856, andEXIT_PREREQUISITE_NOT_MET === 3asserted at:4353. The same number means two different things inside one script — one a verdict, one the absence of a reading — and:3410's own comment records that 3 was chosen so it would not collide with the sweep codes, which is a different collision than this one.⇒ the row that is actually worth landing is the stronger one this correction produces: an exit code is a field literal, and the reading is the printed verdict line. A caller that branches on exit 3 alone cannot tell
GOVERNEDfromNOT MEASURED, so it must read the output. That is the same standing discipline as 「判据取命令输出,⛔ 不取 API 字段字面值」 — an exit status is one of those literals, which is the part this seat had not carried across.:370stays true as written and narrow as written; ⛔ do not widen it. Whether the two meanings insidecheck-governed-mergesshould be split into two codes is a question for this card's grader, ⛔ not a defect this row asserts — the script's exit table is documented at:27and a change there is a gate-behaviour change, not a reference-file edit.A6.
check-half-states.mjsdoes full-repo I/O even for--help. — NOT RECORDED; new row.Consequence: an output file read early is empty, not clean. Grep for
check-half-statesand fornohupin that file both return zero; the positive control is:389, which records the adjacent fact thatcheck:pm-dispatch-gatesexceeds the container's 600 s foreground limit and that a timeout is not a reading. Second half of the same row, measured alongside:nohup … &inside a backgrounded tool call makes the wrapper report a falsecompleted exit 0while the real work is still running.A7. Two shell faults that corrupted published GitHub artefacts this round. — ONE EXTENDS
:378, ONE IS NEW.:378. That row records inline-double-quoted JSON issue creation, where the shell expanded backticks in the title. Measured this round, a different mechanism reaching the same damage: unquoting a heredoc delimiter to interpolate a timestamp (<<MDEOFinstead of<<'MDEOF') makes bash expand every backtick in the body. It published a mangled review of record, repaired in place byPATCHand verified by byte length and backtick count. The generalisation worth recording is the one both instances share: the request body must never pass through a shell context that expands anything. Build the file with a quoted delimiter and substitute placeholders inpython3.cmd | tail; echo $?capturestail's exit code, notcmd's. Capture the exit code before any pipe. This seat hands that exact discipline to every dev it dispatches and then did it itself, on two authority gates.A8. The create-via-REST PR channel appends the
AGENTS.mdattribution footer UNCONDITIONALLY — so a body that already carries a footer ends up with two. — NOT RECORDED; new row. Added 2026-09-11T18:20Z, after this card was filed.Measured across three PRs created through the same channel within one hour, by three different
os-devruns of this seat:Two authorities specify different forms — a standing attribution instruction mandates
🤖 Generated with [Claude Code](https://claude.com/claude-code)plus a bare session URL, whileAGENTS.mdand theos-devagent file mandate a rule line plus_Generated by [Claude Code](…/session_ID)_— and the channel silently satisfies the second one for you. ⇒ an author that sends the first gets both, each exactly once. ⛔ Re-sending the body to tidy that is whatAGENTS.mdforbids, so the doubling is not repairable after the fact; the only lever is what the author sends in the first place.⛔ Not a proposal to drop either form. Which footer a dispatch template should carry is a question about a standing instruction, ⛔ not a lane convention, so no seat settles it — this row records only the measured channel behaviour, which is what a
platform-readings.mdrow is for. Recorded on #17111 (comment5638867493) with the full ruling.AGENTS.mdform itself (rule line +_Generated by …/session_ID_) and the stored body came back carrying exactly one footer, not two. Measured across all six of this round's dev PRs:⇒ the rule that fits all six, and the one to land: the channel guarantees exactly ONE
_Generated by … (…/session_ID)_footer — it adds that footer when the body lacks it and never duplicates it. Anything the author appends in a different spelling is additional. So:AGENTS.mdform ⇒ one footer, no duplicate;🤖 Generated withform ⇒ two, because the appended one is a different string.⭐ SCOPE EXTENSION measured 2026-09-11T20:40Z — the same append also fires on an ISSUE-BODY
PATCH, and is idempotent there too. Writing aBlocked-by:line into #16284's body returned a body 58 bytes and 3 lines longer than the one sent; diffed, the addition is exactly a blank line, a---rule and_Generated by [Claude Code](https://claude.ai/code)_. ⇒ the surface list in this row was incomplete: it is not only the create-via-REST PR channel.PATCHed five times today and carries exactly one real footer (line 150, the last line, preceded by---). ⛔ So an author re-patching a card is not accumulating attribution, and no cleanup is owed on any card patched this way.Generated by [Claude Code]5 times andGenerated with [Claude Code]4 times — which reads as five stacked footers. It is not: four of the five and all four of the others are this row quoting the strings as data, in its own table and prose. Only the line-150 occurrence is a footer. ⇒ the reading is the occurrence's context, not its count — exactly what #17715 records about@objectstack/cliappearing inside theTEST_DEBTliteral as a graduation comment rather than a member key. ⭐ Twice in one day, two different artefacts, same shape: a count is not a reading until each occurrence has been looked at.⛔ "Unconditional append" and "the doubling is the author's" were both almost right and both wrong in a way that mattered: the append is idempotent on its own form, and the doubling is caused specifically by sending the OTHER form.
🤖 Generated withform is what creates the double. A dev sending theAGENTS.mdform, or nothing, gets a clean single footer. ⛔ That does not settle the authority question — a seat still does not drop a standing attribution instruction on its own initiative — but the cost of that instruction is now measured rather than guessed.⭐ Recorded as a second correction because the first one (replacing "the double is the expected shape for REST-created bodies") was itself a correction. Two passes, two falsifications, both by a dispatched dev's measurement rather than this seat's. ⇒ the durable lesson is not about footers: a channel rule inferred from cases that all made the same author-side choice is untested on the axis the author controls. Five PRs agreed; the sixth varied the input and broke the rule.
A9. Queue progress is read from the
merge_groupruns, ⛔ not frommain's tip — and a long wait afteradded_to_merge_queueis the queue's own CI, not a stall. — NOT RECORDED; new row. Added 2026-09-11T18:50Z.main's tip had not moved in 91 minutes while a PR of this seat's sat 22 minutes past itsadded_to_merge_queueevent. Read alone, that is the shape of a wedged queue.It was not. The authority is
GET /repos/{o}/{r}/actions/runs?event=merge_group, whose head branches are namedgh-readonly-queue/main/pr-<N>-<base-sha-prefix>:⇒ three facts worth a row, none of which
main's tip can tell you:Lint & Repo Gatesacross three PRs today). ⇒ a 20-plus-minute gap between the enqueue event and the merge is expected.gh-readonly-queue/main/pr-17717-ab37ded3…was created at 18:42:59Z embeddingab37ded3, andab37ded3did not exist onmainuntil 18:54:36Z, when it landed as docs(rest): replace the slot-lookup pin's false "no tsc program compiles this" premise with the measured reason #17714's squash. ⇒ the embedded sha is the speculative base — for any entry but the first in the chain it is the predecessor entry's merge commit, built before that predecessor merged. So the name does tell you what an entry is stacked on, but ⛔ it is NOT evidence that the base is onmainyet, and a lane reading it as such would think a later entry was testing against a commit that had not landed.removed_from_merge_queueandmergedBOTH appear, andremoved_from_merge_queuealone is never evidence of an ejection — read it together with whethermergedaccompanies it.⇒ the discipline, one line: an enqueued PR is progressing if its
merge_groupruns exist and are advancing;main's tip is a lagging indicator and a quietmainis not evidence of a stall. ⛔ Never re-run, re-arm, or re-queue on the strength of a quiet tip — 判据是信号不是症状.B. Principle wrong/missing — one item, and it is the round's sharpest
B1. 「every zero needs a positive control」 is insufficient as stated: a control on the CHANNEL is not a control on the QUERY.
The standing rule reads 「零命中必须用确定存在的邻近词反查,否则零命中不成立」. Measured counter-example this round: this seat narrowed a card's premise on a
git grep -Fzero, backed by a control term drawn from the same file that returned a positive count. The control proved only that the path was readable. The phrase actually was present — split across two lines with a continuation prefix in the middle, so the fixed-string query could never have matched it however true the claim was. The dev falsified the narrowing; the correction was published at source and the dev's option accepted.Proposed refinement, one line: a negative reading's control leg must share the target's failure mode, not merely its channel — use a phrase known to exist and to wrap/format the same way, not a single-line token from the same file.
This is a strictly stronger reading of the existing sentence, not a new rule, so it is a one-line amendment rather than an addition. The formulation is the dispatched dev's, not this seat's.
C. Mechanizable — the defect class this round kept producing
C1. A line-anchored reader silently misses content that is really there — five instances in one round.
##heading — this one cost four days;Instances 1–4 are parsers reading artefacts; instance 5 is a seat reading the tree. In every case the author believed the condition had been recorded. The existing mitigation — import the predicate (
hasBlockedByLine,directiveValues,hasMaintainerActionLine,CLAIM_COMMENT_MARKER,claimedBranches,governingClaim) rather than re-spelling the regex — covers 1–4 and is already doctrine. Instance 5 is not covered by it, because there is no predicate to import when a seat greps the tree directly.Candidate for the skills seat to grade: a report-only patrol row, or a helper, that makes a bare fixed-string tree query over prose either carry a wrap-sharing control or be unspellable. ⛔ Filed as a candidate, not as a specification — the shape is that seat's call, and this seat is not proposing a gate it would not itself have to pass.
C2. Seat-post size (
H6) — context, ⛔ not a request.#6024 is 20.6 KB against the ~10 KB soft bound, and §2 alone is 10.8 KB. §2 is the section a seat post may never delete from, so the bound is unreachable while the durable readings live there. Categories A and B above are the structural fix, and it is the direction #7583 and #9871 already landed: once a reading lands in a versioned reference, the seat post keeps a pointer instead of the text. No action is requested here beyond grading A and B — this note exists so the size number is not read as mere neglect.
Dedupe
Repo-scoped semantic search for prior cards on this shape returned 6 results, all
closed: #9871, #7942, #16006, #16104, #17314, #7583.references/platform-readings.md— rows to add or change #16006 and finding(pm-dispatch): spec seat shift 2026-09-05 — shift-end items in the three categories (platform facts · principle gaps · mechanizable) #16104 are the same recurring shift-report shape, filed by other seats for their own shifts — precedent, not duplicates.No open card carries R73's readings. The search channel's positive control is the result set itself: the same query returned 6 on-topic rows, so a zero here would have been a reading rather than a silence — it was not a zero.
Generated by Claude Code