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
fix(pm): say the head sha sits in a code span of its own, and name the refused spelling (#18270)
Fixes#18141
`references/contract-review.md` :28 defined the review of record's shape
as 「所审 head sha 码段」 and
never said the span holds the sha ALONE. A seat reading it in good faith
writes the key and the sha
into ONE span; `H51_SHA_SPAN` matches a code span that is hex and
nothing else, so such a record
names no head and C6 reads 「no review of record on that head」 where a
complete review exists.
Taken by the file's own 「先删容许出错的构造,再让正确形态成唯一拼写」 order: the prose names
the one
correct spelling, and the reader keeps refusing the other while NAMING
it. The accept set is
unchanged — a second accepted spelling would be the trap's twin.
## What changed
- `.claude/skills/pm-dispatch/references/contract-review.md` :28 — 「所审
head sha 码段」 becomes
「所审 head sha 独占码段」, and the line sheds 「判词」 to pay for it. The file is
60 lines at its
60-line ceiling before and after; the touched line is 118 bytes (119
before). `check:pm-skill-ratchet`:
"contract-review.md is 60 lines (ceiling 60; headroom 0)".
- `scripts/pm/check-clause2-carriers.mjs` —
- `HEAD_KEY_IN_SPAN` + `headSpanHoldsKey(pair)`: a DIAGNOSIS, read only
AFTER the locator has
already answered `absent`. It chooses no comment, admits none, and
returns nothing for a comment
the locator can already read. The newest-of idiom is
`latestMarkedComment`, the same one the
locator resolves with — never a second one.
- C6's absent row is now two sentences: the empty case keeps 「a cleared
gate with nothing behind
it」, and a pair whose heading comment wrote the head inside the key's
span gets a row naming the
comment, quoting the span the seat actually wrote, and prescribing the
fix (key outside the span,
sha in a span of its OWN, `--template` prints the whole record).
- The shared shape sentence now names the one spelling on both branches.
- The docblock quotation of the rule line was updated in the same edit,
so the file does not quote
a sentence this PR replaced.
- 19 self-test cases in their own battery (658 before, 677 after; roster
floor 23, now 24).
## The measurements this PR was dispatched to take
**P1 — falsified in its live half; the mechanism half stands.** The
dispatch expected C6 to read
「no review of record」 for comment 5652813288 (PR #17986) today. Measured
on the exact bytes (GET,
not edited) against this tree:
```
contractReviewHeadMatch(body, head) = "db55ea6dd"
hex-only spans in the body: 884e834, fc28c1d, ..., db55ea6, 8cdd696, 53ded82bf7a494f54e344e19099dbf00854b8694
spans that prefix the head: db55ea6
key-in-span line ALONE: null
locateReviewOfRecord: { state: "found", id: 5652813288, sha: "db55ea6dd" }
```
Its `Head-sha:` span names nothing — the mechanism the card describes is
real — but the record is
still FOUND, because its own prose quotes the head in a bare span of its
own
("Cross-file staleness, searched at `db55ea6dd`"). So the sha C6 reports
for that record is read off
the prose and not off the line the seat wrote it on. Replayed end to end
through the CLI
(`--pair 17986 --pair-json`, verbatim bytes): no C6 row, the C6-RECORD
note naming `db55ea6dd`; exit 4
comes from C4 (`Implemented-by: branch …`, half written) and C7 (no
`Served-tier:` line), both facts
about that record that predate this PR. The defect is the SPELLING, not
that comment — the same
record trimmed to the spelling alone reads the refusal (below).
**P2 — holds.** `contractReviewRecordLines` prints `Head-sha: ` followed
by the sha in a span of its
own, and the `--template` note already says "7 to 40 hex in a span of
ITS OWN; a span holding the key
as well is not a sha". The prose now agrees with it, and the self-test
derives its refused fixture by
COLLAPSING the template's own line rather than retyping the key — a
template that renamed the key
reds this battery instead of drifting past it.
**P3 — the distinction was absent; it is the sentence that was added.**
Before this PR both cases
printed 「a cleared gate with nothing behind it, indistinguishable from
never reviewing」. Pinned
three ways now: a bare-sha span record reads `found`; a key-in-span
record is `absent` AND earns the
refusal naming the spelling; a comment with no heading is the plain
absence with no spelling
sentence.
**P4 — holds, pinned.** `locateReviewOfRecord` chooses the same comment
it chose before: a refused
spelling is never chosen over a correct record and never chosen at all
(pinned in both arrival
orders, and the pair with a correct record earns no C6 row and no
spelling sentence).
## Reverse verification
- Ablation (fix committed first, mutation proved on disk, restored
byte-identical): replacing
`const keyed = headSpanHoldsKey(pair);` with `const keyed = null;` turns
**5 of 677** self-test cases
red (`ABLATED EXIT=1`). Mutated blob `a3d4174b` vs HEAD blob `af1a124a`;
after restore the blob is
`af1a124a` again and `git diff HEAD` is empty. An earlier run of the
same ablation moved only 3
cases — two pins were reading a comment count and a thread name, which
survive the ablation; both
were retied to the sentence the branch composes and are in the 5.
- Offline replay of the refused spelling (`--pair 17986 --pair-json`,
the record trimmed to comment
5652813288's spelling): exit 4, one row, C6, reading
「⚠️ The SPELLING is why, and this pair is NOT the empty case: the PR
thread's comment 5652813288
… writes this head INSIDE one code span, as `Head-sha:
db55ea6`」
with the remedy naming the span of its own and `--template`.
- Live control, a pair carrying a correct record: `--pair 18256` still
exits 0 with the C6-RECORD note
on comment 5674761187 (head `c96b507db288c20bf270c66c6137dc6fa7e79576`).
## Gates
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, no
paths, reconciled with `--ran`:
```
Run reconciliation — 42 derived, 42 run, 0 NOT-MEASURED, 0 UNRUN.
EXIT CODES — all 42 accounted famil(ies) carry one, so the NOT-MEASURED count above is DERIVED from them.
```
`pnpm --filter @objectstack/lint run check:doc-formula-expressions`
first exited **3** (PREREQUISITE
NOT MET — `@objectstack/formula` and `@objectstack/lint` unbuilt). Built
under the shared verify lock
and re-run: exit 0. `pnpm check:pm-dispatch-gates` ran to completion
(exit 0), not cap-killed.
`pnpm check:pm-clause2-carriers`: 677 cases pass.
Lint, as a proved narrowing rather than a repo sweep: `pnpm lint` is
`eslint . --no-inline-config`;
of this diff's two paths only `scripts/pm/check-clause2-carriers.mjs` is
inside eslint's own
population — the `.md` comes back "File ignored because no matching
configuration was supplied".
`--format json` returns 2 entries, 1 linted, 0 errors, 0 warnings.
`eslint.config.mjs` states of
itself that it "never enables type-aware linting (no
`parserOptions.project`, no typed
`@typescript-eslint` rules) for ANY file", so this diff cannot move the
verdict of a file it does not
contain. No package typecheck is owed: the diff is one `.mjs` under
`scripts/` and one `.md`.
Union head: the readings above were taken at `c3533346`.
## Deviation from the dispatch
The dispatch said the clause is "paid by density" at 60/60.
`.claude/agents/os-dev.md` states that
the only legal currency for the line ratchet is DELETED CONTENT and that
a re-wrap must never buy a
line for new content, so folding two clauses into one line to free a
61st was not available, and no
clause in this file is redundant enough to delete. The clause therefore
lands INSIDE :28: the file
never grows, the ceiling row is untouched, and the payment is 「判词」,
whose fact is carried by the
`PASS/FAIL` token it stood behind. Flagged here rather than chosen
silently.
## Acceptance notes
- noted, not filed: `contractReviewHeadMatch` scans the WHOLE comment,
so the head it reports can
come from a span in the prose rather than from the record's own
`Head-sha:` line — which is how
comment 5652813288 reads `found` today despite the refused spelling.
H51's declared shape is "the
head sha written as a code span somewhere in the comment", so this is
declared behaviour, not a
contract violation; it does mean the trap is survivable for some records
and not others. Successor:
whoever next touches H51's recognition shape.
- noted, not filed: that same record carries `Implemented-by: branch
claude/…` (C4 half-written) and
no `Served-tier:` line (C7). Both are already recorded on the card; a
merged record is not edited.
## 维护者速读(草稿)
**改了什么** —— 契约复核记录的 head sha 从此必须单独占一个码段:`contract-review.md` :28 的措辞改成
「所审 head sha 独占码段」,并由同一行删去「判词」买单(文件仍是 60 行,不动天花板)。机读一侧,
`check-clause2-carriers.mjs` 在判定「本 head 无复核记录」之后,额外说出**为什么**:如果有人把
`Head-sha:` 和 sha 写进同一个码段,这条 C6 行会点名那条评论、引用他写的码段,并给出一次就能改对的修法。
**为什么改** —— 旧措辞只说「head sha 码段」,照字面写就会落进读不出的拼写:一份完整的复核记录,机器读
起来和「根本没人复核」完全一样。先让正确形态成为唯一拼写,再让拒收带上理由。
**风险与代价(含回滚)** —— 受理集合没有变宽:被拒的拼写仍然被拒,定位器选哪条评论一字未动(两个到达
顺序都已钉住)。新增的只是一句诊断文案与 19 条自测。回滚 = revert 本 PR,无数据、无产物、无发布面。
**席位意见** ——
**你要做的** —— 这是 `references/` 层受管面,按 Prime Directive #14 走席内契约档复核 → ready
→ 入队,
不需要维护者逐条拍板;若对「删掉『判词』来买行」这笔密度支付有异议,请在此处说一句,我按你的说法改。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
`the heading and writes this head INSIDE one code span, as \`Head-sha: ${keyed.sha}\`. A span is read as a `+
3030
+
'sha only when it is hex and nothing else, so a span carrying the key as well names no head, and a complete '+
3031
+
`review written that way reads here exactly like no review at all. ${shape} Remedy: the reviewing seat `+
3032
+
'reposts the record with the key OUTSIDE the span and the sha in a span of its OWN -- `--template` prints '+
3033
+
'the whole record -- and cites it in the provenance comment beside the clear. '+
3034
+
`${boundary}${NEVER_WRITES}`
3035
+
);
3036
+
}
3037
+
return(
3038
+
`${read} This is the shape the filing sweep measured five times in one window -- a cleared gate `+
2960
3039
`with nothing behind it, indistinguishable from never reviewing. ${shape} Remedy: the owning seat writes down `+
2961
3040
'the review it already performed, in that shape, on the PR or the card, and cites it in the provenance comment '+
2962
3041
`beside the clear. ${boundary}${NEVER_WRITES}`
@@ -4969,6 +5048,50 @@ export function selfTest() {
4969
5048
t('the offline document serves the PR thread from the same `comments` bag, keyed by the PR number',Array.isArray(pairJsonReader({pulls: DOC.pulls,comments: {13910: []}}).readCardComments('owner/name',13910)));
4970
5049
t('…and one it omits reads null — UNJUDGED, ⛔ never a missing record',pairJsonReader({pulls: DOC.pulls}).readCardComments('owner/name',13910)===null);
4971
5050
5051
+
// -- #18141: the head sha's span holds the sha ALONE -----------------------
5052
+
//
5053
+
// ★ The trap, both halves. `references/contract-review.md` :28 said only
5054
+
// 「head sha 码段」, so a seat reading it in good faith wrote the key and the
5055
+
// sha into ONE span -- the live corpus spelling -- and a span is read as a
5056
+
// sha only when it is hex and nothing else, so that record names no head and
5057
+
// a complete review reads exactly like a pair nobody ever reviewed. The prose
5058
+
// now says 「独占码段」. Here the reader pins that the refused spelling stays
5059
+
// REFUSED -- ⛔ a second accepted spelling would be the trap's twin -- and
5060
+
// that the row NAMES it, so the seat's next act is one respell, not a hunt.
5061
+
battery('#18141: the head sha sits in a span of ITS OWN — the key-in-span spelling, refused and NAMED');
5062
+
// ⛔ Derived by collapsing the TEMPLATE's own line, never retyped: the key the
5063
+
// diagnosis matches is the key `--template` prints, so a template that
5064
+
// renamed it reds here instead of leaving this battery green about nothing.
t('⭐ the template writes the key OUTSIDE the span, and that record names the head',IN_SPAN!==OWN_SPAN&&contractReviewHeadMatch(OWN_SPAN,HEAD_9AF9)===HEAD_9AF9);
5072
+
t('⛔ …and the SAME record with the key folded INTO the span names no head — the defect isolated to the fold',contractReviewHeadMatch(IN_SPAN,HEAD_9AF9)===null);
5073
+
t('⛔ so it is not a review of record: the accept set is still exactly one spelling',reviewOfRecord(keyedPair).state==='absent');
5074
+
t('…and the pair is a C6 row, exactly as if nothing had been written',typeofkeyedRow==='string');
5075
+
t('⭐ but the row NAMES the spelling, quoting the span the seat actually wrote',says(keyedRow,`\`Head-sha: ${HEAD_9AF9}\``)&&says(keyedRow,'comment 3401'));
5076
+
t('…and says WHERE it read it, so the seat opens the right thread',says(keyedRow,"the PR thread's comment 3401"));
5077
+
t('…and prescribes the fix in the rule\'s own words — key outside, sha in a span of its OWN',says(keyedRow,'in a span of its OWN')&&says(keyedRow,'所审 head sha 独占码段'));
5078
+
t('…pointing at the template as the thing to COPY, never a shape to compose',says(keyedRow,'`--template`'));
5079
+
t('⛔ and it is a DIFFERENT sentence from the empty case — the two stopped printing alike',says(keyedRow,'The SPELLING is why')&&!says(keyedRow,'indistinguishable from never reviewing')&&says(absentRow,'indistinguishable from never reviewing')&&!says(absentRow,'The SPELLING is why'));
5080
+
t('⛔ verdict-agnostic and never writes, exactly like the sentence it stands beside',says(keyedRow,'PASS half')&&says(keyedRow,'自查放行'));
5081
+
t('⛔ a heading-less comment carrying the head is the plain absence, not this diagnosis',headSpanHoldsKey(bare({cardComments: [CLAIM('Clause-②: yes'),SEAT_ACCEPT]}))===null);
5082
+
t('⛔ a keyed span naming an OLDER head is the plain absence too — this row speaks about THIS head',headSpanHoldsKey(bare({prComments: [{ ...KEYED_ROW,body: IN_SPAN.replace(HEAD_9AF9,'facefeed')}]}))===null);
5083
+
t('⛔ and a head too short to match is refused before any of it — unreadable is not a spelling verdict',headSpanHoldsKey(bare({headSha: 'abc',prComments: [KEYED_ROW]}))===null);
5084
+
t('the NEWEST refused spelling is the one named, when a thread carries two',headSpanHoldsKey(bare({prComments: [KEYED_ROW,{ ...KEYED_ROW,id: 3405,created_at: '2026-09-01T09:10:00Z'}]}))?.id===3405);
5085
+
// ⭐ The live corpus specimen's own shape: the refused line, and the head
5086
+
// quoted in a bare span somewhere in the prose. It reads FOUND today -- the
5087
+
// spelling is the defect, not that comment -- and this diagnosis stays silent.
5088
+
constRESCUED={id: 3402,created_at: '2026-09-01T08:51:00Z',body: `${IN_SPAN}\n\nCross-file staleness, searched at \`${HEAD_9AF9}\`.`};
5089
+
t('⭐ the refused line BESIDE a bare sha span elsewhere in the prose reads FOUND — and is not this finding',reviewOfRecord(bare({prComments: [RESCUED]})).state==='found'&&headSpanHoldsKey(bare({prComments: [RESCUED]}))===null);
5090
+
t('⭐ a correct record beside a refused one is FOUND, in either arrival order',reviewOfRecord(bare({prComments: [KEYED_ROW,NEWER_RECORD]})).state==='found'&&reviewOfRecord(bare({prComments: [RECORD(HEAD_9AF9,undefined,'2026-09-01T08:45:00Z',3404),KEYED_ROW]})).state==='found');
5091
+
t('…and the locator chooses the CORRECT one — a refused spelling is never chosen over it, and never chosen at all',locateReviewOfRecord(bare({prComments: [KEYED_ROW,NEWER_RECORD]})).id===3403&&locateReviewOfRecord(bare({prComments: [RECORD(HEAD_9AF9,undefined,'2026-09-01T08:45:00Z',3404),KEYED_ROW]})).id===3404);
5092
+
t('…so no C6 row and no spelling sentence on a pair that has a real record',c6NoReviewOfRecord(bare({prComments: [KEYED_ROW,NEWER_RECORD]}))===null);
5093
+
t('the PROSE, the template and the reader name ONE spelling — and the template still round-trips',says(keyedRow,'独占码段')&&contractReviewHeadMatch(contractReviewTemplateLines({headSha: HEAD_9AF9}).join('\n'),HEAD_9AF9)===HEAD_9AF9);
5094
+
4972
5095
4973
5096
// -- C7: the tier that SERVED the verdict the strip stands on (#17915) -----
0 commit comments