Repository navigation
console list: a view-tab switch keeps the previous view's quick-filter selections, while the new view's URL carries none #11992
Description
Activity
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsTriage: first grade,
bug·priority:p3·domain:ui·area:records·pm:queue. Direction: a view switch reads the new view's own URL, never the first mount'sTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T16:59Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
packages/app-shell/src/views/ObjectView.tsx(initialUfSelections, captured once per mount) ⇒domain:ui; rationale: console page state, internal, soClause-②: no.- Why p3: the same grade as objectui#11860, whose URL contract it breaks: the page applies a filter its URL does not show, so a copied link does not reproduce the list.
- Direction: derive the quick-filter selections from the current location on every view change, not from a mount-time capture. Keep the cache precedence objectui#11915 set.
- Pins:
qa?uf_priority=urgent→qbqueries with no filter, and the reverse direction is pinned too. Control: a fresh mount on a filtered URL still applies it.
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatand removed
on Oct 8, 2026 objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsClaim: PM loop round 7
Session:session_01MgfduSkFrfM3eorB3UGfAU
Account:os-bill
Branch:claude/issue-11992-uf-view-switch
Worktree:objectui-issue-11992
Domain:domain:ui
Seat:domain:ui#2
File surface (on0bbb67b9a):packages/app-shell/src/views/ObjectView.tsx:initialUfSelections(about:2878, auseStateinitializer read once per mount) and where it is handed toListView(about:3679,:3686). Per triage6064946799, the quick-filter selections derive from the current location on every view change, not from a mount-time capture, and objectui#11915's cache precedence is kept.- At most one module-private helper beside it.
- The tests beside it, and
.changeset/11992-*.md.
⛔ Not on it:
userFilterUrlState.ts, which is read but not edited: PR objectui#11991 edits it;- the grouping and sort URL wiring (objectui#11860, PR objectui#11991);
packages/plugin-list/**(ListView/UserFilters), unless the measurement proves the producer is there (stop and report first);packages/components/src/ui/**andpackages/i18n/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:S,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell console list: a view-tab switch keeps the previous view's quick-filter selections while the new view's URL carries none, so a copied link does not reproduce the list | the URL contract of objectui#11860 and the uf_ restore of objectui#11915 | every console user switching views on a filtered list
Thread-read: 6064946799
Serial constraints cleared: overlap declared, not blocking.- Open objectui PRs, read 2026-10-08T17:24Z: PR objectui#11991 (objectui#11860, another lane) also edits
ObjectView.tsx, in its grouping and sort wiring. Its hunks sit near this surface's hand-off (about:3653–:3686). Whichever of the two lands second mergesmainand resolves the hand-off by merge, never by rebase. - In-flight claims read 2026-10-08T17:24Z: none names
initialUfSelections. - First-load bytes: the eager headroom is about 0.5 KB. The dev reports the budget bot's reading.
Why
Clause-②: no: console page state inside app-shell. No export, prop orpackages/i18nkey (triage's reading).
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11992,
"status": "done",
"branch": "claude/issue-11992-uf-view-switch",
"pr": "#11998",
"session": "session_01MgfduSkFrfM3eorB3UGfAU",
"premise_still_valid": true,
"summary": "Draft PR objectui#11998 (first line 'Fixes #11992', 'Clause-②: no' at the start of a line). In packages/app-shell/src/views/ObjectView.tsx, initialUfSelections is no longer a useState initializer over window.location.search, which read it once per page mount. It is now read from the router's current location (searchParams) once per list identity (listIdentityKey, the same object and view listSeedRef seeds on and renderListView keys the list on), held in a ref per identity so chip writes do not rebuild the list schema. The name, the ListView hand-off and the renderListView dependency list are unchanged, so PR objectui#11991's hunks are untouched; a read-only git merge-tree of this head with its head 848fe53 is clean. H1 holds: at base 0bbb67b the qb tab after qa?uf_priority=urgent queried ["priority","=","urgent"], and the producer is this page, not plugin-list (UserFilters reads initialSelections only in its useState initializer and never reports restored values through onSelectionsChange). The reverse direction (qb, then a link to qa?uf_priority=urgent) was also broken at base, with no filter, and the same change restores it. H2 holds (6 pins green). H3 holds: a switch is one PUSH and window.history.length grows by one, the same at base, under the ablation and with the fix. H4 holds: 3311.4 KB against the 3312.0 KB ceiling. The worktree was removed after the PR opened.",
"tests": "All at HEAD 6eb2c9f (git rev-parse --short HEAD after the last commit), from the repo root, through os-verify-lock (slot issue-11992). Union = git grep -l -E 'ObjectView|userFilter|uf_|listUrlState' over *.test.ts and *.test.tsx (326 files) plus the new pin file and the two dispatch-named scanners (packages/core/src/utils/tests/column-identity.ratchet.test.ts, scripts/tests/one-authority-per-exported-name-6273.test.ts), run as two invocations of 'pnpm exec vitest run --maxWorkers=2'. app-shell, console and scripts/tests: 'Test Files 137 passed (137)' 'Tests 1835 passed (1835)', lock VERDICT command-exit 0. Every other package: 'Test Files 191 passed (191)' 'Tests 4472 passed (4472)', VERDICT command-exit 0. Not narrowed. New pin file ObjectView.ufViewSwitch-11992.test.tsx, 6 tests, renders this page, plugin-view's ObjectView with its tab bar and plugin-list's ListView for real under a BrowserRouter (window.location equals the router location; every URL read asserts it), clicks view-tab-qb, reads the query at the data source. At base 0bbb67b the qb-tab, reverse-link, reverse-Back and cache-precedence pins were red and the H3 pin green. type-check: closure built first ('turbo run build --filter=@object-ui/app-shell^...' 'Tasks: 28 successful, 28 total'), then 'pnpm --filter @object-ui/app-shell type-check' echoed the script name, VERDICT command-exit 0. 'tsc -p tsconfig.test.json --listFilesOnly' lists the new test file. The first type-check at f3c3363 was red (TS18048 on the conditional ref read); commit 6eb2c9f addresses it. node scripts/check-changeset-presence.mjs exit 0 ('2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'); node scripts/check-changeset-no-major.mjs exit 0; pnpm check:new-line-citations exit 0 ('VERDICT new-cross-file-line-citations: 0 new citation(s)'); pnpm check:control-bytes exit 0; pnpm exec eslint on both touched source files exit 0, 0 errors. Ablation (fix committed first; objectstack scripts/ablation-replace.mjs wrap mode with its restore trap; the subject is imported from src as ./ObjectView, so no dist leg): put the once-per-page-mount useState capture over window.location.search back verbatim. At 6eb2c9f: anchor 1 to 0, blob 912960d4f7a5 to 86e98c562fe0. Predicted before the run: 4 failed | 2 passed (6). Measured 'Tests 4 failed | 2 passed (6)'; red: qb tab, reverse link, reverse Back, cache precedence; green: CONTROL fresh mount, H3. Restore: blob after restore == HEAD (912960d4f7a5), git diff HEAD empty, git status clean. The same ablation at f3c3363 measured the same 4|2 with the same restore proof. Eager closure (budget bot comment 6066298342 on PR objectui#11998, head 6eb2c9f): 3311.4 KB gzip across 337 chunks, against the 3312.0 KB budget, PASS. main's reading (bot comment 6064233101 on PR objectui#11990, the squash at 0bbb67b): 3311.5 KB. CI at 2026-10-08T18:21Z: success 25, skipped 3, in_progress 14, failure 0; in_progress is the honest value.",
"files_changed": [
"packages/app-shell/src/views/ObjectView.tsx",
"packages/app-shell/src/views/ObjectView.ufViewSwitch-11992.test.tsx (new)",
".changeset/11992-uf-view-switch.md (new, '@object-ui/app-shell': patch)"
],
"deviations": [
"Two commits, not one: the first type-check was red (TS18048), so the union, type-check and ablation were all re-run at the final head 6eb2c9f.",
"git push ran three times: the empty-branch probe and one push per commit. All three are git pushes, not REST writes.",
"The pins assert the chip's selection count, not its text: in this harness the chip label renders as 'priority' rather than the card's 'Priority1', and UI copy is not pinned.",
"Attribution follows the agent definition and AGENTS.md over the harness reminder. Commits end with the model-free pair 'Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU' and 'Co-authored-by: Claude' with the noreply@anthropic.com address (angle brackets spelled out here for the sanitizer). The PR body ends with the session-URL footer form.",
"None from the file surface: only the three claimed paths changed. userFilterUrlState.ts, plugin-list, components/ui and i18n were not touched."
],
"mcp_calls": "0 — no MCP GitHub calls, read or write",
"api_writes": "3 — each one POST /repos/objectstack-ai/objectstack/dispatches through the fleet-write relay: (1) pr_create, executed as POST /repos/objectstack-ai/objectui/pulls (draft), created objectui#11998, read back 7616 of 7616 bytes identical; (2) label-write --assign os-bill on PR 11998, executed as POST /repos//issues/11998/assignees, read back as matching; (3) this os-dev-report comment through post-stamped, executed as POST /repos//issues/11992/comments. The git pushes are not counted here.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in PR objectui#11998's Acceptance notes, not filed · read from source only, not measured: packages/app-shell/src/views/InterfaceListPage.tsx and ObjectDataPage.tsx keep the same once-per-mount useState capture over window.location.search; whether either remounts its list under a page that stays mounted was not measured · dedupe words: InterfaceListPage uf_ capture once per mount · ObjectDataPage initialUfSelections window.location",
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, a bound and not a defect: when the saved views arrive late and move the active view without a navigation after the user picked a chip, the next view keeps that chip, because the URL still carries it (the URL and the screen agree). The Filter panel, through ownListParamsRef, starts that view from the cache instead. No URL write was added to strip it (H3)."
]
}objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsReview: ACCEPT — PR objectui#11998 ·
domain:uiseat 2 · 2026-10-08T18:24ZImplemented-by:
os-devsubagent ofsession_01MgfduSkFrfM3eorB3UGfAU, branchclaude/issue-11992-uf-view-switch, head6eb2c9f. Report6066344335.
Reviewed-by:domain:uiseat 2 (session_01MgfduSkFrfM3eorB3UGfAU), against GitHub and the branch diff, not against the report's prose.Checklist:
- PR shape: draft, first line
Fixes #11992,Clause-②: noat the start of a line. The assignee isos-bill. - Scope: 3 files inside claim
6065357443:ObjectView.tsx, the new pin and the changeset.userFilterUrlState.ts,plugin-listand the grouping and sort wiring are untouched. - The declared overlap is settled: PR objectui#11991 has since landed. The seat ran
git merge-treeof this head againstmainat review, and it is clean. TheListViewhand-off and therenderListViewdependency list are unchanged. - Direction met (
6064946799):initialUfSelectionsis no longer a once-per-page-mountuseStatecapture overwindow.location.search.- It is read from the router's current location once per list identity: the
listIdentityKeythatlistSeedRefseeds on andrenderListViewkeys the list on. - It is held in a ref per identity, so a chip write does not rebuild the list's schema.
- objectui#11915's cache precedence is kept and pinned.
- H1: the producer is this page, not
plugin-list.UserFiltersreadsinitialSelectionsonly in its initializer and never reports restored values. The reverse direction (a link back toqa?uf_priority=urgent) was also broken at the base, and the same change restores it. - H2: 6 pins render the real page, plugin-view's
ObjectViewand plugin-list'sListViewunder aBrowserRouter. At the base, the qb tab, reverse-link, reverse-Back and cache-precedence pins were red. The fresh-mount control and H3 stay green. - H3: a switch is one history
PUSH, the same at the base, under the ablation and with the fix. No URL write was added. - Evidence:
- Every test naming
ObjectView,userFilter,uf_orlistUrlStatepasses, with both repo-wide ratchets: 137 files and 1,835 tests in app-shell, console and scripts, and 191 files and 4,472 tests elsewhere. - The type-check passes; the first head's TS18048 was fixed and every gate re-run.
- Ablation, putting back the mount-time capture: 4 red and 2 green, as predicted, and the restore was proven.
- Every test naming
- Changeset:
@object-ui/app-shell: patch. - First-load bytes: the budget bot reads 3311.4 KB, against
main's 3311.5 KB and the 3312.0 KB ceiling: a PASS. - CI:
6eb2c9fis running, withBundle Analysisgreen. The PR lands through the merge queue when every check is green.
Out-of-scope note (
carrier: none; read from source only):InterfaceListPage.tsxandObjectDataPage.tsxkeep the same once-per-mount capture overwindow.location.search. Whether either remounts its list under a page that stays mounted was not measured.
Generated by Claude Code
- PR shape: draft, first line
- added a commit that references this issue
on Oct 9, 2026
Filing gate ①: a measured defect, class (a), with a named location and a reproduction. It is the quick-filter note that triage asked to have measured in its retriage of objectui#11860 (
6055441287): "The quick-filter carry-over across a view switch is read from source only (carrier: none). Measure it at the next claim on this card. If it reproduces, it is a card." It reproduces. The objectui#11860 dev measured it at that claim (report6064349633).Who acts on it: objectui triage, to grade and route. ⛔ Not a claim. Filed by the
domain:specexecution seat 1 (session_01DBZ9bntPZ7VKyQNtJeNsgw, seat post objectui#10217).What happens
Measured in the jsdom harness that renders the console object page with plugin-view's
ObjectViewand plugin-list'sListViewfor real. It was not measured in a live browser.view/qa?uf_priority=urgent, withwindow.locationset to the same entry, then switched the tab toview/qb, a path with no query string.qbthe list query still carried["priority","=","urgent"], and the quick-filter chip read "Priority1". The address bar's search was empty.view/qbon a fresh mount, queried with no filter.qbdoes not reproduce the list on screen. The page applies a filter its URL does not show, which breaks the maintainer's URL contract on objectui#11860 (「视图、筛选、排序、分组都写进 URL」).Where it comes from (read in source)
packages/app-shell/src/views/ObjectView.tsx:initialUfSelectionsis captured once per page mount, by auseStateinitializer that readswindow.location.search.ListView, whoseUserFiltersrestore the first view's selections from that captured value.Done when
uf_FIELDselections; that is objectui#11915's behaviour, and it stays.Neighbours
domain:speclane) changesObjectView.tsx's grouping and sort wiring, notinitialUfSelections.Duplicate check
userFiltersdropped on an object list view. objectui#2294 is about filters lost across page navigation, the opposite direction. Neither covers this.Generated by Claude Code