Guide

Child Lifecycle & Restart

Recover one retained recursive child exactly without confusing runner reenactment with a fresh incarnation.

A recursive node is not the process currently running it. The node is a durable child incarnation; the process is only one temporary owner charged with enacting that authority.

Commit identity before enactment

When a parent macrostep adds a child, the commit records the child slot and its Birth intent before the engine starts or contacts the child. That committed material already determines the exact incarnation:

  • the parent entity type and InstanceId;
  • the child chart, authored site, and member key;
  • the generation allocated by the parent step;
  • the current attempt; and
  • the derived child Ref and InstanceId.

For a recursive child, the immutable Birth also appends one ancestry frame carrying the recursive group id. The resulting depth and identity do not depend on which host, fiber, or runner enacts the child after commit.

Checkpoint + reenactment + exact identity

A process may restart without the child restarting.

Follow one recursive WorkNode child from committed Birth through runner loss and exact recovery.

1 · Commit the incarnation

The durable parent names one exact child before anything runs.

The parent commits its child slot and Birth intent together. The key, generation, Ref, attempt, input, and ancestry now identify one incarnation independently from the process that will enact it.

Recursive child · research1 of 3
Parent headseq 1
Birth commits1
Arm admissions1
Durable authorityunchanged across process lifetime
Parent checkpointWorkNode/root · seq 1Running · one active child
Child activationresearch · generation 1:0Ref child-7f…e2 · attempt 1
Immutable Birthchild-7f…e2same ancestry · same input · same origin
Live enactment
runner-1 activearm admission 1
Commit precedes enactment.

2 · Lose the process

A stopped runner removes liveness, not durable identity.

The live owner disappears. The committed parent head, child activation, immutable Birth, and child checkpoint remain. No Statechart step occurs merely because a process stopped.

Recursive child · research2 of 3
Parent headseq 1
Birth commits1
Arm admissions1
Durable authorityunchanged across process lifetime
Parent checkpointWorkNode/root · seq 1Running · one active child
Child activationresearch · generation 1:0Ref child-7f…e2 · attempt 1
Immutable Birthchild-7f…e2same ancestry · same input · same origin
Live enactment
no live ownerdurable facts remain
Process loss is not a chart event.

3 · Recover exactly

Resume reenacts the retained child; it does not create another one.

A new runner decodes the checkpoint, validates exact child coverage, and arms the same key, generation, Ref, and attempt. Arm admission happens again, while Birth and commit counts do not move.

Recursive child · research3 of 3
Parent headseq 1
Birth commits1
Arm admissions2
Durable authorityunchanged across process lifetime
Parent checkpointWorkNode/root · seq 1Running · one active child
Child activationresearch · generation 1:0Ref child-7f…e2 · attempt 1
Immutable Birthchild-7f…e2same ancestry · same input · same origin
Live enactment
runner-2 activearm admission 2 · exact same child
Same Ref. No new Birth or commit.

A checkpoint is more than a Snapshot

The committed checkpoint contains the authoritative Snapshot together with the exact activations required to resume it. Every non-completed child slot must have exactly one matching child activation. That activation retains the child site, key, generation, Ref, running or retrying state, attempt, original arming step, provenance, and retry journal.

This is why recovery does not need to infer live work from the active state configuration. The configuration says where the model is. The retained activation says which exact external citizen must be enacted there.

An omitted, duplicated, reordered, or mismatched activation fails checkpoint validation. Motive does not rebuild an approximate child from its chart name and key.

Re-enact, do not rebirth

When a new runner first acquires the instance, the engine decodes the stored checkpoint through the registered chart's ResumePlan. Resume validates exact coverage, publishes no new Statechart step, and calls the ordinary child-arm enactment with the retained child.

That second arm admission is intentional. Enactment is retryable because durable authority came first. In a clustered engine, the already-committed outbox may deliver the same Birth again; the child accepts matching immutable birth facts idempotently. A conflicting input, origin, or Resource delegation is an InputMismatch, not another incarnation of the same child id.

The recovery invariant is therefore precise:

recovered.generation === committed.generation;
recovered.ref === committed.ref;
recovered.attempt === committed.attempt;
recovered.snapshot === committed.snapshot;

No new Birth, ancestry frame, parent commit, or child generation is allowed merely because the runner changed.

Keep restart distinct from retry

Restart preserves one incarnation. A child retry does not. After a failed attempt, the parent commits its ChildRetry cursor and later a ChildResume step before arming a fresh exact incarnation. The new child has a different generation and Ref and the next attempt number.

Removing a family member and later adding the same key is also a new generation. The key names the member's logical position; generation and attempt distinguish the incarnations that have occupied it. Late outcomes from an older Ref are stale evidence and cannot settle the current child.

| Boundary | Generation / Ref | Attempt | Parent commit | | --------------------- | ---------------- | ----------- | -------------------------------- | | Runner restart | preserved | preserved | none | | Child retry | fresh | incremented | ChildRetry, then ChildResume | | Remove and re-add key | fresh | starts at 1 | membership-changing step |

Preserve recursive ancestry unchanged

Every recursive child Birth retains its full ownership path: parent, child site, key, generation, attempt, Ref, and recursive group. Recovery reuses that ancestry byte-for-byte. It neither appends a frame nor consumes another unit of maximumDepth.

If the stored checkpoint cannot decode under the registered chart, recovery does not guess. The engine records a revalidation incident and Parks the owning root so an operator can choose an explicit migration or disposition.

Test cold recovery, not only hot continuity

  1. Start one recursive parent and retain its active child's generation, Ref, attempt, and ancestry.
  2. Persist the parent and child checkpoints, then close the entire runner scope.
  3. Create a fresh engine over the same storage and register the same charts.
  4. Acquire the parent through an ordinary read or command and verify the exact child locator is recovered.
  5. Verify reenactment occurs without another parent commit or distinct child Birth.
  6. Separately exercise retry and prove it creates a fresh generation, Ref, and attempt.

Next, Component Definitions and Placements returns to reusable authored structure while the remaining Recursive Systems guides develop mutual groups and Resource propagation.