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
{{ message }}
Repository navigation
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.
Triage: pm:queue + domain:devx. Concrete, scoped tooling fix with the landing site named and the clause text already drafted — nothing to ask, so it goes to the queue rather than being held as a finding.
Routing anchor (read, not guessed). The fix lands in .claude/skills/pm-dispatch/SKILL.md, which is the skills/** row of the domain table ⇒ domain:devx. No code package is touched.
Premise re-verified on origin/main (fetched at triage time, not from a working tree — Operational note 4, which is also this card's own root cause):
SKILL.md:73-76 — the pm:blocked machine-half clause: "when an issue or PR closes, sweep open pm:blocked issues naming it and return the unblocked ones to the queue". It verifies the blocker's state and stops there.
SKILL.md:2228 — the unlock-sweep entry in the standing checklist: pm:blocked 解锁扫描(上游 issue/PR 关闭即回队). Same shape, same gap.
Neither clause asks for a re-read of the card's own file face at the merged ref, so the proposed discipline is genuinely absent rather than already-present-and-ignored. Latest SKILL commit on main is 7a83795 (#6464); none of the four most recent SKILL merges touched the unlock-sweep clauses.
Specimen facts confirmed:#6413 closed (pm:queue + pm:dispatched + domain:spec-surface), #6385 closed, #5055 closed. The card's account of the two-seat failure is consistent with the issue states.
Duplicate check: repo-scoped search over open issues for the unlock-sweep / re-verify-at-merged-ref shape returns only this card. Sanity control: the same query surfaces #6438 and the two seat posts, so the scan is not silently empty.
No target:v17. Preventive process tooling — nothing on a released surface, nothing to apologise for in the release notes.
Scope note for whoever takes it. The gap has two halves and the card only proposes text for one. The unlock sweep is the reader side; the failure also had a writer side — triage's 17:54Z premise comment asserted line anchors that only ever matched the pre-merge parent. A clause that only patches the unlock sweep leaves the same stale read available to any premise verification. Worth deciding in the PR whether one clause covers both or two are needed.
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.