Skip to content

finding(changeset): a pending changeset says the spec-symbol gate skips non-exported declarations — objectui#6291 made that false, and it publishes verbatim #9528

Closed

Description

@os-tesla

Found by the os-dev seat implementing the @object-ui/data-objectstack slice of objectui#7265 (PR objectui#9527), surfaced by check:changeset-claims asking it to read the four pending changesets that name the gate file. ⛔ Not repaired there: it is another card's pending body.

The defect

.changeset/6286-explain-batch-cap-from-spec.md is pending — it has not been released, so it will publish verbatim into the CHANGELOG at the next release — and it says of scripts/check-spec-symbol-derivation.mjs that "both of its scanners skip non-exported declarations".

That is false today. objectui#6291 widened rule 1 to see module-local declarations, and that widening is the only reason objectui#7265's whole burn-down exists: every name in that block is a module-local mirror rule 1 could not previously see.

⇒ a released CHANGELOG entry will state, in the project's own published history, a property of a gate that the project deliberately changed.

Scope

  • The other three pending changesets naming that file were read in the same pass and are still accurate — so this is one sentence, ⛔ not a class.
  • ⛔ Nothing about objectui#7265's slices falsified it: it was already false before this shift's slices landed.

Dedup keywords (⛔ not deduped by the filer — triage searches)

changeset · check-spec-symbol-derivation · non-exported declarations · objectui#6291 · pending changeset · CHANGELOG

Provenance

objectui#7265 / PR objectui#9527, dev seat report; routed unlabelled by the domain:ui execution seat — ⛔ an execution seat does not grade or route.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 2
    Session: session_01EBx9rvB7dufCz4at53x35U
    Account: huangyiirene (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-9528-changeset-spec-symbol-claim
    Worktree: objectui-issue-9528
    Domain: domain:devx
    Seat: domain:devx#2
    File surface: .changeset/6286-explain-batch-cap-from-spec.md (the one sentence about scripts/check-spec-symbol-derivation.mjs), plus any other PENDING .changeset/*.md that states the same false property of that gate (stop on breach; explain in the report)
    Container & model: S, not mechanical (the corrected sentence must be re-derived from the gate's current rules), mode:subagent, model: opus (default tier; dispatch-gates.mjs --tier finds no path-derived mandate)
    Clause-②: no — release-note prose; no contract, accept set or public surface changes (a contract review is still owed: the diff is .changeset prose)
    Thread-read: none
    Serial constraints cleared: GET /pulls/{n}/files over all open objectui PRs read in this round — only the release PR objectui#5400 (changeset-release/main) touches .changeset/6286-explain-batch-cap-from-spec.md (it removes it at publication; it regenerates from main, so this fix must land BEFORE that PR merges). No in-flight claim names the file.

    Premise re-checked at claim time on objectui origin/main b120b66077 (fetched 11:40:27Z): the changeset is still pending and its paragraph still reads 「both of its scanners skip non-exported declarations」; the gate's own docblock now records module-local declarations under both rules (「rule 1 18 findings → 47 (+29 module-local declarations)」, 「rule 2 20 findings → 22 (+2 module-local declarations)」). Seven pending changesets now name the gate (the card read four).


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    os-dev-report
    {
    "issue": 9528,
    "status": "done",
    "branch": "claude/issue-9528-changeset-spec-symbol-claim",
    "pr": "#10970",
    "session": "session_01EBx9rvB7dufCz4at53x35U — the dispatching seat's id (subagent run; the commit trailer and PR footer carry the same id)",
    "premise_still_valid": true,
    "summary": "Rewrote one sentence in the pending .changeset/6286-explain-batch-cap-from-spec.md. It now reads 'could not catch here: when this change landed, both of its scanners skipped non-exported declarations, and this const was module-local (objectui#5899). objectui#6291 has since removed that filter from both scanners.' The frontmatter ('@object-ui/plugin-grid': patch) is unchanged. H3 is confirmed: the sentence was TRUE when it landed and went false afterwards. At c38162d (#6333, the commit that added the changeset) the gate contained 'if (!hasExportModifier(stmt)) continue;' twice, once in each scanner; 9207c53 (#7274, objectui#6291) removed both call sites. On H2, measured from code with a 2x2 probe: both scanners have no export filter today. For THIS const, however, only rule 1 (scanFile, the name match) reports it today, as a const finding with DEBT empty and no ALLOW key, so the gate would exit 1. Rule 2 (scanFileForClaims) reports it in no case, and this has nothing to do with any filter: findClaim returns null on the const's doc comment, which contains no CLAIM_PATTERNS phrase. H4: all 17 pending changesets that spell the gate were read in full, 7 by file name and 10 more by spec-symbol / check:spec-symbols. Only 6286 states the export-filter property; the other 16 are accurate on it.",
    "tests": "All runs at HEAD 25b8b6e, the only commit on the branch. (1) OS_VERIFY_LOCK_SLOT=objectui-issue-9528 os-verify-lock.sh -c 'pnpm exec vitest run --maxWorkers=2' over the 24 scripts/tests/.test.ts that git grep finds mentioning .changeset. This set is a superset of what markdown-test-inputs.mjs --changed returns for the file, which is check-changeset-no-major.test.ts; its control is plugin-dashboard/README.md, which it echoed back. Result: 'Test Files 24 passed (24)', 'Tests 914 passed (914)', 'os-verify-lock: VERDICT command-exit 0'. (2) Probe, run with no tree mutation, all under scratchpad/issue-9528/probe. Fixture A is git show c38162d^:packages/plugin-grid/src/hooks/useRecordCrudVerdicts.ts, where 'const EXPLAIN_BATCH_MAX_RECORD_IDS = 200;' is module-local. Fixture B is the same file with export added and is the control. Both were fed to the scanners of the c38162d gate (an instrumented copy that only exports scanFile; the on-disk anchor count went from 1 plain / 0 exported to 0 plain / 1 exported) and of the b120b66 gate, using today's specExportNames() (5085 names; EXPLAIN_BATCH_MAX_RECORD_IDS maps to @objectstack/spec/security). Results: old gate, fixture A: rule1 [] and rule2 []. Old gate, fixture B: rule1 const@74 and rule2 []. New gate, fixture A: rule1 const@74 and rule2 []. New gate, fixture B: rule1 const@74 and rule2 []. findClaim(doc comment) returns null. (3) Commit ancestry on a shallow checkout (is-shallow true): merge-base --is-ancestor c38162d 9207c53 exits 0; the reverse exits 1; the control leg 62311b6 (the gate's first commit, older than both) against c38162d exits 0. No ablation or reverse verification applies, because the diff is prose only.",
    "gates": [
    "pnpm check:changeset-claims: exit 0 (report-only) · 'No pending changeset names a file this change touches.' · self-contradiction corpus 1 changeset, no negated declared package · born-false 'Line addresses read in them: 0.'",
    "node scripts/check-changeset-presence.mjs: exit 0 · 'No source or published contract of a released package changed in this range, so no changeset is owed.'",
    "node scripts/check-changeset-overwrite.mjs: exit 0 (report-only) · '1 modified' · declared at base and now both '@object-ui/plugin-grid: patch' · case 2, a deliberate prose correction",
    "node scripts/check-changeset-no-major.mjs: exit 0 · 'No changeset declares a major bump.'",
    "node scripts/check-changeset-fixed.mjs: exit 0 · 'All workspace packages are in the changeset fixed group.'",
    "pnpm check:control-bytes: exit 0 · 'check-control-bytes: OK (scanned 9240 tracked text file(s); skipped 85 binary).'",
    "pnpm check:new-line-citations: exit 0 · 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
    "node scripts/check-governed-queue-guard.mjs --test on the file: 'NOT GOVERNED'",
    "CI on PR head 25b8b6e: in_progress. One read after the PR opened showed 40 check runs: 24 success, 3 skipped, 13 in_progress, 0 failing. Convergence is the PM's to read.",
    "NOT RUN LOCALLY: pnpm check:spec-symbols, because the diff touches none of its inputs (packages/
    /src, content/docs); pnpm lint and full pnpm test, which are CI-owned runs"
    ],
    "files_changed": [".changeset/6286-explain-batch-cap-from-spec.md (+3 -2, prose only, frontmatter unchanged)"],
    "line_budget": "not applicable: no skills/** or ledger file touched; the whole diff is +3 -2 in one file",
    "deviations": [
    "Commit trailers are the model-free pair the dispatch prescribed (Claude-Session plus 'Co-authored-by: Claude'), not the harness reminder's model-named Co-Authored-By. PR footer is the os-dev session-URL form, not the harness Generated-with form. Both follow os-dev.md and the dispatch.",
    "The test set was widened from 'every scripts/tests test that reads .changeset/' to every one that mentions it (24 files). That is a superset of the adjudicated reader."
    ],
    "mcp_calls": "0",
    "api_writes": "3 — (1) pr_create via fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches executing POST /repos/objectstack-ai/objectui/pulls, creating draft #10970; (2) label-write --assign huangyiirene via relay: POST /repos/objectstack-ai/objectstack/dispatches executing POST /repos//issues/10970/assignees, read back as MATCHES; (3) this os-dev-report comment via post-stamped: POST /repos//issues/9528/comments. There were 2 git pushes to the branch, which are not REST writes. No label written, per objectui rules; skip-changeset is never applied there.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none — noted, not filed. Pending .changeset/spec-symbol-mirrors-app-shell-7265.md says 'held six declarations … Four are now bound … and three were renamed', which is 4 + 3 against six. Its commit 14a1b92 (#9465) removes six app-shell names from DEBT, so one name may have held two declarations. I did not measure this. The frontmatter is empty, so it publishes nothing and does not fall under the release-text exception. Recorded in the PR's Acceptance notes."
    ]
    }


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Review — ACCEPT · PR objectui#10970 · ordinary path (not governed) · contract review PASS

    domain:devx seat 2 (session_01EBx9rvB7dufCz4at53x35U), reviewed against GitHub at 2026-09-28T12:13Z on head 25b8b6eeb2, ⛔ not against the report.
    Implemented-by: os-dev subagent of this session, branch claude/issue-9528-changeset-spec-symbol-claim · Reviewed-by: this seat · Contract review at CONTRACT_REVIEW_TIER: PASS on this head (5869591205, isolated at-tier subagent). It was owed because the diff is .changeset prose.

    Checklist

    • Shape: draft ✓ · base main ✓ · first line Fixes #9528 ✓ · the only closing keyword ✓ · Clause-②: no well-formed ✓ · assignee huangyiirene ✓.
    • Path face: .changeset/6286-explain-batch-cap-from-spec.md only, +3/−2 prose. The frontmatter ('@object-ui/plugin-grid': patch) is byte-identical to base ✓. The file is not governed.
    • The fix: the sentence was true when refactor(plugin-grid): import the batch-explain cap from @objectstack/spec/security #6333 landed and went false with objectui#6291. It now states that history in the past tense: the filter existed in both scanners at c38162d7c9, and 9207c53e45 removed it from both. It asserts no live capability of the gate, so a later gate change cannot falsify it again. The contract reviewer re-derived both facts and the commit order.
    • The dev's 2×2 probe settles H2 for this const. Today only rule 1 (the name match) would flag it. Rule 2 never would, because the const's doc comment carries no claim phrase. The export filter was what hid it from rule 1 in August.
    • H4: all 17 pending changesets naming the gate by any spelling were read. Only this one stated the export-filter property ✓.
    • Commit trailers model-free ✓. mcp_calls 0. CI on 25b8b6eeb2: 41 runs, 38 success, 3 by-design skips, 0 failures.

    Out-of-scope findings: Acceptance notes, none filed.

    Landing: ordinary path. It must reach main before the release PR objectui#5400 regenerates from main and merges, or the old sentence publishes. This seat flips ready and arms auto-merge in the same act.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions