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 atomically 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 after that prefix; and
- the requested child's live
permission_postureimmediately after the boundary.
The boundary and posture are runtime artifacts
Both Events are authored here by Pixir in the same Log.create_session/3 event
list. No spec field can suppress or move the boundary after the child's first new
user message. The boundary is a user_message so it reaches the Provider — a
subagent_event would be dropped from the input array. The posture remains durable
authorization evidence rather than model conversation.
The fold performed by seed_child_log/3 owns the lineage used in the live posture;
an earlier validation snapshot is never authoritative. On cold resume, posture and
mutation evidence after the last valid runtime boundary are the live segment.
Copied subagent_event and permission_decision Events remain replay evidence, and
ordinary Fork replay keeps them, but historical posture never authorizes the new
warm child. A valid boundary with no following posture therefore fails closed.
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 or requested posture is unusable,
so no partial child Log is ever left behind. Returns the lineage evidence the
envelope reports per child. The required :permission_posture option carries
the requested child identity and effective permission/workspace fields; this
module combines it with lineage from its own seed fold.
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.