docs: clarify fork gather runtime identity

This commit is contained in:
lda
2026-09-03 23:43:31 +07:00 Verified
parent d9559bfbd2
commit ca6425af32
2 changed files with 78 additions and 14 deletions
+30 -12
View File
@@ -260,6 +260,27 @@ state, records trace, and persists runs predictably even when individual
capabilities call nondeterministic tools, APIs, Python code, or LLMs.
_Avoid_: Deterministic external tools, deterministic LLM output
**Runtime Scope**:
The state universe for one workflow invocation, containing its input and
committed state. Every state lineage belongs to exactly one runtime scope.
_Avoid_: Execution frame, branch, global run state
**State Lineage**:
One isolated state worldview inside a runtime scope. Its ancestry describes
state visibility, independently of which execution frame currently uses it.
_Avoid_: Execution frame, scheduler task, activation token
**Execution Frame**:
A schedulable graph cursor that executes against one state lineage. Frame
ancestry describes scheduling ownership and block/wake behavior, not state
ancestry.
_Avoid_: State lineage, workflow invocation, operating-system thread
**Frame Completion**:
The end of one execution frame. Its owner determines whether this completes a
workflow invocation, returns from a subgraph, or completes one foreach item.
_Avoid_: Always completing the run, domain outcome, implicit break
**Fork**:
An explicit workflow control step that creates several concurrent branch
activations. A fork is distinct from an ordinary outcome, which selects exactly
@@ -275,10 +296,10 @@ _Avoid_: Pass-through join marker, arbitrary graph convergence, reference to one
originating fork
**Activation Token**:
A runtime value identifying one control-flow arrival, its workflow scope,
lineage worldview, activation context, and merge provenance. Compatible tokens
can rendezvous at a gather without mixing loop iterations, subgraph
invocations, or repeated fork activations.
A runtime value identifying one control-flow arrival, its state lineage,
activation context, and merge provenance. Compatible tokens can rendezvous at
a gather without mixing loop iterations, subgraph invocations, or repeated
fork activations. The lineage determines the token's runtime scope.
_Avoid_: Static edge, node output payload, scheduler position
**Gather Slot**:
@@ -534,14 +555,6 @@ _Avoid_: Global committed state
A merge boundary that waits for multiple child or upstream frames and combines their lineage patches before continuation.
_Avoid_: Noop join
**Gather Node**:
A future graph step that exposes an explicit barrier for waiting on multiple branches and merging their results.
_Avoid_: Promise.all node, converge node
**Lineage Token**:
A future runtime marker for one branch lineage that can be consumed and merged by gather-style barriers.
_Avoid_: Edge id
**Run**:
One execution attempt of a workflow with input, state, frames, trace, and final output.
_Avoid_: Job, invocation
@@ -549,6 +562,11 @@ _Avoid_: Job, invocation
## Relationships
- A **Run** owns one or more **Frames**.
- Every **State Lineage** belongs to exactly one **Runtime Scope**.
- Every **Execution Frame** executes against one **State Lineage** and derives
its runtime scope through that lineage.
- Frame ancestry expresses scheduling ownership; lineage ancestry expresses
state visibility.
- A **Frame Set** is the source of truth for runtime cursors.
- The **Scheduler Foundation** selects one **Runnable Frame** at a time in the
first pass.
@@ -59,6 +59,21 @@ one token per slot for an activation, waits until all slots are present, then
merges their lineage-local patches. Its result is a new continuation token that
preserves combined provenance and can enter another gather.
Runtime identity follows one canonical dependency chain. A runtime scope is one
workflow invocation and its committed state universe. A lineage belongs to
exactly one scope and represents one isolated state worldview inside it. An
execution frame is a schedulable graph cursor that executes against one
lineage, so the frame's scope and parent lineage are derived through that
lineage rather than independently stored relationships. Frame ancestry remains
separate: a parent frame expresses scheduling ownership and block/wake behavior,
not state ancestry.
Lineages are not owned by frames. A completed branch frame may leave its
lineage waiting at a gather, and a later continuation frame may execute against
the lineage produced by a merge. Activation tokens bind a control-flow arrival
to its lineage plus the correlation and provenance needed by gathers; they do
not duplicate the lineage's scope membership.
Lineage remains a virtual worldview: committed scope state plus writes visible
to one branch. Gathering several lineages does not require turning lineage
ancestry into a multi-parent graph. A partial gather can create an intermediate
@@ -82,6 +97,21 @@ overlap in the asynchronous runtime. Both modes must produce equivalent graph
semantics. Scheduler order decides when compatible work progresses, never which
arrivals belong together.
`END` means completion of the current execution frame, not necessarily
completion of the whole run. The frame owner determines the consequence: a
root frame completes its workflow invocation, a subgraph root returns to its
parent boundary, and a foreach item reports completion to its parent barrier.
For a foreach, normal item-frame completion therefore allows the controller to
admit or resume the next item without introducing a separate continue node.
General break and race behavior are not part of the first fork/gather design.
The existing foreach `fail`, `skip`, and `collect` policies describe the
disposition of runtime item failures; they are distinct from completion
policies such as first-completed, first-error, or all-completed. A future break
feature would require an operational signal to the owning foreach and an
explicit policy for already admitted concurrent items. No `BreakNode` is added
without that use case and policy.
The current `JoinNode` will not be silently upgraded. Before implementation we
will verify whether real persisted artifacts use it. With no real compatibility
obligation, remove it and introduce `GatherNode` cleanly. If persisted callers
@@ -106,6 +136,16 @@ AND across slots and OR within a slot.
belongs to activation tokens; an intermediate merged worldview can remain a
child of the compatible inputs' common lineage parent.
**Store scope and parent-lineage identity on every frame.** Rejected because
those relationships are canonical on the lineage and duplicated frame fields
can disagree with them. Runtime operations should resolve and validate a
frame's lineage and scope together.
**Model normal foreach completion as a continue node.** Rejected because
completion of an item frame already returns control to the owning foreach.
Break and race semantics remain separate future policies rather than additional
meanings assigned to ordinary outcomes.
**Reuse or rename `JoinNode`.** Rejected as the default because the existing
node is a pass-through marker with no barrier contract.
@@ -118,6 +158,12 @@ node is a pass-through marker with no barrier contract.
`(node, outcome)` pair.
- Checkpoints must persist pending gather arrivals and activation provenance so
interruption/resume cannot mix loop iterations or subgraph invocations.
- Runtime operations should resolve a frame, its lineage, and its scope through
one internal interface instead of accepting several independently supplied
identifiers.
- Persisted frame state should not duplicate scope or parent-lineage
relationships once real checkpoint compatibility has been checked and any
required migration has been defined.
- Trace output must make fork activation, branch identity, gather waiting, and
merged continuation inspectable without treating scheduler bookkeeping as
ordinary node output.
@@ -129,8 +175,8 @@ node is a pass-through marker with no barrier contract.
## Open Questions
- The exact serialized edge field and authoring name for a gather slot.
- The minimal activation-context and provenance representation that supports
loops, nested forks, subgraphs, partial gathers, and cross-merges.
- The minimal activation-correlation and provenance representation that
supports loops, nested forks, subgraphs, partial gathers, and cross-merges.
- Whether a gather resumes an existing blocked frame or creates a dedicated
continuation frame in each topology shape.
- The trace representation for waiting and merging without excessive internal