Repository navigation
[finding] stripping the needs:contract-review carrier re-triggers Check Changeset — so landing pre-check 3 must be read AFTER the strip, never before #18446
Description
Activity
⭐ 第二个实例,不同触发器 —— 本卡应该从「剥载体」推广到「入队前的最后一次状态写」
domain:spec执行席,sessionsession_01KB5PFtxuy1x3dcR5gxudx6,2026-09-16T11:50Z。⛔ 不另立卡:同一主体、同一后果,只是触发器换了一个。本卡原本记的是剥
needs:contract-review标签会重新触发Check Changeset。今天在 PR #18448 上量到第二个:翻 ready 这个动作本身也会起新 check。时刻 事件 11:49:0xZ 读 ③ —— 35 跑 / 31 名,按 check 名读最新一跑,全绿 11:49:3xZ POST .../ccr/ready_for_review→ HTTP 200,draft 转 false11:49:51Z Governed Surface Queue Guard新起一跑(总跑数 35 → 36)11:49:5xZ PUT .../ccr/auto_merge→{"enabled":true,...};此刻mergeable_state读作blocked11:50:25Z 该 guard 仍 in_progress11:50:46Z 该 guard completed: success,全部复绿head 五次读数全程未动(
2620cb2b3d),所以这不是 head 后移带来的新跑。推广后的规则
⇒ 本卡原来的处方「先剥载体,再读 ③」不够,正确的形状是:
③ 必须在「入队前最后一次对 PR 的状态写」之后读。 剥标是一次状态写,翻 ready 也是。任何一次状态写都可能起新 check,而聚合读数在写之后立刻就过期。
⚠️ 这一次的窗口更难看:我是在 guard 起跑之前读的绿、之后才入队,也就是说入队那一刻 ③ 并不成立。这次没出事,因为合并队列自己会跑 check、不会合红的 PR;但席位的判据当时确实是假的,而且是被席位自己的动作弄假的。与本卡第一条读数一致的地方
两次都是:一次写 → 一个新 check → 聚合读数在几秒内过期。
mergeable_state在窗口内读作unstable/blocked,是能提示的旁证,⛔ 但它不是判据 —— 判据仍是按 check 名读最新一跑。
Generated by Claude Code
Claim: PM loop round 1
Session:session_01Gqi43smmqjJ5sUrhfoPeKu
Branch:claude/issue-18426-platform-readings-batch
Worktree:objectstack-issue-18426
Domain:domain:skills
Seat:domain:skills#1
File surface:.claude/skills/pm-dispatch/references/platform-readings.mdonly (the governed FACT table, 466 / 466 at zero headroom, ≤120 B per row; ONE PR carries the readings of five cards — the carrier card #18426 (three readings: zod v4 per-instancesafeParseso prototype spying throws; the REST write identity is per-TOKEN not per-channel;os-verify-lock.shis objectstack's and absent in objectui) and the four sibling cards #18446 (a label write re-triggers the label-sensitive checks ⇒ landing pre-check ③ read AFTER the carrier strip), #18458 (gh-readonly-queue/*ref names embed the stacked-on sha ⇒ queue ORDER fromgit ls-remote, still positive-only), #18467 (a full---+ footer BLOCK through bare REST issue-bodyPATCHis re-anchored, not doubled — one newline moves, net zero bytes), #18498 (row 1 only:grep -zwith a literal newline is an OR — the working spelling isgrep -Pzwith\\n; row 2 withdrawn as duplicate on the card); each reading ADOPTED OR REJECTED one at a time with the reason on the PR, every adopted row paid by compression or deletion in the same file, ⛔ never a raise; ⛔ keep off rows :10–:12 and :431 (#18469 PR-A, awaiting the maintainer's hand) and :212 (PR #18666, awaiting approval); ⛔ #18461 is NOT in this batch — its row ② conflicts with #18421's reading and waits on that decision; #18446's landing-sequence half (「③ read after the strip」) lands incontract-review.md:41–:46 only if line-neutral there (60 / 60), else stays a row); governedreferences/**= the FACT layer ⇒ draft, lands on the seat's in-seat contract-tier review of record through the queue (ruling #17950), ⛔ no four-piece
Container & model:L(受管事实表五卡合一,逐条采纳,零余量支付),mode:subagent,model: claude-opus-5—node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack .claude/skills/pm-dispatch/references/platform-readings.mdat 2026-09-17T14:27Z on the fast-forwarded tree (f32f4805b): 「Model tier — no path-derived mandate … floor sonnet · default opus · ceiling fable」; default tier taken; the seat's contract-tier review at delivery
Clause-②: no
Thread-read: 5713976429
Serial constraints cleared: ONE PR for the five-card batch — this card is a SIBLING card folded into the carrier #18426's PR (its ownFixes #18446line lands it; if its reading is REJECTED the PR carriesPart of #18446and the seat re-queues it);platform-readings.mdopen-PR overlap at 2026-09-17T14:27Z: PR #18666 (:212, awaiting approval) only — keep off :212, mergeorigin/mainbefore enqueue;os-verify-lock.sh --statusat 2026-09-17T14:25Z: free; shared checkout atorigin/mainf32f4805b. Slot freed by #18456's delivery (PR #18681). Total order: the p2 Tasks of the 11:59Z–12:07Z routing, in card age, with the p3 rows (#18458 · #18467) folded because they share the one file; #18461 excluded (decision pending on #18421); #18664 · #18665 stay queued.
Ruling-ref: 5713976429
Generated by Claude Code
Batched onto PR #18689 (draft, governed FACT layer) — this card's reading is ADOPTED as one row at
platform-readings.md:85(118 B), paid by compressing the missing-command pair at:289; recorded in the generalised form this card's own addendum asks for (a label strip and a ready flip are both state writes, so pre-check ③ is read after the last one). Its second half was measured NOT line-neutral incontract-review.md(60 / 60; block:40–:46runs 99–120 B, cheapest adjacent merge 213 B), so per the dispatch the row carries the sequence and that file is untouched. Verdicts, payments and gate exit codes are on the PR.
Generated by Claude Code
LANDED — PR #18689 (the seven-card platform-readings batch, carrier #18426) merged through the queue at 2026-09-17T15:59:40Z (
merged_at), squash72dd95fa5(single parente75cc3c2f, an ancestor oforigin/main;platform-readings.md466 / 466 onmain, +17 / −17). Fact-layer landing on the seat's review of record —## Contract review5716694216 on the carrier card and 5717108355 on the PR thread (the Governed Surface Guard's merge_group leg reads the PR thread alone, so the first queue entry at 2026-09-17T15:14:52Z was dequeuedCI_FAILUREat 2026-09-17T15:36:18Z; re-queued 2026-09-17T15:38:54Z after the PR-thread record; #18701 filed). Landing criterion per the seat's publication register: MERGED through the queue, read frommerged_at.This card's row on
mainat :85: 「- 摘标签与翻 ready 是状态写,同 head 重起标签敏感检查 ⇒ ③ 在入队前末次状态写之后读。」. The card auto-closedcompletedon the PR'sFixes;pm:dispatchedis stripped in the same act.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
⛔ Filed bare and ungraded by the
domain:specexecution seat, sessionsession_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-16T11:1xZ.domain:*, type and priority are triage's. ⛔ Not claimed, ⛔ not dispatched. Routes to whichever lane owns.claude/skills/pm-dispatch/references/platform-readings.md.Dedupe keywords:
needs:contract-review strip,Check Changeset re-run,latest run per check name,stale aggregate,landing pre-check ③.The reading
Removing the
needs:contract-reviewlabel from a PR re-triggersCheck Changeseton the same head. Measured on PR #18438 today:commits/812a5bf565/check-runs— 35 names, 35 green, 0 pending, 0 failDELETE /issues/18438/labels/needs%3Acontract-review→ HTTP 200Check Changesetrun starts on the same headCheck Changesetstatus != completed,conclusion: nullsuccess; all 35 green againControl that the head did not move: the sha is byte-identical across all five readings (
812a5bf56595defe827cd27856f577e3699468ab).This is the #18370 hazard with a new trigger, and the trigger is the seat's own landing act.
Landing pre-check ③ («PR 全部 check 全绿») must be read as the latest run per check name, ⛔ not as "the set contains no failure". #18370 established that on a head carrying two
Check Changesetruns with opposite conclusions. What is new here: the carrier strip is step (2) of the landing sequence and the ③ reading is step (3), so a seat that follows the sequence in order reads a green aggregate that its own previous step has just invalidated. The window is about six seconds.⇒ the correct order is: strip the carriers, then re-read ③, ⛔ never reuse a ③ reading taken before the strip. On #18438 that is exactly what held the ready flip — the enqueue happened only after the third run completed.
This head ended up carrying 3
Check Changesetruns, 3Auto Label, 3Check PR Sizeand 2Packed-tarball smokeruns against 35 distinct names (42 runs total), so the multi-run shape is ordinary here, not exotic.Shape, ⛔ offered not specified
One row in the platform-readings fact table saying a label write re-triggers the label-sensitive checks, plus one line in the landing sequence saying ③ is read after the carrier strip. Whether the landing-sequence line belongs in
landing-operations.mdorcontract-review.mdis the owning lane's call.Generated by Claude Code