Skip to content

pm-ratchet: pay down the 8 residual Han+ASCII-punct soft breaks in os-dev.md - #12945

Merged
os-litant merged 1 commit into
mainfrom
claude/issue-12891-osdev-softbreak-paydown
Aug 28, 2026
Merged

pm-ratchet: pay down the 8 residual Han+ASCII-punct soft breaks in os-dev.md#12945
os-litant merged 1 commit into
mainfrom
claude/issue-12891-osdev-softbreak-paydown

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes #12891

Pure paydown of the last 8 residual #12081-class soft breaks in .claude/agents/os-dev.md, the dev-agent definition every dispatched dev reads in full. Zero content change — the diff normalizes to byte-equality.

The defect

scripts/pm/check-skill-line-ratchet.mjs's hanAsciiPunctTail refuses to OFFER a line break placed directly after an ASCII , ; : that follows a Han character. The mark is a narrow byte, so the break is not between two wide characters, it survives the CSS segment-break transformation, and it renders as a stray mid-sentence space in prose that has no spaces anywhere else. The offer-side channel was shut when that rule landed; these 8 were pre-existing and left to be paid down file by file.

Site scan — before and after

The site list was re-derived from the live tree at branch head, not taken from the card's recorded line numbers: the card warns this paydown is self-concealing. The scan drives the gate's own exported hanAsciiPunctTail and its initialState/advanceState block-state machine, so it cannot disagree with the gate about what counts as prose.

BEFORE, at merge base 4d1142753:

.claude/agents/os-dev.md: 8 #12081-class soft break(s)

at lines 15, 32, 87, 99, 245, 356, 361, 454 — which is what the card recorded, so the numbering had not drifted.

AFTER, at 99addb55f:

.claude/agents/os-dev.md: 0 #12081-class soft break(s)

The scan's own cross-check counts every line ending in a Han+ASCII mark, by the plain form the gate's self-test uses. It goes 10 to 2. The surviving 2 are correct and deliberately untouched: both end their paragraph (the next line is blank), so no segment break follows them and nothing renders as a space.

Method

For each site the offending line is joined with the rest of its paragraph and the result re-wrapped by the gate's own exported wrapLine. Lines ahead of a site stay byte-identical, so the diff starts where the defect is. Joining to the paragraph end rather than to the next line alone is load-bearing: a two-line merge strands the overflow as an orphan fragment on a line of its own and grew the file 470 to 473 — measured, then discarded.

Seam semantics follow the recorded precedent for this class:

  • after a Han+ASCII mark, nothing is inserted, so the stray space is removed rather than migrated into the source as a literal;
  • between two wide characters, nothing (it already renders as nothing);
  • anywhere else, a space (the break was legal only because a space was spent on it).

Content-preservation proofs

All seven ran before the write, and the writer refuses to write on any mismatch:

PASS  A  whole-file whitespace-normalize byte-equality (nothing added, cut or altered)   [39313B vs 39313B]
PASS  B  per-site render delta is EXACTLY the stray space (before renders it, after does not, nothing else moves)   [8/8 sites]
PASS  C  every rewritten line is within 120 bytes
PASS  D  rewritten output is wrapLine-idempotent (it IS the canonical form)
PASS  E  no rewritten line ends on a Han+ASCII `,;:` mark
PASS  F  re-scan of the rebuilt text reports ZERO sites   [0 site(s)]
PASS  G  line count never grew   [470 → 466]

Proof A is re-confirmed independently against the committed blobs — base 4d1142753 vs 99addb55f — both normalize to 39,313 B, at 470 and 466 lines.

Proof B is the semantic one and is what makes A honest: A alone would accept a seam that fused two words, since stripping whitespace makes word word and wordword equal. B asserts, per site, that the paragraph's rendered text before the change is exactly its rendered text after plus the one stray space, and nothing else moved.

Ceiling movement

470 → 466, restoring the map's headroom-0 convention, alongside the same closure's earlier lowering of references/decision-analysis.md. Lowering is always legitimate under this ratchet. The 4 lines are re-flow slack, never a cut — proof A is what says so.

✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 466 lines (ceiling 466; headroom 0).
✓ check-skill-line-ratchet: .claude/agents/os-dev.md: widest table row is 0 bytes (pin 0; headroom 0).

Gates

Union derived mechanically at 99addb55f by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (it reads the change set from the merge base itself), then re-run after the final commit. Exit codes captured before any pipe.

✓ check-skill-line-ratchet self-test: 111 cases pass.
✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
  binding sentence present in all 4; 4 count mention(s) agree; 42 markdown files scanned.
check-nul-bytes: OK (scanned 7177 text file(s); no raw ASCII control bytes).
✓ check-skills-token-ratchet: 38 authored bundle file(s) within their ceilings.

22 of 23 families green: check:pm-skill-ratchet, check:pm-skill-id-lint, check:skill-frame-sync, check:nul-bytes, check:pm-governed-merges, check:pm-governed-prose, check:pm-dispatch-gates, check:agent-model-declared, check:agent-test-spelling, check:doc-authoring, check:entry-guard, check:parse-guard, check:watch-hint-literal, check:bash32-floor, check:cli-command-ids, check:pnpm-filter-targets, check:cross-package-test-inputs, bare-root-worklist --self-test, check-published-list-mirrors, check-skills-token-ratchet, check-ci-filter-parity, check-cross-package-test-inputs.

Both convention-triggered gates for a gate-script edit were run and are green — bare-root-worklist --self-test and check:pm-dispatch-gates — since this PR edits check-skill-line-ratchet.mjs, which no path derivation would name.

The 23rd, check-governed-queue-guard, is not measurable locally: it reads the workflow event payload and exits non-zero when it cannot look. That is the guard working, not a finding; CI runs it.

Scope

.claude/agents/os-dev.md plus the one CEILINGS line in scripts/pm/check-skill-line-ratchet.mjs that the shrink obliges. Governed surface — left as draft, no reviewers, no ready flip, no auto-merge.

skip-changeset: the diff publishes nothing (an agent definition and a repo gate script).

Generated by Claude Code


Generated by Claude Code

…-dev.md

`.claude/agents/os-dev.md` still carried the last 8 breaks of the class
check-skill-line-ratchet's `hanAsciiPunctTail` now refuses to offer: a line
break placed directly after an ASCII `,` `;` `:` that follows a Han character.
The mark is a narrow byte, so the break is not between two wide characters,
survives the CSS segment-break transformation, and renders as a stray
mid-sentence space in prose that has no spaces anywhere else — in the one file
every dispatched dev reads in full.

The offer-side channel was shut at the ratchet already, so this is pure paydown:
zero content change. Each site's line was joined with the rest of its paragraph
and re-wrapped by the gate's own exported `wrapLine`; lines ahead of a site are
byte-identical. Seams follow the recorded precedent — nothing is inserted where
the defect break was, so the stray space is removed rather than migrated into
the source as a literal.

Proved before writing, and the writer refuses on any mismatch:
  - whitespace-normalize byte-equality, whole file: 39,313 B both sides
  - per-site render delta is EXACTLY the stray space (before renders it, after
    does not, nothing else moves) — 8/8
  - every re-flowed line within 120 bytes, wrapLine-idempotent, and no line
    ends on a Han+ASCII mark; re-scan reports 0 sites

Ceiling lowered 470 -> 466 to match, restoring the map's headroom-0 convention.
The 4 lines are re-flow slack, never a cut.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Aug 28, 2026
@os-litant os-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Aug 28, 2026 — with Claude
@os-litant
os-litant requested review from hotlong and os-zhuang August 28, 2026 10:00
@os-zhuang
os-zhuang marked this pull request as ready for review August 28, 2026 10:36
@os-litant
os-litant added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit 196a6c7 Aug 28, 2026
37 checks passed
@os-litant
os-litant deleted the claude/issue-12891-osdev-softbreak-paydown branch August 28, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

2 participants