ObjectStackObjectStack

Execution Context

Execution Context protocol schemas

Source: packages/spec/src/kernel/execution-context.zod.ts

TypeScript Usage

import { ExecutionContextSchema } from '@objectstack/spec/kernel';
import type { ExecutionContext } from '@objectstack/spec/kernel';

// Validate data
const result = ExecutionContextSchema.parse(data);

ExecutionContext

Properties

PropertyTypeRequiredDescription
userIdstringoptional
actorstringoptional
attributedUserIdstringoptional
emailstringoptional
tenantIdstringoptional
timezonestringoptional
localestringoptional
currencystringoptional
positionsstring[]optional (default: [])
principalKindEnum<'human' | 'agent' | 'service' | 'guest' | 'system'>optional
audienceEnum<'internal' | 'external'>optional
postureEnum<'PLATFORM_ADMIN' | 'TENANT_ADMIN' | 'MEMBER' | 'EXTERNAL'>optionalADR-0095 D2 posture rung — PLATFORM_ADMIN crosses the tenant wall where object posture permits; TENANT_ADMIN sees all rows in the org; MEMBER gets business RLS; EXTERNAL sees only explicitly shared rows.
authGate{ code: string; message: string }optionalADR-0069 authentication-policy gate: present only while the principal is blocked from protected resources until they remediate (expired password, enforced MFA), absent for every healthy session. code is the stable machine code the client branches on (PASSWORD_EXPIRED / MFA_REQUIRED) and message is what the blocked user reads; both are required because the transport seam renders them as the 403 body. AUTHENTICATION, not authorization — it suspends access entirely rather than narrowing it, and nothing in the permission/RLS path reads it, while the allow-listed remediation endpoints stay reachable. Server-constructed only, never client-supplied; a guest/anonymous principal never carries one.
onBehalfOf{ userId: string; principalKind?: Enum<'human' | 'agent' | 'service' | 'guest' | 'system'> }optional
performedBy{ clientId: string }optionalADR-0090 D10 rule 4 dual attribution: the agent that PERFORMED this operation, when the performer is not the principal the write is authorized as. Set only at the /mcp OAuth door, on the same branch that decides principalKind: agent and onBehalfOf; absent everywhere else, and the absence is the record that the principal acted for itself. ATTRIBUTION ONLY — no security middleware reads it, it never becomes the authorization subject, and userId stays the human so owner-stamping and current_user.* RLS still resolve to them. Server-constructed only, never client-supplied. Surfaced to hooks as HookContext.provenance.performedByClientId and recorded by the audit writer as sys_audit_log.metadata.performed_by beside on_behalf_of; it does not move actor, which ADR-0118 D1/D5 keeps two-valued.
permissionsstring[]optional (default: [])
systemPermissionsstring[]optional
tabPermissionsRecord<string, Enum<'visible' | 'hidden' | 'default_on' | 'default_off'>>optional
org_user_idsstring[]optional
accessible_org_idsstring[]optional
rlsMembershipRecord<string, string[]>optional
isSystembooleanoptional (default: false)
flowRunIdstringoptional
skipTriggersbooleanoptional
skipAutomationsbooleanoptional
seedReplaybooleanoptional
skipStateMachinebooleanoptional
preserveAuditbooleanoptionalHistorical import: preserve the ORIGINAL audit timeline for this write instead of stamping it "now". Opt-in and server-constructed only, never client-supplied. On the UPDATE path it admits a whitelist — the audit/timestamp family (created_at / created_by / updated_at / updated_by) plus author-declared business readonly fields — while platform-managed system columns (tenancy, generated) stay stripped. On INSERT the exemption does NOT apply: the create-side static readonly strip runs inside engine.insert itself (after the beforeInsert hooks, before validation — the 2026-09-03 ruling; the DataProtocol ingress copy it replaced is deleted) and reads only context.isSystem, so a non-system create carrying preserveAudit still has those fields stripped and is warned (WARN) that the exemption is UPDATE-only — replaying archival readonly facts on create requires a system context. Permissions / RLS / field-level security are unaffected.
oauthScopesstring[]optional
accessTokenstringoptional
transactionanyoptional
traceIdstringoptional

On this page