Skip to content

fix(scripts): give the objectui changeset digest #6923's leading-blank-line preamble, and widen the family assertion to that row (#7044) - #7162

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7044-digest-leading-blank-line
Aug 10, 2026
Merged

fix(scripts): give the objectui changeset digest #6923's leading-blank-line preamble, and widen the family assertion to that row (#7044)#7162
os-project-manager merged 1 commit into
mainfrom
claude/issue-7044-digest-leading-blank-line

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #7044

What was wrong

scripts/objectui-changeset-digest.mjs is the fourth carrier of this repo's changeset-frontmatter parser. #7004 aligned its entry regex with the three gates. It never got #6923's other half — it still required the opening fence on line 1:

if (lines[0]?.trim() === '---') {
  i = 1;

The three gates all skip leading blank lines first. So a changeset opening with a single blank line declared, to this file, nothing at all — which makes it read release-nothing, and the commit leaves the release digest entirely. Not a red or a green: a silent DROP, #4731's harm class, worst for exactly the class #4731 says must never vanish.

Measured here rather than inherited from the card, with @changesets/parse@0.4.3 (the version this repo resolves) loaded against the shipped parseChangeset:

                                changesets                               digest (before)
control (no blank)              [{"name":"@object-ui/layout",...major}]  {"@object-ui/layout":"major"}
leading blank line              [{"name":"@object-ui/layout",...major}]  {}
two leading blank lines         [{"name":"@object-ui/layout",...major}]  {}
leading whitespace-only line    [{"name":"@object-ui/layout",...major}]  {}

changesets honours the bump in every row. The digest saw none of them — and handed back the raw frontmatter text as the entry summary on top of it.

Half 1 — the parser

parseChangeset now carries the family's preamble, byte for byte, and tests the fence at the cursor that skip advanced. Unfenced input is unaffected: the trailing blank-skip that follows already consumed those lines, so body and summary are identical to before (pinned as D7).

Half 2 — the family assertion (the half that stops the recurrence)

#7004's family-agreement assertion (in check-empty-changeset.mjs's self-test) covered the entry regex and the whole-line-comment guard. It did not cover the fence preamble — which is precisely why this row survived three alignment passes with nothing mechanical holding it.

It now covers that row too. Per file, it asserts:

  1. an opening-fence test is extractable at all (anti-vacuous-green, test(ci): pin the branch-protection required-context job names (#6865) #6983);
  2. that test is written against the cursor, never a literal lines[0] — the objectui-changeset-digest's frontmatter parser never got #6923's leading-blank-line fix — a changeset opening with a blank line drops out of the release digest #7044 shape itself, so a preamble sitting dead beside a surviving lines[0] is caught;
  3. the statement immediately above it, extracted by position rather than by content, is byte-identical across all four — a real comparison, not a regex agreeing with itself;
  4. that shared statement is the blank-line skip, so four identical copies of something else cannot satisfy (3).

Comment lines are blanked before scanning (indices preserved): two of these files quote the old lines[0] spelling in their headers while explaining why it was wrong, and a scan that read prose would find the defect inside the account of its own fix.

check-empty-changeset.mjs also gains the behavioural half on its own parser. Its existing leading-blank row (isEmptyDeclaration('\n---\n\n---\n\nbody\n')) is empty either way and cannot fail on the preamble's removal; a declaring file opening with a blank line can, and now does.

Verification — both directions, run and quoted

105 -> 118 assertions in check-empty-changeset --self-test; 7 new D-rows in the digest's.

A. Digest preamble removed (the issue's own shape) — predicted D1-D4 red on packages going {}, D5 red the other way (the summary becomes the fence text), D6/D7 green. All four halves as predicted:

  x #7044 D1 one leading blank line before the fence -- {}
  x #7044 D2 two leading blank lines -- {}
  x #7044 D3 a leading WHITESPACE-ONLY line -- {}
  x #7044 D4 a leading blank line with CRLF endings -- {}
  x #7044 D5 the SUMMARY is the body, not the frontmatter -- "--- \"@object-ui/layout\": major ---"
  v #7044 D6 control -- the identical text WITHOUT the leading blank line parses the same
  v #7044 D7 control -- skipping blanks did NOT make the parser fence-less

and the family assertion, in the same state:

- family: scripts/objectui-changeset-digest.mjs must test the opening fence at the cursor
  the blank-line skip advanced, never at a literal line index -- `lines[0]` IS #7044
  (found: "if (lines[0]?.trim() === '---') {")
- family: all four parsers must carry a byte-identical leading-blank-line preamble ...
  found 2 distinct spellings: [... ["scripts/objectui-changeset-digest.mjs","let i = 0;"]]

B. Preamble present but DEAD (skip restored, fence left at lines[0]) — 1 failure, the cursor assertion. This is the case a spelling-only check would have passed.

C. Preamble removed from a GATE instead (check-adr-0087-registration.mjs, digest correct) — the agreement fires naming that file. The assertion is symmetric across the family, not digest-specific.

D. All four identically stale — the agreement is satisfied (one distinct spelling) and the fourth assertion refuses it by name: the shared statement before the fence test must be the leading-blank-line skip itself (#6923) -- found "let i = 0;". check-empty-changeset's two new behavioural rows go red in the same state, and check-changeset-no-major --self-test reports its three #6923 fixtures red — the family's existing coverage, still load-bearing.

Restored state, all green:

v check-empty-changeset --self-test: 118 assertions over real temp git repos (real scan() path)
v check-adr-0087-registration --self-test: 142 assertions over real temp git repos
v check-changeset-no-major --self-test: 113 assertions
v objectui-changeset-digest --self-test: all checks passed
v check-nul-bytes: OK (scanned 6592 text file(s) ...)
eslint (both changed files, --no-inline-config): exit 0

Changeset

None, and the skip-changeset label instead. The diff is two scripts/*.mjs files: it releases no package, and an empty-frontmatter changeset is exactly what check-empty-changeset.mjs rejects. Same disposition as #7048 / #7008 / #6983 / #6917 / #7104 / #7106.

Honest negatives


Generated by Claude Code

…k-line preamble (#7044)

`objectui-changeset-digest.mjs` is the fourth carrier of this repo's changeset
frontmatter parser. #7004 aligned its entry regex with the three gates; it never
got #6923's other half, so it still required the opening fence on line 1. A
changeset opening with a single blank line therefore declared nothing here,
which makes it read `release-nothing` and drops the commit out of the release
digest entirely -- #4731's harm, reached through the parser.

Measured with @changesets/parse@0.4.3 (the version this repo resolves): every
leading-blank-line form below is a real `major` to changesets, and was `{}` to
this file.

Second half, and the one that stops the recurrence: #7004's family-agreement
assertion in `check-empty-changeset.mjs`'s self-test now covers the fence
preamble as well as the entry regex. Per file it asserts the opening fence is
tested at the cursor the blank-line skip advanced (never at a literal
`lines[0]`), and that the statement immediately above that test is the family's
byte-identical skip. Extraction is by position, not by content, so the
agreement is a real comparison; a shared-but-stale statement is rejected by
name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 1:28am

Request Review

@os-project-manager os-project-manager added skip-changeset PR has no user-facing published change; bypasses the changeset gate size/m and removed size/m labels Aug 10, 2026 — with Claude
@os-project-manager
os-project-manager marked this pull request as ready for review August 10, 2026 02:30
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit 1bd6525 Aug 10, 2026
30 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7044-digest-leading-blank-line branch August 10, 2026 02:46
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

2 participants