Skip to content

Commit a52fde2

Browse files
committed
docs(approvals): regenerate the ExecutionContext reference; document the lock's two new behaviours
The `flowRunId` field added to `ExecutionContextSchema` left the GENERATED `content/docs/references/kernel/execution-context.mdx` stale, failing the spec `check:docs` gate. Regenerated via the prescribed path (`gen:schema && gen:docs`) — a one-row addition to the field table. Also updates the hand-written approvals guide, which described the record lock as absolute and predated any automatic recovery: - the lock now exempts the run that opened the request, and the exemption is keyed on run identity rather than elevation, so a `runAs:'user'` run stays RLS-scoped while it writes; - a dead run's lock is released by the sweep, with the note that it acts only on a positively-confirmed terminal run — a paused run, an unknown run, or an unreachable engine all count as alive. `check:docs` and `check:doc-authoring` both green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JGXCuBt5mSXbN3Gc8yfbRv
1 parent 94f9604 commit a52fde2

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

content/docs/automation/approvals.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ The node writes a `sys_approval_request` row: `status: 'pending'`,
210210
record is **locked** against edits while pending (`lockRecord`, default `true`),
211211
and the flow run parks until a decision arrives.
212212

213+
The lock applies to everyone *except the run that opened the request*. A flow may
214+
still write its own target record while its own approval is pending, so it can
215+
never deadlock against itself. The exemption is keyed on run identity rather than
216+
elevation, so a `runAs:'user'` run stays row-level-security scoped while it
217+
writes — it does not become a system write.
218+
213219
Only `approvers` is required on the node; everything else has a default
214220
(`behavior: 'first_response'`, `lockRecord: true`, `maxRevisions: 3`).
215221

@@ -383,6 +389,20 @@ and is audited under the admin's own id. Prefer a guaranteed-staffed fallback
383389
approver so the set is never empty in the first place.
384390
</Callout>
385391

392+
<Callout type="info">
393+
**A dead run releases its own lock.** If the flow run that opened an approval
394+
reaches a terminal state without a decision — it failed, was cancelled, timed
395+
out, or the process hosting it crashed — nothing is left to decide the request,
396+
so a periodic sweep finalizes it as `recalled` and releases the record. The
397+
audit row records the actor `system:dead-run` and names the run and its status,
398+
so it reads distinctly from a submitter's own recall.
399+
400+
The sweep only ever acts on a run it can positively confirm is terminal: a
401+
paused run (the normal state of a live approval), an unknown run, or an
402+
unreachable automation engine all count as *alive* and are left untouched. It
403+
frees orphaned records; it never cancels a live approval.
404+
</Callout>
405+
386406
### Progress and notification deep links
387407

388408
A pending multi-approver request also carries a **server-computed

content/docs/references/kernel/execution-context.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const result = ExecutionContext.parse(data);
6666
| **accessible_org_ids** | `string[]` | optional | |
6767
| **rlsMembership** | `Record<string, string[]>` | optional | |
6868
| **isSystem** | `boolean` || |
69+
| **flowRunId** | `string` | optional | |
6970
| **skipTriggers** | `boolean` | optional | |
7071
| **skipAutomations** | `boolean` | optional | |
7172
| **seedReplay** | `boolean` | optional | |

0 commit comments

Comments
 (0)