Repository navigation
approvals B1 closing card (ruling C on objectui#12438): the inbox opens a request on the served sys_approval_request page where the side sheet is, deletes the sheet, and lists each retired pin against its user report #12484
Description
Filing gate ④: a coordination node, the closing card that ruling 6190549995 on objectui#12438 directs (letter C, the maintainer's 「C (推荐)」, director seat summon #42, items 1 and 4). The ruling's words: "objectui#12045's mount step is re-pointed to a closing card that is Blocked-by: every face card; objectui#12045 stays pm:blocked until then."
Parent: #2763 (B1 of the epic). objectui#12045 waits on this card.
Blocked-by: #12482
Blocked-by: #12483
Blocked-by: #12489
Blocked-by: #12490
Blocked-by: #12491
Faces 3 to 5 were filed in the seat's next fire: objectui#12489 (record-reference states, objectui#11878), objectui#12490 (the gated raw panel, objectui#5553), and objectui#12491 (flow origin and the vertical step line). This card is dispatched only when all five face cards have closed.
Reader who acts: the domain:ui seat 1 (the epic's seat, seat post #5560). It dispatches one replacement PR in objectui after the last face lands.
Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T11:50Z): "approvals inbox replace side sheet drawer with served request page mount RecordDetailView" → 11 results, top 10 read:
- [Decision] approvals inbox: what opening a request shows — keep the hand-built side sheet, replace it with the served request page now, or build the page's missing faces first (B1 of objectui#2763) #12438 (the ruling);
- approvals B1 (child of objectui#2763): the
sys_approval_requestdetail page on the standard record renderer, composed from A1's data source, A2's record card, A3's progress widget, the action timeline and DeclaredActionsBar #12045 (B1, whose mount step this card now carries); - 架构:把审批 UI 重建在标准 SDUI 渲染器上(ListView + RecordDetailView + ApiDataSource + 多态记录预览组件) #2763 (the epic);
- closed: approvals inbox: the request drawer's record summary renders raw stored values, labels two fields "Owner", and logs duplicate React keys #11677, plugin-view: the create/edit record Drawer is opened with direction right but DrawerContent is styled as a bottom sheet, so on desktop it renders as a half-width panel at the bottom left #11775, approvals A1 (child of objectui#2763): read approval requests through the standard ApiDataSource, so ListView and RecordDetailView get
vieweranddecision_progressas fields #12032, console record page: a refused read (403) and a load failure both render "Record not found … may have been deleted" — RecordDetailView maps every rejection to missing #11902, finding(plugin-form,components): object-master-detail-form's edit-mode detail lines and element:record_picker's options have no bus reader — both refresh after a page action only through PageView's remount (the fifth batch; blocks objectui#10519) #10853, Approvals inbox detail drawer unconditionally renders a "Raw data (JSON)" panel — exposeshidden: truefields, internal ids and audit columns to business approvers #5553 and approvals UX: surface OOO/quorum/per_group/attachments SDUI-first — stop hand-editing the inbox per feature #2678.
None of them is this card.
What to build (once every face has landed), the ruling's item 1
-
One PR mounts the served page where the sheet is. The approvals inbox (
apps/console/src/pages/system/ApprovalsInboxPage.tsx) opens a request on the servedsys_approval_request_detailpage, mounted on the standardRecordDetailViewover the approval routing (PR fix(console): every surface reads an approval request through the approvals routes; the served page's timeline counts and labels (objectui#12045, B1 page-mount step, part) #12432), in the place the side sheet occupies today. -
The same PR deletes the side sheet.
-
The PR body lists each retired pin against the user report it came from. These are the 13
ApprovalsInboxPage.*.test.tsxfiles at objectuid9d9d98684:approverHeadline-12110→ face objectui#12482;summaryFaces-11677,hiddenFieldTrimandqueueHiddenAmount→ face objectui#12483;recordLink,recordLinkRefused-11878,tombstoneandunresolvableReference→ face objectui#12489;rawPayloadGate→ face objectui#12490;stepProgressVertical→ face objectui#12491;characterizationPins,cellIdentityanddisplayLocale-10375: queue-list pins; read each at that time, and retire or keep it with its reason.
A pin whose face has a pinned counterpart on the served page retires. A pin with no counterpart blocks this PR, per ADR-0060 rule 3: "What already exists stays until its page migrates, and may only shrink."
Acceptance
- The inbox opens a request on the served page. The side sheet's component and its pins are gone, and each retired pin is named against its report and the face card that carries its counterpart.
- No face regresses: each face card's served-page pin is green on the merge.
Attribution: written by the domain:ui seat 1 in session session_01JZnppgHRp4sREcouhkQYDB, executing ruling 6190549995.
Activity
objectstack-fleet commentedon Oct 15, 2026
Carrier note for this closing card ·
domain:uiseat 1 ·session_01JZnppgHRp4sREcouhkQYDB· 2026-10-15T18:16ZFrom objectui#12489's fit check (
6198994393,out_of_scope_findings[0]): on the servedsys_approval_request_detailpage, the H1 isdisplay_title,plugin-approvals' formulaprocess_name + ' · ' + record_id. So the raw record id is on screen in all four reference states (measured: "invoice_approval · " followed by the id).The sheet's
ApprovalsInboxPage.tombstoneand.unresolvableReferencepins assert that the bare id never shows. The PR that retires those pins against the served page inherits this. Its producer is objectstackpackages/plugins/plugin-approvals/src/sys-approval-request.object.ts(display_title).Face 3's tombstone half waits on the decision on objectui#12489 (
needs-user-decision). Its link half is objectui#12557.Generated by Claude Code