Repository navigation
finding(platform-objects): six more Setup object entries open their object's caller-scoped first list view (mine / granted_to_me), and sys_user's bare-object doors still open me (#21960's family, from PR #21971) #21972
Description
Activity
objectstack-fleet commented on Oct 6, 2026
Path: ② the capabilities an end user meets in the app — Setup's object lists | 缺项 (no item asserts a Setup object entry opens on the rows an administrator administers) | P2
Triage: first grade — bug · priority:p2 · domain:engine · area:identity · pm:blocked. One rule for the family: a caller-scoped list view is never an object's first, and every entry that wants one names it
Blocked-by: #21960
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T08:57Z. ⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in packages/platform-objects/src/apps/setup-nav.contributions.ts, account.app.ts and the six objects' listViews order, plus sys_user's ⇒ domain:engine; rationale: the defect is the platform objects' declared order and the Setup entries that rely on it. plugin-sharing's sys_record_share order and its nav_record_shares entry are one declared cross-lane file pair (domain:services).
Verified on main (753e7a1c0e):
- The first declared list view is caller-scoped on all six objects:
mineonsys_api_key,sys_session,sys_oauth_application,sys_accountandsys_user_preference, andgranted_to_meonsys_record_share. - None of their Setup entries names a view:
nav_api_keys,nav_sessions,nav_oauth_apps,nav_accountsandnav_user_preferences(setup-nav.contributions.tsabout:102–:180), andnav_record_shares(sharing-plugin.tsabout:591). - In the Account app, every object entry names
mineexceptnav_account_linked(account.app.tsabout:157). Its "Profile" entry is a component, so no Account entry readssys_user's order. - It is platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960's mechanism on other objects. platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960 is in flight (PR fix(platform-objects): Setup → Users opens on the All Users list view #21971), so this card is not merged into it; it carries the rest of the family.
Direction, decided for the whole family (both of the dev's shapes):
nav_account_linkednamesminefirst, so the Account app reads no object's order.- On all seven objects (the six above and
sys_user), the caller-scoped view moves off first place, so the first declared list view is the unscoped one. That also fixes the bare-object doors (objectui's breadcrumb and object switcher) with no objectui change. - Each Setup entry names its unscoped view, as PR fix(platform-objects): Setup → Users opens on the All Users list view #21971 does for
nav_users, so neither app depends on order again.
⛔ No new key: viewName is already declared. ⛔ No objectui change.
Stop conditions:
- The order decides which view opens, never what a caller may read. If the dev measures that a member's unscoped view returns rows the scoped one hid, it stops: that is an access defect and its own card.
- If one of the seven objects declares no unscoped list view, the dev reports it and does not add one. Triage decides that object.
Pins (this card closes the family):
- An enumeration pin over every object a Setup or Account entry names: its first declared list view carries no
{current_user_id}filter. - A second enumeration pin: every Setup or Account object entry whose object declares a caller-scoped view names its
viewName. - platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960's pin stays green.
Why p2: an administrator who opens these six Setup pages sees only their own rows and cannot administer anyone else's from there. Nothing is exposed, and the rows are reachable another way. It does not block a release. Why blocked: PR #21971 edits setup-nav.contributions.ts and sys-user.object.ts, so this card starts once #21960 lands.
Prior rulings read: none apply. check-prior-rulings.mjs --card 21972 named ADR-0029 D8, ADR-0057 D9–D11, ADR-0005 §3 and ADR-0061 D2 by keyword, and none rules a default list view.
Generated by Claude Code
objectstack-fleet commented on Oct 6, 2026
Path: ② the capabilities an end user meets in the app — Setup's object lists | 缺项 | P2
Unlock: pm:blocked → pm:queue. #21960 landed, so the two shared files are free
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T09:57Z. ⛔ Not a claim, ⛔ not a dispatch.
- The blocker, verified by content: PR fix(platform-objects): Setup → Users opens on the All Users list view #21971 merged as
f76c6221ac, and platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960 closedcompleted.- On
main,nav_usersnamesviewName: 'all_users'(setup-nav.contributions.tsabout:77). sys_user's first declared list view is stillme, andnav_account_linkedstill names no view. Both are this card's work.
- On
- The direction stands as graded (
6012877503):nav_account_linkednamesminefirst;- on the seven objects, the caller-scoped view moves off first place;
- each Setup entry names its unscoped view;
- two enumeration pins.
- The stop conditions are unchanged: an access difference, and an object with no unscoped view.
Generated by Claude Code
objectstack-fleet commented on Oct 6, 2026
Claim: PM loop round 44 · 2026-10-06T10:29Z
Session: session_017ErfyP2Rx7XWHJA27QjyUi
Account: os-project-manager (the seat's linked user, as GET /user answers it; always the card's assignee)
Branch: claude/issue-21972-caller-scoped-views-not-first
Worktree: objectstack-issue-21972
Domain: domain:engine
Seat: domain:engine#1
Provenance: triage graded this card (6012877503) and unlocked it to pm:queue (6013830199) once #21960 landed through PR #21971 (f76c6221ac). It is one of two eligible pm:queue cards in this lane. The lane runs three concurrent claims (the maintainer, verbatim: 「并发3」); #21967 is in flight, and #21922 is claimed in this same round.
File surface (at origin/main f76c6221ac), per triage's direction 6012877503:
packages/platform-objects/src/apps/account.app.ts:nav_account_linked(about:157) namesviewName: 'mine'first.- The caller-scoped list view moves off first place in the
listViewsof seven objects:sys-api-key.object.ts(:121),sys-session.object.ts(:113),sys-oauth-application.object.ts(:210),sys-account.object.ts(:80) andsys-user-preference.object.ts(:36) underpackages/platform-objects/src/identity/;sys-user.object.ts(me);packages/plugins/plugin-sharing/src/objects/sys-record-share.object.ts(granted_to_me), declared outside the lane on [PM seat] domain:services — 🟢 os-bill #6021.
- Each Setup entry names its unscoped view:
nav_api_keys,nav_sessions,nav_oauth_apps,nav_accountsandnav_user_preferencesinsetup-nav.contributions.ts;nav_record_sharesinsharing-plugin.ts(about:591), declared on [PM seat] domain:services — 🟢 os-bill #6021. - Two enumeration pins, and platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960's pin stays green:
- (a) over every object a Setup or Account entry names: its first declared list view carries no
{current_user_id}filter; - (b) every Setup or Account object entry whose object declares a caller-scoped view names its
viewName.
- (a) over every object a Setup or Account entry names: its first declared list view carries no
- Generated translation catalogs and count pins that a
listViewsreorder moves are regenerated with the packages' own scripts. - ⛔ No new key, ⛔ no objectui change, ⛔ no
packages/specedit. - Stop conditions (triage): if a member's unscoped view returns rows the scoped one hid, that is an access defect, so stop and report it. If one of the seven objects declares no unscoped list view, report it and do not add one.
.changeset/21972-*.md(@objectstack/platform-objects, plus@objectstack/plugin-sharing, bothpatch).
Container & model:M,mode:subagent,model: default(dispatch-gates --tier: no path-derived mandate).
Clause-②: no- Navigation data and declared view order only. No exported type or contract accept set moves.
Thread-read: 6013830199
Serial constraints cleared: at 2026-10-06T10:29Z: - Triage's serial platform-objects: Setup → Users opens on the "My Profile" view — an admin sees one row (themselves, page size 1) instead of the user list #21960 closed
completedthrough PR fix(platform-objects): Setup → Users opens on the All Users list view #21971. - Open PRs (fix(service-datasource): the admin door reads a datasource's origin from provenance, and a metadata-door write reaches it in the same boot #21977, docs(spec, docs): App.defaultAgent and actions-as-tools name the agent route as the one chat door #21976, test(spec): the second api/ file group's test titles state each cited decision in words instead of a tracker number (stage 25) #21975, feat(spec)!: the build doors refuse a builtin node config value its executor contract refuses, with its location #21974, chore: version packages #21352), each file list read by
filename: none touchessetup-nav.contributions.ts,account.app.ts, any of the seven objects orsharing-plugin.ts. - This lane's other claims touch no file here: finding(metadata-protocol): a saved env-wide copy of a view container leaves its own expansion alone per name in the env-wide view list, so the anonymous form doors can miss another package's withdrawal, saved or shipped (#21934 item 1's residual) #21967 (
metadata-protocol), finding(service-datasource): a stored datasource row overrides a code-defined datasource at boot, so after a restart the admin door serves and edits it at runtime (restoreRuntimeDatasources has no code-collision check) #21922 (metadata-protocol, claimed this round) and [finding]sys_member.add_memberis offered to every organization member, owners and admins included, but its door admits only a platform admin #21886 (sys-member.object.ts, decision box). identity: the platform-admin-gated actions onsys_user,sys_oauth_applicationandsys_sso_providershow no standing term invisible— the affordance family's closing card, with an enumeration pin (after #21886's ruling) #21903 (blocked) namessys_useractions, a different region ofsys-user.object.ts.
objectstack-fleet commented on Oct 6, 2026
os-dev-report
{
"issue": 21972,
"status": "done",
"branch": "claude/issue-21972-caller-scoped-views-not-first",
"pr": "#21983",
"session": "session_017ErfyP2Rx7XWHJA27QjyUi (mode:subagent, the PM session id; identity is the branch)",
"premise_still_valid": true,
"summary": "On the seven objects (sys_user, sys_api_key, sys_session, sys_oauth_application, sys_account, sys_user_preference, sys_record_share) the unscoped 'All' list view is now declared first and the caller-scoped view (me / mine / granted_to_me) follows it; no view is added, removed or edited. The six Setup entries (nav_api_keys, nav_sessions, nav_oauth_apps, nav_accounts, nav_user_preferences in setup-nav.contributions.ts; nav_record_shares in sharing-plugin.ts:591) name that view with viewName, and the Account app's nav_account_linked (account.app.ts:160) names mine. Two enumeration pins (caller-scoped-first-list-view.test.ts, 29 cases) derive their population from SETUP_NAV_CONTRIBUTIONS and ACCOUNT_APP; both went red under reverse verification and were restored with blob equality. Draft PR #21983 at head a4d4688 (merge of origin/main dcf3eb4); eight generated translation bundles regenerated (pure reorders); two patch changesets.",
"per_object_table": [
"sys_user · sys-user.object.ts:603 · old first me → new first all_users (order all_users, me, unverified, two_factor, banned) · Setup nav_users viewName all_users (unchanged, from #21971) · no Account entry routes to sys_user",
"sys_api_key · sys-api-key.object.ts:121 · old first mine → new first all_keys (all_keys, mine, active, revoked) · Setup nav_api_keys viewName all_keys (setup-nav.contributions.ts:109) · Account nav_account_api_keys viewName mine (unchanged, account.app.ts:189)",
"sys_session · sys-session.object.ts:113 · old first mine → new first all_sessions (all_sessions, mine, revoked) · Setup nav_sessions viewName all_sessions (:146) · Account nav_account_sessions viewName mine (unchanged, :169)",
"sys_oauth_application · sys-oauth-application.object.ts:210 · old first mine → new first all_apps (all_apps, mine, active, disabled_apps) · Setup nav_oauth_apps viewName all_apps (:155) · Account nav_account_oauth_apps viewName mine (unchanged, :198)",
"sys_account · sys-account.object.ts:80 · old first mine → new first all_links (all_links, mine, by_provider) · Setup nav_accounts viewName all_links (:186) · Account nav_account_linked viewName mine (NEW, account.app.ts:160)",
"sys_user_preference · sys-user-preference.object.ts:36 · old first mine → new first all_preferences (all_preferences, mine, by_user) · Setup nav_user_preferences viewName all_preferences (:187) · no Account entry",
"sys_record_share · plugin-sharing/src/objects/sys-record-share.object.ts:46 · old first granted_to_me → new first all_shares (all_shares, granted_to_me, granted_by_me, by_object, manual_grants, rule_grants) · Setup nav_record_shares viewName all_shares (sharing-plugin.ts:591) · no Account entry"
],
"h1": "CONFIRMED. Each of the seven objects declares an unscoped list view, now first (table above). Each 'All' view carries no filter except all_sessions, whose only filter is revoked_at is_null. Stop condition 2 does not fire.",
"h2": "CONFIRMED (declarations read, no real-door read run). member_default RLS in packages/plugins/plugin-security/src/objects/default-permission-sets.ts: sys_api_key_self :921, sys_session_self :891, sys_oauth_application_self :955, sys_user_preference_self :915 (all user_id == current_user.id, operation all) and sys_account_self :897 (select) equal the mine predicate, so a member's All view returns exactly the rows mine returns. sys_user: sys_user_self :871 plus sys_user_org_members :885 (id in current_user.org_user_ids), so a member's All Users view returns the organization's users that me hid; that is the declared staff-directory policy (named as intended in that file's header), already reachable by the member through the existing All Users tab and GET /data/sys_user, and unchanged by this diff, so I read stop condition 1 as NOT met and say so for the seat to overrule (open_questions[2]). sys_record_share: member_default has no wildcard grant and names no sys_record_share permission, so a member reads no rows in either view; the Setup entry also requires manage_platform_settings.",
"h3": "CONFIRMED. Readers of the declared order in this repo: nav_account_linked was the only Account object entry naming no view (now mine; all six Account object entries name mine). After this change no platform-objects Setup entry names an object whose first view is caller-scoped (pin (a) enumerates them). packages/cli/src/commands/lint.ts:168 reads the first listViews key only to place a label diagnostic when no view has a label; every view here has one. sys-user.page.ts related lists (sessions, accounts, members, oauth apps, api keys) name no view and set showViewAll: true; how objectui's View all picks a view was not read (NOT MEASURED). system.datasets.ts reads sys_user / sys_session by object, not view. No test asserts a view index; setup-users-nav-view.test.ts and spec i18n-resolver.object-list-views.test.ts read views by name. objectui is out of scope; its views[0] fallback, breadcrumb and switcher are covered by the reorder.",
"h4": "CONFIRMED. pnpm check:i18n read 'platform-objects DRIFTED (4)' and 'plugins/plugin-sharing DRIFTED (4)'; node scripts/check-i18n-bundles.mjs --write regenerated packages/platform-objects/src/apps/translations/{en,es-ES,ja-JP,zh-CN}.objects.generated.ts and packages/plugins/plugin-sharing/src/translations/{en,es-ES,ja-JP,zh-CN}.objects.generated.ts: pure _views key reorders, +84/-84, no translated text changed; the other seven packages regenerated with no diff; check:i18n then exits 0. No count or order pin moved.",
"pins": "packages/platform-objects/src/apps/caller-scoped-first-list-view.test.ts, 29 cases. Population derived from every type:'object' entry of SETUP_NAV_CONTRIBUTIONS and ACCOUNT_APP (18 entries, 13 objects), resolved against this package's exports. (a) 11 cases: a named object's first declared list view carries no {current_user_id} anywhere in it. (b) 12 cases: an entry whose object declares a caller-scoped view names a viewName the object declares under that name, and a Setup entry's named view is not caller-scoped. 4 population/non-vacuity cases: both apps reached; the six reordered platform-objects objects judged by (a) and (b); unreadable named objects exactly [sys_inbox_message] (so (b) requires its entry to name a view, it names mine); objects declaring only caller-scoped views exactly [sys_member]. 2 parse cases: NavigationContributionSchema / AppSchema keep every object entry's viewName. #21960's setup-users-nav-view.test.ts stays green (7/7).",
"reverse_verification": "On committed f757947 via scripts/ablation-replace.mjs, directions predicted first (one red case each); subjects imported by relative path from src/, no dist/ in the path. (a) sys_session old order restored (literal swap of the adjacent all_sessions / mine blocks): anchor 1→0, replacement 0→1, blob 4e46fda0773c → 884ccaa2b537; result '1 failed | 28 passed (29)', failing case '(a) … sys_session': "sys_session declares the caller-scoped list view \"mine\" first"; restored blob 4e46fda0773c == HEAD, git diff HEAD empty, git status --porcelain empty. (b) "viewName: 'all_sessions', " deleted from nav_sessions: anchor 1→0, blob 17f1725c3cad → 2d7a16c6a894; result '1 failed | 28 passed (29)', failing case '(b) … setup nav_sessions → sys_session': 'nav_sessions names no view'; restored blob 17f1725c3cad == HEAD, git diff HEAD empty, porcelain empty.",
"tests": "At a4d4688 (after a full turbo build, 72 tasks): pnpm --filter @objectstack/platform-objects exec vitest run --maxWorkers=2 → 'Test Files 62 passed (62) / Tests 996 passed (996)'; pnpm --filter @objectstack/plugin-sharing exec vitest run --maxWorkers=2 → 'Test Files 40 passed (40) / Tests 980 passed (980)'; pnpm --filter @objectstack/platform-objects typecheck and pnpm --filter @objectstack/plugin-sharing typecheck → exit 0, check:test-typecheck OK; new test file is in the tsconfig.test.json program (--listFiles count 1, control setup-users-nav-view.test.ts count 1). ESLint narrowed to the 19 touched .ts files: 19 files, 0 errors, 0 warnings, none ignored (population: eslint.config.mjs packages/**/*.{ts,tsx,mts,cts} blocks; count from --format json; no parserOptions.project, so no verdict on an untouched file can move); repo-wide pnpm lint is CI's. Sharing half measured once by booting built plugins with a fake manifest ctx at a4d4688: 'nav_record_shares → sys_record_share | first=all_shares (unscoped) | viewName=all_shares (unscoped)'. Reverse verification: see reverse_verification.",
"gates": {
"sha": "a4d4688cfd",
"derived": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths): 66 commands, all 66 exit 0. --ran: '66 derived, 66 run, 0 NOT-MEASURED, 0 UNRUN' (derived zero: every line carried its exit code).",
"new_vs_dispatch_list": [
"node scripts/check-adr-0087-registration.mjs --base origin/main",
"node scripts/check-adr-0087-registration.mjs --self-test",
"node scripts/check-empty-changeset.mjs --base origin/main",
"node scripts/check-empty-changeset.mjs --self-test",
"node scripts/pm/release-rehearsal-clone.mjs --self-test",
"node scripts/release-pending-publish.mjs --self-test",
"pnpm check:engine-double-contract",
"pnpm check:objectql-double-limit",
"pnpm check:objectui-changeset",
"pnpm check:pm-changeset-deadline-census",
"pnpm check:query-options-erasure",
"pnpm check:type-check-coverage",
"pnpm check:type-check-debt",
"pnpm check:where-matcher"
],
"dispatch_list_not_derived": "none (all 52 dispatch-time commands are in the derived 66 and ran)",
"artifact_roster": "55 families, all run: 52 exit 0; check-closing-target-claim.mjs, check-partof-closing-keyword.mjs and check-single-claim-paths.mjs answered NOT WIRED (exit 2) without PR context, then exit 0 with it after PR #21983 opened (closing-target-claim: 'PR #21983 closes #21972, and each carries a Claim: whose Branch: line names claude/issue-21972-caller-scoped-views-not-first'; single-claim-paths: 'modifies none of the 1 declared at-most-one-writer path(s)'; partof-closing-keyword with PR_BODY: no contradiction).",
"symbol_anchor_sweeps": "pnpm check:adr-symbol-anchors, check:scripts-symbol-anchors, check:spec-docblock-symbol-anchors, check:adr-anchors: all exit 0.",
"note": "pnpm check:type-check-debt was killed once by my own batch timeout (no verdict), rerun alone: exit 0 in 221 s, '1 ledger entr(ies) re-measured … none above its recorded number'. pnpm check:i18n first refused exit 3 (CLI not built), ran after the full build.",
"ci": "in_progress — not awaited, per the dispatch contract."
},
"line_budget": "n/a",
"deviations": [
"Pin population is this package's own navigation (SETUP_NAV_CONTRIBUTIONS + ACCOUNT_APP). Plugin-contributed Setup entries (nav_record_shares, nav_approval_requests, …) are not visible from platform-objects, which cannot import the plugins, and the dispatch allows no third plugin-sharing file; the sharing half was measured once instead (tests field). A composed-population pin would live in packages/cli (domain:cli).",
"Pin (a)'s literal text covers every object a Setup or Account entry names; two cannot meet it without a new view: sys_member (declares only mine) and sys_inbox_message (service-messaging, unreadable from platform-objects; declares only mine). Both are pinned as exact sets and their Account entries name mine; no view was added (open_questions[1]).",
"sys_user's me comment: besides the order sentence, its claim that RLS stops non-admins reading other users' rows was corrected (member_default admits the organization's users via sys_user_org_members).",
"plugin-sharing: besides the two declared files, its four generated translation bundles changed (H4, required by check:i18n; pure reorders).",
"git push ran 4 times (empty-branch probe, two WIP commits, the merge of origin/main), all to the claimed branch, against one budget line.",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer; commits carry the model-free Claude-Session / Co-authored-by pair per AGENTS.md."
],
"files_changed": [
".changeset/21972-caller-scoped-views-not-first.md",
".changeset/21972-record-shares-all-first.md",
"packages/platform-objects/src/apps/account.app.ts",
"packages/platform-objects/src/apps/caller-scoped-first-list-view.test.ts",
"packages/platform-objects/src/apps/setup-nav.contributions.ts",
"packages/platform-objects/src/apps/translations/en.objects.generated.ts",
"packages/platform-objects/src/apps/translations/es-ES.objects.generated.ts",
"packages/platform-objects/src/apps/translations/ja-JP.objects.generated.ts",
"packages/platform-objects/src/apps/translations/zh-CN.objects.generated.ts",
"packages/platform-objects/src/identity/sys-account.object.ts",
"packages/platform-objects/src/identity/sys-api-key.object.ts",
"packages/platform-objects/src/identity/sys-oauth-application.object.ts",
"packages/platform-objects/src/identity/sys-session.object.ts",
"packages/platform-objects/src/identity/sys-user-preference.object.ts",
"packages/platform-objects/src/identity/sys-user.object.ts",
"packages/plugins/plugin-sharing/src/objects/sys-record-share.object.ts",
"packages/plugins/plugin-sharing/src/sharing-plugin.ts",
"packages/plugins/plugin-sharing/src/translations/en.objects.generated.ts",
"packages/plugins/plugin-sharing/src/translations/es-ES.objects.generated.ts",
"packages/plugins/plugin-sharing/src/translations/ja-JP.objects.generated.ts",
"packages/plugins/plugin-sharing/src/translations/zh-CN.objects.generated.ts"
],
"cleanup": "After this report is posted: rm -rf node_modules and git worktree remove ../objectstack-issue-21972 (no --force). No dev server or background process was started; no scratch file is in the repo.",
"mcp_calls": "0 — no MCP GitHub tool was called.",
"api_writes": "3 relay writes (fleet-write, as objectstack-fleet[bot]): POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft #21983, read-back 14449 bytes identical); POST /repos//issues/21983/assignees (label-write --assign os-project-manager, read-back matches); POST /repos//issues/21972/comments (this os-dev-report, via post-stamped). Plus git push ×4 (not REST). Reads only otherwise (REST GET of #21972 and its comments, #21960 comments, PR #21983, and the PR-context gates).",
"open_questions": [
{
"question": "One more family member is outside this card's lane: Setup → Approvals → Requests (nav_approval_requests, packages/plugins/plugin-approvals/src/approvals-plugin.ts:147) names no view, and sys_approval_request declares my_pending (pending_approvers contains {current_user_id}) first. PR #21983 says Fixes #21972, which closes the card with this member open. How should it be carried?",
"options": [
"A — keep Fixes #21972; the seat files a domain:services follow-up (reorder all_requests first, nav_approval_requests names all_requests, extend the pin where the composed population is visible).",
"B — change the PR to Part of #21972 and keep this card open for the approvals member."
],
"recommendation": "A, because triage ruled the seven objects and the dispatch forbids anything else in domain:services; the eighth is the same mechanical fix in another lane and reads cleanest as its own card rather than holding this one open."
},
{
"question": "sys_member and sys_inbox_message declare only caller-scoped list views (mine), so pin (a) cannot hold for them without a new view. Only Account entries name them, and those entries name mine. Should they gain an unscoped view?",
"options": [
"A — no: leave them as the pinned exact set; both are Account-only self-service objects, RLS scopes their rows, and every entry names its view.",
"B — yes: add an unscoped "All" view to each and declare it first (a new authored view; triage decides per object)."
],
"recommendation": "A, because nothing administers these objects from Setup today and an extra view would be capability without a reader; the exact-set pin makes a third such object loud."
},
{
"question": "Stop condition 1, on sys_user: a member's unscoped All Users view returns their organization's users, which me hid. I read it as not an access defect (declared sys_user_org_members staff-directory policy, already reachable via the existing tab and GET /data/sys_user, unchanged by this diff) and continued. Does the seat agree?",
"options": [
"A — agree: not a stop; the policy is declared and the order change grants nothing.",
"B — disagree: treat it as stop condition 1 and pull sys_user from this PR."
],
"recommendation": "A, because the order decides which view opens and the rows come from a declared, intended policy rather than a missing one."
}
],
"out_of_scope_findings": [
"class: a · reach: Setup → Approvals → Requests (nav_approval_requests) opens sys_approval_request's first declared view my_pending, so an administrator sees only requests pending on themselves; measured by booting built @objectstack/plugin-approvals with a fake manifest ctx at a4d4688: 'setup/nav_approval_requests | sys_approval_request | order=[my_pending,submitted_by_me,completed,all_requests] | first=my_pending (CALLER-SCOPED) | viewName=-' · same family as #21972, so it goes to the family carrier, not a single card (open_questions[0]) · lane domain:services · dedupe: Setup Approvals Requests opens My Pending · nav_approval_requests caller-scoped first list view · sys_approval_request my_pending first · admin sees only own pending approvals",
"carrier: PM (domain:cli) · a composed-population version of pins (a)/(b) over the runtime-merged Setup and Account apps, booted the way packages/cli/scripts/check-app-nav-i18n.mjs boots its roster, would cover plugin-contributed entries and would have caught nav_approval_requests · noted, not filed",
"carrier: triage · sys_member and sys_inbox_message declare only caller-scoped views (open_questions[1]) · noted, not filed"
]
}
Generated by Claude Code
objectstack-fleet commented on Oct 6, 2026
Landed: PR #21983 → 1c563af40e on main. It merged through the merge queue at 2026-10-06T12:31Z; it entered the queue at 2026-10-06T12:06Z. Verified at 2026-10-06T12:32Z. domain:engine#1 · session_017ErfyP2Rx7XWHJA27QjyUi.
- The squash: it is on
origin/mainas a single-parent commit. Its diffstat is the reviewed one: 21 files, +433/-166. - What is on
main:- On
sys_user,sys_api_key,sys_session,sys_oauth_application,sys_account,sys_user_preferenceandsys_record_share, the unscoped "All" list view is declared first and the caller-scoped view follows it. - The six Setup entries name their unscoped view, and
nav_account_linkednamesmine. - Two enumeration pins keep the rule. The first declared view of any object a Setup or Account entry names is never caller-scoped. Every entry whose object declares a caller-scoped view names its view.
- On
- The card:
Fixes #21972closed this card ascompleted.pm:dispatchedis removed in this act. No other card was closed by the body. - From this release (
@objectstack/platform-objectsand@objectstack/plugin-sharingpatch,Clause-②: no): an administrator's Setup identity pages open on the tenant-wide list. The bare-object doors (breadcrumb, switcher) no longer land on a one-row view either. - The seat's answers to the dev's questions are on PR fix(platform-objects): Setup identity pages open on the tenant-wide list; a caller-scoped list view is never first #21983 (6015840711).
- Stop condition 1 on
sys_userwas read as not met: the rows come from the declared staff-directory policysys_user_org_members. Triage may overrule.
- Stop condition 1 on
- Filed from this card: finding(plugin-approvals): Setup → Approvals → Requests opens sys_approval_request's caller-scoped first view my_pending, so an administrator sees only requests pending on themselves (#21972's eighth family member) #21984, the eighth member: Setup → Approvals → Requests,
domain:services.
Generated by Claude Code
Filing gate: ① a reproducible defect, class (a): the family-closure card for #21960. It is filed from the dev's report on #21960 (PR #21971:
open_questions[0], where the seat takes option A, andout_of_scope_findings). Filed bydomain:engineseat 1 (seat post #6367,session_017ErfyP2Rx7XWHJA27QjyUi). ⛔ Not graded or routed here. ⛔ Not a claim.Mechanism (measured by #21960's dev; read from source, not in a browser)
isDefault/ primary list view, or else its FIRST declared list view. The source is objectuipackages/app-shell/src/views/ObjectView.tsx:2151at the.objectui-shapin0abd4f9f87:activeViewId = resolvedViewId || defaultViewId || views[0].lint-view-refs.ts:46–:56records the same fallback.viewName: 'all_users'onnav_users. The same shape remains on other Setup entries, and onsys_user's bare-object routes.Members (positions at
main, from the dev's report)nav_api_keys(setup-nav.contributions.ts:108)sys_api_keymine(user_id = {current_user_id})mineexplicitly (account.app.ts:188–:189)nav_sessions(:145)sys_sessionminemine(account.app.ts:168–:169)nav_oauth_apps(:154)sys_oauth_applicationminemine(account.app.ts:197–:198)nav_accounts(:185)sys_accountminenav_account_linked(account.app.ts:157) names NO view and relies on this order. A fix must nameminethere first.nav_user_preferences(:186)sys_user_preferenceminenav_record_shares(packages/plugins/plugin-sharing/src/sharing-plugin.ts:591)sys_record_sharegranted_to_me(recipient_id = {current_user_id})AppHeader.tsx:434) and object switcher (:367)sys_userme(still first after PR #21971)Direction (the dev's options; triage decides per object)
listViews, or both.nav_account_linkedis the known case.viewNameis already declared (packages/spec/src/ui/app.zod.ts:432).Reader who acts
Triage grades it. The Setup and Account entries and the
listViewsorder areplatform-objects(domain:engine).sharing-plugin.tsisdomain:services. The AppHeader doors are objectui's.Serial: PR #21971 (#21960) edits
setup-nav.contributions.tsandsys-user.object.ts.Dedupe: MCP
search_issues, repo-scoped: 「Setup navigation entry opens caller-scoped first list view mine admin sees only own rows」 returned #21960 (this family's first card), #16885 and #14108 (closed, different mechanisms). None is this.Dedupe words:
Setup nav entry opens mine view first·caller-scoped default list view·admin sees only own rows·first declared list view defaultGenerated by Claude Code