From 36872287929d7bc95d406d506c65de659447238d Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 22:07:02 +0000 Subject: [PATCH] docs(ui): the flow face of `recordLoadDenied` is populated since #15168 (#15303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Flow actions" paragraph under "Authorization inside an action" still carried the honesty clause the contract's TSDoc carried before #15168: that on the flow face `recordLoadDenied` is "declared but not yet populated" and a guard on it is "inert (never `true`), never wrong". That is false on `main`. `dispatchFlowAction` spreads `actionRecordLoadSignal(subject)` into the context it hands `automation.execute` (`packages/runtime/src/action-execution.ts:904`), and both action doors reach it through that one function — the REST `/actions` route (`packages/runtime/src/domains/actions.ts:732`) and the MCP `run_action` bridge (`packages/runtime/src/action-execution.ts:1758`), each passing the whole `ActionSubjectRecordLoad` rather than a bare record. The direction of the defect is the inverted form of the Prime Directive #10 corollary: not a doc advertising a capability the runtime does not deliver, but a doc denying one it now does — so an author reading it would not write the `runAs: 'system'` guard the two-card sequence exists to enable, and no gate reports it. The replacement transcribes the sentence that landed on the contract (`packages/spec/src/contracts/automation-service.ts:56`), adapted to docs voice by naming the two doors, which that page's readers otherwise cannot resolve. The surrounding `runAs: 'user'` / `runAs: 'system'` prose and the `ctx.record.id` table are untouched. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --- content/docs/ui/actions.mdx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/content/docs/ui/actions.mdx b/content/docs/ui/actions.mdx index c95a1808d8..9e35e501a1 100644 --- a/content/docs/ui/actions.mdx +++ b/content/docs/ui/actions.mdx @@ -379,11 +379,12 @@ default for a row-scoped action on a `private` object is to refuse. (`AutomationContext`, the `@objectstack/spec` contract) declares the same key in the same spelling, `recordLoadDenied?: true`, so a `runAs: 'system'` flow has something to guard on before it acts on a row its invoker could not read. -On the flow face the key is **declared but not yet populated**: the flow -dispatcher does not pass the signal into the run's context yet, so until that -lands a flow run never sees it and a guard on it is inert (never `true`), never -wrong. A `runAs: 'user'` flow needs no guard — it re-derives the caller's -scope on its own reads, and the stub resolves to nothing. +On the flow face the key is **populated** since #15168: `dispatchFlowAction` +takes the producer's load outcome and spreads the signal into the context it +hands `automation.execute`, on both doors — the REST `/actions` endpoint and +the MCP `run_action` bridge — so a flow run receives this key exactly when a +handler would. A `runAs: 'user'` flow needs no guard — it re-derives the +caller's scope on its own reads, and the stub resolves to nothing. ## Call it over REST