Found while clearing content/docs/guide/user-state-persistence.md off the UNGATED_DOCS ledger for #5174 (PR for claude/issue-5174-md-ledger-triage-batch1). Filed unassigned. The ts block on that page is fixed there — it is a snippet-compile defect, which is that card. The prose and the yaml block are not, and no gate reads them.
What
createObjectStackUserStateAdapter's real options (packages/data-objectstack/dist/index.d.ts, interface ObjectStackUserStateAdapterOptions):
dataSource: DataSource<any>;
userId: string;/** Storage key. Should be a dotted, namespaced string … Examples: * `ui.favorites`, `ui.recent`, `ui.grid.account.state`. */
key: string;/** Override the storage object name. Defaults to `"sys_user_preference"`. */
resource?: string;
onError?: (where: 'load'|'save',error: unknown)=>void;
And packages/data-objectstack/src/userState.ts:6-10 states the choice outright — the parallel table was considered and rejected:
Using the existing sys_user_preference table (rather than a parallel user_app_state table) keeps things consistent with the platform's …
The guide documents the rejected design. Still on the page after the snippet fix:
- :93 — "The official adapter stores one row per (user_id, kind) pair holding the full list as a JSON blob."
- :95-109 — a ```yaml block declaring an object with a
kind field and `unique: [user_id, kind]`. - :116 —
find('user_app_state', { filter: { user_id, kind }, limit: 1 }). - :188, :205 — "One JSON blob per (user, kind)", "
kind: 'favorites'".
packages/data-objectstack/src/userState.test.ts pins the real calls against 'sys_user_preference' at :41, :143, :165, :216, :240, :266, :293.
Not the whole page is wrong
kind is a real word elsewhere on the page: useUserStateAdapter(kind) (:178) is a genuine @object-ui/app-shell API taking a slot kind. The drift is specifically the storage model — the object name, the field name, and the uniqueness constraint. Whoever takes this should re-read the adapter rather than sed kind → key.
What was already fixed, so this issue is not the whole thing
The page's one typescript block used kind: 'favorites' / kind: 'recent' as adapter options. That is a compile error against the real ObjectStackUserStateAdapterOptions (TS2353: 'kind' does not exist in type …) and it is corrected to key: 'ui.favorites' / key: 'ui.recent' in the #5174 batch, along with the missing useEffect import and the untyped dataSource parameter. The page now compiles and left the ledger. The prose did not move, so the page is internally inconsistent until this is done — an improvement over being uniformly wrong, but worth closing out.
Why not folded into #5174
Different defect class. #5174 is snippet coverage: check-doc-snippet-types.mjs reads ts / tsx fences only, and a ```yaml block plus surrounding prose is invisible to it and to check-doc-component-types. Fixing it needs a reading of the adapter's storage contract, not a snippet triage — and it would have made the batch diff unreviewable.
Reachability
Documentation only, but of the load-bearing kind: a reader following this page would model their backend object on user_app_state with a kind column and find the shipped adapter writing to sys_user_preference with a key.
Related: #5174 (the ledger batch that surfaced it), #5160.
Found while clearing
content/docs/guide/user-state-persistence.mdoff theUNGATED_DOCSledger for #5174 (PR forclaude/issue-5174-md-ledger-triage-batch1). Filed unassigned. The ts block on that page is fixed there — it is a snippet-compile defect, which is that card. The prose and theyamlblock are not, and no gate reads them.What
createObjectStackUserStateAdapter's real options (packages/data-objectstack/dist/index.d.ts,interface ObjectStackUserStateAdapterOptions):And
packages/data-objectstack/src/userState.ts:6-10states the choice outright — the parallel table was considered and rejected:The guide documents the rejected design. Still on the page after the snippet fix:
kindfield and `unique: [user_id, kind]`.find('user_app_state', { filter: { user_id, kind }, limit: 1 }).kind: 'favorites'".packages/data-objectstack/src/userState.test.tspins the real calls against'sys_user_preference'at:41,:143,:165,:216,:240,:266,:293.Not the whole page is wrong
kindis a real word elsewhere on the page:useUserStateAdapter(kind)(:178) is a genuine@object-ui/app-shellAPI taking a slot kind. The drift is specifically the storage model — the object name, the field name, and the uniqueness constraint. Whoever takes this should re-read the adapter rather than sedkind→key.What was already fixed, so this issue is not the whole thing
The page's one
typescriptblock usedkind: 'favorites'/kind: 'recent'as adapter options. That is a compile error against the realObjectStackUserStateAdapterOptions(TS2353: 'kind' does not exist in type …) and it is corrected tokey: 'ui.favorites'/key: 'ui.recent'in the #5174 batch, along with the missinguseEffectimport and the untypeddataSourceparameter. The page now compiles and left the ledger. The prose did not move, so the page is internally inconsistent until this is done — an improvement over being uniformly wrong, but worth closing out.Why not folded into #5174
Different defect class. #5174 is snippet coverage:
check-doc-snippet-types.mjsreadsts /tsx fences only, and a ```yaml block plus surrounding prose is invisible to it and tocheck-doc-component-types. Fixing it needs a reading of the adapter's storage contract, not a snippet triage — and it would have made the batch diff unreviewable.Reachability
Documentation only, but of the load-bearing kind: a reader following this page would model their backend object on
user_app_statewith akindcolumn and find the shipped adapter writing tosys_user_preferencewith akey.Related: #5174 (the ledger batch that surfaced it), #5160.