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: objectstack-ai/objectstack#24168 (the Version Packages PR that publishes next.4, the first runtime release carrying e15897c0f1 — re-pointed by the triage seat from the closed served-page half)
Re-derived on 2026-10-18 by domain:ui seat 1. All five face cards are closed: objectui#12482, #12483, #12489, #12490 (dropped by the maintainer; the sheet's raw panel is deleted) and #12491. The one face half not yet on the served page is face 5's flow display name in the highlights strip, objectstack-ai/objectstack#24264. Until it lands and objectui pairs with a runtime that carries it, the served page shows flow:NAME where the sheet shows the flow's label.
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
objectstack-fleet commentedon Oct 18, 2026
Pointer ·
domain:uiseat 1 ·session_0188TsgPV8kQXfuRuKmkj2ks· 2026-10-18T05:17Z · ⛔ Not a claim.record:jsonpanel of the request payload, gated onstudio.access(objectui#12490, face 4 of objectui#12438 letter C) objectstack#23746 comment6232118266). PR fix(console,i18n): delete the approval drawer's raw payload panel for every viewer (objectui#12490) #12934 (9b82ced) then deleted the side sheet's raw JSON panel for every viewer.ApprovalsInboxPage.rawPayloadGate.test.tsxis retired by that ruling and is not carried. Its successor,ApprovalsInboxPage.noRawPayloadPanel-12490.test.tsx, pins the absence. When this card deletes the sheet, that absence pin retires with it.pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Blockers re-derived ·
pm:blockedstays ·domain:uiseat 1 ·session_0188TsgPV8kQXfuRuKmkj2ks· 2026-10-18T07:06Z⛔ Not a claim.
9b82ced. The raw panel was dropped by the maintainer, and the sheet's raw panel is deleted.7bbd718: the served decision panel now draws the step line and the Flow-initiated marker.Blocked-by: objectstack-ai/objectstack#24264. That is face 5's flow-name half, the served page's highlights showingprocess_labelwhere they showprocess_name. Without it, deleting the sheet loses the flow's label on the request view. The unlock waits on objectui pairing with a runtime that carries it, not on the merge alone.6199128775and objectui#12491's reading6246163097.origin/mainfb6fb24e2,sys_approval_requestdeclaresnameField: 'display_title'andtitleFormat: '{process_name} · {record_id}'.rowFromRequestservesprocess_labelandstep_labelbut nodisplay_title.getRecordDisplayNameinRecordDetailView.tsx) then drawsflow:NAME · <id>, the sheet pinstombstoneandunresolvableReference("the bare id never shows") have no served counterpart. Under this card's own rule, such a pin blocks the PR.Blocked-by:line here before any dev starts.rawPayloadGateis retired by the ruling (see6246027348).approvalRequestsDataSource.servedPageStepLine-12491.test.tsx).submitter_id, so they now draw the Flow-initiated marker unasserted. This card's rewrite of those pins gives the human-submitted rows a submitter.Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Blocked-by:re-pointed to the release ·pm:blockedstays · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-18T09:23ZTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.
e15897c0f1: the served page's strip names the flow byprocess_label.6246960490says the unlock waits on a runtime that carries it, not on the merge alone. npmnextis18.0.0-next.3, which does not carry it. So the body'sBlocked-by:line now names chore: version packages (next) objectstack#24168, the Version Packages PR that publishesnext.4. That PR is the maintainer's to merge.domain:services, filed 07:52Z). The strip's Current Step chip shows the step's machine id (current_step). The get serves the label only asstep_label. Whether deleting the sheet also waits on that card is this lane's call. ⛔ This seat does not add it to theBlocked-by:line.Generated by Claude Code