Skip to content

Commit 1831836

Browse files
fix(pm): read a record's Head-sha line only below its heading, refuse an unreadable one at write time, and name the line in the rules (#28042)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DHcz5tQsg7ziuDgABaqcfbH)_ domain:skills#2 · os-elon-musk · session_016WV4czYNVYrGQqbs51hpvv Fixes #28024 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:契约复核记录「审的是哪个 head」现在只从它自己 `## Contract review` 题头**之下**、第一条不带引用块、不带列表符、不在代码围栏里的 `Head-sha:` 行读;题头之前、引用、列表、围栏里的 `Head-sha:` 行一律当散文。写入侧 `post-stamped.mjs` 在发评论前就拒收「带 `Head-sha` 键但读器读不出 head」的记录。规则文 `contract-review.md:33` 点名这一行。4 个文件,+141/−32,无新门禁。 - 为什么改:PR #28023 之后读器取的是全文第一条 `Head-sha:` 键行,且容忍引用块和列表符。于是一条引用别人记录的 `> Head-sha: B` 若排在自己那行之上,记录就被读成「审过 B」(复核探针实测:在 B 找到、在真 head 缺席)。这是三条 should-fix 里唯一能放进错 head 的一条,另两条是让作者早点知道。 - 风险与回滚:只收紧不放宽。实测 2026-10-23 至 30 的 709 条题头记录:707 条本来就是题头下的裸行,2 条无 `Head-sha` 键(已知旧写法,PR 已合并),0 条在新读法下读数改变。读不出的记录读为「无 head」,补发一条正确的记录即可;写入侧的拒收会在发出前就说明哪一行坏了。回滚即 revert。 - 先看:`scripts/pm/check-half-states.mjs` 的 `contractReviewHeadSha` 与 `CONTRACT_REVIEW_HEAD_SHA_LINE`(所有读者只经这一个函数取 head);`scripts/pm/post-stamped.mjs` 的 `recordKeyedLineRefusals`(导入同一读器,不重拼);`.claude/skills/pm-dispatch/references/contract-review.md:33`。 - 两分钟验证:`node scripts/pm/check-half-states.mjs --self-test && node scripts/pm/post-stamped.mjs --self-test`,预期两者 exit 0(5102 与 743 例),其中含「引用行在上、真行在下:在引用 head 缺席、在真 head 找到」的钉子。 - 需要你做的:无。本 PR 触及 `.claude/**` 受管规则文,欠一轮契约复核(席位安排,CONTRACT_REVIEW_TIER);落地档位以登记册为准(`check-governed-merges.mjs --test` 读为 Tier S,`--pr` 在 PR 上再读一次)。 ## What changes Follow-up to PR #28023 (#27979), closing its review's should-fixes 1–3. Triage ruling: edge 1 is the one that can admit a wrong head; edges 2 and 3 are loudness; no new gate. - **Edge 1 — the reader** (`scripts/pm/check-half-states.mjs`). `contractReviewHeadSha(body)` now returns the span on the FIRST `Head-sha:` line BELOW the record's own `## Contract review` heading (read with `CONTRACT_REVIEW_HEADING_MARKER`, blockquoted heading included, exactly as the locator finds the record), skipping every line inside a fenced code block (three or more backticks or tildes; an unclosed fence runs to the end, as it renders). `CONTRACT_REVIEW_HEAD_SHA_LINE` drops the blockquote and bullet tolerances the `keyLineRegex` convention keeps for `Served-tier:`, `Reviewed-by:` and `Local-runs:`: those values describe the record; this line decides which head a PASS clears, and a quoted or bulleted `Head-sha:` line is one the author cited rather than wrote. Bold and backticks on the key, a trailing span on the line, and CRLF still read. Every reader reaches the head through this one function — `latestContractReviewOnHead` (H43), `locateReviewOfRecord`, owed-reviews `recordReading`, the queue guard's `recordVerdict` — so they move together; no other file changes a predicate. - **Edge 3 — the write side** (`scripts/pm/post-stamped.mjs`). `recordKeyedLineRefusals` refuses a `## Contract review` comment that carries a `Head-sha` key anywhere (case-blind presence test) for which the imported `contractReviewHeadSha` reads `null`, before the write and beside the existing `Local-runs:` row; a record with no key at all is not re-judged (the two retired-dialect records carry none). `RECORD_KEY_SPELLINGS` prints the accepted shape; the refusal names the owner. Imported from `check-half-states.mjs`, which the file already imports at module scope — no new edge, no cycle (both self-tests that load the graph pass). - **Edge 2 — the rules text** (`.claude/skills/pm-dispatch/references/contract-review.md:33`). 「head sha 独占码段」 becomes 「`Head-sha:` 行独占码段」. 60 lines before and after; the line is 117 bytes under the 120-byte cap. - **Pins.** H51 battery (`check-half-states.mjs`): the four probe shapes from the #28023 review — a `Head-sha:` line naming another head placed before the heading, blockquoted, bulleted, fenced, each above the record's own — read absent at the cited head and found at the real one; a quoted, bulleted or fenced line alone, a line with no heading above it, and a line inside an unclosed fence name no head; tilde fence and CRLF. Locator battery (`record-recognisers.mjs`, floor 10 to 13): the same shapes through `locateReviewOfRecord` on the PR thread and the card. `post-stamped.mjs` battery (floor 9 to 17): each unreadable shape refused, the quoted-above-real shape passes, absent not re-judged, both rows together, the structural import pin now covers both readers. ## Tests Self-tests on the committed head `fd3f1f3e`, exit codes captured before any pipe: | Command | Exit | Cases | |:--|:--|:--| | `node scripts/pm/check-half-states.mjs --self-test` | 0 | 5102 (5089 on the base of #28023) | | `node scripts/pm/record-recognisers.mjs --self-test` | 0 | 336 | | `node scripts/pm/post-stamped.mjs --self-test` | 0 | 743 across 26 batteries | | `node scripts/pm/check-owed-reviews.mjs --self-test` | 0 | 65 in 9 batteries | | `node scripts/pm/check-governed-queue-guard.mjs --self-test` | 0 | 403 | Ablations, one per new leg, through `scripts/ablation-replace.mjs` (anchor hit 1 to 0, blob hash moved, restored to the HEAD blob with `git diff HEAD` empty on every leg): | Leg | Mutation | Red pins | |:--|:--|:--| | heading scope | `let belowHeading = true` | half-states 3 of 5102, recognisers 1 of 336 (the pre-heading pin), post-stamped 1 of 743 | | blockquote / bullet refusal | `(?:>[ \t]*)?(?:[-*][ \t]+)?` restored into the key regex | half-states 3, recognisers 2, post-stamped 4 | | fence skip | `if (fenced && false) continue` | half-states 4, recognisers 2, post-stamped 1 | | write-time refusal | `if (false && …)` in `recordKeyedLineRefusals` | post-stamped 5 of 743 | A first attempt at the heading-scope leg mutated the assignment inside the loop (`belowHeading = true; continue`), which also skipped the first line and so stayed green; it was discarded and re-run as the initialiser mutation above. Both runs are in the report. ## Acceptance notes - **Measured before changing the accept set** (REST `issues/comments?since=2026-10-23`, 113 pages, 11,236 comments, at `origin/main` `e1dde1a5c`): 709 bodies with a line-initial `## Contract review`; 707 carry their first readable `Head-sha:` line plain and below the heading; 2 carry no `Head-sha` key (6360650327 on PR #25399, 6397040906 on PR #25774 — the retired dialects, both PRs merged); 0 blockquoted, bulleted, bold-key, backticked-key, fenced or pre-heading first lines; 0 blockquoted headings; 1 body with more than one `Head-sha` key line (the #28023 review record, whose prose names the key mid-sentence; its first line is the real one). 0 records read differently under the new reader. - `keyLineRegex` still tolerates blockquote and bullet for `Served-tier:`, `Reviewed-by:` and `Local-runs:`; only the head line is stricter, for the reason in its docblock. Not changed here. - The template's null-oid placeholder is 40 hex and reads as a head, so `post-stamped` does not refuse a pasted template; C6 refuses it at the locator, as before. - Scope: exactly the four files the claim names (record-recognisers.mjs for pins only). No production predicate outside `check-half-states.mjs` and `post-stamped.mjs` moved. - `skip-changeset`: `scripts/pm/**` and `.claude/**` only, nothing published. ## Verification Local gates on the committed head `fd3f1f3e`, from a second worktree at the same commit (`pnpm install --frozen-lockfile --ignore-scripts`, then `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` for the formula gate), exit codes captured before any pipe: - `node scripts/pm/dispatch-gates.mjs --commands` derived 56 families for the 4 changed paths (+141 / −32, under the human-merge threshold). - All 56 ran and exited 0 — among them `check:pm-half-states`, `check:pm-post-stamped`, `check:pm-record-recognisers` (recognisers + owed-reviews + mailbox-open + fleet-roster self-tests), `check:pm-governed-merges`, `check:pm-dispatch-gates`, `check:pm-skill-id-lint`, `check:pm-skill-ratchet` (the line budget and the 120-byte line cap), `check:skill-frame-sync`, `check:commit-card-trailers`, `check:nul-bytes`, `check:scripts-symbol-anchors`. - `node scripts/pm/dispatch-gates.mjs --ran ran.txt`: 56 derived, 56 run, 0 NOT-MEASURED, 0 UNRUN (exit 0). - `pnpm lint` (the repo-wide ESLint sweep) is CI-owned and was not run locally; read it off the PR check-runs. - Landing tier: `node scripts/pm/check-governed-merges.mjs --test` on the four paths answers Tier S (`.claude/**` ×1, the three `scripts/pm/**` paths not on the register); the seat reads `--pr` on this PR. --- _Generated by [Claude Code](https://claude.ai/code/session_016WV4czYNVYrGQqbs51hpvv)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2f2c6b9 commit 1831836

4 files changed

Lines changed: 169 additions & 33 deletions

File tree

‎.claude/skills/pm-dispatch/references/contract-review.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
- 新 head 即清;点名现 head 时 (b) 不起;条件满足由持有车道挂等复核标记或落交接行。
3131
- 逾 24 小时条件未满的 hold 列入分诊轮次记录(`check-owed-reviews.mjs` 标出)。
3232
- 复核记录 = 一条评论落 PR 或卡,席内与子代理同形;散文、dev 自评、`os-dev-report` 恒不算。
33-
- 同形 = `## Contract review` 题头、head sha 独占码段、①②③ 逐项、独立性对、PASS/FAIL。
33+
- 同形 = `## Contract review` 题头、`Head-sha:` 行独占码段、①②③ 逐项、独立性对、PASS/FAIL。
3434
- 同形含首行 `Served-tier:`:值写该面所定档的常量名 `CONTRACT_REVIEW_TIER` 或 `TIER_DEFAULT`;
3535
无此行不成裁决;模板 `node scripts/pm/record-recognisers.mjs --template`,申报面加 `--face declaration`。
3636
- 同形带 `Local-runs:` 行:`none` 或 `probe — REASON` 具名唯一探针;有行必校,缺行旧记录不改判。

‎scripts/pm/check-half-states.mjs‎

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12641,9 +12641,21 @@ export const H51_SHA_SPAN = /`([0-9a-fA-F]{7,40})`/g;
1264112641
* The `Head-sha:` key line — the ONE place a contract-review record names the
1264212642
* head it reviewed.
1264312643
*
12644-
* The key half is `record-recognisers.mjs`'s `keyLineRegex` convention, spelled
12645-
* here because that file imports this one: optional blockquote, bullet, bold
12646-
* and backticks around the key, then the colon. The VALUE is a hex code span of
12644+
* The key half is `record-recognisers.mjs`'s `keyLineRegex` convention WITHOUT
12645+
* its two positional tolerances, spelled here because that file imports this
12646+
* one: bold and backticks around the key are tolerated, then the colon. ⛔ A
12647+
* leading blockquote or list bullet is NOT — `keyLineRegex` admits both for
12648+
* `Served-tier:`, `Reviewed-by:` and `Local-runs:`, whose values describe the
12649+
* record itself, but this line decides WHICH HEAD a PASS clears, and a quoted
12650+
* or bulleted `Head-sha:` line is one the author CITED rather than wrote (a
12651+
* review quoting the seat's hand-off, a record quoting an earlier record), so
12652+
* a reader that took it read a quoted sha as reviewed. The key may be indented
12653+
* by at most three spaces, CommonMark's limit before a line becomes an
12654+
* INDENTED CODE BLOCK: four spaces or a tab render the line as code, which is
12655+
* a quotation too, so the regex refuses them. `contractReviewHeadSha`
12656+
* adds the two positional rules a single-line regex cannot carry: the line
12657+
* sits BELOW the record's own UNQUOTED `## Contract review` heading and
12658+
* outside any fenced code block. The VALUE is a hex code span of
1264712659
* its OWN — the shape `--template` prints — and it is the FIRST thing after the
1264812660
* colon (spaces and bold may precede it, ⛔ nothing else); what follows the span
1264912661
* on that line is prose and decides nothing. A key folded into the span with
@@ -12652,24 +12664,75 @@ export const H51_SHA_SPAN = /`([0-9a-fA-F]{7,40})`/g;
1265212664
* decoration and the value then opens with hex rather than a backtick, so the
1265312665
* record names no head — the accept set stays exactly one spelling. A bare hex
1265412666
* value with no span, a lowercase key and a span below the floor name no head
12655-
* either; the repair for every one of them is on the WRITE side.
12667+
* either; the repair for every one of them is on the WRITE side, where
12668+
* `post-stamped.mjs` refuses a record carrying a `Head-sha` key this reader
12669+
* cannot read BEFORE the write.
1265612670
*/
1265712671
export const CONTRACT_REVIEW_HEAD_SHA_LINE = new RegExp(
12658-
`^[ \\t]*(?:>[ \\t]*)?(?:[-*][ \\t]+)?(?:\\*\\*)?\`?Head-sha\`?(?:\\*\\*)?[ \\t]*:(?:[ \\t]|\\*\\*)*${H51_SHA_SPAN.source}`,
12672+
`^[ ]{0,3}(?:\\*\\*)?\`?Head-sha\`?(?:\\*\\*)?[ \\t]*:(?:[ \\t]|\\*\\*)*${H51_SHA_SPAN.source}`,
1265912673
);
1266012674

1266112675
/**
12662-
* The head a contract-review record names — the span on its first `Head-sha:`
12663-
* line, as written (case kept), or `null` when no line reads.
12664-
*
12665-
* First line wins, as `readServedTier` reads its key: a record is one comment
12666-
* and names one head, and a later `Head-sha:` line (a quoted record, say) is
12667-
* prose to this reader. Not judged against any head here — that is
12668-
* `contractReviewHeadMatch`'s half — so a caller can also ask which head a
12669-
* record is ABOUT, which the sentence a patrol prints needs.
12676+
* A fence line, as CommonMark spells one: three or more backticks or tildes at
12677+
* the line start (up to three spaces of indent). The run is captured because a
12678+
* fence CLOSES only on the same character with a run at least as long as the
12679+
* one that opened it: a shorter run, or the other character, is content of the
12680+
* open fence (a nested ``` inside a ```` block, a ~~~ inside a ``` block), and
12681+
* reading past either would read fenced content as the record's line. An
12682+
* unclosed fence runs to the end of the body, as it renders.
12683+
*/
12684+
const FENCE_LINE = /^[ ]{0,3}(`{3,}|~{3,})/;
12685+
12686+
/**
12687+
* The head a contract-review record names — the span on the first `Head-sha:`
12688+
* line BELOW its `## Contract review` heading, as written (case kept), or
12689+
* `null` when no such line reads.
12690+
*
12691+
* Three positional rules, each measured in the review of the line-form reader
12692+
* (2026-10-30) as a way a sha the author never reviewed became the record's
12693+
* head: a `Head-sha:` line placed BEFORE the heading, a blockquoted or
12694+
* bulleted one, and one inside a fenced code block — each naming another head
12695+
* ABOVE the record's own line — read as the head, so the record was found at
12696+
* the cited head and absent at the real one. None is prose to a first-line
12697+
* reader, and all four shapes are what a quotation looks like. So: lines
12698+
* before the first UNQUOTED heading-marker line are skipped — the heading is
12699+
* read with `CONTRACT_REVIEW_HEADING_MARKER`, but a blockquoted heading opens
12700+
* nothing here, because a fully quoted record (heading, head line and
12701+
* signature all under `>`) followed by a plain line opening `Head-sha:` would
12702+
* otherwise hand the quoted record's signature to the plain line's head; the
12703+
* locator still finds such a comment as a record, and it then names no head.
12704+
* A fenced line is skipped, fence boundaries included, with the fence closed
12705+
* only by its own character and length (`FENCE_LINE`); and
12706+
* `CONTRACT_REVIEW_HEAD_SHA_LINE` itself refuses the blockquote, the bullet
12707+
* and an indented-code line. Among the lines that remain, the FIRST wins, as
12708+
* `readServedTier` reads its key: a record is one comment and names one head,
12709+
* and a later `Head-sha:` line (a quoted record, say) is prose to this reader.
12710+
* Measured on the 709 records with a line-initial heading posted to this
12711+
* repository in the week to 2026-10-30: 707 carry the line plain and below
12712+
* the heading, 2 carry no `Head-sha` key at all (the two retired-dialect
12713+
* records), and 0 read differently under these rules than under the
12714+
* first-line-anywhere reader they replace.
12715+
*
12716+
* Not judged against any head here — that is `contractReviewHeadMatch`'s half
12717+
* — so a caller can also ask which head a record is ABOUT, which the sentence
12718+
* a patrol prints needs, and which `post-stamped.mjs` asks before it writes a
12719+
* record: a body carrying a `Head-sha` key that reads `null` here is refused.
1267012720
*/
1267112721
export function contractReviewHeadSha(body) {
12722+
let fence = null; // the OPEN fence — its character and run length — or null outside one
12723+
let belowHeading = false;
1267212724
for (const line of String(body ?? '').split(/\r?\n/)) {
12725+
const f = FENCE_LINE.exec(line);
12726+
if (f !== null) {
12727+
if (fence === null) fence = { ch: f[1][0], len: f[1].length };
12728+
else if (f[1][0] === fence.ch && f[1].length >= fence.len) fence = null;
12729+
continue;
12730+
}
12731+
if (fence !== null) continue;
12732+
if (!belowHeading) {
12733+
belowHeading = CONTRACT_REVIEW_HEADING_MARKER.test(line) && !/^\s*>/.test(line);
12734+
continue;
12735+
}
1267312736
const m = CONTRACT_REVIEW_HEAD_SHA_LINE.exec(line);
1267412737
if (m) return m[1];
1267512738
}
@@ -33452,8 +33515,32 @@ Doubles as the fire's **write self-check** (step 0). \`201\` is not the reading.
3345233515
const DELTA51 = RECORD51(OLDHEAD51, `\nThe PR has since moved to \`${HEAD51.slice(0, 8)}\` (seat comment 6515952505); this record judges \`${OLDHEAD51.slice(0, 8)}\` alone. Runs cancelled by the push of \`${HEAD51.slice(0, 8)}\`; landing waits on \`${HEAD51}\`.\n`);
3345333516
t('⛔ record reader: a delta record on head A whose PROSE names head B is NO review of B', latestContractReviewOnHead([cm51(1, DELTA51, T51)], HEAD51), null);
3345433517
t('⭐ record reader: …and IS the review of A — the `Head-sha:` line alone decides', latestContractReviewOnHead([cm51(1, DELTA51, T51)], OLDHEAD51)?.sha, OLDHEAD51);
33455-
t('record reader: `contractReviewHeadSha` reads the line\'s span — the first line wins, decoration and a trailing span tolerated', [contractReviewHeadSha(DELTA51), contractReviewHeadSha(`- **Head-sha:** \`${HEAD51}\` (moved to \`${OLDHEAD51}\`)\nHead-sha: \`${OLDHEAD51}\``), contractReviewHeadSha(`> Head-sha: \`${HEAD51}\``)].join(), [OLDHEAD51, HEAD51, HEAD51].join());
33456-
t('⛔ record reader: the key folded INTO the span, a bare hex value, a lowercase key and a sub-floor span name no head', [contractReviewHeadSha(`\`Head-sha: ${HEAD51}\``), contractReviewHeadSha(`Head-sha: ${HEAD51}`), contractReviewHeadSha(`head-sha: \`${HEAD51}\``), contractReviewHeadSha('Head-sha: `ba3d95`')].join('|'), '|||');
33518+
const UNDER51 = (...lines) => ['## Contract review', ...lines].join('\n');
33519+
t('record reader: `contractReviewHeadSha` reads the line\'s span — the first line BELOW the heading wins; bold or backticks on the key, a trailing span and up to three spaces of indent are tolerated', [contractReviewHeadSha(DELTA51), contractReviewHeadSha(UNDER51(`**Head-sha:** \`${HEAD51}\` (moved to \`${OLDHEAD51}\`)`, `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51(`\`Head-sha\`: \`${HEAD51}\``)), contractReviewHeadSha(UNDER51(` Head-sha: \`${HEAD51}\``))].join(), [OLDHEAD51, HEAD51, HEAD51, HEAD51].join());
33520+
// ⛔ A BLOCKQUOTED heading opens no scope: a fully quoted signed record followed by a plain prose line opening
33521+
// `Head-sha:` would otherwise lend the quoted signature to the plain line's head (the locator still sees a record here,
33522+
// through the marker's `>` tolerance — it then names no head). Measured live: 0 of 709 records quote their heading.
33523+
const QUOTED_RECORD51 = `> ## Contract review\n> Head-sha: \`${OLDHEAD51}\`\n> Reviewed-by: \`session_01SEAT\`\n> **VERDICT: PASS**\n\nHead-sha: \`${HEAD51}\` is the head the PR has since moved to.`;
33524+
t('⛔ record reader: a QUOTED record followed by a plain line opening `Head-sha:` names no head — a blockquoted heading opens no scope, and nor does a quoted heading alone', [contractReviewHeadSha(QUOTED_RECORD51), contractReviewHeadSha(`> ## Contract review\nHead-sha: \`${HEAD51}\``), latestContractReviewOnHead([cm51(1, QUOTED_RECORD51, T51)], HEAD51)].join('|'), '||');
33525+
// ⛔ An INDENTED CODE BLOCK (four spaces or a tab) is a quotation too: skipped above the record's own line, nothing alone.
33526+
t('⛔ record reader: a `Head-sha:` line indented as CODE — four spaces or a tab — above the record\'s own is skipped, and alone names no head', [contractReviewHeadSha(UNDER51(` Head-sha: \`${HEAD51}\``, `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51(`\tHead-sha: \`${HEAD51}\``, `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51(` Head-sha: \`${HEAD51}\``)), contractReviewHeadSha(UNDER51(`\tHead-sha: \`${HEAD51}\``))].join('|'), [OLDHEAD51, OLDHEAD51, '', ''].join('|'));
33527+
// ⛔ A fence closes only on its OWN character and a run at least as long: a nested ``` inside ````, a ~~~ inside ```,
33528+
// are content, and a `Head-sha:` line between them stays fenced; a longer closing run closes; a never-closed one runs out.
33529+
t('⛔ record reader: a nested or mismatched fence does not close the open one — the `Head-sha:` line inside stays fenced; a longer run closes; an unmatched run leaves it open to the end', [contractReviewHeadSha(UNDER51('````', '```', `Head-sha: \`${HEAD51}\``, '```', '````', `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51('```', '~~~', `Head-sha: \`${HEAD51}\``, '```', `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51('```', `Head-sha: \`${HEAD51}\``, '`````', `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(UNDER51('```', '~~~', `Head-sha: \`${HEAD51}\``, '~~~', `Head-sha: \`${OLDHEAD51}\``))].join('|'), [OLDHEAD51, OLDHEAD51, OLDHEAD51, ''].join('|'));
33530+
t('⛔ record reader: the key folded INTO the span, a bare hex value, a lowercase key and a sub-floor span name no head', [contractReviewHeadSha(UNDER51(`\`Head-sha: ${HEAD51}\``)), contractReviewHeadSha(UNDER51(`Head-sha: ${HEAD51}`)), contractReviewHeadSha(UNDER51(`head-sha: \`${HEAD51}\``)), contractReviewHeadSha(UNDER51('Head-sha: `ba3d95`'))].join('|'), '|||');
33531+
// ⛔ The shapes the review of the line-form reader probed (2026-10-30): a `Head-sha:` line naming ANOTHER head above the
33532+
// record's own — placed before the heading, blockquoted, bulleted or fenced. Each is a citation, not the record's line,
33533+
// so the record reads ABSENT at the cited head and FOUND at its own; the first-line-anywhere reader read all four as cited.
33534+
const CITED51 = {
33535+
preHeading: `Head-sha: \`${HEAD51}\`\n\n${RECORD51(OLDHEAD51)}`,
33536+
quoted: UNDER51('', `> Head-sha: \`${HEAD51}\``, `Head-sha: \`${OLDHEAD51}\``, '**VERDICT: PASS**'),
33537+
bulleted: UNDER51('', `- Head-sha: \`${HEAD51}\``, `Head-sha: \`${OLDHEAD51}\``, '**VERDICT: PASS**'),
33538+
fenced: UNDER51('', '```', `Head-sha: \`${HEAD51}\``, '```', `Head-sha: \`${OLDHEAD51}\``, '**VERDICT: PASS**'),
33539+
};
33540+
t('⛔ record reader: a `Head-sha:` line before the heading, blockquoted, bulleted or fenced — naming another head ABOVE the record\'s own — is NO review of that head', Object.values(CITED51).map((body) => latestContractReviewOnHead([cm51(1, body, T51)], HEAD51)).join('|'), '|||');
33541+
t('⭐ record reader: …and each IS the review of the head its own line names — the cited line is prose to the reader', Object.values(CITED51).map((body) => latestContractReviewOnHead([cm51(1, body, T51)], OLDHEAD51)?.sha).join(), [OLDHEAD51, OLDHEAD51, OLDHEAD51, OLDHEAD51].join());
33542+
t('⛔ record reader: a quoted, bulleted or fenced line ALONE names no head, nor does a line with NO heading above it, nor one inside an unclosed fence', [contractReviewHeadSha(UNDER51(`> Head-sha: \`${HEAD51}\``)), contractReviewHeadSha(UNDER51(`- **Head-sha:** \`${HEAD51}\``)), contractReviewHeadSha(UNDER51('```md', `Head-sha: \`${HEAD51}\``, '```')), contractReviewHeadSha(`Head-sha: \`${HEAD51}\``), contractReviewHeadSha(UNDER51('```', `Head-sha: \`${HEAD51}\``))].join('|'), '||||');
33543+
t('record reader: a tilde fence is a fence too, and CRLF line endings read', [contractReviewHeadSha(UNDER51('~~~', `Head-sha: \`${HEAD51}\``, '~~~', `Head-sha: \`${OLDHEAD51}\``)), contractReviewHeadSha(`## Contract review\r\nHead-sha: \`${HEAD51}\`\r\n`)].join(), [OLDHEAD51, HEAD51].join());
3345733544
t('⛔ record reader: the RETIRED dialects — head in the heading (two spellings), on the first body line, in an adoption sentence — name no head', [DIALECT_A, DIALECT_B, DIALECT_C, DIALECT_D].map((d) => latestContractReviewOnHead([cm51(1, d(HEAD51), T51)], HEAD51)).join('|'), '|||');
3345833545

3345933546
// -- H54 — a `[Decision]`-titled card sitting in the DISPATCH pool (#16688) -

0 commit comments

Comments
 (0)