Commit e9efc40
fix(pm): give the clause-② declaration limb a self-solvable exit (#17738)
Fixes #17366
## The defect: a carrier a seat could write into and not get out of
The clause-② declaration limb had one carrier — the `Clause-②:` line
inside the card's
governing `Claim:` comment — and repairing a line already written there
was not an act every
seat can perform. The MCP GitHub tool set carries no
edit-an-issue-comment call; the claim
protocol forbids a second `Claim:`; and this gate's own refusal forbids
the checker filling
the line in ("the declaration IS the judgement"). Three closed doors,
and a seat that wrote
the line as prose was left waiting for somebody outside the repository
to retype it.
That was measured five times in one shift across two roles, and the
fifth instance was still
holding a PR with 38 checks and 0 failures out of the queue when the
card was filed.
## The fix: one correction comment, read by the same reader
A dedicated comment whose FIRST line is a fixed key naming, in digits,
the claim comment it
corrects:
```text
Clause-②-correction: 5642248126
Clause-②: no
Session: `session_01MCLBsUgfykL74aU716rzVK`
```
The newest correction naming the card's governing claim supersedes that
claim's declaration,
in both directions — so a wrong VALUE is repaired by the same act as an
unreadable one. The
declaration inside it is read by the SAME `CLAUSE2_KEY_LINE` through the
SAME
`readClause2Line`, so what moved is WHICH COMMENT may carry the
declaration, never what counts
as an answer. That is the move #16304 already made when it asked a
sibling CARD.
Attribution is the `Session:` line the claim protocol already makes
mandatory
(SKILL.md 〈模板与表〉, 「session ID 不可省」, and 「`mode:subagent` 的 dev 与 PM 同会话同
ID」 —
so the session is exactly the granularity of "the claiming seat"). A
correction is attributed
when its `Session:` equals the governing claim's. That is a DECLARED
identity, never a verified
one: the value is copyable text and this fleet writes under one GitHub
login, so the comparison
is on what the comments SAY — the same ceiling C4 already works at.
⛔ No branch of it may become a new one-way door, which is the defect
being removed. A
correction naming another comment, declaring a different session,
carrying no `Session:` line,
or carrying a prose declaration is IGNORED WITH A PRINTED REASON that
names an act the claiming
seat can perform. And a governing claim that carries no `Session:` line
at all leaves nothing to
compare: the correction APPLIES, with a note saying attribution could
not be verified and why.
Refusing there would have rebuilt the door one room over.
The C2 remedy text was rewritten to name WHO can act and HOW, in three
parts: the claim template
in SKILL.md 〈模板与表〉 that already carries the literal `Clause-②: yes | no`
line and should be
copied rather than composed; the fact that an already-posted claim
comment is not editable from
every seat; and the one comment that repairs it. It replaces "add the
line to that claim comment",
which named an act the claiming seat may have no tool for.
## What deliberately did not move
- **The accept set.** `CLAUSE2_KEY_LINE`, `readValueToken` and
`CLAUSE2_VALUES` are untouched. The
card's five measured prose spellings are pinned as negatives in the
self-test.
- **The exit register.** The correction is a new INPUT to C2, not a new
verdict family. 0/1/2/3/4
keep their meanings and their numbers.
- **`check-half-states.mjs`.** `CLAIM_COMMENT_MARKER` is still imported,
not restated, and not
widened. A correction is not a claim comment and never enters the claim
pool.
- **SKILL.md.** The template already carries the fixed line; this PR
points at it and does not
restate it.
- **The writes.** This script still writes nothing, hangs no label, and
reads no verdict word.
## Acceptance, all four from the card
1. **A seat writing per the template gets a machine-readable
declaration.** Pinned by importing
the reader over the template's own key with each value substituted, plus
the new remedy text
that sends the seat to the template rather than to a regex.
2. **The negative control holds.** All five measured spellings from the
card's table are pinned
as not-declared, from the line reader and from a claim comment. The `#1`
spelling is reported
as a SPELLING near miss; the `#2`–`#5` spelling reaches no pattern at
all, because 条款② carries
no `Clause` token — pinned as a measured fact.
3. **Self-solvability is pinned.** A card whose claim declaration is
unreadable earns a C2 finding;
adding ONE correction comment clears it, with the claim comment
byte-identical across the two
threads, no second `Claim:`, and the governing claim unmoved.
Demonstrated end to end through
the offline `--pair-json` path: `--pair` exit 4 with the broken claim,
exit 0 with the one
comment added.
4. **Ablation.** Deleting the correction reading reds 22 of 465
self-test cases (every criterion-3
case); deleting the template pointer and the who-can-act remedy reds 7
(criterion 1's new half).
Both legs were mutated on disk, proved to have landed, then restored to
a blob hash equal to
HEAD's.
## Acceptance notes
- 1 parent 396eae3 commit e9efc40
1 file changed
Lines changed: 578 additions & 23 deletions
0 commit comments