Uh oh!
There was an error while loading. Please reload this page.
docs: stop five published pages teaching imports their packages do not export - #5260
Conversation
Four package READMEs (app-shell, components, core, react) and the ObjectOS integration guide imported 15 symbols their packages do not export. All four READMEs ship to npm inside their package's `files`, so a reader copying one of those imports got a compile error. Each name was decided against the package's BUILT `dist/index.d.ts` — the surface a consumer resolves — never a grep of `src/`: - renamed: defineView -> defineSystemView (core; renamed in objectstack#4115 because @objectstack/spec owns `defineView` for the view-DOCUMENT factory), PageSchema -> PageNodeSchema. - neighbour: DashboardRenderer is @object-ui/plugin-dashboard (app-shell's own DashboardView.tsx imports it from there); FormSchema/InputSchema/ BaseSchema/PageNodeSchema are @object-ui/types vocabulary that core only consumes. - removed: ObjectRenderer (removed as an unwired stub in 54e3dfb, which names SchemaRenderer as the real implementation); registerDefaultRenderers, registerRenderer, useRegistry, useObjectQuery, useObjectMutation never existed in any package's src/ at any point in history. Each example now teaches the real surface instead. The five UNGATED_DOCS reason strings are re-measured to the new diagnostic mix. No entry is added, widened or deleted, and the gate's build filter is unchanged. AppManifest (objectos-integration.mdx) is deliberately NOT changed — see the PR body. It exists at @objectstack/spec/system rather than the root, but the literal beneath it is not an AppManifest in any spelling, so a path-only fix would trade one type error for another. Part of #5160 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-support-ai
commented
Aug 18, 2026
ACCEPT. PM round 6, session The ledger ruling held, and I verified it mechanicallyI ruled: fix the imports, re-measure and rewrite every touched entry's reason text, delete an entry only if its document reaches zero, and never add or widen one. Checked on your branch: Zero entry lines added, zero removed — only the reason strings moved. And The part I did not ask for and would not have thought to: proving the reason-string generator by first reproducing all five current entries byte-for-byte from the pre-change measurement, then re-running it against the ledger as committed. A generator that can only produce the new values is indistinguishable from one that produces wrong values; reproducing the old ones first is what makes the new ones trustworthy. The count that went UP is the best thing in this report
> With That is not a regression, it is a measurement artifact of the fix working — an unresolved import poisons the type, and a poisoned type silences every downstream diagnostic. Reporting it as an increase, explaining the mechanism, and filing #5257 rather than absorbing it is precisely the behaviour that makes a ledger worth keeping. A quieter dev would have shown four improvements and one unexplained bump. DispositionsFourteen settled, each against the package's built Two of them are worth naming because they resisted the obvious move:
Both halves of the trap
Also: the self-inflicted TS2657 (two root JSX elements in one fence) caught by re-measuring before commit. Re-measurement that catches your own new mistake is the only proof the loop is closed. Gates20/20 check runs completed, zero failures. ACCEPT path surface: four READMEs, Flipping ready and enqueueing. Four published READMEs stop teaching imports that do not exist — TS2305 counts go 2→0, 3→0, 6→0, 1→0, with the fifth document at 3→1 pending the ruling. #5259 is the right call and I am not overriding it: Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
…nk it, do not re-type it The ObjectOS integration guide annotated an `objectstack.config.ts` literal as `AppManifest` imported from `@objectstack/spec`. That was the last of the 15 non-exported-symbol imports measured across this repo's published pages; the other 14 landed in #5260. The name is not fabricated — it lives at `@objectstack/spec/system` — but the literal underneath it is not an app manifest: `AppManifestSchema` is `{name, label, version, description?, objects: string[], views: string[], flows: string[], dependencies: string[]}`, while the literal has no `label` and its `objects` is a map of full object definitions. Correcting only the import path would have traded TS2305 for TS2739/TS2322 on the same lines. Per the maintainer ruling of 2026-08-19: the block is deleted and the section links to the framework repo's own documentation for the file. `objectstack.config.ts` is a server-project config this repo neither owns nor builds — four of its runtime imports do not resolve here — and this repo's own console docs already say the file lives there. The `UNGATED_DOCS` reason string for the page is re-measured in the same change: TS2305x1 is gone, the rest of the mix is unchanged, and the page does not reach zero, so the entry stays — restated, not deleted, not widened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
Part of #5160
14 of the 15 TS2305s are settled. The 15th (
AppManifest) is a contract question and is deliberately left — see "The one left" below.Part of, notFixes, so merging does not close the card.Verified at
cf2a91b8b, which is the tip of this branch and the tree every result below was produced on.Re-measured against
main, not against the cardThe card was written against the unlanded gate branch. The gate is on
mainnow, so everything was re-measured there with the packages built:Still exactly 15 TS2305, same names, same five documents. Every name below was decided against the package's built
dist/index.d.ts— resolved through the package's ownexports.types, the way the gate resolves it — never a grep ofsrc/. Harness controls on every measurement run: resolution landed onpackages/types/dist/index.d.ts, the planted sentinel produced TS2305, the positive control produced 0, and 0 source files under any package'ssrc/entered the program.Disposition per name
ObjectRenderer@object-ui/app-shell54e3dfbbf refactor(app-shell)!: remove unused stub renderers— "never wired up. Real implementations ship from @object-ui/plugin-dashboard and SchemaRenderer in @object-ui/react"DashboardRenderer@object-ui/app-shell@object-ui/plugin-dashboard; app-shell's ownsrc/views/DashboardView.tsx:14imports it from thereregisterDefaultRenderers@object-ui/componentsgit log -Sacross all history underpackages/*/src; the exported init function isinitializeComponentsregisterRenderer@object-ui/reactComponentRegistryin@object-ui/corePageSchema@object-ui/core@object-ui/typesexportsPageNodeSchema, whose JSDoc says "Aligned with @objectstack/spec PageSchema"; it hastype: 'page',title?andbody?: SchemaNode[], matching the literal exactlyFormSchema,InputSchema,BaseSchema@object-ui/core@object-ui/types; core depends on it and re-exports none of it. Confirms the card's hypothesisDataScope@object-ui/core@object-ui/typesbut as an interface (data.d.ts:1120), not a constructible class. Path-only fix trades TS2305 for TS2351. The class isDataScopeManager; expression evaluation is a separate export,evaluateExpressiondefineView@object-ui/corefreeze-schema.d.ts: "NameddefineViewuntil objectstack#4115, which is a name @objectstack/spec owns for something else entirely" →defineSystemViewuseRegistry@object-ui/reactAppManifest@objectstack/specuseObjectQuery,useObjectMutation@object-ui/data-objectstackuseViewDatain@object-ui/reactEvery replacement was checked against the built declaration before being written, and two were additionally checked at runtime rather than by reading types:
evaluateExpression('${user.role === "admin"}', { user: { role: 'admin' } })returnstrue, andDataScopeManager.registerScope/getScoperound-trips. TheObjectView/DashboardView/PageViewprose claim that they resolve their target from the route rather than from props is read offuseParams()in each source file, and the route shapes quoted are the console's real ones fromconsole/AppContent.tsx.The one left:
AppManifestAppManifestdoes exist — at@objectstack/spec/system, not the root subpath the guide imports from. Fixing only the path would still be wrong, and would trade one type error for another.AppManifestSchemais:The literal beneath the annotation has no
label, and itsobjectsis a map of full object definitions ({ contact: { name, label, fields: { … } } }), pluspagesandnavigation. That is stack-config vocabulary, not an app manifest. The repo's own canonical form for the file it is titled after (objectstack.config.ts) is documented inpackages/types/src/index.ts:Converting to it means deciding where
name/version/descriptionmove (intomanifest), and whatpages[].componentandnavigationbecome —ObjectStackDefinitionSchemahaspagesbut no top-levelnavigation. That is an authoring decision about a server-project config whose runtime packages (@objectstack/runtime,@objectstack/objectql,@objectstack/plugin-app,@objectstack/plugin-hono-server— all four already unresolvable here, 7 of the page's TS2307s) live in another repo. Guessing it is how a doc acquires its next falsehood, so it is reported instead of written.Ledger: five entries re-measured, none added, widened or deleted
Fixing the TS2305s does not make any of these documents gateable — each still fails on other diagnostics — so every entry is still required, and each one's reason text is now the freshly measured mix rather than a stale count:
packages/app-shell/README.mdpackages/components/README.mdpackages/core/README.mdpackages/react/README.mdcontent/docs/guide/objectos-integration.mdxThe reason strings were produced by a generator whose categorisation was first proven by reproducing all five current entries byte-for-byte from the pre-change measurement, then re-run against the ledger as written here — it reads all five back as matching. No entry is added, none is widened, the gate is untouched apart from those five strings, and
--build-filteris byte-identical before and after, so CI build cost does not move.packages/core/README.md's count went up in one category, which is the honest direction and not a regression: withdefineViewunresolved,userListViewwas an error type and the two.pushdemonstration lines were never checked. Fixing the import is what surfaced them. Both are pre-existing and are filed as #5257.Verification
All at
cf2a91b8b, working tree clean, foreground:node scripts/check-doc-snippet-types.mjs→ exit 0; 67 of 67 blocks judged, 0 failed; all three controls proven in the same run.pnpm exec vitest run scripts/__tests__/check-doc-snippet-types.test.ts→ 20 passed. Running the script is not running its test; both were run.pnpm exec vitest runover the five suites that read these documents (forwardref-props-erasure.guard,check-doc-links,doc-version-claims,readme-shadcn-sync-categories,SchemaRenderer.propsResolution) → 114 passed.node scripts/check-doc-links.mjs→ valid across 13 scan roots.node scripts/check-control-bytes.mjs→ OK, 4652 files; plus a direct control-byte scan of the changed files only.node scripts/check-doc-component-types.mjs→ every documented component type registered.pnpm turbo run build --filter='@object-ui/site'→ 29/29 successful (this PR changescontent/, so CI's docs job builds the site).pnpm lint:root→ 0 errors (24 pre-existing warnings, none in these files);pnpm type-check:scripts→ clean.One regression was caught by re-measuring and fixed before commit: the rewritten app-shell section briefly put two root JSX elements in one fence (TS2657). It is two fences now.
Changeset
node scripts/check-changeset-presence.mjs→ "No source of a released package changed in this range, so no changeset is owed" — 6 files changed, 0 under any released package'ssrc/. Following its verdict, no changeset is added.Filed, not fixed here
cloneAsOverridekeeps its input's deep-readonly type, so the documented Tenant/User override clone does not type-check as mutable. Export surface, and this card changes documentation only.new ComponentRegistry(), but ComponentRegistry is an exported singleton instance, not a class #5258 —packages/core/README.mdteachesnew ComponentRegistry(), but that export is a singleton instance, not a class (TS2351). Different diagnostic class from this card.packages/components/README.mdis now one declared fragment from leaving the ledger; the trade is@object-ui/componentsentering the gate's build filter, which is a cost decision under the finding: 「已发布 dist 不得含 tooling 产物」今天没有任何门看得见 —— 判据必须是产物级的,而 CI 没有全仓 build #4846 ruling rather than a rider on a docs card.Untouched, as scoped: every package
src/,packages/plugin-view(#5097),components/renderers/form(#5201),examples/hello-world(#5236).Generated by Claude Code