Skip to content

test(types): retire the list-view tabs fixture objectstack#20357 made unauthorable, so the Spec Main Shape Gate compiles again (objectui#10987) - #10992

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-10987-spec-main-tabs-retired
Sep 28, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-10987-spec-main-tabs-retired

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #10987
Clause-②: no — the protocol retired the key upstream, and objectui follows with a test-only change. No published type, export or renderer behaviour moves: the by-reference NamedListView.tabs declaration is untouched, so nothing narrows ahead of the pin bump.

objectstack#20357 retired the list view's own tabs. One @object-ui/types fixture still authored it, so packages/types stopped compiling against spec main, and the Spec Main Shape Gate went red for every PR in the merge queue. This PR is test-only. Session: session_014mXUNuFomfj24w7s1pZzhN (mode:subagent, domain:ui seat 2, PM claim comment 5871115946).

What changed

  • packages/types/src/__tests__/p1-spec-alignment.test.ts: the fixture "should accept tabs configuration" is retired.
    • objectstack#20357 (6e3e5462c6) made the list view's tabs a retiredKey() tombstone whose input type is never, so the protocol now refuses what the fixture authored.
    • The installed 17.4.0 still accepts the key. So until the pin bump, neither an accept fixture nor a refusal fixture compiles against both specs.
  • The replacement fixture, "authors a named preset as a listViews entry, not as the retired list-view tabs", authors the protocol's prescription on an ObjectViewSchema.
    • Each tab becomes a named listViews entry: the tab name is the key, and the entry takes the tab's label and filter and declares its own columns.
    • defaultListView names the entry that isDefault picked.
    • The file had no listViews fixture before this one.
  • .changeset/10987-retire-list-view-tabs-fixture.md: the frontmatter is empty. check-changeset-presence counts a test under src/ as published source, and it asked for a declaration.
  • Nothing is skipped, disabled or ts-ignored. No workflow, published type or export changes.

Reproduction: red against spec main, green against both specs

The procedure is the gate's own:

  1. Build @objectstack/spec from objectstack 7fa3e3e07cc6 in a detached worktree: pnpm install --frozen-lockfile --filter @objectstack/spec..., then pnpm --filter @objectstack/spec build.
  2. Pack it with npm pack --ignore-scripts.
  3. Inject it into a separate objectui worktree with node scripts/spec-main-shape-gate.mjs inject. The marker .spec-main-shape-gate.json is present afterwards, and zod is re-pointed to 4.6.1, as the gate does.

The installed legs ran in the branch worktree, where the marker is absent. Each leg is pnpm run type-check in packages/types, which runs all three tsc programs (tsconfig.test.json included). Every leg ran under the shared verify lock.

leg spec under the compiler tree result
spec main, before source-built 7fa3e3e07cc6 42687baf20 (base) exit 2, 2 diagnostics. TS2322 "... is not assignable to type 'undefined'." at the authored tabs array. TS2339 "Property 'isDefault' does not exist on type 'never'." These are the two the gate reported on the queue run.
spec main, after the same injected build fd91433c16 (head) exit 0, 0 diagnostics
installed, after published 17.4.0 fd91433c16 (head) exit 0, 0 diagnostics

The gate's own report step was run over the same logs:

  • Before: exit 1. Both rows are attributed to src/__tests__/p1-spec-alignment.test.ts "against objectstack-ai/objectstack@7fa3e3e07cc67877ae2f5d49eac42665c0515fda".
  • After: exit 0, "objectui type-checks against @objectstack/spec at that commit."

objectstack main has moved one commit since the build, to 8cdbe0c6e5. That commit touches nothing under packages/spec: git log 7fa3e3e07c..8cdbe0c6e5 -- packages/spec is empty, and the range counts 1.

⚠️ The local check is narrowed on purpose. The gate runs turbo run type-check --continue over every package. Locally, only @object-ui/types was compiled against spec main. It is the only package the gate reported on the queue run (against 6e3e5462c6), and the only package this diff touches. The full farm is the gate's own run on this head.

Census pins

The census pins are the order's three (object-view-unmirrored-keys-7779, schema-reference-named-list-view-keys-7923, list-view-spec-parity), plus the edited file. They were run with pnpm exec vitest run from the repo root.

spec tree result
installed 17.4.0 head fd91433c16 4 files, 296 passed (296)
spec main (7fa3e3e07cc6) head fd91433c16 1 file failed, 3 failed, 293 passed (296)
spec main (7fa3e3e07cc6) base 42687baf20 the same 3 failed, 293 passed (296)

All three failures are in object-view-unmirrored-keys-7779, in the describe block "objectui#7924 — the unread members, in the FOUR buckets the ruling was written in, derived against the installed protocol":

  • "five of the 50 are RETIREMENT TOMBSTONES, refused BY NAME ...": the received set adds pageName and tabs.
  • "objectui declares every LIVE protocol key on this surface ...": the expected length was 45, and the result was 43.
  • "BUCKET ① is EMPTY since objectui#10758 ...": the expected value was pageName, tabs, and the result was empty.

These are runtime pins, derived against the INSTALLED protocol. The Spec Main Shape Gate runs no tests, so they do not gate the queue. They fail the same way on base: pageName is already retired on spec main and sits in the same bucket, and it turns them red before tabs does. That is how objectui carries the pageName retirement today: no objectui change before the pin bump, and the pins move at the bump.

Gates

All gates were run at head fd91433c16.

  • packages/types type-check: exit 0 on the installed spec, and exit 0 on spec main (see the table above).
  • pnpm exec vitest run packages/types/ (installed spec): 271 files, 5984 tests passed.
  • node scripts/check-changeset-presence.mjs: exit 0. "1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/10987-retire-list-view-tabs-fixture.md."
  • pnpm check:pending-changeset-literals: exit 0. "No test source names a pending changeset."
  • pnpm check:new-line-citations: exit 0. "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"
  • pnpm check:control-bytes: exit 0. "check-control-bytes: OK (scanned 9273 tracked text file(s); skipped 85 binary)."
  • The changeset-guard pair: check-changeset-no-major exit 0, and check-changeset-overwrite exit 0.
  • git merge-tree --write-tree against a fresh origin/main: exit 0, tree e5e70ce20c. origin/main is 42687baf20, which is still this branch's base.
  • Lint, narrowed: eslint ran over the one edited .ts file with --no-inline-config --format json and reported 1 file, 0 errors and 0 warnings.
    • Population: the repo-root eslint.config.js. packages/types has no config of its own, and that config's **/*.{ts,tsx} and test-file blocks cover this file.
    • Invariance: that config enables no type-aware linting (no parserOptions.project, no projectService), so this diff cannot move the verdict on any untouched file. The changeset is markdown and outside every package's lint run.

Acceptance notes (left for the pin bump)

These sites compile against both specs today, so they are left untouched, as the order says:

  • NamedListView.tabs?: ListViewSchema['tabs'] in packages/types/src/objectql.ts, the declared-inert member beside pageName. On spec main it resolves to undefined. At the bump, its docblock ("Tab definitions for a multi-tab view interface") and the objectui#8980 measurement text beside it stop being true.
  • objectui's ListViewSchema (the list-view node type) takes tabs by reference from SpecListViewSchema.shape. It follows the tombstone at the bump with no edit.
  • The census in object-view-unmirrored-keys-7779.test.ts: BUCKET_DECLARED_INERT, NAMED_LIST_VIEW_UNREAD, PROTOCOL_RETIRED_KEYS and the live-key count. They go red at the bump, for pageName and tabs together (the three rows above).
  • plugin-list's TabBar, the one component that could draw the list view's own tabs. objectstack#20357 measured it as having zero production mounts. That was not re-measured here, and there is no carrier.

These were measured and are not sites:

  • userFilters.tabs, the page-only preset bar that reuses ViewTabSchema, which is not retired. It appears in phase2-schemas and spec-symbol-parity in packages/types, and in plugin-list's UserFilters tests.
  • DetailView.tabs and page:tabs.
  • The docs. The plugin-view.mdx "View tabs" section and the schema catalog's object-view-named-views entry already teach the listViews prescription.
  • Everything else. A grep covered tabs arrays carrying isDefault or pinned, references to ListViewSchema['tabs'], and .tabs reads, across packages, apps, content/docs, examples and skills. It finds no other author of the list view's own tabs. Controls: the same patterns hit the retired fixture in packages/types at base, and they hit the userFilters.tabs sites above.

Generated by Claude Code

… unauthorable (objectui#10987)

objectstack#20357 retired the list view's own `tabs` as a `retiredKey()`
tombstone, so on spec `main` its input type is `never` and the fixture
"should accept tabs configuration" in `p1-spec-alignment.test.ts` no
longer compiled on the Spec Main Shape Gate (TS2322 on the `tabs` array,
TS2339 on `isDefault`). The installed 17.4.0 still admits the key, so
neither an accept nor a refusal fixture compiles on both specs until the
pin bump; the fixture is retired, and its place is taken by the
protocol's prescription: each tab as a named `listViews` entry, with
`defaultListView` naming the one `isDefault` picked.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…thing (objectui#10987)

The presence gate counts a test under `src/` as published source, so the
test-only change declares itself with an empty frontmatter.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
@github-actions

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 3 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/8604-record-details-columns-enum.md

  • names p1-spec-alignment.test.ts → packages/types/src/__tests__/p1-spec-alignment.test.ts — edited by this change

    ⚠️ The census behind this narrowing covers this repository only: one in-repo call site wrote the number (p1-spec-alignment.test.ts), and it is corrected in the same change. A TypeScript consumer of @object-ui/types outside this repo that wrote columns: 2 is not observable from here and gets a compile error (TS2322) naming the key — which is why the FROM/TO is spelled out above. Nothing to migrate at runtime: the renderer passes the authored value straight through, and the registry manifest (@object-ui/plugin-detail) already published this key as type: 'enum', enum: ['1','2','3','4'], so the published TypeScript face was the only layer that disagreed.

.changeset/9040-retire-record-details-layout.md

  • names packages/types/src/__tests__/p1-spec-alignment.test.ts → packages/types/src/__tests__/p1-spec-alignment.test.ts — edited by this change

    • packages/types/src/__tests__/p1-spec-alignment.test.ts wrote layout: 'stacked' on this interface and read it back. Both lines are gone, with the reason stated at the site and a live-key read-back put in their place so the leg is not quietly shrunk. Its RecordHighlightsComponentProps neighbour keeps its own layout — a different key on a different face. - packages/types/src/__tests__/record-details-top-level-9040.test.ts ledgered the divergence as OPEN. Those legs become the retirement's own: a keyof absence assertion (with a declared key read through the identical form as its control), a @ts-expect-error literal, and a new source-text leg. - packages/types/src/__tests__/record-highlights-layout-9187.test.ts read this declaration as TEXT, using its three-value layout as the lit control for a two-member assertion about the sibling. That control MOVED to RecordChatterComponentProps.position — a three-value union the contract genuinely declares — as that file's own instruction required. It was never to be deleted outright, and it is not.

.changeset/9187-record-highlights-layout-two-values.md

  • names p1-spec-alignment.test.ts → packages/types/src/__tests__/p1-spec-alignment.test.ts — edited by this change

    ⚠️ The census behind this narrowing covers this repository only, and it found no in-repo authoring to migrate: every in-tree layout: 'grid' belongs to a different component (detail-view in content/docs/api/schema-reference.md and phase2-schemas.test.ts, ai-recommendations in packages/plugin-ai/README.md), and the one in-repo consumer of this interface that writes a layout (p1-spec-alignment.test.ts) writes 'horizontal'. So no document in this repository stops type-checking. A TypeScript consumer outside this repo that wrote grid is not observable from here and gets a compile error (TS2322) naming the key — which is why the FROM/TO is spelled out above.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Compared the checked-out tree with 42687baf2 (merge-base with origin/main): 1 file(s) changed outside .changeset/, read against 1698 pending declaration(s) that publish a body (2298 pending in total). · run

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3103.9 KB 3104.5 KB
Main entry chunk (gzip) 149.7 KB 350 KB
Entry file index-q9OI0-wf.js —
Status PASS —

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

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.58KB 6.17KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.52KB 3.45KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 558.59KB 133.88KB
core (index.js) 9.93KB 3.94KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 227.61KB 63.16KB
fields (index.js) 261.01KB 66.28KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 39.32KB 11.09KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 51.96KB 14.83KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 137.83KB 36.71KB
plugin-designer (index.js) 215.78KB 44.42KB
plugin-detail (index.js) 233.51KB 61.80KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 161.21KB 41.41KB
plugin-gantt (index.js) 170.35KB 42.19KB
plugin-grid (index.js) 228.33KB 62.59KB
plugin-kanban (index.js) 48.43KB 15.11KB
plugin-list (index.js) 115.86KB 28.64KB
plugin-map (index.js) 22.90KB 7.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.17KB 12.20KB
plugin-timeline (index.js) 31.07KB 9.15KB
plugin-tree (index.js) 11.21KB 3.89KB
plugin-view (index.js) 89.44KB 22.41KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.16KB 39.05KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.03KB 1.86KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.78KB 2.09KB
sdui-parser (codegen.js) 7.50KB 3.05KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.16KB 2.71KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 18.27KB 6.22KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 3.83KB 1.49KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 17.15KB 6.32KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.27KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: fd91433c166c875cacc76ea228192a0a7a9c7ba1

This is an in-seat review. The PR changes one test file and adds an empty changeset (2 files, +29 −17), Clause-②: no. It fixes the red required Spec Main Shape Gate that ejects every queued objectui PR. I read the whole diff.

① Derived judgments

  1. The fixture is retired, not bent.
  2. The replacement fixture is the protocol's own prescription.
    • Each tab is a named listViews entry on an ObjectViewSchema: the tab's name is the key, label is label, filter is filter, and the entry declares its own columns.
    • defaultListView names the view the tab's isDefault picked.
    • It compiles on both spec builds, and its three expectations are literal reads of the fixture.
  3. The reproduction is the gate's own procedure. The spec is built from objectstack 7fa3e3e07c and injected by scripts/spec-main-shape-gate.mjs.
    • Base: exit 2, the two diagnostics.
    • Head: exit 0 against spec main and exit 0 against the pinned 17.4.0.
  4. Nothing published moves. NamedListView.tabs?: ListViewSchema['tabs'] is left as is. It compiles on both specs, and it is carried to the pin bump the same way pageName was. So Clause-②: no holds.
  5. The census rows the dev names are pin-bump items, not this PR's. On spec main, three runtime pins in object-view-unmirrored-keys-7779 go red: the tombstone list, the live-key count 45 to 43, and bucket ①. They are red identically at base, and the gate runs type-check, not tests. They move together with pageName at the pin bump.

② Semver level

The changeset is empty: test-only, releasing nothing. check-changeset-presence asked for it and accepts it. The level is not major.

③ Boundary flags

  • CI: this record posts only after every check at fd91433c16 is final and green, the Spec Main Shape Gate included. That green gate is the proof that matters.
  • Merge-tree (dev): clean against main 42687baf20.
  • Carried to the pin-bump PR (noted in the PR's Acceptance notes): the NamedListView.tabs docblock and the 7779 census rows for pageName and tabs.
  • State: draft, with assignee os-elon-musk.

Implemented-by: claude/issue-10987-spec-main-tabs-retired
Reviewed-by: session_014mXUNuFomfj24w7s1pZzhN

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 28, 2026 14:23
@os-zhuang
os-zhuang disabled auto-merge September 28, 2026 14:24
@os-zhuang
os-zhuang merged commit 40c076f into main Sep 28, 2026
45 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10987-spec-main-tabs-retired branch September 28, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants