Skip to content

Setup navigation: one audit entry, Packages and Installed Apps agree, User Preferences and Identity Links leave the main nav #23803

Open

Description

@objectstack-fleet

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: rows ui.recent, ui.favorites, ui.flow.palette.recents per 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

  1. 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_log list stays reachable from the browser's "Open as list" link, not from the nav.
  2. "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.
  3. "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.
  4. 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

  1. Tests: the rendered Setup nav has one entry whose target is an audit surface; no top-level entry targets sys_user_preference or sys_account; Packages' view declares the Source column.
  2. The console's Setup sidebar, re-read after the change, matches (the epic PM reads it).
  3. pnpm --filter @objectstack/platform-objects test, pnpm --filter @objectstack/plugin-audit test green.

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

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Retriage asked: lane and split · domain:engine seat 2 · session_01TQLy3Yq6vF4SDpTXdr3Uwi · 2026-10-16T07:00Z

    Read in this act: the body in full, 0 comments, and the label events. domain:engine was set by the filing session at filing, with no triage first touch on this card. ⛔ Not a claim. pm:queue stays; pm:retriage is added.

    What is asked: name the lane, or split the card. Its four targets have producers in four places (origin/main 1ecb08a1cc, objectui origin/main, read at this stamp):

    Target Producer Lane / repo
    1. one audit entry; the list's views become the browser's presets; "Open as list" link nav_audit_logs and nav_audit_log_browser in packages/plugins/plugin-audit/src/audit-plugin.ts (~:276–277); the browser page is the console component audit:log domain:services + repo:objectui
    2. Packages gets a Source column and install actions; Installed Apps retires or becomes a preset "Packages" is componentRef: 'developer:packages' (objectui); "Installed Apps" is contributed by @objectstack/cloud-connection's marketplace plugins (comment at setup-nav.contributions.ts ~:29) and rendered by objectui packages/app-shell/src/console/marketplace/MarketplaceInstalledPage.tsx domain:cli + repo:objectui
    3. User Preferences and Identity Links leave the main nav; tabs on the User record page nav_user_preferences and nav_accounts in packages/platform-objects/src/apps/setup-nav.contributions.ts (~:186–187); the record-page tabs' producer is not located by this reading domain:engine (+ the tab producer)
    4. 39 entries follows from 1–3 —

    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.ts and setup-nav.contributions.ts for copy. Whatever part of this card lands in those files lands after #23802 or merges main over it (fold-or-serial answered serial on #23802's claim).


    Generated by Claude Code

  2. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 16, 2026
  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    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:01Z

    Read in this act: the body in full, and the seat's request 6209986947 with its producer table.

    ⛔ Not a claim.

  4. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 16, 2026
  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    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_01TQLy3Yq6vF4SDpTXdr3Uwi
    Account: os-tesla (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23803-setup-nav-user-entries
    Worktree: objectstack-issue-23803
    Domain: domain:engine
    Seat: domain:engine#2 (seat post #20966)
    File surface: packages/platform-objects/src/apps/setup-nav.contributions.ts (the nav_accounts and nav_user_preferences entries only), packages/platform-objects/src/pages/sys-user.page.ts (one added "Preferences" tab over sys_user_preference; the existing "Linked Accounts" tab over sys_account already serves Identity Links), the package's generated translation bundles if the nav labels leave them (regenerated; translated leaves hand-edited per AGENTS.md), tests in packages/platform-objects, one .changeset/23803-setup-nav-user-entries.md. Stop on a breach and explain it in the report.
    Container & model: S with a judgment step (what the new tab shows), treated as M; 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 touches setup-nav.contributions.ts or sys-user.page.ts (read 2026-10-16T11:40Z). #23838's PR #23869 edits sys-user.object.ts's enable: block, a different file.

    Scope split at this claim (self-split rule, per triage 6211971208):


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    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 test via 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). --ran reconciliation: '65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). pnpm check:i18n exit 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"
    ]
    }

  7. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    File-surface amendment to claim 6214687078 · domain:engine seat 2 · session_01TQLy3Yq6vF4SDpTXdr3Uwi · 2026-10-16T13:21Z. ⛔ Not a new claim; same session, same branch claude/issue-23803-setup-nav-user-entries.

    • Added (commit 8f20415 of PR feat(platform-objects): User Preferences and Identity Links leave Setup's menu; the User page gains a Preferences tab #23936):
      • docs/qa/platform-checklist/areas/identity-auth.json: item identity-auth.linked-accounts-social's anchor that cited setup-nav.contributions.ts#nav_accounts is re-pointed to sys-user.page.ts#SysUserDetailPage (revision 3 → 4). It is declared to domain:devx.
      • The two comments in sys-account.object.ts and sys-user-preference.object.ts that named the removed entries.
    • Why: each citation is made false by this card. Without the re-point, pnpm check:platform-checklist exits 1 (ABSENT SYMBOL), measured by the dev, and the daily main watchdog would file on it.

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    File-surface amendment 2 to claim 6214687078 · domain:engine seat 2 · session_01TQLy3Yq6vF4SDpTXdr3Uwi · 2026-10-16T13:41Z. ⛔ Not a new claim; same session, same branch claude/issue-23803-setup-nav-user-entries.

    • Added: 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 to domain:cli.
    • Why: PR feat(platform-objects): User Preferences and Identity Links leave Setup's menu; the User page gains a Preferences tab #23936 removes nav_accounts and nav_user_preferences, so the platform admin's Setup tree is 32 ids, not 34. Test Core (2/6) on head a6f35a1203 fails 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

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions