Member Junction
    Preparing search index...

    Type Alias TaskGraphParentMetadata

    What the parent Task row remembers about the graph beyond its tasks.

    Persisted rather than held in memory because the dispatcher instance that finishes a graph is routinely not the one that accepted it — a restart, a peer instance, or simply a graph that outlives a deploy all break that assumption.

    type TaskGraphParentMetadata = {
        continuation: "message" | "reinvoke" | "none";
        continuationDeliveredAs?: "delivered" | "expired" | "cancelled";
        continuationDeliveredAt?: string;
        earlyFinishedAt?: string;
        failureSemantics?: "block" | "edges";
        invocation?: { context?: unknown; data?: unknown };
        reinvokeDepth: number;
        submittedByAgentRunID: string | null;
        submittedByUserID?: string | null;
    }
    Index

    Properties

    continuation: "message" | "reinvoke" | "none"
    continuationDeliveredAs?: "delivered" | "expired" | "cancelled"

    HOW it was delivered — written by the same compare-and-swap that sets the timestamp.

    'expired' means the settlement was found after its delivery window, so the run and its cost were corrected but nothing was announced: posting a week-old "your workflow finished" into a live conversation, or starting a fresh billed turn for it, is worse than staying quiet. The distinction has to survive in the row, or an expired settlement is indistinguishable from a delivered one the moment anybody looks afterwards.

    continuationDeliveredAt?: string

    Set once the completion handler has delivered. Written with a compare-and-swap guard, which is what turns at-least-once delivery into effectively-once: a crash between "graph complete" and "continuation delivered" leaves this unset, so the next sweep retries, and two instances racing the same completion produce one winner rather than two notifications.

    earlyFinishedAt?: string

    Set, once and durably, when a step declares the workflow finished before its remaining steps.

    Read by loadGraphState so every instance's claim filter knows the remaining steps are about to be skipped. Without it the decision lives only in the deciding instance's memory, and a concurrent poll — including that same instance's, since task execution is not awaited — can claim and start a step the early finish is in the middle of skipping.

    failureSemantics?: "block" | "edges"

    How a failure propagates in this graph — persisted because the dispatcher that settles a graph is routinely not the process that accepted it, and the spec is gone by then.

    'block' (the default) makes a failed step terminal for its dependents. 'edges' releases them along their drawn paths, which is what lets a workflow author a RECOVERY route. Compiled flows are 'edges'; without persisting it, every recovery path a flow author draws is dead machinery — the edges exist and nothing ever follows them.

    invocation?: { context?: unknown; data?: unknown }

    The invocation's data and context, as the flow dialect's roots of the same names (R3-3).

    Absent for a graph submitted without them, in which case those roots resolve to the same empty-but-readable value any absent data does — a condition on them reads false rather than throwing, exactly as the walker's would on a missing key.

    reinvokeDepth: number
    submittedByAgentRunID: string | null
    submittedByUserID?: string | null

    Who the graph belongs to.

    Stored here rather than on a Task column because Task.UserID already means something else — it designates a human task, the assignee the graph waits on — so setting it on a parent would make every graph look like work waiting on a person. It is durable for the same reason everything else in this bag is: the instance that needs it is routinely not the one that wrote it. Consumed by the live-frame layer, which cannot authorize a viewer without knowing whose run they are watching.