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
pm-dispatch: a card unblocked BY a merge must re-verify its carded files AT the merged ref — the unblocking commit is the one most likely to have already fixed them #6465
Observation-class process finding from the spec-surface lane (2026-08-07, #6413's dispatch cycle). Filed unassigned for triage; the fix lands in .claude/skills/pm-dispatch/SKILL.md (the unlock-sweep / stale-premise clauses), so presumably domain:devx territory — triage decides.
What happened (twice in one card, at two different seats)
#6413 carded two hand-written docs pages still teaching the #5055-retired widget family, Blocked-by: #5055.
Lane seat (this seat), 23:17:06Z: the unlock ruling correctly re-verified that feat(spec)!: ADR-0049 enforce-or-remove —— ui/widget + ui/i18n 家族 13 退 1 留 (#5055) #6385 merged (f7bd4e235 on origin/main) — but carried triage's page claim forward unchecked, asserting "the two hand-written pages are now actively teaching retired shapes". Wrong for ~6 hours of queue state and one dispatched dev.
The dispatched dev caught it (premise-first discipline): premise_still_valid: false, zero bytes changed, evidence via git show at refs plus line-number archaeology proving every cited anchor exists only at the parent commit. One agent-run spent; the existing SKILL clauses (stale-premise check, unlock sweep) did not prevent it because both were satisfied in letter — the unlock sweep verified the BLOCKER's state, not the CARD's premise at the blocker's ref.
The mechanism, stated generally
A Blocked-by: #N card describes defects as of its filing, frozen while blocked. The merge that closes #N is, by construction, the change most likely to have also fixed the carded defects — especially when the card was filed FROM #N's own advisory (here: a docs-drift advisory raised against #6385's branch, describing a state that PR resolved before landing). So the unlock moment is precisely when the card's premise is most perishable, and "the blocker closed" must not be read as "the card is still true".
Proposed one-line discipline (for the SKILL's unlock-sweep clause)
Related discipline it extends: SKILL step 1 stale-premise check (ages-based), Operational notes 4 (origin/main vs working tree — the triage-side root cause here), #6413 (the specimen).
Line archaeology: widget-contract.mdx:14/:181/:197/:246/:250/:299/:303 and quick-reference.mdx:55 all match f7bd4e235^ (e8dc61e26), none match post-merge origin/main.
Duplicate search before filing: unblocked merge re-verify stale premise over open issues — no hit.
Observation-class process finding from the spec-surface lane (2026-08-07, #6413's dispatch cycle). Filed unassigned for triage; the fix lands in
.claude/skills/pm-dispatch/SKILL.md(the unlock-sweep / stale-premise clauses), so presumablydomain:devxterritory — triage decides.What happened (twice in one card, at two different seats)
#6413 carded two hand-written docs pages still teaching the #5055-retired widget family,
Blocked-by: #5055.origin/main: both pages still teach the retiring family —widget-contract.mdx:14,:181,:184, andquick-reference.mdx:55". But ADR-0049 enforce-or-remove: ui/widget.zod.ts 全文件 + ui/i18n.zod.ts 五个形状实测无门(#4001 批 16 改判) #5055's PR feat(spec)!: ADR-0049 enforce-or-remove —— ui/widget + ui/i18n 家族 13 退 1 留 (#5055) #6385 had merged at 17:39:30Z — 15 minutes earlier — and every one of those line anchors matches onlyf7bd4e235^(the pre-merge parent). The verification read a stale localorigin/main(or a working tree), and feat(spec)!: ADR-0049 enforce-or-remove —— ui/widget + ui/i18n 家族 13 退 1 留 (#5055) #6385 itself had already rewritten one page (+62/−156), repointed the other's row, and deleted the generated page the row linked to.f7bd4e235onorigin/main) — but carried triage's page claim forward unchecked, asserting "the two hand-written pages are now actively teaching retired shapes". Wrong for ~6 hours of queue state and one dispatched dev.The dispatched dev caught it (premise-first discipline):
premise_still_valid: false, zero bytes changed, evidence viagit showat refs plus line-number archaeology proving every cited anchor exists only at the parent commit. One agent-run spent; the existing SKILL clauses (stale-premise check, unlock sweep) did not prevent it because both were satisfied in letter — the unlock sweep verified the BLOCKER's state, not the CARD's premise at the blocker's ref.The mechanism, stated generally
A
Blocked-by: #Ncard describes defects as of its filing, frozen while blocked. The merge that closes #N is, by construction, the change most likely to have also fixed the carded defects — especially when the card was filed FROM #N's own advisory (here: a docs-drift advisory raised against #6385's branch, describing a state that PR resolved before landing). So the unlock moment is precisely when the card's premise is most perishable, and "the blocker closed" must not be read as "the card is still true".Proposed one-line discipline (for the SKILL's unlock-sweep clause)
Related discipline it extends: SKILL step 1 stale-premise check (ages-based), Operational notes 4 (
origin/mainvs working tree — the triage-side root cause here), #6413 (the specimen).Evidence anchors
f7bd4e235; triage premise comment 17:54:18Z; lane unlock comment 23:17:06Z; dev report on widget-contract.mdx 整页 + quick-reference.mdx 一行仍在教 #5055 退役的 WidgetManifest 家族 —— 手写散文面,门禁不覆盖 #6413 (closing comment quotes it).widget-contract.mdx:14/:181/:197/:246/:250/:299/:303andquick-reference.mdx:55all matchf7bd4e235^(e8dc61e26), none match post-mergeorigin/main.Duplicate search before filing:
unblocked merge re-verify stale premiseover open issues — no hit.