Commit d9ba33d
fix(pm): a retracted claim leaves the governing-claim pool, so a withdrawn claim never governs (#18770)
Fixes #18719
Clause-②: no
## The defect
`scripts/pm/check-clause2-carriers.mjs` built the governing-claim pool
from `CLAIM_COMMENT_MARKER` alone and then ranked it by recency, so the
pool was closed under addition: a claim entered it and nothing ever took
one out. A RETRACTION carries no `Claim:` line of its own, so it was
never in the pool and could not remove the claim it retracts — which
means the one act the protocol calls explicit (「释放是显式动作」) was the one
act the ownership arbiter could not see. The repair is not a re-sort:
every ordering of a pool that still holds the withdrawn record picks the
withdrawn record, and the next retraction is exactly as invisible. What
changes here is MEMBERSHIP — the selector READS the retraction, and
membership is resolved before recency.
## The #18373 counterfactual, re-derived offline
The six comment ids were fetched ONCE through the REST proxy and
replayed offline through `claimCarrierSelection` / `pairInputRecord`.
#18373 itself is `needs-user-decision` and another seat's; nothing here
re-grades it.
| | BEFORE (`main`) | AFTER (this PR) |
|---|---|---|
| governing claim | `5717315121` (`os-bill`) — **withdrawn by its own
author 84 seconds later** | `5717143021` (`os-litant`) |
| branch it names |
`claude/issue-18373-include-bare-directory-provenance` — **absent from
origin** | `claude/issue-18373-type-source-resolution-bare-dir-include`
— the one ref `git ls-remote origin 'refs/heads/claude/issue-18373*'`
returns |
| the live claimant | listed **SUPERSEDED** | in the pool, governing |
| the withdrawn claim | not mentioned as withdrawn at all | listed
**RETRACTED**, naming `5717333576` |
| `claim.selected` author | `os-bill` | `os-litant` — the card's only
assignee |
The BEFORE row is produced by REMOVING the retraction comment from the
same six rows, so it is a reading rather than a description. The AFTER
`claim.selected` line now names the author, which is the point of the
last row: the LABEL face (assignee `os-litant`) and the SELECTOR face
(governing claim's author) are printed where a reader compares them
instead of reconstructing the contradiction by hand. The assignee itself
is still not read on this path, and the record says so.
## The routes, on the four axes
Triage ruled **A** out as the deliverable (「修法是让选择器读到撤回」), so the choice
is B, C, or both read as ONE predicate. **Recommended: B and C as one
predicate**, which is what this PR implements.
**A — leave it; the selection is an input record.**
*实际业务需求*: fails on measurement. The printed block is a record, but the
POOL is not: `cardDeclaration` reads the pool for the `Clause-②`
declaration, the governing branch is what the liveness rows probe, and
the record is what a seat reads to decide who owns a card. *项目长远合理性*: a
monotone set standing in for a mutable fact (ownership) cannot express a
withdrawal at any ordering. *防 AI 写错*: the worst axis — an arbiter that
answers confidently with the wrong owner is worse than one that
declines, which is the triage's 「一个只会做加法的池子,和一个没有池子,危险方向相反但都不安全」.
*创业阶段不扩散*: cheapest, and that is its only argument.
**B — the `Release:` directive only.**
*需求*: real, and already declared: `AGENTS.md` :408 and `SKILL.md` :468 /
:470 / :496 make `Release:` the act that takes a card out of a seat's
hands, and `check-half-states.mjs` already exports
`RELEASE_COMMENT_MARKER` for H47. *长远*: the best-shaped half — one
declared spelling, contract-first, nothing inferred. *防 AI 写错*:
strongest, because it is 声明即强制. *不扩散*: adds nothing new at all. **⛔ But
measured, B alone does not close the case it was filed for**: the #18373
retraction carries NO `Release:` line — it is a bold opening line 「🚨
**撤回上一条认领(`5717315121`)…**」 posted with the assignee cleared. Under B
the counterfactual above stays red. B is necessary and not sufficient.
**C — skip a claim retracted by a later comment of the same author.**
*需求*: closes the measured case. *长远*: on its own C has no declared shape
— "retracts" still needs a predicate, and an unanchored one is a
natural-language matcher inside an ownership arbiter. *防 AI 写错*: C
without a declared act is the lenient-consumer shape the framework
rejects; its measured cost is in the next section. *不扩散*: C alone
invites the treadmill (#16170's lesson — close one spelling, leave the
next exactly as silent).
**B ∧ C, as ONE predicate — the recommendation.**
*需求*: closes the measured case AND reads the act the protocol already
declares. *长远*: one sentence — a claim leaves the pool when a LATER
comment BY THE SAME AUTHOR retracts it — read through two channels,
which is the shape `check-half-states.mjs` already uses for a block
(`Blocked-by:` directive plus `PROSE_BLOCKER_ANCHORS`). An in-family
reading, ⛔ not a new mechanism. *防 AI 写错*: every loosening is refused in
the direction that would let one seat void another's ownership — same
author, strictly later, the act OPENS the line, the line NAMES the claim
by comment id, fail-closed on an unreadable author on either side;
under-reading leaves the claim standing, which is today's behaviour.
*不扩散*: no governed text moves, no new label, no new request, no new
field in the record roster, one file.
⛔ No protocol text is changed: `Release:` is already the act and its
marker is IMPORTED rather than restated. Whether the protocol should
REQUIRE the `Release:` spelling of a retraction — which would let the
prose channel be retired — is a governed-text question and is raised in
the report's `open_questions`, ⛔ not answered here.
## The three shapes, each with its control
| shape | reads | control |
|---|---|---|
| (1) a retraction NAMING the claim by comment id | leaves the pool |
the SAME words from a DIFFERENT author retract nothing |
| (2) a `Release:` line from the claim's own author, no id | leaves the
pool | the same `Release:` posted BEFORE the claim retracts nothing |
| (3) a `Release:` / retraction from a DIFFERENT author | retracts
nothing | the live claimant's claim still GOVERNS, and is not merely
un-rejected |
Also pinned: a retraction naming some OTHER comment id; an unreadable
author on the retractor, and on the claim; the act buried mid-sentence;
decoration in front of the act (「- 1 parent 5100c42 commit d9ba33d
1 file changed
Lines changed: 478 additions & 19 deletions
0 commit comments