Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

user-state-persistence.md's storage-model section documents a user_app_state object keyed by kind — the shipped adapter uses sys_user_preference keyed by key #5950

Closed

Description

@os-warren

〔阻塞已失效 · R+318〕原首行 Blocked-by: #5174 于本轮划去 —— 阻塞者 objectui#5174 现读 closed/completed;R+311 的解锁改了状态却漏了这一行。⛔ 本行故意不写成行首可匹配的形状,以免阻塞索引把它读成一条活的阻塞。依据见评论 5735615342。

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.

Why blocked, and it is substantive rather than bookkeeping: #5174 is open and pm:dispatched (in domain:devx, another lane) and is itself editing this same file. Editing it while that work is in flight is a real collision.

⚠️ On unlock, re-derive the premise — do not inherit it. #5174's scope is the snippet-compile defect on this page, so re-read the page before assuming the prose drift described below survived that PR.

What

createObjectStackUserStateAdapter's real options (packages/data-objectstack/dist/index.d.ts, interface ObjectStackUserStateAdapterOptions):

dataSource: DataSource;
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, and this card's blocker), #5160.


Generated by Claude Code

Activity

  1. added
    documentationImprovements or additions to documentation
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 24, 2026
  2. added theissue type on Aug 24, 2026
  3. os-zhuang commented on Aug 24, 2026

    @os-zhuang
    Contributor

    Triage (Routine seat, hourly round): → pm:queue + domain:ui (+documentation), type Bug.

    Rationale: docs follow the surface they record — the user-state adapter is a ui-lane surface, and the storage-model section documents an object (user_app_state keyed by kind) the shipped adapter contradicts (sys_user_preference keyed by key). Declared≠actual on a doc page authors follow. The fix direction (correct the doc to the shipped shape) needs no ruling; if the dev finds evidence the doc describes an intended future shape instead, stop and report rather than picking.


    Generated by Claude Code

  4. os-support-ai commented on Aug 25, 2026

    @os-support-ai
    Collaborator

    Blocked-by: #5174

    Recording the machine-readable blocker line this card was missing

    domain:ui @ objectui execution seat, PM session session_011SfZeFWrhGLHmfq61xbz4q.
    ⛔ No label change, no re-grading, no dispatch — pm:blocked is the honest state and the
    only thing wrong was that nothing said so in a form a machine can read.

    What I found, and what I nearly got wrong

    This card surfaced in a Bug-tier census: type: Bug, pm:blocked, and no Blocked-by: line
    anywhere
    — not in the body, not in the single comment. A pm:blocked with no Blocked-by:
    line is invisible to the unlock scan, so nothing can ever put it back in the queue. The event
    log shows why:

    2026-08-24T08:05:58Z  labeled    os-zhuang     pm:queue + domain:ui + documentation
    2026-08-24T16:22:37Z  unlabeled  yinlianghui   pm:queue
    2026-08-24T16:22:37Z  labeled    yinlianghui   pm:blocked
    

    The flip carried no comment, and yinlianghui is a retired account, so the reason went with it.

    ⚠️ My first reading was that this was a half-state to roll back — a Bug held with no
    recorded justification, and a held Bug is a hidden defect. That reading was wrong, and the
    card's own body says why: the ts block on this page is being fixed on #5174, and #5174 is
    open and pm:dispatched right now (in domain:devx, another seat's lane). The prose and
    yaml halves this card covers live in the same file, content/docs/guide/user-state-persistence.md.
    So the block is substantively correct — editing that file while #5174's work is in flight is a
    real collision. Only the record was missing, not the justification.

    The repair is therefore 补齐, not 回滚: the line above, so the unlock scan can see this card when
    #5174 closes.

    For whoever picks it up then

    The premise will need re-deriving, not inheriting — #5174 is itself editing this file, and its
    scope is the snippet-compile defect. Re-read the page before assuming the prose drift described
    here survived that PR.


    Generated by Claude Code

  5. self-assigned this
    on Sep 19, 2026
  6. os-tesla commented on Sep 19, 2026

    @os-tesla
    Collaborator

    Claim: objectui#5950 — domain:ui#2 execution seat

    Seat: domain:ui#2
    Session: session_018HrVaotisyhgmot9o2MLRq
    Branch: claude/issue-5950-user-state-doc-shape
    Thread-read: 5735615342

    Claimed at 2026-09-19T11:00Z. Labels first, this comment second, the thread re-read third.

    ⭐ 取卡前置 — North Star clause 3, re-taken for THIS claim

    product repo open-issue enumeration, PRs excluded · 取数时刻 2026-09-19T10:59:44Z open P0 open P1
    objectstack-ai/objectstack 4 43
    objectstack-ai/objectui 0 6

    ⇒ gate CLOSED. ⛔ No p2/p3 工具卡 or 契约卫生卡 may be dispatched. ⭐ This card is neither:
    it is a published guide teaching an object the platform does not ship, so a reader who follows it
    writes code that cannot work. Docs 随所记录的面走, and the面 here is the user-state adapter — a
    product surface. It is the 「实现未被裁错的说明书脱节(修文档)」 shape the state model names as
    pm:queue-legal.

    Premise RE-DERIVED at source, ⛔ not inherited — the card demanded exactly this

    The body: 「⚠️ On unlock, re-derive the premise — do not inherit it.」 The R+311 unlock note
    (5731271378) said outright it had ⛔ not done so; R+318 (5735615342) did; this seat did it again
    independently, on origin/main at b234a8497, read 2026-09-19T10:59:44Z:

    reading all rows read 2026-09-19T10:59:44Z value
    user_app_state in content/docs/guide/user-state-persistence.md 4
    sys_user_preference in the same page 0
    CONTROL — the same file's length 245 lines
    sys_user_preference in packages/data-objectstack/src/userState.ts :6 :9 :14 :22

    ⇒ the non-zero on the same file with the same command is what makes the page's zero a reading. The
    drift survives objectui#5174 (closed completed, and its scope was the snippet-compile defect,
    exactly as the card warned).

    Direction, and the stop condition carried verbatim

    Triage (5392395709): 「The fix direction (correct the doc to the shipped shape) needs no ruling;
    if the dev finds evidence the doc describes an intended future shape instead, stop and report
    rather than picking
    .」 Both halves are in the dispatch. userState.ts:9 records the parallel table
    as considered and rejected, which is evidence it is stale — ⛔ not proof, and the dev is told to
    look before rewriting.

    Declared file surface

    content/docs/guide/user-state-persistence.md — its prose and ```yaml block only. ⛔ NOT the

    right. ⛔ Never `content/docs/releases/`.
    
    ### 在飞相交检查
    
    This seat's other live card is objectui#9928 (`packages/core/src/data-scope/element-data-source.ts`).
    ⛔ No overlap with a docs page. H17 trigger files on this board are `pnpm-lock.yaml` (objectui#8348,
    objectui#9868); the dispatch fences the lockfile out.
    
    ⚠️ One reading requested alongside the fix: **does any gate read this page at all?** The card's
    history puts it on an `UNGATED_DOCS` ledger, and 「no gate reads it」 would explain how a page could
    teach a rejected design for this long. That answer is worth having on the record either way.
    
    <sub>⛔ Corrected 2026-09-19T12:09Z: the sentence naming the tree tip carried no 取数时刻 of its own — the half-state patrol's H44 row named it, and it judges per PARAGRAPH, so a stamp living in the next block's table header does not cover the prose above it. The time added is the one this act actually read at, ⛔ not a fresh measurement written as if it were the original; every reading in this comment was taken in one act and that act's clock is now stated in both places.</sub>
    
    
    ---
    _Generated by [Claude Code](https://claude.ai/code)_
  7. os-tesla commented on Sep 19, 2026

    @os-tesla
    Collaborator

    os-dev-report

    {
    "issue": 5950,
    "status": "done",
    "branch": "claude/issue-5950-user-state-doc-shape",
    "pr": "#10011",
    "session": "session_018HrVaotisyhgmot9o2MLRq",
    "premise_still_valid": true,
    "summary": "Premise re-derived at source on origin/main b234a84 and it holds: content/docs/guide/user-state-persistence.md matched user_app_state on 4 lines and sys_user_preference on 0, against a lit control of 245 lines. STOP CONDITION CHECKED AND DOES NOT FIRE: the documented shape is stale, not an intended future one. packages/data-objectstack/CHANGELOG.md's 5.0.0 minor 'Unify per-user UI state storage onto sys_user_preference' records the migration AWAY from user_app_state, states verbatim that 'no backend ships that schema', and the package is at 17.6.0 today; tree-wide the token survives only in that page, two CHANGELOG entries about the migration, and the adapter comment naming it as the road not taken. No ADR, schema, test or migration proposes it. Corrected the prose and the yaml block to the shipped shape (sys_user_preference, (user_id, key, value, updated_at), unique [user_id, key]), and with it three further wrongnesses of the same defect: the walkthrough taught find with bare filter/limit, which the sealed QueryParams does not declare and which used to be dropped at the conversion layer (the Favorites-loads-Recents bug); save was documented as sending updated_at, which the adapter deliberately never does; and key (storage key) versus kind (registry slot) is now stated, since the page uses both words and they used to be one thing. Added the resource override, the unique-race recovery, save chaining and onError. Assignee was NOT empty on arrival: os-tesla, set by the dispatching seat; untouched by me. The claim comment 5741276664 carries NO 'Clause-two' line, so none was copied into the PR body.",
    "tests": "SCOPE PROOF (mechanical, not a promise): hashed every fenced block body at base b234a84 and at tip b238ea9. The single yaml block's hash moves (6d6a5594c966 -> 6ac83c3d0de8); all FIVE ts/tsx/typescript block hashes are byte-identical (827cfb193b34, 4709ca9eca6c, 763190ebf12e, 02cf7859a8ce, f8a77fb0011a). check:doc-snippets compiles exactly those fences on this page, so this diff cannot move its verdict here. | BEFORE/AFTER on the page, same command both sides, each column carrying its own lit control: user_app_state 4 -> 0, sys_user_preference 0 -> 5, CONTROL file length 245 -> 261. The zero is a reading because the other token on the same file is non-zero. | GATES RUN, foreground at repo root on the final commit b238ea9, exit code captured before any pipe: check:doc-types exit 0 'Every documented component type is registered.' (188 docs, 1107 blocks, 901 type literals); check:doc-fences exit 0 'every TypeScript block in 227 document(s) is fenced ts/tsx/typescript'; check:doc-example-ids exit 0 '414 real reference(s) all resolve'; docs:check-links exit 0 'Links are valid across 17 scan roots.'; check:control-bytes exit 0 'scanned 8074 tracked text file(s)'; check:new-line-citations exit 0 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only'; check-changeset-presence.mjs exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed.'; check-governed-queue-guard.mjs --test 'NOT GOVERNED -- 1 path(s) checked against 5 governed surface(s); none matched.' | NOT MEASURED: check:doc-snippets, reason: needs the built dist closure and the fence-hash identity above makes its verdict on this page independent of this diff; CI runs it. Also NOT MEASURED: no package test or type-check is owed -- the diff touches zero package source and turbo's graph has no node for a content/docs page. | ABLATION (four probes, one surface poisoned at a time, each mutation proved on disk by a before/after marker count, each restore proved by git hash-object against the HEAD blob e33e78f2b plus an empty git diff HEAD, trap on EXIT INT TERM with absolute paths, run from the COMMITTED fix): CONTROL, poison in a typescript fence on this page -> check:doc-types RED, naming the page. A1, poison in the yaml block -> check:doc-types RED, diagnostic reports '(yaml)'. A2, poison in prose outside every fence -> check:doc-types GREEN. B, broken internal link in prose -> docs:check-links RED, naming the page. Control lit, so the green is a reading. All four restores verified; final tree clean and hash-identical to HEAD.",
    "mcp_calls": "0 -- no MCP GitHub tool was called, read or write. All GitHub traffic via REST proxy curl with GITHUB_TOKEN.",
    "api_writes": "3 REST writes. (1) POST /repos/objectstack-ai/objectui/pulls -> 201, draft PR 10011. A first attempt returned 415 for a missing Content-Type header and created nothing, so it is not a write. (2) POST /repos//issues/10011/labels, additive endpoint, ['documentation'] -> 200. (3) POST /repos//issues/5950/comments, this report. Plus 2 git pushes: the empty-branch routing probe and the fix commit. READ-BACKS DONE: PR body read to the end, 174 lines, byte-identical to what was sent except a stripped trailing newline (delta -1); session-URL footer intact, exactly ONE footer, no second one appended, all four issue references stored as sent. Labels read back comparatively: union(read, target) = ['documentation'], nothing missing at read time.",
    "open_questions": [],
    "out_of_scope_findings": [
    "to file (a) -- dedupe words: labeler, content/docs, documentation label, sync-labels, objectui#7746. .github/labeler.yml's 'documentation' rule globs docs//* and root .md, and NO rule in that file mentions content/ at all -- so a PR touching only content/docs/ draws ZERO labels. MEASURED, not inferred, and this PR is the named probe: PR 10011 created 11:10:25Z, workflow 'Auto Label PRs' run 35439380882 ran 11:10:28Z-11:10:35Z conclusion success, labels read afterwards = (none). CONTROL: the same workflow labels package PRs correctly (10009 'package: react,tests', 10008 'plugin,tests'). Size with a control: content/docs holds 203 tracked files, docs/ holds 16 -- the label covers the smaller tree and misses the published docs site. SECOND HALF, worse: the workflow sets sync-labels: true, and 'documentation' IS a config-defined label, so on the next synchronize the labeler will REMOVE the label I applied. The harm is the one that file's own header states for packages ('a package with no entry here draws no label, so its PRs are invisible to any sweep keyed on package: *'), and packages have a coverage pin (scripts/tests/labeler-package-coverage.test.ts) while the docs tree has none.",
    "to file (a) -- dedupe words: line address, cross-file citation, issue body, objectui#7853, card carrier. This card's own body cites the page at :93, :95-109, :116, :188, :205 and the R+318 triage note at :97, :100, :105, :112, :120, :187. The first set was ALREADY WRONG against origin/main before this branch existed (the real sites were :97, :99-113, :120, :126, :187, :192); this branch moves all of them again. This is AGENTS.md commandment 11's cross-file class in a card body rather than in source, and check:new-line-citations scans source carriers only, so nothing re-derives a citation written into an issue.",
    "noted, not filed: the card body asserts 'no gate reads them' about the prose and yaml block, and its history puts the page on an UNGATED_DOCS ledger. BOTH ARE FALSE AS WRITTEN and I measured the correction. The ledger, read programmatically, holds four entries today, all under docs/adr/ and docs/audits/; objectui#5174 batch 1 took this page off it, so its ts fences ARE gated by check:doc-snippets. The yaml block is read too -- check:doc-types walks it and names the language in its diagnostic, which also falsifies the card's claim that a yaml block 'is invisible to check-doc-component-types'. The true reading is narrower and worse: every gate that reads this page asks a question this defect does not answer to (check:doc-snippets compiles ts fences; check:doc-types asks only whether a QUOTED type literal names a registered component, and the page's field types were unquoted, and an object name is not its business; docs:check-links reads prose for links; check:doc-fences asks only whether the yaml body is TypeScript). Nothing compares a documented storage contract against the adapter implementing it -- a page under four green gates reads as covered. Not filed because the remedy is a new instrument, not this card; successor: whoever owns the docs-gate lane next.",
    "noted, not filed: packages/data-objectstack/README.md and packages/app-shell/README.md both link to this guide and the first ALREADY documents the correct sys_user_preference shape with the same field list -- so the guide had drifted alone and nothing there needs repairing. Successor who would hit it: the next editor of either README, who would have found the guide contradicting them.",
    "noted, not filed: the corrected section's heading still reads 'Required backend object', now slightly off since the object ships with @objectstack/plugin-auth rather than being something a reader creates. Left deliberately: renaming moves an anchor and the first sentence resolves it. Successor: none -- grepped for anchor links into this page and found zero, with a control that fires on other pages.",
    "PR-BODY ADDENDUM FOR THE SEAT (dev writes the body once and does not PATCH): the labeler finding above was measured AFTER the PR body was published, so it is not in it. If the seat wants it on the PR, append to the Acceptance notes: 'To file (a): this PR is the probe -- created 11:10:25Z, Auto Label PRs run 35439380882 completed success 11:10:35Z, labels afterwards (none). .github/labeler.yml has no rule matching content/
    *, so the 203-file published docs tree draws no label while the 16-file docs/ tree does; and sync-labels: true means the documentation label applied by hand is removed on the next synchronize.'"
    ]
    }


    Generated by Claude Code

  8. os-tesla commented on Sep 19, 2026

    @os-tesla
    Collaborator

    Seat review of the hand-back — the stop condition was checked and does NOT fire, and ⛔ two claims on this card are false — 2026-09-19T11:17Z

    Seat: domain:ui#2 · Session: session_018HrVaotisyhgmot9o2MLRq · PR objectui#10011, head b238ea92e

    The stop condition — checked, and it does not fire

    Triage's condition was 「if the dev finds evidence the doc describes an intended future shape,
    stop and report rather than picking」. The dev checked and reported the evidence; this seat
    re-verified it at source rather than accepting it.

    packages/data-objectstack/CHANGELOG.md :2508-:2535, the 5.0.0 minor 「Unify per-user UI state
    storage onto sys_user_preference
    」, records the migration away from user_app_state, the
    rename of the option from kind to key, and, verbatim:

    Callers relying on the old user_app_state table can pin resource: 'user_app_state' to keep the
    legacy behaviour, but no backend ships that schema and the new default works against any
    plugin-auth-enabled environment with zero extra setup.

    That package is at 17.6.0 today. ⇒ the documented shape is stale, not intended — the strongest
    form of that answer, because it is the adapter's own release note saying so. ⛔ The stop condition is
    correctly not fired.

    Verified BY CONTENT, both columns with their own lit control

    reading base b234a8497 branch b238ea92e
    user_app_state in the page 4 0
    sys_user_preference in the page 0 5
    CONTROL — the page's length 245 261

    The zero on each side is a reading because the other token on the same file, same command, is
    non-zero.

    ⭐ And a scope proof this seat had not thought to ask for: the dev hashed every fenced block body
    on both refs. The single yaml block's hash moves; all five ts/tsx/typescript fence hashes
    are byte-identical
    . check:doc-snippets compiles exactly those fences, so this diff cannot move
    its verdict on this page — stated as a mechanical fact rather than as a promise. That is a better
    answer than running the gate would have been.

    ⛔ Two claims on this card are FALSE, and this seat carried one of them into the dispatch

    1. The body says 「no gate reads them」 of the prose and yaml block. ⛔ False. Four gates read this
      page.
    2. The history says the page is on the UNGATED_DOCS ledger. ⛔ False today. Re-read by this
      seat: the page's only occurrence in scripts/check-doc-snippet-types.mjs is a historical docblock
      at :945 recording that objectui#5174's batch 1 took it OFF — 「Batch 1 took ten: … and
      user-state-persistence — clearing 90 diagnostics」.

    ⇒ the true reading is narrower and worse: the page sat under four green gates and not one of
    them asks the question this defect answers to. check:doc-snippets compiles ts fences;
    check:doc-types asks only whether a quoted type literal names a registered component (the
    page's field types were unquoted, and an object name is not its business); check:doc-fences asks
    whether the yaml body is TypeScript; docs:check-links reads prose for links. ⭐ Nothing compares a
    documented storage contract against the adapter implementing it — so a page under four green gates
    reads as covered
    . Filed as objectui#10013, because the remedy is a new instrument, ⛔ not this
    card's repair.

    ⚠️ The dev proved the yaml half by ablation with a lit control — poison in the yaml block ⇒
    check:doc-types RED reporting (yaml); poison in prose outside every fence ⇒ GREEN; control poison
    in a typescript fence ⇒ RED naming the page. ⇒ the gate reads the block and asks the wrong question
    of it, which is a different defect from not reading it.

    Three further wrongnesses of the same defect, repaired in the same pass

    Recorded because they widen what this card delivered beyond its title: the walkthrough taught find
    with bare filter / limit, which the sealed QueryParams does not declare and which used to be
    dropped at the conversion layer (the Favorites-loads-Recents bug); save was documented as sending
    updated_at, which the adapter deliberately never does; and key (storage key) versus kind
    (registry slot) is now stated, since the page used both words as if they were one thing.

    ⛔ Also filed from this hand-back: objectui#10012

    This PR was the probe. It touches content/docs/** only, Auto Label PRs run 35439380882
    completed success, and the labels afterwards were (none) — against a control of the same
    workflow labelling objectui#10009 and objectui#10008 correctly. .github/labeler.yml has no rule
    matching content/**
    : documentation covers docs/**/* (25 tracked files) and not content/docs
    (203). And sync-labels: true means the documentation label the dev applied by hand will be
    removed on the next synchronize. ⚠️ Related but ⛔ not a duplicate of objectstack#19179.

    Next

    Waiting on the full shard matrix against b238ea92e. ⛔ Nothing lands until every gate job reads
    completed: success and check-governed-merges.mjs --pr is re-run on the FINAL file list.


    Generated by Claude Code

  9. os-tesla commented on Sep 19, 2026

    @os-tesla
    Collaborator

    Seat landing verdict — 2026-09-19T12:05Z

    Seat: domain:ui#2 · Session: session_018HrVaotisyhgmot9o2MLRq

    PR objectui#10011 merged 2026-09-19T12:03:15Z as ec1de927d. Healthy merge, ⛔ not an
    ejection: merged and removed_from_merge_queue in the same second.

    Verified BY CONTENT on merged origin/main, ⛔ not by sha and ⛔ not by ancestry

    reading, content/docs/guide/user-state-persistence.md before b234a8497 after 5eabe8646
    user_app_state 4 0
    sys_user_preference 0 5
    CONTROL — the page's own length 245 261

    Each zero is a reading because the other token, on the same file and the same command, is non-zero.

    What this card turned out to be

    The stop condition triage attached — 「if the dev finds evidence the doc describes an intended
    future shape
    , stop and report rather than picking」 — was checked and does not fire, with the
    strongest available evidence: packages/data-objectstack/CHANGELOG.md's 5.0.0 minor 「Unify
    per-user UI state storage onto sys_user_preference」 records the migration AWAY from
    user_app_state, the rename of the option from kind to key, and, verbatim, 「but no backend
    ships that schema
    」. That package is at 17.6.0. ⇒ the guide taught a shape nothing serves,
    across a major version boundary.

    Three further wrongnesses of the same defect were repaired in the same pass: the walkthrough taught
    find with bare filter / limit, which the sealed QueryParams does not declare; save was
    documented as sending updated_at, which the adapter deliberately never does; and key (storage
    key) versus kind (registry slot) is now stated, since the page used both words as if they were one
    thing.

    ⭐ A scope proof worth borrowing. Rather than promising the diff was prose-only, the dev hashed
    every fenced block on both refs: the single yaml block's hash moves, and all five
    ts/tsx/typescript fence hashes are byte-identical
    . check:doc-snippets compiles exactly those
    fences, so the diff cannot move its verdict on this page. That is a mechanical fact, ⛔ not an
    assurance.

    ⛔ Two claims on this card were FALSE, and this seat carried one of them into its own dispatch

    1. 「no gate reads them」 (the prose and yaml block) — ⛔ false; four gates read this page.
    2. 「the page is on the UNGATED_DOCS ledger」 — ⛔ false today; its only occurrence in
      scripts/check-doc-snippet-types.mjs is a historical docblock recording that objectui#5174's
      batch 1 took it OFF.

    ⇒ the true reading is narrower and worse, and it is now objectui#10013: the page sat under four
    GREEN gates and not one asks the question this defect answers to. Nothing compares a documented
    storage contract against the adapter implementing it, so a page under four green gates reads as
    covered
    .

    Also filed from this card

    objectui#10012 — this PR was the probe: it touches content/docs/** only, Auto Label PRs run
    35439380882 completed success, and the labels afterwards were (none), against a control of
    the same workflow labelling two package PRs correctly. .github/labeler.yml has no rule matching
    content/**
    , and sync-labels: true removes the one applied by hand.

    Card state

    Closing completed. pm:dispatched and the assignee are cleared in the same write as this verdict.


    Generated by Claude Code

  10. removed their assignment
    on Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions