Skip to content

fix(react): stop reading the retired navigation.view and substituting it for the navigation-MODE token - #9936

Merged
os-tesla merged 2 commits into
mainfrom
claude/issue-9874-navigation-view-retired-consumer
Sep 18, 2026
Merged

os-tesla merged 2 commits into
mainfrom
claude/issue-9874-navigation-view-retired-consumer

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #9874

useNavigationOverlay read navigation.view — removed in @objectstack/spec 17.5.0 under ADR-0049 — and spent it in the argument that carries the navigation MODE token. This stops both.

The premise, re-measured at source

Every reading below is mine, taken in a worktree off origin/main f5e2fcb4a.

probe dispatch said I measured ref · UTC
objectui origin/main tip 02bc27b08 f5e2fcb4a — the dispatch's base was stale by the time I fetched 2026-09-18T18:15:32Z
the read :275 const view = navigation?.view; confirmed, same line f5e2fcb4a · 18:16:06Z
the two consumers :323 / :356 onNavigate(recordId as string OR number, view ?? 'view') confirmed, same lines f5e2fcb4a · 18:16:06Z
lit control, same command 4 onNavigate( sites; :314 / :337 pass the literal new_window confirmed, 4 sites, same lines f5e2fcb4a · 18:16:06Z
resolved spec version 17.4.0 confirmed — pnpm-lock.yaml carries exactly one @objectstack/spec version string, 17.4.0; control in the same command, sibling package @objectstack/types@17.4.0 f5e2fcb4a · 18:17:55Z
declared ranges "^17.0.0, some ^17.2.0 / ^17.3.0" incomplete — also ^17.1.0 (packages/react, packages/plugin-detail) and ^17.4.0 (packages/types) f5e2fcb4a · 18:17:55Z

The retirement text was read at source in the sibling repo rather than taken from the card's quotation, on objectstack origin/main 07c6f822e (18:16:17Z), packages/spec/src/ui/view.zod.ts:1814-1822. It matches the card verbatim, and its prescription — the half the card did not quote — is load-bearing for this PR:

Delete the key; to choose what opens for a record, assign a record page to the object and let isDefault pick the one that opens — page assignment is the machinery that resolves a detail layout, and a list view's navigation block only decides HOW the detail is surfaced (mode, size).

⇒ the replacement route is page assignment, which lives nowhere near this hook. No fallback belongs here, and the fix is subtractive. retiredKey is z.never(...).optional() (objectstack:packages/spec/src/shared/retired-key.ts:106), so on the bump the key types never and view ?? 'view' would still compile — silently dead rather than loudly broken. That is the reason to remove the read now rather than let the bump find it.

The census the card left open — and what it turned up

Question 1, "does any other surface read navigation?.view". Corpus: git ls-files at f5e2fcb4a, 8090 tracked files, working tree clean.

git grep -nE 'navigation(\?)?(\.|\[.)view|nav(\?)?\.view' -- .

Four lines, and only one is a read of the live key: the hook itself. The other three are two prose comments and one packages/types parity assertion that belongs to objectui#9667. The same command carried a lit control on navigation?.mode, which fires across 40-plus lines. So: no other surface reads it.

A second probe asked whether anything reads the member off the hook's RESULT — that is the published NavigationOverlayState.view:

git grep -nE '\b(navOverlay|nav|state)\.view\b' -- 'packages/**' 'apps/**'

Zero lines, against a lit control in the same command on the sibling members of the same object (isOverlay, handleClick, selectedRecord, width), which fires 20-plus times. I also opened all 12 real call sites of the hook: none destructures view. So the published member has zero readers in this repository. Hosts outside this repository were NOT measured — that is an unmeasured site, not a negative.

⭐ Probe A had a blind spot, and stating it is what found the real work. It matches MEMBER READS, so an object literal authoring the key is invisible to it. A third probe over authoring sites turned up a surface neither the card nor the dispatch names:

packages/plugin-grid/src/__tests__/gridNavigationMembers-8071.test.tsx pins the retired substitution as intended behaviour — clickRow({ view: 'summary_view' }) asserting onNavigate was called with ('7', 'summary_view'), under a docblock bullet teaching it as the contract. packages/react/.../useNavigationOverlay.modeDefault.test.tsx pins the same thing. Both go red against the fix. ⛔ Neither is skipped, disabled or quarantined: both rows are INVERTED in place, each keeping its authored view fixture, because that fixture is the one input the old and new implementations disagree about.

Question 2, "what is the correct behaviour once the key is gone". Not a product choice, so 回翻条款 does not fire: the spec names the replacement route and it is a different machinery (page assignment), while this hook's remaining job — mode and size — is untouched. Both call sites now pass the literal 'view', which is what every config WITHOUT the key already dispatched. The one judgement call is flagged for the seat below.

What changed

  • packages/react/src/hooks/useNavigationOverlay.ts — the read is gone; both view ?? 'view' sites pass 'view'; NavigationOverlayState loses its view member; the module docblock gains the retirement, the prescription and the census; one authoring example that spelled the retired key is rewritten.
  • packages/react/.../useNavigationOverlay.modeDefault.test.tsx — one row inverted, one row added (the state shape, asserted on the KEY rather than on the value, because toBeUndefined() passes just as happily against the member this PR removed).
  • packages/plugin-grid/src/__tests__/gridNavigationMembers-8071.test.tsx — one row inverted, three comment blocks corrected.
  • packages/app-shell/src/views/ObjectView.tsx — a comment my change falsifies. It claimed a custom name arrived here "forwarded from navigation.view" and was "resolved by RecordDetailView from its own config". No layer ever resolved a view by that name. ⭐ This branch already treated the name and the mode token identically, which is exactly what made the substitution inaudible on the Console: behaviour there is unchanged, and that is the finding rather than a caveat.
  • .changeset/9874-navigation-view-retired-consumer.md — minor, per this repo's policy that its own breaking changes ship as minor with the semantics in the body.

Ablation — two legs, both restored and proven

Direction predicted before running: turn red, exactly two rows. Both legs mutate the real source, prove the mutation by blob hash, run, restore, and prove the restore by hash equality AND an empty git diff HEAD, with trap ... EXIT INT TERM on absolute paths.

⭐ The ablation mutates packages/react/src, and the plugin-grid leg imports @object-ui/react by package specifier — the root vitest.config.mts aliases that specifier to ./packages/react/src, so no dist rebuild is interposed. The plugin-grid row going red is itself the proof that the alias is live.

Leg 1 — the substitution. Value chosen because the two implementations DISAGREE about it: an authored view: 'summary_view' with the mode defaulting.

HEAD blob    : 68d8c2061376f3361b37fdf846fae2615014df67
post-mutation: 555d87b4a2bcbeb18ba87c073251ecd3473b8c04   (differs — mutation landed)
MUTATED  exit 1 — Tests 2 failed | 26 passed (28)
  FAIL gridNavigationMembers-8071 ... expected "vi.fn()" to be called with arguments: [ '7', 'view' ]
  FAIL useNavigationOverlay.modeDefault ... expected "vi.fn()" to be called with arguments: [ 'r1', 'view' ]
restored     : 68d8c2061376f3361b37fdf846fae2615014df67   (equals HEAD blob)
git diff HEAD: EMPTY
RESTORED exit 0 — Tests 28 passed (28)

Leg 2 — the published state shape. Re-adding the view member to the returned object:

HEAD blob    : 68d8c2061376f3361b37fdf846fae2615014df67
post-mutation: 87fc43aa850d493909445b7dfa853589e3fb91fb   (differs — mutation landed)
MUTATED  exit 1 — Tests 1 failed | 16 passed (17)
  FAIL ... expected [ 'isOpen', 'selectedRecord', ...(8) ] to not include 'view'
restored     : 68d8c2061376f3361b37fdf846fae2615014df67   ·   git diff HEAD: EMPTY
RESTORED exit 0 — Tests 17 passed (17)

⚠️ One self-correction, since a published reading has to be reproducible: leg 1's observational grep -c "view ?? 'view'" printed 3 where its own label said "expect 2". The third hit is prose in the docblock I added, which quotes the old spelling. The authoritative instrument is the anchored replacement inside the mutation script, which asserts exactly 2 code sites and aborts otherwise; the grep line was a loose observation and its label was wrong, not the mutation.

Verification

All test and build runs serialized behind the seat lock (OS_VERIFY_LOCK_SLOT=3); each reports its own VERDICT command-exit. Read at final HEAD 3f2ed65c5.

run result
baseline, before any edit Test Files 2 passed, Tests 27 passed — the two files were green, so their red is caused by the fix
vitest run packages/react/ plus the plugin-grid pin, the plugin-list navigation-forward test and the packages/types parity test Test Files 91 passed (91), Tests 1114 passed (1114)
type-check for @object-ui/react, @object-ui/app-shell, @object-ui/plugin-grid exit 0, 0 error TS — both legs ran (tsc --noEmit && tsc -p tsconfig.test.json), so the test sources are inside the judged set rather than excluded
check:control-bytes · check:changeset-claims · check:pending-changeset-literals · check:new-line-citations · check:spec-symbols · check:comment-mask-corpus · check:handler-key-reads all exit 0
check:changeset-presence · check:changeset-no-major exit 0
check:governed-queue-guard --test on the five changed paths NOT GOVERNED — 5 path(s) checked against 5 governed surface(s); none matched

⭐ The packages/types parity test is objectui#9667's territory and was run deliberately: it stays green, so the two halves are not entangled and this PR does not pre-empt that one.

check:readme-exports — NOT MEASURED, prerequisite not met. It needs every package's dist on disk and I built only the dependency closure of the three packages I touched. All 87 of its complaint lines read "is not on disk -- run pnpm build first", and 0 of them name any file in this diff. A whole-repo build is CI's run, not a local one.

Lint — a narrowing, measured rather than asserted. eslint --no-inline-config over the four changed source files: exit 0, 0 errors; the 174 warnings are pre-existing no-explicit-any / react-refresh noise in ObjectView.tsx and the grid test, none on a line this diff wrote. The three readings that make the narrowing a measurement:

  1. Population read from eslint's own config via isPathIgnored, not guessed: 5129 lintable tracked files.
  2. Files linted this run, counted from --format json: 4.
  3. Invariance: eslint.config.js has zero hits for projectService, project:, parserOptions or tsconfigRootDir, against a lit control in the same file on rules / languageOptions / ignores. Type-aware linting is off, so this diff cannot move the verdict on any untouched file.

Acceptance notes

⭐ One judgement worth a maintainer's eye, called out rather than buried. Removing view from NavigationOverlayState is a breaking change to a published type. I read it as the mechanical consequence of the retirement rather than a product choice — the member could only ever carry the retired key, so keeping it would publish a field that is permanently undefined, which is the "declared, consumed, and wrong" state the retirement exists to end — and the in-repo census for it is a measured zero. But the alternative (keep it as a deprecated tombstone that is always undefined) is a real option, and it is the seat's to take. Reverting just that half is a two-line change and does not disturb anything else here.

Out of scope, noted, not filed:

  • objectstack#19030 — the producer-side union at objectstack:packages/spec/src/ui/react-blocks.ts:321 declares the navigation-mode union as view-or-edit while this hook passes new_window at two sites. Untouched here and genuinely independent: after this PR the union still lacks new_window. Handed on rather than filed — the triage seat already recorded it against this same file. Successor: that card.

Worth its own card, handed to the seat with dedupe words rather than filed from here:

  • A published doc comment still teaches the retired key. packages/types/src/objectql.ts:2546 tells authors that navigation: { view: 'summary_view' } is legal authored metadata. On the bump this steers an author — very often an AI — to write a key the runtime rejects with the tombstone. Dedupe words: objectql.ts navigation.view doc comment · retired key authored example · spec 17.5.0 tombstone types · ViewNavigationConfig legal metadata.
  • objectui#9667's stated scope is narrower than the census. That card names four declaration sites in one packages/types parity test. My authoring-site probe finds the retired key ALSO authored at packages/types/src/__tests__/gantt-declared-keys.test.ts:117 and :191, packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts:386, and packages/plugin-list/src/__tests__/ListView.ganttNavigationForward-7334.test.tsx:183 and :185 — five more, in three files that card does not name, each typing never on the bump. ⛔ Deliberately not touched: that repo area is the sibling half's, and widening into it is what this dispatch told me to stop and report instead of doing. Dedupe words: navigation.view authoring sites census · retired key never type bump · gantt-declared-keys navigation view · 9667 scope narrower than census.

Two fixtures in THIS diff also author the retired key and are kept on purpose — they are the disagreement inputs the inverted pins rest on, and they will need the same treatment as the five above when the bump lands.

What in the dispatch was wrong

  • The base 02bc27b08 was stale; origin/main was f5e2fcb4a when I fetched.
  • The declared-range summary was incomplete (it omitted ^17.1.0 and ^17.4.0).
  • The dispatch asked me to copy a Clause-②: line from the claim comment into this body. The claim comment on objectui#9874 carries no such line, and no gate in this repository reads one from a PR body — check-changeset-presence.mjs reads no PR body at all, and the marker the changeset workflow hunts for is the first line of a COMMENT. Nothing was copied because there was nothing to copy.

Everything else in the dispatch re-measured as stated — including the 4-call-site control, which is a real lit control and did its job.

🤖 Generated with Claude Code

Generated by Claude Code


Generated by Claude Code

…ng it for the navigation-MODE token (objectui#9874)

`view.list.navigation.view` was removed in `@objectstack/spec` 17.5.0 under
ADR-0049 (enforce-or-remove). `useNavigationOverlay` was its one shipped
consumer: it read `const view = navigation?.view` and spent it at two
`onNavigate` call sites as `view ?? 'view'`, so an authored name landed in the
argument that carries the navigation MODE token and matched no branch in a host
reading it against `edit`/`view`. Both sites now pass the literal `'view'`.

`NavigationOverlayState` loses its `view` member — it could only ever carry the
retired key. Census before removing it: zero readers in this repository.

Two pins that asserted the substitution are inverted rather than deleted, both
keeping their authored `view` fixture because it is the input the old and new
implementations disagree about.

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

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 2 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/7070-no-invented-gantt-date-fields.md

  • names app-shell/src/views/ObjectView.tsx → packages/app-shell/src/views/ObjectView.tsx — edited by this change

    • app-shell/src/views/ObjectView.tsx — the console object page. The inline branch becomes ganttViewOptions, the sibling of calendarViewOptions and timelineViewOptions: the declared block spread whole, title floored at 'name', no date field invented. - plugin-list/src/ListView.tsx — the render branch AND the capability gate. - plugin-view/src/ObjectView.tsx — generateViewSchema, the authored object-view element route, which bypasses ListView entirely.

.changeset/7635-spec-173-comment-repairs.md

  • names scripts/check-installed-spec-pin-claims.mjs → scripts/check-installed-spec-pin-claims.mjs — edited by this change

    Two of the five sites are now watched. They are written as single-line claims about the installed pin, which moves them out of scripts/check-installed-spec-pin-claims.mjs's ledger of known-stale debt and into the population that gate re-derives at every bump; their ledger entries are deleted in the same change, as that gate's both-direction ratchet requires. The remaining three sit on facts no instrument reads, and say so rather than reading as live.

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 00c4df509 (merge-base with origin/main): 5 file(s) changed outside .changeset/, read against 1183 pending declaration(s) that publish a body (1732 pending in total). · run

@os-tesla os-tesla added bug Something isn't working domain:ui objectui ui stream: fix lands on the published library or apps — objectui execution seat priority:p2 labels Sep 18, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3051.5 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-_bo3Q0VW.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.69KB 6.21KB
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) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
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) 26.08KB 7.56KB
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) 545.76KB 130.74KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 216.90KB 60.15KB
fields (index.js) 249.22KB 62.85KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
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) 2.53KB 0.85KB
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.39KB 3.10KB
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) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.73KB 20.08KB
plugin-chatbot (index.js) 195.35KB 46.52KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.63KB 66.00KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.82KB 34.17KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.10KB 14.94KB
plugin-list (index.js) 113.42KB 27.95KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.05KB 21.01KB
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.66KB 3.50KB
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) 104.82KB 34.67KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
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.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
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.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 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

…elease fact, not an installed-pin claim (objectui#9874)

`check-installed-spec-pin-claims` flagged
`gridNavigationMembers-8071.test.tsx:31` for naming `@objectstack/spec` 17.5.0
while the artifact resolves 17.4.0.

The sentence is a "when it changed" claim — 17.5.0 is the release that retired
`view.list.navigation.view` under ADR-0049 — so the gate's other remedy is not
available to it: restamping to the resolved pin would assert that 17.4.0
retired the key, and 17.4.0 is precisely the version where the key still
exists. That is the fresh false premise the gate's own docblock warns
restamping plants.

Recorded as class `historical`, the same class and the same shape as the
existing `offline-nav-performance-spec-parity` entry ("retired that name in
17.0.0-rc.1"). The marker that puts the line in the population is the word
`pinned` in "the row that pinned this", where it means a test row pinning a
behaviour rather than a version pin.

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

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 329 chunks) 3051.5 KB 3104.5 KB
Main entry chunk (gzip) 145.7 KB 350 KB
Entry file index-_bo3Q0VW.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.69KB 6.21KB
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) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
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) 26.08KB 7.56KB
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) 545.76KB 130.74KB
core (index.js) 8.94KB 3.59KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 216.90KB 60.15KB
fields (index.js) 249.22KB 62.85KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.22KB 2.26KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.83KB 10.95KB
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) 2.53KB 0.85KB
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.39KB 3.10KB
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) 14.81KB 3.63KB
plugin-calendar (index.js) 49.92KB 14.22KB
plugin-charts (index.js) 71.73KB 20.08KB
plugin-chatbot (index.js) 195.35KB 46.52KB
plugin-dashboard (index.js) 132.96KB 35.17KB
plugin-designer (index.js) 215.94KB 44.33KB
plugin-detail (index.js) 253.63KB 66.00KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.82KB 34.17KB
plugin-gantt (index.js) 167.62KB 41.26KB
plugin-grid (index.js) 213.44KB 58.21KB
plugin-kanban (index.js) 48.10KB 14.94KB
plugin-list (index.js) 113.42KB 27.95KB
plugin-map (index.js) 21.48KB 6.99KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.41KB 11.93KB
plugin-timeline (index.js) 30.07KB 8.74KB
plugin-tree (index.js) 10.58KB 3.72KB
plugin-view (index.js) 85.05KB 21.01KB
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.66KB 3.50KB
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) 104.82KB 34.67KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
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.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 4.11KB 2.06KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
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.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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) 14.04KB 5.36KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 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

@os-tesla
os-tesla marked this pull request as ready for review September 18, 2026 19:34
@os-tesla
os-tesla added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit 0c789a4 Sep 18, 2026
38 checks passed
@os-tesla
os-tesla deleted the claude/issue-9874-navigation-view-retired-consumer branch September 18, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working domain:ui objectui ui stream: fix lands on the published library or apps — objectui execution seat package: app-shell package: react plugin priority:p2 tests

Projects

None yet

2 participants