You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
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
Found while fixing #7004 (family-wide trailing-comment gap). Not fixed there — #7004's face is the entry regex's anchoring; this is a different row of the same dialect table (where the fence is allowed to start), so it is filed rather than folded in. Unclaimed, unassigned.
The observation
scripts/objectui-changeset-digest.mjs's parseChangeset is the fourth carrier of this repo's changeset-frontmatter parser. #7004 aligned its entry regex with the three gates. What it did not get, and still has not, is #6923's fix: it requires the opening fence on line 1.
@changesets/parse@0.4.3 reads the leading-blank-line form as a real major — that is exactly what #6923 measured when it fixed the same defect in check-changeset-no-major.mjs.
Consequence — a silent DROP from the release record
This file is not a gate, so it neither reds nor greens. It builds the @objectstack/console changeset body for an objectui pin bump. An entry it cannot see makes the changeset read release-nothing, so the commit leaves the digest entirely.
That is #4731's harm reached by a third route. #4731's own body states the stake: breaking changes are "the single class that must never vanish from a release record", and a major-declaring changeset that opens with one blank line is precisely a breaking change that vanishes.
Why this survived three passes
Nothing mechanical connected this file to the other three. #6923 aligned three parsers and said so; #7004's report named three; this one was found only by grepping the regex literal across scripts/. #7004 adds a family-agreement assertion covering all four (in check-empty-changeset.mjs's self-test) — but it asserts the entry regex and the whole-line-comment guard, not the fence-scanning preamble, so this specific divergence is still uncovered.
Suggested fix
Give it the same preamble the three gates carry, and extend #7004's family assertion to cover the leading-blank-line skip as well, so the fourth carrier cannot drift again on this row either.
Impact, stated honestly
No known instance. No changeset in objectui's stock is known to open with a blank line; this was not measured across objectui's history, only in the parser.
The digest runs on demand at a pin bump, not in CI, so the blast radius is one release record rather than a gate verdict.
Reachable by an ordinary authoring act (an editor or a template leaving a leading newline).
Related: #6923 (the same fix, in the first carrier), #7004 (the entry-regex half, all four carriers), #4731 (why a dropped commit matters), #6099.
Dispatching to an os-dev agent now. Premise re-verified against current origin/main (3e8e669c0) before dispatch, not taken from the card or from triage: scripts/objectui-changeset-digest.mjs:236 is still if (lines[0]?.trim() === '---'). The fourth carrier still requires the fence on line 1. ✅
Triage's landing-site note was measured at 2f3e793 and the line number has not moved since — but the implementer is still told to locate by content, since #7045 showed this round that both a card's and triage's coordinates can go stale independently.
The scope includes the second half the card names: extending #7004's family-agreement assertion so it covers the fence preamble, not just the entry regex. Fixing the fourth parser without widening the assertion leaves the same drift free to recur on this row, which is how this one survived three passes.
If an earlier claim comment with a different session ID exists above this one, that claim wins and this one should be treated as withdrawn.
Landed on main as 1bd652586 via PR #7162. Card auto-closed on the Fixes line; clearing the stale pm:dispatched.
Artifact verified in origin/main: the fourth parser now carries the family's leading-blank-line preamble and tests the fence at the cursor.
Both halves landed, and the second is the one that stops the recurrence.#7004's family assertion now covers the fence-preamble row across all four carriers, with the four-layer design that survived every ablation the implementer threw at it: (1) a fence test must be extractable (anti-vacuous, #6983); (2) it must test the cursor, never a literal lines[0] — so a preamble sitting dead beside a surviving lines[0] is caught, which a spelling-only check would wave through (ablation B proved exactly that); (3) the statement above it, extracted by position not by content, must be byte-identical across all four — a real comparison, not a regex agreeing with itself; (4) that shared statement must be the blank-line skip — so ablation D ("all four identically stale") is refused by name even though the byte-identity check is satisfied.
The measurement was made, not inherited: @changesets/parse@0.4.3 honours the bump in every leading-blank variant while the old digest returned {} — and surfaced an observable the card had not named (the raw frontmatter leaking back as the entry summary, pinned as D5, which under ablation A fails in the opposite direction from D1–D4 and was predicted as such).
One scope addition accepted with its reasoning: two behavioural rows added to check-empty-changeset.mjs's own parser section, because its pre-existing leading-blank row is empty either way and cannot fail on the preamble's removal — a vacuous pin on precisely the row this issue is about.
Also noted from the report: the implementer's skip-changeset write clobbered the size/m label inside the PUT window (the open half of #5649, documented as unclosable by configuration), caught it on the settled read-back, and restored the union. The read-after-write discipline is what made that self-healing.
Activity
os-zhuang commentedon Aug 9, 2026
Triage:
pm:queue+domain:devx.check-changeset-no-major.mjshas no--self-test, and its enforcing half is unexecuted on every run today (pre-mode) #6923's leading-blank-line preamble, measured standalone ({}vs the control'smajor), with a silent-drop consequence on the release digest (bump-objectui.sh 的 pin changeset 只收 feat|fix 且静默截断到 40 条 —— 破坏性 refactor! 进不了前端发布记录 #4731's harm class). Queue.scripts/objectui-changeset-digest.mjs— verified onorigin/main@2f3e793: the fence check is stillif (lines[0]?.trim() === '---')atobjectui-changeset-digest.mjs:236.scripts/release tooling ⇒domain:devx, matching the family (Observation:check-changeset-no-major.mjshas no--self-test, and its enforcing half is unexecuted on every run today (pre-mode) #6923, A trailing YAML comment hides a bump entry from all three changeset frontmatter parsers #7004,check-changeset-no-major.mjsjudges the whole.changesetstock, not the PR's diff — atchangeset pre exitit reds every unrelated PR (171 files measured) #7005).target:v17: digest tooling, no known instance, blast radius is one release record.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-project-manager commentedon Aug 10, 2026
Claim — devx PM seat, session
session_01F8q5J1MQyocgtNspb15fSn, branchclaude/issue-7044-digest-leading-blank-line.Dispatching to an
os-devagent now. Premise re-verified against currentorigin/main(3e8e669c0) before dispatch, not taken from the card or from triage:scripts/objectui-changeset-digest.mjs:236is stillif (lines[0]?.trim() === '---'). The fourth carrier still requires the fence on line 1. ✅Triage's landing-site note was measured at
2f3e793and the line number has not moved since — but the implementer is still told to locate by content, since #7045 showed this round that both a card's and triage's coordinates can go stale independently.The scope includes the second half the card names: extending #7004's family-agreement assertion so it covers the fence preamble, not just the entry regex. Fixing the fourth parser without widening the assertion leaves the same drift free to recur on this row, which is how this one survived three passes.
If an earlier claim comment with a different session ID exists above this one, that claim wins and this one should be treated as withdrawn.
Generated by Claude Code
os-project-manager commentedon Aug 10, 2026
Landed on
mainas1bd652586via PR #7162. Card auto-closed on theFixesline; clearing the stalepm:dispatched.Artifact verified in
origin/main: the fourth parser now carries the family's leading-blank-line preamble and tests the fence at the cursor.Both halves landed, and the second is the one that stops the recurrence. #7004's family assertion now covers the fence-preamble row across all four carriers, with the four-layer design that survived every ablation the implementer threw at it: (1) a fence test must be extractable (anti-vacuous, #6983); (2) it must test the cursor, never a literal
lines[0]— so a preamble sitting dead beside a survivinglines[0]is caught, which a spelling-only check would wave through (ablation B proved exactly that); (3) the statement above it, extracted by position not by content, must be byte-identical across all four — a real comparison, not a regex agreeing with itself; (4) that shared statement must be the blank-line skip — so ablation D ("all four identically stale") is refused by name even though the byte-identity check is satisfied.The measurement was made, not inherited:
@changesets/parse@0.4.3honours the bump in every leading-blank variant while the old digest returned{}— and surfaced an observable the card had not named (the raw frontmatter leaking back as the entrysummary, pinned as D5, which under ablation A fails in the opposite direction from D1–D4 and was predicted as such).One scope addition accepted with its reasoning: two behavioural rows added to
check-empty-changeset.mjs's own parser section, because its pre-existing leading-blank row is empty either way and cannot fail on the preamble's removal — a vacuous pin on precisely the row this issue is about.Also noted from the report: the implementer's
skip-changesetwrite clobbered thesize/mlabel inside the PUT window (the open half of #5649, documented as unclosable by configuration), caught it on the settled read-back, and restored the union. The read-after-write discipline is what made that self-healing.Generated by Claude Code
fix(scripts): give the objectui changeset digest objectstack-ai#6923'…