@ixo/editor 6.34.0 → 6.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/{BidFlowDetail-TJCJBJZZ.js → BidFlowDetail-U2SX5M7F.js} +3 -3
  2. package/dist/{ClaimFlowDetail-UVEQMEI5.js → ClaimFlowDetail-I4OQSHAB.js} +3 -3
  3. package/dist/{CollectionLifecycleFlowDetail-WFCSVIIG.js → CollectionLifecycleFlowDetail-LQHKB227.js} +3 -3
  4. package/dist/{CollectionUsersFlowDetail-ZLCJBWHG.js → CollectionUsersFlowDetail-HELGXFYN.js} +5 -5
  5. package/dist/{EvaluateBidFlowDetail-2S2N4YTW.js → EvaluateBidFlowDetail-YR7PK7EG.js} +5 -5
  6. package/dist/{EvaluateClaimFlowDetail-QYR7PJRD.js → EvaluateClaimFlowDetail-FEUMB37M.js} +4 -4
  7. package/dist/{IdentityCreateFlowDetail-WGKO43IH.js → IdentityCreateFlowDetail-4TE6UCEB.js} +2 -2
  8. package/dist/{IidCreateFlowDetail-6M32S6XS.js → IidCreateFlowDetail-HPVZAHVY.js} +2 -2
  9. package/dist/{KycVerifyFlowDetail-EWOMXSD3.js → KycVerifyFlowDetail-FEU43HML.js} +2 -2
  10. package/dist/{OracleConfigureOracleFlowDetail-73BHAN76.js → OracleConfigureOracleFlowDetail-MIBXUEKC.js} +2 -2
  11. package/dist/{OracleStoreSecretsAndConfigFlowDetail-BFV2EHLT.js → OracleStoreSecretsAndConfigFlowDetail-HQU3UKEB.js} +2 -2
  12. package/dist/{OracleStoreSecretsFlowDetail-DNNOPHVA.js → OracleStoreSecretsFlowDetail-5RXWQ3KA.js} +2 -2
  13. package/dist/{ProposalCreateFlowDetail-4VZZPAWH.js → ProposalCreateFlowDetail-2FCRCNYV.js} +2 -2
  14. package/dist/{chunk-HRRI4BLF.js → chunk-5E6Z6JJN.js} +1 -1
  15. package/dist/chunk-5E6Z6JJN.js.map +1 -0
  16. package/dist/{chunk-JBBFSORW.js → chunk-BLFBVFHV.js} +2 -2
  17. package/dist/{chunk-JBBFSORW.js.map → chunk-BLFBVFHV.js.map} +1 -1
  18. package/dist/{chunk-3O42FYT3.js → chunk-F5GTFCYV.js} +2 -2
  19. package/dist/chunk-F5GTFCYV.js.map +1 -0
  20. package/dist/{chunk-2WPEATI7.js → chunk-JB6ASLUJ.js} +2 -2
  21. package/dist/{chunk-3XSLBJYI.js → chunk-MZIBZ5FY.js} +2 -2
  22. package/dist/{chunk-6ESTNTSH.js → chunk-WZW2WDJM.js} +2 -2
  23. package/dist/{chunk-D2CQPNQG.js → chunk-YAY3ZF3O.js} +16 -16
  24. package/dist/chunk-YAY3ZF3O.js.map +1 -0
  25. package/dist/core/index.cjs.map +1 -1
  26. package/dist/core/index.js +3 -3
  27. package/dist/index.js +4 -4
  28. package/dist/mantine/index.js +3 -3
  29. package/package.json +1 -1
  30. package/dist/chunk-3O42FYT3.js.map +0 -1
  31. package/dist/chunk-D2CQPNQG.js.map +0 -1
  32. package/dist/chunk-HRRI4BLF.js.map +0 -1
  33. /package/dist/{BidFlowDetail-TJCJBJZZ.js.map → BidFlowDetail-U2SX5M7F.js.map} +0 -0
  34. /package/dist/{ClaimFlowDetail-UVEQMEI5.js.map → ClaimFlowDetail-I4OQSHAB.js.map} +0 -0
  35. /package/dist/{CollectionLifecycleFlowDetail-WFCSVIIG.js.map → CollectionLifecycleFlowDetail-LQHKB227.js.map} +0 -0
  36. /package/dist/{CollectionUsersFlowDetail-ZLCJBWHG.js.map → CollectionUsersFlowDetail-HELGXFYN.js.map} +0 -0
  37. /package/dist/{EvaluateBidFlowDetail-2S2N4YTW.js.map → EvaluateBidFlowDetail-YR7PK7EG.js.map} +0 -0
  38. /package/dist/{EvaluateClaimFlowDetail-QYR7PJRD.js.map → EvaluateClaimFlowDetail-FEUMB37M.js.map} +0 -0
  39. /package/dist/{IdentityCreateFlowDetail-WGKO43IH.js.map → IdentityCreateFlowDetail-4TE6UCEB.js.map} +0 -0
  40. /package/dist/{IidCreateFlowDetail-6M32S6XS.js.map → IidCreateFlowDetail-HPVZAHVY.js.map} +0 -0
  41. /package/dist/{KycVerifyFlowDetail-EWOMXSD3.js.map → KycVerifyFlowDetail-FEU43HML.js.map} +0 -0
  42. /package/dist/{OracleConfigureOracleFlowDetail-73BHAN76.js.map → OracleConfigureOracleFlowDetail-MIBXUEKC.js.map} +0 -0
  43. /package/dist/{OracleStoreSecretsAndConfigFlowDetail-BFV2EHLT.js.map → OracleStoreSecretsAndConfigFlowDetail-HQU3UKEB.js.map} +0 -0
  44. /package/dist/{OracleStoreSecretsFlowDetail-DNNOPHVA.js.map → OracleStoreSecretsFlowDetail-5RXWQ3KA.js.map} +0 -0
  45. /package/dist/{ProposalCreateFlowDetail-4VZZPAWH.js.map → ProposalCreateFlowDetail-2FCRCNYV.js.map} +0 -0
  46. /package/dist/{chunk-2WPEATI7.js.map → chunk-JB6ASLUJ.js.map} +0 -0
  47. /package/dist/{chunk-3XSLBJYI.js.map → chunk-MZIBZ5FY.js.map} +0 -0
  48. /package/dist/{chunk-6ESTNTSH.js.map → chunk-WZW2WDJM.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/types/baseUcan.ts","../src/core/lib/flowEngine/triggers.ts","../src/core/lib/flowEngine/versionManifest.ts","../src/core/lib/flowEngine/reconcile.ts","../src/core/lib/flowEngine/emitEvents.ts","../src/core/lib/flowEngine/runtime.ts","../src/core/lib/flowEngine/conditions.ts","../src/core/lib/flowEngine/utils.ts","../src/core/lib/flowEngine/proof.ts","../src/core/lib/flowEngine/completion.ts","../src/core/lib/flowAgent/store.ts","../src/core/lib/flowAgent/utils.ts","../src/core/lib/flowEngine/runMigration.ts","../src/core/lib/flowEngine/runLifecycle.ts","../src/core/lib/flowCompiler/resolveRefs.ts","../src/core/lib/flowEngine/authorization.ts","../src/core/lib/flowEngine/executor.ts","../src/core/lib/flowEngine/readBackReconciler.ts","../src/core/lib/flowEngine/actionExecutor.ts","../src/core/lib/flowEngine/verifiedCompletion.ts","../src/core/lib/invocationStore.ts","../src/core/lib/flowEngine/blockPhase.ts","../src/core/lib/flowEngine/validateBlockConfig.ts","../src/core/lib/flowEngine/migration.ts","../src/core/lib/flowEngine/migrations/v0_3_to_v1_0_0.ts"],"sourcesContent":["// ─── Base UCAN Flow Plan ────────────────────────────────────────────────────\n// A structured, capability-shaped planning document that borrows UCAN semantics.\n// The AI generates this plan; the compiler turns it into blocks + graph + Yjs state.\n\n/** Condition that gates when a capability activates. */\nexport interface ConditionRef {\n /** ID of the upstream capability whose output is checked. */\n sourceId: string;\n /** Output field path to inspect, e.g., \"decision\". */\n field: string;\n /** Comparison operator. */\n operator: 'eq' | 'neq' | 'gt' | 'lt' | 'in' | 'exists';\n /** Value to compare against (omit for 'exists'). */\n value?: unknown;\n /** What happens when the condition is (not) met. */\n effect?: {\n action: 'enable' | 'disable' | 'hide' | 'show';\n message?: string;\n };\n}\n\n/** Authorization constraint for a capability. */\nexport interface ActorConstraint {\n /** Whitelisted actor DIDs. */\n authorisedActors?: string[];\n /** Parent capability URI for delegation chain. */\n parentCapability?: string;\n}\n\n/** Time-to-live constraint for a capability. */\nexport interface TTLConstraint {\n /** Hard deadline (ISO 8601 date string). */\n absoluteDueDate?: string;\n /** Duration from when the block becomes enabled (ISO 8601 duration, e.g., \"P7D\"). */\n fromEnablement?: string;\n /** Duration from when an actor commits (ISO 8601 duration, e.g., \"PT2H\"). */\n fromCommitment?: string;\n}\n\n/**\n * A single capability in a Base UCAN flow plan.\n *\n * UCAN semantics:\n * can = the action\n * with = the resource or scope\n * nb = typed caveats, inputs, parameters\n *\n * Workflow semantics (kept separate from nb):\n * condition, trigger, parallelGroup, phase\n */\nexport interface FlowCapability {\n /** Stable node identifier for this step. */\n id: string;\n /** UCAN-style ability string, e.g., \"bid/submit\", \"email/send\". */\n can: string;\n /** Resource URI, e.g., \"ixo:flow:{flowId}\" or \"ixo:flow:{flowId}:{nodeId}\". */\n with: string;\n /** Typed caveats / input parameters. Shape is dictated by the action registry. */\n nb?: Record<string, unknown>;\n\n // ── Workflow topology ──\n /** Condition that must be met for this capability to activate. */\n condition?: ConditionRef;\n /** Capabilities sharing a parallelGroup run concurrently. */\n parallelGroup?: string;\n /** Semantic grouping for layout lanes. */\n phase?: string;\n\n // ── Authorization ──\n /** Who can execute this step. */\n actor?: ActorConstraint;\n\n // ── TTL ──\n /** Time-to-live constraints. */\n ttl?: TTLConstraint;\n\n // ── Trigger ──\n /**\n * When and how this block fires. Defaults to `{ type: 'manual' }` if absent\n * (i.e. block runs only when a user explicitly invokes it).\n *\n * `block.event` triggers turn this block into a listener: when the source\n * block emits an event matching `eventName`, a pending invocation is\n * queued on this block and the assigned actor is DM'd to invoke it. See\n * `docs/flow-engine/events-and-triggers-plan.md` §3.7 and §18 for the full model.\n *\n * Triggers are a NEW sibling field on FlowCapability (decided in eng review\n * pass 2 phase 0 #1). They are NOT an extension of `condition`. The decompile\n * branch's author needs to add `props.trigger` parsing when their work merges.\n */\n trigger?: TriggerSpec;\n\n // ── Human-facing metadata ──\n /** Display title (falls back to can statement). */\n title?: string;\n /** Description of what this step does. */\n description?: string;\n /** Icon identifier. */\n icon?: string;\n}\n\n/**\n * Trigger declaration for a block. When and how it fires.\n */\n/** A single event source in a barrier trigger. */\nexport interface TriggerSource {\n /** ID of the block that emits the event. */\n sourceBlockId: string;\n /** Name of the event (must match an event declared on the source action's `events` vocabulary). */\n eventName: string;\n /** Namespace alias for payload access: `trigger.payload.<alias>.*` */\n alias: string;\n /**\n * When `true`, this source does NOT block queuing — the barrier fires once all\n * *required* (non-optional) sources have fired. If an optional source fired before\n * the barrier completes, its payload is merged in; if it never fires, it's skipped.\n * Defaults to `false` (required) for backward compatibility.\n */\n optional?: boolean;\n}\n\nexport interface TriggerSpec {\n /**\n * - `manual`: block runs only when a user explicitly invokes it (default).\n * - `flow.start`: block runs when the flow execution begins.\n * - `block.event`: block runs each time another block emits a matching event.\n * - `block.event.all`: block runs once ALL listed sources have emitted (barrier/join).\n * - `schedule`: block runs when a sovereign schedule fires (Sovereign\n * Scheduling, IXO-4429). The block carries only a reference — the five\n * time kinds (time.at/cron/interval/delay/relative), timezone and\n * recurrence live in the referenced ScheduleSpec, never in block props,\n * so editing a schedule does not force a flow recompile and the timing\n * provider never sees flow content.\n */\n type: 'manual' | 'flow.start' | 'block.event' | 'block.event.all' | 'schedule';\n /** Required when `type === 'block.event'`. ID of the block that emits the event. */\n sourceBlockId?: string;\n /** Required when `type === 'block.event'`. Name of the event (must match an event declared on the source action's `events` vocabulary). */\n eventName?: string;\n /** Required when `type === 'block.event.all'`. Array of event sources — ALL must fire before the listener is queued. */\n sources?: TriggerSource[];\n /** Required when `type === 'schedule'`. Stable ID of the ScheduleSpec this block is bound to. */\n scheduleRef?: string;\n /**\n * Optional when `type === 'schedule'`: pin to one schedule revision.\n * Cloning a flow as a template must strip `scheduleRef` — an active\n * schedule ID names one authorized binding, not a reusable default.\n */\n scheduleRevision?: number;\n}\n\n/**\n * The Base UCAN flow plan — the intermediate representation between\n * user intent and the compiled flow graph.\n *\n * capabilities is an ordered list. Each capability carries its own stable `id`.\n */\nexport interface BaseUcanFlow {\n kind: 'qi.flow.base-ucan';\n version: '1.0';\n flowId: string;\n title: string;\n goal?: string;\n meta?: {\n entityDid?: string;\n flowUri?: string;\n rootIssuer?: string;\n };\n /** Ordered capabilities, each with its own stable node ID. */\n capabilities: FlowCapability[];\n}\n\n// ─── Runtime References ─────────────────────────────────────────────────────\n// Used in nb values to reference outputs from upstream capabilities.\n// Resolved at execution time, serialized as-is at compile time.\n\n/** A reference to an upstream node's output field. Format: \"nodeId.output.fieldPath\" */\nexport interface RuntimeRef {\n $ref: string;\n}\n\nexport function isRuntimeRef(value: unknown): value is RuntimeRef {\n return typeof value === 'object' && value !== null && '$ref' in value && typeof (value as Record<string, unknown>).$ref === 'string';\n}\n\n// ─── Compiled Flow Output ───────────────────────────────────────────────────\n// Produced by the compiler, consumed by hydration.\n\n/** A single block ready for insertion into BlockNote. */\nexport interface CompiledBlock {\n /** Pre-generated stable block ID. */\n id: string;\n /** BlockNote block type (e.g., \"action\"). */\n type: string;\n /** Block props — all values are strings per BlockNote convention. */\n props: Record<string, string>;\n}\n\n/**\n * An edge in the flow graph. Currently only `kind: 'trigger'` edges are\n * synthesized — they come from `block.event` triggers and represent the\n * source → listener relationship visually on the canvas.\n */\nexport interface CompiledEdge {\n id: string;\n source: string;\n target: string;\n kind: 'trigger';\n condition?: ConditionRef;\n}\n\n/** A compiled flow node stored in qi.flow.nodes. */\nexport interface CompiledFlowNode {\n id: string;\n blockId: string;\n can: string;\n with: string;\n registryType: string;\n title: string;\n description: string;\n props: Record<string, string>;\n phase?: string;\n parallelGroup?: string;\n actor?: ActorConstraint;\n}\n\n/** The complete compiled output from the Base UCAN compiler. */\nexport interface CompiledFlow {\n /** Flow metadata for qi.flow.meta and Y.Map('root'). */\n meta: {\n flowId: string;\n title: string;\n goal?: string;\n version: string;\n flowOwnerDid: string;\n flowUri?: string;\n compiledAt: string;\n compiledFrom: 'BaseUcanFlow';\n };\n /** Blocks to insert into BlockNote, in topological order. */\n blocks: CompiledBlock[];\n /** Flow graph nodes, keyed by node ID. */\n nodes: Record<string, CompiledFlowNode>;\n /** Dependency edges. */\n edges: CompiledEdge[];\n /** Topological order of node IDs. */\n order: string[];\n /** nodeId → blockId mapping. */\n blockIndex: Record<string, string>;\n}\n\n/** Strategy for how a compiled flow is applied to an existing document. */\nexport type FlowStrategy = 'full' | 'merge' | 'patch';\n","import * as Y from 'yjs';\nimport type { RuntimeRef } from '../../types/baseUcan';\nimport { isRuntimeRef } from '../../types/baseUcan';\nimport { getNestedValue } from './referenceResolver';\nimport { getExistingYMap } from '../yjsTypes';\nimport { ensureRunScopedMap, getRunScopedMap, isRecordInRun, resolveActiveRunId, resolveRunIdForExecution, usesLegacyRuntimeCompatibility } from './runs';\n\n/**\n * Run record stored in the audit trail as `type: 'block.run'`.\n *\n * Per Phase 0 #2 (eng review pass 2), run records are NOT a parallel\n * `_yRunHistory` structure — they ride on the existing `auditTrail` Y.Map\n * via `useAuditTrail.addEvent`. The shape below is what goes into the\n * audit trail event's `details` field.\n *\n * See `docs/flow-engine/events-and-triggers-plan.md` §3.4, §18, §19.\n */\nexport interface RunRecordDetails {\n /**\n * Stable identifier for **this execution**, deterministic from invocation\n * context (`run-<ts>-<rand>` / `readback-<ts>-<rand>`).\n *\n * D2 — **NOT the session run, and never renamed.** This is persisted data in\n * live rooms and it is the `sourceRunId` component of\n * `computePendingInvocationId`; renaming it forks that join and the same\n * logical event queues twice. New code calls this the *execution* id and\n * uses {@link RunRecordDetails.sessionRunId} for the session run.\n */\n runId: string;\n /**\n * The session run (`runs.ts`) this execution belonged to. Phase A writes it\n * additively and **nothing reads it** — it exists so Phase B's per-run\n * history attribution is free, and it deliberately does not participate in\n * `computePendingInvocationId` (moving the id space is Phase B, together with\n * `pendingInvocations` and `barrierState`).\n */\n sessionRunId?: string;\n /** Action's output. */\n output: Record<string, unknown>;\n /**\n * Events the action emitted on this run. Persisted as part of the run\n * record so the reconciliation loop can process them idempotently — even\n * across page refreshes and across multiple clients.\n */\n events: Array<{ name: string; payload: Record<string, unknown> }>;\n /** ISO timestamp when the action started. */\n startedAt: string;\n /** ISO timestamp when the action completed (success or failure). */\n completedAt: string;\n /** DID of the actor who signed the invocation that produced this run. */\n actorDid: string;\n /** UCAN invocation CID when execution produced one. */\n invocationCid?: string;\n /** Capability/proof CID used when no invocation CID was produced. */\n capabilityId?: string;\n /** Optional error if the run failed. */\n error?: { message: string; code?: string };\n /** External read-back metadata associated with this run or reconciliation. */\n readBack?: Record<string, unknown>;\n /** True when this audit entry was written by external read-back reconciliation. */\n reconciled?: boolean;\n /**\n * If this run was triggered by a pending invocation (i.e. it's a listener\n * run), the id of that pending invocation. Used to dedup replays and trace\n * causality back through `triggeredBy`.\n */\n fromPendingInvocationId?: string;\n /**\n * If this run is a listener run, the (sourceBlockId, eventName) that\n * caused it. Used by the failure visibility surface to attribute failures\n * back to the source block (CP-1).\n */\n triggeredBy?: { sourceBlockId: string; eventName: string };\n /** Source run id for listener runs, stored explicitly for failure lookups. */\n sourceRunId?: string;\n}\n\nexport const RUN_RECORD_AUDIT_TYPE = 'block.run';\n\n/**\n * Pending invocation queued on a listener block.\n *\n * Stored in `_yPendingInvocations: Y.Map<blockId, Y.Map<id, PendingInvocation>>`.\n *\n * The id is deterministic — derived from\n * `(sourceBlockId, sourceRunId, listenerBlockId, eventName, eventIndex)` —\n * so the reconciliation loop can run idempotently from multiple clients\n * without producing duplicates.\n *\n * See `docs/flow-engine/events-and-triggers-plan.md` §3.4, §3.5.1, §18.\n */\nexport interface PendingInvocation {\n /** Deterministic id, see `computePendingInvocationId`. */\n id: string;\n /** Block that emitted the event. */\n triggeringBlockId: string;\n /** Run id of the triggering source run, used for the deterministic id. */\n sourceRunId: string;\n /** Session run that owns this queue entry. Required by Phase B writers. */\n sessionRunId?: string;\n /** Event name from the source action's vocabulary. */\n eventName: string;\n /** Event index within the source run's `events` array (a single run can emit multiple). */\n eventIndex: number;\n /**\n * The frozen event payload, captured by value at emission time. The\n * assignee invokes the listener against this payload, not against the\n * source block's current state. This is the property that makes the\n * Sally → Mike scenario produce 10 distinct emails even when Mike acts\n * on them all hours later.\n */\n payload: Record<string, unknown>;\n /**\n * Snapshots of `nodeId.output.*` ref values that the listener's inputs\n * reference, captured at queue time. Keyed by the full ref string.\n *\n * §3.5.1: ref snapshots are the load-bearing fix for the lag-time\n * overwrite scenario. If a listener references a non-trigger block's\n * output (e.g. `evaluateBlock.output.claimId`), that value is captured\n * here at queue time. Resolution at invocation time prefers the snapshot\n * over current state, so multiple queued invocations don't drift when\n * the source re-runs.\n */\n refSnapshots: Record<string, unknown>;\n /** DID of the assigned actor who must invoke this listener. Resolved from `props.assignment.assignedActor.did`. */\n assigneeDid: string;\n /** ISO timestamp when the source emission happened. */\n emittedAt: string;\n /** ISO timestamp after which this pending invocation is considered expired. Resolved from `FlowCapability.ttl` at queue time. */\n expiresAt: string;\n}\n\n/**\n * Compute a deterministic id for a pending invocation from its content.\n *\n * The same (sourceBlockId, sourceRunId, listenerBlockId, eventName,\n * eventIndex) tuple always produces the same id. This is the property that\n * makes the reconciliation loop idempotent — re-running it from a different\n * client, or after a page refresh, produces the same `Y.Map.set` operation\n * with the same key, which Yjs converges to a single entry.\n *\n * Implementation: simple deterministic string concatenation, hashed via a\n * 32-bit FNV-1a. The id is short and stable; collision risk within a single\n * flow is negligible because the inputs are scoped (block ids are unique\n * within a flow, run ids are unique within a block).\n */\nexport function computePendingInvocationId(args: {\n sourceBlockId: string;\n sourceRunId: string;\n listenerBlockId: string;\n eventName: string;\n eventIndex: number;\n sessionRunId?: string;\n}): string {\n const { sourceBlockId, sourceRunId, listenerBlockId, eventName, eventIndex, sessionRunId } = args;\n const input = `${sessionRunId ? `${sessionRunId}:` : ''}${sourceBlockId}:${sourceRunId}:${listenerBlockId}:${eventName}:${eventIndex}`;\n return `pi-${fnv1a32(input)}`;\n}\n\n/**\n * Walk an inputs object and collect every RuntimeRef of the form\n * `nodeId.output.fieldPath`. Returns a map of `{refString: resolvedValue}`\n * suitable for storing as `PendingInvocation.refSnapshots`.\n *\n * The walker mirrors `resolveRuntimeRefs` in `flowCompiler/resolveRefs.ts`\n * but reads instead of resolving — it captures the current value of each\n * ref so the listener can later resolve against the snapshot rather than\n * against current state.\n *\n * See `docs/flow-engine/events-and-triggers-plan.md` §3.5.1.\n */\nexport function snapshotInputRefs(inputs: unknown, getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined): Record<string, unknown> {\n const snapshots: Record<string, unknown> = {};\n walkRefs(inputs, (ref) => {\n // Skip trigger.* refs — those resolve from the pending invocation's payload, not snapshots\n if (ref.$ref.startsWith('trigger.')) return;\n const parsed = parseOutputRef(ref.$ref);\n if (!parsed) return;\n const output = getNodeOutput(parsed.nodeId);\n if (!output) return;\n snapshots[ref.$ref] = getNestedValue(output, parsed.fieldPath);\n });\n return snapshots;\n}\n\n/**\n * Recursively walk a value and invoke the visitor on every RuntimeRef found.\n * Mirrors the recursion shape of `resolveValue` in `resolveRefs.ts`.\n */\nfunction walkRefs(value: unknown, visit: (ref: RuntimeRef) => void): void {\n if (isRuntimeRef(value)) {\n visit(value);\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) walkRefs(item, visit);\n return;\n }\n if (typeof value === 'object' && value !== null) {\n for (const v of Object.values(value)) walkRefs(v, visit);\n }\n}\n\n/** Parse `\"nodeId.output.fieldPath\"` into its parts. Returns null if not a node output ref. */\nfunction parseOutputRef(ref: string): { nodeId: string; fieldPath: string } | null {\n const outputIndex = ref.indexOf('.output.');\n if (outputIndex === -1) return null;\n return {\n nodeId: ref.slice(0, outputIndex),\n fieldPath: ref.slice(outputIndex + '.output.'.length),\n };\n}\n\n/**\n * 32-bit FNV-1a hash. Returns a hex string. Used for deterministic\n * pending-invocation ids — not cryptographic, just stable across clients.\n */\nfunction fnv1a32(input: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n// ─── Yjs storage helpers ────────────────────────────────────────────────────\n\nexport const PENDING_INVOCATIONS_MAP_KEY = 'pendingInvocations';\n\n/**\n * Get the top-level pending invocations Y.Map from the editor's yDoc.\n * Lazily creates it if missing.\n *\n * Shape: `Y.Map<blockId, Y.Map<pendingInvocationId, PendingInvocation>>`.\n * The outer map is keyed by listener block id; the inner map is keyed by\n * deterministic pending invocation id (see `computePendingInvocationId`).\n */\nexport function getPendingInvocationsMap(yDoc: Y.Doc, sessionRunId?: string): Y.Map<Y.Map<unknown>> {\n if (usesLegacyRuntimeCompatibility(yDoc)) {\n return yDoc.getMap<Y.Map<unknown>>(PENDING_INVOCATIONS_MAP_KEY);\n }\n return ensureRunScopedMap<Y.Map<unknown>>(yDoc, resolveRunIdForExecution(yDoc, sessionRunId), PENDING_INVOCATIONS_MAP_KEY);\n}\n\n/**\n * Read-only lookup for the pending-invocation container.\n *\n * Unlike {@link getPendingInvocationsMap}, this never creates a top-level map,\n * run, or nested run map. Status/history surfaces must use this path so merely\n * inspecting an empty run cannot mutate the shared document.\n */\nfunction readPendingInvocationsMap(yDoc: Y.Doc, sessionRunId?: string): Y.Map<Y.Map<unknown>> | undefined {\n if (usesLegacyRuntimeCompatibility(yDoc)) {\n return getExistingYMap<Y.Map<unknown>>(yDoc, PENDING_INVOCATIONS_MAP_KEY);\n }\n const runId = sessionRunId || resolveActiveRunId(yDoc);\n if (!runId) return undefined;\n return getRunScopedMap<Y.Map<unknown>>(yDoc, runId, PENDING_INVOCATIONS_MAP_KEY);\n}\n\n/**\n * Count all pending invocations in one session run without materialising any\n * missing CRDT containers.\n */\nexport function countPendingInvocations(yDoc: Y.Doc, sessionRunId?: string): number {\n const outer = readPendingInvocationsMap(yDoc, sessionRunId);\n if (!outer) return 0;\n let count = 0;\n outer.forEach((inner) => {\n if (inner && typeof inner.forEach === 'function') {\n inner.forEach(() => {\n count += 1;\n });\n }\n });\n return count;\n}\n\n/**\n * Get the inner pending-invocations map for a specific listener block.\n * Lazily creates it if missing. Caller is responsible for being inside a\n * Yjs transaction if atomic creation matters.\n */\nexport function getOrCreateBlockPendingMap(yDoc: Y.Doc, blockId: string, sessionRunId?: string): Y.Map<unknown> {\n const outer = getPendingInvocationsMap(yDoc, sessionRunId);\n let inner = outer.get(blockId);\n if (!inner) {\n inner = new Y.Map();\n outer.set(blockId, inner);\n }\n return inner;\n}\n\n/**\n * Read all pending invocations for a block as plain JS objects.\n * Returns an array sorted by `emittedAt` ascending (oldest first).\n */\nexport function readPendingInvocations(yDoc: Y.Doc, blockId: string, sessionRunId?: string): PendingInvocation[] {\n const outer = readPendingInvocationsMap(yDoc, sessionRunId);\n if (!outer) return [];\n const inner = outer.get(blockId);\n if (!inner) return [];\n const items: PendingInvocation[] = [];\n inner.forEach((value) => {\n if (value && typeof value === 'object') {\n items.push(value as PendingInvocation);\n }\n });\n items.sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));\n return items;\n}\n\n/**\n * Idempotently write a pending invocation under its deterministic id.\n *\n * Returns true if a new entry was created, false if the id already\n * existed (meaning another client or a previous reconciliation pass\n * already queued this invocation). This is the property that makes\n * `reconcilePendingInvocations` safe to run from multiple clients\n * simultaneously and across page refreshes — see plan §18.\n *\n * Wraps the write in a Yjs transaction so the existence check and the\n * subsequent set are atomic from the local client's perspective. Concurrent\n * clients each computing the same id will all converge to a single entry\n * because Y.Map.set with the same key is last-writer-wins on identical\n * content.\n */\nexport function queuePendingInvocation(yDoc: Y.Doc, listenerBlockId: string, invocation: PendingInvocation, sessionRunId?: string): boolean {\n let created = false;\n yDoc.transact(() => {\n const inner = getOrCreateBlockPendingMap(yDoc, listenerBlockId, sessionRunId || invocation.sessionRunId);\n if (inner.has(invocation.id)) return;\n inner.set(invocation.id, invocation);\n created = true;\n });\n return created;\n}\n\n/**\n * Remove a pending invocation by id. Used when the assignee completes the\n * invocation (transitioning to a `block.run` audit trail entry) or when\n * the expiration sweep marks it as expired.\n */\nexport function removePendingInvocation(yDoc: Y.Doc, listenerBlockId: string, pendingInvocationId: string, sessionRunId?: string): boolean {\n const outer = readPendingInvocationsMap(yDoc, sessionRunId);\n if (!outer) return false;\n const inner = outer.get(listenerBlockId);\n if (!inner) return false;\n if (!inner.has(pendingInvocationId)) return false;\n inner.delete(pendingInvocationId);\n return true;\n}\n\n/**\n * Collect the ids of pending invocations this listener has already consumed:\n * every run record the listener wrote carries `fromPendingInvocationId`.\n * The reconciliation loop skips these ids so a consumed invocation is not\n * resurrected from the (immutable) source run record on the next pass.\n * Joining on run records needs no extra tombstone state and converges\n * across clients like everything else in the audit trail.\n */\nexport function readConsumedPendingInvocationIds(yDoc: Y.Doc, listenerBlockId: string, sessionRunId?: string): Set<string> {\n const consumed = new Set<string>();\n for (const record of readRunRecords(yDoc, listenerBlockId, sessionRunId)) {\n if (record.fromPendingInvocationId) consumed.add(record.fromPendingInvocationId);\n }\n return consumed;\n}\n\n/**\n * Physically delete expired pending invocations across all listeners.\n * Safe against resurrection because the reconciliation loop refuses to\n * queue an invocation whose computed expiry is already in the past.\n * Returns the number of entries removed.\n */\nexport function sweepExpiredPendingInvocations(yDoc: Y.Doc, now: number = Date.now(), sessionRunId?: string): number {\n const outer = readPendingInvocationsMap(yDoc, sessionRunId);\n if (!outer) return 0;\n let removed = 0;\n outer.forEach((inner, listenerBlockId) => {\n const innerMap = inner as Y.Map<unknown>;\n if (!innerMap || typeof innerMap.forEach !== 'function') return;\n const expiredIds: string[] = [];\n innerMap.forEach((value, id) => {\n const expiresAt = (value as PendingInvocation | undefined)?.expiresAt;\n if (expiresAt && Date.parse(expiresAt) < now) expiredIds.push(id);\n });\n for (const id of expiredIds) {\n innerMap.delete(id);\n removed += 1;\n }\n void listenerBlockId;\n });\n return removed;\n}\n\n// ─── Barrier state helpers (block.event.all) ──────────────────────────────────\n\n/**\n * Top-level Y.Doc map owning partial barrier completion for `block.event.all`\n * listeners. Exported so `clearRuntimeForTemplateClone` can clear it without\n * duplicating the literal — a barrier that survives a template clone can be\n * satisfied in the clone by entries emitted in the source flow.\n */\nexport const BARRIER_STATE_MAP_KEY = 'barrierState';\n\n/**\n * A single source event recorded toward a barrier trigger's completion.\n */\nexport interface BarrierEntry {\n sourceBlockId: string;\n eventName: string;\n alias: string;\n runId: string;\n sessionRunId?: string;\n payload: Record<string, unknown>;\n emittedAt: string;\n}\n\n/** Get the top-level barrier state Y.Map. Shape: `Y.Map<listenerBlockId, Y.Map<sourceKey, BarrierEntry>>`. */\nexport function getBarrierStateMap(yDoc: Y.Doc, sessionRunId?: string): Y.Map<Y.Map<unknown>> {\n if (usesLegacyRuntimeCompatibility(yDoc)) {\n return yDoc.getMap<Y.Map<unknown>>(BARRIER_STATE_MAP_KEY);\n }\n return ensureRunScopedMap<Y.Map<unknown>>(yDoc, resolveRunIdForExecution(yDoc, sessionRunId), BARRIER_STATE_MAP_KEY);\n}\n\nfunction readBarrierStateMap(yDoc: Y.Doc, sessionRunId?: string): Y.Map<Y.Map<unknown>> | undefined {\n if (usesLegacyRuntimeCompatibility(yDoc)) {\n return getExistingYMap<Y.Map<unknown>>(yDoc, BARRIER_STATE_MAP_KEY);\n }\n const runId = sessionRunId || resolveActiveRunId(yDoc);\n if (!runId) return undefined;\n return getRunScopedMap<Y.Map<unknown>>(yDoc, runId, BARRIER_STATE_MAP_KEY);\n}\n\nfunction getOrCreateListenerBarrierMap(yDoc: Y.Doc, listenerBlockId: string, sessionRunId?: string): Y.Map<unknown> {\n const outer = getBarrierStateMap(yDoc, sessionRunId);\n let inner = outer.get(listenerBlockId);\n if (!inner) {\n inner = new Y.Map();\n outer.set(listenerBlockId, inner);\n }\n return inner;\n}\n\n/** Record one source event firing toward a barrier. Idempotent — skips write if same runId already recorded. */\nexport function recordBarrierEvent(yDoc: Y.Doc, listenerBlockId: string, entry: BarrierEntry, sessionRunId?: string): boolean {\n let written = false;\n yDoc.transact(() => {\n const inner = getOrCreateListenerBarrierMap(yDoc, listenerBlockId, sessionRunId || entry.sessionRunId);\n const key = `${entry.sourceBlockId}::${entry.eventName}`;\n const existing = inner.get(key) as BarrierEntry | undefined;\n // Skip if same runId already recorded — prevents Yjs observer re-trigger loop\n if (existing && typeof existing === 'object' && (existing as BarrierEntry).runId === entry.runId) return;\n inner.set(key, entry);\n written = true;\n });\n return written;\n}\n\n/** Read all barrier entries for a listener block. */\nexport function readBarrierState(yDoc: Y.Doc, listenerBlockId: string, sessionRunId?: string): BarrierEntry[] {\n const outer = readBarrierStateMap(yDoc, sessionRunId);\n if (!outer) return [];\n const inner = outer.get(listenerBlockId);\n if (!inner) return [];\n const entries: BarrierEntry[] = [];\n inner.forEach((value) => {\n if (value && typeof value === 'object') {\n entries.push(value as BarrierEntry);\n }\n });\n return entries;\n}\n\n/** Clear barrier state after an invocation is queued (resets for next cycle). */\nexport function clearBarrierState(yDoc: Y.Doc, listenerBlockId: string, sessionRunId?: string): void {\n const outer = readBarrierStateMap(yDoc, sessionRunId);\n if (!outer) return;\n yDoc.transact(() => {\n outer.delete(listenerBlockId);\n });\n}\n\n/**\n * Compute a deterministic id for a barrier invocation from all contributing\n * source run IDs. Sorted to ensure order-independence — whichever source\n * completes last, the same ID is produced.\n */\nexport function computeBarrierInvocationId(entries: BarrierEntry[], listenerBlockId: string, sessionRunId?: string): string {\n const sorted = [...entries].sort((a, b) => a.sourceBlockId.localeCompare(b.sourceBlockId));\n const input = `${sessionRunId ? `${sessionRunId}|` : ''}${sorted.map((e) => `${e.sourceBlockId}:${e.runId}:${e.eventName}`).join('|')}|>${listenerBlockId}`;\n return `bi-${fnv1a32(input)}`;\n}\n\n/**\n * Merge barrier entries into a namespaced payload object keyed by alias.\n * E.g. { governance: { groupName, groupType }, members: { memberCount }, preview: { domainCardData } }\n */\nexport function mergeBarrierPayloads(entries: BarrierEntry[]): Record<string, unknown> {\n const merged: Record<string, unknown> = {};\n for (const entry of entries) {\n if (entry.alias) {\n merged[entry.alias] = entry.payload;\n } else {\n Object.assign(merged, entry.payload);\n }\n }\n return merged;\n}\n\n// ─── Run record helpers (audit trail integration, Phase 0 #2) ───────────────\n\n/**\n * Append a run record to the audit trail for a block. Run records are\n * stored as audit trail events with `type: 'block.run'` and the structured\n * data in `details`. Per Phase 0 #2 of eng review pass 2, this avoids\n * inventing a parallel `_yRunHistory` storage system.\n *\n * Y.Array.push from concurrent clients merges correctly — verified by the\n * existing `useAuditTrail` shipping in production.\n */\nexport function appendRunRecord(yDoc: Y.Doc, blockId: string, details: RunRecordDetails, userId: string): void {\n const auditMap = yDoc.getMap<Y.Array<unknown>>('auditTrail');\n\n yDoc.transact(() => {\n let arr = auditMap.get(blockId);\n if (!arr) {\n arr = new Y.Array<unknown>();\n auditMap.set(blockId, arr);\n }\n const event = {\n id: `${details.runId}`,\n blockId,\n type: RUN_RECORD_AUDIT_TYPE,\n details,\n message: undefined,\n meta: {\n timestamp: details.completedAt,\n userId,\n editable: false,\n },\n };\n arr.push([event]);\n });\n}\n\n/**\n * Read all run records for a block from the audit trail. Filters audit\n * trail entries to only those with `type: 'block.run'`.\n */\nexport function readRunRecords(yDoc: Y.Doc, blockId: string, sessionRunId?: string): RunRecordDetails[] {\n const auditMap = getExistingYMap<Y.Array<unknown>>(yDoc, 'auditTrail');\n if (!auditMap) return [];\n const arr = auditMap.get(blockId);\n if (!arr) return [];\n const records: RunRecordDetails[] = [];\n arr.forEach((entry) => {\n if (!entry || typeof entry !== 'object') return;\n const e = entry as { type?: string; details?: RunRecordDetails };\n if (e.type === RUN_RECORD_AUDIT_TYPE && e.details) {\n if (sessionRunId && !isRecordInRun(e.details.sessionRunId, sessionRunId)) {\n return;\n }\n records.push(e.details);\n }\n });\n return records;\n}\n\n// ─── Failure visibility (slice L: CP-1 + CP-2) ──────────────────────────────\n\n/**\n * A failed listener run, attributed to the source block emission that\n * triggered it. Used by the failure visibility surface (CP-1) on source\n * blocks: the source block can show \"N listeners failed for your last run\".\n */\nexport interface FailedListenerRun {\n /** Block id of the listener whose run failed. */\n listenerBlockId: string;\n /** The full RunRecordDetails of the failed listener invocation. */\n record: RunRecordDetails;\n}\n\n/**\n * Find all failed listener runs that were triggered by a specific source\n * block run. Walks every block's audit trail, filters to listener runs\n * triggered by (sourceBlockId, sourceRunId), and returns the ones with an\n * error set.\n *\n * Used by the source block UI to show a failure badge linked to a specific\n * run — if Sally evaluates 10 claims and 2 of Mike's emails fail, Sally\n * sees \"2 failed listeners on claim-G\" rather than discovering it days\n * later in the email service logs.\n */\nexport function findFailedListenersForSourceRun(yDoc: Y.Doc, sourceBlockId: string, sourceRunId: string, listenerBlockIds: string[]): FailedListenerRun[] {\n const failures: FailedListenerRun[] = [];\n for (const listenerBlockId of listenerBlockIds) {\n const records = readRunRecords(yDoc, listenerBlockId);\n for (const record of records) {\n if (!record.error) continue;\n if (record.triggeredBy?.sourceBlockId !== sourceBlockId) continue;\n if (record.fromPendingInvocationId == null) continue;\n // The fromPendingInvocationId encodes the source run; we match on\n // triggeredBy + the listener's record actually being a listener run\n // for THIS source block. The plan's deterministic id includes\n // sourceRunId, so failures from a specific source run are findable\n // by joining on the audit trail's stored sourceRunId reference.\n const sourceRunIdField = (record as { sourceRunId?: string }).sourceRunId;\n if (sourceRunIdField && sourceRunIdField !== sourceRunId) continue;\n failures.push({ listenerBlockId, record });\n }\n }\n return failures;\n}\n\n/**\n * Replay a previously failed listener run by re-queueing a pending\n * invocation with the same content. Reuses the original frozen payload\n * and ref snapshots from the failed run record's audit trail entry, so the\n * replay sees exactly the same data the original invocation saw.\n *\n * CP-2 from the plan. Used by the replay button in the failure visibility\n * surface. Returns true if a new pending invocation was queued.\n *\n * Note: replay does NOT re-derive the deterministic id from the original\n * source emission, because the original pending invocation's id is already\n * present (or removed) in the pendingInvocations Y.Map. Instead, replay\n * generates a fresh id by appending a `:replay-N` suffix to the original.\n * This means the replay creates a NEW pending invocation that the assignee\n * can act on, separate from any history of the original.\n */\nexport function replayFailedListenerRun(\n yDoc: Y.Doc,\n failedRecord: RunRecordDetails,\n listenerBlockId: string,\n originalPayload: Record<string, unknown>,\n originalRefSnapshots: Record<string, unknown>,\n assigneeDid: string,\n sessionRunId?: string\n): boolean {\n if (!failedRecord.triggeredBy) return false;\n const replayId = `${failedRecord.runId}:replay-${Date.now().toString(36)}`;\n const now = new Date().toISOString();\n const replay: PendingInvocation = {\n id: replayId,\n triggeringBlockId: failedRecord.triggeredBy.sourceBlockId,\n sourceRunId: (failedRecord as { sourceRunId?: string }).sourceRunId || failedRecord.runId,\n sessionRunId: sessionRunId || failedRecord.sessionRunId,\n eventName: failedRecord.triggeredBy.eventName,\n eventIndex: 0,\n payload: originalPayload,\n refSnapshots: originalRefSnapshots,\n assigneeDid,\n emittedAt: now,\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),\n };\n return queuePendingInvocation(yDoc, listenerBlockId, replay, sessionRunId || failedRecord.sessionRunId);\n}\n","/**\n * Flow Version Manifest\n *\n * Single source of truth for what each schema version requires.\n * Blocks and components read policy hints rather than checking version strings directly.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type FlowVersionString = '0.3' | '1.0.0';\n\nexport interface VersionPolicyUi {\n /** Show the delegation management panel in block config */\n showDelegationPanel: boolean;\n /** Show the whitelist (specific actors) option in authorization config */\n showWhitelistConfig: boolean;\n /** Show the \"anyone with flow access\" option in authorization config */\n showAnyoneConfig: boolean;\n /** Show a banner when a newer version is available */\n showMigrationBanner: boolean;\n /** Require PIN entry for block execution (invocation signing) */\n requirePinForExecution: boolean;\n}\n\nexport interface VersionPolicy {\n /** Semver-style version identifier */\n version: FlowVersionString;\n /** Human-readable label */\n label: string;\n /** Whether UCAN delegation chains are required for all executions */\n ucanRequired: boolean;\n /** Whether a root delegation must exist before any execution */\n delegationRootRequired: boolean;\n /** Whether whitelist-only authorization (no parentCapability) is acceptable */\n whitelistOnlyAllowed: boolean;\n /** Whether unrestricted access (no authorisedActors, no parentCapability) is acceptable */\n unrestrictedAllowed: boolean;\n /** Which execution path to use */\n executionPath: 'legacy' | 'invocation';\n /** Which authorization function to use */\n authorizationFn: 'v1' | 'v2';\n /** Allowed authorization modes in the UI */\n allowedAuthModes: Array<'anyone' | 'actors' | 'capability'>;\n /** UI rendering hints — blocks query these instead of checking version strings */\n ui: VersionPolicyUi;\n /** Human-readable description of this version */\n description: string;\n}\n\n// ---------------------------------------------------------------------------\n// Manifest\n// ---------------------------------------------------------------------------\n\nexport const VERSION_MANIFEST: Record<FlowVersionString, VersionPolicy> = {\n '0.3': {\n version: '0.3',\n label: 'Legacy',\n ucanRequired: false,\n delegationRootRequired: false,\n whitelistOnlyAllowed: true,\n unrestrictedAllowed: true,\n executionPath: 'legacy',\n authorizationFn: 'v1',\n allowedAuthModes: ['anyone', 'actors', 'capability'],\n ui: {\n showDelegationPanel: false,\n showWhitelistConfig: true,\n showAnyoneConfig: true,\n showMigrationBanner: true,\n requirePinForExecution: false,\n },\n description: 'Legacy version. UCAN optional, whitelist-only authorization accepted.',\n },\n '1.0.0': {\n version: '1.0.0',\n label: 'UCAN Required',\n ucanRequired: true,\n delegationRootRequired: true,\n whitelistOnlyAllowed: false,\n unrestrictedAllowed: false,\n executionPath: 'invocation',\n authorizationFn: 'v2',\n allowedAuthModes: ['capability'],\n ui: {\n showDelegationPanel: true,\n showWhitelistConfig: false,\n showAnyoneConfig: false,\n showMigrationBanner: false,\n requirePinForExecution: true,\n },\n description: 'UCAN-enforced. Every block execution requires a valid delegation chain.',\n },\n};\n\n/** The version stamped on newly created flows */\nexport const LATEST_VERSION: FlowVersionString = '1.0.0';\n\n// ---------------------------------------------------------------------------\n// Internal test-only UCAN enforcement override\n// ---------------------------------------------------------------------------\n\n/**\n * Tests occasionally need to isolate non-authorization behavior. Production\n * starts fail-closed and the public package does not export this override.\n */\nlet tempUcanEnforcementDisabled = false;\n\n/** Internal read used by lifecycle code and focused tests. */\nexport function isTempUcanEnforcementDisabled(): boolean {\n return tempUcanEnforcementDisabled;\n}\n\n/** Internal test hook. This symbol is intentionally absent from public package exports. */\nexport function setTempUcanEnforcementDisabled(disabled: boolean): void {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env;\n if (!env || (env.NODE_ENV !== 'test' && !env.VITEST)) {\n throw new Error('UCAN enforcement can only be overridden by the test runner');\n }\n tempUcanEnforcementDisabled = disabled;\n}\n\n/** Ordered migration path — each flow must step through versions sequentially */\nexport const MIGRATION_PATH: FlowVersionString[] = ['0.3', '1.0.0'];\n\n// ---------------------------------------------------------------------------\n// Utility functions\n// ---------------------------------------------------------------------------\n\n/**\n * Get the policy for a given schema version.\n * Unknown versions fall back to the strictest (latest) policy.\n */\nexport function getVersionPolicy(version: string): VersionPolicy {\n const policy = VERSION_MANIFEST[version as FlowVersionString] ?? VERSION_MANIFEST[LATEST_VERSION];\n // TEMPORARY: see the kill switch above — soften UCAN-enforcing policies.\n if (tempUcanEnforcementDisabled && policy.ucanRequired) {\n return {\n ...policy,\n ucanRequired: false,\n delegationRootRequired: false,\n ui: { ...policy.ui, requirePinForExecution: false },\n };\n }\n return policy;\n}\n\n/**\n * Check whether `current` is at least `minimum` in the migration path.\n */\nexport function isVersionAtLeast(current: string, minimum: FlowVersionString): boolean {\n const currentIdx = MIGRATION_PATH.indexOf(current as FlowVersionString);\n const minimumIdx = MIGRATION_PATH.indexOf(minimum);\n // Unknown versions are treated as latest (highest index)\n const effectiveCurrent = currentIdx === -1 ? MIGRATION_PATH.length : currentIdx;\n return effectiveCurrent >= minimumIdx;\n}\n\n/**\n * Get the next version in the migration path, or null if already at latest.\n */\nexport function getNextVersion(current: string): FlowVersionString | null {\n const idx = MIGRATION_PATH.indexOf(current as FlowVersionString);\n if (idx === -1 || idx >= MIGRATION_PATH.length - 1) {\n return null;\n }\n return MIGRATION_PATH[idx + 1];\n}\n\n/**\n * Get the chain of versions needed to migrate from `from` to `to`.\n * Returns the intermediate and target versions (excludes the `from` version).\n * Returns empty array if no migration needed or path is invalid.\n */\nexport function getMigrationChain(from: string, to: string): FlowVersionString[] {\n const fromIdx = MIGRATION_PATH.indexOf(from as FlowVersionString);\n const toIdx = MIGRATION_PATH.indexOf(to as FlowVersionString);\n\n if (fromIdx === -1 || toIdx === -1 || fromIdx >= toIdx) {\n return [];\n }\n\n return MIGRATION_PATH.slice(fromIdx + 1, toIdx + 1);\n}\n","import * as Y from 'yjs';\nimport type { IxoEditorType } from '../../types/editor';\nimport type { TriggerSpec } from '../../types/baseUcan';\nimport { getAction } from '../actionRegistry/registry';\nimport { getVersionPolicy } from './versionManifest';\nimport { warnOnce } from '../warnOnce';\nimport { readActionState, resolveRunIdForExecution, writeActionState } from './runs';\nimport {\n computePendingInvocationId,\n computeBarrierInvocationId,\n mergeBarrierPayloads,\n queuePendingInvocation,\n readConsumedPendingInvocationIds,\n readRunRecords,\n readBarrierState,\n recordBarrierEvent,\n clearBarrierState,\n snapshotInputRefs,\n sweepExpiredPendingInvocations,\n type PendingInvocation,\n type RunRecordDetails,\n} from './triggers';\n\n/**\n * Reconciliation loop — turns persisted run records into pending invocations\n * idempotently, so the trigger system survives page refreshes and works\n * across multiple connected clients.\n *\n * See `docs/flow-engine/events-and-triggers-plan.md` §18 for the full design rationale.\n *\n * Called from:\n * - The editor lifecycle on open (alongside performDMNotificationScan)\n * - The yDoc observer when remote run records arrive\n * - Immediately after a local action completes\n *\n * Idempotency comes from `computePendingInvocationId` producing the same id\n * for the same (sourceBlockId, sourceRunId, listenerBlockId, eventName,\n * eventIndex) tuple. Both ends of a sync compute the same id, both call\n * `Y.Map.set` on the same key, Yjs converges to one entry.\n *\n * The loop is intentionally write-only-on-new — it never deletes pending\n * invocations. Removal happens elsewhere (assignee invokes, expiration sweep).\n */\nconst activeReconciliations = new WeakMap<Y.Doc, Set<string>>();\n\nfunction flattenBlocks(blocks: any[]): any[] {\n const flattened: any[] = [];\n const visit = (block: any) => {\n flattened.push(block);\n if (Array.isArray(block?.children)) block.children.forEach(visit);\n };\n blocks.forEach(visit);\n return flattened;\n}\n\nexport function reconcilePendingInvocations(editor: IxoEditorType, runId?: string): void {\n const yDoc = (editor as unknown as { _yDoc?: Y.Doc })._yDoc;\n if (!yDoc) return;\n const sessionRunId = resolveRunIdForExecution(yDoc, runId);\n let activeRuns = activeReconciliations.get(yDoc);\n if (!activeRuns) {\n activeRuns = new Set();\n activeReconciliations.set(yDoc, activeRuns);\n }\n // Re-entrancy guard: barrier state writes trigger Yjs observers which\n // re-invoke reconciliation synchronously. Without this guard, cascading\n // re-entrant calls process different source blocks, each writing a new\n // barrier entry that triggers yet another observer. The guard ensures the\n // outer call completes all blocks before any observer-triggered call runs.\n if (activeRuns.has(sessionRunId)) return;\n activeRuns.add(sessionRunId);\n try {\n _reconcilePendingInvocationsInner(editor, yDoc, sessionRunId);\n } finally {\n activeRuns.delete(sessionRunId);\n }\n}\n\nfunction _reconcilePendingInvocationsInner(editor: IxoEditorType, yDoc: Y.Doc, runId: string): void {\n const blocks = flattenBlocks((editor as unknown as { document?: any[] }).document || []);\n if (blocks.length === 0) return;\n\n // Build a map of (sourceBlockId, eventName) → listenerBlocks[]\n // by walking every block's parsed trigger.\n const listenersBySource = new Map<string, Array<{ block: any; trigger: TriggerSpec }>>();\n const barrierListenersBySource = new Map<string, Array<{ block: any; trigger: TriggerSpec; source: { sourceBlockId: string; eventName: string; alias: string } }>>();\n\n for (const block of blocks) {\n const trigger = parseTrigger(block);\n if (!trigger) continue;\n\n if (trigger.type === 'block.event') {\n if (!trigger.sourceBlockId || !trigger.eventName) continue;\n const key = `${trigger.sourceBlockId}::${trigger.eventName}`;\n if (!listenersBySource.has(key)) listenersBySource.set(key, []);\n listenersBySource.get(key)!.push({ block, trigger });\n } else if (trigger.type === 'block.event.all' && trigger.sources) {\n for (const source of trigger.sources) {\n if (!source.sourceBlockId || !source.eventName) continue;\n const key = `${source.sourceBlockId}::${source.eventName}`;\n if (!barrierListenersBySource.has(key)) barrierListenersBySource.set(key, []);\n barrierListenersBySource.get(key)!.push({ block, trigger, source });\n }\n }\n }\n\n if (listenersBySource.size === 0 && barrierListenersBySource.size === 0) return;\n\n // Compaction: physically drop expired pending invocations. Re-queue is\n // prevented below (queue-time expiry check), so the sweep cannot fight\n // the write-only-on-new loop.\n const now = Date.now();\n sweepExpiredPendingInvocations(yDoc, now, runId);\n\n // Consumed-invocation dedup, computed lazily per listener: a listener's\n // own run records carry fromPendingInvocationId, and those ids must never\n // be re-queued from the immutable source run record.\n const consumedByListener = new Map<string, Set<string>>();\n const isConsumed = (listenerBlockId: string, pendingId: string): boolean => {\n let consumed = consumedByListener.get(listenerBlockId);\n if (!consumed) {\n consumed = readConsumedPendingInvocationIds(yDoc, listenerBlockId, runId);\n consumedByListener.set(listenerBlockId, consumed);\n }\n return consumed.has(pendingId);\n };\n\n // On UCAN-enforced flows, only run records that reference a resolvable\n // invocation may fire triggers — a hand-written run record (or one from a\n // permissive-era client) must not advance the flow.\n const schemaVersionRaw = yDoc.getMap('root').get('schema_version');\n const ucanRequired = typeof schemaVersionRaw === 'string' ? !!getVersionPolicy(schemaVersionRaw)?.ucanRequired : false;\n const invocationsMap = yDoc.getMap('invocations');\n\n // IGNITION PHASE A: the session run every read and write below is scoped to.\n // Constant in Phase A. Resolved from the doc, never from `editor._yRuntime` —\n // that handle is the flat map (or, on the headless path, a read-only shim),\n // and reading it directly would make `refSnapshots` see a *stale* output\n // whenever the run entry is the fresher side. Snapshots are frozen into\n // pending invocations, so a stale read here is signed against later.\n const getNodeOutput = (nodeId: string): Record<string, unknown> | undefined => {\n const out = readActionState(yDoc, runId, nodeId).output;\n return out && typeof out === 'object' && !Array.isArray(out) ? out : undefined;\n };\n\n // For each block that has subscribed listeners, walk its run records and\n // queue pending invocations for any (run, event) pairs not yet queued.\n for (const block of blocks) {\n const sourceBlockId = block?.id;\n if (!sourceBlockId) continue;\n\n // Quick check — does any listener subscribe to this block at all?\n let hasAnyListener = false;\n for (const key of listenersBySource.keys()) {\n if (key.startsWith(`${sourceBlockId}::`)) {\n hasAnyListener = true;\n break;\n }\n }\n for (const key of barrierListenersBySource.keys()) {\n if (key.startsWith(`${sourceBlockId}::`)) {\n hasAnyListener = true;\n break;\n }\n }\n if (!hasAnyListener) continue;\n\n const records = readRunRecords(yDoc, sourceBlockId, runId);\n for (const record of records) {\n if (!isTrustedRunRecord(record, ucanRequired, invocationsMap)) continue;\n processRunRecord(yDoc, runId, sourceBlockId, record, listenersBySource, getNodeOutput, isConsumed, now);\n processBarrierRunRecord(yDoc, runId, sourceBlockId, record, barrierListenersBySource, getNodeOutput, isConsumed, now);\n }\n }\n}\n\n/**\n * Materialize `trigger: flow.start` as durable pending invocations in the new\n * run. The run.started Matrix event is the source fact; deterministic ids make\n * reconnect/retry safe without keeping a second history log in the Y.Doc.\n */\nexport function dispatchFlowStartTriggers(params: { yDoc: Y.Doc; runId: string; blocks: any[]; startedAt: number; sourceEventId?: string }): number {\n const blocks = flattenBlocks(params.blocks);\n const sourceRunId = params.sourceEventId || `${params.runId}:run.started`;\n const emittedAt = new Date(params.startedAt).toISOString();\n const getNodeOutput = (nodeId: string): Record<string, unknown> | undefined => {\n const output = readActionState(params.yDoc, params.runId, nodeId).output;\n return output && typeof output === 'object' && !Array.isArray(output) ? output : undefined;\n };\n let queued = 0;\n\n for (const block of blocks) {\n const trigger = parseTrigger(block);\n if (trigger?.type !== 'flow.start' || !block?.id) continue;\n const id = computePendingInvocationId({\n sourceBlockId: '__flow_start__',\n sourceRunId,\n listenerBlockId: block.id,\n eventName: 'flow.start',\n eventIndex: 0,\n sessionRunId: params.runId,\n });\n const inputs = parseInputs(block);\n const refSnapshots = snapshotInputRefs(inputs, getNodeOutput);\n const invocation: PendingInvocation = {\n id,\n triggeringBlockId: '__flow_start__',\n sourceRunId,\n sessionRunId: params.runId,\n eventName: 'flow.start',\n eventIndex: 0,\n payload: {\n runId: params.runId,\n startedAt: params.startedAt,\n ...(params.sourceEventId ? { eventId: params.sourceEventId } : {}),\n },\n refSnapshots,\n assigneeDid: resolveAssignee(block) || 'unassigned',\n emittedAt,\n expiresAt: computeExpiry(block, emittedAt),\n };\n if (queuePendingInvocation(params.yDoc, block.id, invocation, params.runId)) {\n queued += 1;\n }\n writeActionState(params.yDoc, params.runId, block.id, {\n pendingPayload: { ...invocation.payload, ...refSnapshots },\n });\n }\n return queued;\n}\n\n/**\n * Decide whether a run record may act as a trigger source.\n *\n * Legacy flows trust every record (room-level access control). On\n * UCAN-enforced flows a record must reference an invocation that resolves in\n * the doc's `invocations` map — INCLUDING read-back reconciliation records.\n *\n * H3: read-back records (`reconciled: true`) used to be trusted\n * unconditionally, so any room member could write a record with that flag set\n * and fire downstream triggers on a UCAN-enforced flow. They now chain to the\n * same evidence as every other record: `writeReconciliationRunRecord` carries\n * the original execution's `invocationCid` forward (from the read-back\n * metadata), and that CID must resolve here. A hand-written `reconciled: true`\n * with no resolvable invocation is no longer trusted.\n *\n * TRUST BOUNDARY (still open, tracked as the remaining part of H3): this is a\n * store-level presence check. The invocation's CAR signature was verified when\n * it was minted, but it is NOT re-verified here. A room member with write\n * access can still forge BOTH a run record and a matching invocation entry.\n * Fully closing forgery requires re-verifying the stored CAR signature against\n * the delegation chain at read time — a 1.0.0 trust-model decision, not a\n * presence tweak. Do not describe this check as making completions\n * unforgeable.\n */\nfunction isTrustedRunRecord(record: RunRecordDetails, ucanRequired: boolean, invocationsMap: Y.Map<unknown>): boolean {\n if (!ucanRequired) return true;\n if (!record.invocationCid) return false;\n return invocationsMap.get(record.invocationCid) !== undefined;\n}\n\n/**\n * Process a single run record: for each event it emitted, queue a pending\n * invocation on every subscribed listener if not already queued.\n */\nfunction processRunRecord(\n yDoc: Y.Doc,\n runId: string,\n sourceBlockId: string,\n record: RunRecordDetails,\n listenersBySource: Map<string, Array<{ block: any; trigger: TriggerSpec }>>,\n getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined,\n isConsumed: (listenerBlockId: string, pendingId: string) => boolean,\n now: number\n): void {\n if (!Array.isArray(record.events)) return;\n\n record.events.forEach((event, eventIndex) => {\n if (!event?.name) return;\n const key = `${sourceBlockId}::${event.name}`;\n const listeners = listenersBySource.get(key);\n if (!listeners || listeners.length === 0) return;\n\n for (const { block: listenerBlock } of listeners) {\n const listenerBlockId = listenerBlock.id;\n if (!listenerBlockId) continue;\n\n const id = computePendingInvocationId({\n sourceBlockId,\n sourceRunId: record.runId,\n listenerBlockId,\n eventName: event.name,\n eventIndex,\n sessionRunId: runId,\n });\n\n // A pending invocation the listener already ran must not resurrect\n // from the immutable source run record after its removal-on-invoke.\n if (isConsumed(listenerBlockId, id)) continue;\n\n const assigneeDid = resolveAssignee(listenerBlock) || 'unassigned';\n\n // Snapshot every nodeId.output.* ref the listener references at this\n // moment. This is the §3.5.1 fix that makes the Sally → Mike scenario\n // produce frozen values per pending invocation.\n const inputs = parseInputs(listenerBlock);\n const refSnapshots = snapshotInputRefs(inputs, getNodeOutput);\n\n const expiresAt = computeExpiry(listenerBlock, record.completedAt);\n\n // Never (re-)queue an invocation that is already past its expiry —\n // this is what lets the expiration sweep physically delete entries\n // without the write-only-on-new loop restoring them.\n if (expiresAt && Date.parse(expiresAt) < now) continue;\n\n const invocation: PendingInvocation = {\n id,\n triggeringBlockId: sourceBlockId,\n sourceRunId: record.runId,\n sessionRunId: runId,\n eventName: event.name,\n eventIndex,\n payload: event.payload as Record<string, unknown>,\n refSnapshots,\n assigneeDid,\n emittedAt: record.completedAt,\n expiresAt,\n };\n\n queuePendingInvocation(yDoc, listenerBlockId, invocation, runId);\n\n // Write the payload into the listener's runtime so the FlowDetail\n // can read it without depending on React state. Through the waist:\n // run entry + flat mirror, one transaction, merged onto the resolved\n // previous value (a raw flat read-modify-write here would drop whatever\n // the run entry holds).\n writeActionState(yDoc, runId, listenerBlockId, {\n pendingPayload: { ...(event.payload as Record<string, unknown>), ...refSnapshots },\n });\n }\n });\n}\n\nfunction processBarrierRunRecord(\n yDoc: Y.Doc,\n runId: string,\n sourceBlockId: string,\n record: RunRecordDetails,\n barrierListenersBySource: Map<string, Array<{ block: any; trigger: TriggerSpec; source: { sourceBlockId: string; eventName: string; alias: string } }>>,\n getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined,\n isConsumed: (listenerBlockId: string, pendingId: string) => boolean,\n now: number\n): void {\n if (!Array.isArray(record.events)) return;\n\n for (const event of record.events) {\n if (!event?.name) continue;\n const key = `${sourceBlockId}::${event.name}`;\n const listeners = barrierListenersBySource.get(key);\n if (!listeners || listeners.length === 0) continue;\n\n for (const { block: listenerBlock, trigger, source } of listeners) {\n const listenerBlockId = listenerBlock.id;\n if (!listenerBlockId) continue;\n\n const entry = {\n sourceBlockId,\n eventName: event.name,\n alias: source.alias,\n runId: record.runId,\n sessionRunId: runId,\n payload: (event.payload as Record<string, unknown>) || {},\n emittedAt: record.completedAt,\n };\n\n recordBarrierEvent(yDoc, listenerBlockId, entry, runId);\n\n // Accumulate this source's payload into the listener's runtime so partial\n // barrier state is visible to the FlowDetail. Read through the waist too:\n // accumulating onto a raw flat read would silently discard partial\n // barrier payload already accumulated in the run entry.\n const existing = readActionState(yDoc, runId, listenerBlockId).pendingPayload || {};\n writeActionState(yDoc, runId, listenerBlockId, {\n pendingPayload: { ...existing, ...((event.payload as Record<string, unknown>) || {}) },\n });\n\n const allSources = trigger.sources || [];\n const currentState = readBarrierState(yDoc, listenerBlockId, runId);\n\n // Optional sources don't gate queuing — the barrier fires once every\n // required source has fired. Optional payloads are merged in if they\n // already arrived (mergeBarrierPayloads reads currentState below).\n const requiredSources = allSources.filter((s) => s.optional !== true);\n // Degenerate all-optional config falls back to \"all sources\" so the\n // barrier can still complete instead of never firing.\n const gatingSources = requiredSources.length > 0 ? requiredSources : allSources;\n\n const allFired = gatingSources.length > 0 && gatingSources.every((s) => currentState.some((e) => e.sourceBlockId === s.sourceBlockId && e.eventName === s.eventName));\n\n if (!allFired) continue;\n\n const assigneeDid = resolveAssignee(listenerBlock) || 'unassigned';\n\n const id = computeBarrierInvocationId(currentState, listenerBlockId, runId);\n // A barrier invocation the listener already ran must not resurrect.\n if (isConsumed(listenerBlockId, id)) continue;\n const mergedPayload = mergeBarrierPayloads(currentState);\n\n const inputs = parseInputs(listenerBlock);\n const refSnapshots = snapshotInputRefs(inputs, getNodeOutput);\n const expiresAt = computeExpiry(listenerBlock, record.completedAt);\n\n // Never (re-)queue an invocation that is already past its expiry —\n // this is what lets the expiration sweep physically delete entries\n // without the write-only-on-new loop restoring them.\n if (expiresAt && Date.parse(expiresAt) < now) continue;\n\n const invocation: PendingInvocation = {\n id,\n triggeringBlockId: sourceBlockId,\n sourceRunId: record.runId,\n sessionRunId: runId,\n eventName: `barrier:${allSources.map((s) => s.alias).join('+')}`,\n eventIndex: 0,\n payload: mergedPayload,\n refSnapshots,\n assigneeDid,\n emittedAt: record.completedAt,\n expiresAt,\n };\n\n queuePendingInvocation(yDoc, listenerBlockId, invocation, runId);\n clearBarrierState(yDoc, listenerBlockId, runId);\n\n // Persist the merged payload into the listener block's runtime so the\n // FlowDetail can read it across navigation without relying on React state.\n writeActionState(yDoc, runId, listenerBlockId, {\n pendingPayload: { ...mergedPayload, ...refSnapshots },\n });\n }\n }\n}\n\n// ─── Block prop helpers ─────────────────────────────────────────────────────\n\nfunction parseTrigger(block: any): TriggerSpec | null {\n const raw = block?.props?.trigger;\n if (!raw || typeof raw !== 'string') return null;\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object' && typeof parsed.type === 'string') {\n return parsed as TriggerSpec;\n }\n } catch {\n // Invalid trigger JSON — treat as no trigger, but say so once.\n warnOnce(`trigger-parse:${block?.id}`, `[flow-config] block ${block?.id}: props.trigger is not valid JSON; trigger ignored`);\n }\n return null;\n}\n\nfunction parseInputs(block: any): Record<string, unknown> {\n const raw = block?.props?.inputs;\n if (!raw || typeof raw !== 'string') return {};\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object') return parsed as Record<string, unknown>;\n } catch {\n // Invalid inputs JSON — treat as empty, but say so once.\n warnOnce(`inputs-parse:${block?.id}`, `[flow-config] block ${block?.id}: props.inputs is not valid JSON; treated as empty`);\n }\n return {};\n}\n\nfunction resolveAssignee(block: any): string | undefined {\n const raw = block?.props?.assignment;\n if (!raw) return undefined;\n try {\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n const did = parsed?.assignedActor?.did;\n return typeof did === 'string' && did.length > 0 ? did : undefined;\n } catch {\n warnOnce(`assignment-parse:${block?.id}`, `[flow-config] block ${block?.id}: props.assignment is not valid JSON; assignee unresolved`);\n return undefined;\n }\n}\n\n/**\n * Compute the expiration timestamp for a pending invocation, reusing the\n * existing TTL props on the listener block (slice D persists these via\n * blockMapping). Falls back to 7 days from emission if no TTL is set.\n */\nfunction computeExpiry(block: any, emittedAt: string): string {\n const ttlAbsolute = block?.props?.ttlAbsoluteDueDate;\n if (typeof ttlAbsolute === 'string' && ttlAbsolute) {\n return ttlAbsolute;\n }\n\n const ttlFromEnablement = block?.props?.ttlFromEnablement;\n if (typeof ttlFromEnablement === 'string' && ttlFromEnablement) {\n // Parse ISO 8601 duration like \"P7D\" → milliseconds\n const ms = parseIsoDurationToMs(ttlFromEnablement);\n if (ms != null) {\n return new Date(new Date(emittedAt).getTime() + ms).toISOString();\n }\n }\n\n // Default: 7 days\n return new Date(new Date(emittedAt).getTime() + 7 * 24 * 60 * 60 * 1000).toISOString();\n}\n\n/** Parse a small subset of ISO 8601 durations: P[n]D, PT[n]H, PT[n]M, PT[n]S. */\nfunction parseIsoDurationToMs(duration: string): number | null {\n const match = /^P(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?$/.exec(duration);\n if (!match) return null;\n const [, d, h, m, s] = match;\n let ms = 0;\n if (d) ms += parseInt(d, 10) * 24 * 60 * 60 * 1000;\n if (h) ms += parseInt(h, 10) * 60 * 60 * 1000;\n if (m) ms += parseInt(m, 10) * 60 * 1000;\n if (s) ms += parseInt(s, 10) * 1000;\n return ms;\n}\n\n// ─── Action registry compatibility ──────────────────────────────────────────\n// The reconciliation loop doesn't strictly need to look up the action — it\n// trusts the compiler to have validated the trigger and event vocabulary at\n// compile time. But for diagnostics, expose a helper that returns the action\n// for a given block. Used by slice F's tests and slice J's UI.\n\nexport function getActionForBlock(block: any): ReturnType<typeof getAction> {\n const actionType = block?.props?.actionType;\n if (typeof actionType !== 'string') return undefined;\n return getAction(actionType);\n}\n","import * as Y from 'yjs';\nimport type { IxoEditorType } from '../../types/editor';\nimport { resolveActiveRunId } from './runs';\nimport { appendRunRecord, type RunRecordDetails } from './triggers';\nimport { reconcilePendingInvocations } from './reconcile';\n\n/**\n * Write a run record to the audit trail and trigger the reconciliation loop\n * so listener blocks pick up the emitted events as pending invocations.\n *\n * Call this after `updateRuntime({ state: 'completed', output })` in any\n * FlowDetail component whose action defines events.\n *\n * @param runId The **session run** (`runs.ts`) this emission belongs to.\n * Defaults to the active run. Recorded additively as\n * `RunRecordDetails.sessionRunId`; nothing in Phase A reads it, and it is\n * deliberately kept out of `computePendingInvocationId` (D2 / spec §2 rule 8\n * — the id space moves in Phase B, together with `pendingInvocations` and\n * `barrierState`, or the same logical event queues once per generation).\n */\nexport function writeRunRecordAndReconcile(\n editor: IxoEditorType,\n blockId: string,\n output: Record<string, unknown>,\n events: Array<{ name: string; payload: Record<string, unknown> }>,\n actorDid: string,\n detailsPatch: Partial<RunRecordDetails> & { sourceRunId?: string } = {},\n runId?: string\n): void {\n const yDoc = (editor as unknown as { _yDoc?: Y.Doc })._yDoc;\n if (!yDoc) return;\n if (events.length === 0) return;\n\n // The per-EXECUTION audit id, not the session run — `RunRecordDetails.runId`\n // keeps its historical meaning and format because it is live persisted data\n // feeding `computePendingInvocationId` (D2).\n const executionId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const now = new Date().toISOString();\n\n const details: RunRecordDetails = {\n runId: executionId,\n sessionRunId: runId || resolveActiveRunId(yDoc),\n output,\n events,\n startedAt: now,\n completedAt: now,\n actorDid,\n ...detailsPatch,\n };\n\n appendRunRecord(yDoc, blockId, details, actorDid);\n reconcilePendingInvocations(editor, details.sessionRunId);\n}\n","import type { Doc, Map as YMap } from 'yjs';\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport type { IxoEditorType } from '../../types/editor';\nimport { FLOW_CONNECTION_BINDINGS_MAP_KEY } from '../flowCompiler/connections';\nimport { DM_NOTIFICATIONS_MAP_KEY } from './dmNotificationState';\nimport { RUNS_MAP_KEY, RUNS_TERMINAL_MAP_KEY, RUNS_TERMINAL_PENDING_MAP_KEY, createRunScopedRuntimeManager, resolveRunIdForExecution } from './runs';\nimport { BARRIER_STATE_MAP_KEY } from './triggers';\n\nconst XERO_WORK_ITEMS_MAP_NAME = 'xeroWorkItems';\nconst XERO_WORK_TERMINAL_MAP_NAME = 'xeroWorkItemsTerminal';\nconst XERO_CONNECTION_MAP_NAME = 'xeroConnection';\n\nexport interface FlowRuntimeStateManager {\n get: (nodeId: string) => FlowNodeRuntimeState;\n update: (nodeId: string, updates: Partial<FlowNodeRuntimeState>) => void;\n}\n\n/**\n * The small, public Y.Doc surface needed to clear execution state.\n *\n * Keeping this structural prevents a linked consumer with a compatible Yjs\n * minor version from inheriting this package's private Y.Doc type identity.\n * Template cleanup only needs map iteration/deletion and one transaction.\n */\nexport interface TemplateCloneDocument {\n getMap(name?: string): {\n forEach(callback: (value: unknown, key: string) => void): void;\n delete(key: string): void;\n };\n transact(callback: () => void): void;\n}\n\nconst ensureStateObject = (value: unknown): FlowNodeRuntimeState => {\n if (!value || typeof value !== 'object') {\n return {};\n }\n return { ...(value as FlowNodeRuntimeState) };\n};\n\nconst createYMapManager = (map: YMap<any>): FlowRuntimeStateManager => {\n return {\n get: (nodeId: string) => {\n const stored = map.get(nodeId);\n return ensureStateObject(stored);\n },\n update: (nodeId: string, updates: Partial<FlowNodeRuntimeState>) => {\n const current = ensureStateObject(map.get(nodeId));\n map.set(nodeId, { ...current, ...updates });\n },\n };\n};\n\nconst createMemoryManager = (): FlowRuntimeStateManager => {\n const memory = new Map<string, FlowNodeRuntimeState>();\n return {\n get: (nodeId: string) => ensureStateObject(memory.get(nodeId)),\n update: (nodeId: string, updates: Partial<FlowNodeRuntimeState>) => {\n const current = ensureStateObject(memory.get(nodeId));\n memory.set(nodeId, { ...current, ...updates });\n },\n };\n};\n\n/**\n * Resolve the Y.Doc behind an editor handle.\n *\n * `_yDoc` is the real field; `_yRuntime.doc` is the long-standing fallback used\n * across this repo (`useEntities.ts`, `DebugButton.tsx`) and by every test that\n * builds an editor stub as `{ _yRuntime: yDoc.getMap('runtime') }`. A duck-typed\n * mock map has no `.doc`, which is exactly what keeps those callers on the\n * legacy path below instead of throwing.\n *\n * Exported so the React write path (`useNodeRuntime`) resolves the doc by\n * exactly the same rule the core write path does. Two subtly different\n * resolutions would leave the two twins of a path on different generations —\n * precisely the half-measure §9.3's adoption gate exists to forbid.\n */\nexport function resolveEditorYDoc(editor?: IxoEditorType | null): Doc | undefined {\n const direct = (editor as { _yDoc?: Doc } | null | undefined)?._yDoc;\n if (direct && typeof direct.getMap === 'function') return direct;\n const viaRuntime = (editor as { _yRuntime?: { doc?: Doc } } | null | undefined)?._yRuntime?.doc;\n return viaRuntime && typeof viaRuntime.getMap === 'function' ? viaRuntime : undefined;\n}\n\n/**\n * `FlowRuntimeStateManager` for an editor.\n *\n * IGNITION PHASE A: when a Y.Doc is reachable this delegates to the run-scoped\n * manager (`runs.ts#createRunScopedRuntimeManager`), so every `update()` made\n * through it dual-writes the run entry and the flat mirror in one transaction,\n * and every `get()` resolves the two through the freshness predicate. That is\n * what makes a *downgrade* — a reset, an unchecked box, a read-back proof\n * failure — visible on both sides; a flat-only downgrade can never be\n * materialised into the run and would strand the stale higher state forever\n * (§9.3 The adoption gate).\n *\n * The name is kept because it is public API (`src/index.ts`, `src/core/index.ts`).\n *\n * The two non-doc branches are unchanged on purpose: a duck-typed `_yRuntime`\n * (test stubs, mocks) still gets a plain map manager, and a handle-less editor\n * still gets the historical in-memory manager rather than a throw — narrowing\n * that contract is a separate, breaking change.\n */\nexport const createRuntimeStateManager = (editor?: IxoEditorType | null, runId?: string): FlowRuntimeStateManager => {\n const yDoc = resolveEditorYDoc(editor);\n if (yDoc) {\n return createRunScopedRuntimeManager(yDoc, resolveRunIdForExecution(yDoc, runId));\n }\n if (editor?._yRuntime) {\n return createYMapManager(editor._yRuntime);\n }\n return createMemoryManager();\n};\n\n/**\n * `FlowRuntimeStateManager` for a Y.Doc.\n *\n * IGNITION PHASE A: a thin alias for the run-scoped manager over the active\n * run. Kept as a named export because it is public API and both orchestrators\n * (flow-manager, flow-agent) import it.\n */\nexport const createYDocRuntimeManager = (yDoc: Doc, runId?: string): FlowRuntimeStateManager => {\n return createRunScopedRuntimeManager(yDoc, resolveRunIdForExecution(yDoc, runId));\n};\n\n/**\n * Clears runtime, invocations, and pending invocations from a Y.Doc.\n * Used when cloning a flow as a template — the new document should\n * carry only configuration (intent), not execution history.\n *\n * The audit trail (which now also holds run records as `type: 'block.run'`\n * entries) and pending invocations are observation, not configuration —\n * both are cleared on template clone.\n *\n * `barrierState` belongs to the same class and was missing here: a partially\n * filled barrier (`block.event.all`) survived the clone, so a single source\n * firing in the clone could satisfy the barrier using entries emitted in the\n * *source* flow and queue an invocation whose merged payload mixes two flows.\n *\n * `dmNotificationState` is dedup bookkeeping about DMs that were sent for the\n * source flow's execution; carrying it into a clone suppresses the clone's\n * first legitimate notification for every block already notified upstream.\n *\n * `runs`, `runsTerminalPending`, and `runsTerminal` are where that same execution state now lives\n * (Ignition Phase A). Clearing the flat `runtime` map without clearing `runs`\n * would leave the clone pre-completed for every adopted block. Deleting the\n * outer run key is sufficient — the nested per-run maps go with it.\n *\n * `qi.flow.connectionBindings` names one workspace's connected accounts, so it\n * is cleared too: a clone that kept them would point at a Xero organisation its\n * own members hold no grant for, and would read as connected while every call\n * through it fails. The requirements themselves (`qi.flow.connections`) are\n * configuration and survive, exactly like the participant roster.\n */\nexport function clearRuntimeForTemplateClone(yDoc: TemplateCloneDocument): void {\n const runtime = yDoc.getMap('runtime');\n const runs = yDoc.getMap(RUNS_MAP_KEY);\n const runsTerminalPending = yDoc.getMap(RUNS_TERMINAL_PENDING_MAP_KEY);\n const runsTerminal = yDoc.getMap(RUNS_TERMINAL_MAP_KEY);\n const invocations = yDoc.getMap('invocations');\n const pendingInvocations = yDoc.getMap('pendingInvocations');\n const barrierState = yDoc.getMap(BARRIER_STATE_MAP_KEY);\n const dmNotificationState = yDoc.getMap(DM_NOTIFICATIONS_MAP_KEY);\n const agentOutbox = yDoc.getMap('agentOutbox');\n const agentLeases = yDoc.getMap('agentLeases');\n const auditTrail = yDoc.getMap('auditTrail');\n const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME);\n const xeroWorkTerminal = yDoc.getMap(XERO_WORK_TERMINAL_MAP_NAME);\n const xeroConnection = yDoc.getMap(XERO_CONNECTION_MAP_NAME);\n const connectionBindings = yDoc.getMap(FLOW_CONNECTION_BINDINGS_MAP_KEY);\n const designPodState = yDoc.getMap('designPodState');\n const root = yDoc.getMap('root');\n\n yDoc.transact(() => {\n runtime.forEach((_, key) => runtime.delete(key));\n runs.forEach((_, key) => runs.delete(key));\n runsTerminalPending.forEach((_, key) => runsTerminalPending.delete(key));\n runsTerminal.forEach((_, key) => runsTerminal.delete(key));\n invocations.forEach((_, key) => invocations.delete(key));\n pendingInvocations.forEach((_, key) => pendingInvocations.delete(key));\n barrierState.forEach((_, key) => barrierState.delete(key));\n dmNotificationState.forEach((_, key) => dmNotificationState.delete(key));\n agentOutbox.forEach((_, key) => agentOutbox.delete(key));\n agentLeases.forEach((_, key) => agentLeases.delete(key));\n auditTrail.forEach((_, key) => auditTrail.delete(key));\n xeroWorkItems.forEach((_, key) => xeroWorkItems.delete(key));\n xeroWorkTerminal.forEach((_, key) => xeroWorkTerminal.delete(key));\n xeroConnection.forEach((_, key) => xeroConnection.delete(key));\n connectionBindings.forEach((_, key) => connectionBindings.delete(key));\n // The method definition is template configuration and remains pinned. The\n // project state is provider-specific build and approval history.\n designPodState.forEach((_, key) => designPodState.delete(key));\n // Selection is execution state and would point at a run removed above.\n // Keep runStorageVersion: it is the document's storage format, not history.\n root.delete('activeRunId');\n });\n}\n","import type * as Y from 'yjs';\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport { getNestedValue } from './referenceResolver';\nimport { readActionState, usesLegacyRuntimeCompatibility } from './runs';\n\nexport type ConditionOperator = 'equals' | 'not_equals' | 'greater_than' | 'less_than' | 'contains' | 'not_contains' | 'is_empty' | 'is_not_empty';\n\nexport interface BlockCondition {\n id: string;\n name: string;\n description?: string;\n sourceBlockId: string;\n sourceBlockType: string;\n rule: {\n type: 'property_value';\n property: string;\n operator: ConditionOperator;\n value: string | number | boolean;\n };\n effect: {\n action: 'enable' | 'disable' | 'hide' | 'show';\n message?: string;\n };\n}\n\nexport interface ConditionConfig {\n enabled: boolean;\n mode: 'all_must_pass' | 'any_can_pass';\n conditions: BlockCondition[];\n}\n\nexport interface ConditionEvaluationResult {\n passes: boolean;\n message?: string;\n}\n\nexport interface ConditionActionResult {\n action: 'enable' | 'disable' | 'hide' | 'show';\n message?: string;\n conditionName: string;\n}\n\nexport interface BlockConditionsResult {\n actions: ConditionActionResult[];\n}\n\nexport interface BlockExecutionEligibility {\n eligible: boolean;\n enabled: boolean;\n visible: boolean;\n message?: string;\n result: BlockConditionsResult;\n}\n\nexport interface ConditionEvaluationOptions {\n getRuntimeState?: (blockId: string) => FlowNodeRuntimeState | undefined;\n /**\n * Phase A only: fall back to authored props when no run output exists.\n * Multi-run documents deliberately disable this so execution results never\n * leak through shared definition props.\n */\n allowPropsFallback?: boolean;\n}\n\nconst OPERATOR_INVERSIONS: Record<ConditionOperator, ConditionOperator> = {\n equals: 'not_equals',\n not_equals: 'equals',\n contains: 'not_contains',\n not_contains: 'contains',\n is_empty: 'is_not_empty',\n is_not_empty: 'is_empty',\n greater_than: 'less_than',\n less_than: 'greater_than',\n};\n\nconst ACTION_INVERSIONS: Record<BlockCondition['effect']['action'], BlockCondition['effect']['action'] | null> = {\n disable: 'enable',\n hide: 'show',\n enable: null,\n show: null,\n};\n\nexport function normalizeCondition(condition: BlockCondition): BlockCondition {\n const canonicalAction = ACTION_INVERSIONS[condition.effect.action];\n if (canonicalAction === null) return condition;\n\n let value = condition.rule.value;\n if ((condition.rule.operator === 'equals' || condition.rule.operator === 'not_equals') && typeof value === 'boolean') {\n value = !value;\n }\n return {\n ...condition,\n rule: {\n ...condition.rule,\n operator: OPERATOR_INVERSIONS[condition.rule.operator],\n value,\n },\n effect: { ...condition.effect, action: canonicalAction },\n };\n}\n\nexport function normalizeConditions(conditions: BlockCondition[]): BlockCondition[] {\n return conditions.map(normalizeCondition);\n}\n\nexport function parseConditionConfig(value: unknown): ConditionConfig {\n if (!value) return { enabled: false, mode: 'all_must_pass', conditions: [] };\n try {\n const parsed = typeof value === 'string' ? JSON.parse(value) : value;\n if (!parsed || typeof parsed !== 'object') {\n return { enabled: false, mode: 'all_must_pass', conditions: [] };\n }\n const candidate = parsed as Partial<ConditionConfig>;\n return {\n enabled: candidate.enabled === true,\n mode: candidate.mode === 'any_can_pass' ? 'any_can_pass' : 'all_must_pass',\n conditions: Array.isArray(candidate.conditions) ? (candidate.conditions as BlockCondition[]) : [],\n };\n } catch {\n return { enabled: false, mode: 'all_must_pass', conditions: [] };\n }\n}\n\nexport class InvalidConditionConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'InvalidConditionConfigError';\n }\n}\n\n/** Fail-closed parser for execution/planning boundaries. */\nexport function parseConditionConfigStrict(value: unknown): ConditionConfig {\n if (value == null || value === '') {\n return { enabled: false, mode: 'all_must_pass', conditions: [] };\n }\n let parsed: unknown;\n try {\n parsed = typeof value === 'string' ? JSON.parse(value) : value;\n } catch {\n throw new InvalidConditionConfigError('Block conditions are not valid JSON.');\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new InvalidConditionConfigError('Block conditions must be an object.');\n }\n const candidate = parsed as Partial<ConditionConfig>;\n if (candidate.enabled !== true) {\n return { enabled: false, mode: 'all_must_pass', conditions: [] };\n }\n if (candidate.mode !== 'all_must_pass' && candidate.mode !== 'any_can_pass') {\n throw new InvalidConditionConfigError('Enabled block conditions require a valid mode.');\n }\n if (!Array.isArray(candidate.conditions)) {\n throw new InvalidConditionConfigError('Enabled block conditions require a conditions array.');\n }\n for (const condition of candidate.conditions) {\n if (\n !condition ||\n typeof condition !== 'object' ||\n typeof (condition as BlockCondition).sourceBlockId !== 'string' ||\n !(condition as BlockCondition).rule ||\n !(condition as BlockCondition).effect\n ) {\n throw new InvalidConditionConfigError('Block conditions contain an invalid condition.');\n }\n }\n return {\n enabled: true,\n mode: candidate.mode,\n conditions: candidate.conditions as BlockCondition[],\n };\n}\n\nfunction flattenBlocks(blocks: unknown[]): unknown[] {\n const flattened: unknown[] = [];\n const visit = (block: unknown) => {\n flattened.push(block);\n const children = (block as { children?: unknown[] } | null)?.children;\n if (Array.isArray(children)) children.forEach(visit);\n };\n blocks.forEach(visit);\n return flattened;\n}\n\nfunction resolveRuntimeValue(runtime: FlowNodeRuntimeState | undefined, property: string): unknown {\n if (!runtime) return undefined;\n if (property.startsWith('output.')) {\n return getNestedValue(runtime.output, property.slice('output.'.length));\n }\n const direct = getNestedValue(runtime, property);\n if (direct !== undefined) return direct;\n return getNestedValue(runtime.output, property);\n}\n\nexport function resolveConditionSourceValue(condition: BlockCondition, sourceBlock: unknown, options: ConditionEvaluationOptions = {}): unknown {\n const runtimeValue = resolveRuntimeValue(options.getRuntimeState?.(condition.sourceBlockId), condition.rule.property);\n if (runtimeValue !== undefined || options.allowPropsFallback === false) return runtimeValue;\n const props = (sourceBlock as { props?: unknown } | null | undefined)?.props;\n return getNestedValue(props, condition.rule.property);\n}\n\nfunction compareConditionValue(sourceValue: unknown, operator: ConditionOperator, expected: unknown): boolean {\n switch (operator) {\n case 'equals':\n return sourceValue === expected;\n case 'not_equals':\n return sourceValue !== expected;\n case 'greater_than':\n return typeof sourceValue === 'number' && typeof expected === 'number' && sourceValue > expected;\n case 'less_than':\n return typeof sourceValue === 'number' && typeof expected === 'number' && sourceValue < expected;\n case 'contains':\n return typeof sourceValue === 'string' && typeof expected === 'string' && sourceValue.toLowerCase().includes(expected.toLowerCase());\n case 'not_contains':\n return typeof sourceValue === 'string' && typeof expected === 'string' && !sourceValue.toLowerCase().includes(expected.toLowerCase());\n case 'is_empty':\n return sourceValue === '' || sourceValue === null || sourceValue === undefined;\n case 'is_not_empty':\n return sourceValue !== '' && sourceValue !== null && sourceValue !== undefined;\n }\n}\n\nexport function evaluateCondition(condition: BlockCondition, sourceBlock: unknown, options: ConditionEvaluationOptions = {}): ConditionEvaluationResult {\n if (!sourceBlock) {\n return {\n passes: false,\n message: `Required block not found: ${condition.name || condition.sourceBlockType}`,\n };\n }\n const passes = compareConditionValue(resolveConditionSourceValue(condition, sourceBlock, options), condition.rule.operator, condition.rule.value);\n return { passes, message: passes ? undefined : condition.effect.message };\n}\n\nexport function evaluateBlockConditions(conditionConfig: ConditionConfig, editorDocument: unknown[], options: ConditionEvaluationOptions = {}): BlockConditionsResult {\n if (!conditionConfig.enabled || conditionConfig.conditions.length === 0) return { actions: [] };\n const blocks = flattenBlocks(editorDocument);\n\n const evaluations = normalizeConditions(conditionConfig.conditions).map((condition) => {\n const sourceBlock = blocks.find((block) => {\n const candidate = block as { id?: unknown; type?: unknown };\n return candidate.id === condition.sourceBlockId && candidate.type === condition.sourceBlockType;\n });\n return { condition, result: evaluateCondition(condition, sourceBlock, options) };\n });\n\n const passed =\n conditionConfig.mode === 'all_must_pass' ? (evaluations.every(({ result }) => result.passes) ? evaluations : []) : evaluations.filter(({ result }) => result.passes);\n\n return {\n actions: passed.map(({ condition }) => ({\n action: condition.effect.action,\n message: condition.effect.message,\n conditionName: condition.name,\n })),\n };\n}\n\n/** Canonical run-aware evaluator used by browser and headless consumers. */\nexport function evaluateBlockConditionsForRun(conditionConfig: ConditionConfig, editorDocument: unknown[], yDoc: Y.Doc, sessionRunId: string): BlockConditionsResult {\n return evaluateBlockConditions(conditionConfig, editorDocument, {\n getRuntimeState: (blockId) => readActionState(yDoc, sessionRunId, blockId),\n allowPropsFallback: usesLegacyRuntimeCompatibility(yDoc),\n });\n}\n\n/**\n * Canonical decision used immediately before execution and by planners. The\n * condition vocabulary is positive after normalization: if an authored\n * enable/show gate exists, at least one corresponding action must fire.\n */\nexport function evaluateBlockExecutionEligibilityForRun(conditionConfig: ConditionConfig, editorDocument: unknown[], yDoc: Y.Doc, sessionRunId: string): BlockExecutionEligibility {\n const normalized = normalizeConditions(conditionConfig.conditions);\n const result = evaluateBlockConditionsForRun(conditionConfig, editorDocument, yDoc, sessionRunId);\n const requiresEnable = normalized.some((condition) => condition.effect.action === 'enable');\n const requiresShow = normalized.some((condition) => condition.effect.action === 'show');\n const enabled = !conditionConfig.enabled || !requiresEnable || result.actions.some((action) => action.action === 'enable');\n const visible = !conditionConfig.enabled || !requiresShow || result.actions.some((action) => action.action === 'show');\n const failedMessage = normalized.map((condition) => condition.effect.message).find((message): message is string => !!message);\n return {\n eligible: enabled && visible,\n enabled,\n visible,\n ...(enabled && visible ? {} : { message: failedMessage || 'Block conditions are not satisfied.' }),\n result,\n };\n}\n","import { FlowNode, FlowNodeAuthzExtension } from '../../types/authorization';\n\nexport const buildAuthzFromProps = (props: Record<string, any>): FlowNodeAuthzExtension => {\n const linkedClaimCollectionId = typeof props.linkedClaimCollectionId === 'string' ? props.linkedClaimCollectionId.trim() : '';\n\n const authz: FlowNodeAuthzExtension = {};\n\n if (linkedClaimCollectionId) {\n authz.linkedClaim = { collectionId: linkedClaimCollectionId };\n }\n\n return authz;\n};\n\nexport const buildFlowNodeFromBlock = (block: any): FlowNode => {\n const base: FlowNode = {\n id: block.id,\n type: block.type,\n props: block.props || {},\n } as FlowNode;\n\n const authz = buildAuthzFromProps(block.props || {});\n\n return {\n ...base,\n ...authz,\n };\n};\n","import type { ActionDefinition, ActionProofDeclaration } from '../actionRegistry/types';\n\nexport const PROOF_MISSING_CODE = 'PROOF_MISSING';\n\nexport interface ProofValidationResult {\n valid: boolean;\n reason?: string;\n}\n\nfunction getOutputValue(output: Record<string, unknown>, path: string): unknown {\n return path.split('.').reduce<unknown>((acc, key) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[key];\n return undefined;\n }, output);\n}\n\nfunction isProofValue(value: unknown): boolean {\n if (Array.isArray(value)) return value.length > 0;\n // A numeric proof field is present when it is any real number — including\n // 0, which is a legitimate value for zero-indexed on-chain ids, a `status`\n // of 0, or an epoch timestamp. `!!value` would wrongly reject those. `false`\n // stays non-proof: a boolean success flag (configStored, alreadyExisted) is\n // only proof when true.\n if (typeof value === 'number') return !Number.isNaN(value);\n return !!value;\n}\n\n/**\n * Validate a successful action run's output against the action's proof\n * declaration. Called by `executeActionBlock` before writing\n * `state: 'completed'` — success without proof becomes a failure.\n *\n * A `sideEffect: true` action with no declaration fails closed; a\n * side-effect-free action with no declaration is tolerated (legacy\n * consumer-registered actions) but should declare `'none'` explicitly.\n */\nexport function validateActionProof(\n action: Pick<ActionDefinition, 'type' | 'sideEffect'> & { proof?: ActionProofDeclaration },\n output: Record<string, unknown>\n): ProofValidationResult {\n const proof = action.proof;\n\n if (proof === 'none') return { valid: true };\n\n if (proof === undefined) {\n if (action.sideEffect) {\n return {\n valid: false,\n reason: `Action '${action.type}' has a side effect but declares no proof of execution. Declare proof (or 'none') on its ActionDefinition.`,\n };\n }\n return { valid: true };\n }\n\n if ('validate' in proof) {\n let valid = false;\n try {\n valid = proof.validate(output);\n } catch {\n valid = false;\n }\n return valid ? { valid: true } : { valid: false, reason: `Action '${action.type}' returned success but its proof validator rejected the output.` };\n }\n\n const satisfied = proof.fields.some((field) => isProofValue(getOutputValue(output, field)));\n if (satisfied) return { valid: true };\n return {\n valid: false,\n reason: `Action '${action.type}' returned success without proof. Expected at least one of [${proof.fields.join(', ')}] in the output. Check the handler logs.`,\n };\n}\n","import type * as Y from 'yjs';\nimport type { ActionDefinition, ActionRunContext, CompletionCheck } from '../actionRegistry/types';\nimport { getAction } from '../actionRegistry';\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport { validateActionProof } from './proof';\nimport { readActionState, writeActionState } from './runs';\nimport { boundRunActionOutput } from './runTimeline';\n\n/**\n * Fold a run entry to Done using the action's own completion contract.\n *\n * There is no fallback branch: every registered action declares `done` (the\n * registry backfills the default for untyped consumers), so the contract is\n * the single place Done-ness is decided. One-shot actions typically use\n * `doneWhenCompleted`, repeatable ones `neverDone`.\n */\nexport function isActionDone<TInputs extends Record<string, any> = Record<string, any>>(\n action: ActionDefinition<TInputs> | undefined,\n actionState: FlowNodeRuntimeState,\n runContext: ActionRunContext\n): boolean {\n if (!action) return false;\n return action.done.isDone(actionState, runContext);\n}\n\nexport function isActionTypeDone(actionType: string | undefined, actionState: FlowNodeRuntimeState, runContext: ActionRunContext): boolean {\n return isActionDone(actionType ? getAction(actionType) : undefined, actionState, runContext);\n}\n\n/**\n * `reopened`: a `reopenable` action's completed entry read back as not done —\n * new work arrived. The entry keeps its state and proof; only the check output\n * is merged so the pure fold now says \"not done\".\n */\nexport type CompletionReconciliationTransition = 'unchanged' | 'adopted' | 'reopened' | 'needs_verification' | 'unknown';\n\nexport interface ReconcileCompletionParams<TInputs extends Record<string, any> = Record<string, any>> {\n yDoc: Y.Doc;\n sessionRunId: string;\n blockId: string;\n actionType: string;\n inputs: TInputs;\n flowId?: string;\n flowUri?: string;\n actorDid?: string;\n services?: ActionRunContext['services'];\n handlers?: ActionRunContext['handlers'];\n now?: () => number;\n}\n\nexport interface ReconcileCompletionResult {\n transition: CompletionReconciliationTransition;\n check: CompletionCheck;\n previous: FlowNodeRuntimeState;\n next: FlowNodeRuntimeState;\n}\n\n/**\n * Reconcile a run entry against an action's pure/external completion contract.\n *\n * `check` is an explicit read: it must not execute the action or mutate the\n * external system. Unknown results are inert. A positive read can adopt work\n * completed outside this client; a negative read never retries an action and\n * instead moves a contradictory completed entry to human verification.\n */\nexport async function reconcileCompletion<TInputs extends Record<string, any> = Record<string, any>>(\n params: ReconcileCompletionParams<TInputs>\n): Promise<ReconcileCompletionResult> {\n const action = getAction(params.actionType) as ActionDefinition<TInputs> | undefined;\n if (!action) throw new Error(`Unknown action type \"${params.actionType}\"`);\n\n const previous = readActionState(params.yDoc, params.sessionRunId, params.blockId);\n const ctx: ActionRunContext = {\n runId: params.sessionRunId,\n flowId: params.flowId,\n flowUri: params.flowUri,\n actorDid: params.actorDid,\n nodeId: params.blockId,\n services: params.services,\n handlers: params.handlers,\n now: params.now?.() ?? Date.now(),\n };\n\n const check: CompletionCheck = action.done.check\n ? await action.done.check({ inputs: params.inputs, actionState: previous, ctx })\n : {\n done: isActionDone(action, previous, ctx),\n source: 'runtime-proof',\n };\n\n if (check.done === 'unknown') {\n return { transition: 'unknown', check, previous, next: previous };\n }\n\n // A snapshot qualifies a run that happened; it never stands in for one. An\n // empty queue on a block that has not fired is not a completion to adopt.\n if (action.done.reopenable && previous.state !== 'completed') {\n return { transition: 'unchanged', check, previous, next: previous };\n }\n\n if (check.done === true) {\n if (isActionDone(action, previous, ctx)) {\n return { transition: 'unchanged', check, previous, next: previous };\n }\n const mergedOutput = {\n ...((previous.output as Record<string, unknown>) || {}),\n ...(check.output || {}),\n };\n const proof = validateActionProof(action, mergedOutput);\n const bounded = boundRunActionOutput(mergedOutput);\n if (!proof.valid || bounded.exceeded) {\n const { next } = writeActionState(params.yDoc, params.sessionRunId, params.blockId, {\n state: 'needs_verification',\n output: bounded.output,\n error: {\n message: bounded.exceeded ? 'External completion output exceeds the run-head size limit.' : proof.reason || 'External completion did not return the action proof.',\n code: bounded.exceeded ? 'RUN_OUTPUT_TOO_LARGE' : 'COMPLETION_PROOF_MISSING',\n at: ctx.now,\n },\n reconciledAt: ctx.now,\n completionSource: check.source,\n } as Partial<FlowNodeRuntimeState>);\n return {\n transition: 'needs_verification',\n check,\n previous,\n next,\n };\n }\n const { next } = writeActionState(params.yDoc, params.sessionRunId, params.blockId, {\n state: 'completed',\n output: bounded.output,\n error: undefined,\n executedAt: previous.executedAt ?? ctx.now,\n reconciledAt: ctx.now,\n completionSource: check.source,\n } as Partial<FlowNodeRuntimeState>);\n return { transition: 'adopted', check, previous, next };\n }\n\n if (previous.state === 'completed' && action.done.reopenable) {\n if (!check.output) {\n return { transition: 'unchanged', check, previous, next: previous };\n }\n const wasDone = isActionDone(action, previous, ctx);\n const bounded = boundRunActionOutput({\n ...((previous.output as Record<string, unknown>) || {}),\n ...check.output,\n });\n if (bounded.exceeded) {\n return { transition: 'unchanged', check, previous, next: previous };\n }\n const { next } = writeActionState(params.yDoc, params.sessionRunId, params.blockId, {\n output: bounded.output,\n reconciledAt: ctx.now,\n completionSource: check.source,\n } as Partial<FlowNodeRuntimeState>);\n return { transition: wasDone ? 'reopened' : 'unchanged', check, previous, next };\n }\n\n if (previous.state === 'completed') {\n const { next } = writeActionState(params.yDoc, params.sessionRunId, params.blockId, {\n state: 'needs_verification',\n error: {\n message: check.reason || 'External completion check contradicts the completed run state.',\n code: 'COMPLETION_MISMATCH',\n at: ctx.now,\n },\n reconciledAt: ctx.now,\n completionSource: check.source,\n } as Partial<FlowNodeRuntimeState>);\n return { transition: 'needs_verification', check, previous, next };\n }\n\n return { transition: 'unchanged', check, previous, next: previous };\n}\n\nexport interface ReconcileCheckableCompletionsParams {\n yDoc: Y.Doc;\n sessionRunId: string;\n /** Manifest block id → action type, as frozen into the session. */\n actionTypes: Record<string, string>;\n /** The block's resolved inputs, as its own execution would see them. */\n inputsFor: (blockId: string, actionType: string) => Record<string, any>;\n flowId?: string;\n flowUri?: string;\n actorDid?: string;\n services?: ActionRunContext['services'];\n handlers?: ActionRunContext['handlers'];\n now?: () => number;\n}\n\n/**\n * Refresh every block whose action declares an external `check`, in manifest\n * order. This is the \"on a close attempt\" read: the session summary is a pure\n * fold over stored snapshots, so a close must first give each snapshot-backed\n * action one chance to notice work that arrived while nobody was looking.\n *\n * A check that throws is reported as `unknown` and leaves the entry untouched;\n * the close then judges the entry on what is already stored.\n */\nexport async function reconcileCheckableCompletions(params: ReconcileCheckableCompletionsParams): Promise<Record<string, ReconcileCompletionResult>> {\n const results: Record<string, ReconcileCompletionResult> = {};\n for (const [blockId, actionType] of Object.entries(params.actionTypes)) {\n const action = getAction(actionType);\n if (!action?.done.check) continue;\n try {\n results[blockId] = await reconcileCompletion({\n yDoc: params.yDoc,\n sessionRunId: params.sessionRunId,\n blockId,\n actionType,\n inputs: params.inputsFor(blockId, actionType),\n flowId: params.flowId,\n flowUri: params.flowUri,\n actorDid: params.actorDid,\n services: params.services,\n handlers: params.handlers,\n now: params.now,\n });\n } catch (error) {\n const previous = readActionState(params.yDoc, params.sessionRunId, blockId);\n results[blockId] = {\n transition: 'unknown',\n check: { done: 'unknown', source: 'reconcile', reason: error instanceof Error ? error.message : String(error) },\n previous,\n next: previous,\n };\n }\n }\n return results;\n}\n","import * as Y from 'yjs';\nimport type { Doc } from 'yjs';\nimport type { FlowAgentCommand, FlowAgentLedgerEvent, FlowAgentLedgerEventType, FlowAgentLease, FlowAgentMaps } from '../../types/flowAgent';\nimport { isRecordInRun, resolveRecordRunId } from '../flowEngine/runs';\nimport { createIntentHash, stableStringify } from './utils';\nimport { getExistingYMap } from '../yjsTypes';\n\nexport const FLOW_AGENT_OUTBOX_KEY = 'agentOutbox';\nexport const FLOW_AGENT_LEASES_KEY = 'agentLeases';\nexport const FLOW_AGENT_AUDIT_SCOPE = '__flow_agent__';\n\nfunction readExistingMap<T>(yDoc: Doc, key: string): Y.Map<T> | undefined {\n return getExistingYMap<T>(yDoc, key);\n}\n\nexport function getFlowAgentMaps(yDoc: Doc): FlowAgentMaps {\n return {\n outbox: yDoc.getMap<FlowAgentCommand>(FLOW_AGENT_OUTBOX_KEY),\n leases: yDoc.getMap(FLOW_AGENT_LEASES_KEY),\n };\n}\n\nexport function computeAgentCommandId(params: { flowId: string; sessionRunId: string; nodeId: string; type: string; payload: Record<string, unknown> }): string {\n const intentHash = createIntentHash(params);\n return `${params.flowId}:${params.nodeId}:${intentHash}`;\n}\n\nexport function queueAgentCommand(yDoc: Doc, command: FlowAgentCommand): { command: FlowAgentCommand; created: boolean } {\n const { outbox } = getFlowAgentMaps(yDoc);\n const existing = outbox.get(command.id);\n if (existing) {\n const retryFailedAssignment = existing.type === 'assign_actor' && existing.status === 'failed';\n const retryFailedDiagnosis = existing.type === 'diagnose_blocker' && existing.status === 'failed';\n const retryUnprovenDiagnosis = existing.type === 'diagnose_blocker' && existing.status === 'confirmed' && typeof existing.payload.delegatedInvocationId !== 'string';\n if (retryFailedAssignment || retryFailedDiagnosis || retryUnprovenDiagnosis) {\n const retried: FlowAgentCommand = {\n ...existing,\n status: 'queued',\n error: undefined,\n lease: undefined,\n reason: command.reason,\n payload: command.payload,\n capability: command.capability,\n actorDid: command.actorDid,\n updatedAt: command.updatedAt,\n };\n outbox.set(command.id, retried);\n try {\n appendAgentLedgerEvent(yDoc, {\n type: 'agent.command',\n flowId: retried.flowId,\n sessionRunId: retried.sessionRunId,\n nodeId: retried.nodeId,\n commandId: retried.id,\n actorDid: retried.actorDid,\n timestamp: retried.updatedAt,\n details: {\n commandType: retried.type,\n status: retried.status,\n idempotencyKey: retried.idempotencyKey,\n reason: retried.reason,\n retry: true,\n retryCause: retryFailedDiagnosis ? 'diagnosis_failed' : retryUnprovenDiagnosis ? 'missing_delegated_invocation' : 'assignment_failed',\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to append flow-agent ledger event';\n if (!message.includes('Unexpected content type') && !message.includes('already been defined with a different constructor')) {\n throw error;\n }\n }\n return { command: retried, created: true };\n }\n return { command: existing, created: false };\n }\n outbox.set(command.id, command);\n try {\n appendAgentLedgerEvent(yDoc, {\n type: 'agent.command',\n flowId: command.flowId,\n sessionRunId: command.sessionRunId,\n nodeId: command.nodeId,\n commandId: command.id,\n actorDid: command.actorDid,\n timestamp: command.createdAt,\n details: {\n commandType: command.type,\n status: command.status,\n idempotencyKey: command.idempotencyKey,\n reason: command.reason,\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to append flow-agent ledger event';\n if (!message.includes('Unexpected content type') && !message.includes('already been defined with a different constructor')) {\n throw error;\n }\n }\n return { command, created: true };\n}\n\nfunction belongsToSessionRun(value: { sessionRunId?: string }, sessionRunId?: string): boolean {\n return !sessionRunId || isRecordInRun(value.sessionRunId, sessionRunId);\n}\n\n/** Read every command for one session without creating the outbox map. */\nexport function readAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[] {\n const outbox = readExistingMap<FlowAgentCommand>(yDoc, FLOW_AGENT_OUTBOX_KEY);\n if (!outbox) return [];\n const commands: FlowAgentCommand[] = [];\n outbox.forEach((command) => {\n if (belongsToSessionRun(command, sessionRunId)) {\n commands.push({\n ...command,\n sessionRunId: resolveRecordRunId(command.sessionRunId, sessionRunId),\n });\n }\n });\n commands.sort(\n (a, b) =>\n (a.createdAt ?? 0) - (b.createdAt ?? 0) ||\n (a.id ?? (a as FlowAgentCommand & { commandId?: string }).commandId ?? '').localeCompare(b.id ?? (b as FlowAgentCommand & { commandId?: string }).commandId ?? '')\n );\n return commands;\n}\n\nexport function readQueuedAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[] {\n return readAgentCommands(yDoc, sessionRunId).filter((command) => command.status === 'queued' || command.status === 'leased' || command.status === 'running');\n}\n\n/** Read every lease for one session without creating the leases map. */\nexport function readFlowAgentLeases(yDoc: Doc, sessionRunId?: string): FlowAgentLease[] {\n const leases = readExistingMap<FlowAgentLease>(yDoc, FLOW_AGENT_LEASES_KEY);\n if (!leases) return [];\n const results: FlowAgentLease[] = [];\n leases.forEach((lease) => {\n if (belongsToSessionRun(lease, sessionRunId)) {\n results.push({\n ...lease,\n sessionRunId: resolveRecordRunId(lease.sessionRunId, sessionRunId),\n });\n }\n });\n results.sort((a, b) => (a.acquiredAt ?? 0) - (b.acquiredAt ?? 0) || (a.id ?? a.commandId ?? '').localeCompare(b.id ?? b.commandId ?? ''));\n return results;\n}\n\nexport function updateAgentCommand(yDoc: Doc, commandId: string, patch: Partial<FlowAgentCommand>): FlowAgentCommand | null {\n const { outbox } = getFlowAgentMaps(yDoc);\n const current = outbox.get(commandId);\n if (!current) return null;\n const next = { ...current, ...patch };\n outbox.set(commandId, next);\n return next;\n}\n\nexport function appendAgentLedgerEvent(\n yDoc: Doc,\n event: Omit<FlowAgentLedgerEvent, 'id'> & {\n id?: string;\n }\n): FlowAgentLedgerEvent {\n const auditMap = yDoc.getMap<Y.Array<unknown>>('auditTrail');\n let arr = auditMap.get(FLOW_AGENT_AUDIT_SCOPE);\n if (!arr) {\n arr = new Y.Array<unknown>();\n auditMap.set(FLOW_AGENT_AUDIT_SCOPE, arr);\n }\n\n const fullEvent: FlowAgentLedgerEvent = {\n id: event.id || `${event.type}:${event.commandId || event.nodeId || 'flow'}:${createIntentHash(event.details)}:${event.timestamp}`,\n type: event.type,\n flowId: event.flowId,\n sessionRunId: event.sessionRunId,\n actorDid: event.actorDid,\n timestamp: event.timestamp,\n details: JSON.parse(stableStringify(event.details)) as Record<string, unknown>,\n };\n\n if (event.nodeId) fullEvent.nodeId = event.nodeId;\n if (event.commandId) fullEvent.commandId = event.commandId;\n\n arr.push([\n {\n id: fullEvent.id,\n type: fullEvent.type,\n details: fullEvent,\n meta: {\n timestamp: new Date(fullEvent.timestamp).toISOString(),\n userId: fullEvent.actorDid,\n editable: false,\n },\n },\n ]);\n\n return fullEvent;\n}\n\nexport function readAgentLedgerEvents(yDoc: Doc, eventType?: FlowAgentLedgerEventType, sessionRunId?: string): FlowAgentLedgerEvent[] {\n const auditMap = readExistingMap<Y.Array<unknown>>(yDoc, 'auditTrail');\n if (!auditMap) return [];\n const arr = auditMap.get(FLOW_AGENT_AUDIT_SCOPE);\n if (!arr) return [];\n const events: FlowAgentLedgerEvent[] = [];\n arr.forEach((value) => {\n if (!value || typeof value !== 'object') return;\n const entry = value as { type?: string; details?: FlowAgentLedgerEvent };\n if (!entry.details) return;\n if (eventType && entry.details.type !== eventType) return;\n if (sessionRunId && !isRecordInRun(entry.details.sessionRunId, sessionRunId)) {\n return;\n }\n events.push({\n ...entry.details,\n sessionRunId: resolveRecordRunId(entry.details.sessionRunId, sessionRunId),\n });\n });\n events.sort((a, b) => a.timestamp - b.timestamp || a.id.localeCompare(b.id));\n return events;\n}\n","import type { Block } from '@blocknote/core';\nimport type { UcanCapability } from '../../types/ucan';\n\nexport function stableStringify(value: unknown): string {\n if (value === undefined) return 'null';\n if (value === null || typeof value !== 'object') {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item)).join(',')}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b));\n return `{${entries.map(([key, val]) => `${JSON.stringify(key)}:${stableStringify(val)}`).join(',')}}`;\n}\n\nexport function fnv1a32(input: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nexport function createIntentHash(intent: Record<string, unknown>): string {\n return fnv1a32(stableStringify(intent));\n}\n\nexport function parseJsonProp<T>(value: unknown, fallback: T): T {\n if (value == null || value === '') return fallback;\n if (typeof value === 'object') return value as T;\n if (typeof value !== 'string') return fallback;\n try {\n const parsed = JSON.parse(value);\n return parsed as T;\n } catch {\n return fallback;\n }\n}\n\nexport function getBlockActionType(block: unknown): string | undefined {\n const props = (block as { props?: Record<string, unknown> })?.props;\n const actionType = props?.actionType;\n return typeof actionType === 'string' && actionType.length > 0 ? actionType : undefined;\n}\n\nexport function getBlockTitle(block: unknown): string | undefined {\n const props = (block as { props?: Record<string, unknown> })?.props;\n const title = props?.title;\n return typeof title === 'string' && title.length > 0 ? title : undefined;\n}\n\nexport function getBlockType(block: unknown): string {\n const type = (block as { type?: string })?.type;\n return typeof type === 'string' && type.length > 0 ? type : 'block';\n}\n\nexport function getBlockProps(block: unknown): Record<string, unknown> {\n return ((block as { props?: Record<string, unknown> })?.props || {}) as Record<string, unknown>;\n}\n\nexport function getBlockId(block: unknown): string | undefined {\n const id = (block as { id?: string })?.id;\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n}\n\nexport function getAssigneeDid(block: unknown): string | undefined {\n const props = getBlockProps(block);\n const assignment = parseJsonProp<Record<string, any>>(props.assignment, {});\n const did = assignment?.assignedActor?.did;\n return typeof did === 'string' && did.length > 0 ? did : undefined;\n}\n\nexport function getDueAt(block: unknown): number | undefined {\n const props = getBlockProps(block);\n const ttlAbsoluteDueDate = props.ttlAbsoluteDueDate;\n if (typeof ttlAbsoluteDueDate !== 'string' || ttlAbsoluteDueDate.length === 0) return undefined;\n const parsed = new Date(ttlAbsoluteDueDate).getTime();\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nexport function normalizeBlocks(blocks: unknown[]): Block[] {\n return blocks.filter((block) => typeof getBlockId(block) === 'string') as Block[];\n}\n\nexport function capabilityForCommand(can: string, flowUri: string, nodeId: string): UcanCapability {\n return {\n can,\n with: `${flowUri}:${nodeId}`,\n };\n}\n","import * as Y from 'yjs';\nimport type { StoredInvocation } from '../../types/ucan';\nimport { getExistingYMap } from '../yjsTypes';\nimport { FLOW_AGENT_AUDIT_SCOPE, FLOW_AGENT_LEASES_KEY, FLOW_AGENT_OUTBOX_KEY } from '../flowAgent/store';\nimport { INVOCATIONS_MAP_KEY } from './runHistory';\nimport { RUN_RECORD_AUDIT_TYPE } from './triggers';\n\n/**\n * # Migrating a pre-session document\n *\n * Everything here exists to answer one question about records written before\n * sessions existed: **which session owns them?**\n *\n * The old answer was a hard-coded constant every repo agreed to read as \"the\n * legacy run\" (`sessionRunId ?? LEGACY_RUN_ID`). That put a document-shaped\n * fact in a string literal, so ownership was re-derived, identically and by\n * hand, in a dozen places across three repositories — and a record's owner\n * changed meaning if any one of them disagreed.\n *\n * Migration answers it once, in the data: every untagged record is stamped with\n * the id of the session that absorbs the document's history. Afterwards nothing\n * infers ownership, and no constant needs to survive.\n *\n * This is the only module that rewrites history, which is why it is separate\n * from the waist: `runs.ts` owns *action state*, and nothing there should learn\n * the shape of an agent lease or an invocation.\n */\n\n/** One counter per container touched, so a migration can report what it moved. */\nexport interface StampedRecordCounts {\n commands: number;\n leases: number;\n ledgerEvents: number;\n invocations: number;\n runRecords: number;\n}\n\nfunction stampMapValues(yDoc: Y.Doc, key: string, sessionRunId: string): number {\n const map = getExistingYMap<{ sessionRunId?: string }>(yDoc, key);\n if (!map) return 0;\n let stamped = 0;\n map.forEach((value, entryKey) => {\n if (!value || typeof value !== 'object' || value.sessionRunId) return;\n map.set(entryKey, { ...value, sessionRunId });\n stamped += 1;\n });\n return stamped;\n}\n\n/**\n * Stamp entries of one `auditTrail` scope in place.\n *\n * `Y.Array` has no positional set, so an entry is replaced by a delete plus an\n * insert at the same index. Iterating by index and rewriting as we go is safe\n * because the length never changes; doing it inside the caller's transaction\n * keeps the whole migration one atomic update.\n */\nfunction stampAuditEntries(yDoc: Y.Doc, scope: string, sessionRunId: string, matches: (entry: { type?: string; details?: { sessionRunId?: string } }) => boolean): number {\n const auditMap = getExistingYMap<Y.Array<unknown>>(yDoc, 'auditTrail');\n const arr = auditMap?.get(scope);\n if (!arr) return 0;\n let stamped = 0;\n for (let index = 0; index < arr.length; index += 1) {\n const value = arr.get(index);\n if (!value || typeof value !== 'object') continue;\n const entry = value as { type?: string; details?: { sessionRunId?: string } };\n if (!entry.details || entry.details.sessionRunId || !matches(entry)) continue;\n arr.delete(index, 1);\n arr.insert(index, [{ ...entry, details: { ...entry.details, sessionRunId } }]);\n stamped += 1;\n }\n return stamped;\n}\n\n/**\n * Give every pre-session record an explicit owner.\n *\n * Idempotent: a record that already carries a `sessionRunId` is never rewritten,\n * so re-running this changes nothing and reports zero.\n *\n * Runs inside the migration's transaction — callers must not invoke it on its\n * own, or a failure later in the migration would leave records pointing at a\n * session that does not exist.\n */\nexport function stampPreSessionRecords(yDoc: Y.Doc, sessionRunId: string): StampedRecordCounts {\n const auditScopes = getExistingYMap<Y.Array<unknown>>(yDoc, 'auditTrail');\n let runRecords = 0;\n auditScopes?.forEach((_, scope) => {\n if (scope === FLOW_AGENT_AUDIT_SCOPE) return;\n runRecords += stampAuditEntries(yDoc, scope, sessionRunId, (entry) => entry.type === RUN_RECORD_AUDIT_TYPE);\n });\n\n return {\n commands: stampMapValues(yDoc, FLOW_AGENT_OUTBOX_KEY, sessionRunId),\n leases: stampMapValues(yDoc, FLOW_AGENT_LEASES_KEY, sessionRunId),\n ledgerEvents: stampAuditEntries(yDoc, FLOW_AGENT_AUDIT_SCOPE, sessionRunId, () => true),\n invocations: stampInvocations(yDoc, sessionRunId),\n runRecords,\n };\n}\n\nfunction stampInvocations(yDoc: Y.Doc, sessionRunId: string): number {\n const map = getExistingYMap<StoredInvocation>(yDoc, INVOCATIONS_MAP_KEY);\n if (!map) return 0;\n let stamped = 0;\n map.forEach((value, cid) => {\n if (!value || typeof value !== 'object' || value.sessionRunId) return;\n map.set(cid, { ...value, sessionRunId });\n stamped += 1;\n });\n return stamped;\n}\n\n/**\n * When the document's history began, derived rather than observed.\n *\n * The earliest execution the flat runtime map records, falling back to the\n * document's creation time and finally to zero. Never `Date.now()`: the value\n * is written into run metadata, and a wall-clock reading would make two clients\n * migrating the same document disagree about what they migrated.\n */\nexport function deriveMigratedStartedAt(yDoc: Y.Doc): number {\n let earliest: number | undefined;\n getExistingYMap<{ executedAt?: unknown }>(yDoc, 'runtime')?.forEach((value) => {\n if (!value || typeof value !== 'object') return;\n const executedAt = value.executedAt;\n if (typeof executedAt !== 'number' || !Number.isFinite(executedAt)) return;\n if (earliest === undefined || executedAt < earliest) earliest = executedAt;\n });\n if (earliest !== undefined) return earliest;\n\n const createdAt = getExistingYMap(yDoc, 'root')?.get('createdAt');\n if (typeof createdAt === 'number' && Number.isFinite(createdAt)) return createdAt;\n if (typeof createdAt === 'string') {\n const parsed = Date.parse(createdAt);\n if (!Number.isNaN(parsed)) return parsed;\n }\n return 0;\n}\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\nfunction fnv1a(input: string): number {\n let hash = 0x811c9dc5;\n for (let index = 0; index < input.length; index += 1) {\n hash ^= input.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n return hash >>> 0;\n}\n\nfunction encodeCrockford(value: number, length: number): string {\n let remaining = value;\n let encoded = '';\n for (let index = 0; index < length; index += 1) {\n encoded = CROCKFORD[remaining % 32] + encoded;\n remaining = Math.floor(remaining / 32);\n }\n return encoded;\n}\n\n/**\n * The id of the session a migration creates — **derived, not random.**\n *\n * `createRunId` appends a random ULID, which is right for `startRun`: starting a\n * session is a single writer acting once. Migration is not: two clients opening\n * the same legacy flow and both pressing Migrate would mint two ids and split\n * one history into two sessions, each holding half the answer.\n *\n * Deriving the suffix from document-stable inputs makes concurrent migrations\n * converge on the same container instead, which is the property the old fixed\n * `r-0000-legacy` id provided for free.\n */\nexport function deriveMigratedRunId(params: { docId: string; defHash: string; startedAt: number }): string {\n const seed = `${params.docId}\u0000${params.defHash}\u0000${params.startedAt}`;\n return `r-0001-${encodeCrockford(fnv1a(seed), 8)}${encodeCrockford(fnv1a(`${seed}\u0000salt`), 8)}`;\n}\n","import type * as Y from 'yjs';\nimport { getAction } from '../actionRegistry';\nimport type { ActionRunContext } from '../actionRegistry';\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport type { StoredInvocation, UcanCapability } from '../../types/ucan';\nimport { isActionDone } from './completion';\nimport {\n collectPhantomLegacyRun,\n ensureRun,\n getExistingRunsMap,\n getExistingRunsTerminalPendingMap,\n getExistingRunsTerminalMap,\n getRunMeta,\n getRunsTerminalPendingMap,\n getRunsTerminalMap,\n isBelowTheLineBlock,\n readActionState,\n resetActionState,\n seedRunFromLegacyRuntime,\n setMultiRunStorage,\n usesLegacyRuntimeCompatibility,\n type MultiRunMigrationResult,\n type RunMeta,\n type RunTerminalRecord,\n type RunTerminalReservation,\n} from './runs';\nimport { deriveMigratedRunId, deriveMigratedStartedAt, stampPreSessionRecords, type StampedRecordCounts } from './runMigration';\nimport { dispatchFlowStartTriggers } from './reconcile';\nimport { createRunEventIdempotencyKey } from './runTimeline';\nimport { isTempUcanEnforcementDisabled } from './versionManifest';\nimport { getExistingYMap } from '../yjsTypes';\nimport type { DesignPodInvocationVerifier } from '../designPod/compiler';\nimport { digestDesignPodValue } from '../designPod/digest';\nimport type { RunTerminalAuthorizationProof } from './terminalAuthorization';\nimport { assertLegacyFlowOperationAllowed, type FlowProtocolGateV1 } from './vnext/legacy';\n\nexport type { RunTerminalAuthorizationProof } from './terminalAuthorization';\n\nexport type RunJsonValue = null | string | number | boolean | RunJsonObject | RunJsonValue[];\nexport interface RunJsonObject {\n [key: string]: RunJsonValue;\n}\n\nexport type LifecycleRunEventInput =\n | {\n runId: string;\n kind: 'run.started';\n payload: { invocationCid?: string; definitionRevision?: string; label?: string };\n idempotencyKey: string;\n ts?: number;\n blockId?: never;\n }\n | {\n runId: string;\n kind: 'run.closed';\n payload: { invocationCid?: string; actorDid?: string; summary?: RunJsonObject; authorization?: RunJsonObject };\n idempotencyKey: string;\n ts?: number;\n blockId?: never;\n }\n | {\n runId: string;\n kind: 'run.cancelled';\n payload: { invocationCid?: string; actorDid?: string; reason?: string; summary?: RunJsonObject; authorization?: RunJsonObject };\n idempotencyKey: string;\n ts?: number;\n blockId?: never;\n }\n | {\n runId: string;\n kind: 'definition.changed';\n payload: { revision: string; previousRevision?: string; changedBlockIds?: string[]; summary?: string };\n idempotencyKey: string;\n ts?: number;\n blockId?: never;\n };\n\nexport type ActionRunEventInput =\n | {\n runId: string;\n blockId: string;\n kind: 'action.started';\n payload: { attempt: number; executionId?: string; invocationCid?: string; input?: RunJsonValue };\n idempotencyKey: string;\n ts?: number;\n }\n | {\n runId: string;\n blockId: string;\n kind: 'action.output';\n payload: { attempt: number; executionId?: string; output: RunJsonValue };\n idempotencyKey: string;\n ts?: number;\n }\n | {\n runId: string;\n blockId: string;\n kind: 'action.done';\n payload: { attempt: number; executionId?: string; durationMs?: number; output?: RunJsonValue };\n idempotencyKey: string;\n ts?: number;\n }\n | {\n runId: string;\n blockId: string;\n kind: 'action.failed';\n payload: {\n attempt: number;\n executionId?: string;\n durationMs?: number;\n error: { message: string; name?: string; code?: string; retryable?: boolean; details?: RunJsonValue };\n };\n idempotencyKey: string;\n ts?: number;\n };\n\nexport type RunLogEventInput = {\n runId: string;\n blockId?: string;\n kind: 'log';\n payload: { level: 'debug' | 'info' | 'warn' | 'error'; message: string; data?: RunJsonValue };\n idempotencyKey: string;\n ts?: number;\n};\n\nexport type RunEventInput = LifecycleRunEventInput | ActionRunEventInput | RunLogEventInput;\n\n/** Assignment-compatible with matrix-crdt's IRoomEventLog. */\nexport interface RunEventAppender {\n append(event: RunEventInput): Promise<string>;\n /**\n * Matrix-backed implementations expose ordered readback. Governed actions\n * use this to select the first server-persisted claim across disconnected\n * Portal clients before an irreversible side effect.\n */\n read?(\n runId: string,\n options: { direction: 'forward' | 'backward'; limit: number; from?: string }\n ): Promise<{\n events: Array<{ eventId: string; originServerTs: number; content: RunEventInput }>;\n nextToken?: string;\n }>;\n}\n\nexport type RunLifecycleCapability = 'flow/run.start' | 'flow/run.close';\n\nexport interface RunLifecycleAuthorizationRequest {\n can: RunLifecycleCapability;\n with: string;\n actorDid: string;\n runId?: string;\n}\n\nexport interface RunLifecycleAuthorizationDecision {\n allowed: boolean;\n reason?: string;\n invocationCid?: string;\n}\n\nexport type RunLifecycleAuthorizer = (request: RunLifecycleAuthorizationRequest) => Promise<RunLifecycleAuthorizationDecision> | RunLifecycleAuthorizationDecision;\n\nexport interface RunManifest {\n blockIds: string[];\n defHash: string;\n}\n\nexport interface RunDefinitionBlock {\n id?: string;\n type?: string;\n props?: Record<string, unknown>;\n children?: RunDefinitionBlock[];\n}\n\nexport interface RunDefinitionSnapshot {\n manifest: RunManifest;\n actionTypes: Record<string, string>;\n}\n\nexport interface RunSnapshot {\n id: string;\n meta: RunMeta;\n terminal?: RunTerminalRecord;\n}\n\nexport class RunLifecycleAuthorizationError extends Error {\n constructor(\n public readonly capability: RunLifecycleCapability,\n message: string\n ) {\n super(message);\n this.name = 'RunLifecycleAuthorizationError';\n }\n}\n\nexport class RunNotReadyError extends Error {\n constructor(public readonly incompleteBlockIds: string[]) {\n super(`Run cannot close while manifest actions remain incomplete: ${incompleteBlockIds.join(', ')}`);\n this.name = 'RunNotReadyError';\n }\n}\n\n/**\n * The flow predates sessions and has not been migrated, so it has no session to\n * act on. Thrown by `startRun` rather than quietly migrating on the caller's\n * behalf: migration is one-way and changes how every client reads the document,\n * which is a decision for an actor, not a side effect of pressing Start.\n */\nexport class FlowNotMigratedError extends Error {\n constructor(public readonly flowUri: string) {\n super('This flow predates sessions. Migrate it to enable them.');\n this.name = 'FlowNotMigratedError';\n }\n}\n\n/**\n * The run exists but has no frozen manifest, so there is no definition to judge\n * completeness against.\n *\n * Reaching this means the run was created by something other than `startRun` or\n * `migrateFlowToSessions` — in practice a container left behind by a build that\n * created one on connect. Computing a summary against the *live* document\n * instead would let an unstarted flow report work as belonging to a session\n * nobody opened.\n */\nexport class RunNotMigratedError extends Error {\n constructor(public readonly runId: string) {\n super(`Run \"${runId}\" has no frozen manifest, so it is not a session.`);\n this.name = 'RunNotMigratedError';\n }\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(canonicalize);\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n const nested = (value as Record<string, unknown>)[key];\n if (nested !== undefined && typeof nested !== 'function') result[key] = canonicalize(nested);\n }\n return result;\n}\n\nfunction fnv1a32(input: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < input.length; i += 1) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nexport function computeRunDefinitionHash(definition: unknown): string {\n return `def-${fnv1a32(JSON.stringify(canonicalize(definition)))}`;\n}\n\n/** Convert arbitrary action data into Matrix-event-safe JSON. */\nexport function toRunJsonValue(value: unknown): RunJsonValue {\n if (value === undefined) return null;\n try {\n return JSON.parse(JSON.stringify(value)) as RunJsonValue;\n } catch {\n return String(value);\n }\n}\n\nfunction walkBlocks(blocks: RunDefinitionBlock[], visit: (block: RunDefinitionBlock) => void): void {\n for (const block of blocks) {\n visit(block);\n if (Array.isArray(block.children)) walkBlocks(block.children, visit);\n }\n}\n\nexport function buildRunDefinitionSnapshot(blocks: RunDefinitionBlock[], definition: unknown = blocks): RunDefinitionSnapshot {\n const blockIds: string[] = [];\n const actionTypes: Record<string, string> = {};\n walkBlocks(blocks, (block) => {\n const actionType = block.props?.actionType;\n if (!block.id || typeof actionType !== 'string' || isBelowTheLineBlock(block) || actionType === 'qi/flow.run.start' || actionType === 'qi/flow.run.close') {\n return;\n }\n blockIds.push(block.id);\n actionTypes[block.id] = actionType;\n });\n return {\n manifest: {\n blockIds,\n defHash: computeRunDefinitionHash(definition),\n },\n actionTypes,\n };\n}\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\nfunction encodeTime(timestamp: number): string {\n let value = Math.max(0, Math.floor(timestamp));\n let encoded = '';\n for (let i = 0; i < 10; i += 1) {\n encoded = CROCKFORD[value % 32] + encoded;\n value = Math.floor(value / 32);\n }\n return encoded;\n}\n\nfunction randomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n const cryptoApi = (globalThis as { crypto?: { getRandomValues?: (target: Uint8Array) => Uint8Array } }).crypto;\n if (cryptoApi?.getRandomValues) return cryptoApi.getRandomValues(bytes);\n for (let i = 0; i < length; i += 1) bytes[i] = Math.floor(Math.random() * 256);\n return bytes;\n}\n\nexport function createRunUlid(timestamp = Date.now()): string {\n const bytes = randomBytes(16);\n let randomPart = '';\n for (let i = 0; i < 16; i += 1) randomPart += CROCKFORD[bytes[i] & 31];\n return `${encodeTime(timestamp)}${randomPart}`;\n}\n\nfunction nextRunSequence(yDoc: Y.Doc): number {\n let max = 0;\n getExistingRunsMap(yDoc)?.forEach((_, runId) => {\n max = Math.max(max, getRunMeta(yDoc, runId)?.seq || 0);\n });\n return max + 1;\n}\n\nexport function createRunId(seq: number, timestamp = Date.now()): string {\n return `r-${String(seq).padStart(4, '0')}-${createRunUlid(timestamp)}`;\n}\n\nexport function listRuns(yDoc: Y.Doc): RunSnapshot[] {\n const terminal = getExistingRunsTerminalMap(yDoc);\n const runs: RunSnapshot[] = [];\n getExistingRunsMap(yDoc)?.forEach((_, id) => {\n const meta = getRunMeta(yDoc, id);\n if (!meta) return;\n const terminalRecord = terminal?.get(id);\n runs.push({\n id,\n meta: { ...meta, manifest: meta.manifest ? { ...meta.manifest, blockIds: [...meta.manifest.blockIds] } : undefined },\n terminal: terminalRecord ? { ...terminalRecord, summary: terminalRecord.summary ? { ...terminalRecord.summary } : undefined } : undefined,\n });\n });\n return runs.sort((a, b) => b.meta.seq - a.meta.seq || b.meta.startedAt - a.meta.startedAt || b.id.localeCompare(a.id));\n}\n\nexport function listOpenRuns(yDoc: Y.Doc): RunSnapshot[] {\n return listRuns(yDoc).filter((run) => !run.terminal);\n}\n\nexport function setAdvisoryActiveRunId(yDoc: Y.Doc, runId: string): void {\n if (!getExistingRunsMap(yDoc)?.has(runId)) throw new Error(`Unknown run \"${runId}\"`);\n yDoc.getMap('root').set('activeRunId', runId);\n}\n\nasync function requireAuthorization(authorize: RunLifecycleAuthorizer, request: RunLifecycleAuthorizationRequest): Promise<RunLifecycleAuthorizationDecision> {\n // TEMPORARY — the same kill switch that disables UCAN enforcement for block\n // execution (`versionManifest.ts#isTempUcanEnforcementDisabled`). While it is\n // on, starting, migrating, closing and cancelling a session are ungated.\n //\n // The authorizer is **not called at all**, rather than called and ignored: a\n // consumer's authorizer may itself throw (the Portal's reads room state), and\n // \"the gate is off\" must not depend on the gate being reachable.\n //\n // Only the permission check goes. Everything that makes a lifecycle\n // transition correct still runs — the timeline is appended before the\n // document changes, the close fold still demands every manifest action be\n // done, and terminal state is still write-once — so restoring enforcement is\n // a one-line change with nothing to reconstruct.\n if (isTempUcanEnforcementDisabled()) {\n return { allowed: true };\n }\n const decision = await authorize(request);\n if (!decision.allowed) {\n throw new RunLifecycleAuthorizationError(request.can, decision.reason || `${request.actorDid} is not authorized for ${request.can}`);\n }\n return decision;\n}\n\nexport interface StartRunParams {\n yDoc: Y.Doc;\n flowUri: string;\n actorDid: string;\n definition: RunDefinitionSnapshot;\n /** Live block tree used to dispatch authored `trigger: flow.start` actions. */\n document?: RunDefinitionBlock[];\n eventLog: RunEventAppender;\n authorize: RunLifecycleAuthorizer;\n label?: string;\n now?: () => number;\n /** Activating read-only legacy mode freezes this pre-vNext start surface. */\n protocolGate?: FlowProtocolGateV1;\n}\n\nexport interface StartRunResult {\n run: RunSnapshot;\n eventId: string;\n flowStartInvocations: number;\n}\n\nconst lifecycleQueues = new WeakMap<Y.Doc, Map<string, Promise<void>>>();\n\nasync function withLifecycleLock<T>(yDoc: Y.Doc, key: string, operation: () => Promise<T>): Promise<T> {\n let queues = lifecycleQueues.get(yDoc);\n if (!queues) {\n queues = new Map();\n lifecycleQueues.set(yDoc, queues);\n }\n const previous = queues.get(key) || Promise.resolve();\n let release!: () => void;\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n const current = previous.then(() => gate);\n queues.set(key, current);\n await previous;\n try {\n return await operation();\n } finally {\n release();\n if (queues.get(key) === current) queues.delete(key);\n }\n}\n\nexport async function startRun(params: StartRunParams): Promise<StartRunResult> {\n return withLifecycleLock(params.yDoc, '__start__', async () => {\n assertLegacyFlowOperationAllowed(params.protocolGate, 'run.start');\n // A version 1 document still reads and writes the flat runtime map, so a\n // session started on it would be a second, partial view of the same state.\n // Migration is the only way across, and it is an actor's decision.\n if (usesLegacyRuntimeCompatibility(params.yDoc)) {\n throw new FlowNotMigratedError(params.flowUri);\n }\n const authorization = await requireAuthorization(params.authorize, {\n can: 'flow/run.start',\n with: params.flowUri,\n actorDid: params.actorDid,\n });\n const now = params.now?.() ?? Date.now();\n const seq = nextRunSequence(params.yDoc);\n const runId = createRunId(seq, now);\n const meta: RunMeta = {\n seq,\n startedAt: now,\n startedByDid: params.actorDid,\n origin: 'started',\n ...(params.label ? { label: params.label } : {}),\n manifest: {\n blockIds: [...params.definition.manifest.blockIds],\n defHash: params.definition.manifest.defHash,\n },\n };\n\n // Timeline first: a transient Matrix failure must leave the document\n // completely unchanged, including its storage-version latch.\n const eventId = await params.eventLog.append({\n runId,\n kind: 'run.started',\n payload: {\n ...(authorization.invocationCid ? { invocationCid: authorization.invocationCid } : {}),\n definitionRevision: params.definition.manifest.defHash,\n ...(params.label ? { label: params.label } : {}),\n },\n idempotencyKey: createRunEventIdempotencyKey('run.started', runId),\n ts: now,\n });\n\n let flowStartInvocations = 0;\n params.yDoc.transact(() => {\n // A document with a session is session-based, permanently. Without this\n // the format would stay *inferred* from the absence of flat history, and\n // one stray write from a not-yet-upgraded client — which still dual-writes\n // the flat map — would flip the document back to version 1 underneath a\n // session that is already open.\n setMultiRunStorage(params.yDoc);\n ensureRun(params.yDoc, runId, meta);\n for (const blockId of meta.manifest!.blockIds) {\n resetActionState(params.yDoc, runId, blockId, { state: 'idle' });\n }\n if (params.document) {\n flowStartInvocations = dispatchFlowStartTriggers({\n yDoc: params.yDoc,\n runId,\n blocks: params.document,\n startedAt: now,\n sourceEventId: eventId,\n });\n }\n params.yDoc.getMap('root').set('activeRunId', runId);\n });\n\n return {\n run: { id: runId, meta },\n eventId,\n flowStartInvocations,\n };\n });\n}\n\nexport interface MigrateFlowParams {\n yDoc: Y.Doc;\n flowUri: string;\n actorDid: string;\n /** Frozen into the migrated session, exactly as `startRun` freezes its own. */\n definition: RunDefinitionSnapshot;\n eventLog: RunEventAppender;\n authorize: RunLifecycleAuthorizer;\n label?: string;\n}\n\nexport interface MigrateFlowResult {\n /** The session that now owns the document's history, or `undefined` when\n * there was no history to carry and the document was simply latched. */\n run?: RunSnapshot;\n eventId?: string;\n seeded: MultiRunMigrationResult;\n stamped?: StampedRecordCounts;\n phantomCollected: boolean;\n alreadyMigrated: boolean;\n}\n\n/**\n * Turn a pre-session document into a session-based one, **one way**.\n *\n * What already happened in the flow becomes its first session: an ordinary open\n * run carrying the same action states, pending invocations and partial barriers,\n * closable and tickable like any other. A document with no history has nothing\n * to carry, so it is simply latched and the actor starts session 1 normally.\n *\n * ## Order matters\n *\n * The timeline event is appended **before** anything is written to the document,\n * exactly as `startRun` does it: a transient Matrix failure must leave the\n * document completely unchanged rather than latched onto a layout whose history\n * nobody can see. Everything after it is one transaction, so a document is\n * never observed half-migrated — history seeded but unlatched, or latched with\n * records still pointing nowhere.\n *\n * Idempotent. A second call sees the latch and returns `alreadyMigrated`.\n */\nexport async function migrateFlowToSessions(params: MigrateFlowParams): Promise<MigrateFlowResult> {\n return withLifecycleLock(params.yDoc, '__start__', async () => {\n const empty: MultiRunMigrationResult = { actionStates: 0, pendingInvocations: 0, barrierEntries: 0 };\n // Sessions are the default, so \"legacy\" now means the document genuinely\n // carries pre-session history. A document without it is already\n // session-based and has nothing to migrate — including every flow created\n // by copying a template, which used to land in the branch below and be\n // latched by a migration that moved no state.\n if (!usesLegacyRuntimeCompatibility(params.yDoc)) {\n return { seeded: empty, phantomCollected: false, alreadyMigrated: true };\n }\n\n const authorization = await requireAuthorization(params.authorize, {\n can: 'flow/run.start',\n with: params.flowUri,\n actorDid: params.actorDid,\n });\n\n const startedAt = deriveMigratedStartedAt(params.yDoc);\n const runId = deriveMigratedRunId({\n docId: String(params.yDoc.getMap('root').get('doc_id') || params.flowUri),\n defHash: params.definition.manifest.defHash,\n startedAt,\n });\n const meta: RunMeta = {\n seq: 1,\n startedAt,\n startedByDid: params.actorDid,\n origin: 'migrated',\n label: params.label || 'Session 1 (migrated)',\n manifest: {\n blockIds: [...params.definition.manifest.blockIds],\n defHash: params.definition.manifest.defHash,\n },\n };\n\n const eventId = await params.eventLog.append({\n runId,\n kind: 'run.started',\n payload: {\n ...(authorization.invocationCid ? { invocationCid: authorization.invocationCid } : {}),\n definitionRevision: params.definition.manifest.defHash,\n label: meta.label,\n },\n idempotencyKey: createRunEventIdempotencyKey('run.started', runId),\n ts: startedAt,\n });\n\n let seeded = empty;\n let stamped: StampedRecordCounts | undefined;\n let phantomCollected = false;\n params.yDoc.transact(() => {\n // Before the run is created, so the collector cannot mistake the new\n // session for the phantom it is looking for.\n phantomCollected = collectPhantomLegacyRun(params.yDoc);\n ensureRun(params.yDoc, runId, meta);\n seeded = seedRunFromLegacyRuntime(params.yDoc, runId);\n stamped = stampPreSessionRecords(params.yDoc, runId);\n // Last: every read switches to the multi-run layout the moment this\n // lands, so nothing above may still be missing.\n setMultiRunStorage(params.yDoc);\n params.yDoc.getMap('root').set('activeRunId', runId);\n });\n\n return {\n run: { id: runId, meta },\n eventId,\n seeded,\n stamped,\n phantomCollected,\n alreadyMigrated: false,\n };\n });\n}\n\nexport function computeRunSummary(yDoc: Y.Doc, runId: string, actionTypes: Record<string, string>, context: Omit<ActionRunContext, 'runId'>): Record<string, boolean> {\n const meta = getRunMeta(yDoc, runId);\n if (!meta?.manifest) throw new RunNotMigratedError(runId);\n const runContext: ActionRunContext = { ...context, runId };\n const summary: Record<string, boolean> = {};\n for (const blockId of meta.manifest.blockIds) {\n summary[blockId] = isActionDone(actionTypes[blockId] ? getAction(actionTypes[blockId]) : undefined, readActionState(yDoc, runId, blockId), runContext);\n }\n return summary;\n}\n\nexport interface CloseRunParams {\n yDoc: Y.Doc;\n flowUri: string;\n runId: string;\n actorDid: string;\n actionTypes: Record<string, string>;\n eventLog: RunEventAppender;\n authorize: RunLifecycleAuthorizer;\n /** Re-authenticate a pinned Design POD publication against its signed invocation and IXO readback. */\n verifyDesignPodPublication?: (request: { yDoc: Y.Doc; runId: string; flowUri: string }) => Promise<{ valid: boolean; error?: string }>;\n /** Signed invocation for this exact close/cancel action. Required for a pinned Design POD. */\n terminalAuthorization?: RunTerminalAuthorizationProof;\n /** Cryptographically verify terminal invocations read from Matrix. Required for a pinned Design POD. */\n verifyTerminalInvocation?: DesignPodInvocationVerifier;\n allowIncomplete?: boolean;\n now?: () => number;\n}\n\nexport interface FinishRunResult {\n terminal: RunTerminalRecord;\n created: boolean;\n eventId?: string;\n}\n\ninterface PinnedDesignPodClosureState {\n pinned: boolean;\n snapshot?: string;\n}\n\nfunction inspectPinnedDesignPodRunForClosure(yDoc: Y.Doc, runId: string): PinnedDesignPodClosureState {\n const designPodDefinition = getExistingYMap(yDoc, 'designPodDefinition');\n const designPodState = getExistingYMap(yDoc, 'designPodState');\n const designPodIdentity = designPodState?.get('identity') as { sessionRunId?: string; [key: string]: unknown } | undefined;\n if (designPodDefinition?.get('manifest') && !designPodIdentity?.sessionRunId) {\n throw new Error('A Design POD session cannot close or cancel before its project identity is pinned');\n }\n const isPinnedDesignPodRun = designPodIdentity?.sessionRunId === runId;\n const designPodRelease = designPodState?.get('release') as { status?: string; digest?: string; [key: string]: unknown } | undefined;\n if (isPinnedDesignPodRun && designPodRelease?.status !== 'published') {\n throw new Error('The pinned Design POD session cannot close until its current independently reviewed release is published');\n }\n if (!isPinnedDesignPodRun) return { pinned: false };\n const releaseDigest = designPodRelease?.digest;\n return {\n pinned: true,\n snapshot: JSON.stringify(\n canonicalize({\n manifest: designPodDefinition?.get('manifest'),\n identity: designPodIdentity,\n release: designPodRelease,\n publication: typeof releaseDigest === 'string' ? designPodState?.get(`publication:${releaseDigest}`) : undefined,\n root: {\n doc_id: getExistingYMap(yDoc, 'root')?.get('doc_id'),\n flowOwnerDid: getExistingYMap(yDoc, 'root')?.get('flowOwnerDid'),\n },\n })\n ),\n };\n}\n\nasync function authenticatePinnedDesignPodClosure(params: CloseRunParams): Promise<PinnedDesignPodClosureState> {\n const captured = inspectPinnedDesignPodRunForClosure(params.yDoc, params.runId);\n if (!captured.pinned) return captured;\n if (!params.verifyDesignPodPublication) {\n throw new Error('The pinned Design POD session requires authenticated publication verification before close or cancel');\n }\n const verification = await params.verifyDesignPodPublication({ yDoc: params.yDoc, runId: params.runId, flowUri: params.flowUri });\n if (!verification.valid) {\n throw new Error(`The pinned Design POD publication could not be authenticated${verification.error ? `: ${verification.error}` : ''}`);\n }\n return captured;\n}\n\nfunction incompleteBlocks(summary: Record<string, boolean>): string[] {\n return Object.entries(summary)\n .filter(([, done]) => !done)\n .map(([blockId]) => blockId);\n}\n\ninterface MatrixTerminalState {\n terminal?: { reservation: RunTerminalReservation; eventId: string };\n}\n\nfunction terminalSummary(value: unknown): Record<string, boolean> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.some(([, done]) => typeof done !== 'boolean')) return undefined;\n return Object.fromEntries(entries) as Record<string, boolean>;\n}\n\nfunction terminalAuthorizationFromEvent(event: { content: RunEventInput }): RunTerminalAuthorizationProof | undefined {\n if (event.content.kind !== 'run.closed' && event.content.kind !== 'run.cancelled') return undefined;\n const value = event.content.payload.authorization;\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const proof = value as Record<string, unknown>;\n const actionInputs = proof.actionInputs;\n const capability = proof.capability;\n if (\n typeof proof.invocationCid !== 'string' ||\n typeof proof.invocation !== 'string' ||\n typeof proof.actorDid !== 'string' ||\n proof.actionType !== 'qi/flow.run.close' ||\n typeof proof.actionBlockId !== 'string' ||\n typeof proof.inputDigest !== 'string' ||\n !actionInputs ||\n typeof actionInputs !== 'object' ||\n Array.isArray(actionInputs) ||\n !capability ||\n typeof capability !== 'object' ||\n Array.isArray(capability) ||\n typeof (capability as Record<string, unknown>).can !== 'string' ||\n typeof (capability as Record<string, unknown>).with !== 'string' ||\n !Array.isArray(proof.proofCids) ||\n proof.proofCids.some((cid) => typeof cid !== 'string')\n ) {\n return undefined;\n }\n return {\n invocationCid: proof.invocationCid,\n invocation: proof.invocation,\n actorDid: proof.actorDid,\n actionType: 'qi/flow.run.close',\n actionBlockId: proof.actionBlockId,\n inputDigest: proof.inputDigest,\n actionInputs: actionInputs as Record<string, unknown>,\n capability: capability as UcanCapability,\n proofCids: [...(proof.proofCids as string[])],\n };\n}\n\nfunction terminalReservationFromEvent(\n event: { eventId: string; originServerTs: number; content: RunEventInput },\n authorization?: RunTerminalAuthorizationProof\n): { reservation: RunTerminalReservation; eventId: string } | undefined {\n if (event.content.kind !== 'run.closed' && event.content.kind !== 'run.cancelled') return undefined;\n const summary = terminalSummary(event.content.payload.summary);\n if (!summary) return undefined;\n return {\n reservation: {\n reservationId: `matrix:${event.eventId}`,\n status: event.content.kind === 'run.closed' ? 'closed' : 'cancelled',\n at: event.originServerTs,\n ...(authorization?.actorDid || event.content.payload.actorDid ? { by: authorization?.actorDid || event.content.payload.actorDid } : {}),\n ...(authorization?.invocationCid || event.content.payload.invocationCid ? { closeInvocationCid: authorization?.invocationCid || event.content.payload.invocationCid } : {}),\n ...(event.content.kind === 'run.cancelled' && event.content.payload.reason ? { reason: event.content.payload.reason } : {}),\n summary,\n },\n eventId: event.eventId,\n };\n}\n\nfunction sameTerminalSummary(left: Record<string, boolean>, right: Record<string, boolean>): boolean {\n return JSON.stringify(canonicalize(left)) === JSON.stringify(canonicalize(right));\n}\n\nasync function authenticatedTerminalFromEvent(\n event: { eventId: string; originServerTs: number; content: RunEventInput },\n params: {\n runId: string;\n flowUri: string;\n flowOwnerDid: string;\n verifyInvocation: DesignPodInvocationVerifier;\n }\n): Promise<{ reservation: RunTerminalReservation; eventId: string } | undefined> {\n if (event.content.runId !== params.runId || (event.content.kind !== 'run.closed' && event.content.kind !== 'run.cancelled')) return undefined;\n const authorization = terminalAuthorizationFromEvent(event);\n if (!authorization || event.content.payload.invocationCid !== authorization.invocationCid) return undefined;\n if ((await digestDesignPodValue(authorization.actionInputs)) !== authorization.inputDigest) return undefined;\n\n const cancelled = authorization.actionInputs.cancel === true;\n const expectedStatus: RunTerminalRecord['status'] = cancelled ? 'cancelled' : 'closed';\n const eventStatus: RunTerminalRecord['status'] = event.content.kind === 'run.cancelled' ? 'cancelled' : 'closed';\n if (eventStatus !== expectedStatus) return undefined;\n const expectedReason = cancelled && typeof authorization.actionInputs.reason === 'string' ? authorization.actionInputs.reason : undefined;\n const eventReason = event.content.kind === 'run.cancelled' ? event.content.payload.reason : undefined;\n if (eventReason !== expectedReason) return undefined;\n\n const terminal = terminalReservationFromEvent(event, authorization);\n if (!terminal) return undefined;\n const authorizedSummary = terminalSummary(authorization.actionInputs.terminalSummary);\n if (!authorizedSummary || !sameTerminalSummary(terminal.reservation.summary, authorizedSummary)) return undefined;\n\n const blockCapability = authorization.capability.can === 'flow/block/execute' && authorization.capability.with === `${params.flowUri}:${authorization.actionBlockId}`;\n const directCapability = authorization.capability.can === 'flow/run.close' && authorization.capability.with === params.flowUri;\n if (!blockCapability && !directCapability) return undefined;\n\n const invocation: StoredInvocation = {\n cid: authorization.invocationCid,\n invocation: authorization.invocation,\n invokerDid: authorization.actorDid,\n capability: authorization.capability,\n executedAt: event.originServerTs,\n flowId: params.flowUri.replace(/^ixo:flow:/, ''),\n sessionRunId: params.runId,\n blockId: authorization.actionBlockId,\n result: 'success',\n proofCids: authorization.proofCids,\n facts: { actionType: authorization.actionType, inputDigest: authorization.inputDigest, sessionRunId: params.runId },\n };\n const verified = await params.verifyInvocation({\n invocation,\n expected: {\n actorDid: authorization.actorDid,\n actionType: authorization.actionType,\n blockId: authorization.actionBlockId,\n inputDigest: authorization.inputDigest,\n flowUri: params.flowUri,\n flowOwnerDid: params.flowOwnerDid,\n sessionRunId: params.runId,\n capability: authorization.capability,\n },\n });\n return verified.valid ? terminal : undefined;\n}\n\nasync function readMatrixTerminalState(\n eventLog: RunEventAppender,\n params: {\n runId: string;\n flowUri: string;\n flowOwnerDid: string;\n legacyExpectedSummary?: Record<string, boolean>;\n verifyInvocation?: DesignPodInvocationVerifier;\n requireAuthenticated: boolean;\n }\n): Promise<MatrixTerminalState> {\n if (!eventLog.read) throw new Error('Matrix ordered readback is required to elect a terminal transition');\n let from: string | undefined;\n const seenTokens = new Set<string>();\n do {\n const page = await eventLog.read(params.runId, { direction: 'forward', limit: 100, ...(from ? { from } : {}) });\n for (const event of page.events) {\n if (event.content.kind !== 'run.closed' && event.content.kind !== 'run.cancelled') continue;\n if (params.verifyInvocation) {\n const authenticated = await authenticatedTerminalFromEvent(event, { ...params, verifyInvocation: params.verifyInvocation });\n if (authenticated) return { terminal: authenticated };\n // A signed-looking but invalid event can never fall back to legacy\n // authority, even on a non-Design-POD run.\n if (terminalAuthorizationFromEvent(event)) continue;\n }\n if (!params.requireAuthenticated) {\n const legacy = terminalReservationFromEvent(event);\n if (legacy && (!params.legacyExpectedSummary || sameTerminalSummary(legacy.reservation.summary, params.legacyExpectedSummary))) return { terminal: legacy };\n }\n }\n from = page.nextToken;\n if (from && seenTokens.has(from)) throw new Error('Matrix repeated a terminal-event pagination token');\n if (from) seenTokens.add(from);\n } while (from);\n return {};\n}\n\nfunction clearOwnTerminalReservation(yDoc: Y.Doc, runId: string, reservationId: string): void {\n yDoc.transact(() => {\n const pending = getExistingRunsTerminalPendingMap(yDoc)?.get(runId);\n if (pending?.reservationId === reservationId) getRunsTerminalPendingMap(yDoc).delete(runId);\n });\n}\n\nasync function reconcileTerminalEvent(\n eventLog: RunEventAppender,\n event: Extract<LifecycleRunEventInput, { kind: 'run.closed' | 'run.cancelled' }>,\n reservation: RunTerminalReservation,\n params: {\n flowUri: string;\n flowOwnerDid: string;\n verifyInvocation?: DesignPodInvocationVerifier;\n requireAuthenticated: boolean;\n }\n): Promise<{ reservation: RunTerminalReservation; eventId: string }> {\n let eventId: string | undefined;\n let appendError: unknown;\n try {\n eventId = await eventLog.append(event);\n } catch (error) {\n appendError = error;\n }\n if (eventLog.read) {\n const state = await readMatrixTerminalState(eventLog, {\n runId: event.runId,\n flowUri: params.flowUri,\n flowOwnerDid: params.flowOwnerDid,\n legacyExpectedSummary: reservation.summary,\n verifyInvocation: params.verifyInvocation,\n requireAuthenticated: params.requireAuthenticated,\n });\n if (state.terminal) return state.terminal;\n if (appendError) throw appendError;\n throw new Error('Matrix did not retain an authoritative terminal event');\n }\n if (eventId) return { reservation, eventId };\n throw appendError;\n}\n\nfunction prepareTerminalTransition(\n params: CloseRunParams,\n status: RunTerminalRecord['status'],\n authorization: RunLifecycleAuthorizationDecision,\n now: number,\n pinnedDesignPod: PinnedDesignPodClosureState,\n reason?: string\n): { reservation?: RunTerminalReservation; existing?: RunTerminalRecord } {\n let existing: RunTerminalRecord | undefined;\n let reservation: RunTerminalReservation | undefined;\n const matrixAuthoritative = pinnedDesignPod.pinned || Boolean(params.terminalAuthorization);\n params.yDoc.transact(() => {\n const current = getExistingRunsTerminalMap(params.yDoc)?.get(params.runId);\n if (current && !matrixAuthoritative) {\n existing = current;\n return;\n }\n if (pinnedDesignPod.pinned) {\n const current = inspectPinnedDesignPodRunForClosure(params.yDoc, params.runId);\n if (current.snapshot !== pinnedDesignPod.snapshot) {\n throw new Error('The authenticated Design POD publication changed before its terminal transition could be reserved');\n }\n }\n const finalSummary = computeRunSummary(params.yDoc, params.runId, params.actionTypes, {\n flowId: params.flowUri,\n actorDid: params.actorDid,\n now,\n });\n const incomplete = incompleteBlocks(finalSummary);\n if (status === 'closed' && incomplete.length > 0 && (!params.allowIncomplete || pinnedDesignPod.pinned)) {\n throw new RunNotReadyError(incomplete);\n }\n reservation = {\n reservationId: `${status}:${params.runId}:${createRunUlid(now)}`,\n status,\n at: now,\n by: params.actorDid,\n ...(params.terminalAuthorization?.invocationCid || authorization.invocationCid\n ? { closeInvocationCid: params.terminalAuthorization?.invocationCid || authorization.invocationCid }\n : {}),\n ...(reason ? { reason } : {}),\n summary: finalSummary,\n };\n });\n return { reservation, existing };\n}\n\nfunction installTerminalReservation(params: CloseRunParams, reservation: RunTerminalReservation, pinnedDesignPod: PinnedDesignPodClosureState): RunTerminalRecord | undefined {\n let existing: RunTerminalRecord | undefined;\n const matrixAuthoritative = pinnedDesignPod.pinned || Boolean(params.terminalAuthorization);\n params.yDoc.transact(() => {\n const current = getExistingRunsTerminalMap(params.yDoc)?.get(params.runId);\n if (current && !matrixAuthoritative) {\n existing = current;\n return;\n }\n if (pinnedDesignPod.pinned) {\n const current = inspectPinnedDesignPodRunForClosure(params.yDoc, params.runId);\n if (current.snapshot !== pinnedDesignPod.snapshot) {\n throw new Error('The authenticated Design POD publication changed before its terminal transition could be reserved');\n }\n }\n const finalSummary = computeRunSummary(params.yDoc, params.runId, params.actionTypes, {\n flowId: params.flowUri,\n actorDid: params.actorDid,\n now: reservation.at,\n });\n const incomplete = incompleteBlocks(finalSummary);\n if (reservation.status === 'closed' && incomplete.length > 0 && (!params.allowIncomplete || pinnedDesignPod.pinned)) {\n throw new RunNotReadyError(incomplete);\n }\n if (JSON.stringify(canonicalize(finalSummary)) !== JSON.stringify(canonicalize(reservation.summary))) {\n throw new Error('The run completion summary changed while its terminal event was being prepared');\n }\n // This CRDT reservation only blocks local/sequenced work while Matrix is\n // appending. It is never an election primitive: a disconnected peer may\n // replace it, and the first authenticated Matrix terminal event wins.\n getRunsTerminalPendingMap(params.yDoc).set(params.runId, reservation);\n });\n return existing;\n}\n\nfunction finalizeTerminalTransition(yDoc: Y.Doc, runId: string, reservation: RunTerminalReservation, eventId: string, matrixAuthoritative = false): FinishRunResult {\n const terminal: RunTerminalRecord = {\n status: reservation.status,\n at: reservation.at,\n by: reservation.by,\n terminalEventId: eventId,\n ...(reservation.closeInvocationCid ? { closeInvocationCid: reservation.closeInvocationCid } : {}),\n summary: reservation.summary,\n };\n let created = false;\n yDoc.transact(() => {\n const terminalMap = getRunsTerminalMap(yDoc);\n if (matrixAuthoritative || !terminalMap.has(runId)) {\n created = !terminalMap.has(runId);\n terminalMap.set(runId, terminal);\n }\n // Once Matrix has an authoritative terminal event, every provisional or\n // superseded Yjs lease is obsolete, including one left by a crashed peer.\n if (getExistingRunsTerminalPendingMap(yDoc)?.has(runId)) getRunsTerminalPendingMap(yDoc).delete(runId);\n });\n const winner = getRunsTerminalMap(yDoc).get(runId) || terminal;\n return {\n terminal: { ...winner, summary: winner.summary ? { ...winner.summary } : undefined },\n created,\n eventId: winner.terminalEventId || eventId,\n };\n}\n\nexport async function closeRun(params: CloseRunParams): Promise<FinishRunResult> {\n return withLifecycleLock(params.yDoc, params.runId, async () => {\n const existing = getExistingRunsTerminalMap(params.yDoc)?.get(params.runId);\n const initialPinnedState = inspectPinnedDesignPodRunForClosure(params.yDoc, params.runId);\n if (existing && !initialPinnedState.pinned && !params.terminalAuthorization) {\n return {\n terminal: {\n ...existing,\n summary: existing.summary ? { ...existing.summary } : undefined,\n },\n created: false,\n ...(existing.terminalEventId ? { eventId: existing.terminalEventId } : {}),\n };\n }\n const meta = getRunMeta(params.yDoc, params.runId);\n if (!meta) throw new Error(`Unknown run \"${params.runId}\"`);\n\n const authorization = await requireAuthorization(params.authorize, {\n can: 'flow/run.close',\n with: params.flowUri,\n actorDid: params.actorDid,\n runId: params.runId,\n });\n const now = params.now?.() ?? Date.now();\n const summary = computeRunSummary(params.yDoc, params.runId, params.actionTypes, {\n flowId: params.flowUri,\n actorDid: params.actorDid,\n now,\n });\n const incomplete = incompleteBlocks(summary);\n const pinnedDesignPod = await authenticatePinnedDesignPodClosure(params);\n const authenticatedTerminalRequired = pinnedDesignPod.pinned || Boolean(params.terminalAuthorization);\n if (authenticatedTerminalRequired && !params.eventLog.read) {\n throw new Error('Matrix ordered readback is required to elect an authenticated terminal transition');\n }\n if (authenticatedTerminalRequired && (!params.terminalAuthorization || !params.verifyTerminalInvocation)) {\n throw new Error('This terminal transition requires a cryptographically verified signed Flow invocation');\n }\n if (authenticatedTerminalRequired) {\n const retained = await readMatrixTerminalState(params.eventLog, {\n runId: params.runId,\n flowUri: params.flowUri,\n flowOwnerDid: String(getExistingYMap(params.yDoc, 'root')?.get('flowOwnerDid') || ''),\n verifyInvocation: params.verifyTerminalInvocation,\n requireAuthenticated: true,\n });\n if (retained.terminal) {\n return finalizeTerminalTransition(params.yDoc, params.runId, retained.terminal.reservation, retained.terminal.eventId, true);\n }\n }\n if (incomplete.length > 0 && (!params.allowIncomplete || pinnedDesignPod.pinned)) {\n throw new RunNotReadyError(incomplete);\n }\n const transition = prepareTerminalTransition(params, 'closed', authorization, now, pinnedDesignPod);\n if (transition.existing) {\n return {\n terminal: { ...transition.existing, summary: transition.existing.summary ? { ...transition.existing.summary } : undefined },\n created: false,\n ...(transition.existing.terminalEventId ? { eventId: transition.existing.terminalEventId } : {}),\n };\n }\n const reservation = transition.reservation!;\n const installedTerminal = installTerminalReservation(params, reservation, pinnedDesignPod);\n if (installedTerminal) {\n return {\n terminal: { ...installedTerminal, summary: installedTerminal.summary ? { ...installedTerminal.summary } : undefined },\n created: false,\n ...(installedTerminal.terminalEventId ? { eventId: installedTerminal.terminalEventId } : {}),\n };\n }\n const event = {\n runId: params.runId,\n kind: 'run.closed',\n payload: {\n ...(reservation.closeInvocationCid ? { invocationCid: reservation.closeInvocationCid } : {}),\n ...(reservation.by ? { actorDid: reservation.by } : {}),\n summary: reservation.summary as unknown as RunJsonObject,\n ...(params.terminalAuthorization ? { authorization: toRunJsonValue(params.terminalAuthorization) as RunJsonObject } : {}),\n },\n idempotencyKey: createRunEventIdempotencyKey('run.closed', params.runId, reservation.closeInvocationCid || reservation.reservationId),\n ts: reservation.at,\n } satisfies Extract<LifecycleRunEventInput, { kind: 'run.closed' }>;\n try {\n const reconciled = await reconcileTerminalEvent(params.eventLog, event, reservation, {\n flowUri: params.flowUri,\n flowOwnerDid: String(getExistingYMap(params.yDoc, 'root')?.get('flowOwnerDid') || ''),\n verifyInvocation: params.verifyTerminalInvocation,\n requireAuthenticated: authenticatedTerminalRequired,\n });\n return finalizeTerminalTransition(params.yDoc, params.runId, reconciled.reservation, reconciled.eventId, authenticatedTerminalRequired);\n } catch (error) {\n clearOwnTerminalReservation(params.yDoc, params.runId, reservation.reservationId);\n throw error;\n }\n });\n}\n\nexport interface CancelRunParams extends Omit<CloseRunParams, 'allowIncomplete'> {\n reason?: string;\n}\n\nexport async function cancelRun(params: CancelRunParams): Promise<FinishRunResult> {\n return withLifecycleLock(params.yDoc, params.runId, async () => {\n const existing = getExistingRunsTerminalMap(params.yDoc)?.get(params.runId);\n const initialPinnedState = inspectPinnedDesignPodRunForClosure(params.yDoc, params.runId);\n if (existing && !initialPinnedState.pinned && !params.terminalAuthorization) {\n return {\n terminal: {\n ...existing,\n summary: existing.summary ? { ...existing.summary } : undefined,\n },\n created: false,\n ...(existing.terminalEventId ? { eventId: existing.terminalEventId } : {}),\n };\n }\n if (!getRunMeta(params.yDoc, params.runId)) {\n throw new Error(`Unknown run \"${params.runId}\"`);\n }\n const authorization = await requireAuthorization(params.authorize, {\n can: 'flow/run.close',\n with: params.flowUri,\n actorDid: params.actorDid,\n runId: params.runId,\n });\n const now = params.now?.() ?? Date.now();\n const pinnedDesignPod = await authenticatePinnedDesignPodClosure(params);\n const authenticatedTerminalRequired = pinnedDesignPod.pinned || Boolean(params.terminalAuthorization);\n if (authenticatedTerminalRequired && !params.eventLog.read) {\n throw new Error('Matrix ordered readback is required to elect an authenticated terminal transition');\n }\n if (authenticatedTerminalRequired && (!params.terminalAuthorization || !params.verifyTerminalInvocation)) {\n throw new Error('This terminal transition requires a cryptographically verified signed Flow invocation');\n }\n if (authenticatedTerminalRequired) {\n const retained = await readMatrixTerminalState(params.eventLog, {\n runId: params.runId,\n flowUri: params.flowUri,\n flowOwnerDid: String(getExistingYMap(params.yDoc, 'root')?.get('flowOwnerDid') || ''),\n verifyInvocation: params.verifyTerminalInvocation,\n requireAuthenticated: true,\n });\n if (retained.terminal) {\n return finalizeTerminalTransition(params.yDoc, params.runId, retained.terminal.reservation, retained.terminal.eventId, true);\n }\n }\n const transition = prepareTerminalTransition(params, 'cancelled', authorization, now, pinnedDesignPod, params.reason);\n if (transition.existing) {\n return {\n terminal: { ...transition.existing, summary: transition.existing.summary ? { ...transition.existing.summary } : undefined },\n created: false,\n ...(transition.existing.terminalEventId ? { eventId: transition.existing.terminalEventId } : {}),\n };\n }\n const reservation = transition.reservation!;\n const installedTerminal = installTerminalReservation(params, reservation, pinnedDesignPod);\n if (installedTerminal) {\n return {\n terminal: { ...installedTerminal, summary: installedTerminal.summary ? { ...installedTerminal.summary } : undefined },\n created: false,\n ...(installedTerminal.terminalEventId ? { eventId: installedTerminal.terminalEventId } : {}),\n };\n }\n const event = {\n runId: params.runId,\n kind: 'run.cancelled',\n payload: {\n ...(reservation.closeInvocationCid ? { invocationCid: reservation.closeInvocationCid } : {}),\n ...(reservation.by ? { actorDid: reservation.by } : {}),\n ...(reservation.reason ? { reason: reservation.reason } : {}),\n summary: reservation.summary as unknown as RunJsonObject,\n ...(params.terminalAuthorization ? { authorization: toRunJsonValue(params.terminalAuthorization) as RunJsonObject } : {}),\n },\n idempotencyKey: createRunEventIdempotencyKey('run.closed', params.runId, reservation.closeInvocationCid || reservation.reservationId),\n ts: reservation.at,\n } satisfies Extract<LifecycleRunEventInput, { kind: 'run.cancelled' }>;\n try {\n const reconciled = await reconcileTerminalEvent(params.eventLog, event, reservation, {\n flowUri: params.flowUri,\n flowOwnerDid: String(getExistingYMap(params.yDoc, 'root')?.get('flowOwnerDid') || ''),\n verifyInvocation: params.verifyTerminalInvocation,\n requireAuthenticated: authenticatedTerminalRequired,\n });\n return finalizeTerminalTransition(params.yDoc, params.runId, reconciled.reservation, reconciled.eventId, authenticatedTerminalRequired);\n } catch (error) {\n clearOwnTerminalReservation(params.yDoc, params.runId, reservation.reservationId);\n throw error;\n }\n });\n}\n\nexport interface RunDefinitionDrift {\n changed: boolean;\n previousRevision?: string;\n revision: string;\n changedBlockIds: string[];\n}\n\nexport function detectRunDefinitionDrift(yDoc: Y.Doc, runId: string, definition: RunDefinitionSnapshot): RunDefinitionDrift {\n const manifest = getRunMeta(yDoc, runId)?.manifest;\n if (!manifest) throw new RunNotMigratedError(runId);\n const before = new Set(manifest.blockIds);\n const after = new Set(definition.manifest.blockIds);\n const changedBlockIds = [...new Set([...before, ...after])].filter((id) => before.has(id) !== after.has(id));\n return {\n // With no frozen hash — a run the flow manager opened — the step list is\n // the whole of what can be compared. It catches a step added or removed\n // and misses one whose configuration was edited in place, which is less\n // than the hash sees and more than a hash comparison against a differently\n // computed value would be worth: that would read \"changed\" always, on\n // every scheduled run, and mean nothing.\n changed: manifest.defHash === undefined\n ? changedBlockIds.length > 0\n : manifest.defHash !== definition.manifest.defHash,\n previousRevision: manifest.defHash,\n revision: definition.manifest.defHash,\n changedBlockIds,\n };\n}\n\nexport async function recordRunDefinitionDrift(\n yDoc: Y.Doc,\n runId: string,\n definition: RunDefinitionSnapshot,\n eventLog: RunEventAppender,\n now = Date.now()\n): Promise<RunDefinitionDrift & { eventId?: string }> {\n const drift = detectRunDefinitionDrift(yDoc, runId, definition);\n if (!drift.changed) return drift;\n const eventId = await eventLog.append({\n runId,\n kind: 'definition.changed',\n payload: {\n revision: drift.revision,\n previousRevision: drift.previousRevision,\n changedBlockIds: drift.changedBlockIds,\n summary: 'The live flow definition changed after this session started.',\n },\n idempotencyKey: createRunEventIdempotencyKey('definition.changed', runId, drift.revision),\n ts: now,\n });\n return { ...drift, eventId };\n}\n\nexport function readRunActionStates(yDoc: Y.Doc, runId: string, blockIds: string[]): Record<string, FlowNodeRuntimeState> {\n return Object.fromEntries(blockIds.map((blockId) => [blockId, readActionState(yDoc, runId, blockId)]));\n}\n","import { isRuntimeRef } from '../../types/baseUcan';\nimport { getNestedValue } from '../flowEngine/referenceResolver';\n\n/**\n * Context passed to resolveRuntimeRefs when resolving inputs for a triggered\n * listener block. The runtime constructs this from a PendingInvocation when\n * the assignee invokes the listener.\n *\n * - `payload`: the frozen event payload, used to resolve `trigger.payload.*` refs\n * - `refSnapshots`: frozen `nodeId.output.*` values captured at queue time,\n * used to resolve those refs against the moment of emission rather than\n * current state. See docs/flow-engine/events-and-triggers-plan.md §3.5.1 for the\n * Sally → Mike scenario this fixes.\n */\nexport interface TriggerResolutionContext {\n payload: Record<string, unknown>;\n refSnapshots: Record<string, unknown>;\n}\n\n/**\n * Resolve runtime references in an nb (caveats) object.\n *\n * At compile time, `{ \"$ref\": \"nodeId.output.fieldPath\" }` values are serialized\n * as-is into the block's `inputs` JSON string. At execution time, this function\n * replaces them with actual output values from upstream nodes.\n *\n * Two ref namespaces are supported:\n * - `nodeId.output.fieldPath` — looked up via `getNodeOutput`. When a\n * `triggerContext` is provided AND `refSnapshots[ref]` exists, the\n * snapshot is preferred over the live lookup. This is the load-bearing\n * fix for the lag-time scenario where multiple pending invocations are\n * queued and the source block re-runs before the assignee acts on them.\n * - `trigger.payload.fieldPath` — looked up in `triggerContext.payload`.\n * Only valid when `triggerContext` is provided (i.e. resolving inputs\n * for a triggered listener invocation). Compile-time validation in\n * compiler.ts guarantees these only appear on `block.event`-triggered\n * blocks.\n *\n * @param nb - The caveats object (may contain nested RuntimeRef values)\n * @param getNodeOutput - Lookup function for upstream node outputs\n * @param triggerContext - Optional, present only for triggered listener invocations\n * @returns A new object with all $ref values resolved\n */\nexport function resolveRuntimeRefs(\n nb: Record<string, unknown>,\n getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined,\n triggerContext?: TriggerResolutionContext\n): Record<string, unknown> {\n return resolveValue(nb, getNodeOutput, triggerContext) as Record<string, unknown>;\n}\n\nfunction resolveValue(value: unknown, getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined, triggerContext?: TriggerResolutionContext): unknown {\n if (isRuntimeRef(value)) {\n return resolveRef(value.$ref, getNodeOutput, triggerContext);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => resolveValue(item, getNodeOutput, triggerContext));\n }\n\n if (typeof value === 'object' && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n result[key] = resolveValue(val, getNodeOutput, triggerContext);\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Resolve a single $ref string.\n *\n * Supported forms:\n * - \"trigger.payload.fieldPath\" — looked up in triggerContext.payload\n * - \"nodeId.output.fieldPath\" — looked up in triggerContext.refSnapshots first\n * (if present), falling back to getNodeOutput. Snapshot preference is\n * what makes the Sally → Mike scenario produce frozen values per pending\n * invocation.\n */\nfunction resolveRef(ref: string, getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined, triggerContext?: TriggerResolutionContext): unknown {\n // trigger.payload.* — only valid when a triggerContext is provided\n if (ref.startsWith('trigger.payload.')) {\n if (!triggerContext) {\n throw new Error(`Trigger ref \"${ref}\" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);\n }\n const fieldPath = ref.slice('trigger.payload.'.length);\n return getNestedValue(triggerContext.payload, fieldPath);\n }\n\n // nodeId.output.fieldPath — prefer the snapshot if we're inside a trigger context\n if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {\n return triggerContext.refSnapshots[ref];\n }\n\n // Parse \"nodeId.output.fieldPath\"\n const outputIndex = ref.indexOf('.output.');\n if (outputIndex === -1) {\n throw new Error(`Invalid runtime reference \"${ref}\". Expected format: \"nodeId.output.fieldPath\" or \"trigger.payload.fieldPath\"`);\n }\n\n const nodeId = ref.slice(0, outputIndex);\n const fieldPath = ref.slice(outputIndex + '.output.'.length);\n\n const output = getNodeOutput(nodeId);\n if (!output) {\n return undefined;\n }\n\n // Traverse the field path (supports dot notation)\n return getNestedValue(output, fieldPath);\n}\n","import type { UcanCapability } from '../../types/ucan';\nimport type { UcanService } from '../../services/ucanService';\nimport { getVersionPolicy } from './versionManifest';\n\nexport interface AuthorizationResult {\n authorized: boolean;\n reason?: string;\n capabilityId?: string;\n proofCids?: string[];\n}\n\nexport interface AuthorizationOptions {\n /** Ignore the temporary version-policy bypass and require a real proof chain. */\n requireSignedInvocation?: boolean;\n}\n\n/**\n * Check if an actor is authorized to execute a block.\n *\n * Behaviour depends on the flow's schema version:\n * - v0.x (or no version): UCAN is optional. If ucanService is unavailable,\n * execution is allowed without a delegation chain.\n * - v1.0.0+: UCAN is required. A valid delegation chain must exist.\n */\nexport const isAuthorized = async (\n blockId: string,\n actorDid: string,\n ucanService: UcanService | undefined,\n flowUri: string,\n schemaVersion?: string,\n options: AuthorizationOptions = {}\n): Promise<AuthorizationResult> => {\n const policy = schemaVersion ? getVersionPolicy(schemaVersion) : null;\n const requireUcan = options.requireSignedInvocation === true;\n\n // If UCAN is not required by this version, allow execution without delegation chain\n if (policy && !policy.ucanRequired && !requireUcan) {\n return { authorized: true };\n }\n\n // UCAN is required (v1.0.0+ or unknown version) — ucanService must be available\n if (!ucanService) {\n // No ucanService and no version info: allow for backward compatibility\n if (!policy && !requireUcan) {\n return { authorized: true };\n }\n return {\n authorized: false,\n reason: requireUcan\n ? 'UCAN service is not configured. This governed action requires a signed Flow invocation.'\n : 'UCAN service is not configured. This flow version requires UCAN authorization.',\n };\n }\n\n const capability: UcanCapability = {\n can: 'flow/block/execute',\n with: `${flowUri}:${blockId}`,\n };\n\n const result = await ucanService.validateDelegationChain(actorDid, capability);\n\n if (!result.valid) {\n return {\n authorized: false,\n reason: result.error || 'No valid capability chain found',\n };\n }\n\n const proofCids = result.proofChain?.map((d) => d.cid) || [];\n if (requireUcan && proofCids.length === 0) {\n return {\n authorized: false,\n reason: 'A signed invocation requires a non-empty UCAN delegation proof chain.',\n };\n }\n\n return {\n authorized: true,\n capabilityId: proofCids[0],\n proofCids,\n };\n};\n","import { isAuthorized } from './authorization';\nimport type { FlowNode, FlowNodeRuntimeState, EvaluationStatus } from '../../types/authorization';\nimport type { FlowRuntimeStateManager } from './runtime';\nimport type { InvocationStore } from '../invocationStore';\nimport type { UcanService } from '../../services/ucanService';\nimport type { StoredInvocation, UcanCapability } from '../../types/ucan';\n\nexport interface NodeActionResult {\n claimId?: string;\n evaluationStatus?: EvaluationStatus;\n submittedByDid?: string;\n payload?: any;\n}\n\nexport interface ExecutionContext {\n runtime: FlowRuntimeStateManager;\n /** UCAN service — optional for v0.x flows, required for v1.0.0+ */\n ucanService?: UcanService;\n /** Invocation store — optional for v0.x flows */\n invocationStore?: InvocationStore;\n flowUri: string;\n flowId: string;\n /** Session run that owns runtime and invocation records for this execution. */\n sessionRunId?: string;\n flowOwnerDid: string;\n /** Flow schema version. When set, controls whether UCAN is enforced. */\n schemaVersion?: string;\n now?: () => number;\n}\n\nexport interface ExecutionOutcome {\n success: boolean;\n stage: 'authorization' | 'claim' | 'action' | 'complete';\n error?: string;\n result?: NodeActionResult;\n capabilityId?: string;\n invocationCid?: string;\n}\n\nexport interface ExecuteNodeParams {\n node: FlowNode;\n actorDid: string;\n actorType: 'entity' | 'user';\n entityRoomId?: string;\n context: ExecutionContext;\n action: (proof: {\n invocationCid?: string;\n /** Signed UCAN CAR for authority checks that must complete before the invocation audit record can be finalized. */\n invocation?: string;\n capabilityId?: string;\n proofCids: string[];\n capability: UcanCapability;\n facts: Record<string, unknown>;\n }) => Promise<NodeActionResult>;\n invocationFacts?: Record<string, unknown>;\n /** Require a persisted UCAN invocation regardless of the temporary global policy bypass. */\n requireSignedInvocation?: boolean;\n pin: string;\n}\n\nconst updateRuntimeAfterSuccess = (\n node: FlowNode,\n actorDid: string,\n runtime: FlowRuntimeStateManager,\n actionResult: NodeActionResult,\n invocationCid?: string,\n now?: () => number\n) => {\n const updates: FlowNodeRuntimeState = {\n submittedByDid: actionResult.submittedByDid || actorDid,\n evaluationStatus: actionResult.evaluationStatus || 'pending',\n executionTimestamp: now ? now() : Date.now(),\n lastInvocationCid: invocationCid,\n };\n\n if (actionResult.claimId) {\n updates.claimId = actionResult.claimId;\n }\n\n runtime.update(node.id, updates);\n};\n\n/**\n * Execute a node.\n *\n * The pipeline adapts based on the flow's schema version (via context.schemaVersion):\n *\n * **v0.x (legacy):** activation → action → runtime update.\n * UCAN authorization and invocations are skipped when ucanService is not available.\n *\n * **v1.0.0+:** activation → UCAN authorization → invocation → action → runtime update.\n * Requires a configured ucanService with valid delegation chains.\n */\nexport const executeNode = async ({\n node,\n actorDid,\n actorType,\n entityRoomId,\n context,\n action,\n invocationFacts = {},\n requireSignedInvocation = false,\n pin,\n}: ExecuteNodeParams): Promise<ExecutionOutcome> => {\n const { runtime, ucanService, invocationStore, flowUri, flowId, sessionRunId, schemaVersion, now } = context;\n\n // 1. Check authorization (version-aware: skips UCAN for v0.x when service unavailable)\n const auth = await isAuthorized(node.id, actorDid, ucanService, flowUri, schemaVersion, { requireSignedInvocation });\n if (!auth.authorized) {\n return { success: false, stage: 'authorization', error: auth.reason };\n }\n if (requireSignedInvocation && !invocationStore) {\n return { success: false, stage: 'authorization', error: 'A persisted invocation store is required for this governed action.' };\n }\n\n // 3. Check linked claim requirement\n if (node.linkedClaim && !node.linkedClaim.collectionId) {\n return { success: false, stage: 'claim', error: 'Linked claim collection is required but missing.' };\n }\n\n // 4. Create invocation BEFORE execution (only when UCAN proof chain exists)\n let invocationCid: string | undefined;\n let invocationData: string | undefined;\n\n if (ucanService && auth.proofCids && auth.proofCids.length > 0) {\n const capability: UcanCapability = {\n can: 'flow/block/execute',\n with: `${flowUri}:${node.id}`,\n };\n\n try {\n const invocationResult = await ucanService.createAndValidateInvocation(\n {\n invokerDid: actorDid,\n invokerType: actorType,\n entityRoomId,\n capability,\n proofs: auth.proofCids,\n facts: invocationFacts,\n pin,\n },\n flowId,\n node.id\n );\n\n if (!invocationResult.valid) {\n return {\n success: false,\n stage: 'authorization',\n error: `Invocation validation failed: ${invocationResult.error}`,\n };\n }\n\n invocationCid = invocationResult.cid;\n invocationData = invocationResult.invocation;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to create invocation';\n return { success: false, stage: 'authorization', error: message };\n }\n }\n if (requireSignedInvocation && (!invocationCid || !invocationData)) {\n return { success: false, stage: 'authorization', error: 'This governed action requires a signed Flow invocation.' };\n }\n\n // 5. Execute action\n try {\n const result = await action({\n invocationCid,\n invocation: invocationData,\n capabilityId: auth.capabilityId,\n proofCids: auth.proofCids || [],\n capability: { can: 'flow/block/execute', with: `${flowUri}:${node.id}` },\n facts: invocationFacts,\n });\n\n // 6. Verify linked claim was provided if required\n if (node.linkedClaim && !result.claimId) {\n if (invocationStore && invocationCid && invocationData) {\n const storedInvocation: StoredInvocation = {\n cid: invocationCid,\n invocation: invocationData,\n invokerDid: actorDid,\n capability: { can: 'flow/block/execute', with: `${flowUri}:${node.id}` },\n executedAt: now ? now() : Date.now(),\n flowId,\n sessionRunId,\n blockId: node.id,\n result: 'failure',\n error: 'Execution did not return a claimId for linked claim requirement.',\n proofCids: auth.proofCids || [],\n facts: invocationFacts,\n };\n invocationStore.add(storedInvocation);\n }\n\n return {\n success: false,\n stage: 'claim',\n error: 'Execution did not return a claimId for linked claim requirement.',\n invocationCid,\n };\n }\n\n // 7. Store successful invocation\n if (invocationStore && invocationCid && invocationData) {\n const storedInvocation: StoredInvocation = {\n cid: invocationCid,\n invocation: invocationData,\n invokerDid: actorDid,\n capability: { can: 'flow/block/execute', with: `${flowUri}:${node.id}` },\n executedAt: now ? now() : Date.now(),\n flowId,\n sessionRunId,\n blockId: node.id,\n result: 'success',\n proofCids: auth.proofCids || [],\n facts: invocationFacts,\n claimId: result.claimId,\n };\n invocationStore.add(storedInvocation);\n }\n\n // 8. Update runtime state\n updateRuntimeAfterSuccess(node, actorDid, runtime, result, invocationCid || auth.capabilityId, now);\n\n return {\n success: true,\n stage: 'complete',\n result,\n capabilityId: auth.capabilityId,\n invocationCid,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Execution failed';\n\n // Store failed invocation\n if (invocationStore && invocationCid && invocationData) {\n const storedInvocation: StoredInvocation = {\n cid: invocationCid,\n invocation: invocationData,\n invokerDid: actorDid,\n capability: { can: 'flow/block/execute', with: `${flowUri}:${node.id}` },\n executedAt: now ? now() : Date.now(),\n flowId,\n sessionRunId,\n blockId: node.id,\n result: 'failure',\n error: message,\n proofCids: auth.proofCids || [],\n facts: invocationFacts,\n };\n invocationStore.add(storedInvocation);\n }\n\n return { success: false, stage: 'action', error: message, invocationCid };\n }\n};\n\n// ---------------------------------------------------------------------------\n// Version-aware execution dispatch (convenience wrapper)\n// ---------------------------------------------------------------------------\n\nexport interface ExecuteNodeVersionedParams {\n node: FlowNode;\n actorDid: string;\n actorType: 'entity' | 'user';\n entityRoomId?: string;\n schemaVersion: string;\n context: ExecutionContext;\n action: ExecuteNodeParams['action'];\n invocationFacts?: Record<string, unknown>;\n requireSignedInvocation?: boolean;\n pin: string;\n}\n\n/**\n * Convenience wrapper that ensures schemaVersion is set on the context.\n * Prefer using executeNode directly with context.schemaVersion set.\n */\nexport const executeNodeVersioned = async (params: ExecuteNodeVersionedParams): Promise<ExecutionOutcome> => {\n return executeNode({\n node: params.node,\n actorDid: params.actorDid,\n actorType: params.actorType,\n entityRoomId: params.entityRoomId,\n context: { ...params.context, schemaVersion: params.schemaVersion },\n action: params.action,\n invocationFacts: params.invocationFacts,\n requireSignedInvocation: params.requireSignedInvocation,\n pin: params.pin,\n });\n};\n","import * as Y from 'yjs';\nimport { getAction } from '../actionRegistry';\nimport type { ActionResult } from '../actionRegistry/types';\nimport { PROOF_MISSING_CODE, validateActionProof } from './proof';\nimport type { ActionReadBackMetadata, FlowNodeRuntimeState, ReadBackTerminalState } from '../../types/authorization';\nimport type { IxoEditorType } from '../../types/editor';\nimport type { FlowRuntimeStateManager } from './runtime';\nimport { createRuntimeStateManager } from './runtime';\nimport { createRunRuntimeReaderWithDoc, createRunScopedRuntimeManager, resolveRunIdForExecution, usesLegacyRuntimeCompatibility } from './runs';\nimport { reconcilePendingInvocations } from './reconcile';\nimport { isYDocLike } from '../yjsTypes';\nimport { appendRunRecord, removePendingInvocation, type PendingInvocation, type RunRecordDetails } from './triggers';\nimport type { RunEventAppender, RunEventInput } from './runLifecycle';\nimport { appendRunTimelineEvent, appendRunTimelineEvents, boundRunActionOutput, boundRunEventJson, createRunEventIdempotencyKey, MAX_RUN_ACTION_OUTPUT_BYTES } from './runTimeline';\n\ntype EditorOrYDoc = IxoEditorType | Y.Doc;\n\nexport interface NormalizeReadBackMetadataParams {\n readBack?: Record<string, unknown>;\n blockId: string;\n actionType: string;\n actorDid: string;\n invocationCid?: string;\n capabilityId?: string;\n requestedAt: number;\n pendingInvocation?: PendingInvocation;\n}\n\nexport interface ActionReadBackResolution {\n state: ReadBackTerminalState;\n output?: Record<string, unknown>;\n events?: NonNullable<ActionResult['events']>;\n readBack?: Record<string, unknown>;\n error?: string | { message: string; code?: string };\n}\n\nexport interface ActionReadBackResolverInput {\n blockId: string;\n runtime: FlowNodeRuntimeState;\n output: Record<string, unknown>;\n readBack: ActionReadBackMetadata;\n}\n\nexport type ActionReadBackResolver = (input: ActionReadBackResolverInput) => ActionReadBackResolution | Promise<ActionReadBackResolution>;\n\nexport interface ReconcileActionReadBackParams {\n editorOrYDoc?: EditorOrYDoc | null;\n blockId: string;\n actorDid?: string;\n runtime?: FlowRuntimeStateManager;\n document?: Array<{ id?: string; props?: Record<string, unknown> }>;\n resolver?: ActionReadBackResolver;\n resolvers?: Record<string, ActionReadBackResolver>;\n runEventLog?: RunEventAppender;\n now?: () => number;\n /**\n * The **session run** (`runs.ts`) this reconciliation writes into — not the\n * per-execution audit id. Multi-run documents require this explicitly; only\n * legacy documents retain the advisory active-run fallback.\n *\n * D2: every new parameter named `runId` means the session run.\n */\n runId?: string;\n}\n\nexport interface ReconcileActionReadBackResult {\n success: boolean;\n blockId: string;\n state: ReadBackTerminalState;\n output?: Record<string, unknown>;\n events: NonNullable<ActionResult['events']>;\n error?: string;\n /**\n * Id of the audit record this reconciliation wrote (`readback-<ts>-<rand>`).\n *\n * @deprecated Use {@link ReconcileActionReadBackResult.executionId}; both\n * carry the same value. The persisted `RunRecordDetails.runId` is never\n * renamed (D2).\n */\n runId?: string;\n /** Forward name for the per-execution audit id. Identical to {@link runId}. */\n executionId?: string;\n pendingInvocationRemoved: boolean;\n readBack?: ActionReadBackMetadata;\n}\n\nasync function appendReadBackTimeline(\n eventLog: RunEventAppender | undefined,\n event: RunEventInput,\n runtime: FlowRuntimeStateManager,\n blockId: string,\n now: () => number\n): Promise<boolean> {\n const result = await appendRunTimelineEvent({\n eventLog,\n event,\n runtime,\n blockId,\n now,\n });\n return result.ok;\n}\n\nfunction isYDoc(value: unknown): value is Y.Doc {\n return isYDocLike(value);\n}\n\nfunction getYDoc(editorOrYDoc?: EditorOrYDoc | null): Y.Doc | undefined {\n if (!editorOrYDoc) return undefined;\n if (isYDoc(editorOrYDoc)) return editorOrYDoc;\n return (editorOrYDoc as { _yDoc?: Y.Doc })._yDoc;\n}\n\nfunction getEditor(editorOrYDoc?: EditorOrYDoc | null): IxoEditorType | undefined {\n return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : undefined;\n}\n\n/**\n * IGNITION PHASE A: run-scoped runtime manager, so every write below\n * dual-writes the run entry and the flat mirror in one transaction.\n *\n * This path is the sharpest instance of why that matters. The read-back\n * failure branches — `state: 'failed'` and the `PROOF_MISSING` branch — are\n * **downgrades from `awaiting_readback`**, and they deliberately do *not*\n * restamp `executedAt`. Written flat-only they are invisible to the freshness\n * predicate in both directions: rule (a) keeps the started run entry, and with\n * no fresher `executedAt` rule (b) never fires either. The run would report\n * `awaiting_readback` with `error: undefined` forever, in a live room, with no\n * repair possible. The proof-failure test in `runs.test.ts` pins exactly this.\n */\nfunction getRuntime(editorOrYDoc?: EditorOrYDoc | null, runtime?: FlowRuntimeStateManager, runId?: string): FlowRuntimeStateManager {\n if (runtime) return runtime;\n const yDoc = getYDoc(editorOrYDoc);\n if (yDoc) return createRunScopedRuntimeManager(yDoc, resolveRunIdForExecution(yDoc, runId));\n return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : undefined);\n}\n\n/**\n * Synthetic editor for `reconcilePendingInvocations` on the headless path.\n * `_yRuntime` is a **read-only, run-scoped** reader — never the raw flat map\n * it used to be. See `actionExecutor.ts#getReconcileEditor`.\n */\nfunction getReconcileEditor(params: ReconcileActionReadBackParams, yDoc: Y.Doc | undefined, editor: IxoEditorType | undefined): IxoEditorType | undefined {\n if (editor) return editor;\n if (!yDoc || !params.document) return undefined;\n return {\n _yDoc: yDoc,\n _yRuntime: createRunRuntimeReaderWithDoc(yDoc, resolveRunIdForExecution(yDoc, params.runId)),\n document: params.document,\n } as unknown as IxoEditorType;\n}\n\n/**\n * Mint the per-execution audit id for a reconciliation record\n * (`RunRecordDetails.runId`). Not the session run — see D2.\n */\nfunction makeExecutionId(now: () => number): string {\n return `readback-${now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction asOutput(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? { ...(value as Record<string, unknown>) } : {};\n}\n\nfunction boundActionEvents(events: NonNullable<ActionResult['events']>): NonNullable<ActionResult['events']> {\n return events.map((event) => ({\n name: event.name,\n payload: boundRunEventJson(event.payload) as Record<string, unknown>,\n }));\n}\n\nfunction errorRecord(error: string | { message: string; code?: string } | undefined): { message: string; code?: string } | undefined {\n if (!error) return undefined;\n return typeof error === 'string' ? { message: error } : { message: error.message, code: error.code };\n}\n\nexport function normalizeActionReadBackMetadata(params: NormalizeReadBackMetadataParams): ActionReadBackMetadata {\n const base = params.readBack && typeof params.readBack === 'object' && !Array.isArray(params.readBack) ? { ...params.readBack } : {};\n const kind = typeof base.kind === 'string' && base.kind.trim() ? base.kind.trim() : params.actionType;\n\n const normalized: ActionReadBackMetadata = {\n ...base,\n kind,\n status: 'pending',\n requestedAt: typeof base.requestedAt === 'string' ? base.requestedAt : new Date(params.requestedAt).toISOString(),\n blockId: params.blockId,\n actionType: params.actionType,\n actorDid: params.actorDid,\n invocationCid: params.invocationCid,\n capabilityId: params.capabilityId,\n };\n\n if (params.pendingInvocation) {\n normalized.pendingInvocation = {\n id: params.pendingInvocation.id,\n triggeringBlockId: params.pendingInvocation.triggeringBlockId,\n eventName: params.pendingInvocation.eventName,\n sourceRunId: params.pendingInvocation.sourceRunId,\n };\n }\n\n return normalized;\n}\n\nfunction writeReconciliationRunRecord(params: {\n yDoc?: Y.Doc;\n editor?: IxoEditorType;\n blockId: string;\n actorDid: string;\n output: Record<string, unknown>;\n events: NonNullable<ActionResult['events']>;\n readBack: ActionReadBackMetadata;\n error?: { message: string; code?: string };\n now: () => number;\n /** Session run (`runs.ts`), recorded additively for Phase B attribution. */\n sessionRunId?: string;\n}): string | undefined {\n if (!params.yDoc) return undefined;\n\n const completedAt = params.now();\n const executionId = makeExecutionId(params.now);\n const pendingInvocation = params.readBack.pendingInvocation;\n const details: RunRecordDetails = {\n runId: executionId,\n sessionRunId: params.sessionRunId,\n output: params.output,\n events: params.events,\n startedAt: params.readBack.requestedAt || new Date(completedAt).toISOString(),\n completedAt: new Date(completedAt).toISOString(),\n actorDid: params.actorDid,\n invocationCid: params.readBack.invocationCid,\n capabilityId: params.readBack.capabilityId,\n error: params.error,\n readBack: params.readBack,\n reconciled: true,\n };\n\n if (pendingInvocation) {\n details.fromPendingInvocationId = pendingInvocation.id;\n details.triggeredBy = {\n sourceBlockId: pendingInvocation.triggeringBlockId,\n eventName: pendingInvocation.eventName,\n };\n details.sourceRunId = pendingInvocation.sourceRunId;\n }\n\n appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);\n if (params.editor && params.events.length > 0) {\n reconcilePendingInvocations(params.editor, params.sessionRunId);\n }\n return executionId;\n}\n\nexport async function reconcileActionReadBack(params: ReconcileActionReadBackParams): Promise<ReconcileActionReadBackResult> {\n const now = params.now || Date.now;\n const yDoc = getYDoc(params.editorOrYDoc);\n const editor = getEditor(params.editorOrYDoc);\n const eventLog = params.runEventLog || editor?._runEventLog;\n const sessionRunId = yDoc ? resolveRunIdForExecution(yDoc, params.runId) : params.runId;\n const runtime = getRuntime(params.editorOrYDoc, params.runtime, sessionRunId);\n const current = runtime.get(params.blockId);\n const output = asOutput(current.output);\n const readBack = current.readBack;\n const timelineRequired = Boolean(yDoc && !usesLegacyRuntimeCompatibility(yDoc));\n\n if (timelineRequired && !eventLog) {\n return {\n success: false,\n blockId: params.blockId,\n state: 'pending',\n output,\n events: [],\n error: 'Read-back was not reconciled because a canonical run event log is required.',\n pendingInvocationRemoved: false,\n readBack,\n };\n }\n\n if (current.state !== 'awaiting_readback' || !readBack?.kind) {\n return {\n success: false,\n blockId: params.blockId,\n state: current.state === 'failed' ? 'failed' : 'pending',\n output,\n events: [],\n error: `Block \"${params.blockId}\" is not awaiting read-back`,\n pendingInvocationRemoved: false,\n readBack,\n };\n }\n\n const resolver = params.resolver || params.resolvers?.[readBack.kind];\n if (!resolver) {\n return {\n success: false,\n blockId: params.blockId,\n state: 'pending',\n output,\n events: [],\n error: `No read-back resolver registered for \"${readBack.kind}\"`,\n pendingInvocationRemoved: false,\n readBack,\n };\n }\n\n const resolution = await resolver({\n blockId: params.blockId,\n runtime: current,\n output,\n readBack,\n });\n const checkedAt = now();\n const checkedIso = new Date(checkedAt).toISOString();\n const nextReadBack: ActionReadBackMetadata = {\n ...readBack,\n ...(resolution.readBack || {}),\n status: resolution.state,\n lastCheckedAt: checkedIso,\n };\n\n if (resolution.state === 'pending') {\n runtime.update(params.blockId, {\n readBack: nextReadBack,\n });\n return {\n success: true,\n blockId: params.blockId,\n state: 'pending',\n output,\n events: resolution.events || [],\n pendingInvocationRemoved: false,\n readBack: nextReadBack,\n };\n }\n\n const events = boundActionEvents(resolution.events || []);\n const mergedOutput = {\n ...output,\n ...(resolution.output || {}),\n };\n const boundedOutput = boundRunActionOutput(mergedOutput);\n const finalOutput = boundedOutput.output;\n const actorDid = params.actorDid || readBack.actorDid || current.executedByDid || 'system:readback';\n\n if (resolution.state === 'failed') {\n const error = errorRecord(resolution.error) || { message: 'External read-back failed' };\n const failedReadBack = {\n ...nextReadBack,\n terminalAt: checkedIso,\n };\n runtime.update(params.blockId, {\n state: 'failed',\n output: finalOutput,\n error: { ...error, at: checkedAt },\n readBack: failedReadBack,\n });\n const executionId = writeReconciliationRunRecord({\n yDoc,\n editor: getReconcileEditor(params, yDoc, editor),\n sessionRunId,\n blockId: params.blockId,\n actorDid,\n output: finalOutput,\n events,\n readBack: failedReadBack,\n error,\n now,\n });\n if (sessionRunId && eventLog) {\n const timelineExecutionId = current.executionId || executionId || readBack.requestedAt || `readback-${checkedAt}`;\n await appendReadBackTimeline(\n eventLog,\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.failed',\n payload: {\n attempt: current.attempt || 1,\n executionId: timelineExecutionId,\n ...(current.executionStartedAt ? { durationMs: Math.max(0, checkedAt - current.executionStartedAt) } : {}),\n error: {\n message: error.message,\n ...(error.code ? { code: error.code } : {}),\n },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n runtime,\n params.blockId,\n now\n );\n }\n return {\n success: false,\n blockId: params.blockId,\n state: 'failed',\n output: finalOutput,\n events,\n error: error.message,\n runId: executionId,\n executionId,\n pendingInvocationRemoved: false,\n readBack: failedReadBack,\n };\n }\n\n // Terminal read-back completion is a `completed` write like any other:\n // the resolver's final output must satisfy the action's proof declaration.\n const readBackActionType = (readBack as { actionType?: string }).actionType || readBack.kind;\n const actionDef = readBackActionType ? getAction(readBackActionType) : undefined;\n if (actionDef) {\n const proofCheck = validateActionProof(actionDef, mergedOutput);\n if (!proofCheck.valid) {\n const message = proofCheck.reason || 'Read-back resolved completed without proof of execution.';\n const proofFailedReadBack = {\n ...nextReadBack,\n terminalAt: checkedIso,\n };\n // Side-effecting proof failure → `needs_verification`, never a silently\n // retryable `failed` (H1). Payload (finalOutput) is already retained.\n runtime.update(params.blockId, {\n state: actionDef.sideEffect ? 'needs_verification' : 'failed',\n output: finalOutput,\n error: { message, code: PROOF_MISSING_CODE, at: checkedAt },\n readBack: proofFailedReadBack,\n });\n const failedExecutionId = writeReconciliationRunRecord({\n yDoc,\n editor: getReconcileEditor(params, yDoc, editor),\n sessionRunId,\n blockId: params.blockId,\n actorDid,\n output: finalOutput,\n events,\n readBack: proofFailedReadBack,\n error: { message, code: PROOF_MISSING_CODE },\n now,\n });\n if (sessionRunId && eventLog) {\n const timelineExecutionId = current.executionId || failedExecutionId || readBack.requestedAt || `readback-${checkedAt}`;\n await appendReadBackTimeline(\n eventLog,\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.failed',\n payload: {\n attempt: current.attempt || 1,\n executionId: timelineExecutionId,\n ...(current.executionStartedAt ? { durationMs: Math.max(0, checkedAt - current.executionStartedAt) } : {}),\n error: { message, code: PROOF_MISSING_CODE },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n runtime,\n params.blockId,\n now\n );\n }\n return {\n success: false,\n blockId: params.blockId,\n state: 'failed',\n output: finalOutput,\n events,\n error: message,\n runId: failedExecutionId,\n executionId: failedExecutionId,\n pendingInvocationRemoved: false,\n readBack: proofFailedReadBack,\n };\n }\n }\n\n if (boundedOutput.exceeded) {\n const message = `Read-back output exceeded the ${MAX_RUN_ACTION_OUTPUT_BYTES / 1024} KiB run-head limit.`;\n const oversizedReadBack = {\n ...nextReadBack,\n terminalAt: checkedIso,\n };\n runtime.update(params.blockId, {\n state: actionDef?.sideEffect === false ? 'failed' : 'needs_verification',\n output: finalOutput,\n error: {\n message,\n code: 'RUN_OUTPUT_TOO_LARGE',\n at: checkedAt,\n data: { byteLength: boundedOutput.byteLength },\n },\n readBack: oversizedReadBack,\n });\n const oversizedExecutionId = writeReconciliationRunRecord({\n yDoc,\n editor: getReconcileEditor(params, yDoc, editor),\n sessionRunId,\n blockId: params.blockId,\n actorDid,\n output: finalOutput,\n events,\n readBack: oversizedReadBack,\n error: { message, code: 'RUN_OUTPUT_TOO_LARGE' },\n now,\n });\n if (sessionRunId && eventLog) {\n const attempt = current.attempt || 1;\n const timelineExecutionId = current.executionId || oversizedExecutionId || readBack.requestedAt || `readback-${checkedAt}`;\n await appendRunTimelineEvents({\n eventLog,\n events: [\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.output',\n payload: {\n attempt,\n executionId: timelineExecutionId,\n output: boundRunEventJson(finalOutput),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.output', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.failed',\n payload: {\n attempt,\n executionId: timelineExecutionId,\n ...(current.executionStartedAt\n ? {\n durationMs: Math.max(0, checkedAt - current.executionStartedAt),\n }\n : {}),\n error: {\n message,\n code: 'RUN_OUTPUT_TOO_LARGE',\n details: {\n byteLength: boundedOutput.byteLength,\n maxBytes: MAX_RUN_ACTION_OUTPUT_BYTES,\n },\n },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n ],\n runtime,\n blockId: params.blockId,\n now,\n });\n }\n return {\n success: false,\n blockId: params.blockId,\n state: 'failed',\n output: finalOutput,\n events,\n error: message,\n runId: oversizedExecutionId,\n executionId: oversizedExecutionId,\n pendingInvocationRemoved: false,\n readBack: oversizedReadBack,\n };\n }\n\n const completedReadBack = {\n ...nextReadBack,\n terminalAt: checkedIso,\n };\n runtime.update(params.blockId, {\n state: 'completed',\n output: finalOutput,\n executedAt: checkedAt,\n error: undefined,\n readBack: completedReadBack,\n });\n const executionId = writeReconciliationRunRecord({\n yDoc,\n editor: getReconcileEditor(params, yDoc, editor),\n sessionRunId,\n blockId: params.blockId,\n actorDid,\n output: finalOutput,\n events,\n readBack: completedReadBack,\n now,\n });\n let timelineComplete = true;\n if (sessionRunId && eventLog) {\n const attempt = current.attempt || 1;\n const timelineExecutionId = current.executionId || executionId || readBack.requestedAt || `readback-${checkedAt}`;\n const timelineResult = await appendRunTimelineEvents({\n eventLog,\n events: [\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.output',\n payload: {\n attempt,\n executionId: timelineExecutionId,\n output: boundRunEventJson(finalOutput),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.output', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n {\n runId: sessionRunId,\n blockId: params.blockId,\n kind: 'action.done',\n payload: {\n attempt,\n executionId: timelineExecutionId,\n ...(current.executionStartedAt\n ? {\n durationMs: Math.max(0, checkedAt - current.executionStartedAt),\n }\n : {}),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.done', sessionRunId, params.blockId, timelineExecutionId, 'readback'),\n ts: checkedAt,\n },\n ],\n runtime,\n blockId: params.blockId,\n now,\n });\n timelineComplete = timelineResult.ok && timelineResult.remaining === 0;\n }\n const pendingInvocationRemoved =\n timelineComplete &&\n Boolean(yDoc && completedReadBack.pendingInvocation?.id) &&\n removePendingInvocation(yDoc!, params.blockId, completedReadBack.pendingInvocation!.id, sessionRunId);\n\n return {\n success: timelineComplete,\n blockId: params.blockId,\n state: 'completed',\n output: finalOutput,\n events,\n ...(!timelineComplete ? { error: 'Canonical run history replay remains incomplete.' } : {}),\n runId: executionId,\n executionId,\n pendingInvocationRemoved,\n readBack: completedReadBack,\n };\n}\n","import * as Y from 'yjs';\nimport { getAction } from '../actionRegistry';\nimport type { ActionHandlers, ActionResult, ActionServices, TopicActionRecord, TopicExecutionContext } from '../actionRegistry/types';\nimport type { TopicActionBridge, TopicActionReceiptStatus, TopicActionWriteBackResult } from '../topicActions';\nimport type { InvocationStore } from '../invocationStore';\nimport { resolveRuntimeRefs, type TriggerResolutionContext } from '../flowCompiler/resolveRefs';\nimport type { UcanService } from '../../services/ucanService';\nimport type { FlowNodeRuntimeState, NodeState } from '../../types/authorization';\nimport type { FlowRuntimeStateManager } from './runtime';\nimport { createRuntimeStateManager } from './runtime';\nimport { assertRunActionExecutionAllowed, createRunRuntimeReaderWithDoc, createRunScopedRuntimeManager, resolveRunIdForExecution, usesLegacyRuntimeCompatibility } from './runs';\nimport { executeNode, type ExecutionOutcome, type NodeActionResult } from './executor';\nimport { reconcilePendingInvocations } from './reconcile';\nimport { appendRunRecord, readPendingInvocations, removePendingInvocation, type PendingInvocation, type RunRecordDetails } from './triggers';\nimport { buildFlowNodeFromBlock } from './utils';\nimport { normalizeActionReadBackMetadata } from './readBackReconciler';\nimport { PROOF_MISSING_CODE, validateActionProof } from './proof';\nimport { warnOnce } from '../warnOnce';\nimport { isYDocLike } from '../yjsTypes';\nimport type { IxoEditorType } from '../../types/editor';\nimport { buildRunDefinitionSnapshot, computeRunSummary, type RunEventAppender, type RunEventInput } from './runLifecycle';\nimport { appendRunTimelineEvent, appendRunTimelineEvents, boundRunActionOutput, boundRunEventJson, createRunEventIdempotencyKey, MAX_RUN_ACTION_OUTPUT_BYTES } from './runTimeline';\nimport { evaluateBlockExecutionEligibilityForRun, parseConditionConfigStrict } from './conditions';\nimport { digestDesignPodValue } from '../designPod/digest';\nimport { canonicalDesignPodJson } from '../designPod/digest';\nimport { DESIGN_POD_METHODS } from '../designPod/contracts';\nimport { readDesignPodDefinition, readDesignPodState } from '../designPod/state';\nimport type { DesignPodRuntimeAuthorityV1 } from '../designPod/contracts';\n\nexport type ActionBlockLike = {\n id?: string;\n props?: Record<string, unknown>;\n};\n\ntype EditorOrYDoc = IxoEditorType | Y.Doc;\n\nexport interface BuildActionRunInputsParams {\n editorOrYDoc?: EditorOrYDoc | null;\n block?: ActionBlockLike | null;\n blockId?: string;\n document?: ActionBlockLike[];\n runtime?: FlowRuntimeStateManager;\n savedInputs?: unknown;\n runtimeInputs?: Record<string, unknown>;\n pendingInvocationId?: string;\n /**\n * The **session run** this execution belongs to (`runs.ts`), not the\n * per-execution audit id. Defaults to `resolveActiveRunId(yDoc)`, which is a\n * constant in Phase A.\n *\n * D2: every *new* parameter named `runId` means the session run. The\n * execution-scoped id keeps its historical name only where it is already\n * persisted (`RunRecordDetails.runId`), and is surfaced going forward as\n * {@link ExecuteActionBlockResult.executionId}.\n */\n runId?: string;\n}\n\nexport interface BuildActionRunInputsResult {\n inputs: Record<string, unknown>;\n savedInputs: Record<string, unknown>;\n mergedInputs: Record<string, unknown>;\n pendingInvocation?: PendingInvocation;\n triggerContext?: TriggerResolutionContext;\n}\n\nexport type ActionExecutionCompletionState = 'completed' | 'failed' | 'awaiting_readback' | 'needs_verification';\n\nexport interface ExecuteActionBlockParams extends BuildActionRunInputsParams {\n actorDid: string;\n actorType: 'entity' | 'user';\n entityRoomId?: string;\n ucanService?: UcanService;\n invocationStore?: InvocationStore;\n services?: ActionServices;\n handlers?: ActionHandlers;\n runEventLog?: RunEventAppender;\n pin?: string;\n now?: () => number;\n flowUri?: string;\n flowId?: string;\n flowOwnerDid?: string;\n schemaVersion?: string;\n /** Optional revision-bound Topic context; never substitutes for Flow authority. */\n topic?: TopicExecutionContext;\n /** Durable receipt bridge, supplied only after independent Topic UCAN verification. */\n topicBridge?: TopicActionBridge;\n /** DID of the runtime provider/controller issuing Topic receipts. */\n executorDid?: string;\n /** Pinned Flow revision or digest used by Topic bindings and receipts. */\n flowRevision?: string;\n /** Portal-owned entity/room/session authority for Design POD actions. */\n designPodAuthority?: DesignPodRuntimeAuthorityV1;\n}\n\nexport interface ExecuteActionBlockResult {\n success: boolean;\n stage: ExecutionOutcome['stage'] | 'input' | 'action_lookup';\n blockId: string;\n actionType?: string;\n output?: Record<string, unknown>;\n events: NonNullable<ActionResult['events']>;\n error?: string;\n invocationCid?: string;\n capabilityId?: string;\n /**\n * Id of the audit record this execution wrote (`run-<ts>-<rand>`).\n *\n * @deprecated Use {@link ExecuteActionBlockResult.executionId}. Both fields\n * carry the same value and both stay populated — `flow-manager` and\n * `flow-agent` read `runId` today, and `RunRecordDetails.runId` is persisted\n * live data feeding `computePendingInvocationId`, so the *stored* name is\n * never renamed.\n *\n * PHASE A COMPAT — REMOVAL TRIGGER: Phase B, once both orchestrators read\n * `executionId` (compat register item 8).\n */\n runId?: string;\n /**\n * Forward name for the per-execution audit id. Identical to {@link runId}.\n *\n * D2: bare `runId` now means the *session* run everywhere in new code, so the\n * execution id gets an unambiguous name rather than the persisted one being\n * renamed out from under live rooms.\n */\n executionId?: string;\n pendingInvocationRemoved?: boolean;\n completionState: ActionExecutionCompletionState;\n pendingInvocation?: PendingInvocation;\n topicWriteBack?: TopicActionWriteBackResult;\n}\n\nconst COMPACT_TIMELINE_ACTION_TYPES = new Set<string>(DESIGN_POD_METHODS['design-yoma/v1'].operationalActions);\n\n/** Keep governed Design POD and youth-operation event inputs free of artifact bodies and participant data. */\nexport function buildActionTimelineInput(actionType: string, inputs: Record<string, unknown>, inputDigest: string): Record<string, unknown> {\n if (actionType.startsWith('qi/blueprint.') || COMPACT_TIMELINE_ACTION_TYPES.has(actionType)) return { inputDigest };\n return inputs;\n}\n\nfunction isYDoc(value: unknown): value is Y.Doc {\n return isYDocLike(value);\n}\n\nfunction getYDoc(editorOrYDoc?: EditorOrYDoc | null): Y.Doc | undefined {\n if (!editorOrYDoc) return undefined;\n if (isYDoc(editorOrYDoc)) return editorOrYDoc;\n return (editorOrYDoc as { _yDoc?: Y.Doc })._yDoc;\n}\n\nfunction parseInputs(value: unknown): Record<string, unknown> {\n if (value == null || value === '') return {};\n if (typeof value === 'object' && !Array.isArray(value)) return { ...(value as Record<string, unknown>) };\n if (typeof value !== 'string') return {};\n\n try {\n const parsed = JSON.parse(value);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};\n } catch {\n warnOnce(`executor-inputs-parse:${value}`, `[flow-config] saved block inputs are not valid JSON; treated as empty`);\n return {};\n }\n}\n\n/**\n * IGNITION PHASE A: resolve the runtime manager for a session run.\n *\n * When a Y.Doc is reachable this is the run-scoped manager, so every\n * `runtime.update(...)` below — including the `needs_verification` /\n * `PROOF_MISSING` write, which is a *downgrade* — lands in the run entry and\n * the flat mirror in one transaction. A downgrade written flat-only can never\n * be materialised into the run (the freshness predicate refuses it), which is\n * precisely the state that strands forever once adoption is on (§9.3).\n */\nfunction getRuntime(editorOrYDoc?: EditorOrYDoc | null, runtime?: FlowRuntimeStateManager, runId?: string): FlowRuntimeStateManager {\n if (runtime) return runtime;\n const yDoc = getYDoc(editorOrYDoc);\n if (yDoc) {\n return createRunScopedRuntimeManager(yDoc, resolveRunIdForExecution(yDoc, runId));\n }\n return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : undefined);\n}\n\nfunction getEditor(editorOrYDoc?: EditorOrYDoc | null): IxoEditorType | undefined {\n return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : undefined;\n}\n\nfunction findBlock(params: Pick<ExecuteActionBlockParams, 'block' | 'blockId' | 'editorOrYDoc' | 'document'>): ActionBlockLike | undefined {\n if (params.block) return params.block;\n const blockId = params.blockId;\n if (!blockId) return undefined;\n const editor = getEditor(params.editorOrYDoc);\n const visit = (blocks: ActionBlockLike[]): ActionBlockLike | undefined => {\n for (const block of blocks) {\n if (block?.id === blockId) return block;\n const nested = (block as ActionBlockLike & { children?: ActionBlockLike[] })?.children;\n if (Array.isArray(nested)) {\n const found = visit(nested);\n if (found) return found;\n }\n }\n return undefined;\n };\n return visit(params.document || (editor?.document as ActionBlockLike[]) || []);\n}\n\nfunction getFlowMetadata(editor?: IxoEditorType): { flowId: string; flowUri: string; flowOwnerDid: string; schemaVersion: string } {\n const metadata = editor?.getFlowMetadata?.();\n const flowId = metadata?.doc_id || '';\n return {\n flowId,\n flowUri: flowId ? `ixo:flow:${flowId}` : '',\n flowOwnerDid: editor?.getFlowOwnerDid?.() || metadata?.flowOwnerDid || '',\n schemaVersion: metadata?.schema_version || '0.3',\n };\n}\n\nfunction getPendingInvocation(yDoc: Y.Doc | undefined, blockId: string | undefined, pendingInvocationId: string | undefined, sessionRunId?: string): PendingInvocation | undefined {\n if (!pendingInvocationId) return undefined;\n if (!yDoc) {\n throw new Error(`Cannot load pending invocation \"${pendingInvocationId}\" without a Y.Doc`);\n }\n if (!blockId) {\n throw new Error(`Cannot load pending invocation \"${pendingInvocationId}\" without a block id`);\n }\n\n const pending = readPendingInvocations(yDoc, blockId, sessionRunId).find((invocation) => invocation.id === pendingInvocationId);\n if (!pending) {\n throw new Error(`Pending invocation \"${pendingInvocationId}\" was not found for block \"${blockId}\"`);\n }\n return pending;\n}\n\nfunction getNodeOutput(runtime: FlowRuntimeStateManager, nodeId: string): Record<string, unknown> | undefined {\n const state = runtime.get(nodeId);\n const output = state.output;\n return output && typeof output === 'object' && !Array.isArray(output) ? output : undefined;\n}\n\nexport function buildActionRunInputs(params: BuildActionRunInputsParams): BuildActionRunInputsResult {\n const blockId = params.blockId || params.block?.id;\n const yDoc = getYDoc(params.editorOrYDoc);\n const runtime = getRuntime(params.editorOrYDoc, params.runtime, params.runId);\n const savedInputs = parseInputs(params.savedInputs ?? params.block?.props?.inputs);\n const pendingInvocation = getPendingInvocation(yDoc, blockId, params.pendingInvocationId, params.runId);\n\n const triggerContext = pendingInvocation\n ? {\n payload: pendingInvocation.payload || {},\n refSnapshots: pendingInvocation.refSnapshots || {},\n }\n : undefined;\n\n const mergedInputs = {\n ...savedInputs,\n ...(pendingInvocation?.payload || {}),\n ...(pendingInvocation?.refSnapshots || {}),\n ...(params.runtimeInputs || {}),\n };\n\n return {\n inputs: resolveRuntimeRefs(mergedInputs, (nodeId) => getNodeOutput(runtime, nodeId), triggerContext),\n savedInputs,\n mergedInputs,\n pendingInvocation,\n triggerContext,\n };\n}\n\nfunction buildFailureResult(params: {\n blockId: string;\n actionType?: string;\n stage: ExecuteActionBlockResult['stage'];\n error: string;\n pendingInvocation?: PendingInvocation;\n}): ExecuteActionBlockResult {\n return {\n success: false,\n stage: params.stage,\n blockId: params.blockId,\n actionType: params.actionType,\n events: [],\n error: params.error,\n completionState: 'failed',\n pendingInvocation: params.pendingInvocation,\n };\n}\n\nfunction updateRuntimeFailure(runtime: FlowRuntimeStateManager, blockId: string, message: string, now: () => number): void {\n runtime.update(blockId, {\n state: 'failed',\n error: { message, at: now() },\n } as Partial<FlowNodeRuntimeState>);\n}\n\n/**\n * Mint the **per-execution audit id** (`RunRecordDetails.runId`).\n *\n * D2: this is the pre-existing meaning of `runId` in this codebase and it is\n * load-bearing — it is the `sourceRunId` component of\n * `computePendingInvocationId`, a deterministic hash over live data. The format\n * and the persisted field name must not change. New code calls it the\n * *execution* id to keep `runId` free for the session run.\n */\nfunction makeExecutionId(now: () => number): string {\n return `run-${now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * The synthetic editor handed to `reconcilePendingInvocations` on the headless\n * path.\n *\n * `_yRuntime` used to be `yDoc.getMap('runtime')` — a raw flat-map handle that\n * `reconcile.ts` both read and wrote through, i.e. a runtime writer outside the\n * waist that no grep for `runtimeMap.set` in this file would ever surface. It\n * is now a **read-only, run-scoped** reader (`runs.ts`); reconciliation writes\n * through `writeActionState` against the doc instead.\n */\nfunction getReconcileEditor(params: ExecuteActionBlockParams, yDoc: Y.Doc | undefined, editor: IxoEditorType | undefined): IxoEditorType | undefined {\n if (editor) return editor;\n if (!yDoc || !params.document) return undefined;\n return {\n _yDoc: yDoc,\n _yRuntime: createRunRuntimeReaderWithDoc(yDoc, resolveRunIdForExecution(yDoc, params.runId)),\n document: params.document,\n } as unknown as IxoEditorType;\n}\n\nfunction persistEvents(params: {\n yDoc?: Y.Doc;\n editor?: IxoEditorType;\n blockId: string;\n actorDid: string;\n output: Record<string, unknown>;\n events: NonNullable<ActionResult['events']>;\n invocationCid?: string;\n capabilityId?: string;\n pendingInvocation?: PendingInvocation;\n startedAt: number;\n completedAt: number;\n now: () => number;\n executionId: string;\n /** Session run (`runs.ts`), recorded additively for Phase B attribution. */\n sessionRunId?: string;\n}): string | undefined {\n if (!params.yDoc || params.events.length === 0) return undefined;\n\n const details: RunRecordDetails = {\n runId: params.executionId,\n sessionRunId: params.sessionRunId,\n output: params.output,\n events: params.events,\n startedAt: new Date(params.startedAt).toISOString(),\n completedAt: new Date(params.completedAt).toISOString(),\n actorDid: params.actorDid,\n invocationCid: params.invocationCid,\n capabilityId: params.capabilityId,\n };\n\n if (params.pendingInvocation) {\n details.fromPendingInvocationId = params.pendingInvocation.id;\n details.triggeredBy = {\n sourceBlockId: params.pendingInvocation.triggeringBlockId,\n eventName: params.pendingInvocation.eventName,\n };\n details.sourceRunId = params.pendingInvocation.sourceRunId;\n }\n\n appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);\n if (params.editor) {\n reconcilePendingInvocations(params.editor, params.sessionRunId);\n }\n return params.executionId;\n}\n\nfunction cleanupCompletedPendingInvocation(yDoc: Y.Doc | undefined, blockId: string, pendingInvocation: PendingInvocation | undefined, sessionRunId?: string): boolean {\n if (!yDoc || !pendingInvocation) return false;\n return removePendingInvocation(yDoc, blockId, pendingInvocation.id, sessionRunId || pendingInvocation.sessionRunId);\n}\n\nexport async function executeActionBlock(params: ExecuteActionBlockParams): Promise<ExecuteActionBlockResult> {\n const block = findBlock(params);\n const blockId = params.blockId || block?.id;\n const editor = getEditor(params.editorOrYDoc);\n const yDoc = getYDoc(params.editorOrYDoc);\n const now = params.now || Date.now;\n const eventLog = params.runEventLog || editor?._runEventLog;\n\n if (!block || !blockId) {\n return buildFailureResult({\n blockId: blockId || '',\n stage: 'input',\n error: blockId ? `Block \"${blockId}\" was not found` : 'executeActionBlock requires a blockId or block',\n });\n }\n\n let sessionRunId = params.runId;\n try {\n if (yDoc) {\n sessionRunId = resolveRunIdForExecution(yDoc, params.runId);\n assertRunActionExecutionAllowed(yDoc, sessionRunId, block);\n }\n } catch (error) {\n return buildFailureResult({\n blockId,\n stage: 'input',\n error: error instanceof Error ? error.message : 'The requested session run cannot execute this action.',\n });\n }\n\n const runtime = getRuntime(params.editorOrYDoc, params.runtime, sessionRunId);\n\n const actionType = typeof block.props?.actionType === 'string' ? block.props.actionType : undefined;\n if (!actionType) {\n updateRuntimeFailure(runtime, blockId, 'Action block is missing props.actionType', now);\n return buildFailureResult({\n blockId,\n stage: 'input',\n error: 'Action block is missing props.actionType',\n });\n }\n\n const action = getAction(actionType);\n if (!action) {\n const message = `No registered action found for ${actionType}`;\n updateRuntimeFailure(runtime, blockId, message, now);\n return buildFailureResult({ blockId, actionType, stage: 'action_lookup', error: message });\n }\n\n if (yDoc && sessionRunId) {\n const document = params.document || (editor?.document as ActionBlockLike[]) || [block];\n let eligibility;\n try {\n eligibility = evaluateBlockExecutionEligibilityForRun(parseConditionConfigStrict(block.props?.conditions), document, yDoc, sessionRunId);\n } catch (error) {\n return buildFailureResult({\n blockId,\n actionType,\n stage: 'input',\n error: error instanceof Error ? error.message : 'Block conditions are invalid.',\n });\n }\n if (!eligibility.eligible) {\n return buildFailureResult({\n blockId,\n actionType,\n stage: 'input',\n error: eligibility.message || 'Block conditions are not satisfied.',\n });\n }\n }\n\n let inputBuild: BuildActionRunInputsResult;\n try {\n inputBuild = buildActionRunInputs({ ...params, block, blockId, runtime });\n if (\n actionType.startsWith('qi/blueprint.') &&\n !['qi/blueprint.workspace-start', 'qi/blueprint.journey-resume', 'qi/blueprint.guided-authoring', 'qi/blueprint.phase-confirm'].includes(actionType)\n ) {\n const authority = params.designPodAuthority;\n if (!authority || !sessionRunId || authority.sessionRunId !== sessionRunId) {\n throw new Error('Portal-owned Design Project entity, Flow room, and session authority are required');\n }\n if (!yDoc) throw new Error('Portal-native Design POD actions require the active Flow Y.Doc');\n const manifest = readDesignPodDefinition(yDoc);\n const state = readDesignPodState(yDoc);\n const registeredManifest = manifest && DESIGN_POD_METHODS[manifest.methodId];\n if (!manifest || !state || !registeredManifest || canonicalDesignPodJson(manifest) !== canonicalDesignPodJson(registeredManifest)) {\n throw new Error('The active Design POD method is not the registered Portal method');\n }\n inputBuild.inputs = {\n ...inputBuild.inputs,\n designProjectEntityDid: authority.designProjectEntityDid,\n flowRoomId: authority.flowRoomId,\n sessionRunId: authority.sessionRunId,\n methodManifestDigest: await digestDesignPodValue(registeredManifest),\n };\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to build action inputs';\n updateRuntimeFailure(runtime, blockId, message, now);\n return buildFailureResult({ blockId, actionType, stage: 'input', error: message });\n }\n\n const flowNode = buildFlowNodeFromBlock(block);\n const metadata = getFlowMetadata(editor);\n // Design POD authority comes from the Portal/Matrix envelope, never from\n // mutable Flow metadata. The collaborative root is checked separately as a\n // consistency witness by every governed Design POD action.\n const flowId = params.designPodAuthority?.flowRoomId || params.flowId || metadata.flowId || blockId;\n const flowUri = params.designPodAuthority ? `ixo:flow:${params.designPodAuthority.flowRoomId}` : params.flowUri || metadata.flowUri || `ixo:flow:${flowId}`;\n const flowOwnerDid = params.designPodAuthority?.flowOwnerDid || params.flowOwnerDid || metadata.flowOwnerDid;\n const schemaVersion = params.schemaVersion || metadata.schemaVersion;\n if (actionType === 'qi/flow.run.close' && yDoc && sessionRunId) {\n const document = params.document || (editor?.document as ActionBlockLike[]) || [block];\n inputBuild.inputs = {\n ...inputBuild.inputs,\n // Bind the exact completion projection into the signed invocation. The\n // lifecycle re-computes it before append and rejects any Matrix event\n // whose payload differs from these signed inputs.\n terminalSummary: computeRunSummary(yDoc, sessionRunId, buildRunDefinitionSnapshot(document).actionTypes, {\n flowId: flowUri,\n actorDid: params.actorDid,\n now: now(),\n }),\n };\n }\n const events: NonNullable<ActionResult['events']> = [];\n let completionState: ActionExecutionCompletionState = 'completed';\n let readBack: Record<string, unknown> | undefined;\n let rawReadBack: Record<string, unknown> | undefined;\n let requestedAwaitingReadBack = false;\n let proofFailureReason: string | null = null;\n let proofFailureOutput: Record<string, unknown> | undefined;\n let topicRecords: TopicActionRecord[] = [];\n let terminalRaceError: string | null = null;\n const startedAt = now();\n const previousState = runtime.get(blockId);\n const attempt = (previousState.attempt || 0) + 1;\n const executionId = makeExecutionId(now);\n const inputDigest = await digestDesignPodValue(inputBuild.inputs);\n const invocationFacts = {\n actionType,\n inputDigest,\n ...(sessionRunId ? { sessionRunId } : {}),\n };\n\n const recordTopicPhase = async (\n status: TopicActionReceiptStatus,\n options: { output?: Record<string, unknown>; error?: { code?: string; message: string }; invocationReference?: string } = {}\n ): Promise<TopicActionWriteBackResult | undefined> => {\n if (!params.topic || !params.topicBridge) return undefined;\n try {\n return await params.topicBridge.recordFlowPhase({\n topic: params.topic,\n actionType,\n actorDid: params.actorDid,\n executorDid: params.executorDid || params.actorDid,\n executionId,\n status,\n input: inputBuild.inputs,\n output: options.output,\n semanticRecords: topicRecords,\n flowUri,\n sessionRunId,\n nodeId: blockId,\n invocationReference: options.invocationReference,\n traceReference: sessionRunId ? `${flowUri}/session/${sessionRunId}/execution/${executionId}` : `${flowUri}/execution/${executionId}`,\n error: options.error,\n });\n } catch (error) {\n return { state: 'queued', error: error instanceof Error ? error.message : 'Topic receipt bridge failed' };\n }\n };\n\n const timelineRequired = !!yDoc && !usesLegacyRuntimeCompatibility(yDoc);\n if (sessionRunId && (eventLog || timelineRequired)) {\n const startedLogged = await appendRunTimelineEvent({\n eventLog,\n event: {\n runId: sessionRunId,\n blockId,\n kind: 'action.started',\n payload: {\n attempt,\n executionId,\n input: boundRunEventJson(buildActionTimelineInput(actionType, inputBuild.inputs, inputDigest)),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.started', sessionRunId, blockId, executionId),\n ts: startedAt,\n },\n runtime,\n blockId,\n retainOnFailure: false,\n now,\n });\n if (!startedLogged.ok) {\n const message = 'Action was not executed because its run timeline could not be opened.';\n runtime.update(blockId, {\n state: 'failed',\n error: {\n message,\n code: 'RUN_EVENT_APPEND_FAILED',\n at: now(),\n data: startedLogged.error,\n },\n });\n return {\n ...buildFailureResult({ blockId, actionType, stage: 'action', error: message, pendingInvocation: inputBuild.pendingInvocation }),\n executionId,\n runId: executionId,\n };\n }\n }\n\n if (yDoc && sessionRunId) {\n try {\n // The Matrix append above is asynchronous. A completed action can be\n // retried while another client closes the run from its prior completed\n // state, so recheck before changing runtime state or preparing UCAN.\n assertRunActionExecutionAllowed(yDoc, sessionRunId, block);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'The requested session became terminal before this action could execute.';\n return {\n ...buildFailureResult({ blockId, actionType, stage: 'action', error: message, pendingInvocation: inputBuild.pendingInvocation }),\n executionId,\n runId: executionId,\n };\n }\n }\n\n runtime.update(blockId, {\n state: 'running',\n output: undefined,\n error: undefined,\n executedByDid: params.actorDid,\n attempt,\n executionId,\n executionStartedAt: startedAt,\n } as Partial<FlowNodeRuntimeState>);\n\n const runningWriteBack = await recordTopicPhase('running');\n if (runningWriteBack?.state === 'rejected') {\n const message = runningWriteBack.error || 'Topic Action execution was rejected by the receipt bridge.';\n updateRuntimeFailure(runtime, blockId, message, now);\n return {\n ...buildFailureResult({ blockId, actionType, stage: 'authorization', error: message, pendingInvocation: inputBuild.pendingInvocation }),\n executionId,\n runId: executionId,\n topicWriteBack: runningWriteBack,\n };\n }\n\n // Topic mutation authority is a separate host grant. Only the explicit\n // Topic-native operation family can see the append/read service; every\n // other Action receives Topic context for receipts but no mutation port.\n const actionServices: ActionServices = action.type.startsWith('qi/topic.') ? params.services || {} : { ...(params.services || {}), topic: undefined };\n\n const outcome = await executeNode({\n node: flowNode,\n actorDid: params.actorDid,\n actorType: params.actorType,\n entityRoomId: params.entityRoomId,\n context: {\n runtime,\n ucanService: params.ucanService || editor?.getUcanService?.() || undefined,\n invocationStore: params.invocationStore || editor?._invocationStore,\n flowUri,\n flowId,\n sessionRunId,\n flowOwnerDid,\n schemaVersion,\n now,\n },\n invocationFacts,\n requireSignedInvocation: action.requiresSignedInvocation === true,\n action: async (executionProof): Promise<NodeActionResult> => {\n if (yDoc && sessionRunId) {\n try {\n // Runtime is already `running`, which is the execution reservation\n // closure folds into readiness. This final check is defense in depth\n // immediately before the handler may perform a side effect.\n assertRunActionExecutionAllowed(yDoc, sessionRunId, block);\n } catch (error) {\n terminalRaceError = error instanceof Error ? error.message : 'The requested session became terminal before this action could execute.';\n throw error;\n }\n }\n const result = await action.run(inputBuild.inputs, {\n actorDid: params.actorDid,\n flowId,\n sessionRunId,\n designPodAuthority: params.designPodAuthority,\n flowUri,\n nodeId: blockId,\n flowNode,\n runtime,\n services: actionServices,\n runEventLog: params.runEventLog,\n handlers: params.handlers,\n editor,\n yDoc,\n pendingInvocation: inputBuild.pendingInvocation,\n topic: params.topic,\n flowRevision: params.flowRevision,\n ...(executionProof.invocationCid\n ? {\n executionProof: {\n invocationCid: executionProof.invocationCid,\n invocation: executionProof.invocation,\n capabilityId: executionProof.capabilityId,\n proofCids: executionProof.proofCids,\n capability: executionProof.capability,\n facts: executionProof.facts,\n inputDigest,\n },\n }\n : {}),\n });\n if (result.events?.length) events.push(...result.events);\n if (result.topicRecords?.length) topicRecords = result.topicRecords;\n if (result.completion?.state === 'awaiting_readback') {\n requestedAwaitingReadBack = true;\n rawReadBack = result.completion.readBack;\n } else {\n // Proof guard runs inside the action callback so that a proofless\n // success is recorded as a FAILED invocation by executeNode's catch\n // path — never as a success invocation followed by a failed runtime.\n const proofCheck = validateActionProof(action, (result.output as Record<string, unknown>) || {});\n if (!proofCheck.valid) {\n proofFailureReason = proofCheck.reason || 'Action returned success without proof of execution.';\n // Keep the handler payload: for a side-effecting action this is the\n // only evidence the effect may have happened (H1). It is retained on\n // runtime.output below instead of being discarded.\n proofFailureOutput = (result.output as Record<string, unknown>) || {};\n throw new Error(proofFailureReason);\n }\n }\n return {\n payload: result.output,\n submittedByDid: params.actorDid || undefined,\n };\n },\n pin: params.pin || '',\n });\n\n if (!outcome.success) {\n const message = outcome.error || 'Action execution failed';\n if (terminalRaceError) {\n return {\n ...buildFailureResult({ blockId, actionType, stage: outcome.stage, error: terminalRaceError, pendingInvocation: inputBuild.pendingInvocation }),\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n executionId,\n runId: executionId,\n };\n }\n if (proofFailureReason) {\n // A side-effecting action that ran but couldn't prove it did is NOT a\n // clean failure: the effect may have happened (e.g. an on-chain tx that\n // landed under a differently-named field), so it must never be silently\n // auto-retried — that would double-execute. Route it to the\n // `needs_verification` dead-end and RETAIN the handler payload as\n // evidence for the human/automated verifier. A non-side-effecting proof\n // failure stays `failed` — re-running it is harmless. See H1.\n const proofFailureState: NodeState = action.sideEffect ? 'needs_verification' : 'failed';\n const boundedProofFailure = boundRunActionOutput(proofFailureOutput || {});\n runtime.update(blockId, {\n state: proofFailureState,\n output: boundedProofFailure.output,\n error: { message, code: PROOF_MISSING_CODE, at: now() },\n } as Partial<FlowNodeRuntimeState>);\n if (sessionRunId && (eventLog || timelineRequired)) {\n await appendRunTimelineEvent({\n eventLog,\n event: {\n runId: sessionRunId,\n blockId,\n kind: 'action.failed',\n payload: {\n attempt,\n executionId,\n durationMs: Math.max(0, now() - startedAt),\n error: { message, code: PROOF_MISSING_CODE },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, blockId, executionId),\n ts: now(),\n },\n runtime,\n blockId,\n now,\n });\n }\n return {\n ...buildFailureResult({\n blockId,\n actionType,\n stage: outcome.stage,\n error: message,\n pendingInvocation: inputBuild.pendingInvocation,\n }),\n completionState: proofFailureState === 'needs_verification' ? 'needs_verification' : 'failed',\n output: proofFailureOutput,\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n executionId,\n runId: executionId,\n topicWriteBack: await recordTopicPhase(proofFailureState === 'needs_verification' ? 'needs_verification' : 'failed', {\n output: proofFailureOutput,\n error: { code: PROOF_MISSING_CODE, message },\n invocationReference: outcome.invocationCid || outcome.capabilityId,\n }),\n };\n }\n if (outcome.stage === 'authorization') {\n // The action never ran: authorization / signing / PIN failed before\n // execution. Nothing governed happened, so a transient user error must\n // not be persisted into the room — restore the prior runtime entry and\n // surface the error locally through the returned failure result only.\n runtime.update(blockId, {\n state: previousState.state,\n output: previousState.output,\n error: previousState.error,\n executedByDid: previousState.executedByDid,\n attempt: previousState.attempt,\n executionId: previousState.executionId,\n executionStartedAt: previousState.executionStartedAt,\n } as Partial<FlowNodeRuntimeState>);\n return {\n ...buildFailureResult({\n blockId,\n actionType,\n stage: outcome.stage,\n error: message,\n pendingInvocation: inputBuild.pendingInvocation,\n }),\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n executionId,\n runId: executionId,\n };\n }\n updateRuntimeFailure(runtime, blockId, message, now);\n if (sessionRunId && (eventLog || timelineRequired)) {\n await appendRunTimelineEvent({\n eventLog,\n event: {\n runId: sessionRunId,\n blockId,\n kind: 'action.failed',\n payload: {\n attempt,\n executionId,\n durationMs: Math.max(0, now() - startedAt),\n error: { message },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, blockId, executionId),\n ts: now(),\n },\n runtime,\n blockId,\n now,\n });\n }\n // Authorization failures returned above, deliberately without a topic\n // write-back — nothing governed happened, so nothing is persisted.\n const topicWriteBack = await recordTopicPhase('failed', {\n error: { message },\n invocationReference: outcome.invocationCid || outcome.capabilityId,\n });\n return {\n ...buildFailureResult({\n blockId,\n actionType,\n stage: outcome.stage,\n error: message,\n pendingInvocation: inputBuild.pendingInvocation,\n }),\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n executionId,\n runId: executionId,\n topicWriteBack,\n };\n }\n\n const output = (outcome.result?.payload || {}) as Record<string, unknown>;\n const boundedOutput = boundRunActionOutput(output);\n const completedAt = now();\n if (requestedAwaitingReadBack) {\n completionState = 'awaiting_readback';\n readBack = normalizeActionReadBackMetadata({\n readBack: rawReadBack,\n blockId,\n actionType,\n actorDid: params.actorDid,\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n requestedAt: startedAt,\n pendingInvocation: inputBuild.pendingInvocation,\n });\n }\n if (boundedOutput.exceeded) {\n completionState = action.sideEffect ? 'needs_verification' : 'failed';\n }\n runtime.update(blockId, {\n state: completionState,\n output: boundedOutput.output,\n executedByDid: params.actorDid,\n executedAt: completedAt,\n lastInvocationCid: outcome.invocationCid || outcome.capabilityId,\n readBack,\n ...(boundedOutput.exceeded\n ? {\n error: {\n message: `Action output exceeded the ${MAX_RUN_ACTION_OUTPUT_BYTES / 1024} KiB run-head limit.`,\n code: 'RUN_OUTPUT_TOO_LARGE',\n at: completedAt,\n data: { byteLength: boundedOutput.byteLength },\n },\n }\n : { error: undefined }),\n } as Partial<FlowNodeRuntimeState>);\n persistEvents({\n yDoc,\n editor: getReconcileEditor(params, yDoc, editor),\n sessionRunId,\n blockId,\n actorDid: params.actorDid,\n output: boundedOutput.output,\n events,\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n pendingInvocation: inputBuild.pendingInvocation,\n startedAt,\n completedAt,\n now,\n executionId,\n });\n if (sessionRunId && (eventLog || timelineRequired)) {\n const timelineEvents: RunEventInput[] = [\n {\n runId: sessionRunId,\n blockId,\n kind: 'action.output',\n payload: {\n attempt,\n executionId,\n output: boundRunEventJson(boundedOutput.output),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.output', sessionRunId, blockId, executionId, 1),\n ts: completedAt,\n },\n ];\n if (completionState === 'completed') {\n timelineEvents.push({\n runId: sessionRunId,\n blockId,\n kind: 'action.done',\n payload: {\n attempt,\n executionId,\n durationMs: Math.max(0, completedAt - startedAt),\n },\n idempotencyKey: createRunEventIdempotencyKey('action.done', sessionRunId, blockId, executionId),\n ts: completedAt,\n });\n } else if (boundedOutput.exceeded) {\n timelineEvents.push({\n runId: sessionRunId,\n blockId,\n kind: 'action.failed',\n payload: {\n attempt,\n executionId,\n durationMs: Math.max(0, completedAt - startedAt),\n error: {\n message: `Action output exceeded the ${MAX_RUN_ACTION_OUTPUT_BYTES / 1024} KiB run-head limit.`,\n code: 'RUN_OUTPUT_TOO_LARGE',\n details: {\n byteLength: boundedOutput.byteLength,\n maxBytes: MAX_RUN_ACTION_OUTPUT_BYTES,\n },\n },\n },\n idempotencyKey: createRunEventIdempotencyKey('action.failed', sessionRunId, blockId, executionId),\n ts: completedAt,\n });\n }\n await appendRunTimelineEvents({\n eventLog,\n events: timelineEvents,\n runtime,\n blockId,\n now,\n });\n }\n const pendingInvocationRemoved = completionState === 'completed' ? cleanupCompletedPendingInvocation(yDoc, blockId, inputBuild.pendingInvocation, sessionRunId) : false;\n const topicWriteBack = await recordTopicPhase(completionState === 'completed' ? 'succeeded' : completionState === 'needs_verification' ? 'needs_verification' : 'failed', {\n output,\n ...(boundedOutput.exceeded ? { error: { code: 'RUN_OUTPUT_TOO_LARGE', message: `Action output exceeded the ${MAX_RUN_ACTION_OUTPUT_BYTES / 1024} KiB run-head limit.` } } : {}),\n invocationReference: outcome.invocationCid || outcome.capabilityId,\n });\n\n return {\n success: !boundedOutput.exceeded,\n stage: outcome.stage,\n blockId,\n actionType,\n output,\n ...(boundedOutput.exceeded\n ? {\n error: `Action output exceeded the ${MAX_RUN_ACTION_OUTPUT_BYTES / 1024} KiB run-head limit.`,\n }\n : {}),\n events,\n invocationCid: outcome.invocationCid,\n capabilityId: outcome.capabilityId,\n // Both names, same value — see the field docs on ExecuteActionBlockResult.\n runId: executionId,\n executionId,\n pendingInvocationRemoved,\n completionState,\n pendingInvocation: inputBuild.pendingInvocation,\n topicWriteBack,\n };\n}\n","import type { Doc as YDoc } from 'yjs';\n\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport type { StoredInvocation } from '../../types/ucan';\nimport { getAction } from '../actionRegistry';\nimport { validateActionProof } from './proof';\nimport { getVersionPolicy } from './versionManifest';\n\n/** Where the flow manager writes the run projections it reduces from the ledger. */\nexport const RUN_PROJECTIONS_MAP_KEY = 'qi.flow.runProjections';\n\n/**\n * What the run ledger says about one execution attempt.\n *\n * Reduced from the signed `ixo.qi.flow.event.v1` chain the flow manager\n * appends to the room — `action.requested`, `started`, `effect_armed`,\n * `succeeded` — each event Ed25519-signed by the oracle and naming the\n * delegation it ran under.\n */\nexport interface RunAttestation {\n attemptId?: string;\n stepId?: string;\n disposition?: string;\n runId?: string;\n}\n\n/**\n * A lookup from attempt id to what the run ledger recorded for it.\n *\n * Built from the projections in the document, so it is the same class of\n * evidence as the invocation store below: presence in a room-writable map,\n * not a re-verification of signatures. It is grounded better — the projection\n * is reduced from signed events — but the check is presence, and a completion\n * that passes it is not unforgeable. `completionEventId` on the action is the\n * pointer a read-time signature check would follow.\n */\nexport function runLedgerAttestations(\n yDoc: YDoc | null | undefined,\n): (attemptId: string) => RunAttestation | undefined {\n let index: Map<string, RunAttestation> | null = null;\n const build = (): Map<string, RunAttestation> => {\n const found = new Map<string, RunAttestation>();\n if (!yDoc) return found;\n const projections = yDoc.getMap<unknown>(RUN_PROJECTIONS_MAP_KEY);\n projections.forEach((raw) => {\n const projection = raw as { runId?: unknown; attempts?: Record<string, unknown> } | null;\n if (!projection || typeof projection !== 'object') return;\n const runId = typeof projection.runId === 'string' ? projection.runId : undefined;\n const attempts = projection.attempts;\n if (!attempts || typeof attempts !== 'object') return;\n for (const [attemptId, value] of Object.entries(attempts)) {\n const attempt = value as { stepId?: unknown; disposition?: unknown } | null;\n if (!attempt || typeof attempt !== 'object') continue;\n // A succeeded attempt is the final word on itself, so it wins over an\n // earlier projection of the same attempt from a shorter timeline.\n const existing = found.get(attemptId);\n if (existing?.disposition === 'succeeded') continue;\n found.set(attemptId, {\n attemptId,\n ...(runId ? { runId } : {}),\n ...(typeof attempt.stepId === 'string' ? { stepId: attempt.stepId } : {}),\n ...(typeof attempt.disposition === 'string' ? { disposition: attempt.disposition } : {}),\n });\n }\n });\n return found;\n };\n return (attemptId: string) => (index ??= build()).get(attemptId);\n}\n\nexport type CompletionVerificationStatus = 'verified' | 'unverified' | 'not_completed';\n\nexport interface CompletionVerification {\n status: CompletionVerificationStatus;\n /** Populated when status is 'unverified'. */\n reason?: string;\n}\n\nexport interface VerifyCompletionParams {\n runtime: FlowNodeRuntimeState | undefined | null;\n blockId: string;\n /** Action type of the block, used to re-check the proof declaration. */\n actionType?: string;\n /** Invocation lookup, typically backed by the doc's `invocations` Y.Map. */\n getInvocation?: (cid: string) => StoredInvocation | undefined | null;\n /**\n * Run-ledger lookup, from {@link runLedgerAttestations}. Supply it wherever a\n * flow may be executed by the flow manager, which is every flow with an\n * oracle in the room: without it, every step the oracle completes reads as\n * unverified for want of an invocation it is never going to mint.\n */\n getRunAttestation?: (attemptId: string) => RunAttestation | undefined | null;\n /** Flow schema version; UCAN binding is only required when the version policy demands it. */\n schemaVersion?: string;\n}\n\n/**\n * Decide whether a block's `state: 'completed'` can be trusted.\n *\n * Anyone with room write access can set `completed` directly in the runtime\n * Y.Map — a completion is only *verified* when it carries the evidence the\n * execution kernel writes:\n *\n * 1. Proof of execution per the action's `proof` declaration (all versions).\n * 2. On UCAN-enforced flows (policy.ucanRequired), a `lastInvocationCid`\n * that resolves in the invocation store to a successful invocation for\n * this block.\n *\n * The invocation check is store-level PRESENCE, not a cryptographic\n * re-verification of the CAR bytes: signatures are validated when the\n * invocation is minted, but the `invocations` Y.Map is room-writable, so a\n * member with write access can forge a matching `{ result: 'success', blockId }`\n * entry and pass this check. This raises the bar (a completion must at least\n * reference a resolvable, successful, block-matching invocation) but does NOT\n * make completions unforgeable — that needs read-time CAR-signature\n * re-verification against the delegation chain (open trust-model decision, H3).\n * Do not describe a completion that passes here as \"impossible to forge\".\n *\n * Consumers gate on this instead of raw `state === 'completed'`:\n * trigger reconciliation (event sources), flow-agent planning (Done\n * classification), and the FlowView completion badge.\n */\nexport function verifyCompletion(params: VerifyCompletionParams): CompletionVerification {\n const { runtime, blockId, actionType, getInvocation, getRunAttestation, schemaVersion } = params;\n\n if (!runtime || runtime.state !== 'completed') {\n return { status: 'not_completed' };\n }\n\n // A human resolved a `needs_verification` block by confirming the side effect\n // really happened (see NodeState 'needs_verification'). This is a deliberate\n // human-in-the-loop override of the missing declared proof — trust it, but it\n // is recorded (manuallyVerifiedByDid/At) for the audit trail. Preferable to\n // leaving a genuinely-completed on-chain action stuck Blocked forever.\n if (runtime.manuallyVerified === true) {\n return { status: 'verified' };\n }\n\n // Proof re-check applies to every version: a completed entry whose output\n // lacks the declared proof is stale or forged.\n if (actionType) {\n const action = getAction(actionType);\n if (action) {\n const proofCheck = validateActionProof(action, (runtime.output as Record<string, unknown>) || {});\n if (!proofCheck.valid) {\n return { status: 'unverified', reason: proofCheck.reason || 'Completed without proof of execution.' };\n }\n }\n }\n\n const policy = schemaVersion ? getVersionPolicy(schemaVersion) : null;\n if (!policy?.ucanRequired) {\n // Legacy flows: room-level access control is the trust boundary.\n return { status: 'verified' };\n }\n\n // A step the flow manager ran carries no invocation, and never will.\n //\n // Invocations are minted by the browser as it executes a block. The flow\n // manager executes headlessly and proves it a different way: a signed\n // `ixo.qi.flow.event.v1` chain in the room, reduced into the run\n // projections this reads. Demanding an invocation caused false diagnostic\n // failures for valid oracle-completed steps.\n const attemptId = typeof runtime.attemptId === 'string' ? runtime.attemptId : undefined;\n const attestation = attemptId ? getRunAttestation?.(attemptId) : undefined;\n if (attestation) {\n if (attestation.disposition !== 'succeeded') {\n return {\n status: 'unverified',\n reason: `The run ledger records attempt ${attemptId} as ${attestation.disposition ?? 'unfinished'}, not succeeded.`,\n };\n }\n if (attestation.stepId && attestation.stepId !== blockId) {\n return { status: 'unverified', reason: 'The run ledger records this attempt against a different block.' };\n }\n return { status: 'verified' };\n }\n\n const invocationCid = runtime.lastInvocationCid;\n if (!invocationCid) {\n return {\n status: 'unverified',\n reason: attemptId\n ? `Completed with no invocation record and no run-ledger attestation for attempt ${attemptId}.`\n : 'Completed without an invocation record on a UCAN-enforced flow.',\n };\n }\n if (!getInvocation) {\n return { status: 'unverified', reason: 'No invocation store available to verify the completion.' };\n }\n const invocation = getInvocation(invocationCid);\n if (!invocation) {\n return { status: 'unverified', reason: `Invocation ${invocationCid} not found in the invocation store.` };\n }\n if (invocation.result !== 'success') {\n return { status: 'unverified', reason: 'Completion references a failed invocation.' };\n }\n if (invocation.blockId && invocation.blockId !== blockId) {\n return { status: 'unverified', reason: 'Completion references an invocation for a different block.' };\n }\n\n return { status: 'verified' };\n}\n\nexport function isVerifiedCompletion(params: VerifyCompletionParams): boolean {\n return verifyCompletion(params).status === 'verified';\n}\n","import type { Map as YMap } from 'yjs';\nimport type { StoredInvocation } from '../types/ucan';\n\n/**\n * Invocation Store for storing and querying invocations\n *\n * Invocations are stored for:\n * - Audit trail: Cryptographic proof of who did what, when, with what authority\n * - Replay protection: Prevent same invocation being used twice\n * - Dispute resolution: Evidence if actions are contested\n * - Blockchain submission: Submit proofs to chain for immutable record\n * - Analytics: Understand flow execution patterns\n */\nexport interface InvocationStore {\n // Core operations\n add: (invocation: StoredInvocation) => void;\n get: (cid: string) => StoredInvocation | null;\n remove: (cid: string) => void;\n\n // Query operations\n getAll: () => StoredInvocation[];\n getByInvoker: (invokerDid: string) => StoredInvocation[];\n getByFlow: (flowId: string) => StoredInvocation[];\n getByBlock: (flowId: string, blockId: string) => StoredInvocation[];\n getByCapability: (can: string, withUri: string) => StoredInvocation[];\n\n // Replay protection\n hasBeenInvoked: (cid: string) => boolean;\n\n // Audit queries\n getInDateRange: (startMs: number, endMs: number) => StoredInvocation[];\n getSuccessful: () => StoredInvocation[];\n getFailures: () => StoredInvocation[];\n\n // Blockchain submission tracking\n getPendingSubmission: () => StoredInvocation[];\n markSubmitted: (cid: string, transactionHash: string) => void;\n\n // Statistics\n getCount: () => number;\n getCountByResult: () => { success: number; failure: number };\n}\n\n/**\n * Create an invocation store backed by Y.Map\n */\nexport const createInvocationStore = (yMap: YMap<unknown>): InvocationStore => {\n /**\n * Add an invocation to the store\n */\n const add = (invocation: StoredInvocation): void => {\n yMap.set(invocation.cid, invocation);\n };\n\n /**\n * Get an invocation by CID\n */\n const get = (cid: string): StoredInvocation | null => {\n const raw = yMap.get(cid);\n if (!raw || typeof raw !== 'object') return null;\n return raw as StoredInvocation;\n };\n\n /**\n * Remove an invocation (use with caution - typically invocations should be immutable)\n */\n const remove = (cid: string): void => {\n yMap.delete(cid);\n };\n\n /**\n * Get all invocations\n */\n const getAll = (): StoredInvocation[] => {\n const invocations: StoredInvocation[] = [];\n yMap.forEach((value) => {\n if (value && typeof value === 'object' && 'cid' in value) {\n invocations.push(value as StoredInvocation);\n }\n });\n // Sort by executedAt descending (most recent first)\n return invocations.sort((a, b) => b.executedAt - a.executedAt);\n };\n\n /**\n * Get invocations by invoker DID\n */\n const getByInvoker = (invokerDid: string): StoredInvocation[] => {\n return getAll().filter((i) => i.invokerDid === invokerDid);\n };\n\n /**\n * Get invocations for a specific flow\n */\n const getByFlow = (flowId: string): StoredInvocation[] => {\n return getAll().filter((i) => i.flowId === flowId);\n };\n\n /**\n * Get invocations for a specific block in a flow\n */\n const getByBlock = (flowId: string, blockId: string): StoredInvocation[] => {\n return getAll().filter((i) => i.flowId === flowId && i.blockId === blockId);\n };\n\n /**\n * Get invocations that used a specific capability\n */\n const getByCapability = (can: string, withUri: string): StoredInvocation[] => {\n return getAll().filter((i) => i.capability.can === can && i.capability.with === withUri);\n };\n\n /**\n * Check if an invocation has already been used (replay protection)\n */\n const hasBeenInvoked = (cid: string): boolean => {\n return yMap.has(cid);\n };\n\n /**\n * Get invocations in a date range\n */\n const getInDateRange = (startMs: number, endMs: number): StoredInvocation[] => {\n return getAll().filter((i) => i.executedAt >= startMs && i.executedAt <= endMs);\n };\n\n /**\n * Get successful invocations\n */\n const getSuccessful = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'success');\n };\n\n /**\n * Get failed invocations\n */\n const getFailures = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'failure');\n };\n\n /**\n * Get invocations pending blockchain submission\n */\n const getPendingSubmission = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'success' && !i.transactionHash);\n };\n\n /**\n * Mark an invocation as submitted to blockchain\n */\n const markSubmitted = (cid: string, transactionHash: string): void => {\n const invocation = get(cid);\n if (invocation) {\n const updated: StoredInvocation = {\n ...invocation,\n transactionHash,\n };\n yMap.set(cid, updated);\n }\n };\n\n /**\n * Get total count of invocations\n */\n const getCount = (): number => {\n return getAll().length;\n };\n\n /**\n * Get count by result type\n */\n const getCountByResult = (): { success: number; failure: number } => {\n const all = getAll();\n return {\n success: all.filter((i) => i.result === 'success').length,\n failure: all.filter((i) => i.result === 'failure').length,\n };\n };\n\n return {\n add,\n get,\n remove,\n getAll,\n getByInvoker,\n getByFlow,\n getByBlock,\n getByCapability,\n hasBeenInvoked,\n getInDateRange,\n getSuccessful,\n getFailures,\n getPendingSubmission,\n markSubmitted,\n getCount,\n getCountByResult,\n };\n};\n\n/**\n * Create an in-memory invocation store (for testing)\n */\nexport const createMemoryInvocationStore = (): InvocationStore => {\n const store = new Map<string, StoredInvocation>();\n\n const add = (invocation: StoredInvocation): void => {\n store.set(invocation.cid, invocation);\n };\n\n const get = (cid: string): StoredInvocation | null => {\n return store.get(cid) || null;\n };\n\n const remove = (cid: string): void => {\n store.delete(cid);\n };\n\n const getAll = (): StoredInvocation[] => {\n const invocations = Array.from(store.values());\n return invocations.sort((a, b) => b.executedAt - a.executedAt);\n };\n\n const getByInvoker = (invokerDid: string): StoredInvocation[] => {\n return getAll().filter((i) => i.invokerDid === invokerDid);\n };\n\n const getByFlow = (flowId: string): StoredInvocation[] => {\n return getAll().filter((i) => i.flowId === flowId);\n };\n\n const getByBlock = (flowId: string, blockId: string): StoredInvocation[] => {\n return getAll().filter((i) => i.flowId === flowId && i.blockId === blockId);\n };\n\n const getByCapability = (can: string, withUri: string): StoredInvocation[] => {\n return getAll().filter((i) => i.capability.can === can && i.capability.with === withUri);\n };\n\n const hasBeenInvoked = (cid: string): boolean => {\n return store.has(cid);\n };\n\n const getInDateRange = (startMs: number, endMs: number): StoredInvocation[] => {\n return getAll().filter((i) => i.executedAt >= startMs && i.executedAt <= endMs);\n };\n\n const getSuccessful = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'success');\n };\n\n const getFailures = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'failure');\n };\n\n const getPendingSubmission = (): StoredInvocation[] => {\n return getAll().filter((i) => i.result === 'success' && !i.transactionHash);\n };\n\n const markSubmitted = (cid: string, transactionHash: string): void => {\n const invocation = get(cid);\n if (invocation) {\n store.set(cid, { ...invocation, transactionHash });\n }\n };\n\n const getCount = (): number => {\n return store.size;\n };\n\n const getCountByResult = (): { success: number; failure: number } => {\n const all = getAll();\n return {\n success: all.filter((i) => i.result === 'success').length,\n failure: all.filter((i) => i.result === 'failure').length,\n };\n };\n\n return {\n add,\n get,\n remove,\n getAll,\n getByInvoker,\n getByFlow,\n getByBlock,\n getByCapability,\n hasBeenInvoked,\n getInDateRange,\n getSuccessful,\n getFailures,\n getPendingSubmission,\n markSubmitted,\n getCount,\n getCountByResult,\n };\n};\n","import type * as Y from 'yjs';\nimport type { FlowNodeRuntimeState } from '../../types/authorization';\nimport { isRepeatableAction } from '../actionRegistry';\nimport type { CompletionVerification } from './verifiedCompletion';\nimport { readRunRecords } from './triggers';\n\n/**\n * The four top-level phases a block presents to users and planners. This is a\n * DERIVED vocabulary — it is never written to the runtime Y.Map. The stored\n * `NodeState` machine is unchanged; every consumer (badge, flow agent, future\n * dashboards) computes its view through {@link deriveBlockPhase} so the two\n * can never drift, and existing flows need no migration.\n *\n * - `pending` — not actionable yet: nothing has run and no work is queued.\n * - `active` — actionable or in motion: running, awaiting external\n * confirmation, queued invocations to act on, or (for repeatable actions) a\n * standing capability that has fired and remains open.\n * - `complete` — Done. Terminal for one-shot (`cardinality: 'once'`) actions.\n * A repeatable action that has fired stays `active`, unless its own `done`\n * fold says no work is outstanding (`drained`), which reopens if work arrives.\n * - `failed` — needs attention. Includes plain failures (safe to retry) and\n * `needs_verification`, which is not safe to retry.\n */\nexport type BlockPhase = 'pending' | 'active' | 'complete' | 'failed';\n\n/**\n * Finer-grained detail preserved from the underlying state machine so UIs can\n * distinguish sub-states without re-deriving them:\n *\n * - `idle` — pending, nothing has run.\n * - `queued` — pending invocations exist for the block.\n * - `running` — executing right now.\n * - `awaiting_readback` — ran; final outcome arrives via read-back\n * reconciliation. Neither pending (it ran) nor complete (not settled).\n * - `standing` — repeatable action with ≥1 completed run; stays\n * active for the flow's life. Progress = `runCount`, not this entry.\n * - `drained` — repeatable action whose `done` fold says no work is\n * outstanding as of its last check. Complete for now; reopens (back to\n * `standing`) when new work arrives. Run count is still the progress measure.\n * - `completed` — terminal Done (one-shot actions only).\n * - `cancelled` — deliberately closed; terminal for any cardinality.\n * - `failed` — the run failed; retrying is safe.\n * - `needs_verification` — side effect MAY have happened but proof is\n * missing. Retrying could double-execute; requires human resolution.\n */\nexport type BlockPhaseDetail =\n | 'idle'\n | 'queued'\n | 'pending'\n | 'running'\n | 'retry_scheduled'\n | 'awaiting_readback'\n | 'awaiting_human'\n | 'standing'\n | 'completed'\n | 'drained'\n | 'cancelled'\n | 'failed'\n | 'needs_verification';\n\nexport interface DerivedBlockState {\n phase: BlockPhase;\n detail: BlockPhaseDetail;\n /** Whether the block's action type is a repeatable ('many') capability. */\n repeatable: boolean;\n /**\n * Successful run count for repeatable blocks, when the caller supplied one\n * (see {@link countSuccessfulRuns}). Undefined when unknown.\n */\n runCount?: number;\n /**\n * Whether re-executing the block is safe. False for `needs_verification`,\n * because the side effect may already have happened.\n */\n safeToRetry: boolean;\n}\n\nexport interface DeriveBlockPhaseParams {\n runtime: FlowNodeRuntimeState | null | undefined;\n /** The block's action type, used to resolve cardinality from the registry. */\n actionType?: string | null;\n /** Diagnostic result retained for API compatibility. It does not change a completed state. */\n completionVerification?: CompletionVerification;\n /** Number of queued pending invocations for the block, when known. */\n pendingInvocationCount?: number;\n /** Successful run count from the audit trail, when the caller has it. */\n runCount?: number;\n /**\n * The action's own `done` fold for this entry, when the caller has run it\n * (`isActionTypeDone`). Only consulted for repeatable actions: a completed\n * entry that folds done derives `complete`/`drained` instead of `standing`.\n */\n done?: boolean;\n}\n\n/**\n * Derive the presentation phase of a block from its canonical runtime state.\n *\n * Pure and read-only: never writes, never consults the clock. Cardinality is\n * the main branch — a repeatable ('many') action never derives `complete`;\n * a `completed` entry just means \"has fired at least once\" and the block\n * remains a standing `active` capability (see ActionDefinition.cardinality).\n *\n * Unknown state strings derive as `failed`/`needs_verification` with\n * `safeToRetry: false`: a state this build doesn't understand was written by\n * a newer client, and the only safe assumption is \"do not touch\".\n */\nexport function deriveBlockPhase(params: DeriveBlockPhaseParams): DerivedBlockState {\n const { runtime, actionType, pendingInvocationCount = 0, runCount, done = false } = params;\n const repeatable = isRepeatableAction(actionType);\n const state = runtime?.state ?? 'idle';\n\n const base = { repeatable, ...(repeatable && runCount !== undefined ? { runCount } : {}) };\n\n switch (state) {\n case 'idle':\n if (pendingInvocationCount > 0) {\n return { ...base, phase: 'active', detail: 'queued', safeToRetry: true };\n }\n return { ...base, phase: 'pending', detail: 'idle', safeToRetry: true };\n case 'running':\n return { ...base, phase: 'active', detail: 'running', safeToRetry: false };\n case 'pending':\n return { ...base, phase: 'active', detail: 'pending', safeToRetry: false };\n case 'retry_scheduled':\n return { ...base, phase: 'active', detail: 'retry_scheduled', safeToRetry: false };\n case 'awaiting_readback':\n return { ...base, phase: 'active', detail: 'awaiting_readback', safeToRetry: false };\n case 'awaiting_human':\n return { ...base, phase: 'failed', detail: 'awaiting_human', safeToRetry: false };\n case 'completed':\n if (repeatable) {\n // A snapshot-backed repeatable action (see ActionDoneContract.reopenable)\n // is complete for now when its fold says so; it reopens when work\n // arrives, so re-running it stays safe.\n if (done && pendingInvocationCount === 0) {\n return { ...base, phase: 'complete', detail: 'drained', safeToRetry: true };\n }\n return { ...base, phase: 'active', detail: 'standing', safeToRetry: true };\n }\n return { ...base, phase: 'complete', detail: 'completed', safeToRetry: false };\n case 'cancelled':\n // Cancellation deliberately closes the block — terminal even for a\n // repeatable capability, unlike `completed` which just means \"fired\".\n return { ...base, phase: 'complete', detail: 'cancelled', safeToRetry: false };\n case 'failed':\n return { ...base, phase: 'failed', detail: 'failed', safeToRetry: true };\n case 'needs_verification':\n return { ...base, phase: 'failed', detail: 'needs_verification', safeToRetry: false };\n default:\n // Forward-compat guard: an unknown state was written by a newer client.\n // Deriving it as pending would let auto-execute gates fire and risk\n // double-execution — treat it as needs-attention, never retryable.\n return { ...base, phase: 'failed', detail: 'needs_verification', safeToRetry: false };\n }\n}\n\n/**\n * Count the successful runs of a block from the audit trail — the real\n * progress measure for a repeatable ('many') block, whose single runtime\n * entry only says \"has fired at least once\".\n */\nexport function countSuccessfulRuns(yDoc: Y.Doc, blockId: string): number {\n return readRunRecords(yDoc, blockId).filter((record) => !record.error).length;\n}\n","/**\n * Validate a block's user-authored JSON configuration props.\n *\n * The engine's parse helpers absorb malformed JSON (a block with a broken\n * trigger simply never fires) — this helper makes that state visible so the\n * UI can render an \"Invalid configuration\" indicator instead of leaving the\n * block silently inert.\n */\nexport function validateBlockConfig(block: { id?: string; props?: Record<string, unknown> } | null | undefined): string[] {\n const issues: string[] = [];\n if (!block?.props) return issues;\n\n const checkJson = (propName: string, value: unknown, expectObject = true): void => {\n if (value == null || value === '') return;\n if (typeof value !== 'string') return; // already parsed — fine\n try {\n const parsed = JSON.parse(value);\n if (expectObject && (parsed == null || typeof parsed !== 'object')) {\n issues.push(`${propName} is valid JSON but not an object`);\n }\n } catch {\n issues.push(`${propName} is not valid JSON`);\n }\n };\n\n checkJson('inputs', block.props.inputs);\n checkJson('trigger', block.props.trigger);\n checkJson('assignment', block.props.assignment);\n checkJson('conditions', block.props.conditions);\n\n return issues;\n}\n","/**\n * Flow Migration Engine\n *\n * State machine that manages per-flow version upgrades.\n * Migration progress is persisted in a Yjs map so it survives page reloads\n * and is visible to all collaborators.\n *\n * Key properties:\n * - Incremental: each work item is processed and persisted individually\n * - Resumable: interrupted migrations pick up from the last pending item\n * - Safe: version is only stamped after all items complete and post-validation passes\n * - Owner-only: only the flow owner can initiate or resume a migration\n */\n\nimport type { Map as YMap } from 'yjs';\nimport type { IxoEditorType } from '../../types/editor';\nimport type { UcanService } from '../../services/ucanService';\nimport type { FlowVersionString } from './versionManifest';\nimport { getMigrationChain } from './versionManifest';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type MigrationPhase = 'idle' | 'analyzing' | 'ready' | 'executing' | 'validating' | 'finalizing' | 'complete' | 'failed';\n\nexport interface MigrationWorkItem {\n /** Unique identifier for this work item */\n id: string;\n /** Block ID this item relates to (empty for flow-level items like root delegation) */\n nodeId: string;\n /** Type of work to perform */\n type: 'create_root_delegation' | 'create_node_delegation' | 'backfill_capability';\n /** Current status */\n status: 'pending' | 'completed' | 'failed';\n /** Error message if failed */\n error?: string;\n /** Whether this item requires user interaction (e.g., PIN for signing) */\n requiresUserAction: boolean;\n /** Human-readable description */\n description: string;\n}\n\nexport interface MigrationState {\n /** Current phase of the migration */\n phase: MigrationPhase;\n /** Version migrating from */\n fromVersion: string;\n /** Version migrating to */\n toVersion: string;\n /** DID of the user who initiated the migration */\n initiatorDid: string;\n /** ISO timestamp when migration started */\n startedAt: string;\n /** Work items to process */\n workItems: MigrationWorkItem[];\n /** Number of completed items */\n completedItems: number;\n /** Total number of items */\n totalItems: number;\n /** Error message if migration failed */\n error?: string;\n /** ISO timestamp when migration completed */\n completedAt?: string;\n}\n\nexport interface MigrationHistoryEntry {\n from: string;\n to: string;\n migratedBy: string;\n migratedAt: string;\n itemCount: number;\n}\n\nexport interface MigrationPrecondition {\n id: string;\n description: string;\n check: (ctx: MigrationContext) => boolean | Promise<boolean>;\n /** If true, failing this precondition blocks the entire migration */\n blocking: boolean;\n}\n\nexport interface MigrationDefinition {\n from: FlowVersionString;\n to: FlowVersionString;\n\n /** Preconditions that must be met before migration can start */\n preconditions: MigrationPrecondition[];\n\n /** Analyze the flow and return work items */\n analyze: (ctx: MigrationContext) => Promise<MigrationWorkItem[]>;\n\n /** Execute a single work item */\n executeItem: (ctx: MigrationContext, item: MigrationWorkItem) => Promise<{ success: boolean; error?: string }>;\n\n /** Validate the flow after all items are processed */\n postValidate: (ctx: MigrationContext) => Promise<{ valid: boolean; errors: string[] }>;\n\n /** Finalize the migration (stamp version, update context) */\n finalize: (ctx: MigrationContext) => void;\n}\n\nexport interface MigrationContext {\n /** The editor instance */\n editor: IxoEditorType;\n /** The migration Yjs map for persisting state */\n migrationMap: YMap<any>;\n /** DID of the actor performing the migration (must be flow owner) */\n actorDid: string;\n /** DID of the flow owner */\n flowOwnerDid: string;\n /** Flow URI for capability resources */\n flowUri: string;\n /** Flow document ID */\n flowId: string;\n /** UCAN service for creating delegations */\n ucanService: UcanService;\n /** PIN for signing operations */\n pin: string;\n /** Actor type for signing */\n actorType: 'entity' | 'user';\n /** Entity room ID if signing as entity */\n entityRoomId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Migration Registry\n// ---------------------------------------------------------------------------\n\nconst MIGRATION_REGISTRY: Record<string, MigrationDefinition> = {};\n\n/**\n * Register a migration definition. Called by migration files on import.\n */\nexport function registerMigration(definition: MigrationDefinition): void {\n const key = `${definition.from}->${definition.to}`;\n MIGRATION_REGISTRY[key] = definition;\n}\n\n/**\n * Get the migration definition for a version pair.\n */\nexport function getMigrationDefinition(from: string, to: string): MigrationDefinition | null {\n return MIGRATION_REGISTRY[`${from}->${to}`] || null;\n}\n\n// ---------------------------------------------------------------------------\n// State persistence helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read the current migration state from the Yjs map.\n */\nexport function getMigrationState(migrationMap: YMap<any>): MigrationState | null {\n const raw = migrationMap.get('state');\n if (!raw) return null;\n return typeof raw === 'string' ? JSON.parse(raw) : raw;\n}\n\nfunction persistState(migrationMap: YMap<any>, state: MigrationState): void {\n migrationMap.set('state', JSON.parse(JSON.stringify(state)));\n}\n\nfunction getMigrationHistory(migrationMap: YMap<any>): MigrationHistoryEntry[] {\n const raw = migrationMap.get('history');\n if (!raw) return [];\n return typeof raw === 'string' ? JSON.parse(raw) : raw;\n}\n\nfunction appendMigrationHistory(migrationMap: YMap<any>, entry: MigrationHistoryEntry): void {\n const history = getMigrationHistory(migrationMap);\n history.push(entry);\n migrationMap.set('history', JSON.parse(JSON.stringify(history)));\n}\n\n// ---------------------------------------------------------------------------\n// Migration lifecycle functions\n// ---------------------------------------------------------------------------\n\n/**\n * Start a migration from the flow's current version to the target version.\n * Runs preconditions and analysis, persists work items.\n * Does NOT execute any items — call executeMigrationStep() for that.\n */\nexport async function startMigration(ctx: MigrationContext, fromVersion: string, toVersion: string): Promise<{ success: boolean; state: MigrationState; errors: string[] }> {\n const errors: string[] = [];\n\n // Resolve migration definition\n const definition = getMigrationDefinition(fromVersion, toVersion);\n if (!definition) {\n return {\n success: false,\n state: createFailedState(fromVersion, toVersion, ctx.actorDid, `No migration path from ${fromVersion} to ${toVersion}`),\n errors: [`No migration definition registered for ${fromVersion} -> ${toVersion}`],\n };\n }\n\n // Check preconditions\n for (const precondition of definition.preconditions) {\n const passed = await precondition.check(ctx);\n if (!passed) {\n if (precondition.blocking) {\n const state = createFailedState(fromVersion, toVersion, ctx.actorDid, `Precondition failed: ${precondition.description}`);\n persistState(ctx.migrationMap, state);\n return { success: false, state, errors: [precondition.description] };\n }\n errors.push(`Warning: ${precondition.description}`);\n }\n }\n\n // Analyze\n const workItems = await definition.analyze(ctx);\n\n const state: MigrationState = {\n phase: workItems.length === 0 ? 'ready' : 'ready',\n fromVersion,\n toVersion,\n initiatorDid: ctx.actorDid,\n startedAt: new Date().toISOString(),\n workItems,\n completedItems: 0,\n totalItems: workItems.length,\n };\n\n persistState(ctx.migrationMap, state);\n return { success: true, state, errors };\n}\n\n/**\n * Execute the next pending work item in the migration.\n * Call this repeatedly until all items are processed.\n * Returns the updated state after processing one item.\n */\nexport async function executeMigrationStep(ctx: MigrationContext): Promise<MigrationState> {\n const state = getMigrationState(ctx.migrationMap);\n if (!state) {\n throw new Error('No migration in progress');\n }\n\n if (state.phase === 'complete' || state.phase === 'failed') {\n return state;\n }\n\n const definition = getMigrationDefinition(state.fromVersion, state.toVersion);\n if (!definition) {\n state.phase = 'failed';\n state.error = `Migration definition not found for ${state.fromVersion} -> ${state.toVersion}`;\n persistState(ctx.migrationMap, state);\n return state;\n }\n\n // Find next pending item\n const pendingItem = state.workItems.find((item) => item.status === 'pending');\n if (!pendingItem) {\n // All items processed, move to validating\n state.phase = 'validating';\n persistState(ctx.migrationMap, state);\n return state;\n }\n\n // Execute the item\n state.phase = 'executing';\n persistState(ctx.migrationMap, state);\n\n const result = await definition.executeItem(ctx, pendingItem);\n\n if (result.success) {\n pendingItem.status = 'completed';\n state.completedItems++;\n } else {\n pendingItem.status = 'failed';\n pendingItem.error = result.error;\n }\n\n // Check if all items are done\n const stillPending = state.workItems.some((item) => item.status === 'pending');\n if (!stillPending) {\n const anyFailed = state.workItems.some((item) => item.status === 'failed');\n state.phase = anyFailed ? 'failed' : 'validating';\n if (anyFailed) {\n state.error = 'One or more migration items failed. Review individual items for details.';\n }\n }\n\n persistState(ctx.migrationMap, state);\n return state;\n}\n\n/**\n * Execute all remaining pending work items in sequence.\n * Convenience wrapper around executeMigrationStep.\n */\nexport async function executeAllMigrationSteps(ctx: MigrationContext): Promise<MigrationState> {\n let state = getMigrationState(ctx.migrationMap);\n if (!state) throw new Error('No migration in progress');\n\n while (state.phase !== 'validating' && state.phase !== 'failed' && state.phase !== 'complete') {\n const hasRemaining = state.workItems.some((item) => item.status === 'pending');\n if (!hasRemaining) break;\n state = await executeMigrationStep(ctx);\n }\n\n return state;\n}\n\n/**\n * Run post-validation after all work items are complete.\n * Returns validation result without modifying the version.\n */\nexport async function validateMigration(ctx: MigrationContext): Promise<{ valid: boolean; errors: string[] }> {\n const state = getMigrationState(ctx.migrationMap);\n if (!state || state.phase !== 'validating') {\n return { valid: false, errors: ['Migration is not in validating phase'] };\n }\n\n const definition = getMigrationDefinition(state.fromVersion, state.toVersion);\n if (!definition) {\n return { valid: false, errors: ['Migration definition not found'] };\n }\n\n const result = await definition.postValidate(ctx);\n\n if (!result.valid) {\n state.phase = 'failed';\n state.error = `Post-validation failed: ${result.errors.join('; ')}`;\n persistState(ctx.migrationMap, state);\n }\n\n return result;\n}\n\n/**\n * Finalize the migration — stamp the new version and record history.\n * Only call after validateMigration returns { valid: true }.\n */\nexport function finalizeMigration(ctx: MigrationContext): MigrationState {\n const state = getMigrationState(ctx.migrationMap);\n if (!state || state.phase !== 'validating') {\n throw new Error('Cannot finalize: migration is not in validating phase');\n }\n\n const definition = getMigrationDefinition(state.fromVersion, state.toVersion);\n if (!definition) {\n throw new Error('Migration definition not found');\n }\n\n // Run the definition's finalize (stamps version on root map, etc.)\n definition.finalize(ctx);\n\n // Record history\n appendMigrationHistory(ctx.migrationMap, {\n from: state.fromVersion,\n to: state.toVersion,\n migratedBy: ctx.actorDid,\n migratedAt: new Date().toISOString(),\n itemCount: state.totalItems,\n });\n\n // Update state\n state.phase = 'complete';\n state.completedAt = new Date().toISOString();\n persistState(ctx.migrationMap, state);\n\n return state;\n}\n\n/**\n * Abandon an in-progress migration. Safe because the version hasn't been bumped.\n * Resets migration state to idle.\n */\nexport function abandonMigration(migrationMap: YMap<any>): void {\n migrationMap.delete('state');\n}\n\n/**\n * Check if a migration can be resumed (has persisted state with pending items).\n */\nexport function canResumeMigration(migrationMap: YMap<any>): boolean {\n const state = getMigrationState(migrationMap);\n if (!state) return false;\n return state.phase !== 'idle' && state.phase !== 'complete' && state.phase !== 'failed';\n}\n\n/**\n * Run a full migration chain from one version to another,\n * stepping through each intermediate version.\n * For UI-driven migrations, prefer calling the individual lifecycle functions.\n */\nexport async function runMigrationChain(ctx: MigrationContext, fromVersion: string, toVersion: string): Promise<{ success: boolean; finalVersion: string; errors: string[] }> {\n const chain = getMigrationChain(fromVersion, toVersion);\n if (chain.length === 0) {\n return { success: false, finalVersion: fromVersion, errors: ['No migration path found'] };\n }\n\n let currentVersion = fromVersion;\n const allErrors: string[] = [];\n\n for (const targetVersion of chain) {\n // Start\n const startResult = await startMigration(ctx, currentVersion, targetVersion);\n if (!startResult.success) {\n return { success: false, finalVersion: currentVersion, errors: [...allErrors, ...startResult.errors] };\n }\n\n // Execute all steps\n const state = await executeAllMigrationSteps(ctx);\n if (state.phase === 'failed') {\n return { success: false, finalVersion: currentVersion, errors: [...allErrors, state.error || 'Migration failed'] };\n }\n\n // Validate\n const validation = await validateMigration(ctx);\n if (!validation.valid) {\n return { success: false, finalVersion: currentVersion, errors: [...allErrors, ...validation.errors] };\n }\n\n // Finalize\n finalizeMigration(ctx);\n currentVersion = targetVersion;\n }\n\n return { success: true, finalVersion: currentVersion, errors: allErrors };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction createFailedState(from: string, to: string, initiator: string, error: string): MigrationState {\n return {\n phase: 'failed',\n fromVersion: from,\n toVersion: to,\n initiatorDid: initiator,\n startedAt: new Date().toISOString(),\n workItems: [],\n completedItems: 0,\n totalItems: 0,\n error,\n };\n}\n","/**\n * Migration: 0.3 → 1.0.0\n *\n * Upgrades a flow from optional UCAN to required UCAN authorization.\n *\n * What this migration does:\n * 1. Creates a root delegation if one doesn't exist\n * 2. For each executable block, ensures a delegation granting\n * flow/block/execute exists in the delegation store\n * 3. Validates all delegation chains resolve back to root\n * 4. Stamps schema_version to '1.0.0'\n *\n * In v1.0.0, delegations live in the UcanDelegationStore (Yjs-backed),\n * not as block props. The authorization layer validates chains from\n * the store at execution time.\n */\n\nimport type { MigrationDefinition, MigrationContext, MigrationWorkItem } from '../migration';\nimport { registerMigration } from '../migration';\nimport type { UcanCapability } from '../../../types/ucan';\n\n/** Block types that are structural/content and don't participate in flow execution */\nconst NON_EXECUTABLE_BLOCK_TYPES = new Set(['paragraph', 'heading', 'bulletListItem', 'numberedListItem', 'image', 'table']);\n\n/**\n * Check if a delegation already exists in the store for a given block.\n */\nfunction hasDelegationForBlock(ctx: MigrationContext, blockId: string): boolean {\n const delegations = ctx.ucanService.getAllDelegations();\n const resourceUri = `${ctx.flowUri}:${blockId}`;\n return delegations.some((d) => d.capabilities.some((c) => c.can === 'flow/block/execute' && c.with === resourceUri));\n}\n\nexport const migration_0_3_to_1_0_0: MigrationDefinition = {\n from: '0.3',\n to: '1.0.0',\n\n preconditions: [\n {\n id: 'has_flow_owner',\n description: 'Flow must have a flowOwnerDid set',\n check: (ctx) => {\n const ownerDid = ctx.editor.getFlowOwnerDid?.() || ctx.flowOwnerDid;\n return !!ownerDid;\n },\n blocking: true,\n },\n {\n id: 'is_owner',\n description: 'Only the flow owner can initiate migration',\n check: (ctx) => {\n const ownerDid = ctx.editor.getFlowOwnerDid?.() || ctx.flowOwnerDid;\n return ctx.actorDid === ownerDid;\n },\n blocking: true,\n },\n {\n id: 'ucan_service_available',\n description: 'UCAN service must be configured',\n check: (ctx) => {\n return !!ctx.ucanService && ctx.ucanService.isConfigured();\n },\n blocking: true,\n },\n ],\n\n async analyze(ctx: MigrationContext): Promise<MigrationWorkItem[]> {\n const items: MigrationWorkItem[] = [];\n const blocks = ctx.editor.document;\n\n // Check if root delegation exists\n const rootDelegation = ctx.ucanService.getRootDelegation();\n if (!rootDelegation) {\n items.push({\n id: '__root_delegation__',\n nodeId: '',\n type: 'create_root_delegation',\n status: 'pending',\n requiresUserAction: true,\n description: 'Create root delegation for flow owner',\n });\n }\n\n // Scan all blocks — create delegations for executable blocks that don't have one\n if (blocks) {\n for (const block of blocks) {\n if (NON_EXECUTABLE_BLOCK_TYPES.has(block.type)) continue;\n\n if (!hasDelegationForBlock(ctx, block.id)) {\n items.push({\n id: `node_delegation_${block.id}`,\n nodeId: block.id,\n type: 'create_node_delegation',\n status: 'pending',\n requiresUserAction: true,\n description: `Create delegation for block \"${block.type}\" (${block.id})`,\n });\n }\n }\n }\n\n return items;\n },\n\n async executeItem(ctx: MigrationContext, item: MigrationWorkItem): Promise<{ success: boolean; error?: string }> {\n try {\n switch (item.type) {\n case 'create_root_delegation': {\n await ctx.ucanService.createRootDelegation({\n flowOwnerDid: ctx.flowOwnerDid,\n issuerType: ctx.actorType,\n entityRoomId: ctx.entityRoomId,\n flowUri: ctx.flowUri,\n pin: ctx.pin,\n });\n return { success: true };\n }\n\n case 'create_node_delegation':\n case 'backfill_capability': {\n // Create a delegation from flow owner granting flow/block/execute for this node\n const capability: UcanCapability = {\n can: 'flow/block/execute',\n with: `${ctx.flowUri}:${item.nodeId}`,\n };\n\n await ctx.ucanService.createDelegation({\n issuerDid: ctx.flowOwnerDid,\n issuerType: ctx.actorType,\n entityRoomId: ctx.entityRoomId,\n audience: ctx.flowOwnerDid, // Owner delegates to self initially; actors get sub-delegations\n capabilities: [capability],\n pin: ctx.pin,\n });\n\n return { success: true };\n }\n\n default:\n return { success: false, error: `Unknown work item type: ${item.type}` };\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { success: false, error: message };\n }\n },\n\n async postValidate(ctx: MigrationContext): Promise<{ valid: boolean; errors: string[] }> {\n const errors: string[] = [];\n const blocks = ctx.editor.document;\n\n // Verify root delegation exists\n const rootDelegation = ctx.ucanService.getRootDelegation();\n if (!rootDelegation) {\n errors.push('Root delegation is missing after migration');\n }\n\n // Verify each executable block has a valid delegation chain\n if (blocks) {\n for (const block of blocks) {\n if (NON_EXECUTABLE_BLOCK_TYPES.has(block.type)) continue;\n\n const requiredCapability: UcanCapability = {\n can: 'flow/block/execute',\n with: `${ctx.flowUri}:${block.id}`,\n };\n\n const validation = await ctx.ucanService.validateDelegationChain(ctx.flowOwnerDid, requiredCapability);\n if (!validation.valid) {\n errors.push(`Block \"${block.type}\" (${block.id}): delegation chain invalid — ${validation.error || 'unknown error'}`);\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n },\n\n finalize(ctx: MigrationContext): void {\n const root = ctx.editor._yRoot;\n if (!root) {\n throw new Error('Cannot finalize: editor _yRoot not available');\n }\n\n root.set('schema_version', '1.0.0');\n root.set('@context', 'https://ixo.world/flow/1.0');\n },\n};\n\n// Auto-register this migration on import\nregisterMigration(migration_0_3_to_1_0_0);\n"],"mappings":"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","names":["getNodeOutput","getNodeOutput","flattenBlocks","next","Y","fnv1a32","fnv1a32","CROCKFORD","current","getNodeOutput","fieldPath","executionId","isYDoc","getYDoc","parseInputs","getRuntime","getEditor","makeExecutionId","getReconcileEditor","topicWriteBack"]}