Repository navigation
Reach the member page again on 18.2 with a record-header action - #175
Conversation
On @objectstack 18.2 the console opens the isDefault record page first, so Duly > People > a person opens plugin-auth's sys_user_detail and duly_member is unreachable by the plain record route. PageSchema has no priority key and a second default refuses the boot, so nothing authorable outranks it (filed as objectstack-ai/objectstack#28979). - duly_member_open: a type 'url' action on sys_user that opens the explicit /page/duly_member route from the record's menu. A labelled stopgap. record_header only: 18.2 runs a row url action with no record in context. - test/member-page.test.ts mirrors the console's resolution rule and pins that a person resolves to sys_user_detail today, with a control, plus the route the action builds. - test/security.test.ts exempts exactly handler-less in-app navigation into Duly from the capability gate, with controls one step off that shape. - member.page.ts gap §5 rewritten with the 18.2 measurement. Fixes #113 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQwxbY2bWFwe8GRYRBqzbg
席位核对ACCEPT — PR #175 at head
Generated by Claude Code |
LandedSeat landing at 2026-11-02T05:56Z (duly lane seat, session
State: #113 is closed Generated by Claude Code |
Requested by Warren · project thread
Fixes #113
What the 18.2 re-measure found
#113 was written on 17.2, where
duly_memberwon thesys_userpage by list order. On 18.2.0 (mainac5b5c4, livepnpm demo),/api/v1/meta/pagestill listsduly_memberfirst. However, the console'susePageAssignmentnow picks theisDefaultpage first:candidates.find(p => defaultRecordPageObject(p) === object) ?? candidates[0]. So Duly > People > a person opens plugin-auth'ssys_user_detail, andduly_memberwas unreachable by the plain record route. This was a regression from the 18 upgrade, not the latent risk the card described.No authorable key outranks the platform page:
PageSchemahas no priority key.isDefaultforsys_userrefuses the boot withDEFAULT_RECORD_PAGE_CONFLICT(ruling A on objectstack#23015).Filed upstream as objectstack-ai/objectstack#28979. It asks for an app-scoped record page, because a deployment-wide
sys_userdefault would also replace Setup > Users.What this ships (seat Claim + amendments 1 and 2 on #113)
src/actions/member.actions.ts:duly_member_open. Atype: 'url'action onsys_userthat opens the explicit route/apps/ai.objectstack.duly/sys_user/record/${ctx.recordId}/page/duly_member. It is a labelled stopgap, to be deleted when #28979 lands. It is ungated, by seat ruling.record_headeronly. On 18.2 a row (list_item) url action runs with no record in context:${ctx.recordId},${ctx.record.id}and${ctx.selection.ids}all came out empty, measured live. The row version would land on a broken/record/page/duly_member.src/actions/index.ts: barrel entry.src/translations/zh-CN.ts:打开成员页.src/pages/member.page.ts: gap §5 is rewritten with the 18.2 measurement and #28979.test/member-page.test.ts: mirrors the console's rule and pins that a person resolves tosys_user_detailtoday. The control is that the same rule without plugin-auth's page picksduly_member. It also pins the route the action builds, againstmanifest.idand the page name, and therecord_header-only location. The card's original "first in list" pin was not written, because on 18.2 it would pass while the page was gone.test/security.test.ts: the "every action declares a gate" walk now exempts exactly one shape:type: 'url', no registered handler, nooperation/patch/body, and a target starting/apps/ai.objectstack.duly/. Controls one step off that shape must still fail: an external target, a protocol-relative target, another app's route, a template-led target, an operation, a patch, a body, a registered handler, and a non-url type.Verification
pnpm validate0 ·pnpm typecheck0 ·pnpm test1143/1143 ·pnpm build0pnpm demoon this branch, en-US and zh-CN: People > Elin Halvorsen > ⋯ showsOpen member page/打开成员页. Clicking it opens…/page/duly_memberwith the member page rendered. The People row menu no longer offers it. Screenshots are in the project folderduly-113-user-page/browser-pass/.Generated by Claude Code