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.

console lists: per-user list state (view tab order, filter state, sort, column widths) moves from localStorage and shared-view writes onto sys_user_preference ui.* keys; a toolbar sort or drag-reorder no longer rewrites the shared view #12418

Closed

Description

@objectstack-fleet

Filing gate ③, a task the maintainer dispatched in person (chat, 2026-10-15). The maintainer asked 「这是主流类似系统的做法吗?浏览器侧的个人偏好——objectui 把视图顺序和每人每视图的筛选状态存在 localStorage」; the director seat answered that mainstream systems keep per-user list preferences on the server per user and offered 「是否立一张 objectui 卡做第一层(个人偏好上服务端、排序不写共享视图)?你一个字「立」我就立,归 objectui 车道。」; the maintainer's word: 「立」. Filed by the director seat (summon #37 continuation 2, session_01LqNgdPZB2Jnr5HpGbaqLeB). ⛔ Not a claim; triage may regrade.

The problem in one sentence: a console user's list preferences live in three places — the view tab order and the Filter panel's state in the browser's localStorage (gone on another device or after a cleared cache, no admin reset), favorites / recents / palette recents on the server under sys_user_preference ui.* keys (the cloud-synced adapter), and a user's sort click or view drag written INTO the shared view metadata through client.meta.saveItem — so one user's sort changes what every user sees, and under a walled posture (group / isolated) that write is refused by the platform (ADR-0131 D12 items 7–8: tenants do not write environment metadata), so a personal preference ends in an error.

Reader who acts: the domain:ui lane, one dev round in @object-ui/app-shell (plus @object-ui/data-objectstack if the adapter needs a new slot shape).

Readings (objectui origin/main 28fb2a001; objectstack origin/main 086fa4640)

  1. View tab order: packages/app-shell/src/views/ObjectView.tsx:2739-2760 (handleReorderViews) writes viewOrder:<object> to localStorage first, then PATCHes sortOrder onto every saved view through dispatchViewPatches / reorderViewPatches (:1102-1118), the shared row, "so other sessions / users can pick up the order".
  2. Sort: :3745-3747 onSortChange → persistViewPatch(viewDef.id, viewDef, { sort }) (the shared view, through updateViewConfig → client.meta.saveItem, a PUT on /meta/view, :1168) and writeListUrlState({ sort }).
  3. Filter panel state: :3752-3762 onFilterChange → writeListFilterState(listFilterKey, …) (localStorage, "SESSION state only", objectui#4155's rule that the builder's group never touches the view's stored body) and the URL (objectui#11860).
  4. Already on the server, per user: packages/data-objectstack/src/userState.ts (createObjectStackUserStateAdapter: resource sys_user_preference, (user_id, key, value), load() / save(), keys namespaced ui.*; one shared read per load, objectui#12187, pinned by consoleUserPreferenceBudget.test.tsx). Consumers today: ui.favorites, ui.recent, ui.flow.palette.recents (ConsoleShell.tsx:331-341).
  5. The object: objectstack packages/platform-objects/src/identity/sys-user-preference.object.ts ("Per-user key-value preferences"), organization-owned rows, unique on (organization_id, user_id, key): a data write, not a metadata write, admitted for a tenant's own user under every posture. Environment metadata writes under a wall are refused for everyone but the platform operator (packages/metadata-core/src/meta-write-capability.ts, walledCatalogWriteVerdict).
  6. Saved views in the console are metadata: ObjectView.tsx:2244-2247 reads them from /meta/view via listViews; there is no per-user or per-organization saved-view object (sys_view_definition retired as inert, ADR-0131 §7; per-user view scope is "a parked platform-side v18 direction").

What to build (the first layer only: preferences, not personal views)

  1. One per-user list-state slot on the existing adapter: key ui.list.<object>, value { viewOrder, perView: { [viewId]: { sort, filters, columnWidths? } } }, written through save() and read in the same shared read as the three existing slots: the objectui#12187 budget stays ONE sys_user_preference read per console load (extend the pinned test; add no request). localStorage stays as the write-through cache and the no-adapter fallback (load() answering [] keeps today's localStorage path), so an adapter-less or offline host behaves as today.
  2. A user's sort and drag-reorder stop writing the shared view: onSortChange and handleReorderViews write the user's slot (and the URL, objectui#11860, unchanged); persistViewPatch and the sortOrder PATCHes are reached only from the view editor (Studio, or an explicit "save view" action by a metadata author), never from a toolbar click. ⛔ The view's authored sort and the authored tab order stay the default for every user with no preference.
  3. Filter state moves from the session-only localStorage key to the same slot, keeping objectui#4155's rule (the builder's group never touches the view's stored body) and the URL.
  4. Reset: the toolbar's "Clear all" (filters) and a "Reset view" entry clear the user's slot for that view; an admin deletes the row in Setup → User Preferences (already navigable).
  5. Under a wall: nothing new to build; the point of the move is that a tenant user's list preferences are organization rows and therefore allowed where metadata writes are refused. Measure it: a non-operator user on a group posture changes sort and order with no error and no change to the shared view (an adapter-level pin with the fake framework the budget test already uses, or a dogfood run).
  6. ⛔ Not in this card: personal or shared saved views (ViewItem.owner was retired in 18; that is a protocol decision card if wanted); the Studio view editor; any change to packages/spec.

Acceptance

  • The objectui#12187 budget pin passes with the new slot included: still one sys_user_preference read per console load, every consumer receiving its own row.
  • A pin that a toolbar sort or drag-reorder issues NO /meta/view write (the fake framework counts 0 PUTs) and one preference save(); the view editor's save still writes /meta/view.
  • Cross-device: the same user in a second browser (fresh localStorage) sees their order, sort and filters after load(); another user sees the authored defaults.
  • The walled-posture pin of item 5.
  • pnpm -r typecheck, the app-shell suite and the check:* gates the repo's AGENTS.md lists.

Dedupe

Titles of the last 300 objectui issues (all states) grepped for preference / localStorage / viewOrder / personal / per-user / filter state / column width / sortOrder: 1 hit, objectui#12212 (closed, the bell's object label; not this). Open issue bodies mentioning sys_user_preference, viewOrder or localStorage: 0. Precedents cited, all closed: objectui#4155 (the filter panel must not persist an overlay), objectui#11860 (filters, sort and grouping in the URL), objectui#5544 and objectui#12187 (the preference read budget). The GitHub search API is not available to this session; the dedupe is the repository listing above.

Related: objectui#4155 · objectui#11860 · objectui#12187 · objectui#5544 · objectstack ADR-0131 D12 items 7–8 · objectstack walledCatalogWriteVerdict.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Deferred, not parked: domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T04:40Z. ⛔ Not a claim; the card stays pm:queue, unassigned.

    Why it waits: this card's surface shares hot files with two in-flight claims. Same-area cards run serially, so it is next in this lane's order once both land.

    • objectui#12423 (seat 3, claim 6184189645) edits packages/plugin-list/src/ListView.tsx (the right toolbar cluster), packages/plugin-view/src/ViewTabBar.tsx, the grid's leading cell, and the ViewTabBar call site in ObjectView.tsx. This card's sort, filter, drag-reorder and column-width paths run through the same toolbar, tab bar and grid.
    • objectui#12417 (seat 2, claim 6184389018) edits handleRenameView in ObjectView.tsx, a few hundred lines from this card's handleReorderViews (:2739–:2760).

    Known pitfalls, for whichever seat claims it:

    • Every line number in the body was read on an earlier main. Re-read handleReorderViews, onSortChange and onFilterChange on the ref that carries both landings.
    • The objectui#12187 budget stays one sys_user_preference read per console load. consoleUserPreferenceBudget.test.tsx is the pin to extend; a fourth slot must not add a request.
    • If objectui#12423's display popover moves where sort and filter controls live, the toolbar call sites this card rewires move with it.

    Restart: when objectui#12417 and objectui#12423 have both merged. The seat that claims it re-checks the in-flight list at that moment.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (the deferral 6184567991 is lifted: objectui#12417 and objectui#12423 have both closed)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12418-per-user-list-state
    Worktree: objectui-issue-12418
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/views/ObjectView.tsx (handleReorderViews, the toolbar onSortChange / onFilterChange handlers and the viewOrder: / list-filter reads, read on main a2225f913 at :2381, :2748, :3432, :3755), packages/app-shell/src/views/listFilterStorage.ts, the console's preference wiring (ConsoleShell.tsx and the user-state adapters provider) and consoleUserPreferenceBudget.test.tsx, packages/data-objectstack/src/userState.ts only if the slot needs a new shape, packages/plugin-grid or packages/plugin-list only where column widths are reported, the tests beside each, and one .changeset/12418-*.md (stop on breach; explain in the report)
    Container & model: L, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate)
    Clause-②: yes
    Responsibility: n/a — not a defect card
    Thread-read: 6184567991
    Serial constraints cleared: read at objectui main a2225f913.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 12418,
    "status": "done",
    "branch": "claude/issue-12418-per-user-list-state",
    "pr": "#12471",
    "session": "session_01JZnppgHRp4sREcouhkQYDB (mode:subagent, so this is the dispatching seat's session id, the same id the relay stamped)",
    "premise_still_valid": true,
    "summary": "Draft PR objectui#12471 (head ec82faf, 6 commits on base a2225f9). It moves each user's list state into one sys_user_preference row per object, key ui.list.OBJECT, value { viewOrder, perView: { VIEW_ID: { sort, filters, columnState } } }: the view-tab order, plus per view the sort, the Filter panel's conditions and the grid's column order and widths. A new ListPreferencesProvider in ConsoleShell holds it, with localStorage (list-state:USER:OBJECT) as the write-through cache and the no-adapter fallback. A toolbar sort (both sort sites), a column resize or drag, a Filter panel change and a Manage Views drag now write that row and never /meta/view. The view editor's save is unchanged. A3 is falsified in its simple form: the shared read is opened at boot, and the object page mounts after metadata, so a per-object key cannot join it by name. The budget is kept by a new @object-ui/data-objectstack export, createObjectStackUserPreferenceFamily, whose boot load joins the same request as a key PREFIX arm (key in [3 slot keys] OR key startswith 'ui.list.'). That is still ONE GET, pinned, with a saturation fallback for the slot keys. Item 4 also landed: 'Clear all' clears the stored filters, and a 'Reset view' button in the page header (2 new keys in all 10 i18n packs) drops the active view's entry and remounts the list on the authored defaults. Measured beyond A1: the drag door is admin-only (ViewTabBar mount has reorderable:false; only the admin-only ManageViewsDialog calls onReorder), so the reordered tabs become that admin's own order. The new cross-device pin caught a bug in this branch, now repaired: the first render ran before the bridge attached the family and seeded the list from an empty cache. The provider now waits for a signed-in user's family, bounded by 2.5 s.",
    "tests": "All runs went through os-verify-lock. (1) Final-HEAD union at ec82faf: vitest run of ObjectView*, consoleUserPreferenceBudget, consoleListStateWall-12418, context/tests, data-objectstack userState*, the i18n objectView-config-keys-retired-4730 test, view-filter-fold.ratchet and writeRefusalCensus-11583 printed 'Test Files 79 passed (79) / Tests 695 passed (695)', VERDICT command-exit 0. (2) Full @object-ui/data-objectstack plus @object-ui/i18n: 1 red, the i18n namespace-count pin (+2 keys, updated with its reason), then i18n 'Test Files 83 passed (83)'. data-objectstack userState pins: 4 files, 30 tests green. (3) app-shell in segments: root + console + context + misc 204 files with 1 red, entryRegistersBuiltinDesigners-11939, a load-timing test that passed alone 1/1 and is already reported on objectui#12423's report; hooks/layout/providers/preview/utils/chrome 230 passed + 1 skipped; top-level views 100 + 103 files, where 2 source ratchets went red and were updated (filter-panel 'not amnesiac' leg, write-refusal census reorder row), re-run 62 files green; studio-design 58 of 173 green. NOT MEASURED: studio-design 115 files and views/metadata-admin 492 files, reason under gates. (4) Ablations, 7 of them, each one mutation through objectstack scripts/ablation-replace.mjs. Each anchor hit 1 time, went 1 to 0 and changed the blob, and each restore was proven by 'blob == HEAD and git diff HEAD is empty', with the tree clean after. Tests load @object-ui/* from src through the vitest alias, so there was no dist leg. A1 (the ListView sort prop writes persistViewPatch({sort}) again): 3 red, the userListState sort pin, the wall pin and the no-provider sort control. A2 (a drag also sends updateView sortOrder): 4 red, the drag pin, the wall pin, the 11583 reorder pin and the no-provider drag control. A3 (the family opens its own read): 7 red across the budget and family files. A4 (the seed ignores listPrefs.ready): 2 red. A5 (Reset view does not move the identity): 1 red. A6 (no saturation fallback): 1 red. A7 (the provider does not wait for a family to attach): 2 red. Every observed direction is turn-red, matching the prediction. (5) Cross-package types: app-shell type-check reads createObjectStackUserPreferenceFamily from the rebuilt data-objectstack .d.ts; the base declares no such symbol. That stands in for the paste-a-refused-key reverse check, which was not run separately.",
    "gates": "Derived by hand from objectui package.json check:* and lint.yml / ci.yml / changeset-guard.yml / changeset-presence.yml / performance-budget.yml, since the dispatch-gates tool refuses a sister repo. Each exit code was written to a file before any pipe. At ec82faf: type-check of @object-ui/app-shell (both tsconfigs) exit 0; @object-ui/data-objectstack and @object-ui/i18n exit 0 at af031bb, neither changed since. check:control-bytes 0 ('check-control-bytes: OK (scanned 8795 tracked text file(s)')), check:new-line-citations 0 ('VERDICT new-cross-file-line-citations: 0 new citation(s)'), check:i18n-keys 0, check:i18n-drift 0, check:i18n-dead-keys 0, check:i18n-designer-parity 0, check:vi-mock-specifiers 0, check:vi-mock-inherit 0, check:vi-mock-override-shape 0, check:test-path-roots 0, check:unreferenced-sources 0, check:phantom-deps 0, check:self-import 0, check:esm-specifiers 0, check:handler-key-reads 0, check:metadata-write-doors 0, check:changeset-claims 0, check:pending-changeset-literals 0, check:unused-deps 0, check:doc-json 0, check:doc-fences 0, check-doc-links 0, and the changeset gates check-changeset-no-major / check-changeset-overwrite / check-changeset-presence / check-changeset-fixed all 0. On the console build of 831cf78: check:eager-closure 0 ('Console eager closure is 3079.3 KB gzipped ... (budget: 3119.4 KB, headroom: 40.1 KB)'; vendor-objectstack at 0.0 KB headroom, which is the installed @objectstack/* npm packages and not touched by this diff), check:eager-locale-catalogues 0, check:doc-snippets 0 ('793 of 793 block(s) judged, 0 failed'), check:doc-examples 0, check:readme-exports 0, check:docs-route-closure 0. These first ran before that build and printed PREREQUISITE NOT MET (exit 2), which is not a reading; after the scoped build they passed. They were not re-measured after the later ObjectView.tsx byte-level commits; CI's performance-budget re-measures them. ESLint on the 32 changed files: 0 errors. DECLARED NARROWING: studio-design 115/173 and views/metadata-admin 492 test files were not run locally. The shared lock was held by other agents' builds (queues of 64 to 296 s on every acquisition), and two attempts were killed by my own 590 s cap (exit 124, read as NOT MEASURED). These are declared to CI's pnpm test. PR check-runs at ec82faf: none registered yet at read time (total_count 0), so CI is in_progress / NOT MEASURED. The seat owns CI convergence.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches through scripts/pm/fleet-write/dispatch.mjs (pr_create) and scripts/pm/post-stamped.mjs (this comment), executed as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos//issues/12471/assignees (sunhaolin); POST /repos//issues/12418/comments. Plus git push of the branch (7 pushes, not REST). No label write.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: the list toolbar's density toggle and Hide Fields popover in the console are public doors, measured in consoleListStateWall-12418's CONTROL leg: under a walled fake, a density change goes to /meta/view, is answered 403 and is toasted as an error · evidence: ObjectView's relay rung onDensityChange calls persistViewPatch({ rowHeight }), and persistHiddenFields calls persistViewPatch({ hiddenFields }). Both are personal toolbar actions that still write the shared view, change it for every user, and are refused for a tenant under group/isolated posture. This is the same family as objectui#12418. The ui.list.OBJECT slot could carry both, but hiddenFields interacts with the authored columns projection (objectui#10694), so it needs a ruling and was not folded in · fold into this family's follow-up card rather than a single-point card · dedupe words: density toggle shared view, hidden fields popover persistViewPatch, toolbar writes view metadata walled, per-user display preferences",
    "carrier: objectui#12440 (it edits the ViewTabBar mount next) · noted, not filed: a non-admin user has no tab-reorder door at all (the ViewTabBar mount sets reorderable:false and passes no onReorderViews; the only door is the admin-only Manage Views dialog). Now that the order is per-user, opening the door to every user is a one-prop change at that mount.",
    "carrier: 承接者:无 · noted, not filed (test infrastructure, repaired in-scope because it is the pinned test this card extends): the objectui#12187 budget pin's fake framework refused an unknown filter operator only while matching rows, and an 'or' whose first arm matched every stored row never evaluated the second arm. The prefix arm went green on the unmodified pin (measured). The fake now refuses unknown operators when it reads the filter."
    ],
    "deviations": [
    "File surface beyond the claim, each named in the PR body: packages/i18n/** (2 keys x 10 packs + the namespace-count pin); docs per objectui AGENTS.md #2 (content/docs/guide/user-state-persistence.md, packages/data-objectstack/README.md); the new packages/app-shell/src/context/ListPreferencesProvider.tsx; console/tests/preferenceFramework.ts (the budget fake, extracted so the wall pin uses the same one); and 6 existing tests whose pinned behaviour this card moves (11642, 11583 x2, unboundAdapterCall, overlayPatchOnly, view-filter-fold ratchet).",
    "ObjectView.tsx changes outside the A1/A2 handlers: the views-memo order read, the list seed and its readiness gate, the Reset view header button, and the header icon line. The icon line was forced: removing the views memo's try/catch let the React Compiler lint analyse ObjectViewInner for the first time, and react-hooks/static-components (error level) then refused the pre-existing icon JSX tag. It is now createElement, the ObjectDataPage convention. Warn-level compiler diagnostics in that component now appear in lint output; CI sets no --max-warnings.",
    "The slot keeps columnState { order, widths } instead of the card's columnWidths: the grid reports both in one callback, and a split would leave column order writing the shared view.",
    "listFilterStorage.ts is unchanged (it keeps the search term). plugin-grid and plugin-list are untouched.",
    "The removed export reorderViewPatches (ObjectView.tsx) had no reader left; it was not on any package entry.",
    "Local test narrowing declared (see gates).",
    "The commit trailer pair is the model-free 'Claude-Session' + 'Co-authored-by: Claude', per objectui AGENTS.md; the harness reminder's model-named trailer was not used."
    ],
    "line_budget": "n/a: no skills/** or governed ledger touched (no .claude/, AGENTS.md, docs/adr/, .github/workflows/**)",
    "files_changed": [
    ".changeset/12418-per-user-list-state.md",
    "content/docs/guide/user-state-persistence.md",
    "packages/app-shell/src/console/ConsoleShell.tsx",
    "packages/app-shell/src/console/tests/consoleListStateWall-12418.test.tsx",
    "packages/app-shell/src/console/tests/consoleUserPreferenceBudget.test.tsx",
    "packages/app-shell/src/console/tests/preferenceFramework.ts",
    "packages/app-shell/src/context/ListPreferencesProvider.tsx",
    "packages/app-shell/src/context/UserStateAdapters.tsx",
    "packages/app-shell/src/context/tests/ListPreferencesProvider.slot-12418.test.ts",
    "packages/app-shell/src/views/ObjectView.overlayPatchOnly.test.ts",
    "packages/app-shell/src/views/ObjectView.toolbarWritesCompose-11642.test.tsx",
    "packages/app-shell/src/views/ObjectView.tsx",
    "packages/app-shell/src/views/ObjectView.unboundAdapterCall.test.ts",
    "packages/app-shell/src/views/ObjectView.userListState-12418.test.tsx",
    "packages/app-shell/src/views/ObjectView.viewWriteRefusal-11583.test.tsx",
    "packages/app-shell/src/views/view-filter-fold.ratchet.test.ts",
    "packages/app-shell/src/views/writeRefusalCensus-11583.test.ts",
    "packages/data-objectstack/README.md",
    "packages/data-objectstack/src/index.ts",
    "packages/data-objectstack/src/userState.family-12418.test.ts",
    "packages/data-objectstack/src/userState.ts",
    "packages/i18n/src/tests/objectView-config-keys-retired-4730.test.ts",
    "packages/i18n/src/locales/ar.ts",
    "packages/i18n/src/locales/de.ts",
    "packages/i18n/src/locales/en.ts",
    "packages/i18n/src/locales/es.ts",
    "packages/i18n/src/locales/fr.ts",
    "packages/i18n/src/locales/ja.ts",
    "packages/i18n/src/locales/ko.ts",
    "packages/i18n/src/locales/pt.ts",
    "packages/i18n/src/locales/ru.ts",
    "packages/i18n/src/locales/zh.ts"
    ],
    "cleanup": "worktree /home/user/objectui-issue-12418 removed (node_modules first, no --force, exit 0); no server or background process left by this run"
    }

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev follow-up: seat review round 1 on objectui#12471

    • Merge: 8855da7423 merges objectui main e869e41275 into the branch as a merge commit, with no rebase and no force-push. The one conflict was the lucide import line in ObjectView.tsx, and both sides were kept: objectui#12443's MoreHorizontal and the SidebarItemMenu import, plus this branch's RotateCcw. The new head is 2fcd8575af. git merge-tree against the newer main d25585cffb exits 0. CI has started on the head: 36 check-runs, all still queued, running or skipped.
    • Ask 2, done (e816fd02f3 and 3cb0cd7763):
      • The "Reset view" header button is gone, and "Reset view" is now a DropdownMenuItem in the header's ⋯ menu, after the favorites entry.
      • The item is drawn only while activeViewHasPreference is true, and the ⋯ trigger renders when listFavorite || activeViewHasPreference.
      • The label is console.objectView.resetView, the title is resetViewTitle, and the test id is still object-view-reset-view-button.
      • The pins now open the ⋯ first and assert the item is not drawn while the menu is closed.
      • A new pin covers a page with no favorites entry (no app segment): the ⋯ is drawn for "Reset view" alone, and it disappears once there is nothing to reset.
      • The changeset and the guide now say "entry of the header's ⋯ menu" (2fcd8575af). The PR body still says "header button" in Clause-② item 4 and in the A5 bullet. The dev writes the body once only, so that edit is the seat's.
    • Ask 3, done (e816fd02f3): measured that the list does emit []: removing the last level in the Sort builder calls handleChange([]), which reaches ListView's emitSortChange. The ListViewPreferencePatch docblock now says that sort: [] is kept as "no sort", that null or undefined clears the stored sort, and that Reset view is the way back. A new pin checks that a patch of { sort: [] } stores sort: [], and that this is distinct from what { sort: null } and { sort: undefined } store.
    • Re-run on the merged tree:
      • The app-shell dependency closure built: 28 of 28 tasks.
      • Type-check passed (exit 0 for each) for @object-ui/app-shell (both tsconfigs), @object-ui/data-objectstack and @object-ui/i18n, at e816fd02f3. The commits after it change only tests and docs.
      • The vitest union passed at e816fd02f3: ObjectView* (now including main's favoritesEntry-12427), the console preference pins, context/__tests__, data-objectstack userState*, the i18n namespace pin and the two ratchets. That is 80 files and 699 tests.
      • The userListState-12418 file passed at 3cb0cd7763: 12 of 12.
      • ESLint on the changed files reports 0 errors.
      • These gates all exit 0: check:control-bytes, check:new-line-citations ("0 new citation(s)"), check:i18n-keys, check:i18n-drift, check:i18n-dead-keys, the three check:vi-mock-* gates, check:test-path-roots, check:unreferenced-sources, check:esm-specifiers, check:handler-key-reads, check:metadata-write-doors, check:changeset-claims, check:pending-changeset-literals, check:doc-fences, check:doc-json, check-doc-links, and changeset no-major, overwrite and presence.
    • Ablations re-run (each through ablation-replace.mjs, with the restore proven against HEAD):
      • A5 (Reset view does not move the identity): its anchor did not move, and it re-ran red, 1 test.
      • A8 (new; the entry is drawn regardless of stored state): red, 2 tests.
      • A9 (new; the ⋯ is gated on the favorites entry only): green on the first run, because every existing pin had a favorites entry. After the no-app-segment pin was added, it went red, 1 test.

    Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev follow-up: CI round on objectui#12471

    • New head: 6338c47e38. It is one commit on 2fcd8575af, and it changes only packages/plugin-form/src/affordanceGrantMap-12082.test.tsx.
    • What moved: the write-call-site census keyed the user-state upsert under createObjectStackUserStateAdapter > upsert. The refactor moved that upsert's dataSource.update and dataSource.create calls into the shared createPreferenceRowWriter > upsert in userState.ts, which both the per-key adapter and the list-state family use. Both entries now carry the new key. Their classification (outOfFamily) and their reason are unchanged, because the reason names no handler. Nothing else in the census changed.
    • Other keyed ratchets: git grep finds no other census keyed on createObjectStackUserStateAdapter > or on userState.ts call-site paths. The one other test that names userState.ts is one-authority-per-exported-name-6273, and it was run.
    • Verdicts (run from the repo root, exit captured before any pipe): affordanceGrantMap-12082 and one-authority-per-exported-name-6273 exit 0, 2 files and 60 tests passed. check:control-bytes and check:new-line-citations both exit 0.
    • Check-runs read on 2fcd8575af:
      • Test (shard 9/16) failed. Its only failure annotation is this census.
      • Test failed as the rollup of shard 9.
      • Type Check and Test (shard 3/16) succeeded, as did every other shard.
      • Spec Main Shape Gate failed in packages/types/src/layout.ts (PageNodeSchema, TS2430). This PR does not touch that file. main's own scheduled runs of the gate are red at cf430cd10e and 5c4deb56ab, and its last green was a8e5b73645. So this is objectstack drift, a main-red for the domain:devx lane, and the check is advisory on pull requests.

    Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T11:58Z

    • Merged: PR feat(app-shell): a list's sort, column layout, filters and tab order are the user's own, not the shared view's (objectui#12418) #12471 landed through the merge queue as main caac3b24ee at 2026-10-15T11:45Z. It has one parent, d9d9d98684, and is an ancestor of origin/main.
    • Verified by content: the PR changes 33 files, and its hunks are line-identical on main for all of them. The diff d9d9d98684..caac3b24ee equals the PR's own diff e869e41275..6338c47e38 file by file. Twenty-three files are also blob-identical to the accepted head 6338c47e38. The ten i18n packs are not blob-identical, because objectui#12461's PR feat(app-shell,i18n): the console app bar's left group is the app pill and its PREVIEW chip; an object route draws no crumb; Edit app is an icon button (objectui#12461) #12469 landed first and retired topbar.switchObject from them. This PR's two added keys sit beside that change unchanged.
    • Mis-close scan: the PR body's only closing keyword is Fixes #12418. The only issue closed with the merge is this card, completed.
    • What now holds:
      • A console user's list sort, column layout, Filter panel conditions and view-tab order are their own: one sys_user_preference row per object, ui.list.OBJECT, read in the console's one preference read per load. They follow the user to another browser.
      • A toolbar sort, a column change, a Filter panel change or a Manage Views drag no longer writes /meta/view, so one user's click no longer changes the view for everyone, and a walled tenant is no longer refused.
      • "Reset view" is an entry in the page header's ⋯ menu.
      • @object-ui/data-objectstack adds createObjectStackUserPreferenceFamily.
    • The chain:
      • the claim 6187168689, the report 6190169765, and the follow-ups 6190609737 and 6190831748;
      • the seat's review round 1 (the merge of main, Reset view moved into the ⋯ menu, the empty-sort docblock);
      • the TIER_DEFAULT PASS 6190683123, the ACCEPT 6190697555, and the ACCEPT carried to the head 6190848387;
      • the Spec Main Shape Gate base-red note 6190753666.
    • Carried on:
      • objectui#12474: the density toggle and Hide Fields still write the shared view (finding, Blocked-by: #12418, now met).
      • Seat 2's objectui#12440 edits ObjectView.tsx / ListView.tsx next, and starts from this merge.
    • Label: pm:dispatched is removed in the same act as this note. The assignee stays, as the record of who drove it.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions