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
Description
Activity
Triage:
pm:queue+domain:devx.- Classification: scoped tooling fix — the fourth changeset-frontmatter parser is missing Observation:
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. - Landing site:
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). - Dedup: not a duplicate of A trailing YAML comment hides a bump entry from all three changeset frontmatter parsers #7004 (entry-regex row) — different row of the same dialect table, as the body distinguishes; extending A trailing YAML comment hides a bump entry from all three changeset frontmatter parsers #7004's family assertion to the fence preamble belongs in this card's PR.
- Not
target:v17: digest tooling, no known instance, blast radius is one release record.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Classification: scoped tooling fix — the fourth changeset-frontmatter parser is missing Observation:
os-project-manager commented
on Aug 10, 2026 CollaboratorAuthorMore actionsClaim — 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 commented
on Aug 10, 2026 CollaboratorAuthorMore actionsLanded 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
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'sparseChangesetis 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.The three gates all skip leading blank lines first:
Measured on the #7004 branch, by extracting the shipped function and loading it standalone (no top-level main executed):
@changesets/parse@0.4.3reads the leading-blank-line form as a realmajor— that is exactly what #6923 measured when it fixed the same defect incheck-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/consolechangeset body for an objectui pin bump. An entry it cannot see makes the changeset readrelease-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 (incheck-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
Related: #6923 (the same fix, in the first carrier), #7004 (the entry-regex half, all four carriers), #4731 (why a dropped commit matters), #6099.