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 }}
Repository navigation
Console: send a same-origin type: 'api' action click through POST /actions/:object/:action instead of fetching its target directly (ruling on #27506, step 3 of 3) #27611
立卡门:③ 维护者直派(ruling on #27506, comment 6499781492)。
What this card is
Step 3 of the three-step ruling on #27506 (comment 6499781492). The maintainer's words, verbatim and untranslated (card thread of #27506, 2026-10-29): 「我们的平台设计目标是 agent 和人类使用同一套系统」 · 「同意」.
Blocked-by: #27506 (step 2, the server door accepting type: 'api' declared actions and forwarding to the declared target). Do not start before that PR is on main.
Business reason
Today the console's two api handlers fetch an api action's target directly (ui/packages/app-shell/src/hooks/useConsoleActionRuntime.tsxapiHandler, ui/packages/app-shell/src/views/RecordDetailView.tsxapiHandler), so the click never meets the platform's gates: switching Ban User off in Setup › Packaged automation does not stop the button (#27506), and the human click and an agent's run_action take different roads. After step 2 the door runs the ADR-0126 switch, ADR-0066 D4, the anonymous baseline and the audit, then forwards to the same target; the console only has to send the click there.
Scope
Both api handlers: for a declared type: 'api' action whose target is a same-origin platform path, POST /api/v1/actions/:object/:action (or /actions/global/:action) with { recordId, params } the way the script handler (serverActionHandler) already does; the server assembles the target body from the declaration (recordIdParam, bodyShape.wrap, bodyExtra, method, target placeholders). Page-variable tokens ({{page.x}}) are client state: keep resolving them client-side and send the resolved values as params.
An api action whose target is not same-origin keeps today's direct fetch (the server refuses to govern it; see the ruling).
Keep the newTabUrl fast path (withNewTabUrlFastPath), the entitlement-dialog mapping of coded 403s, the { success, data } unwrapping and refreshAfter as they are; the response shape from the door is the forwarded target's data.
Pins: a switched-off api action's click answers the door's 409 ACTION_DISABLED and nothing is sent to the target; a switched-on click reaches the target through the door with the same body as before (compare the recorded request); an off-origin target still goes direct.
Who acts
ui lane. Sibling #27504 (the switched-off button stays visible and its toast wording) is a separate card and stays open.
Dedupe
Searched issues for "Ban User button stays live after packaged action switched off" (5 hits: #27506, #27504, none on the console sending api clicks through the door) and "api type action dispatched through platform action route" (11 hits, none). Dedupe words: apiHandler, type api, /actions door, useConsoleActionRuntime, RecordDetailView
For step 3 of the #27506 ruling · 2026-10-29T18:33Z · ⛔ not a claim.
PR #27664 (card #27610) amends ADR-0066 D4 and the requiredPermissions.describe() to the ruling. These ui sites still quote the superseded text ("action route (script/flow/modal + MCP) …" / "never for a type: api action pointed at a custom endpoint") and fall to this card:
Note for whoever claims this card (from the ADR contract review on #27664, record 6505129020): the file list above misses one console surface that restates the old ADR-0066 D4 api clause. ui/packages/plugin-detail/src/RelatedList.tsx (around L810, the list_toolbar docblock quoting "enforced with 403 on the platform action route (script/flow/modal + MCP)") and its pin ui/packages/plugin-detail/src/__tests__/RelatedList.toolbarCapabilityGate-9782.test.tsx (around L14). Once #27610's ADR text and #27649 land, an api click through the door is enforced at the route too, so read both against the new clause when this card is cut.
Claim: PM loop round 1
Session: session_01Utp6CbDAucNyQ4UtzCJKyh
Account: os-bill
Branch: claude/project-thread-d3yu0i (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-27611
Domain: domain:ui
Seat: domain:ui#4
File surface: ui/packages/app-shell/src/hooks/useConsoleActionRuntime.tsx (apiHandler and direct helpers), ui/packages/app-shell/src/views/RecordDetailView.tsx (apiHandler only; seat 2's #27640 edits fmtCtx in the same file and spec draft PR #27713 also touches it: different regions, second to merge resolves), ui/packages/app-shell/src/utils/flowResponse.ts if the door envelopes need it, the six ADR-0066 D4 docblock/pin sites of comments 6505154678 and 6505165215 (components containers.tsx + two tests, plugin-grid bulkActionCapabilityGate test, plugin-detail RelatedList.tsx + its 9782 test), tests beside, root .changeset/ (stop on breach; explain in the report)
Container & model: L, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on ecd944f5: no path-derived mandate), effort: xhigh
Clause-②: no
Metadata-protocol: none
Responsibility: same-origin type: api clicks POST through /api/v1/actions/:object/:action; off-origin stays direct; pins per the card (409 ACTION_DISABLED sends nothing to the target; switched-on body unchanged; off-origin direct)
Thread-read: 6505165215
Premise: holds
Serial constraints cleared: step 2 #27506 (PR #27649) and ADR amendment #27610 (PR #27664) merged; RecordDetailView overlap with #27640 (seat 2) and PR #27713 (spec) declared
Dispatched 2026-10-29T21:46Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
{
"issue": 27611,
"status": "done",
"branch": "claude/project-thread-d3yu0i",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27793",
"session": "session_01Utp6CXnX1eGkqKFsNRxR8H",
"premise_still_valid": true,
"summary": "Both console api handlers send a click on a DECLARED same-origin type api action to POST /api/v1/actions/:object/:action with { recordId: subject row id, params } through core's createServerActionHandler; off-origin targets, clicks naming no declared action and object-less declared actions keep the direct fetch. The door is chosen by lookup in the host's object metadata (new module-internal utils/apiActionDoor.ts: isSameOriginApiTarget restating the server predicate, findDeclaredApiAction tolerant of runner-interpolated ${...} tokens, sendApiActionThroughDoor, readApiActionDoorSuccess). Non-2xx answers keep each host's reader (entitlement dialog then apiActionFailureMessage in the list runtime, apiActionFailureMessage on the record page), so 409 ACTION_DISABLED shows its sentence; 2xx reads the door's data through the /actions envelope rule, so a bare better-auth payload behind a resultDialog reads at the same level as before. Six docblock/pin sites aligned to amended ADR-0066 D4. Server gaps G1 (door drops error.details/userMessage) and G2 (param contract refuses approval outputs.<key>) were stopped on and reported; the seat filed #27738 and ruled Route A, so the PR is draft with Blocked-by: #27738 and the three regression pins are written against the door's post-#27738 answer, shown only against a mocked door. Opened with no assignee and no review request (maintainer rule); the harness after-PR assign/review step was skipped on purpose.",
"tests": "Final head b6ee6801 (post-merge), lock VERDICT command-exit 0: vitest on 3 new + 7 updated files, Test Files 10 passed, Tests 71 passed; pnpm --filter @object-ui/app-shell run type-check (tsc --noEmit + tsconfig.test.json) exit 0. Affected surface on bd2818b4 (714 ui test files selected by grep for api actions, api handlers, the /actions route, useConsoleActionRuntime, RecordDetailView, ObjectView, PageView): Test Files 714 passed, Tests 8944 passed, VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs on source-imported suites (anchor 1 -> 0, blob 82d30ed8bd08 -> b3f537e95b1e), marker 'ABLATED_27611' making findDeclaredApiAction answer undefined: 10-file set 27 red / 44 green (every updated pin red); after strengthening two pins that read alike on both roads, the 3 new files 17 red / 8 green (every door-road case red; the 4 direct-road controls, the predicate and negative lookup cases green); restore blob == HEAD 82d30ed8bd08, git diff HEAD empty.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on b6ee6801: 34 derived, 34 run, all exit 0 (incl. check-sdui-manifest.mjs and --self-test, check:nul-bytes), lock VERDICT command-exit 0; --ran reconciliation: 34 run, 0 NOT-MEASURED, 0 UNRUN. Outside derivation: pnpm --dir ui run check:new-line-citations exit 0 (0 new citations); app-shell type-check exit 0. CI on b6ee6801 at report time: Governed Surface Queue Guard success; Check Changeset, Check PR Size, Lint (8 lanes), Type Check (4 lanes), PR-body guards, filter in_progress; three opt-in lanes skipped.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no MCP GitHub tool used. Non-GitHub MCP: mcp__claude-code-remote__get_session x1 (session id), mcp__claude-code-remote__subscribe_pr_activity x1 on PR 27793 (this session's event subscription; writes nothing to GitHub).",
"api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 40973109951, PR 27793, body read back identical, assignees none); this report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27611/comments). git push x3 not counted (not REST).",
"line_budget": "20 files, +1044 / -65 vs origin/main (git diff --shortstat), under the 3000 human-merge threshold",
"files_changed": [
".changeset/27611-api-action-click-through-door.md",
"ui/apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx",
"ui/packages/app-shell/src/hooks/__tests__/useConsoleActionRuntime.apiActionDoor-27611.test.tsx",
"ui/packages/app-shell/src/hooks/useConsoleActionRuntime.tsx",
"ui/packages/app-shell/src/utils/__tests__/apiActionDoor.test.ts",
"ui/packages/app-shell/src/utils/apiActionDoor.ts",
"ui/packages/app-shell/src/views/ObjectView.inviteFeedback-11817.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.accessEndedAfterDecision-26589.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.apiActionDoor-27611.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.apiNewTabUrl-26747.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.approvalDeclaredActions.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.printPageHeaderActions-12906.test.tsx",
"ui/packages/app-shell/src/views/RecordDetailView.tsx",
"ui/packages/app-shell/src/views/__tests__/PageView.relatedListActions-12870.test.tsx",
"ui/packages/components/src/__tests__/action-bar.test.tsx",
"ui/packages/components/src/__tests__/page-header-capability-gate.test.tsx",
"ui/packages/components/src/renderers/layout/containers.tsx",
"ui/packages/plugin-detail/src/RelatedList.tsx",
"ui/packages/plugin-detail/src/__tests__/RelatedList.toolbarCapabilityGate-9782.test.tsx",
"ui/packages/plugin-grid/src/__tests__/bulkActionCapabilityGate.test.tsx"
],
"deviations": [
"RecordDetailView.tsx (hot file, seat ruling): the edit stays inside apiHandler plus its import line and `objects` added to that handler's useCallback dependency list; origin/main merged before the PR opened.",
"Record page 2xx level: the record page's direct fetch handed back the target's whole body; on the door road it hands back the door's data (the list runtime's level). Without this a bare better-auth answer behind a one-shot resultDialog (rotate_client_secret, enable_two_factor on record pages) would come back wrapped and the dialog would read nothing. A relayed HTTP 200 rejection is now a failure on the record page too. Declared in the PR acceptance notes.",
"The 714-file affected-surface run is a grep-selected subset, not the full ui suite, and ran on bd2818b4 (before the pin-strengthening commit and the origin/main merge); the final head was re-measured on the 10 card files plus app-shell type-check. CI runs the full farm.",
"Harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; followed os-dev instead (model-free trailer pair on every commit incl. the merge commit, session-URL PR footer).",
"PR body attribution line links the seat thread exactly as the dispatch order spells it (thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: #27738 · server door drops the target's error.details and userMessage, and its param contract refuses approval decision outputs.<key> params on approval_approve / approval_reject; filed by the seat",
"carrier: seat (suggested for #27738) · no server test pins buildApiActionRequest's outputs.* fold, which the console now relies on",
"carrier: none · noted, not filed — by code reading only (not reproduced): a target answering HTTP 200 { success: false, data } loses its rejection at the door (apiActionResultOf returns data), and 200 { success: false, message } with non-legacy keys reads as success under the narrow /actions rule; no producer measured; dedupe words: apiActionResultOf, 200 success false, action door forward",
"carrier: none · noted, not filed — object-less declared api actions (/actions/global/:action) and standalone action rows are invisible to the console lookup, so their click stays direct and their activation switch does not hold on a click; dedupe words: global api action, action door, lookup"
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 审批与自动化 | none | P②
Triage: p1 ·
domain:ui·area:automation·pm:blockedon #27506 · 2026-10-29T15:10Z⛔ Not a claim.
6499781492). The priority is the parent's.main.enhancement,pm:blocked.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:skills#1 · marchtian · session_017ihL2dPRZXfgE1A2Vct3FU
For step 3 of the #27506 ruling · 2026-10-29T18:33Z · ⛔ not a claim.
PR #27664 (card #27610) amends ADR-0066 D4 and the
requiredPermissions.describe()to the ruling. These ui sites still quote the superseded text ("action route (script/flow/modal + MCP) …"/ "never for atype: apiaction pointed at a custom endpoint") and fall to this card:ui/packages/components/src/renderers/layout/containers.tsx~L2015ui/packages/components/src/__tests__/action-bar.test.tsx~L408ui/packages/components/src/__tests__/page-header-capability-gate.test.tsx~L12ui/packages/plugin-grid/src/__tests__/bulkActionCapabilityGate.test.tsx~L15ui/packages/plugin-detail/src/RelatedList.tsxL810ui/packages/plugin-detail/src/__tests__/RelatedList.toolbarCapabilityGate-9782.test.tsxL14The last two were found by the at-tier contract review 6505129020 on #27664.
objectstack-fleet commentedon Oct 29, 2026
domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw
Note for whoever claims this card (from the ADR contract review on #27664, record 6505129020): the file list above misses one console surface that restates the old ADR-0066 D4 api clause.
ui/packages/plugin-detail/src/RelatedList.tsx(around L810, thelist_toolbardocblock quoting "enforced with 403 on the platform action route (script/flow/modal + MCP)") and its pinui/packages/plugin-detail/src/__tests__/RelatedList.toolbarCapabilityGate-9782.test.tsx(around L14). Once #27610's ADR text and #27649 land, an api click through the door is enforced at the route too, so read both against the new clause when this card is cut.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
Claim: PM loop round 1
Session:
session_01Utp6CbDAucNyQ4UtzCJKyhAccount:
os-billBranch:
claude/project-thread-d3yu0i(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-27611Domain:
domain:uiSeat:
domain:ui#4File surface:
ui/packages/app-shell/src/hooks/useConsoleActionRuntime.tsx(apiHandlerand direct helpers),ui/packages/app-shell/src/views/RecordDetailView.tsx(apiHandleronly; seat 2's #27640 editsfmtCtxin the same file and spec draft PR #27713 also touches it: different regions, second to merge resolves),ui/packages/app-shell/src/utils/flowResponse.tsif the door envelopes need it, the six ADR-0066 D4 docblock/pin sites of comments 6505154678 and 6505165215 (componentscontainers.tsx + two tests,plugin-gridbulkActionCapabilityGate test,plugin-detailRelatedList.tsx + its 9782 test), tests beside, root.changeset/(stop on breach; explain in the report)Container & model:
L,mode:thread,model: TIER_DEFAULT(dispatch-gates --tieronecd944f5: no path-derived mandate),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility: same-origin
type: apiclicks POST through/api/v1/actions/:object/:action; off-origin stays direct; pins per the card (409 ACTION_DISABLED sends nothing to the target; switched-on body unchanged; off-origin direct)Thread-read: 6505165215
Premise: holds
Serial constraints cleared: step 2 #27506 (PR #27649) and ADR amendment #27610 (PR #27664) merged; RecordDetailView overlap with #27640 (seat 2) and PR #27713 (spec) declared
Dispatched 2026-10-29T21:46Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:ui#4 · os-bill · session_01Utp6CXnX1eGkqKFsNRxR8H
os-dev-report
{ "issue": 27611, "status": "done", "branch": "claude/project-thread-d3yu0i", "pr": "https://github.com/objectstack-ai/objectstack/pull/27793", "session": "session_01Utp6CXnX1eGkqKFsNRxR8H", "premise_still_valid": true, "summary": "Both console api handlers send a click on a DECLARED same-origin type api action to POST /api/v1/actions/:object/:action with { recordId: subject row id, params } through core's createServerActionHandler; off-origin targets, clicks naming no declared action and object-less declared actions keep the direct fetch. The door is chosen by lookup in the host's object metadata (new module-internal utils/apiActionDoor.ts: isSameOriginApiTarget restating the server predicate, findDeclaredApiAction tolerant of runner-interpolated ${...} tokens, sendApiActionThroughDoor, readApiActionDoorSuccess). Non-2xx answers keep each host's reader (entitlement dialog then apiActionFailureMessage in the list runtime, apiActionFailureMessage on the record page), so 409 ACTION_DISABLED shows its sentence; 2xx reads the door's data through the /actions envelope rule, so a bare better-auth payload behind a resultDialog reads at the same level as before. Six docblock/pin sites aligned to amended ADR-0066 D4. Server gaps G1 (door drops error.details/userMessage) and G2 (param contract refuses approval outputs.<key>) were stopped on and reported; the seat filed #27738 and ruled Route A, so the PR is draft with Blocked-by: #27738 and the three regression pins are written against the door's post-#27738 answer, shown only against a mocked door. Opened with no assignee and no review request (maintainer rule); the harness after-PR assign/review step was skipped on purpose.", "tests": "Final head b6ee6801 (post-merge), lock VERDICT command-exit 0: vitest on 3 new + 7 updated files, Test Files 10 passed, Tests 71 passed; pnpm --filter @object-ui/app-shell run type-check (tsc --noEmit + tsconfig.test.json) exit 0. Affected surface on bd2818b4 (714 ui test files selected by grep for api actions, api handlers, the /actions route, useConsoleActionRuntime, RecordDetailView, ObjectView, PageView): Test Files 714 passed, Tests 8944 passed, VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs on source-imported suites (anchor 1 -> 0, blob 82d30ed8bd08 -> b3f537e95b1e), marker 'ABLATED_27611' making findDeclaredApiAction answer undefined: 10-file set 27 red / 44 green (every updated pin red); after strengthening two pins that read alike on both roads, the 3 new files 17 red / 8 green (every door-road case red; the 4 direct-road controls, the predicate and negative lookup cases green); restore blob == HEAD 82d30ed8bd08, git diff HEAD empty.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on b6ee6801: 34 derived, 34 run, all exit 0 (incl. check-sdui-manifest.mjs and --self-test, check:nul-bytes), lock VERDICT command-exit 0; --ran reconciliation: 34 run, 0 NOT-MEASURED, 0 UNRUN. Outside derivation: pnpm --dir ui run check:new-line-citations exit 0 (0 new citations); app-shell type-check exit 0. CI on b6ee6801 at report time: Governed Surface Queue Guard success; Check Changeset, Check PR Size, Lint (8 lanes), Type Check (4 lanes), PR-body guards, filter in_progress; three opt-in lanes skipped.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0 — no MCP GitHub tool used. Non-GitHub MCP: mcp__claude-code-remote__get_session x1 (session id), mcp__claude-code-remote__subscribe_pr_activity x1 on PR 27793 (this session's event subscription; writes nothing to GitHub).", "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 40973109951, PR 27793, body read back identical, assignees none); this report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27611/comments). git push x3 not counted (not REST).", "line_budget": "20 files, +1044 / -65 vs origin/main (git diff --shortstat), under the 3000 human-merge threshold", "files_changed": [ ".changeset/27611-api-action-click-through-door.md", "ui/apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx", "ui/packages/app-shell/src/hooks/__tests__/useConsoleActionRuntime.apiActionDoor-27611.test.tsx", "ui/packages/app-shell/src/hooks/useConsoleActionRuntime.tsx", "ui/packages/app-shell/src/utils/__tests__/apiActionDoor.test.ts", "ui/packages/app-shell/src/utils/apiActionDoor.ts", "ui/packages/app-shell/src/views/ObjectView.inviteFeedback-11817.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.accessEndedAfterDecision-26589.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.apiActionDoor-27611.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.apiNewTabUrl-26747.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.approvalDeclaredActions.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.printPageHeaderActions-12906.test.tsx", "ui/packages/app-shell/src/views/RecordDetailView.tsx", "ui/packages/app-shell/src/views/__tests__/PageView.relatedListActions-12870.test.tsx", "ui/packages/components/src/__tests__/action-bar.test.tsx", "ui/packages/components/src/__tests__/page-header-capability-gate.test.tsx", "ui/packages/components/src/renderers/layout/containers.tsx", "ui/packages/plugin-detail/src/RelatedList.tsx", "ui/packages/plugin-detail/src/__tests__/RelatedList.toolbarCapabilityGate-9782.test.tsx", "ui/packages/plugin-grid/src/__tests__/bulkActionCapabilityGate.test.tsx" ], "deviations": [ "RecordDetailView.tsx (hot file, seat ruling): the edit stays inside apiHandler plus its import line and `objects` added to that handler's useCallback dependency list; origin/main merged before the PR opened.", "Record page 2xx level: the record page's direct fetch handed back the target's whole body; on the door road it hands back the door's data (the list runtime's level). Without this a bare better-auth answer behind a one-shot resultDialog (rotate_client_secret, enable_two_factor on record pages) would come back wrapped and the dialog would read nothing. A relayed HTTP 200 rejection is now a failure on the record page too. Declared in the PR acceptance notes.", "The 714-file affected-surface run is a grep-selected subset, not the full ui suite, and ran on bd2818b4 (before the pin-strengthening commit and the origin/main merge); the final head was re-measured on the 10 card files plus app-shell type-check. CI runs the full farm.", "Harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; followed os-dev instead (model-free trailer pair on every commit incl. the merge commit, session-URL PR footer).", "PR body attribution line links the seat thread exactly as the dispatch order spells it (thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgDFH4S5pR1C8YvYCWWsZfXx)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: #27738 · server door drops the target's error.details and userMessage, and its param contract refuses approval decision outputs.<key> params on approval_approve / approval_reject; filed by the seat", "carrier: seat (suggested for #27738) · no server test pins buildApiActionRequest's outputs.* fold, which the console now relies on", "carrier: none · noted, not filed — by code reading only (not reproduced): a target answering HTTP 200 { success: false, data } loses its rejection at the door (apiActionResultOf returns data), and 200 { success: false, message } with non-legacy keys reads as success under the narrow /actions rule; no producer measured; dedupe words: apiActionResultOf, 200 success false, action door forward", "carrier: none · noted, not filed — object-less declared api actions (/actions/global/:action) and standalone action rows are invisible to the console lookup, so their click stays direct and their activation switch does not hold on a click; dedupe words: global api action, action door, lookup" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh
ACCEPT → PR #27793 comment 6519049786 · 2026-10-30T09:03Z
Generated by Claude Code