pub struct CanonicalOperationDriver { /* private fields */ }Expand description
Reduces the five canonical input classes onto the kernel’s existing semantic mechanisms.
Use it as the plan function of KernelTransaction::prepare:
let preparation = tx.prepare(&envelope, |ctx| driver.plan(ctx));
// ... host CAS-appends the record ...
let committed = tx.commit(&token, &head)?;
driver.note_committed(committed.step_seq)?;Implementations§
Source§impl CanonicalOperationDriver
impl CanonicalOperationDriver
pub fn new() -> Self
Sourcepub fn root_kind(&self) -> Option<RootKind>
pub fn root_kind(&self) -> Option<RootKind>
The operation’s root class. None until the root start commits; immutable afterwards.
Sourcepub fn focus(&self) -> Option<&ExecutionFocus>
pub fn focus(&self) -> Option<&ExecutionFocus>
Where control currently is. Moves only on a committed transition (§7.4).
pub fn workflow_id(&self) -> Option<&WorkflowId>
Sourcepub fn attempt_id(&self, task_id: &str) -> Option<&AttemptId>
pub fn attempt_id(&self, task_id: &str) -> Option<&AttemptId>
Return the kernel-issued live attempt for task_id.
Bindings use this read-only projection to correlate a host completion with the live task attempt. The value comes from checkpointed kernel state; hosts must never synthesize it.
pub fn poison(&self) -> Option<&KernelFault>
Sourcepub fn engine(&self) -> Option<&LoopStateMachine>
pub fn engine(&self) -> Option<&LoopStateMachine>
Read-only access to the semantic engine, for tests and host projections.
Sourcepub fn lifecycle(&self) -> OperationLifecycle
pub fn lifecycle(&self) -> OperationLifecycle
Where the driver’s own fold says the operation is. The transaction stays the authority on lifecycle; this exists so a host projection never needs a second copy of the rule.
Sourcepub fn project_logical_state(&self) -> LogicalStateProjection
pub fn project_logical_state(&self) -> LogicalStateProjection
Project the three driver-owned partitions of §12.1, plus the two transition fields the driver rather than the transaction owns.
Explicitly a projection, not a serialisation: every value below is read through a named
accessor and written into a canonical DTO field. That is the whole point of §12.1 — adding a
field to [LoopStateMachine] must not change the checkpoint format, and a checkpoint field
must not silently vanish because an internal one was renamed. It is also why the internal
enums travel as their label() plus their carried data: TaskLifecycle::Done(reason) and
Residency::External { .. } are semantic-kernel shapes, and mirroring them would make the
checkpoint a checkpoint of a private layout.
Sourcepub fn restore_logical_state(
genesis_config: &ResolvedOperationConfig,
state: &LogicalKernelState,
) -> Result<Self, KernelFault>
pub fn restore_logical_state( genesis_config: &ResolvedOperationConfig, state: &LogicalKernelState, ) -> Result<Self, KernelFault>
Rebuild a driver from a checkpoint’s logical state (§12.2 line 3).
The exact inverse of Self::project_logical_state, and deliberately nothing more: every
value written here is a value the projection reads back, so “did the restore work” is not a
judgement call — super::restore::restore_operation re-projects immediately afterwards and
compares the digest. A field this function forgets therefore fails the restore rather than
producing a runtime that is quietly one field short of the one that crashed.
Task 16b makes every scheduler branch invertible here: workflow source nodes rebuild their
private graph indexes, queued signals rebuild priority and dedupe state, and child process
identity is restored without re-running permission defaults. Unknown labels and inconsistent
relationships still fail closed as CheckpointIncompatible.
Sourcepub fn plan(
&mut self,
context: &PlanContext<'_>,
) -> Result<PlannedStep, KernelFault>
pub fn plan( &mut self, context: &PlanContext<'_>, ) -> Result<PlannedStep, KernelFault>
Plan one input.
Pass this to KernelTransaction::prepare.
The focus/root-kind fold does not advance here — call Self::note_committed once the
host’s append and the transaction’s commit have both succeeded.
Sourcepub fn note_committed(&mut self, step_seq: WireU64) -> Result<(), KernelFault>
pub fn note_committed(&mut self, step_seq: WireU64) -> Result<(), KernelFault>
Install the staged fold after the transaction committed the record (§7.4: a focus moves only on a committed transition).
Sourcepub fn fold(
&mut self,
context: &PlanContext<'_>,
) -> Result<PlannedStep, KernelFault>
pub fn fold( &mut self, context: &PlanContext<'_>, ) -> Result<PlannedStep, KernelFault>
Plan and fold in one call — the shape
rebuild_from_records needs,
where every record it replays is by definition already durable.
Sourcepub fn begin_nested_workflow(
&mut self,
context: &PlanContext<'_>,
spec: &WireSpec,
) -> Result<PlannedStep, KernelFault>
pub fn begin_nested_workflow( &mut self, context: &PlanContext<'_>, spec: &WireSpec, ) -> Result<PlannedStep, KernelFault>
Enter a workflow the agent asked for, inside an agent root (§10.2).
This is the P1 reduction point Task 10 wires its SyscallRequest::SubmitWorkflow gate to;
the authority rules it enforces are already the final ones:
- the root kind stays
Agent— a syscall never re-roots an operation; - the focus moves to
WorkflowController { parent_task_id: Some(agent task) }; - depth is at most 1. Asking for a workflow while the focus already is a
WorkflowControlleris anInvalidAuthorityfault with zero mutation — workflows do not stack (§15.4).