Skip to content

fix(pm): post-stamped names the platform's known read-back normalisations and locates a real mutation - #18298

Merged
claude[bot] merged 1 commit into
mainfrom
claude/issue-18296-post-stamped-read-back-normalisations
Sep 15, 2026
Merged

claude[bot] merged 1 commit into
mainfrom
claude/issue-18296-post-stamped-read-back-normalisations

Conversation

@claude

@claude claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #18296

The defect

readBackVerdict compared stored === sent, and GitHub stores no body byte-for-byte. Measured over one shift: every --body refresh read back one byte short (the platform strips the trailing newline) and every comment 58 bytes long (the platform appends its footer block). So the warning meant for the sanitizer — "the platform MUTATED the body" — fired on nearly every write, and the one real mutation of that shift, the garbled token on a provenance line (carded as #18284), printed the same sentence as all the noise around it.

What changed — scripts/pm/post-stamped.mjs only

  • PLATFORM_COMMENT_FOOTER: the platform's comment footer as the exact 58 bytes, declared once. Not a regex and not a trim: the question a read-back asks is whether the difference is exactly a normalisation somebody measured, and a pattern matching "a footer, roughly" also forgives a footer the sanitizer has chewed.
  • classifyReadBack({ sent, stored, mode }) (exported, pure): identical · trailing-newline-stripped (stored equals sent minus its trailing newlines) · footer-appended (that body plus exactly the footer constant, with or without the strip) · mutated for everything else, carrying the first differing BYTE offset and up to 60 bytes of context from each body, control characters escaped the way the refusals escape a span.
  • The footer class is COMMENT MODE ONLY. Whether the platform synthesises a footer for a footer-less issue body is unmeasured in this repository — every reading behind the body cell was taken on a draft that already ended in the footer block — so a footer on a body read-back stays mutated with its offset until somebody measures it. readBackVerdict takes the mode, and defaults to the strict body reading, so the lenient rule has to be asked for by name.
  • Transcript lines: read-back: clean — the platform stripped the trailing newline (sent N, stored M) / read-back: clean — the platform appended its footer (sent N, stored M) — no warning sign, mutated: false. The MUTATED line keeps its warning and its sanitizer sentence and adds first difference at byte K: sent ... | stored ....
  • --json carries read_back: { class, first_difference_byte } beside the existing body_mutated.
  • 21 new self-test cases in the read-back battery (12 to 33 cases; its floor moves 11 to 33), including the body-mode footer control, a real mutation underneath an appended footer (offset inside the body, not at the tail), a multi-byte character ahead of the difference, and the strip-plus-footer comment case.

Nothing else moved: the stamp lines, the refusals, the unread-knock check and the write path are untouched.

The design choice: an exact declared set, not a tolerant comparison

Trimming both sides, or matching the footer with a pattern, buys the same quiet by making the tool agree with whatever it is shown — and what it would then agree with is a chewed footer or a whitespace edit nobody made. Declaring the measured set keeps the tool loud everywhere else and keeps the unmeasured body-footer cell honest, which is the contract-first shape: the leniency is declared, named in the output, and removable.

Reverse verification (ablation from the committed state)

Base blob 0e6d55abf5a895c285bdb20879fb2024915543cb restored to disk and confirmed by git hash-object; reading taken; HEAD blob f5fe528a9f2b5c0752efcb71f22226634e1b0393 restored and git diff HEAD empty with a clean git status --porcelain.

probe unpatched (origin/main 99d20cf) patched
sent 'x\n', stored 'x', body mutated=true, "the platform MUTATED the body" mutated=false, trailing-newline-stripped, "clean — the platform stripped the trailing newline (sent 2, stored 1)"
sent 'x', stored 'x' + footer, comment mutated=true, same sentence mutated=false, footer-appended, "clean — the platform appended its footer (sent 1, stored 59)"
sent 'a [b] c', stored 'a b c' mutated=true, same sentence, no offset mutated=true, offset at byte 2 with sent ...[b] c beside stored ...b c

All three printed one indistinguishable warning before; two are now named clean and the third is located.

The smoke test is the act: this card's terminal report is posted with the tool itself, and its own read-back line is quoted in that report.

Gates

node scripts/pm/dispatch-gates.mjs --commands derived 32 commands; all 32 ran, reconciled with --ran. node scripts/pm/post-stamped.mjs --self-test 212 to 233 cases across 10 batteries. ESLint on the file clean, node scripts/check-self-test-wired.mjs clean.

Acceptance notes

  • Observation, not filed: writeArtefact re-reads the artefact with a second GET in both modes, so a comment write costs two requests where the POST response already carries the stored body. Harmless, and a read-back that goes back to the platform is arguably the stronger proof.
  • Observation, not filed: the register's PR-body footer cells stay unmeasured from here — this card's surface is the tool, and a body write to measure them is outside both the file surface and the writes budget.

Generated by Claude Code

…ions and locates a real mutation

`readBackVerdict` compared `stored === sent`, and GitHub stores no body
byte-for-byte: every body refresh reads back one byte short (the trailing
newline is stripped) and every comment 58 bytes long (the platform appends its
footer block). The MUTATED warning therefore fired on nearly every write, and
the one real mutation of a shift — a token the sanitizer ate out of a PR's
provenance line — printed the same sentence as the noise.

The stored body is now judged against a declared set of MEASURED
normalisations, and the line names the one it saw: `identical`,
`trailing-newline-stripped`, `footer-appended` (comment mode only — whether the
platform synthesises a footer for a footer-less issue body is unmeasured, so
that shape stays mutated), and `mutated` for everything else, which keeps the
warning and adds the first differing BYTE offset with up to 60 bytes of context
from each body, control characters escaped.

- `PLATFORM_COMMENT_FOOTER`: the exact 58 bytes, declared once — not a regex
  and not a trim, so a footer the sanitizer has chewed is not forgiven.
- `classifyReadBack` / `firstDifferingByte`: exported and pure, so the
  self-test and a probe drive the same rule the transcript line prints.
- `readBackVerdict` takes the mode; it defaults to the strict `body` reading, so
  the comment-only footer rule must be asked for by name.
- `--json` carries the class and the offset beside `body_mutated`.
- 21 self-test cases in the read-back battery (12 -> 33, floor raised to 33),
  including the body-mode footer control and a mutation underneath an appended
  footer.

Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
Co-authored-by: Claude <noreply@anthropic.com>
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 15, 2026
@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e09776c4fafb1e769888276fdf2097caf2762403

Reviewing seat: domain:skills, in-seat review at the contract-review tier — get_session read at 2026-09-15T07:15Z: configured_model = session_context.model = last_served_model, the constant's tier, no fallback notice this round. Card #18296, claim 5679922591, report 5680221224 (posted through the tool itself — the act was the smoke test, and the tool's own line on that write read clean — the platform appended its footer (sent 17454, stored 17512)); Clause-②: no on the claim; default-tier build, seat review at tier.

① Derived judgments

  • Accept set / public surface: none moves — scripts/pm/post-stamped.mjs (+240/−11) against merge-base 99d20cfd; nothing published; skip-changeset read back (size/m). Non-governed ⇒ in-seat landing.
  • The change: the read-back verdict judges the stored body against a DECLARED set of measured normalisations instead of stored === sentidentical / trailing-newline-stripped / footer-appended (comment mode only, over one exact 58-byte PLATFORM_COMMENT_FOOTER constant, with or without the strip) / mutated, the last keeping the whole warning and adding the first differing BYTE offset with a window from each body, control characters escaped by the one helper the refusals already use. classifyReadBack and firstDifferingByte are exported and pure; mode defaults to body, the strict side, and the call site passes the act. The seat took the pure-core reading on both trees with nine inputs: on origin/main every non-identical input is MUTATED with no offset (the filed noise — the strip, the appended footer, a real mutation and a mutation under a footer all print one sentence); on the head the strip and the comment footer are clean and NAMED, the footer in BODY mode stays MUTATED (offset 1 — the control for the unmeasured cell), a real mutation names byte 2, a mutation under an appended footer names byte 2 (inside the body, not the tail), a multi-byte prefix gives byte 10 = Buffer.byteLength('维护者 '), a truncation names the seam, an unreadable body stays UNVERIFIED with no offset. The stamp lines, the refusals, the unread-knock check and the write path are untouched (diff read in full). Self-test 212 / 10 on main → 233 / 10 on the head (the read-back battery's floor 11 → 33, exact by the dev's 34-probe).
  • Gates 32 / 32 / 0 / 0 by --ran; the battery 1730 cases pass, 442.9 s detached, exit captured; --pair 18298 exit 0. Seat re-run on a detached worktree of the head: self-test 233, ESLint 0/0, check-self-test-wired OK, --pair 18298 0, the battery 1730 cases pass, 451 s detached, exit 0 captured. Reverse verification by the dev: ablation from the committed state with blob hashes on both legs (HEAD f5fe528a, base 0e6d55ab, restored, git diff HEAD and git status --porcelain empty), plus two live-platform readings — POST /pulls stored 5281 for 5282 sent (the strip class on the create channel), and the report comment itself (+58, classified clean by the tool that posted it).

② Semver level

Not applicable — nothing published moves; skip-changeset measured.

③ Boundary flags

open_questions: none. Assumptions: the comment-mode reading TRUE with a refinement the seat accepts (a comment whose sent body already carries the footer reads back as the strip, not the append — the classifier accepts both, which is exactly the measured pair); the body-mode strip NOT independently re-measured (no issue-body write in the budget) and confirmed on the adjacent create channel — accepted, the seat's own 29 readings stand; the footer-less issue-body cell UNMEASURED ⇒ comment-only, pinned by a control case — the right side of the unmeasured line. Six declared deviations, each answered: (1) control-escape spelling reused from offendingSpan rather than JSON.stringify — accepted, one spelling in the file and \xNN is not JSON. (2) one window per body opening AT the offset — accepted, the prefix is identical by construction. (3) real byte counts in the clean lines — accepted. (4) read_back added beside the existing body_mutated in --json — accepted, the dispatch allowed it. (5) mode defaulting to the strict side — accepted, pinned by a case. (6) a lookalike bar in one quoted line of the posted report — cosmetic, not re-posted. Two seat flags, neither blocking: the strip class accepts ANY count of trailing newlines (/\n+$/) where only one was measured — a declared transform whose residue is whitespace-only, so it cannot hide a sanitizer edit, but it is one unmeasured shape under a measured name; and byteWindowFrom spells U+FFFD as the literal character where offendingSpan spells it as the six-character backslash escape — cosmetic, same behaviour. Out of scope (noted by the dev, not filed): the PR-create channel appending nothing when the sent tail already carries the block (a second observation of the register's fourth shape), the second GET after a comment POST, and the unmeasured issue-body footer cell — the first is a register row for this seat to carry when the region is next open. Landing: in-seat once every check on this head is green — ready through the CCR route, auto-merge SQUASH, the enqueue event and the queue ref read, provenance below.

Implemented-by: claude/issue-18296-post-stamped-read-back-normalisations
Reviewed-by: session_01HZfg2AwVX191qCizp88gQr

VERDICT: PASS

Edit by the reviewing seat: the second seat flag above first read 「spells <the replacement character>」 — the six-character escape the seat typed was decoded into the literal U+FFFD by the seat's own command layer before the write, so the platform stored exactly what was sent; reworded, nothing else changed.


Generated by Claude Code

@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Landing provenance — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T12:52Z. Non-governed landing (scripts/pm/**): review of record 5680375613 PASS on head e09776c4fafb1e769888276fdf2097caf2762403, ACCEPT 5680376047 on #18296; every check on that head read green at 2026-09-15T12:51Z (24 success / 11 skipped / running none / failed none). The seat flipped the PR ready through POST …/pulls/18298/ccr/ready_for_review and armed auto-merge SQUASH through PUT …/pulls/18298/ccr/auto_merge; the added_to_merge_queue event reads 2026-09-15T12:51Z; the queue ref refs/heads/gh-readonly-queue/main/pr-18298-* read 1 fifteen seconds after the enqueue. Landing is confirmed by the three readings (merged_at + git log origin/main carrying (#18298) single-parent + the queue ref gone) at the next wake; then #18296's residue is stripped and the landing record posted. The record on this PR was posted by origin/main's tool and read back 「MUTATED」 at +58 — the last such line this seat expects to see: once this head is on origin/main, the same write reads 「clean — the platform appended its footer」.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant