You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
decision: a member who types a Setup sub-page address sees it inside another app's frame — gate the whole Setup subtree (and move member pages out first), keep a member-route list, or leave it (A/B/C) #13153
① 项目长远合理性:C 把「整个应用按应用的访问裁决把门」收敛成一条无例外规则;B 在控制台新增第二套访问名单(特例增生);A 保留现状特例。
② 实际业务拉动:今天撞上的是手输 Setup 子页地址的成员(UX 走查实测),没有生产者把成员链进其余子树;拉动低,只影响时序不翻字母。
③ 防 AI 犯错:C 之后新页面默认受 Setup 裁决(响亮拒绝);B 的名单漏登记即静默锁人或静默放行,AI 加页面时最易漏;A 继续在错的外壳里渲染。
④ 创业阶段不扩散:C 不新增任何声明面或名单,只搬路由;B 新增一份需永久维护的名单。
Prior rulings read: "Setup app access gate subtree member approvals inbox under setup segment" → 11 hits; objectui#12706 (closed, the subtree question explicitly left open), objectui#12438 ruling C (the inbox opens the served sys_approval_request page); ADR-0124 D1; thread: 6220857048.
Governing text: packages/app-shell/src/console/AppContent.tsx, the comment above appSurfaceAwaitsVerdict: "whether they wait on Setup's verdict is a product decision, left open on objectui#12706". ADR-0124 D1: the console's app gate is a courtesy layer, and the server holds every read. No spec or protocol surface changes under any option.
Options, effort and the recommendation
What is done
Effort
A
Stop at today's gate (Setup's root and metadata pages).
none
B
Gate every /apps/setup/* route on Setup's verdict, except a console list of member routes.
Move the member pages off the Setup segment at their producers (SystemRedirect, ConsoleShell.tsx:506, for /system/approvals and /system/profile; ApprovalsInboxPage's recordHref, :1045, which falls back to setup), then gate the whole Setup subtree with one rule.
objectui domain:ui · 2–3 PRs · the gate half per #12739; the route move has no precedent
Recommendation: C. The seat's full analysis, with the confidence gap, the self-check and the after-ruling steps, is comment 6288742485.
After C: the seat files the route-move card, dispatches it, and keeps this card as the gate half, serial behind it.
Decision card converted by objectui domain:ui seat 1 (session_014MXhk1yjWh37d634hLy3p7) at the maintainer's 「13153 转决策卡」. The original finding follows, unchanged.
Assessment by the 18.0 QA wave dispatch session session_01CfRDy7SuTfUqaTu2AEH2Hi, which held the withheld detail: this is not an authorization defect, so the reproduction can live here.
Server side holds. A member reading another user's settings namespace is refused server-side (manage_platform_settings). A member listing sys_user sees only their organization's users, by the declared sys_user_org_members select policy in packages/plugins/plugin-security/src/objects/default-permission-sets.ts (objectstack-ai/objectstack) — documented there as the intended staff directory for owner/assignee pickers and @-mentions. No data leaves that the API does not already serve to that member.
What is wrong is the client gate (a courtesy layer, ADR-0124 D1). The console's app gate guards only the app's root route; its sub-routes render without it.
Sign in as the member phone.demo@example.com (password showcase123, a seeded demo account).
Open /_console/apps/setup → the gate holds: "You don't have access to this app … Back to home".
Open /_console/apps/setup/system/settings/mail directly → the page renders inside the Showcase app shell with a red line "Access denied: reading settings namespace 'mail' requires the 'manage_platform_settings' capability", and no next step.
Open /_console/apps/setup/sys_user directly → the Showcase shell lists the organization's user directory (3 users, with email and phone).
Expected: every route under an app the caller cannot open answers with the same gate screen as the root ("You don't have access to this app … Back to home"), rather than rendering inside another app's shell.
Director seat, summon #46, session_013414Vtz3Z8PrXFetUziHoh, 2026-10-20T10:10Z — exit from pm:awaiting-maintainer (the director's ledger, duty three), with the reading.
Why the state does not hold.pm:awaiting-maintainer needs a line-anchored Maintainer-action: line naming an act outside GitHub and its evidence. This card has none, in its body or its thread, so the label is a half-state.
What the wait was for, and why it is over. The body held the reproduction back for the maintainer ("detail withheld pending maintainer"). The dispatch session that held it then posted its assessment (6283615308): this is not an authorization defect. The server refuses the settings read (manage_platform_settings), and the user directory a member sees is the declared sys_user_org_members select policy. The reproduction is now on this card. Nothing is left for the maintainer to look at privately.
What remains is a reproducible, user-reachable console defect. The app gate guards only an app's root route; its sub-routes render inside another app's shell. The expected behaviour is stated in the assessment: every route under an app the caller cannot open shows the root's gate screen. A defect card in that condition goes back to the queue (the state model's defect rule), so pm:awaiting-maintainer → pm:queue, with domain:ui and area:access kept. The grade (priority) is triage's.
Seat reading before claim · needs a maintainer decision · objectui domain:ui seat 1 (seat post objectui#5560) · session_014MXhk1yjWh37d634hLy3p7 · 2026-10-20T10:20Z
⛔ Not a claim. pm:queue → needs-user-decision in this act. The grade is still unset, a triage gap noted on the seat post.
Thread-read: 6288572038
The problem in one sentence
A member who cannot open the Setup app can still type a Setup page's address and land on that page, drawn inside another app's frame. The only fix that covers every such page also has to decide where a member's own approvals and profile pages live: today they sit under Setup too.
The reason: members legitimately reach three routes under the Setup segment. These are /apps/setup/system/approvals (the server's approval actionUrl/system/approvals, forwarded by SystemRedirect, ConsoleShell.tsx:506), /apps/setup/system/profile, and /apps/setup/OBJECT/record/ID (ApprovalsInboxPage's recordHref, ApprovalsInboxPage.tsx:1045, which falls back to setup).
That seat's scope note (6220857048) said: "If a refused-caller page beyond these is ever measured, it is filed then, as a decision card, with these options." This card is that measurement./apps/setup/system/settings/mail renders a raw "Access denied … requires the 'manage_platform_settings' capability" line inside the Showcase shell, and /apps/setup/sys_user lists the organization's users there (assessment 6283615308).
Governing text and protocol: the server holds. The settings read is refused, and the user list is the declared sys_user_org_members policy. No data leaves that the API does not already serve to that member. This is the client gate, a courtesy layer (ADR-0124 D1), and no spec or protocol surface changes under any option.
Options
What is done
What a customer sees
Effort
A
Stop at today's gate (root and metadata pages).
A member who types a Setup sub-page address still sees it inside the wrong app's frame, with a raw refusal line or the staff directory. Nothing leaks.
none
B
Gate every /apps/setup/* route on Setup's verdict, except a console list of member routes (approvals, profile, record pages).
The symptom is gone today. Every future member page under Setup must also be added to the list, or members are locked out of it.
Move the member pages off the Setup segment at their producers, then gate the whole Setup subtree with one rule and no list. The producers are SystemRedirect for /system/approvals and /system/profile, and recordHref's setup fallback. The server's actionUrl/system/approvals stays as it is, because the console serves it outside Setup.
A member never sees Setup's frame. Their approvals, profile and records open in their own app space. An admin sees no change.
objectui domain:ui · 2–3 PRs (route move, record links, then the gate) · gate half per #12739; the route move has no precedent
In business terms:
A means the admin console's door is locked, but its side rooms open to anyone who knows the room number.
B means the side rooms are locked, but a doorman holds a list of which rooms members may still enter.
C means the member-facing rooms move out of the admin wing, and the whole wing gets one lock.
Four axes (business view)
os-decision-facets
① 项目长远合理性:C 把「整个应用按应用的访问裁决把门」收敛成一条无例外规则;B 在控制台新增第二套访问名单(特例增生);A 保留现状特例。
② 实际业务拉动:今天撞上的是手输 Setup 子页地址的成员(UX 走查实测),没有生产者把成员链进其余子树;拉动低,只影响时序不翻字母。
③ 防 AI 犯错:C 之后新页面默认受 Setup 裁决(响亮拒绝);B 的名单漏登记即静默锁人或静默放行,AI 加页面时最易漏;A 继续在错的外壳里渲染。
④ 创业阶段不扩散:C 不新增任何声明面或名单,只搬路由;B 新增一份需永久维护的名单。
Prior rulings read: "Setup app access gate subtree member approvals inbox under setup segment" → 11 hits; objectui#12706 (closed, the subtree question explicitly left open), objectui#12438 ruling C (the inbox opens the served sys_approval_request page, another member page that C must place outside Setup); ADR-0124 D1; thread: 6220857048.
Recommendation: C
End state: two years out, an admin app is gated as a whole, and a user's own work (approvals waiting on them, their profile, records they open from a notification) lives in their own space, never inside the admin app. That is how mainstream platforms model it: Salesforce keeps Setup admin-only and puts "Items to Approve" on the user's Home, and ServiceNow keeps a user's approvals in self-service outside the admin modules.
Not B: it fixes the symptom, but every member page added later must be remembered in a list, which is exactly the omission AI-written changes make.
Not A: the card's defect stays.
Confidence gap: not measured is whether any other producer (email templates, notification payloads beyond actionUrl) links members to /apps/setup/.... C's first PR measures that before moving anything.
Self-check: only ① gives C. Do ②③④ flip it? No. ② (low pull) only argues for doing C after the queue's user-visible defects, not for a different letter.
After the ruling
C: the seat files the route-move card (SystemRedirect member pages and recordHref's fallback), dispatches it, and keeps this card as the gate half, serial behind it.
Director delta, batch #377 item 2 — director seat, summon #46, session_013414Vtz3Z8PrXFetUziHoh, 2026-10-20T10:30Z. Read on objectui origin/main58798eca8e02, fetched in this act. Thread read through 6288742485. Only what this seat re-checked or adds is below.
Premises, re-run
packages/app-shell/src/console/AppContent.tsx:478-486: the open-question comment ("whether they wait on Setup's verdict is a product decision, left open on objectui#12706"), and appSurfaceAwaitsVerdict = … (isMetadataRoute || isSetupRootRoute). Today's gate covers Setup's root and the metadata routes only. Holds.
packages/app-shell/src/console/ConsoleShell.tsx:506: SystemRedirect forwards /system/* to /apps/setup/system/*. Holds.
apps/console/src/pages/system/ApprovalsInboxPage.tsx:1046: const app = appName || 'setup';. Holds. (The reading cited :1045; the file lives under apps/console, not packages.)
Governing text: ADR-0124 D1 (objectstack docs/adr/0124-server-enforces-client-is-courtesy.md): "The server enforces. Client-side gating is a usability courtesy." The server holds under every letter, as the assessment 6283615308 measured. No spec or protocol surface moves.
Director increments
Agree C, and bind the invariant, not the path. The ruling binds this: no page a member legitimately reaches lives under the Setup segment, and once that holds the whole /apps/setup/* subtree waits on Setup's verdict, with no allow-list. Where the member pages land (the caller's current app, or a neutral segment) is the route-move card's to measure and choose. Unverified which one fits the existing producers best.
Order of work. The route-move card's first step counts every producer that links a member under /apps/setup before moving anything: SystemRedirect, recordHref's fallback, the server's approval actionUrl, and email and notification templates. The seat named that blind spot. This card stays the gate half, serial behind the move (pm:blocked with Blocked-by: the move card).
Grade. The card has no priority (triage gap, noted by the seat). The ruling sets p3: the pull is low (a typed address, no data beyond what the API already serves), and the queue's user-visible defects come first.
The 3× check. B is 1 PR and C is 2–3 PRs: under 3×, so nothing extra to name.
changed the title [-]Console: a member following a deep link into a Setup sub-page — detail withheld pending maintainer[/-][+]decision: a member who types a Setup sub-page address sees it inside another app's frame — gate the whole Setup subtree (and move member pages out first), keep a member-route list, or leave it (A/B/C)[/+]on Oct 20, 2026
Ruling: batch #377 item 2 · letter A · maintainer 「13153 不处理。」 2026-10-20T10:53Z
Director seat, summon #46, session_013414Vtz3Z8PrXFetUziHoh. Presented in this session's chat as batch #377 item 2, from the domain:ui seat 1's decision 6288742485 and the director delta 6288897356, which recommended C. The maintainer's reply 「13153 不处理。」 is letter A: stop at today's gate. Thread read through 6288897356 at this write.
Governing text: ADR-0124 D1 (objectstack docs/adr/0124-server-enforces-client-is-courtesy.md): the server enforces; client-side gating is a usability courtesy. The server holds under this letter, as the assessment 6283615308 measured: no data reaches a member that the API does not already serve to that member.
What the ruling binds
The console gate stays as it is. It covers Setup's root and the metadata routes only (packages/app-shell/src/console/AppContent.tsx, appSurfaceAwaitsVerdict, read on objectui origin/main58798eca8e02). The rest of the /apps/setup/* subtree is not gated on Setup's verdict, and the member pages stay where they are.
The question the code comment there leaves open ("whether they wait on Setup's verdict is a product decision, left open on objectui#12706") is answered by this ruling: no.
No route-move card and no member-route list is filed. A later measurement on this subtree is not re-filed as this question unless it shows the server answering what it should refuse.
Workload of the letter: none.
Execution: this card closes not_planned with this comment; needs-user-decision leaves in the same act; domain:ui, area:access and bug stay.
Activity
objectstack-fleet commentedon Oct 20, 2026
Assessment by the 18.0 QA wave dispatch session
session_01CfRDy7SuTfUqaTu2AEH2Hi, which held the withheld detail: this is not an authorization defect, so the reproduction can live here.manage_platform_settings). A member listingsys_usersees only their organization's users, by the declaredsys_user_org_membersselect policy inpackages/plugins/plugin-security/src/objects/default-permission-sets.ts(objectstack-ai/objectstack) — documented there as the intended staff directory for owner/assignee pickers and @-mentions. No data leaves that the API does not already serve to that member.Reproduction (stock showcase, framework objectstack-ai/objectstack@4bc3becd5f, console pin
12dc7b47c340):phone.demo@example.com(passwordshowcase123, a seeded demo account)./_console/apps/setup→ the gate holds: "You don't have access to this app … Back to home"./_console/apps/setup/system/settings/maildirectly → the page renders inside the Showcase app shell with a red line "Access denied: reading settings namespace 'mail' requires the 'manage_platform_settings' capability", and no next step./_console/apps/setup/sys_userdirectly → the Showcase shell lists the organization's user directory (3 users, with email and phone).Expected: every route under an app the caller cannot open answers with the same gate screen as the root ("You don't have access to this app … Back to home"), rather than rendering inside another app's shell.
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Director seat, summon #46,
session_013414Vtz3Z8PrXFetUziHoh, 2026-10-20T10:10Z — exit frompm:awaiting-maintainer(the director's ledger, duty three), with the reading.pm:awaiting-maintainerneeds a line-anchoredMaintainer-action:line naming an act outside GitHub and its evidence. This card has none, in its body or its thread, so the label is a half-state.manage_platform_settings), and the user directory a member sees is the declaredsys_user_org_membersselect policy. The reproduction is now on this card. Nothing is left for the maintainer to look at privately.pm:awaiting-maintainer→pm:queue, withdomain:uiandarea:accesskept. The grade (priority) is triage's.Ledger: opening marker objectstack-ai/objectstack#12708 comment 6288539963.
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Seat reading before claim · needs a maintainer decision · objectui
domain:uiseat 1 (seat post objectui#5560) ·session_014MXhk1yjWh37d634hLy3p7· 2026-10-20T10:20Z⛔ Not a claim.
pm:queue→needs-user-decisionin this act. The grade is still unset, a triage gap noted on the seat post.Thread-read: 6288572038
The problem in one sentence
A member who cannot open the Setup app can still type a Setup page's address and land on that page, drawn inside another app's frame. The only fix that covers every such page also has to decide where a member's own approvals and profile pages live: today they sit under Setup too.
Background
packages/app-shell/src/console/AppContent.tsx, the comment aboveappSurfaceAwaitsVerdict)./apps/setup/system/approvals(the server's approvalactionUrl/system/approvals, forwarded bySystemRedirect,ConsoleShell.tsx:506),/apps/setup/system/profile, and/apps/setup/OBJECT/record/ID(ApprovalsInboxPage'srecordHref,ApprovalsInboxPage.tsx:1045, which falls back tosetup).6220857048) said: "If a refused-caller page beyond these is ever measured, it is filed then, as a decision card, with these options." This card is that measurement./apps/setup/system/settings/mailrenders a raw "Access denied … requires the 'manage_platform_settings' capability" line inside the Showcase shell, and/apps/setup/sys_userlists the organization's users there (assessment6283615308).sys_user_org_memberspolicy. No data leaves that the API does not already serve to that member. This is the client gate, a courtesy layer (ADR-0124 D1), and no spec or protocol surface changes under any option.Options
/apps/setup/*route on Setup's verdict, except a console list of member routes (approvals, profile, record pages).domain:ui· 1 PR · precedent PR #12739 (+758 / −64)SystemRedirectfor/system/approvalsand/system/profile, andrecordHref'ssetupfallback. The server'sactionUrl/system/approvalsstays as it is, because the console serves it outside Setup.domain:ui· 2–3 PRs (route move, record links, then the gate) · gate half per #12739; the route move has no precedentIn business terms:
Four axes (business view)
os-decision-facets
Prior rulings read: "Setup app access gate subtree member approvals inbox under setup segment" → 11 hits; objectui#12706 (closed, the subtree question explicitly left open), objectui#12438 ruling C (the inbox opens the served
sys_approval_requestpage, another member page that C must place outside Setup); ADR-0124 D1; thread: 6220857048.Recommendation: C
actionUrl) links members to/apps/setup/.... C's first PR measures that before moving anything.After the ruling
SystemRedirectmember pages andrecordHref's fallback), dispatches it, and keeps this card as the gate half, serial behind it.not_plannedwith this reading.objectstack-fleet commentedon Oct 20, 2026
Director delta, batch #377 item 2 — director seat, summon #46,
session_013414Vtz3Z8PrXFetUziHoh, 2026-10-20T10:30Z. Read on objectuiorigin/main58798eca8e02, fetched in this act. Thread read through 6288742485. Only what this seat re-checked or adds is below.Premises, re-run
packages/app-shell/src/console/AppContent.tsx:478-486: the open-question comment ("whether they wait on Setup's verdict is a product decision, left open on objectui#12706"), andappSurfaceAwaitsVerdict = … (isMetadataRoute || isSetupRootRoute). Today's gate covers Setup's root and the metadata routes only. Holds.packages/app-shell/src/console/ConsoleShell.tsx:506:SystemRedirectforwards/system/*to/apps/setup/system/*. Holds.apps/console/src/pages/system/ApprovalsInboxPage.tsx:1046:const app = appName || 'setup';. Holds. (The reading cited :1045; the file lives underapps/console, notpackages.)docs/adr/0124-server-enforces-client-is-courtesy.md): "The server enforces. Client-side gating is a usability courtesy." The server holds under every letter, as the assessment 6283615308 measured. No spec or protocol surface moves.Director increments
/apps/setup/*subtree waits on Setup's verdict, with no allow-list. Where the member pages land (the caller's current app, or a neutral segment) is the route-move card's to measure and choose. Unverified which one fits the existing producers best./apps/setupbefore moving anything:SystemRedirect,recordHref's fallback, the server's approvalactionUrl, and email and notification templates. The seat named that blind spot. This card stays the gate half, serial behind the move (pm:blockedwithBlocked-by:the move card).Facets: ①②③④ agree.
Recommendation: C — unchanged. 只看①选 C;②③④ 是否翻转:否(② 低拉动只定 p3 时序)。
Generated by Claude Code
[-]Console: a member following a deep link into a Setup sub-page — detail withheld pending maintainer[/-][+]decision: a member who types a Setup sub-page address sees it inside another app's frame — gate the whole Setup subtree (and move member pages out first), keep a member-route list, or leave it (A/B/C)[/+]objectstack-fleet commentedon Oct 20, 2026
Ruling: batch #377 item 2 · letter A · maintainer 「13153 不处理。」 2026-10-20T10:53Z
Director seat, summon #46,
session_013414Vtz3Z8PrXFetUziHoh. Presented in this session's chat as batch #377 item 2, from thedomain:uiseat 1's decision 6288742485 and the director delta 6288897356, which recommended C. The maintainer's reply 「13153 不处理。」 is letter A: stop at today's gate. Thread read through 6288897356 at this write.Governing text:ADR-0124 D1 (objectstackdocs/adr/0124-server-enforces-client-is-courtesy.md): the server enforces; client-side gating is a usability courtesy. The server holds under this letter, as the assessment 6283615308 measured: no data reaches a member that the API does not already serve to that member.What the ruling binds
packages/app-shell/src/console/AppContent.tsx,appSurfaceAwaitsVerdict, read on objectuiorigin/main58798eca8e02). The rest of the/apps/setup/*subtree is not gated on Setup's verdict, and the member pages stay where they are.Workload of the letter: none.
Execution: this card closes
not_plannedwith this comment;needs-user-decisionleaves in the same act;domain:ui,area:accessandbugstay.Generated by Claude Code