Warm-start a Delegate child from a named prior Session in the same workspace (#435).
A warm-started child does not open on an empty Log. Its Log is created up front with:
- a seq-0
session_forklineage Event naming the seed Session and inheriting the seed's fork-tree root, so the child joins the seed's Provider cache family (ADR 0020) instead of deriving a freshs_segment from its own id; - the seed Session's COMPLETE replayable conversational prefix, copied under the
existing
replay_v1rules owned byPixir.Fork(ADR 0024) — full, never a summary and never truncated, because the byte-stable shared prefix is exactly what earns the cache hit; - a runtime-authored lineage boundary marker appended after that prefix.
The boundary marker is a runtime artifact
The marker is authored here, by Pixir, never by the operator and never by the model.
No spec field can suppress it, reword it, or move it after the child's first new user
message: the child's first new user message is appended by the Turn after this Log
already ends with the marker. It is a user_message so it actually reaches the
Provider — a subagent_event would be dropped from the input array and the child
would inherit the transcript with no boundary at all.
Seeding grants context, never scope
replay_v1 copies subagent_event and permission_decision Events verbatim. Those
arrive in the child Log as inert historical transcript. The child's effective policy
is resolved from the NEW request only: the Subagents Manager writes the child's
own spawn-time permission_posture record with child lineage after this Log exists,
and no code path reads a replayed posture or permission decision as live policy input.
Restrict-never-widen is untouched.
Summary
Functions
The marker kind stamped on every runtime-authored lineage boundary Event.
The runtime-authored boundary text.
The per-child envelope projection for warm-start lineage.
Create the warm-started child Log for child_session_id from seed_session_id.
Validate a seed reference without writing anything.
Functions
@spec boundary_marker_kind() :: String.t()
The marker kind stamped on every runtime-authored lineage boundary Event.
The runtime-authored boundary text.
Public so contract tests can pin the substance without reimplementing the wording.
The per-child envelope projection for warm-start lineage.
Cold children report the absence of a seed rather than omitting the distinction, so an operator can tell a warm child from a cold one without reading Logs.
Create the warm-started child Log for child_session_id from seed_session_id.
Fails before creating anything when the seed is unusable, so no partial child Log is ever left behind. Returns the lineage evidence the envelope reports per child.
Pass :child_workspace when the child's Log lives somewhere other than the seed's
workspace — an isolated Subagent runs in a snapshot directory, and snapshots exclude
.pixir, so the seed Log is read from the delegate workspace and written into the
child's. It defaults to the seed workspace (a shared-workspace child).
Validate a seed reference without writing anything.
Returns the resolved lineage (seed_session_id, fork_root_session_id,
replay_event_count) so callers can reject a bad seed before any child Session is
created. A seed that does not exist, is empty of replayable content, or lives outside
the delegate workspace is rejected here.