fix(pm): H19's summary clause ends its own sentence - #13677
Merged
Conversation
`summaryLine`'s H19 clause carried its terminating `. ` inside the cross-repo branch alone, so the only rendering that ended the sentence was the one where an unrelated optional probe had fired. On an ordinary healthy pass -- no shortfall and no probe -- the clause stopped at `card(s)` and a lone space joined it straight onto H20's lead-in, which the live 2026-08-31 patrol rendered as `...card(s) Dispatch liveness (H20 + H27): ...`. Terminate the clause unconditionally and let the two optional branches contribute only their own text. The cross-repo branch already ended in a period of its own, so its leading space and the join's trailing space move into the terminator rather than adding a second one: across every rendered shape the whole line differs from base by exactly one inserted `.`, inside H19's terminator region and nowhere else. Pin it with the #13654 scoped-assertion scaffolding: `saidBy('h19Blockers', ...)` cases assert the clause ends `. ` on the healthy, shortfall, probe and both-branches shapes, plus that the probe shape does not render `resolves them.. `. The neighbouring whole-line `endsWith('not a gate verdict.')` cases could not see this -- they pin where the SENTENCE ends, not where this clause does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
zhuangjianguo
marked this pull request as ready for review
August 31, 2026 06:09
zhuangjianguo
enabled auto-merge
August 31, 2026 06:09
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13650
summaryLine's H19 clause carried its terminating.inside the cross-repo branchalone, so the ONE rendering that ended the sentence was the one where an unrelated
optional probe happened to fire. On an ordinary healthy pass — no shortfall AND no probe
— the clause stopped at
card(s)and a lone space joined it straight onto H20's lead-in,so two disclosures read as one sentence and the boundary was findable only by a reader who
already knew the row inventory.
What changed
One file:
scripts/pm/check-half-states.mjs..every other clauseon the line uses.
cross-repo branch already ended in a period of its own, so its leading space and the
join's trailing space move into the terminator rather than adding a second one: the
probe shape renders
resolves them., never a doubled...Everything else on the line is byte-identical
Rendered at the base commit and at head over the same six shapes, then diffed character by
character. Nothing is removed on any shape, and the single inserted character sits in
H19's terminator region on all six:
....summaryLine({}, 0)..The clause-boundary extractor is unmoved: the partition control (every window's clause
length summing to the whole line's length — no gap, no overlap) holds on all six shapes at
head, so adding the terminator inside H19's clause moved no boundary.
Live read-only fire, at this PR's head commit
PM_SWEEP_REPO=objectstack-ai/objectstack node scripts/pm/check-half-states.mjsat59d5c22bb, exit 0, read-only. The H19 to H20 boundary now reads:A no-shortfall, no-probe pass — the exact shape that used to run on. The old adjacency
card(s) Dispatch livenessoccurs 0 times in that run's output.Pins
Scoped to H19 via the clause extractor, so no neighbour's text can satisfy them. Eight
cases: the clause ends
.on the healthy, shortfall, probe and both-branches shapes;the probe shape carries no doubled period and closes exactly once; and two deliberately
whole-line cases on the boundary itself, because the adjacency between two clauses has no
single window to scope it to.
All four shapes are pinned rather than one, because the defect WAS that the shapes
disagreed — a pin written on the probe shape alone would have been green for the whole
life of the bug. The neighbouring whole-line
endsWith('not a gate verdict.')cases couldnot see this at all: they pin where the SENTENCE ends, which is H37's business, not where
this clause ends.
Ablations
Both legs mutated on disk with the anchor hit-count asserted (a zero-hit edit refuses
loudly instead of measuring an unmutated tree), and restored against
HEADwith therestored blob hash compared to the HEAD blob and
git diff HEADproven empty.the healthy and shortfall terminator cases and both boundary cases. The two probe-shape
cases stayed green, which is the measurement that shows why one shape was not enough.
summaryClause: h19Blockers opens its own clause on every run. H19's presence controlis still red under its own ablation and the other 16 windows' presence controls stayed
green, so the per-window contract is intact.
Verification
Self-test, quoting its own verdict lines:
✓ check-half-states self-test: 1783 cases pass.at the base commit,
✓ check-half-states self-test: 1791 cases pass.at head (+8).Gate family derived from the actual diff with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, run at59d5c22bb— 17 path-derived families plus the 2 convention-triggered ones this changekind incurs (it edits a gate script). All green, each read from the gate's own verdict
line with the exit code captured before any pipe, except two that decline to measure
locally and say so themselves:
node scripts/check-test-completeness.mjs—PREREQUISITE NOT MET, exit 3: it grades asaved
turbo run testlog and there is none locally. NOT MEASURED, not a red; its owntext says so.
node scripts/check-partof-closing-keyword.mjswith no PR context —NOT WIRED,exit 2. Its self-test spelling (
pnpm check:partof-closing-keyword, 28 cases) is green,and the gate was additionally run against this body with
PR_BODYset before the PR wasopened.
No changeset: nothing here is published from any package — the diff is
scripts/pm/**only, so the PR carries
skip-changeset.Notes for the reviewer
Card relationships, stated once here and carried by no commit trailer (this branch
squashes): the scoped-assertion scaffolding these pins are built on came from #13654, and
its adjudicated default was that the rendered summary line must not change — this card is
the one sanctioned rendered-line change deferred out of it. Nothing from #13654 or #13628
is undone here. The shortfall wording and the cross-repo branch, both from #11218, are
untouched apart from the whitespace that moved into the terminator.
Generated by Claude Code
Generated by Claude Code