Uh oh!
There was an error while loading. Please reload this page.
refactor(react): retire the spec-bridge — SpecBridge, bridgeListView, bridgeFormView (#6366) - #6632
refactor(react): retire the spec-bridge — SpecBridge, bridgeListView, bridgeFormView (#6366)#6632claude[bot] wants to merge 3 commits into
Conversation
…tView, bridgeFormView Removal under the 2026-08-27 maintainer ruling (Option A, whole bridge): zero consumers at every reachable endpoint, and a bridged route that is structurally unable to deliver fields (no objectName, no customFields — the renderer's own "cannot proceed" branch). The suites pinning the removed route are retired with it; the non-bridge pins on ObjectGrid's own behavior stay. The one-authority ledger drops the three form-view.ts rows (app-shell's form-spec.ts is now the sole authority), and the schema-reference doc line advertising the bridge round-trip is removed. Changeset declares the honest `major`; check-changeset-no-major refuses it by design — held for release coordination per the ruling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-sales
commented
Aug 28, 2026
PM — retracting an instruction I sent this branch. The dev was right to decline it, and I was wrong. When
That constraint was in the dispatch order I wrote for this card. So I contradicted my own order, on the strength of a CI error message, within minutes of the check going red. The dev declined the specific edit, honored everything else in the message (ran the complete changeset-gate family, kept the PR draft), and reported the conflict instead of quietly resolving it either way. That is the correct handling and it is what the stop-and-report clause exists for. The red on this PR is the anticipated outcome, not a defect.
The PR stays draft and red until the maintainer rules. Going green here requires a release act, which is not this lane's to perform. The dev's flag-back on my human-floor question is answered and I am recording it as measured, not assumed: no published capability with a reachable consumer is removed — zero consumers at every measurable endpoint, and the post-removal repo scan finds zero imports, with a positive control in the same query shape ( It also settles a question I had raised from the bundle report and correctly refused to answer from it: this is a real removal, not a barrel-only one. The release-coordination decision is now on #6366 with both shapes prepared. Nothing on this PR is waiting on the dev. Generated by Claude Code |
…ng (#6366) The fixed-group publish policy means one `major` changeset carries all 39 publishable packages to the next major while `@objectstack` stays pinned to its current one, breaking the cross-repo "same major ⇒ compatible" invariant. objectui's own breaking changes ship as `minor` with the break spelled out in the changeset body (AGENTS.md §版本号策略, scripts/check-changeset-no-major.mjs) — the BREAKING CHANGE block already in this changeset satisfies that condition unchanged. Maintainer ruling 2026-08-28. `check-changeset-no-major.mjs` goes from exit 1 (naming this file) to exit 0.
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Part of #6366 — the code removal is complete on this branch. ⭐ The changeset score is RESOLVED as of 2026-08-28 (see below); the earlier stop-and-report is now history, not current state. Merging still leaves #6366 open, because this PR uses
Part of.What this is
Whole-bridge retirement of the spec-bridge in
@object-ui/react:SpecBridge,bridgeListView,bridgeFormView, and the typesBridgeContext/BridgeFn/ObjectDefLite, per the maintainer ruling recorded on the card (os-zhuang, 2026-08-27T05:31Z, decision-inbox batch 4, verbatim 「其他接受」 — stage-1 recommendation A with the whole-bridge constraint adopted). Basis, measured in stage 1 (2026-08-26, PM-verified, not re-derived here): zero consumers at every reachable endpoint (in-repo, sibling repo, GitHub-wide public search); the bridged form route structurally unable to work (noobjectName, nocustomFields— the renderer's own "cannot proceed" branch, rendering "a field-less card in silence"); the only working recipe existed solely inside the list bridge's own tests and was documented nowhere.This knowingly reverses the 17.0.0 changelog line "The
listandformbridges are unaffected and remain the live authoring path" — same criteria that entry itself used to removebridgePage/bridgeDashboard.Diff map — every file, with which of retire/edit it got and why
Removed — the module (12 files):
packages/react/src/spec-bridge/**(SpecBridge.ts, bridges/form-view.ts, bridges/list-view.ts, index.ts, types.ts, and the seven suites under__tests__/). The seven in-module suites (FormViewRetiredKeys, FormViewSpecConformance, FormViewWidenedArms, ListViewExportOptionsLift, P1SpecBridge, RowHeightDensityAgreement, SpecBridge) pin only the bridge's own behavior — retirement of a route nothing travels, not quarantine.FormViewSpecConformanceis #5898's conformance suite: that restored-key work is superseded by this removal, not fixed — the route it repaired is gone, and #6366's measuredtext-vs-field:textasymmetry is mooted rather than repaired.RowHeightDensityAgreementpinned agreement between the bridge's density mapping and core'srowHeightToDensityMode; the non-bridge surface keeps its own pins (corenormalize-list-view.test.ts, plugin-gridrowHeightOffSpecBoundary.test.tsx).Removed — the two render-integration suites (PM assumption 2, measured):
packages/plugin-grid/src/__tests__/specBridgeColumnSpelling.test.tsx(4 tests, every one routes a spec ListView throughnew SpecBridge().transformListView) andspecBridgeExportFormats.test.tsx(5 tests, same). Both files exist to pin the SpecBridge-to-ObjectGrid seam; nothing unrelated rides in them. ObjectGrid's own behavior they touched in passing keeps independent non-bridge pins: column spelling viacolumnDeclaredSpellingOnly.test.tsx/columnSpellingDiagnosticRender.test.tsx, the export menu and server-stream gate viaexportGate.test.tsx/exportServer.test.tsx/ObjectGrid.exportOptionsKeys.test.ts.Edited, not deleted:
packages/plugin-grid/src/__tests__/gridNonAuthorKeys.test.tsx— this 859-line file is the objectui#5091 / #5234 / #5240 non-author-keys census, not a bridge suite; exactly oneit("the PRODUCER writes it onto the veryobject-gridnode ObjectGrid renders") used the bridge as its producer witness. That single test is removed with an in-place comment; the header's producer sentence now names the surviving producer (app-shell's ObjectView, built unconditionally). The removed test's own failure message said "do not just delete this assertion" — that instruction covered the 2026-08-20 producer-side-fix scenario, not a whole-bridge retirement by maintainer ruling; the replacement comment says so explicitly.Edited:
packages/react/src/index.ts— the one barrel line (export * from './spec-bridge/index.js', PM assumption 1 verified at line 14 on the merged ref).Edited:
scripts/__tests__/one-authority-per-exported-name-6273.test.ts— theKNOWN_COLLISIONSledger drops its threeFormFieldSpec/FormSectionSpec/FormViewSpecrows, whose second authority wasspec-bridge/bridges/form-view.ts; the ledger fails in the stale-baseline direction, so keeping them would be red. app-shell'sform-spec.tsis now the sole authority for those names.Edited (declared adjacent edit, one sentence):
content/docs/api/schema-reference.md— the sentence "Metadata using these keys round-trips through the SpecBridge without loss" is removed from the ObjectFormSchema spec-alignment bullet; the alignment claim itself stands and is unchanged. Declared here because the dispatch fence did not name this file: it is the same defect class (a live reference to the removed surface), mechanical, and gate-neutral.Added:
.changeset/retire-spec-bridge-6366.md—'@object-ui/react': minor, body naming the ruling and the measurement, and carrying the fullBREAKING CHANGE:block (the retirement-discipline changelog entry).⭐ The changeset score — RESOLVED 2026-08-28, gate is GREEN
The PR originally scored the changeset
major, as the honest declaration of a breaking removal on a published package, and stopped for release coordination rather than mislabelling it. The maintainer ruled on 2026-08-28: score itminor. That is not a concession — it is this repo's correct score, and the gate's own header says so:The mechanism: all 39 publishable packages sit in one
fixedgroup, so a singlemajordoes not release one package as a major — it carries the whole family off the@objectstackline it is pinned to. The condition theminorconvention attaches — the break spelled out in the body — was already satisfied by this changeset, which carries a fullBREAKING CHANGE:block namingSpecBridge,bridgeListView,bridgeFormView,BridgeContext,BridgeFn,ObjectDefLiteand the migration path. Only the bump level changed; ⛔ not one word of the prose.Precedent, all verifiable on
origin/main:.changeset/6355-retire-timeline-timescale-alias.md(merged as #6656) retires a published alias, says "BREAKING for authored metadata" in its body, and scoresminoron three packages; same shape in4919-retire-mobile-overrides.mdand3917-retire-action-condition-branch.md. Census of every pending changeset onmain: 362 patch, 188 minor, zero major.Gate, quoted before and after on this branch:
⛔
OBJECTUI_ALLOW_MAJORwas never set, and nothing was worked around.check-changeset-overwritestays green because this branch's own changeset counts as newly-added relative to theorigin/mainmerge-base, so editing it does not trip the overwrite guard.Two pending changesets in
.changeset/describe form-view-bridge behavior this PR removes:react-form-view-bridge-drifted-arms-5652.md('@object-ui/react': minor) andtidy-forms-carry-spec-keys.md('@object-ui/react': patch, #5898's entry). They are other PRs' release declarations, so this PR leaves them untouched — release coordination should decide whether they compile into the changelog alongside the retirement entry or are dropped as superseded.Verification
turbo run build --filter=@object-ui/react --filter=@object-ui/plugin-grid— 13 tasks successful (verify-lock VERDICT command-exit 0).grep -rl -E "SpecBridge|bridgeFormView|bridgeListView|BridgeContext|ObjectDefLite" packages/react/dist/matches zero files (exit 1) anddist/spec-bridge/does not exist, while the controlgrep -rl -E "SchemaRenderer" packages/react/dist/matches 29 files;dist/index.js/dist/index.d.tscarry no spec-bridge re-export.git grep -nE "SpecBridge|bridgeFormView|bridgeListView|BridgeContext|BridgeFn|ObjectDefLite"over*.ts/tsx/mts/mjs/jsreturns comment lines only (doc-comments and the retirement notes this PR adds; zero imports, zero code references); positive controlSchemaRendererin the same shape: 482 files.@object-ui/reacttype-check(tsc + tsconfig.test.json),@object-ui/plugin-gridtype-check,tsc -p tsconfig.scripts.json --noEmit(covers the edited ledger test).pnpm test --shard=N/4 --maxWorkers=2, all four shards — results and the head sha they ran on are in the report comment on finding(react): a spec-bridge form field skips the normalizer's object-schema merge — it arrives with the raw spec (text), never the resolved widget id (field:text) #6366.origin/mainmerged in, zero conflicts):vitest run packages/react/— 54 files / 709 tests passed;vitest run packages/plugin-grid/— 94 files / 875 tests passed; both packages'type-checkclean;check-control-bytesexit 0 (5513 files).check-control-bytesOK;check-spec-symbol-derivationgreen post-removal;check-changeset-presencegreen (16 source files of 2 released packages, 1 changeset);check-changeset-fixedgreen;check-changeset-overwritegreen; ⭐check-changeset-no-majorGREEN (was red by design before the rescore, quoted above). Targeted eslint on the three edited code files: 0 errors (9 pre-existingno-explicit-anywarnings on untouched lines); the fullpnpm lintfarm is CI-owned.Tripwire assessment (external-consumer evidence)
Live throughout implementation, not triggered. The one candidate found: the
content/docs/api/schema-reference.mdsentence removed above — it advertises the bridge's lossless key mapping but shows no host consuming it and does not document theobjectNamestaple recipe; stage 1 already counted docs among the in-repo mention sites, and the ruling's "documented nowhere" (about the working recipe) stands. No docs page, example, README, migration guide, or fixture implying a host recipe surfaced beyond it. Fallback C stays unexercised.Residue left by fences (stale comments, no code references)
packages/plugin-grid/src/ObjectGrid.tsx(collision comment near line 1300; line 1799 is historical narration and stays true as history) — file outside this card's fence.packages/types/src/base.tslines 94-96 / 131 / 147-148 andpackages/types/src/__tests__/base-schema-label-vocabulary.test.tslines 70-71 — producer-example comments namingbridgeListView/BridgeContext;packages/types/**held elsewhere, read-only here.packages/plugin-form/src/__tests__/sectionVisibleWhen-6111.test.tsxline 14 —packages/plugin-form/**read-only for this card.packages/components/src/__tests__/inline-locale-label-read-sites.test.tsxlines 15/20 — historical narration of the PR fix(types): ariaLabel declares the keyed vocabulary, disabled accepts the predicate string (#4581) #4603-era measurement.All comment-only; none breaks compile or tests (proved by the scan above). Listed for a follow-up sweep.
⛔ Still held for a human
This PR removes published exports from
@object-ui/react. That is a breaking removal of a published capability, so it stays in draft and is merged by the maintainer — not flipped ready, not auto-merged, not enqueued by this lane, regardless of CI. Getting it green was the job; the merge is the maintainer's.