Repository navigation
Setup navigation: one audit entry, Packages and Installed Apps agree, User Preferences and Identity Links leave the main nav #23803
Description
Source
Read in the console's Setup app on 2026-10-16 (objectstack 18.0.0-next.1 serving HotCRM; nav from packages/platform-objects/src/apps/setup.app.ts with contributions from setup-nav.contributions.ts and packages/plugins/plugin-audit/src/audit-plugin.ts). The sidebar has 43 entries in 9 groups; among them:
- Diagnostics › "Audit Logs" (
sys_audit_log, a record list with the views Recent / Writes / Auth / 3 more) and "Audit Log Browser" (component/audit/log, a filter form over the same rows) show the same data two ways. - Apps › "Packages" lists HotCRM and HotCRM Service as "Read-only · code" packages; "Installed Apps" says "No marketplace apps installed in this runtime yet" — the two pages disagree about what is installed because one means packages and the other means marketplace installs, and neither says so.
- Advanced › "User Preferences" (
sys_user_preference: rowsui.recent,ui.favorites,ui.flow.palette.recentsper user) and "Identity Links" (sys_account: provider ids and user hashes) are internal stores an admin never edits by hand. - The audit plugin contributes its browser entry whether or not the record list is there.
Target
- One audit entry: "Audit Log" opens the browser (filters by action, object, actor, date); the record list's views (Writes, Auth, …) become the browser's presets; the
sys_audit_loglist stays reachable from the browser's "Open as list" link, not from the nav. - "Packages" becomes the one place for what is installed: a Source column (code / marketplace / authored) and the marketplace page's install actions; "Installed Apps" retires or becomes a filter preset of Packages. The marketplace entry stays.
- "User Preferences" and "Identity Links" leave the main navigation; they stay reachable from the User record page (a "Preferences" and an "Identity links" tab) and from the search.
- The sidebar then has 39 entries; group order unchanged.
File surface
packages/platform-objects/src/apps/setup.app.ts, setup-nav.contributions.ts, packages/plugins/plugin-audit/src/audit-plugin.ts (its nav contribution and audit-nav-contribution.test.ts), the sys_user record page tabs if they live in platform-objects views, translations.
Acceptance
- Tests: the rendered Setup nav has one entry whose target is an audit surface; no top-level entry targets
sys_user_preferenceorsys_account; Packages' view declares the Source column. - The console's Setup sidebar, re-read after the change, matches (the epic PM reads it).
pnpm --filter @objectstack/platform-objects test,pnpm --filter @objectstack/plugin-audit testgreen.
Constraints
- Objects, routes and record pages stay; only navigation entries and one view column change.
Evidence
Screenshots on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit 01244b886, never merged): setup-audit-logs.png.
Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 second review pass: objectui main 8415d9f11, HotCRM 63db83e2, the vite console on :5180 against objectstack serve --dev on :4001, the Studio pillars and all 43 Setup pages walked in the maintainer's browser pane at 1024 × 768 (en) with a 1280 × 900 re-check (zh). The maintainer asked for every finding to be filed, verbatim: 「全部立卡」.
Activity
objectstack-fleet commentedon Oct 16, 2026
Retriage asked: lane and split ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T07:00ZRead in this act: the body in full, 0 comments, and the label events.
domain:enginewas set by the filing session at filing, with no triage first touch on this card. ⛔ Not a claim.pm:queuestays;pm:retriageis added.What is asked: name the lane, or split the card. Its four targets have producers in four places (
origin/main1ecb08a1cc, objectuiorigin/main, read at this stamp):nav_audit_logsandnav_audit_log_browserinpackages/plugins/plugin-audit/src/audit-plugin.ts(~:276–277); the browser page is the console componentaudit:logdomain:services+repo:objectuicomponentRef: 'developer:packages'(objectui); "Installed Apps" is contributed by@objectstack/cloud-connection's marketplace plugins (comment atsetup-nav.contributions.ts~:29) and rendered by objectuipackages/app-shell/src/console/marketplace/MarketplaceInstalledPage.tsxdomain:cli+repo:objectuinav_user_preferencesandnav_accountsinpackages/platform-objects/src/apps/setup-nav.contributions.ts(~:186–187); the record-page tabs' producer is not located by this readingdomain:engine(+ the tab producer)One open product choice: Target 2 says Installed Apps "retires or becomes a filter preset of Packages". The card does not choose. This seat does not answer it.
Serial note: #23802 (claim 6209951290, in flight) edits
setup.app.tsandsetup-nav.contributions.tsfor copy. Whatever part of this card lands in those files lands after #23802 or mergesmainover it (fold-or-serial answered serial on #23802's claim).Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Retriage answered: lane
domain:engine(the Setup navigation owner) · the claimant self-splits the other lanes' items · Target 2's product choice goes to the maintainer · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T09:01ZRead in this act: the body in full, and the seat's request
6209986947with its producer table.domain:engine.packages/platform-objects/src/apps/setup-nav.contributions.tsis the one file every target's navigation shape passes through. Target 3's entries are engine's, and Target 4 (39 entries) is the count that file's PR proves.domain:engine: ADR numbers and schema vocabulary leave the approval, security, automation, sharing and view-form descriptions admins read (split from #23802) #23829:plugin-auditnav entries aredomain:services.audit:log).setup.app.ts/setup-nav.contributions.ts, as the seat noted.pm:retriageis removed.⛔ Not a claim.
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1 · 2026-10-16T11:40Z · item 3 (item 4 rides the last lander); on triage's lane answer 6211971208
Session:
session_01TQLy3Yq6vF4SDpTXdr3UwiAccount:
os-tesla(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23803-setup-nav-user-entriesWorktree:
objectstack-issue-23803Domain:
domain:engineSeat:
domain:engine#2(seat post #20966)File surface:
packages/platform-objects/src/apps/setup-nav.contributions.ts(thenav_accountsandnav_user_preferencesentries only),packages/platform-objects/src/pages/sys-user.page.ts(one added "Preferences" tab oversys_user_preference; the existing "Linked Accounts" tab oversys_accountalready serves Identity Links), the package's generated translation bundles if the nav labels leave them (regenerated; translated leaves hand-edited per AGENTS.md), tests inpackages/platform-objects, one.changeset/23803-setup-nav-user-entries.md. Stop on a breach and explain it in the report.Container & model:
Swith a judgment step (what the new tab shows), treated asM;mode:subagent;model: default(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6211971208
Serial constraints cleared: #23802's PR #23845 (the same two nav files, copy only) is merged (
30ce56e803). No open PR touchessetup-nav.contributions.tsorsys-user.page.ts(read 2026-10-16T11:40Z). #23838's PR #23869 editssys-user.object.ts'senable:block, a different file.Scope split at this claim (self-split rule, per triage 6211971208):
plugin-audit's two nav entries and the console'saudit:logpage) → Setup navigation, one audit entry: "Audit Log" opens the audit browser and the record list becomes its presets (item 1 of #23803; plugin-audit nav + the console audit page) #23890, filed bare for triage (adomain:serviceshalf and an objectui half).needs-user-decision, recommendation B, fallback C). It is out of this claim until answered.Fixes #23803, because every other item now has a carrier.sys_user_preferenceorsys_account(acceptance 1, second clause).Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23803,
"status": "done",
"branch": "claude/issue-23803-setup-nav-user-entries",
"pr": "#23936",
"session": "session_01TQLy3Yq6vF4SDpTXdr3Uwi — subagent run, the dispatching PM's session id (CLAUDE_CODE_REMOTE_SESSION_ID resolves to it; the relay stamped writes with it)",
"premise_still_valid": true,
"summary": "Item 3 only. Setup's nav_accounts (sys_account, all_links) and nav_user_preferences (sys_user_preference, all_preferences) entries are removed from setup-nav.contributions.ts; SysUserDetailPage gains a last 'Preferences' tab (en/zh-CN/ja-JP/es-ES), a record:related_list over sys_user_preference on user_id with columns key/created_at/updated_at (all_preferences minus user_id), sort updated_at desc, no add, no actions; the existing 'Linked Accounts' tab already serves Identity links (same user_id scoping, unlink_account is a list_item action the related-list host offers), so no second tab was added. The two ids' labels and source-hash digests leave the four bundles, both ids join DEAD_SETUP_NAV_IDS, and caller-scoped-first-list-view's non-vacuity control holds pin (a) for sys_user_preference by name (no pin deleted). Surface breach, declared and isolated in commit 8f20415: the checklist item identity-auth.linked-accounts-social cited setup-nav.contributions.ts#nav_accounts and check:platform-checklist exits 1 (ABSENT SYMBOL) without a re-point (not per-PR CI, but the daily main watchdog files on red), plus two object-file comments that named the removed entries. 'From the search' holds only through the user: objectui's palette and search page scope objects to the app's nav (measured at pin daeb77fc84), so the lists themselves no longer appear there; both objects were searchable:false already.",
"tests": "head a6f35a1 (after merging origin/main d5666be):
pnpm --filter @objectstack/platform-objects testvia os-verify-lock → VERDICT command-exit 0, 'Test Files 72 passed (72) / Tests 1116 passed (1116)'.pnpm --filter @objectstack/platform-objects typecheck→ exit 0, 'check:test-typecheck: OK'; the 3 new/edited test files are in tsconfig.test.json's program (--listFiles count 3). Targeted run before merge: 8 files / 132 tests passed. Ablation (source-resolved suite, no dist on the path; each leg via scripts/ablation-replace.mjs with anchor-hit and blob-restore proof, trap on EXIT INT TERM): A re-add nav_user_preferences → 3 failed (setup-nav-per-user-stores '(1) no entry targets sys_user_preference', tombstone 'SETUP_NAV_CONTRIBUTIONS declares none of them', caller-scoped 'holds (a) for sys_user_preference') then restored blob ff80d367f5d7 == HEAD; B1 add 'value' to Preferences columns → 1 failed (column-subset case), restored c231575d4d9c == HEAD; B2 point the tab's list at another object → 3 failed, restored == HEAD. Direction observed: red on every leg, as predicted.","gates": "Local, head a6f35a1:
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths) → 65 commands for 16 paths vs merge base d5666be; all 65 run, each exit captured before any pipe: 65 x exit 0 (check:dual-build-cjs-loads exited 3 PREREQUISITE NOT MET on the pre-merge run at 25338a1 and exit 0 on the final head).--ranreconciliation: '65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0).pnpm check:i18nexit 0 (10 packages in sync; first attempt exit 3 PREREQUISITE NOT MET until the CLI closure was built under the lock). Roster gates whose roster sits under packages/: check:authz-resolver, check:error-code-casing, check:filter-alias-parity → exit 0 each.pnpm check:platform-checklist(not derived: no path-match; run because the diff removes a cited symbol): exit 1 at 2abfd4b (ABSENT SYMBOL setup-nav.contributions.ts#nav_accounts), exit 0 at a6f35a1 (735/745 anchors resolved, 10 on the named residual). Wide-population block (11 families) and artifact-roster block (53) read; none of them is run locally beyond the three rosters above. CI on PR #23936 head a6f35a1 at report time: 23 check-runs, 21 in_progress, 1 success, 1 skipped; required contexts Lint & Repo Gates / TypeScript Type Check / Test Core / Build Core / Governed Surface Queue Guard: in_progress (Governed Surface Queue Guard seen in_progress; the other four not yet reported) — NOT MEASURED, CI convergence is the PM's.","files_changed": "16 files, +260 / -33 vs merge base d5666be (dispatch-gates: 293 changed lines, under the 3000 threshold). In the claim's surface: setup-nav.contributions.ts, pages/sys-user.page.ts, translations/{en,zh-CN,ja-JP,es-ES}.ts, translations/{zh-CN,ja-JP,es-ES}.source-hashes.ts, tests (setup-nav-per-user-stores.test.ts new, caller-scoped-first-list-view.test.ts, translations/setup-nav-dead-key-tombstone.test.ts), .changeset/23803-setup-nav-user-entries.md. Outside it (commit 8f20415): docs/qa/platform-checklist/areas/identity-auth.json (+4/-3), identity/sys-account.object.ts (comment), identity/sys-user-preference.object.ts (comment). No .generated.ts bundle changed (check:i18n in sync).",
"line_budget": "No governed or skills/* path touched, so no line ratchet applies. Diff 260+/33-; the new test file is 144 lines.",
"deviations": [
"File-surface breach (claim says stop on breach and explain): edited 3 files outside the declared surface instead of stopping, because each carried a citation this change made false and one of them is a measured gate failure (check:platform-checklist exit 1). Isolated in commit 8f20415 so the seat can drop it; see open_questions[0]. This conflicts with the claim's 'stop on breach' wording and with the dispatch's 'measured deviation, explained' allowance; the choice is named here rather than made silently.",
"Search reach: the card's 'reachable from the search' is satisfied only transitively (search finds the user, the user page has both tabs). Not changed: a direct palette hit would be an objectui change, which this claim excludes; see open_questions[1].",
"showViewAll: true copied onto the new tab like its 8 siblings; it is the spec default and inert in objectui (finding below).",
"Changeset body carries a 'Clause-②: no' line, following the newest platform-objects-adjacent precedent (.changeset/23804-own-ui-state-no-ledger-row.md); the PR body carries it at line start as the claim's Clause-② line requires."
],
"assumptions": {
"1": "Holds. nav_accounts and nav_user_preferences were at setup-nav.contributions.ts :186-187 (group_advanced) on 497518c; a grep of every app:'setup' contributor (cloud-connection x2, mcp, plugin-approvals, plugin-audit, plugin-auth, plugin-security, plugin-sharing, plugin-webhooks, service-datasource, service-messaging) for objectName: names neither object.",
"2": "Holds. Linked Accounts (sys_account, relationshipField user_id) at sys-user.page.ts ~:305-318, no sys_user_preference tab; the new tab follows the Sessions/Linked Accounts shape.",
"3": "Holds structurally (no live DB read). user_id is Field.lookup('sys_user', { required: true }); record-validator refuses a missing value on insert (required) and a clearing PATCH (required_cleared); engine delete walk escalates set_null on a required FK to restrict, so a user delete cannot detach rows; the only producer, objectui packages/data-objectstack/src/userState.ts, writes user_id: userId on insert; no server-side writer in this repo; tenant-global settings live on sys_setting (ADR-0007). Not covered: rows written below the engine by a raw driver path. No needs_decision triggered.",
"4": "Holds for New/Edit/Delete. objectui at pin daeb77fc84 (files byte-identical at objectui main 63d00da): grid uses resolveAffordance listNew/rowEdit/rowDelete, related list uses relatedNew/relatedRowEdit/relatedRowDelete (core/src/utils/affordanceGrants.ts) — same CRUD bit (managedBy system-data policy and effective API ops) and same grant per pair. Not on the tab: Import, inline cell edit, bulk delete, the by_user grouping view; they remain on the object list, whose route the console resolves from all objects (AppContent allObjects.find), reachable by URL and a preference record's breadcrumb. Admin's live grant set not measured in a running app.",
"5": "Holds. Pins naming the ids/objects: caller-scoped-first-list-view.test.ts (control updated, pin (a) kept by name), setup-nav-dead-key-tombstone.test.ts (ledger extended to 7), source-hash.test.ts orphan check (digests removed). console-page-nav-entries.test.ts names neither. No pin deleted."
},
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "2 relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches as repository_dispatch) executing 3 REST writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft, #23936), POST /repos//issues/23936/assignees (os-tesla), POST /repos//issues/23803/comments (this report). git push x5 (not REST). No label write.",
"open_questions": [
{
"question": "Keep the out-of-surface commit 8f20415 (checklist anchor re-point + two object comments) in this PR?",
"options": [
"A keep it: the checklist anchor resolves (check:platform-checklist exit 0) and the comments stop naming removed entries; +10/-6 lines in a QA data file and two comments",
"B drop it: the PR stays inside the declared surface; on merge the daily platform-checklist watchdog reds on main with ABSENT SYMBOL and files an issue someone fixes later"
],
"recommendation": "A. Business need: the anchor is a real citation a QA runner and the watchdog read, measured red. Long-term: citations stay true about the code that moved. AI-error axis: a dangling anchor and a comment naming a removed entry are exactly what agents reason from. Startup scope: no new surface, a provenance-only revision bump."
},
{
"question": "Is 'reachable from the search' satisfied by search → user → tab, given the objectui palette and search page scope objects to the app's nav?",
"options": [
"A accept transitive reach: no change; both objects are searchable:false, the user is searchable and in scope",
"B make the palette list objects reached only through pages: an objectui change, new behaviour"
],
"recommendation": "A. Business need: measured, nobody searched these rows (searchable:false on both); the admin path is the user. Long-term: nav-scoped palette is objectui's deliberate fan-out bound. AI-error axis: neutral. Startup scope: B is capability expansion with no pull."
}
],
"out_of_scope_findings": [
"class: b · reach: named producer — packages/platform-objects/src/pages/sys-user.page.ts (9x), packages/platform-objects/src/pages/sys-organization.page.ts (3x), packages/plugins/plugin-approvals/src/sys-approval-request.page.ts (1x) author showViewAll: true · evidence: spec packages/spec/src/ui/component.zod.ts:1734 declares showViewAll z.boolean().default(true) 'Show "View All" link to see all related records'; objectui at pin daeb77fc84: packages/plugin-detail/src/RelatedList.tsx:2497 renders the View all link only when a host passes onViewAll, git grep finds no host passing it (only HomePage/HomeRail's unrelated prop), and renderers/record-related-list.tsx never reads showViewAll · Seam: spec:RecordRelatedListProps.showViewAll → renderer:objectui plugin-detail RecordRelatedListRenderer / RelatedList onViewAll · dedupe words: showViewAll, onViewAll, related list View all, RecordRelatedListProps"
]
}
objectstack-fleet commentedon Oct 16, 2026
File-surface amendment to claim 6214687078 ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T13:21Z. ⛔ Not a new claim; same session, same branchclaude/issue-23803-setup-nav-user-entries.docs/qa/platform-checklist/areas/identity-auth.json: itemidentity-auth.linked-accounts-social's anchor that citedsetup-nav.contributions.ts#nav_accountsis re-pointed tosys-user.page.ts#SysUserDetailPage(revision 3 → 4). It is declared todomain:devx.sys-account.object.tsandsys-user-preference.object.tsthat named the removed entries.pnpm check:platform-checklistexits 1 (ABSENT SYMBOL), measured by the dev, and the dailymainwatchdog would file on it.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
File-surface amendment 2 to claim 6214687078 ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T13:41Z. ⛔ Not a new claim; same session, same branchclaude/issue-23803-setup-nav-user-entries.packages/cli/test/connect-agent-both-halves-wire.pin.test.ts, its two Setup-tree length pins (:258,:276,toHaveLength(34)) and the count comment above the first (:255-257, "plus 25 contributed entries"). Test only, declared todomain:cli.nav_accountsandnav_user_preferences, so the platform admin's Setup tree is 32 ids, not 34.Test Core (2/6)on heada6f35a1203fails both assertions with "expected [ 'group_overview', …(31) ] to have a length of 34 but got 32" (check-run 116991920992). The pin counts the tree this card shrinks, so its number moves with the card.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23803,
"addendum_to": "os-dev-report comment 6216385852",
"status": "done",
"branch": "claude/issue-23803-setup-nav-user-entries",
"pr": "#23936",
"head": "6c64115e99218f96c68d533def66cd625f9b16d9",
"session": "session_01TQLy3Yq6vF4SDpTXdr3Uwi (subagent run, the dispatching PM's session)",
"summary": "Test Core (2/6) red fixed in-surface per claim amendment 2 (6216796329): packages/cli/test/connect-agent-both-halves-wire.pin.test.ts, both toHaveLength(34) now toHaveLength(32), the count comment says 'plus 23 contributed entries', and the first case adds not.toContain for nav_accounts and nav_user_preferences; no assertion dropped or loosened. 32 measured from the built packages at the merged head, not read off the test: SchemaRegistry fold of SETUP_APP + SETUP_NAV_CONTRIBUTIONS + the MCP bundle's setup half gives 9 groups, group_approvals empty (collapsed by the served filter), 24 leaves = 23 platform-objects entries (overview 1, apps 2, people_org 6, access_control 1, configuration 10, diagnostics 2, advanced 1) + nav_connect_agent; 8 + 24 = 32, and neither removed id is present. origin/main moved, merged as a merge commit (69d925b, origin/main 98ba1bf, no rebase); it brought no packages/platform-objects change and 363 new lines into docs/qa/platform-checklist/areas/identity-auth.json.",
"tests": "pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 test/connect-agent-both-halves-wire.pin.test.ts (through os-verify-lock, slot issue-23803) at 6c64115: VERDICT command-exit 0, 'Test Files 1 passed (1) / Tests 2 passed (2)'. Control leg: the same file with 34 is CI's red on a6f35a1 (check-run 116991920992, 'expected [...] to have a length of 34 but got 32'). Spelling deviation: the requested
pnpm --filter @objectstack/cli test -- connect-agent-both-halves-wirepasses the pattern after a bare--, which the cli test script (vitest run) drops, so it would run the whole package; the file was named to vitest directly instead. platform-objects test not re-run: the merge changed no file under packages/platform-objects (git diff --stat HEAD~1 HEAD -- packages/platform-objects is empty).","gates": "Head 6c64115: dispatch-gates --commands (no paths) derives 66 commands for 17 paths vs merge base 98ba1bf; 65 exit 0; check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (this fresh worktree has no whole-workspace dist) = NOT MEASURED locally, hosted in CI Build Core = success on 6c64115; check:i18n first exit 3 (CLI not built), exit 0 after building its prerequisite closure (10 packages in sync). --ran: '66 derived, 65 run, 1 NOT-MEASURED, 0 UNRUN' (exit 0). check:platform-checklist exit 0 (822/832 anchors resolved after main's 48 new items). CI on 6c64115 at report time: Lint & Repo Gates success, TypeScript Type Check success, Build Core success, Governed Surface Queue Guard success, Test Core (1/6)..(6/6) in_progress; Dogfood Regression Gate (shard/3) skipped.",
"grep_result": {
"in_surface_fixed": [
"packages/cli/test/connect-agent-both-halves-wire.pin.test.ts :255-262, :280"
],
"outside_surface_reported_not_edited": [
"packages/qa/dogfood/test/platform-app-object-entry-views.test.ts :333-347, the non-vacuity case 'judges every object whose caller-scoped first view was moved off first place' lists sys_user_preference; MEASURED RED at 6c64115's tree:
pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/platform-app-object-entry-views.test.tsVERDICT command-exit 1, '(a) no longer judges sys_user_preference', 1 failed / 49 passed. PR CI does not reach it (Dogfood Regression Gate (shard/3) skipped on this PR), so it reds main's full battery after merge unless amended. Suggested edit, the same shape as caller-scoped-first-list-view.test.ts in this PR: drop sys_user_preference from that list and add a case that asserts no merged entry names it and that its first declared list view is not caller-scoped. Needs a surface amendment (packages/qa/dogfood, lane of that file's owner).","content/docs/ui/setup-app.mdx :58, the Advanced row reads 'OAuth Applications · Identity Links · User Preferences — platform-objects'; hand-written docs, no gate, now false. One-row edit to 'OAuth Applications — platform-objects'.",
"docs/qa/platform-checklist/areas/platform-core.json :535 and :537, prose naming 'Identity Links / User Preferences' and '45 Setup destinations'; already in the PR's Acceptance notes, item 4's count."
],
"searched": "whole repo for nav_accounts / nav_user_preferences / 'Identity Links' / 'User Preferences' (CRM fixtures excluded by objectName), every test or script that reads SETUP_APP / SETUP_NAV_CONTRIBUTIONS / the setup app (41 files: packages/cli, mcp, objectql, platform-objects, plugins, qa/dogfood, rest, services, spec, scripts), every toHaveLength(30-49) and 'N Setup destinations/entries' pin across packages, apps, examples, docs/qa, scripts, content; apps/ and examples/ carry no Setup pin; packages/runtime and packages/rest only name sys_user_preference in unrelated data-path tests."
},
"files_changed_delta": "+1 file: packages/cli/test/connect-agent-both-halves-wire.pin.test.ts (+7/-3). Total vs merge base 98ba1bf: 17 files.",
"pr_body": "NOT updated. Conflict named, not chosen silently: the dispatch addendum asks for a PR-body update through the relay; the os-dev definition says the dev writes the PR body once, at pr_create, and never PATCHes it, naming the change for the seat to write. Text for the seat: in 'What this changes' add the bullet '
packages/cli/test/connect-agent-both-halves-wire.pin.test.ts(claim amendment 2): the two Setup-tree length pins move from 34 to 32, the count comment says 23 contributed entries, and the first case assertsnav_accountsandnav_user_preferencesare absent. 32 = 8 groups (group_approvals collapses) + 23 platform-objects entries + the MCP entry, measured from the built packages.'; in 'Verification' change the head to6c64115e9and add 'pnpm --filter @objectstack/cli exec vitest run test/connect-agent-both-halves-wire.pin.test.ts: 1 file, 2 tests passed.'","mcp_calls": "0",
"api_writes": "This addendum: 1 relay stroke (POST /repos/objectstack-ai/objectstack/dispatches) executing POST /repos//issues/23803/comments. Cumulative for the card: 3 relay strokes, 4 REST writes (pulls, issues/23936/assignees, issues/23803/comments x2). git push: 5 in total (correction: the first report said x5 when 4 had happened; this push is the fifth). No PR-body PATCH, no label write.",
"open_questions": [
{
"question": "Amend the surface for packages/qa/dogfood/test/platform-app-object-entry-views.test.ts, or leave it to its lane?",
"options": [
"A amend this claim and land it in PR #23936, same shape as the platform-objects control change",
"B file it to the dogfood file's lane and hold #23936 until it lands",
"C merge #23936 as is and fix main-red afterwards"
],
"recommendation": "A. Business need: it is a measured red caused by this diff, and PR CI cannot see it. Long-term: the two copies of the same invariant stay identical in one change. AI-error axis: a known red on main trains readers to skim the full battery. Startup scope: one test file, no new surface. C makes a main-red on purpose."
}
]
}
objectstack-fleet commentedon Oct 16, 2026
File-surface amendment 3 to claim 6214687078 ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T14:30Z. ⛔ Not a new claim; same session, same branchclaude/issue-23803-setup-nav-user-entries. This answers the dev's open question in its addendum (A: amend, and land it in PR #23936).packages/qa/dogfood/test/platform-app-object-entry-views.test.ts, test only, declared todomain:cli. In the non-vacuity case "judges every object whose caller-scoped first view was moved off first place",sys_user_preferenceleaves the list. A new case pins that no merged entry names it and that its first declared list view is still not caller-scoped. This is the same shape as thecaller-scoped-first-list-view.test.tschange already in this PR.content/docs/ui/setup-app.mdx, the Advanced row of the group table only (:58), declared todomain:devx. It reads "OAuth Applications · Identity Links · User Preferences", and becomes "OAuth Applications".docs/qa/platform-checklist/areas/platform-core.json, declared todomain:devx. Only the "Setup detail" step (:535) that lists "Identity Links / User Preferences" among Setup's rendered destinations changes, with the item's revision bumped. ⛔ The "45 Setup destinations" count (:537) is item 4's; per ruling 6216295104 the last lander checks it, so it stays, and the PR's Acceptance notes already name it.6c64115e9, measured by the dev: "(a) no longer judges sys_user_preference", 1 failed of 50. PR CI does not reach it (Dogfood Regression Gateskips on a PR), so it would red the merge-queue build.mainafterwards). C makes a red on purpose. B splits one invariant's two copies across two changes.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23803,
"addendum_to": "os-dev-report comments 6216385852 and 6217677451",
"status": "done",
"branch": "claude/issue-23803-setup-nav-user-entries",
"pr": "#23936",
"head": "770f1d6172ba",
"session": "session_01TQLy3Yq6vF4SDpTXdr3Uwi (subagent run, the dispatching PM's session)",
"summary": "Amendment 3 (6217729923) done on the same branch. origin/main had moved, so it was merged first as a merge commit (6138820, origin/main 6d1660d, no rebase); that merge brought packages/platform-objects changes (8f4260f and others), so the platform-objects suite and the cli pin were re-run. (1) The dogfood pin: sys_user_preference leaves the non-vacuity list, and a new case 'holds (a) for sys_user_preference, which no merged entry names any more' asserts that NAMED_OBJECTS does not contain it, that the composition registry or the identity barrel declares it, and that its first list view is not caller-scoped. No other assertion was dropped or loosened. (2) content/docs/ui/setup-app.mdx: only the Advanced row changed. A grep of the page finds no other sentence naming the two entries. (3) platform-core.json: in platform-core.builtin-apps-nav-render, the Setup detail step (:535) now has the runner check the user page's Preferences and Linked Accounts tabs. Revision 5 becomes 6, with a history entry, and the '45 Setup destinations' count (:537) is untouched.",
"tests": "Dogfood pin red to green, through os-verify-lock, exit codes captured before any pipe: at 6c64115's tree
pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/platform-app-object-entry-views.test.tsgave VERDICT command-exit 1, 'Tests 1 failed | 49 passed (50)'. At 770f1d6 the same command gave VERDICT command-exit 0, 'Test Files 1 passed (1) / Tests 51 passed (51)'. Dogfood subset: the 21 test/*.test.ts files that are not *.dogfood.test.ts, in one vitest call, gave VERDICT command-exit 0, 'Test Files 21 passed (21) / Tests 329 passed | 6 skipped (335)'. The subset was chosen by file name, not by boot: some of the 21 boot a kernel in-process. The other 264 files (244 *.dogfood.test.ts plus helpers) boot example apps and are CI's Dogfood Regression Gate; none reads Setup's menu, and the two that name sys_user_preference read it over the data API, which this change does not touch. Re-run after the merge, through os-verify-lock:pnpm --filter @objectstack/platform-objects testgave 'Test Files 73 passed (73) / Tests 1136 passed (1136)', andpnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 test/connect-agent-both-halves-wire.pin.test.tsgave 'Test Files 1 passed (1) / Tests 2 passed (2)'; VERDICT command-exit 0. No ablation of the new dogfood case: its subject resolves through @objectstack/platform-objects dist, so a mutation leg would need a rebuild per leg. The same assertion shape was ablated red in platform-objects (first report).","gates": "Head 770f1d6:
pnpm check:doc-authoringexit 0.pnpm check:platform-checklistexit 0 (327 items, 822/832 anchors resolved, 10 on the named residual).dispatch-gates --commands(no paths) derives 94 commands for 20 paths against merge base 6d1660d. 91 exited 0 on the first pass.pnpm --filter @objectstack/spec run check:skill-examplesexited 3 (client-react not built) and then 0 afterpnpm --filter @objectstack/client-react build.pnpm check:dual-build-cjs-loadsexited 3 PREREQUISITE NOT MET, so it is NOT MEASURED locally; it runs in CI Build Core, which is a success on this head. check:i18n's prerequisite closure was built before the battery (61/61 cache hits), and check:i18n then exited 0 in it.--rangave '94 derived, 93 run, 1 NOT-MEASURED, 0 UNRUN' (exit 0). PR #23936 check-runs on 770f1d6: 41 total, 36 success, 5 skipped, 0 failed or in progress. Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Test Core (1/6) to (6/6) and Dogfood Regression Gate all show success. Dogfood Regression Gate (shard/3) is skipped on PRs.","files_changed": "20 paths vs merge base 6d1660d. This round adds 3: packages/qa/dogfood/test/platform-app-object-entry-views.test.ts (+20/-1), content/docs/ui/setup-app.mdx (+1/-1), docs/qa/platform-checklist/areas/platform-core.json (+8/-2). Commit 770f1d6.",
"pr_body_for_the_seat": {
"note": "The PR body is not PATCHed. The seat writes it. Replace two sections whole with the text below: '## What this changes', including its '### Outside the claim's declared file surface' subsection, which the new text absorbs; and '## Verification', including its heading line. '## The card's other items', '## Measured before the change' and '## Search' stay as they are. In '## Acceptance notes', the first bullet (platform-core.json) should shrink to its count half. Suggested text: '
docs/qa/platform-checklist/areas/platform-core.jsonstill records "45 Setup destinations" in the Account-detail step. That count is item 4's, re-measured by whichever of this card's changes lands last.' The other two acceptance-note bullets (plugin-audit comments, showViewAll) stay.","what_this_changes": "## What this changes\n\nItem 3 of the card: "User Preferences" and "Identity Links" leave Setup's menu, and each stays reachable from the user its rows belong to.\n\n-
packages/platform-objects/src/apps/setup-nav.contributions.ts: thenav_accounts(sys_account, viewall_links) andnav_user_preferences(sys_user_preference, viewall_preferences) entries are removed. A comment in their place records why, and where the rows are reached instead.\n-packages/platform-objects/src/pages/sys-user.page.ts:SysUserDetailPagegains a last tab, "Preferences" (en / zh-CN / ja-JP / es-ES, like its siblings). It is arecord:related_listoversys_user_preferenceonuser_id, with the columnskey,created_at,updated_at(theall_preferencesview's columns minususer_id, which is the page's own record), sorted byupdated_atdescending like that view, 25 rows per page with the list's own paging. It authors noaddand noactions. The existing "Linked Accounts" tab oversys_accountis unchanged and serves "Identity links" (measured below), so no second tab is added.\n- Translations: the two ids' labels leaveen.ts,zh-CN.ts,ja-JP.tsandes-ES.ts, and their recorded digests leave the three*.source-hashes.tstables (an orphan digest redssource-hash.test.ts). Both ids joinDEAD_SETUP_NAV_IDSinsetup-nav-dead-key-tombstone.test.ts, with their reason in its header.\n- Tests inpackages/platform-objects: the newsetup-nav-per-user-stores.test.tspins (1) no Setup entry this package contributes targets either object, byobjectNameor by a URL; (2) the User page has one related list over each object, keyed onuser_id, accepted byRecordRelatedListProps, and the page parses throughPageSchema; (3) the Preferences list shows a subset of theall_preferencescolumns and authors noaddoractions; (4)unlink_accountis alist_itemaction. Incaller-scoped-first-list-view.test.ts, the non-vacuity control dropssys_user_preference, because no nav entry names it now and the population is derived from nav; a new case holds pin (a) for that object by name, and goes red if an entry names it again.\n-packages/cli/test/connect-agent-both-halves-wire.pin.test.ts(claim amendment 2): the two Setup-tree length pins move from 34 to 32, the count comment says 23 contributed entries, and the first case assertsnav_accountsandnav_user_preferencesare absent. 32 is measured from the built packages: 8 groups (group_approvalsis empty and collapses), plus 23platform-objectsentries, plus the MCP entry.\n-packages/qa/dogfood/test/platform-app-object-entry-views.test.ts(claim amendment 3): the composed-boot copy of the same invariant gets the same change.sys_user_preferenceleaves the non-vacuity list, and a new case pins that no merged Setup or Account entry names it and that its first declared list view is still not caller-scoped (read from the composition, or else the identity barrel).\n-content/docs/ui/setup-app.mdx(claim amendment 3): the Advanced row of the group table lists "OAuth Applications" only. No other sentence on the page names the two entries.\n-docs/qa/platform-checklist/areas/platform-core.json(claim amendment 3): inplatform-core.builtin-apps-nav-render, the Setup detail step no longer lists Identity Links and User Preferences among Setup's rendered destinations. It now has the runner open a user from Users and check the Preferences and Linked Accounts tabs. Revision 5 becomes 6, and no acceptance clause changes. The "45 Setup destinations" count is left as it is: it belongs to item 4, which whichever change lands last re-measures.\n-docs/qa/platform-checklist/areas/identity-auth.json: itemidentity-auth.linked-accounts-socialcitedsetup-nav.contributions.ts#nav_accounts. It now citessys-user.page.ts#SysUserDetailPage. Revision 3 becomes 4, as provenance only, with no clause change. Without the re-point,pnpm check:platform-checklistexits 1 (ABSENT SYMBOL, measured at2abfd4b4c).\n-packages/platform-objects/src/identity/sys-account.object.tsandsys-user-preference.object.ts: comments only. They no longer say a Setup entry names the object's unscoped view.\n- Changeset:@objectstack/platform-objectspatch, worded for administrators.\n\nNo pin was deleted, and no assertion was loosened.","verification": "## Verification, at head
770f1d617(after mergingorigin/mainat6d1660dc3)\n\n-pnpm --filter @objectstack/platform-objects test: 73 files and 1136 tests passed.\n-pnpm --filter @objectstack/cli exec vitest run test/connect-agent-both-halves-wire.pin.test.ts: 1 file and 2 tests passed. Ata6f35a120, before the edit, CI's Test Core (2/6) showed it red: "expected [...] to have a length of 34 but got 32".\n-pnpm --filter @objectstack/dogfood exec vitest run test/platform-app-object-entry-views.test.ts: before the edit, 1 failed and 49 passed (exit 1), with "(a) no longer judges sys_user_preference". After the edit, 51 passed (exit 0). The 21 dogfood*.test.tsfiles that are not*.dogfood.test.tsalso ran together: 329 passed and 6 skipped. That subset is chosen by file name, not by whether a file boots; some of the 21 boot a kernel in-process. The 244*.dogfood.test.tsfiles boot example apps and run in CI's Dogfood Regression Gate. None of them reads Setup's menu, and the two that namesys_user_preferenceread it over the data API, which this change does not touch.\n-pnpm --filter @objectstack/platform-objects typecheck: exit 0 ata6f35a120. The three edited or new test files are in thetsconfig.test.jsonprogram (counted with--listFiles).\n-pnpm check:i18n,pnpm check:platform-checklist(822/832 anchors resolved, 10 on the named residual) andpnpm check:doc-authoring: each exits 0.\n-node scripts/pm/dispatch-gates.mjs --commands(no paths): 94 commands for the 20 changed paths. 93 exited 0: two needed their prerequisite built first (check:i18nneeded the CLI, andcheck:skill-examplesneededclient-react), then exited 0.check:dual-build-cjs-loadsexited 3 (PREREQUISITE NOT MET: it reads the whole workspace'sdist), so it is NOT MEASURED locally; CI runs it in Build Core, which is green on this head.--ranreconciliation: 94 derived, 93 run, 1 NOT MEASURED, 0 UNRUN.\n- Ablation, one leg per platform-objects behaviour, each landed withscripts/ablation-replace.mjs(it proves the anchor hit and restores the blob to HEAD):\n - re-addingnav_user_preferencesturns 3 tests red;\n - addingvalueto the Preferences columns turns 1 test red;\n - pointing the tab's list at another object turns 3 tests red.\n - After every leg,git diff HEADis empty.\n- CI's families are not re-run here: read them on this PR's checks."},
"mcp_calls": "0",
"api_writes": "This addendum: 1 relay stroke (POST /repos/objectstack-ai/objectstack/dispatches), which executes POST /repos//issues/23803/comments. Cumulative for the card: 4 relay strokes and 5 REST writes (pulls, issues/23936/assignees, issues/23803/comments x3). git push: 6 in total; this round's push is the sixth. No PR-body PATCH, no label write.",
"open_questions": []
}
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23936 comment 6218787379 ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T15:25Z. Landing next: ready, then auto-merge through the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landing record: PR #23936 →
2e0e4517a6·domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T15:56Zmerged: true, merge commit2e0e4517a6, through the merge queueorigin/main2e0e4517aisorigin/main's tip.setup-nav.contributions.tsnamesnav_accounts/nav_user_preferencesonly in the comment that records their removal (:187-188). The cli wire pin readstoHaveLength(32)at:258and:280..changeset/23803-setup-nav-user-entries.mdis presentgh-readonly-queue/main/*pr-23936*head remainsState change: this card closed
completedbyFixes #23803;pm:dispatchedremoved in this act. No other card closed with it (closed since 2026-10-16T15:53Z: this card only).Carried, per the claim's split and ruling 6216295104:
domain:services,pm:blocked).platform-core.json's "45 Setup destinations") → re-measured by whichever of those lands last.plugin-audit's two stale "Setup's User Preferences grid" comments stay in the PR's Acceptance notes; no carrier.showViewAll→ spec(ui):record:related_list.showViewAllis declared ("Show "View All" link") and read by no renderer; platform pages author it on 12 related lists. Enforce or retire #23941.Generated by Claude Code