Skip to content

objectui-changeset-digest under-counts breaking entries: the family of author annotation shapes it misses (a decorated opener, #23112; a parenthetical "(breaking …)" inside a bold lead label) #23118

Closed

Description

@objectstack-fleet

Filing-gate category ① — a defect with a named landing point; reach: exception release text: the digest writes the @objectstack/console changeset that publishes into its CHANGELOG on every console pin hop (scripts/bump-objectui.sh).

This is the family card for one defect class: hasBreakingAnnotation() in scripts/objectui-changeset-digest.mjs does not recognise a breaking annotation that an objectui author did write, so the console changeset under-counts breaking entries. A range whose only breaking entry takes a missed shape also skips the ADR-0087 disposition prompt. New shapes join this card; ⛔ no single-shape card.

Reader who acts: the domain:devx execution seat, through a dispatch of this card once triage grades it and gives the positional direction for shape 2.

Dedupe: semantic issue search on this repo, closed included, with the words "objectui changeset digest parenthetical breaking bold label hasBreakingAnnotation undercount console changeset". 46 hits. The only one covering this class is #23112 (shape 1, below); none covers shape 2. The nearest others are #6099 (the original annotation support, closed) and #7044 (a frontmatter parser miss, closed).

The family, one row per shape

# Shape Example Status
1 A pictograph (with its variation selector) between the heading/bullet mark and the word, at the line start: ## ⚠️ BREAKING, … objectui#12242's changeset #23112 → PR #23117 (in review at filing)
2 A parenthetical (breaking …) inside a bold lead label, not at the line start objectui 8a55f0ccd, .changeset/12059-sidebar-no-reorder.md: **`@object-ui/layout` (breaking, declared `minor` per the version policy).** open: this card

Shape 2, as measured by the #23112 dev (report on #23112; not re-run by this seat)

Why shape 2 needs a direction first

#23112's grade (6134888169) binds the opener rule to the line start: "⛔ Not a "contains BREAKING anywhere" match, which would count prose that merely mentions the word." Shape 2 sits inside a bold lead label, which is a different position. The same corpus also carries prose shapes in which "breaking" follows punctuation: ( 39 blobs, — 5, a double quote 2, per the same dev's corpus reading. So admitting shape 2 needs a rule for the lead-label position that is separate from the line-start opener. Triage gives that direction at grading.

Fix lands in

scripts/objectui-changeset-digest.mjs (hasBreakingAnnotation), with --self-test pins:

Activity

  1. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p2 · domain:devx · area:devpath, into pm:queue. Shape 2 is a second position: a bold lead label that opens the line

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T01:56Z. ⛔ Not a claim, ⛔ not a dispatch.

  2. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · domain:devx seat 1 · 2026-10-13T02:24Z
    Session: session_012zwsLMxQBwHUYJgPyrpEvx
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-23118-digest-lead-label-breaking
    Worktree: objectstack-issue-23118
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: scripts/objectui-changeset-digest.mjs: a lead-label rule beside BREAKING_BLOCK_OPENER inside hasBreakingAnnotation, plus whatever markBreaking / OPENS_WITH_BREAKING_LABEL need so that a lead label marked this way is never restated, and the --self-test cases. Nothing else (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus (the default judgment tier; dispatch-gates --tier on this surface: "no path-derived mandate", floor sonnet · default opus · ceiling fable)
    Clause-②: no
    Responsibility: scripts/objectui-changeset-digest.mjs's hasBreakingAnnotation (on main 0d4300410, after PR #23117) produces the miss | no platform path covers it: the digest's count line is the console changeset's only breaking signal | every console pin hop (scripts/bump-objectui.sh) reaches it; 39 objectui changeset blobs carry the shape, per #23112's dev
    Thread-read: 6136389360
    Serial constraints cleared: no open PR touches scripts/objectui-changeset-digest.mjs or scripts/bump-objectui.sh (all 8 open PRs' file lists read at this act). The sibling PR #23117 (#23112) merged as c9b5b24b0f, and this branch starts after it.

  3. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23118,
      "status": "done",
      "branch": "claude/issue-23118-digest-lead-label-breaking",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23131",
      "session": "session_012zwsLMxQBwHUYJgPyrpEvx — subagent, so the parent's id (the dispatch's PM session; the claim's Session line names the same id)",
      "premise_still_valid": true,
      "summary": "scripts/objectui-changeset-digest.mjs gains BREAKING_LEAD_LABEL beside the byte-identical BREAKING_BLOCK_OPENER. A line reads breaking when it opens (after optional indentation and an optional -/*/+ bullet) with a ** span that closes on that line, and holds, before anything closes it, a parenthetical whose first word is breaking (any case). hasBreakingAnnotation tests it on every line, so a bulleted label that opens no block counts. Corpus (blobless clone of objectui, every head + every pull-request head, main 45ae6b89e845; 6449 .changeset blobs / 4825 paths): 39 blobs / 18 paths flip (33 / 18 on heads and on main), 0 flips outside a lead label, 0 lost readings. The heads-corpus '(' set is 39 blobs / 23 paths, which matches the earlier reading exactly. It splits as 33 / 18 inside a line-opening bold lead label (these flip) and 6 / 5 prose (none flips): a label closed before the paren, an unbolded plain label, an unbolded code-span label, mid-sentence. Mechanism assumptions: (1) reproduced on main f931e765b: false for objectui 8a55f0ccd 12059-sidebar-no-reorder.md (blob 873e53f906), control 12242 true. (2) split as above. (3) measured: none of the 39 flipped blobs opens its summary with the lead label, so the stamp always lands on an ordinary first paragraph. markBreaking / OPENS_WITH_BREAKING_LABEL are deliberately unchanged: a lead label names a package or topic, not the class, and the count note's 'Each is marked **BREAKING**' needs the stamp. The decision is pinned (cases 10, 14). Real hops: the current pin hop 7578323a544e..1fb1ced36243 and the prospective next hop 1fb1ced36243..45ae6b89e845 are byte-identical. Of the last 11 hops, 2 change: 47b1f0bb7174..20c6d351ad74 goes 6 to 10 breaking (8a55f0ccd, c7b30bd66, 025341692, 3fd862510) and a58626c88dc8..f0268ad78485 goes 4 to 10 (5d77c099b, cf62edf68, b13ea3c67, 1473757bf, d7e9e9ab6, d73d98770).",
      "tests": "All at HEAD b7b8bf6d7 (script blob 2e67cb6c2848). (1) node scripts/objectui-changeset-digest.mjs --self-test: exit 0, 163 checks, 'objectui-changeset-digest --self-test: all checks passed'. The new battery '#23118: a bold LEAD LABEL holding a (breaking …) parenthetical' has 16 cases at floor 16, and the roster floor goes 17 to 18. The #23112 (16) and #6099 (17) batteries are unchanged and green, so every shape-1 pin of PR #23117 holds. (2) Ablation from the committed state via scripts/ablation-replace.mjs in wrap mode (root script, run from source, no build/dist). Each leg went anchor 1 to 0 and replacement 0 to 1, then was restored with blob == HEAD 2e67cb6c2848 and git diff HEAD empty. Leg 1 replaces the rule's call site with a comment (blob 2e67cb6c2848 to 781585fad31f): exactly 8 of 16 #23118 cases go red, all positives (1, 2, 3, 11, 12, 13, 14, 16), no other battery moves, self-test exit 1, and the corpus census shows 0 flips. Leg 2 widens the rule to '(breaking' anywhere (blob to ffcc7b692ee7): 7 cases go red (negatives 4, 6, 7, 9 and digest cases 11, 12, 15), and the census shows 45 blobs / 23 paths flipping with 6 blobs / 5 paths outside a lead label, so the corpus check can fail. (3) Gates: 30 derived by dispatch-gates --commands --repo objectstack-ai/objectstack on the real change set, identical to the dispatch's list, all exit 0. pnpm check:pm-dispatch-gates ran detached (nohup, log read): '1833 cases pass', EXIT=0, 375.2s. --ran: '30 derived, 30 run, 0 NOT-MEASURED, 0 UNRUN'. Consumer suites: pnpm check:objectui-bump exit 0 ('20 assertions across 5 cases'); pnpm check:changeset-gate-self-tests exit 0 (empty-changeset 170, adr-0087 548, no-major 401); check:objectui-changeset also ran objectui-range --self-test (imports classifyRange), passed. (4) Lint, a proven narrowing: the population is read from eslint.config.mjs (the **/*.{ts,...,mjs,cjs} object covers scripts/*.mjs); --format json gives files 1, errors 0, warnings 0; all 7 parserOptions carry only ecmaVersion/sourceType, so no type-aware linting is enabled and untouched files' verdicts are invariant. (5) Control-byte self-scan of the changed file and the PR body: 0 hits. (6) CI at report time on b7b8bf6d7: 40 check runs, 11 success, 11 skipped, 18 in_progress, 0 failure.",
      "mcp_calls": "0 — no MCP GitHub tool called (reads via gh api REST; writes via the scripts/pm relay)",
      "api_writes": "3 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]: (a) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft, #23131) + POST /repos/objectstack-ai/objectstack/issues/23131/assignees [zhuangjianguo], read back byte-identical (13544 bytes), draft true; (b) label-write = POST /repos/objectstack-ai/objectstack/issues/23131/labels [skip-changeset], read back size/m + skip-changeset; (c) this os-dev-report comment = POST /repos/objectstack-ai/objectstack/issues/23118/comments. Plus git push (not REST) x2 to the claim branch: the empty-branch probe and b7b8bf6d7.",
      "gates": {
        "derived": 30,
        "ran": 30,
        "exit_nonzero": 0,
        "reconcile": "30 derived, 30 run, 0 NOT-MEASURED, 0 UNRUN (dispatch-gates --ran, at b7b8bf6d7)",
        "extra": [
          "pnpm check:objectui-bump :: exit 0",
          "pnpm check:changeset-gate-self-tests :: exit 0"
        ],
        "ci": "in_progress at report time (40 runs: 11 success, 11 skipped, 18 in_progress, 0 failure)"
      },
      "line_budget": "not applicable — no skills/** or line-ratcheted ledger touched; diff +242/-2 in 1 file (dispatch-gates changed lines 244, under the 3000 human-merge threshold)",
      "deviations": [
        "Corpus wider than 'every head': the clone also fetched every pull-request head (7169 refs), so the full set is 6449 blobs. Every count is also given for the heads-only subset (5683 blobs), which is the set comparable to the earlier reading; that subset's '(' total is 39 / 23, which matches it exactly.",
        "File surface used narrower than claimed: markBreaking / OPENS_WITH_BREAKING_LABEL are untouched. The claim allowed changing them 'so that a lead label marked this way is never restated'. Measured: no flipped blob opens its summary with the label, so the question never arises in the corpus. For the hypothetical case, the stamp is kept on purpose (reasoning in summary, pinned by cases 10 and 14); it does not restate a breaking label. If the seat wants the label kept verbatim instead, that is a one-fragment change to OPENS_WITH_BREAKING_LABEL plus flipping pins 10 and 14.",
        "objectui reads: only from a blobless bare clone in this run's scratchpad, with .changeset blobs batch-fetched. The digest ran over a --no-checkout linked worktree of that clone, because the CLI requires a .git entry. Nothing was fetched into, checked out in, or written to the shared /home/user/objectui checkout. That scratch worktree was removed with --force, because a no-checkout worktree always reads as dirty and it held no work. The objectstack worktree was removed without --force after the branch was confirmed pushed and git status was clean.",
        "pm-dispatch-gates: run detached with nohup per its header, and its log was read after the 29 foreground gates finished. The wrapper (PID 20445) had already exited with EXIT=0 in the log, so no tail --pid wait was needed.",
        "Attribution: commit trailers use AGENTS.md's model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. The PR footer uses AGENTS.md's session-URL form, not the harness's robot-line form.",
        "Report template: added gates / line_budget / deviations / files_changed, which the dispatch says the seat reads; the role file's template does not carry them."
      ],
      "files_changed": [
        "scripts/objectui-changeset-digest.mjs"
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: exception: release-text (pending changesets publish into @objectstack/console's CHANGELOG at the next release) · evidence: two console changesets still pending on main carry the old rule's under-count. .changeset/console-20c6d351ad74.md line 43 reads '⚠️ 6 of these carry a breaking change', but the fixed digest at b7b8bf6d7 over 47b1f0bb7174..20c6d351ad74 reads 10, with 4 entries unmarked: objectui 8a55f0ccd, c7b30bd66, 025341692, 3fd862510. .changeset/console-f0268ad78485.md line 111 reads '⚠️ 4 of these carry', but the fixed digest over a58626c88dc8..f0268ad78485 reads 10, with 6 unmarked: 5d77c099b, cf62edf68, b13ea3c67, 1473757bf, d7e9e9ab6, d73d98770. The other 9 pending console changesets read the same under both rules. Out of this card's scope (no .changeset/ edits). Suggested landing: a changeset-only PR that hand-corrects the two count lines and stamps the entries, named as a sub-issue of #23118. Regenerating them would rewrite their hand-answered ADR-0087 dispositions · dedupe words: pending console changeset breaking undercount 20c6d351ad74 f0268ad78485 lead label",
        "class: a · reach: exception: release-text · evidence: further positions of the same family that the binding grade rules prose, so they are left unflagged: 6 blobs / 5 paths on heads. They are a label closed before the parenthetical, '**Behaviour change on the console record page** (breaking in the objectui sense,' (5896-feeditem-single-constructor.md, 2 blobs); an unbolded plain-text label, 'Narrowed (breaking for an author who wrote them, …' (11168-element-family-inputs.md, 11168-action-family-published-inputs.md); an unbolded code-span label, '`@object-ui/i18n` (BREAKING; `minor` under this repository's release model …):' (11674-shortcuts-dialog-wired-only.md); and mid-sentence prose (11717-dashboard-widget-chart-measure-arity.md). The 11674 and 11717 changesets fall inside the pending console hops 0abd4f9f8769..1fb1ced36243. Per the card's own rule, further shapes join #23118 as a comment for triage, not a new card. 11717 is genuine mid-sentence prose that the #6099 positional principle rejects by design · dedupe words: objectui changeset digest unbolded lead label breaking parenthetical code span label closed"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT · PR #23131 (draft, head b7b8bf6d71) · domain:devx seat 1 · session_012zwsLMxQBwHUYJgPyrpEvx · 2026-10-13T03:05Z

    Checked on GitHub and on the branch, not on the report's say-so:

    PR shape

    • Open, draft, base main.
    • Body line 1 is Fixes #23118, and the body has no other closing keyword.
    • Assignee zhuangjianguo, labels size/m and skip-changeset, mergeable_state: clean.
    • One file, scripts/objectui-changeset-digest.mjs, +242 / −2. That is a root script and no published package, so skip-changeset is right. Not governed.

    The rule, read on the branch

    Evidence (from the report; the spot check above corroborates it)

    • Corpus: 39 blobs / 18 paths flip, with 0 flips outside a lead label and 0 lost readings. The heads-only ( set of 39 / 23 matches the earlier reading and splits into 33 / 18 lead-label blobs and 6 / 5 prose blobs.
    • Self-test: 163 checks, with the new battery at 16 cases and the floor going from 17 to 18.
    • Ablation, two legs, both restored to the HEAD blob:
      • removing the rule turns 8 positives red;
      • widening it to "(breaking anywhere" turns 7 cases red, and the census then flips 6 blobs outside a lead label, so the corpus check can fail.
    • Gates: 30 derived, 30 run, all exit 0. mcp_calls: 0.
    • markBreaking and OPENS_WITH_BREAKING_LABEL are left unchanged on purpose, within the claim. No flipped blob opens its summary with the label, and the decision is pinned by cases 10 and 14.

    CI on b7b8bf6d71: 43 check runs, 32 success and 11 skipped, none red. The seat lands it through the queue.

    Out-of-scope findings

  5. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    LANDED: PR #23131 is merged through the merge queue as 88072064e6. Read on origin/main by domain:devx seat 1, session_012zwsLMxQBwHUYJgPyrpEvx, at 2026-10-13T03:23Z.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:devxpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions