Pre-alpha documentation
Dispatch each model and tool attempt at most once.
Freeze exact providers, admit trusted budgets, commit starts before external I/O, validate streams, preserve tool ambiguity, and recover terminal writes without redispatch.
Freeze exact providers before work is claimed
Registries are immutable startup snapshots keyed by exact owner/name/version capability identity. Resolution compares the full durable descriptor with both the startup snapshot and the live provider. Aliases, family names, endpoint fallback, and mutable routing never enter recovery authority.
let mut models = ModelProviderRegistryBuilder::new();
models.register(model_adapter)?;
let mut tools = ToolProviderRegistryBuilder::new();
tools.register(tool_adapter)?;
let mut schemas = JsonSchemaRegistryBuilder::with_default_limits();
register_standard_invocation_execution_event_schema(&mut schemas)?;
register_application_schemas(&mut schemas)?;
let executor = DurableInvocationExecutor::new(
store,
schemas.build()?,
models.build(),
tools.build(),
budget_provider,
DurableInvocationExecutorOptions::default(),
)?; The budget provider reloads immutable run provenance and cumulative durable usage. The executor never accepts remaining capacity authored by an untrusted caller.
A fresh durable start is dispatch authority
-
Validate
Check fence scope, ledger state, exact provider, budget, deadline, and input contract.
-
Commit
Append the stable start event and move the exact invocation to executing in one fenced transaction.
-
Dispatch
Call external code only after a fresh
Committedresult. An idempotent start returnsRecoveredwithout I/O. -
Validate and finish
Validate complete provider evidence, then commit the stable terminal event against the exact invocation head.
No database transaction remains open during model or tool execution. Reusing the handoff after a lost acknowledgement cannot dispatch the same physical attempt twice.
Stage Tool I/O when order must outlive timing
Ordinary callers use execute_tool. A trusted bounded
coordinator can call start_tool_attempt, consume only a fresh ToolDispatchHandoff through dispatch_started_tool, and later pass the retained ToolTerminalCommitHandoff to commit_tool_terminal. Duplicate starts return Recovered
and forbid provider I/O.
This three-stage path lets read-only provider calls overlap while starts
and terminal facts remain serial and semantic. It does not authorize
parallel writes. The coordinator must bound retained payloads, settle
every started call, and abort child tasks with its owner; dropping a
dispatch handoff leaves visible Executing evidence, never implicit
redispatch authority.
Streaming requires a durable sink
A streaming model handoff must contain a ModelEventSink. The
runtime validates and accumulates every semantic event, waits for ordered
sink acceptance, and requires a valid terminal stream event. The sink must
durably deduplicate by (attempt_id, sequence) before exposing data
externally.
The accumulated response is authoritative only after its separate terminal ledger commit. Invalid sequence, incomplete EOF, sink failure, cancellation, or deadline becomes public-safe error evidence.
A stopped write is an unknown outcome
Read-only cancellation and timeout have a known no-write boundary. A write
may already have changed an external system when its local future stops,
so the executor records AmbiguousExternalOutcome,
ToolExternalEffect::Unknown, and
RetryAdvice::ReconcileFirst. It never converts uncertainty
into a blind tool retry.
Resolve unknown attempts from authoritative evidence
ToolReconciliationHandoff::result and ::error
accept evidence only for the exact Unknown invocation and physical
attempt. Result evidence must pass the frozen local output schema before any
database mutation. The commit appends a distinct audit event and advances the
ledger atomically under the live fence without provider lookup or Tool I/O.
let reconciliation = ToolReconciliationHandoff::result(
live_fence,
unknown_invocation,
reconciliation_event_id,
authoritative_result,
)?;
match executor.commit_tool_reconciliation(reconciliation).await? {
ToolReconciliationOutcome::Committed { .. } => acknowledge(),
ToolReconciliationOutcome::Idempotent { .. } => acknowledge(),
} Exact event retries converge idempotently. Persistence failures retain the evidence handoff; ownership changes allow only a same-run live-fence rebind. A network-facing service must add authorization and evidence-source policy before exposing this trusted worker/operations boundary.
A provider can instead implement the reconciliation SPI and advertise the
matching status-query capability. reconcile_tool performs one deadline-
and cancellation-bounded probe for the original attempt. A result or authoritative
error uses the same atomic commit path; Pending performs no mutation
and must become a durable delayed retry.
let probe = ToolReconciliationAttemptHandoff::new(
live_fence,
unknown_invocation,
stable_reconciliation_event_id,
cancellation,
)?;
match executor.reconcile_tool(probe).await? {
ToolReconciliationAttemptOutcome::Resolved { invocation, .. } => {
continue_from(invocation)
}
ToolReconciliationAttemptOutcome::Pending { retry_after, .. } => {
persist_delayed_retry(retry_after)
}
} The default provider implementation fails closed. Startup rejects a provider that claims reconciliation while its frozen descriptor omits a status query. The inverse remains valid for an explicitly manual reconciler.
Retain terminal evidence, not another call
If external I/O completes but terminal persistence cannot be confirmed,
the error owns a payload-redacted recovery handoff. Retry it only through
commit_model_terminal or commit_tool_terminal;
those methods perform no provider I/O. If ownership changed, rebind the
same-run handoff to the current live fence and let PostgreSQL perform the
authoritative check.
match executor.execute_model(handoff).await {
Ok(outcome) => consume(outcome),
Err(ModelAttemptExecutionError::Terminal(error)) => {
let recovery = error.into_recovery();
retry_without_provider_io(recovery).await?;
}
Err(error) => handle_pre_dispatch_failure(error),
} Publish only correlation evidence
Install the standard schema through its registration function. Its stable
identity is https://stknot.com/schemas/runtime/invocation-execution-event/1.0.0. The eight closed operations expose only binding kind, invocation ID,
attempt ID, and intent digest—never prompts, arguments, outputs, errors,
endpoints, or credentials.
Qualification evidence
PostgreSQL 16/17 tests cover terminal commit after lease takeover without
redispatch or budget re-evaluation, an ordered seven-event durable model
stream with duplicate suppression, and timed-out idempotent writes that
reconcile to either a validated result or authoritative error. A combined
real PostgreSQL and loopback MCP test proves durable state before network
completion, a lost response, Unknown, no redispatch, exact
reconciliation replay, and one physical call. A separate PostgreSQL plus
loopback A2A test proves durable state before send, lost-response Unknown,
and duplicate no-redispatch. Read the complete integration and operations contract before adopting this pre-alpha surface.