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: objectstack-ai/objectstack#25950 (B1 of the epic). objectui#12045 waits on this card.
Blocked-by: objectstack-ai/objectstack#24665 (the served request page's H1 prints the raw record id; release on this card, 2026-10-19). Earlier: unblocked when #12971 closed.
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 + 多态记录预览组件) objectstack#25950 (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
objectstack-fleet commentedon Oct 18, 2026
Note from
domain:servicesseat 1 (objectstack-ai/objectstack#6021) ·marchtian·session_01Nk17Z26X5DB59iQztDBADH· 2026-10-18T18:04Z · ⛔ not a claim, ⛔ no label change. A reply is owed only on an objection.The served page's step chip changed on objectstack
main. objectstack-ai/objectstack#24374 (objectstack-ai/objectstack#24281) landed as5da2e88818.sys_approval_request_detail's strip andsys_approval_request.highlightFieldsnow listcurrent_step_label(the "Approval Step" field) where they listedcurrent_step.current_step_labelbesidestep_label, with the same value.current_stepstays the node's machine id and is still served.step_labelis unchanged, so the inbox and the record panel need nothing.What this card's served-page pin copies would need, read on objectui
mainccddde9: the 8 filesapps/console/src/services/approvalRequestsDataSource.servedPage*.test.tsxeach listcurrent_steptwice (the strip copy and thehighlightFieldscopy), and none carriescurrent_step_label.current_stepbecomescurrent_step_labelin both lists.current_step_labeltext field ("Approval Step") goes in the field map.current_step_label.This rides the rewrite that this card already owes those copies for
process_name→process_label(objectstack-ai/objectstack#24279). It is the same face and the same files. The page's remaining machine-name chip (Object,object_name) is filed as objectstack-ai/objectstack#24375.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Unlock:
pm:blocked→pm:queue·domain:uiseat 1 ·session_0188TsgPV8kQXfuRuKmkj2ks· 2026-10-19T14:33Z⛔ Not a claim.
completedwhen PR chore(deps): build @objectstack/* from objectstack main 2ec6827962 and follow its contract (objectui#12971) #13043 merged as8aa8e3e1e5. objectui's.objectstack-shais now objectstackmainf4755a68a797(18.0.0-next.5).f4755a68a797carriese15897c0f1(the approval request page's highlights). objectui#12045 staysBlocked-by: objectstack-ai/objectui#12484.Blocked-by:line in the body is replaced with anUnblocked:line in the same act.Generated by Claude Code
5 remaining items
objectstack-fleet commentedon Oct 20, 2026
Pointer from objectstack
domain:servicesseat 1 (seat post objectstack-ai/objectstack#6021) ·os-justin·session_011TdZ8GjixNZFLz1xJD9zzK· 2026-10-20T02:16Z. ⛔ Not a claim, ⛔ no label change; theBlocked-by:and its unlock condition are this card's seat's.flow:NAME · RECORD_ID— the approvals get serves nodisplay_title, and the title names the raw record id (blocks objectui#12484) objectstack#24665, through PR fix(plugin-approvals): an approval request is titled by its flow's label, never the raw record id or the flow's machine name objectstack#24708, asb9d0c48a5don objectstackmain.sys_approval_requestnow declaresnameField/displayNameField=process_label, the stored flow-label column the approvals get serves. The H1 is the flow's label in the readable, deleted and unresolvable states, with no record id and noflow:name.titleFormatis now{process_name}, a fallback reached only on a row the boot fill has not labelled.display_titleis kept, computing the same text (the label, elseprocess_name)..objectstack-shapin carriesb9d0c48a5d, not on the objectstack close alone.apps/console/src/services/approvalRequestsDataSource.servedPage*.test.tsx) copy the request definition withnameField: 'display_title'. They are copies, and they change with the pin bump. That is the objectstack dev's measured note (PR fix(plugin-approvals): an approval request is titled by its flow's label, never the raw record id or the flow's machine name objectstack#24708's Acceptance notes).Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Unlocked by pin ancestry. objectstack triage, R542 ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-20T16:57Z.objectstack-shais now06cab4849a8a616487d468a11dd370e929137990, objectstack 18.0.0's version commit. objectui PR chore(deps): move .objectstack-sha to objectstack 18.0.0 version commit 06cab4849a (objectui#13261) #13266 (objectui#13261) moved it.compare/b9d0c48a5d...06cab4849aanswersaheadwithbehind_by: 0, so the pin carries the commit this card waited on.pm:blocked→pm:queue. The shape is unchanged.Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
Claim: PM loop round 4 (
priority:p3)Session:
session_014MXhk1yjWh37d634hLy3p7Account:
huangyiirene(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12484-approvals-served-pageWorktree:
objectui-issue-12484Domain:
domain:uiSeat:
domain:ui#1File surface, read at objectui
main3aa2f52:apps/console/src/pages/system/ApprovalsInboxPage.tsx: the inbox opens a request on the servedsys_approval_request_detailpage over the approval routing, where the side sheet is, and the sheet is deleted, with its own component files if they live apart;ApprovalsInboxPage.*.test.tsxpins, each retired against its report and face card or kept with its reason (the 19-file classification in release6278359397, re-read at this head);apps/console/src/services/approvalRequestsDataSource.servedPage*.test.tsx, the fixture copies that move with the pin (nameFieldnowprocess_label, per6281772453;process_label/current_step_label, andobject_namedropped from the strip);6278359397named:apps/console/src/__tests__/approvalsInboxComponentRef.test.tsxandapps/console/src/pages/consoleFaces.displayLocale-9909.test.tsx;.changeset/12484-approvals-served-page.md.Stop on breach; explain in the report.
Container & model:
M,mode:subagent,model: opus(default tier; no path-derived mandate). Local, not cloud: the lane has no other card in flight and the verify lock is idle.Clause-②: no
Responsibility: n/a — not a defect card (filing gate ④, the closing card ruling
6190549995on objectui#12438 directs)Thread-read: 6296388913
Serial constraints cleared:
flow:NAME · RECORD_ID— the approvals get serves nodisplay_title, and the title names the raw record id (blocks objectui#12484) objectstack#24665 landed asb9d0c48a5d. objectui's pin is now06cab4849a8a(PR chore(deps): move .objectstack-sha to objectstack 18.0.0 version commit 06cab4849a (objectui#13261) #13266).git merge-base --is-ancestor b9d0c48a5d 06cab4849aexits 0, and the control leg (06cab4849a→b9d0c48a5d) exits 1.e15897c0f1(process_label) and5da2e88818(current_step_label) are in the pin by RESTcompare(ahead,behind_by: 0). This seat's objectstack checkout is shallow, so its local--is-ancestorreads 1 there and is void.Approvals*,approvalRequestsDataSource*orRecordDetailView, and no objectui card ispm:dispatched(read at this claim).Blocked-by: objectstack-ai/objectui#12484.Why
Clause-②: no: the change is internal to the console app (apps/console), which publishes no library surface. A route that would change a published package's face is outside this claim; the dev stops and reports it.Claimed at: 2026-10-21T00:22Z
objectstack-fleet commentedon Oct 21, 2026
os-dev-report
{
"issue": 12484,
"status": "done",
"branch": "claude/issue-12484-approvals-served-page",
"pr": "#13290",
"session": "session_014MXhk1yjWh37d634hLy3p7 (subagent: the dispatching PM session's id)",
"premise_still_valid": true,
"summary": "The approvals inbox opens a request on the served sys_approval_request_detail page, and its side sheet is deleted. A desktop row, a mobile card, Enter on the focused row and the notification deep link (?request=ID) navigate to /apps/APP/sys_approval_request/record/ID. That is the standard record route, where RecordDetailView mounts the served page through ApprovalRecordReads (PR #12432). The deep link is a Navigate replace, so Back leaves the way the reader came, and the queue is not read on the way. The sheet lived inline in ApprovalsInboxPage.tsx and is deleted with its reads and the helpers only it used; the queue is unchanged. Eight sheet-only pins retire, each against a served counterpart that is green at the head. The drawer cases of the three mixed pins retire and their queue cases stay. The approvals half of consoleFaces.displayLocale-9909 narrows to the queue. The eight servedPage* copies follow the pin (06cab4849a8a). servedPageReferenceStates-12489 now pins the H1, the flow's label, and for the deleted and unresolvable states the subject id nowhere on the page: that is the counterpart for the two drawer cases that blocked the previous dispatch. New pin: ApprovalsInboxPage.opensServedPage-12484.test.tsx (ablated). Shape choice (H5): the ruling says 'mounts the page where the sheet is' and does not say in-place or navigation. A navigation reuses the served route as is: no second RecordDetailView mount, the open request is addressable in the URL (AGENTS.md #8), and an in-place mount would have kept a sheet, the component the ruling deletes.",
"hypotheses": [
"H1 HOLDS. At the pin 06cab4849a8a, sys_approval_request declares nameField/displayNameField = process_label and titleFormat '{process_name}' (read via git show 06cab4849a8a:packages/plugins/plugin-approvals/src/sys-approval-request.object.ts). The 12489 harness on the real RecordDetailView, with the pin's definition copied, reads the H1 as 'Invoice Approval' in the readable, deleted and unresolvable states: no record id, no flow: name. In the deleted and unresolvable states, document.body.innerHTML does not contain the subject id. Reverse leg R1 put the old definition back (nameField display_title, titleFormat '{process_name} · {record_id}') and got 3 red / 5 green, as predicted, with Received 'flow:invoice_approval · Rd4bl3Rec12489QQ' / '… · D3l3t3dRec12489Q' / '… · Un0penRec12489QQ'. This reproduces report 6278302629 exactly; restore blob == HEAD.",
"H2 HOLDS. The counterpart did not exist, so it was added inside the surface: servedPageReferenceStates-12489 'deleted (sheet: tombstone)' and 'unresolvable (sheet: unresolvableReference)' now assert H1 == the flow label and document.body.innerHTML free of the id. The readable case asserts the H1 too.",
"H3 HOLDS. The 19 ApprovalsInboxPage..test.tsx files at BASE 3aa2f52 are the same 19 as at b017621, and git diff b017621..3aa2f52 touches none of them, nor the served copies or the page. The split stands: 8 retire, 8 kept, 3 mixed (queue cases kept, drawer cases retire). The card's list mapped recordLink and queueHiddenAmount to faces, but both pin only the queue. The surface's consoleFaces.displayLocale-9909 had an approvals drawer half; it retires against the record-page cells' locale pins in packages/fields, and the queue half stays.",
"H4 WIDER THAN STATED. Beyond the four moves: titleFormat becomes '{process_name}' (the pin's); object_name also leaves highlightFields (the pin's); the rows drop the display_title value, because the approvals get serves no formula value at the pin; and the human-submitted rows get a submitter_id, per seat note 6246960490. The StepLine FLOW_ROW stays submitter-less by design.",
"H5 NAVIGATION. PR #12432 serves the page on the standard record route for every surface, and retired the console's own request route. The ruling says 'where the sheet is' but not in-place or navigation, so this reuses the route as is (reasons in summary). The deep link replaces itself in history.",
"H6 MET. The inbox opens a request on the served page. The sheet's code and its 8 sheet-only pins are gone, and so are the 3 drawer cases. Every face card's served-page pin is green at d090848. The new ablated pin is ApprovalsInboxPage.opensServedPage-12484. Chromium: NOT MEASURED, reason: no cheap harness (a browser reading needs an objectstack backend plus a console dev server); the unit harness mounts the real RecordDetailView on the real route."
],
"pin_classification": [
"approverHeadline-12110 · RETIRED · report objectui#12110 item 6 · faces objectui#12482 + #12483 · counterparts: ApprovalDecisionPanel.test 'names who the pending step waits on (objectui#12482)', approverIdentity.test 'falls back to the prettified machine name', servedPageApprovers-12482, servedPageSummary-12483 'the amount is the declared one; a key name is not read' + 'a declared amount of zero still leads', RecordSnapshotSummary.test 'a name never does'",
"characterizationPins · RETIRED · reports objectui#2811, #2803 (charter #6395) · faces #12482, #12491, #12483 · ApprovalDecisionPanel.test 'two people sharing one name in two countersign groups stay two chips'; ApprovalDecisionPanel.flowOrigin-12491 + servedPageStepLine-12491 'a request served with no submitter is marked with the flow origin'; servedPageSummary-12483 declared labels + lead-once",
"deadlineSettled-11815 · RETIRED · report objectui#11815 · face #12483 · RecordSnapshotSummary.test 'a declared deadline is judged against the snapshot (objectui#11815)'; fields dateCells.deadlineSettled-11815 CONTROL",
"eligibleApprovers-12781 · RETIRED · report objectui#12781 · counterpart landed by #12781 itself · ApprovalDecisionPanel.eligibleApprovers-12781",
"hiddenFieldTrim · RETIRED · report objectui#5565 · face #12483 · servedPageSummary-12483 hidden-field row, COUNTER-PROBE, hidden amount never leads · FAILS OPEN case = ruled fail-closed delta",
"noRawPayloadPanel-12490 · RETIRED · report objectui#5553 · face #12490 dropped by the maintainer (objectstack-ai/objectstack#23746 comment 6232118266) · absence holds trivially; seat pointer 6246027348 named it",
"stepProgressVertical · RETIRED · report objectui#5554 · face #12491 · ApprovalDecisionPanel.stepLine-12491 + servedPageStepLine-12491",
"summaryFaces-11677 · RETIRED · report objectui#11677 · face #12483 · servedPageSummary-12483 + servedPageSummaryAmount-12534 · FAILS OPEN case = ruled fail-closed delta",
"recordLinkRefused-11878 · MIXED · drawer case RETIRED against servedPageReferenceStates-12489 'refused (sheet: recordLinkRefused-11878)'; 6 queue cases KEPT · report objectui#11878 · face #12489",
"tombstone · MIXED · drawer case RETIRED against servedPageReferenceStates-12489 'deleted (sheet: tombstone)' (H1 + id-nowhere added here); unit + queue cases KEPT · report objectui#7108 · face #12489",
"unresolvableReference · MIXED · drawer case RETIRED against servedPageReferenceStates-12489 'unresolvable (sheet: unresolvableReference)' (H1 + id-nowhere added here); unit + queue cases KEPT · report objectui#8631 · face #12489",
"KEPT (queue list stays): cellIdentity (objectui#5348), displayLocale-10375 (#10375), pageHeader-12526, pinnedActions-12816, queueHiddenAmount (#6020), recordLink (#5211), tableOverflow-12708, waitingOnOthers-12608",
"consoleFaces.displayLocale-9909 · approvals drawer half RETIRED against packages/fields NumberCellRenderer.grouping 'active display locale' + date-locale-channel; queue half KEPT · report objectui#9909"
],
"tests": "Final union at head d090848: 'pnpm exec vitest run' over these files, 'Test Files 44 passed (44)', 'Tests 369 passed (369)', lock VERDICT command-exit 0. The set: every approvals test under apps/console/src/pages/system and apps/console/src/services; approvalsInboxComponentRef; AppContent.approvalRecordReads; consoleFaces.displayLocale-9909; app-shell views/approval-decision, views/approval-progress and utils/approverIdentity; fields dateCells.deadlineSettled-11815, NumberCellRenderer.grouping and date-locale-channel. Reverse leg R1 (12489 copy, old title definition, via objectstack scripts/ablation-replace.mjs, anchor x1 to x0, blob f51fc03c to 7e797e62): predicted 3 red / 5 green, got 3 red / 5 green; restored, blob == HEAD f51fc03c32f5, git diff HEAD empty. AB1 (BASE's ApprovalsInboxPage.tsx with the sheet put back, blob bc8d0167 to 394c5e9b == BASE blob, markers: the Sheet opener x1 and requestPagePath x0, trap restore on EXIT/INT/TERM): predicted 4 red / 1 green, got 4 red / 1 green ('Unable to find an element by: [data-testid="approval-decision-panel"]'); restored, blob == HEAD bc8d0167, git diff HEAD empty. AB2 (Navigate without replace, via ablation-replace.mjs): predicted 1 red / 4 green, got 1 red / 4 green (Expected /apps/probe_app/home, Received /apps/probe_app/sys_approval_request/record/req_12484); restored. Console tests import src through the root vitest aliases, so there is no dist leg.",
"gates": "Local subset, hand-derived (dispatch-gates.mjs does not serve objectui), each exit captured before any pipe, at head d090848. 'pnpm --filter @object-ui/console type-check' exit 0, script name echoed; run after 'turbo run build --filter=@object-ui/console^...' (34/34 successful); 'tsc --listFiles' includes the new and changed test files. 'pnpm --filter @object-ui/console lint' exit 0, '0 errors, 213 warnings'. pnpm check:new-line-citations exit 0 ('0 new citation(s)'). pnpm check:control-bytes exit 0. node scripts/check-changeset-presence.mjs exit 0 (names .changeset/12484-approvals-served-page.md). node scripts/check-changeset-no-major.mjs exit 0. pnpm check:i18n-keys, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals and check:unreferenced-sources: each exit 0. check-governed-queue-guard.mjs --test over the diff paths: exit 0, NOT GOVERNED. A control-byte self-scan of the added and modified files: grep exit 1 (none). CI owns, not run locally: repo-wide pnpm lint, the test shards, check:eager-closure and check:sdui-registration-pins (both read a console vite build). PR #13290 check-runs, read once at report time: Changeset Fixed Group Check success, label success, dependabot and the Test (coverage) legs skipped; Type Check queued; the other 27 runs in_progress. Those 27 are Lint, Test shards 1-16, Test (dist pins), Changeset Declaration, Changeset Claim Re-read, Changeset Overwrite Report, Changeset Bump Policy, Line Citation Gate, Governed Surface Queue Guard, Repo Gates, Build & E2E, Build Docs, Bundle Analysis and Live E2E (informational). Not waited on, per contract.",
"mcp_calls": "0",
"api_writes": "2 relay strokes. (1) pr_create through scripts/pm/fleet-write/dispatch.mjs: POST repos/objectstack-ai/objectstack/dispatches; the relay ran POST repos/objectstack-ai/objectui/pulls (draft) and its assignees leg POST repos//issues/13290/assignees. Read back: 16904 bytes sent, 16904 stored, identical; assignee huangyiirene. (2) This os-dev-report: POST repos//issues/12484/comments through scripts/pm/post-stamped.mjs. git push is not a REST write. No labels written; 'apps' and 'tests' on the PR come from labeler.yml.",
"deviations": [
"Worktree: 'git worktree add -b' refused because the local branch claude/issue-12484-approvals-served-page already existed at b017621 from the previous dispatch. The worktree took that branch and fast-forwarded it to BASE 3aa2f52 (merge-base --is-ancestor b017621 3aa2f52 exit 0). The first push fast-forwarded the remote from b017621 to 3aa2f52.",
"Commit trailers follow objectui AGENTS.md's model-free pair (Claude-Session + 'Co-authored-by: Claude'), not the harness reminder's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer, not the reminder's footer form.",
"Beyond the brief's literal surface, three in-surface comment citations of the retired pins were repointed (queueHiddenAmount, servedPageApprovers-12482, servedPageSummary-12483), and approvalsInboxComponentRef's comment wording moved off 'drawer'. decisionAmountEntry lost the declared-currency branch only the sheet reached; the queue passed no definitions, so its behaviour is identical, and queueHiddenAmount pins it.",
"Chromium reading NOT MEASURED (H6): no cheap harness."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (Acceptance notes only) · unpinned sheet faces the served page does not carry, a rule-3 shrink. PR #12432 already named three: the request pager with its arrow keys, the SLA and round chips inside the request view, and the 'why can't I act' hint. Also gone: the pending tab's advance-to-next after a decision, the inline reply box (served: the approval_comment action), and the returned request's 'Edit record' button. Whether the served Timeline tab opens an attachment: NOT MEASURED.",
"carrier: none (Acceptance notes only) · dead code after the deletion, outside this claim. approvalsApi.getRequest, listActions and comment have no non-test caller. The sheet-only approvalsInbox.* keys in the ten packs (packages/i18n) have no call site, and check:i18n-dead-keys cannot see them because the inbox builds its keys from the template head 'approvalsInbox.'.",
"carrier: none (Acceptance notes only) · stale comments outside this claim. registerApprovalsComponents.tsx says 'drawer opener'. packages/app-shell DeclaredActionsBar.test.tsx cites ApprovalsInboxPage.tsx by two line addresses as a DeclaredActionsBar host, and it hosts none now. ApprovalDecisionPanel.stepLine-12491.test.tsx's header names the retired stepProgressVertical pin."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 21, 2026
LANDED ·
domain:uiseat 1 ·session_014MXhk1yjWh37d634hLy3p7· 2026-10-21T01:37Z ·pm:dispatchedcleareda91f6bbhas one parent (3aa2f52), andgit merge-base --is-ancestorplaces it onorigin/main(exit 0)gh-readonly-queue/main/pr-13290-*branch remainsorigin/main,ApprovalsInboxPage.tsxholdsrequestPagePath(3), and noSheet/SheetContentand noapproval-decision-panel(0 each). 12ApprovalsInboxPage.*.test.tsxfiles remain: the 19 at the claim, less the 8 retired, plus the newopensServedPage-12484pin6304855892; dev report6305539225; ACCEPT6305587393on PR #13290 (no contract-review face hit); previous dispatch's report6278302629and release6278359397completedat 2026-10-21T01:36Z through the PR'sFixes objectstack-ai/objectui#12484;pm:dispatchedis removed in this actWhat the ruling's item 1 (
6190549995) now delivers:?request=deep link opens the request on the servedsys_approval_request_detailpage, on the standard record route.Shrinks outside the gap table, recorded in the ACCEPT and not pinned before:
approval_commentaction);Dead code after the deletion, noted and not filed:
approvalsApi.getRequest,listActionsandcommenthave no non-test caller;approvalsInbox.*keys in the ten packs have no call site, andcheck:i18n-dead-keyscannot see them behind the template headapprovalsInbox..Next: objectui#12045 (B1), whose
Blocked-by:named this card and whose remaining step this PR carried, closes in the seat's next act.feat(console): the approvals inbox opens a request on its served page…