--- id: SG-12 family: RT-SG level: extended profiles: [runtime] posture: normative-target added: "1.0" changed: "1.0" source: https://flowdrop.io/spec/rules/rt-sg/sg-12 specification: FlowDrop Workflow Specification 1.0-draft licence: CC BY 4.0 --- # SG-12 — Where a run's starting state comes from *RT-SG (Part II) · level: extended · profiles: runtime · added in 1.0* ## The rule > **Normative.** This is the rule. > > 1. A run's starting state is resolved in a fixed order: an explicit initial snapshot; else the checkpoint the caller named (an identifier that resolves to nothing is a warning and the run starts fresh, while a checkpoint of a run that has already ended is refused); else the latest state for the caller's thread; else a fresh state. > > 2. Seeding from a thread whose last run ended keeps what the thread accumulated (its messages, data, metadata and thread identifier), and clears everything the finished run owned: its outcome, so the new run reports its own, and its execution position, including the iterator, the iteration count and the current node, so the new run starts its loops from the beginning. > > 3. Seeding from a run that is paused rather than ended restores it untouched, which is what keeps a pause taken mid-loop resumable. ## What it means A run's starting state is not one thing: seeding a new turn from a thread whose last run ended keeps what the thread itself accumulated and clears everything the finished run owned. The two halves pull in different directions, and it is easy to keep the wrong one. Kept: the messages, the data, the metadata, the thread identifier — what a conversation carries forward. Cleared: the outcome, so the new turn reports its own rather than inheriting a finished one's, and the execution position — the iteration count, the current node, the iterator — so the new turn's loops start from the beginning rather than resuming mid-iteration inside a turn that never asked to resume. Seeding from a run that is paused rather than ended is not this path at all: a pause is restored untouched, execution position included, which is what lets a pause taken mid-loop actually resume there. ## Example A finished run's state, cancelled, with one turn's worth of accumulated conversation and execution position: ```json title="A cancelled run's state" verdict="cancelled" { "status": "cancelled", "isComplete": true, "data": { "k": "v" }, "metadata": { "m": 1 }, "threadId": "thread_1", "currentNodeId": "node_a", "iterationCount": 3 } ``` ```json title="What seeds the next turn on that thread" verdict="cleared" { "status": null, "isComplete": false, "error": null, "data": { "k": "v" }, "metadata": { "m": 1 }, "threadId": "thread_1", "currentNodeId": "", "iterationCount": 0, "iterator": null } ``` ## Related rules - Names: SG-11, SG-13 - Referenced by: INT-13, SG-11, SG-13 --- Rule identifiers are permanent and are never renumbered. This specification carries no implementation status: each implementation publishes its own standing against these rules. Licensed CC BY 4.0.