Documentation
¶
Overview ¶
Package agent provides the Scope Agent Framework execution kernel.
Definition owns immutable behavior and creates serializable Execution values; Engine owns Process lifecycle, Signal delivery, Effect dispatch, child composition, resource bounds, observation, and portable snapshots. Strategy payloads stay opaque to the kernel, and persistence stays a caller responsibility.
Engine and Process operations require a non-nil context. A nil context is a programming error and panics on a valid receiver; use context.TODO when the caller has not yet chosen a context. A canceled non-nil context follows each operation's cancellation contract.
The kernel exists for one purpose: a multi-step agent with children and external side effects must resume after a process restart with a stated meaning for every operation that was in flight. Everything below follows from that.
The execution waist ¶
Every strategy intersects on exactly two interfaces:
type Definition interface {
Descriptor() Descriptor
Start(Input) (Execution, error)
Restore(ExecutionState) (Execution, error)
}
type Execution interface {
Step(context.Context, []Signal) (Transition, error)
Snapshot() (ExecutionState, error)
}
The waist is not generic, because the Engine holds heterogeneous definitions homogeneously. Input, Output, Signal, Effect, and ExecutionState cross it as bounded, defensively copied JSON. Generics belong to edge adapters that convert a Go input to raw input and raw output back to a Go output; they never enter the contract the Engine has to hold.
Step ¶
A Step is one cancellable, discardable, purely candidate reduction. It may not call a model, run a tool, perform any other external I/O, hide an unbounded loop, or start an unowned goroutine. An external operation can only be declared as an Effect and executed outside the Step.
These are cooperation contracts for implementations sharing one Go process. Capability checks mediate declared Effects; they do not sandbox arbitrary I/O. Cancellation and kill still depend on in-flight code returning and external operations settling. They cannot forcibly terminate a goroutine.
Three scales explain the kernel: the root tree is the consistency, commit, and recovery unit; a Process is the lifecycle and strategy-state isolation unit; a Step is the concurrency unit. Adding Processes to a tree adds isolated computation and external I/O concurrency, not authoritative commit parallelism. Independent commit throughput means separate root trees.
Each root tree has one private commit owner. Pure computation does not occupy the commit owner: a Process has at most one Step job in flight and siblings run in parallel. Only the owner revalidates and adopts a result. Process state owns local admission rules and deterministic transitions; the tree owner coordinates cross-Process waits, external jobs, durable acknowledgment, and publication. Candidate adoption and wait registration succeed together, or all new registrations are rolled back. When a kill, pause, cancel, or a new incarnation expires an attempt, the result and its error are discarded whole and the Execution is rebuilt from committed Execution state.
The owner services continuously ready control requests, job completions, and queued Processes in bounded scheduling turns. Queries do not wake execution. Pending commits and held freezes still block work that cannot cross those boundaries; a checkpoint still requires a safe tree cut. This is a scheduling guarantee, not a wall-clock deadline: implementations must honor their bounded execution contracts, and the Host owns storage deadlines. A progress checkpoint can acknowledge one Process while unrelated sibling jobs run. Their cut retains committed state and any prepared Effect frontier; their return cannot change that cut until the single commit owner resumes.
Before adopting initial or candidate state, the Engine captures Snapshot and successfully restores it through that Deployment's Definition. An unrestorable candidate cannot advance signal consumption or dispatch Effects. This admission check does not prove exact state equivalence or deterministic continuation: the Definition must establish those properties with conformance cases. Complete tree recovery also validates runtime identities, mailboxes, child ownership, settlements, and the exact Deployment binding. The Engine owns deployment identity; a Definition validates its own opaque state under that matching binding rather than duplicating deployment identity. RestoreTree retains captured authority, limits, budgets, and usage. EngineConfig resource defaults apply to new root trees; the Host must authorize a captured tree before restoring it under current policy. Recovery never silently edits historical grants or repeats initialization admission.
Lifecycle timestamps are observed UTC wall times, not causal ordering proofs. Clock adjustment or a different restoration writer can put a finish before a start, or a child start before its parent. Identities, relations, Step progress, and committed lifecycle facts establish causality; timestamps must be present but need not increase.
Effects and settlement ¶
An Effect is the only way an Execution requests work outside a Step. The Engine derives a stable effect identity from the Process identity, step sequence, and effect index, then freezes the payload. It interprets only its own closed set of framework Effects: RequestWait, StartChild, WaitForChildren, SignalChild, and CancelChild. It hands a strategy effect whole to the dispatcher its Deployment bound. A Deployment without a dispatcher admits only framework Effects, including during recovery. A dispatcher never mutates an Execution; it produces deltas and one settlement Signal.
Dispatcher Effects advance through planned, pending, and settled in declaration order, one at a time:
- the owner validates candidate state, signal consumption, budget, capability, and batch identity;
- the effect enters pending, and in durable mode the pending boundary commits the whole tree first;
- only then does the dispatcher job start, outside the owner;
- the result is normalized to a definite or an unknown settlement;
- only after the settled boundary succeeds does the owner install the settlement, candidate state, mailbox, and Process transition.
Direct-child controls need no external pending attempt. Their recipient change and definite settlement share one tree commit; the recipient cannot consume newly delivered input before durable acknowledgment.
A planned effect that was never dispatched can never become unknown. Automatic redelivery is allowed only where replaying one effect identity is proven to be the same logical operation; where it is not, an unknown settlement stays observable and awaits explicit adjudication. It is never silently replayed and never assumed successful. Ephemeral mode runs the same state machine without calling the durability port. A prepared batch has one execution frontier: definitely settled Effects precede at most one pending or unknown Effect, followed only by planned Effects. Runtime scheduling and snapshot admission enforce this same order. Terminal intent stops the remaining batch without adopting candidate state or advancing input consumption. The terminal snapshot retains the started prefix's actual settlements and the unstarted planned tail. PreparedEffects usage and published child allocations remain charged; unused Step and settlement-Signal reservations are released. Restoring this terminal evidence neither executes the candidate nor replays its Effects. If installing a settled batch fails, the same boundary retains its actual settlements without adopting the candidate or partially installing waits. A restored pending external attempt becomes Unknown when termination forbids replay. An interrupted child start whose child is absent from the authoritative cut becomes a failed publication; its Host admission may already have run.
Signals and waiting ¶
A Signal is the only runtime input into an Execution. Process.DeliverSignals admits one ordered batch atomically, including a batch with one Signal. Repeated submission of one signal identity produces exactly one logical consumption and never charges the signal budget twice. The same identity with different immutable content is rejected as a conflict. In durable mode, successful admission is acknowledged only after mailbox records and budget charges commit to the authoritative tree head. The consumption cursor advances only when candidate state and transition commit, so a failed Step never permanently swallows input. ProcessSnapshot.SignalReceipts exposes the same admitted identities and committed consumption cursor for delivery reconciliation and input cutover. SignalReceipt.Matches proves external admission, including after consumption. Internal wait-opening and child-wait settlement Signals cannot prove an external delivery even when their identity and payload agree. A terminal Process may retain inputs admitted after its final Signal window. Their original recipient binding and pending payload remain observable. Consumption is bounded by the Signal window delivered to that Step; input admitted while the Step runs belongs to a later window. Once consumed, a mailbox record keeps its identity, addressed wait, arrival order, and normalized payload digest. The payload itself is released with candidate adoption. Recovery retains exact pending inputs and validates wait history from these facts; consumed content is no longer a transcript.
A wait identity is minted by the Engine; an Execution cannot generate an external one. The Execution declares a logical wait through a Transition; the Engine saves the mapping and enqueues an internal Signal carrying the identity; on the next Step the Execution records it and enters Waiting explicitly. That round trip keeps the Execution the single writer of its own state. The Engine wall clock never enters strategy input — business time is submitted as an explicit payload. Wait registration and its opening Signal are one mailbox operation. Restoring history uses the same opening, admission, and consumption rules: an answer closes its wait when consumed, and Process termination closes all remaining waits. Snapshots whose wait facts contradict that history are rejected. Child completions remain queued while their parent is Paused or waiting on another WaitID. Only an answer to the current WaitID releases Waiting; an explicit pause still requires Resume. Unaddressed Strategy input can also queue while Paused or waiting for children without releasing either state. WaitForChildren requires an explicit ChildWaitBoundary. The result boundary counts terminal children. The drained boundary counts children whose entire subtree satisfies Process.Join. All, any, and quorum count those facts in request order; none selects successful business outcomes or cancels losers. ChildWaitSatisfied carries the chosen boundary with the terminal results. Wait registration is nonblocking even when a child already reached its boundary. SignalChild and CancelChild declare controls over an exact direct child. The tree owner records the recipient change and ChildControlResult in one durable Effect settlement. Rejected ownership or mailbox admission is a definite failed receipt. Signals retain their caller-chosen deduplication identity and obey the recipient's safe boundary; cancellation records intent and requires a drained wait to establish resource release.
Each strategy declares its own safe consumption boundary and proves it with contract tests.
Process lifecycle ¶
A Process moves through StatusNotStarted, StatusRunning, and then one of StatusWaiting, StatusPaused, StatusCompleted, StatusFailed, StatusCanceled, StatusTimedOut, or StatusKilled.
A terminal state is decided jointly by the recorded control intent and the Step result, never inferred from error text or from context.Canceled alone. The matrix is matched in priority order: an explicit kill wins; then a reached deadline; then parent or host cancellation; then a contract violation, external failure, or panic; then legal completion. A committed terminal state is first-terminal-wins, so a late cancellation cannot overwrite it. An effect's own cancellation first reaches the strategy as a settlement Signal — a local failure is never promoted to a Process terminal state on its own. Process.RequestCancellation also terminates active descendants through their owned lifecycle. The surviving parent receives the ordinary completion Signal and its Strategy chooses the next transition. Cancellation uses the same checkpoint acknowledgment as every other terminal transition. Once applied, terminal intent cancels active Step, Dispatch, and child-admission contexts throughout the owned subtree without waiting for an ancestor's work to return. The owner still collects started external work. Initialization outcome and durability acknowledgments are not canceled. A late successful child initialization joins the tree under terminal intent before any Step. Process.Await establishes the Process result and immediate bookkeeping. Process.Join additionally waits for owned descendant calls and required acknowledgments in this runtime. It leaves unrelated siblings running and does not release the tree. A runtime failure in the subtree makes Join fail after its local calls return, even if this Process already published a result. Terminal Unknown settlements remain evidence of remote uncertainty after Join. Engine.Run composes Start, Join, and Await as one synchronous operation. It returns the root result only after the subtree finishes, or a RuntimeError if that completion fails. Canceling its context requests termination but does not abandon owned work or required acknowledgments.
A child-completion delivery failure is recorded as pending termination. Accepted external effects settle first, and any unknown identities remain in the terminal result. The pending failure survives tree capture.
A long-lived Engine retains completed trees for diagnostics and capture until the Host calls Engine.ReleaseTree. Release waits for all descendant work to settle, removes the tree from lookup, and leaves existing handles' results and runtime errors readable.
Signal identities, wait history, and descendants remain retained for that lifetime. Finite budgets and snapshot limits bound one execution; the kernel does not prune facts needed for deduplication or extend a tree indefinitely.
Engine.InspectTree is the sole live inspection entry. It composes existing ProcessSnapshot values with current job, commit, and freeze facts, and stays available while storage acknowledgment or a tree freeze blocks execution. Snapshots own lifecycle, usage, wait authority, and Unknown settlements; runtime work may be newer than a durable snapshot. Reports describe one owner turn, never drive execution, and add nothing to the recovery schema. Synchronous EventListener callbacks must not query, control, or Await their tree. Calls that forward the callback context receive ErrListenerReentrancy while that invocation is active. Different tree owners remain independently callable, but callbacks must avoid cyclic waits and return in bounded time. Engine.Close requires every tree's publication, bookkeeping, and owned work to finish in both durable and ephemeral mode. Join or Run establishes this subtree completion; any separately acquired freeze must also be released. Close(ctx) closes admission once and joins Engine-owned observation shutdown; canceling ctx ends only that caller's wait. DeltaListener callbacks must not call Close or FlushDeltas on their Engine because both join Delta delivery. Forwarding an active callback context makes those calls fail with ErrListenerReentrancy.
A durable writer can stop without terminating the logical execution. Storage failures and ownership conflicts reach Process.Await as a RuntimeError with no Result. The error preserves the original cause, the last acknowledged head, and uncertain Effect identities. EventRuntimeStopped describes this instance failure; it never substitutes for EventProcessFinished. Status and usage in durable mode project only acknowledged tree state. The Host reads its authoritative head before reactivation, since a lost commit response or another writer may have advanced it beyond the stopped instance's view.
Recovery ¶
ExecutionState is a discriminated envelope of a kind and an opaque payload. The kernel constrains the envelope and never interprets the payload recursively; each strategy owns and guards its own wire shape. A host may persist the envelope but must not parse it by kind and join strategy control flow. Recovery finds the Definition through an exact DeploymentRef; a global kind-to-factory switch is forbidden.
TreeSnapshot is the canonical recovery state of a complete root tree. It uses one current strict wire shape without a version envelope or migration dispatch; parsing validates the structure and the recorded domain facts. ProcessSnapshot is a single-Process diagnostic value and is not a recovery unit. Events and Delta values record attempts and observations only; they never substitute for an acknowledged TreeSnapshot. Committed events wait for durable acknowledgment. Event sequences describe publication within one runtime activation and restart when a nonterminal Process is restored; they do not change snapshot contents or trigger commits.
Strategies ¶
Built-in strategies live under strategy/. Each concrete package implements the public execution protocol; the directory itself defines no package or runtime contract. Host-defined strategies use the same protocol.
github.com/Tangerg/scope/agent/strategy/interaction implements ReAct-style model and tool loops with working context, delegates, and artifacts. github.com/Tangerg/scope/agent/strategy/planning owns goal-driven planning; its goap subpackage supplies a bounded search implementation selected by the Host. github.com/Tangerg/scope/agent/strategy/workflow implements ordered deterministic stages over a closed vocabulary, composing real child Processes. github.com/Tangerg/scope/agent/strategy/coordination composes bounded input gates, absolute deadlines, and first-success competition through the same child and wait contracts. github.com/Tangerg/scope/agent/strategy/collaboration runs bounded coordinator turns beside background workers. Decisions choose whether to continue while workers run, wait for drained results, or complete. The Strategy retains explicit working state and immutable child bindings; the Engine resolves and runs the children. Workflow child failures and collaboration coordinator failures preserve their original Failure kind, code, and diagnostic.
github.com/Tangerg/scope/agent/messaging delivers intermediate input through a narrow Host-authorized port, retaining the original recipient and Effect-derived Signal identity. Its sender and recipient acknowledge separately; it does not provide the direct-child control's single tree commit.
The Engine never imports or type-switches a concrete strategy. A new strategy is admitted by implementing the waist, state codec, and safe consumption boundary, and binding a dispatcher when it declares external Effects.
Boundaries ¶
A long-lived Host can run successive bounded root trees. The successive episodes example under Engine.Start establishes a completed, joined predecessor, seals input routing, reconciles SignalReceipts, and binds explicit successor state, Deployment, limits, and authority. Its Host transaction links the successor identity with the initial tree checkpoint; a lost start response is reconciled by restoring that identity. Calling Start with equal Input alone does not provide idempotent successor admission. Retained unconsumed inputs keep their predecessor address, and unresolved descendant Effects prevent the example's safe boundary. Production Hosts implement the transaction and retention policy in their own durable storage.
The framework owns definition validation, deployment freezing, the Process state machine, signal ordering and deduplication, effect identity and settlement, budgets, the lifecycle, framework events, and the snapshot and recovery protocol.
The host owns product identity, transports, stores and transactions, permissions and billing, deployment catalogs and routing, provider and model selection, storage acknowledgment, and retention of its own facts. A host depends only on this neutral lifecycle contract and never parses a strategy's snapshot payload.
Production database adapters and their storage-specific integration tests belong to the consuming application or an independently owned adapter. The agenttest package supplies shared durability and Definition conformance suites.
Chat, tools, embeddings, history, and telemetry stay in their own modules. Agent reuses them and duplicates none of them.
Index ¶
- Constants
- Variables
- type Budget
- type Capability
- type CapabilitySet
- func (c CapabilitySet) Allows(requested CapabilitySet) bool
- func (c CapabilitySet) Contains(capability Capability) bool
- func (CapabilitySet) JSONSchemaAlias() any
- func (c CapabilitySet) MarshalJSON() ([]byte, error)
- func (c *CapabilitySet) UnmarshalJSON(data []byte) error
- func (c CapabilitySet) Valid() bool
- func (c CapabilitySet) Values() []Capability
- type ChildControlResult
- func (c ChildControlResult) ChildID() ProcessID
- func (c ChildControlResult) Failure() (Failure, bool)
- func (ChildControlResult) JSONSchemaAlias() any
- func (c ChildControlResult) MarshalJSON() ([]byte, error)
- func (c ChildControlResult) Matches(effect Effect) bool
- func (c ChildControlResult) SignalID() (SignalID, bool)
- func (c *ChildControlResult) UnmarshalJSON(data []byte) error
- func (c ChildControlResult) Valid() bool
- type ChildKey
- type ChildOutcome
- type ChildSpec
- type ChildStartResult
- func (c ChildStartResult) DeploymentRef() DeploymentRef
- func (c ChildStartResult) Failure() (Failure, bool)
- func (ChildStartResult) JSONSchemaAlias() any
- func (c ChildStartResult) Key() ChildKey
- func (c ChildStartResult) MarshalJSON() ([]byte, error)
- func (c ChildStartResult) ProcessID() (ProcessID, bool)
- func (c *ChildStartResult) UnmarshalJSON(data []byte) error
- func (c ChildStartResult) Valid() bool
- type ChildWaitBoundary
- type ChildWaitCondition
- type ChildWaitOpened
- type ChildWaitSatisfied
- type ChildWaitSpec
- type Definition
- type Delta
- func (d Delta) EffectID() EffectID
- func (d Delta) EffectSequence() uint64
- func (d Delta) EmittedAt() time.Time
- func (d Delta) MarshalJSON() ([]byte, error)
- func (d Delta) Payload() json.RawMessage
- func (d Delta) ProcessID() ProcessID
- func (d Delta) TreeIncarnationID() (TreeIncarnationID, bool)
- func (d *Delta) UnmarshalJSON(data []byte) error
- func (d Delta) Valid() bool
- type DeltaDroppedFact
- type DeltaEmitter
- type DeltaListener
- type DeltaListenerFunc
- type Deployment
- type DeploymentConfig
- type DeploymentRef
- func (d DeploymentRef) ConfigurationDigest() Digest
- func (d DeploymentRef) ContractDigest() Digest
- func (d DeploymentRef) Digest() Digest
- func (d DeploymentRef) ImplementationDigest() Digest
- func (DeploymentRef) JSONSchemaAlias() any
- func (d DeploymentRef) MarshalJSON() ([]byte, error)
- func (d DeploymentRef) Name() string
- func (d DeploymentRef) String() string
- func (d *DeploymentRef) UnmarshalJSON(data []byte) error
- func (d DeploymentRef) Valid() bool
- type DeploymentResolver
- type Descriptor
- func (d Descriptor) DecodeOutput[T any](output Output) (T, error)
- func (d Descriptor) Description() string
- func (d Descriptor) Digest() Digest
- func (d Descriptor) EncodeInput[T any](value T) (Input, error)
- func (d Descriptor) InputSchema() Schema
- func (Descriptor) JSONSchemaAlias() any
- func (d Descriptor) MarshalJSON() ([]byte, error)
- func (d Descriptor) Name() string
- func (d Descriptor) OutputSchema() Schema
- func (d *Descriptor) UnmarshalJSON(data []byte) error
- func (d Descriptor) Valid() bool
- func (d Descriptor) ValidateInput(input Input) error
- func (d Descriptor) ValidateOutput(output Output) error
- type DescriptorConfig
- type Digest
- type Dispatcher
- type Effect
- func CancelChild(childID ProcessID, reason string) (Effect, error)
- func NewDispatcherEffect(payload json.RawMessage, required ...Capability) (Effect, error)
- func RequestWait(key WaitKey, signalPayload json.RawMessage) (Effect, error)
- func SignalChild(childID ProcessID, signal SignalRequest) (Effect, error)
- func StartChild(spec ChildSpec) (Effect, error)
- func WaitForChildren(spec ChildWaitSpec) (Effect, error)
- type EffectBoundary
- type EffectBoundaryKind
- type EffectFinishedFact
- type EffectID
- type EffectRequest
- func (e EffectRequest) BatchIndex() uint32
- func (e EffectRequest) DeploymentRef() DeploymentRef
- func (e EffectRequest) Effect() Effect
- func (e EffectRequest) ID() EffectID
- func (e EffectRequest) ProcessID() ProcessID
- func (e EffectRequest) Relation() ProcessRelation
- func (e EffectRequest) StepSequence() uint64
- func (e EffectRequest) TreeIncarnationID() (TreeIncarnationID, bool)
- func (e EffectRequest) Valid() bool
- type EffectStartedFact
- type EffectTarget
- type Engine
- func (e *Engine) CaptureTree(ctx context.Context, rootID ProcessID) (TreeSnapshot, error)
- func (e *Engine) Close(ctx context.Context) error
- func (e *Engine) FlushDeltas(ctx context.Context) error
- func (e *Engine) InspectTree(ctx context.Context, rootID ProcessID) (TreeInspection, error)
- func (e *Engine) ObservationFailures() ObservationFailures
- func (e *Engine) Process(id ProcessID) (*Process, bool)
- func (e *Engine) ReleaseTree(ctx context.Context, rootID ProcessID) error
- func (e *Engine) RestoreTree(ctx context.Context, rootDeployment Deployment, snapshot TreeSnapshot) (*Process, error)
- func (e *Engine) Run(ctx context.Context, deployment Deployment, input Input) (Result, error)
- func (e *Engine) Start(ctx context.Context, deployment Deployment, input Input) (*Process, error)
- type EngineConfig
- type Event
- func (e Event) DeltaDropped() (DeltaDroppedFact, bool)
- func (e Event) DeploymentRef() DeploymentRef
- func (e Event) EffectFinished() (EffectFinishedFact, bool)
- func (e Event) EffectID() (EffectID, bool)
- func (e Event) EffectStarted() (EffectStartedFact, bool)
- func (e Event) MarshalJSON() ([]byte, error)
- func (e Event) Name() string
- func (e Event) OccurredAt() time.Time
- func (e Event) Payload() json.RawMessage
- func (e Event) Phase() EventPhase
- func (e Event) ProcessFinished() (ProcessFinishedFact, bool)
- func (e Event) ProcessID() ProcessID
- func (e Event) ProcessSequence() uint64
- func (e Event) Relation() ProcessRelation
- func (e Event) RuntimeStopped() (RuntimeStoppedFact, bool)
- func (e Event) SignalAccepted() (SignalAcceptedFact, bool)
- func (e Event) StepCommitted() (StepCommittedFact, bool)
- func (e Event) StepFinished() (StepFinishedFact, bool)
- func (e Event) StepSequence() (uint64, bool)
- func (e Event) TreeIncarnationID() (TreeIncarnationID, bool)
- func (e *Event) UnmarshalJSON(data []byte) error
- func (e Event) Valid() bool
- type EventListener
- type EventListenerFunc
- type EventPhase
- type Execution
- type ExecutionState
- type Failure
- type FailureKind
- type Input
- type Limits
- type ListenerPanic
- type ObservationFailures
- type Output
- type Process
- func (p *Process) Await(ctx context.Context) (Result, error)
- func (p *Process) Budget() Budget
- func (p *Process) Capabilities() CapabilitySet
- func (p *Process) DeliverSignals(ctx context.Context, requests ...SignalRequest) (accepted bool, err error)
- func (p *Process) DeploymentRef() DeploymentRef
- func (p *Process) ID() ProcessID
- func (p *Process) Join(ctx context.Context) error
- func (p *Process) Kill(ctx context.Context, reason string) error
- func (p *Process) Pause(ctx context.Context, reason string) error
- func (p *Process) Relation() ProcessRelation
- func (p *Process) RequestCancellation(ctx context.Context, reason string) error
- func (p *Process) ResolveUnknownEffect(ctx context.Context, settlement Settlement) error
- func (p *Process) Resume(ctx context.Context) error
- func (p *Process) StartedAt() time.Time
- type ProcessAdmission
- type ProcessAdmitter
- type ProcessAdmitterFunc
- type ProcessFinishedFact
- type ProcessID
- type ProcessInitializationOutcome
- func (p ProcessInitializationOutcome) Admission() ProcessAdmission
- func (p ProcessInitializationOutcome) Failure() (Failure, bool)
- func (p ProcessInitializationOutcome) StartedAt() (time.Time, bool)
- func (p ProcessInitializationOutcome) Status() ProcessInitializationOutcomeStatus
- func (p ProcessInitializationOutcome) Valid() bool
- type ProcessInitializationOutcomeAcknowledger
- type ProcessInitializationOutcomeAcknowledgerFunc
- type ProcessInitializationOutcomeStatus
- type ProcessInspection
- type ProcessRelation
- func (p ProcessRelation) ChildKey() (ChildKey, bool)
- func (p ProcessRelation) Depth() uint32
- func (p ProcessRelation) IsRoot() bool
- func (p ProcessRelation) ParentID() (ProcessID, bool)
- func (p ProcessRelation) ProcessID() ProcessID
- func (p ProcessRelation) RootID() ProcessID
- func (p ProcessRelation) Valid() bool
- type ProcessSnapshot
- func (p ProcessSnapshot) Budget() Budget
- func (p ProcessSnapshot) Capabilities() CapabilitySet
- func (p ProcessSnapshot) CommittedExecutionState() ExecutionState
- func (p ProcessSnapshot) DeploymentRef() DeploymentRef
- func (p ProcessSnapshot) JSON() json.RawMessage
- func (p ProcessSnapshot) MarshalJSON() ([]byte, error)
- func (p ProcessSnapshot) ProcessID() ProcessID
- func (p ProcessSnapshot) Relation() ProcessRelation
- func (p ProcessSnapshot) SignalReceipts() []SignalReceipt
- func (p ProcessSnapshot) Status() Status
- func (p ProcessSnapshot) UnknownEffectIDs() []EffectID
- func (p *ProcessSnapshot) UnmarshalJSON(data []byte) error
- func (p ProcessSnapshot) Usage() Usage
- func (p ProcessSnapshot) Valid() bool
- func (p ProcessSnapshot) WaitID() (WaitID, bool)
- func (p ProcessSnapshot) WaitKind() (WaitKind, bool)
- type ProcessWork
- type ReplayPolicy
- type Result
- type RuntimeError
- type RuntimeStoppedFact
- type Schema
- type Settlement
- type SettlementStatus
- type Signal
- type SignalAcceptedFact
- type SignalID
- type SignalReceipt
- func (s SignalReceipt) ArrivalSequence() uint64
- func (s SignalReceipt) Consumed() bool
- func (s SignalReceipt) ID() SignalID
- func (s SignalReceipt) Matches(request SignalRequest) bool
- func (s SignalReceipt) PayloadDigest() Digest
- func (s SignalReceipt) PendingSignal() (Signal, bool)
- func (s SignalReceipt) WaitID() (WaitID, bool)
- type SignalRequest
- func (s SignalRequest) ID() SignalID
- func (SignalRequest) JSONSchemaAlias() any
- func (s SignalRequest) MarshalJSON() ([]byte, error)
- func (s SignalRequest) Payload() json.RawMessage
- func (s *SignalRequest) UnmarshalJSON(data []byte) error
- func (s SignalRequest) Valid() bool
- func (s SignalRequest) WaitID() (WaitID, bool)
- type Status
- type StepCommittedFact
- type StepFinishedFact
- type StepStatus
- type Termination
- func (t Termination) Cause() TerminationCause
- func (t Termination) Failure() (Failure, bool)
- func (Termination) JSONSchemaAlias() any
- func (t Termination) MarshalJSON() ([]byte, error)
- func (t Termination) Reason() string
- func (t Termination) Status() Status
- func (t *Termination) UnmarshalJSON(data []byte) error
- func (t Termination) UnresolvedEffectIDs() []EffectID
- func (t Termination) Valid() bool
- type TerminationCause
- type Transition
- func Complete(consumedSignals uint32, output Output) (Transition, error)
- func Continue(consumedSignals uint32, effects ...Effect) (Transition, error)
- func Fail(consumedSignals uint32, failure Failure) (Transition, error)
- func Pause(consumedSignals uint32, reason string) (Transition, error)
- func Wait(consumedSignals uint32, waitID WaitID) (Transition, error)
- func (t Transition) ConsumedSignals() uint32
- func (t Transition) Effects() []Effect
- func (t Transition) Failure() (Failure, bool)
- func (t Transition) Kind() TransitionKind
- func (t Transition) MarshalJSON() ([]byte, error)
- func (t Transition) Output() (Output, bool)
- func (t Transition) Reason() (string, bool)
- func (t *Transition) UnmarshalJSON(data []byte) error
- func (t Transition) Valid() bool
- func (t Transition) WaitID() (WaitID, bool)
- type TransitionKind
- type TreeActivation
- type TreeCheckpoint
- type TreeCheckpointKind
- type TreeDurability
- type TreeFreezePhase
- type TreeIncarnationID
- type TreeInspection
- type TreeLimits
- type TreeSnapshot
- func (t TreeSnapshot) Digest() Digest
- func (t TreeSnapshot) IncarnationID() (TreeIncarnationID, bool)
- func (t TreeSnapshot) JSON() json.RawMessage
- func (t TreeSnapshot) MarshalJSON() ([]byte, error)
- func (t TreeSnapshot) ProcessSnapshots() []ProcessSnapshot
- func (t TreeSnapshot) RootID() ProcessID
- func (t *TreeSnapshot) UnmarshalJSON(data []byte) error
- func (t TreeSnapshot) Valid() bool
- type Usage
- type WaitID
- type WaitKey
- type WaitKind
Examples ¶
Constants ¶
const ( // EventProcessStarted reports initial Process execution. EventProcessStarted = "agent.process.started" // EventProcessRestored reports execution resumed from a TreeSnapshot. EventProcessRestored = "agent.process.restored" // EventProcessPaused reports a committed scheduling pause. EventProcessPaused = "agent.process.paused" // EventProcessResumed reports committed scheduling resumption. EventProcessResumed = "agent.process.resumed" // EventProcessFinished reports one immutable terminal outcome. EventProcessFinished = "agent.process.finished" // EventRuntimeStopped reports loss of an active instance without a committed // logical terminal result. It never changes the durable Process lifecycle. EventRuntimeStopped = "agent.runtime.stopped" // EventSignalAccepted reports one newly accepted Signal. EventSignalAccepted = "agent.signal.accepted" // EventStepStarted reports an Execution.Step call about to begin. EventStepStarted = "agent.step.started" // EventStepFinished reports an Execution.Step return or failure. EventStepFinished = "agent.step.finished" // EventStepPrepared reports validated candidate Step state and fixed Effects. EventStepPrepared = "agent.step.prepared" // EventStepCommitted reports authoritative Step state publication. EventStepCommitted = "agent.step.committed" // EventEffectStarted reports a Framework or Dispatcher Effect attempt. EventEffectStarted = "agent.effect.started" // EventEffectFinished reports a definite or unknown attempt settlement. EventEffectFinished = "agent.effect.finished" // EventDeltaDropped reports best-effort increments lost to backpressure. EventDeltaDropped = "agent.delta.dropped" )
Variables ¶
var ( ErrInvalidEngineConfig = errors.New("agent: invalid engine configuration") ErrEngineClosed = errors.New("agent: engine is closed") ErrEngineHasActiveProcesses = errors.New("agent: engine has active processes") ErrProcessAlreadyExists = errors.New("agent: process identity already exists") )
var ( ErrSignalRejected = errors.New("agent: signal rejected") // ErrSignalConflict reports reuse of a SignalID with different immutable // content, including the addressed WaitID. ErrSignalConflict = errors.New("agent: signal identity conflicts with accepted content") )
var ( ErrProcessFinished = errors.New("agent: process has finished") ErrProcessNotRunning = errors.New("agent: process is not running") ErrEffectNotPending = errors.New("agent: effect does not require resolution") ErrInvalidProcessControl = errors.New("agent: invalid process control request") )
var ( ErrDurabilityConflict = errors.New("agent: durability boundary conflicts with committed content") ErrTreeIncarnationConflict = errors.New("agent: tree incarnation conflict") ErrTreeDurabilityMismatch = errors.New("agent: tree durability mode mismatch") )
var ( ErrInvalidInput = errors.New("agent: invalid input") ErrInvalidOutput = errors.New("agent: invalid output") )
var ErrInvalidCapability = errors.New("agent: invalid capability")
var ErrInvalidChildControl = errors.New("agent: invalid child control")
var ErrInvalidChildStart = errors.New("agent: invalid child process start")
var ErrInvalidChildWait = errors.New("agent: invalid child wait")
var ErrInvalidDelta = errors.New("agent: invalid delta")
var ErrInvalidDeployment = errors.New("agent: invalid deployment")
var ErrInvalidDeploymentRef = errors.New("agent: invalid deployment reference")
var ErrInvalidDescriptor = errors.New("agent: invalid descriptor")
var ErrInvalidDigest = errors.New("agent: invalid digest")
var ErrInvalidEffect = errors.New("agent: invalid effect")
var ErrInvalidEvent = errors.New("agent: invalid event")
var ErrInvalidExecutionState = errors.New("agent: invalid execution state")
var ErrInvalidFailure = errors.New("agent: invalid failure")
var ErrInvalidIdentity = errors.New("agent: invalid identity")
var ErrInvalidProcessRelation = errors.New("agent: invalid process relation")
var ErrInvalidSchema = errors.New("agent: invalid schema")
var ErrInvalidSettlement = errors.New("agent: invalid effect settlement")
var ErrInvalidSignal = errors.New("agent: invalid signal")
var ErrInvalidSignalRequest = errors.New("agent: invalid signal request")
var ErrInvalidSnapshot = errors.New("agent: invalid process snapshot")
var ErrInvalidStatus = errors.New("agent: invalid status")
var ErrInvalidTransition = errors.New("agent: invalid transition")
var ErrInvalidTreeIncarnationID = errors.New("agent: invalid tree incarnation identity")
var ErrInvalidTreeSnapshot = errors.New("agent: invalid process tree snapshot")
var ErrListenerReentrancy = errors.New("agent: operation would wait for its active listener")
ErrListenerReentrancy reports an operation that would wait for the active listener carrying its context: an EventListener's tree owner or a DeltaListener's delivery worker. Derived contexts retain this restriction until the callback returns. Replacing the context does not remove the listener's obligation to avoid waiting for itself.
var ErrProcessAdmissionRejected = errors.New("agent: process admission rejected")
ErrProcessAdmissionRejected marks failure at the policy boundary before execution starts.
var ErrResourceLimitExceeded = errors.New("agent: resource limit exceeded")
ErrResourceLimitExceeded reports a designed execution bound, not an Engine defect.
Functions ¶
This section is empty.
Types ¶
type Budget ¶
type Budget struct {
// Steps is the maximum committed Step count allocated to the child.
Steps uint64 `json:"steps"`
// Effects is the maximum prepared Effect count allocated to the child.
Effects uint64 `json:"effects"`
// Signals is the maximum accepted Signal count allocated to the child.
Signals uint64 `json:"signals"`
}
Budget is a non-renewable allocation of Framework-owned work units. A child allocation is permanently transferred from its parent's remaining budget; unused units are not silently reclaimed or duplicated. Remaining budget excludes the parent's prepared Step and its future settlement Signals. Construct allocations with named fields; child admission and capability constructors validate the complete allocation before it grants authority.
type Capability ¶
type Capability struct {
// contains filtered or unexported fields
}
Capability is one stable qualified authority name understood by a Deployment's dispatcher or another external boundary. The Framework only enforces possession and attenuation; it does not assign product meaning.
func ParseCapability ¶
func ParseCapability(name string) (Capability, error)
ParseCapability validates a lowercase qualified capability name.
func (Capability) JSONSchemaAlias ¶ added in v0.17.0
func (Capability) JSONSchemaAlias() any
func (Capability) MarshalText ¶
func (c Capability) MarshalText() ([]byte, error)
func (Capability) String ¶
func (c Capability) String() string
func (*Capability) UnmarshalText ¶
func (c *Capability) UnmarshalText(text []byte) error
func (Capability) Valid ¶
func (c Capability) Valid() bool
type CapabilitySet ¶
type CapabilitySet struct {
// contains filtered or unexported fields
}
CapabilitySet is an immutable, sorted set of authority names. Its zero value is the valid empty set, encoded as an empty JSON array. JSON null is invalid.
func NewCapabilitySet ¶
func NewCapabilitySet(capabilities ...Capability) (CapabilitySet, error)
NewCapabilitySet builds the frozen grant a Process runs under. It is a set rather than a slice because a duplicated or reordered grant must not change authority, and because every child grant must be a subset of its parent's.
func (CapabilitySet) Allows ¶
func (c CapabilitySet) Allows(requested CapabilitySet) bool
Allows reports whether requested is a subset of c.
func (CapabilitySet) Contains ¶
func (c CapabilitySet) Contains(capability Capability) bool
Contains reports whether capability belongs to the set.
func (CapabilitySet) JSONSchemaAlias ¶ added in v0.17.0
func (CapabilitySet) JSONSchemaAlias() any
func (CapabilitySet) MarshalJSON ¶
func (c CapabilitySet) MarshalJSON() ([]byte, error)
func (*CapabilitySet) UnmarshalJSON ¶
func (c *CapabilitySet) UnmarshalJSON(data []byte) error
func (CapabilitySet) Valid ¶
func (c CapabilitySet) Valid() bool
func (CapabilitySet) Values ¶
func (c CapabilitySet) Values() []Capability
Values returns an independently owned, sorted capability slice.
type ChildControlResult ¶ added in v0.18.0
type ChildControlResult struct {
// contains filtered or unexported fields
}
ChildControlResult is a definite tree-local admission result. SignalID is present for every signal attempt, including rejected delivery. Failure preserves rejected authority, wait, or resource admission without failing the sending Strategy implicitly.
func ParseChildControlResult ¶ added in v0.18.0
func ParseChildControlResult(signal Signal) (ChildControlResult, error)
ParseChildControlResult decodes an unaddressed Framework control settlement.
func (ChildControlResult) ChildID ¶ added in v0.18.0
func (c ChildControlResult) ChildID() ProcessID
func (ChildControlResult) Failure ¶ added in v0.18.0
func (c ChildControlResult) Failure() (Failure, bool)
func (ChildControlResult) JSONSchemaAlias ¶ added in v0.18.0
func (ChildControlResult) JSONSchemaAlias() any
func (ChildControlResult) MarshalJSON ¶ added in v0.18.0
func (c ChildControlResult) MarshalJSON() ([]byte, error)
func (ChildControlResult) Matches ¶ added in v0.18.0
func (c ChildControlResult) Matches(effect Effect) bool
Matches checks the operation and concrete recipient of the declared Effect. The enclosing settlement Signal retains the Engine-owned effect identity.
func (ChildControlResult) SignalID ¶ added in v0.18.0
func (c ChildControlResult) SignalID() (SignalID, bool)
func (*ChildControlResult) UnmarshalJSON ¶ added in v0.18.0
func (c *ChildControlResult) UnmarshalJSON(data []byte) error
func (ChildControlResult) Valid ¶ added in v0.18.0
func (c ChildControlResult) Valid() bool
type ChildKey ¶
type ChildKey struct {
// contains filtered or unexported fields
}
ChildKey is an Execution-owned stable identity for one logical child start. The Engine combines it with the parent Process identity and prepared Effect identity to make retries and restoration idempotent.
func ParseChildKey ¶
ParseChildKey validates an Execution-owned logical child identity.
func (ChildKey) JSONSchemaAlias ¶ added in v0.17.0
func (ChildKey) JSONSchemaAlias() any
func (ChildKey) MarshalText ¶
func (*ChildKey) UnmarshalText ¶
type ChildOutcome ¶
type ChildOutcome struct {
// contains filtered or unexported fields
}
ChildOutcome pairs a parent's logical ChildKey with one immutable terminal Process Result.
func (ChildOutcome) JSONSchemaAlias ¶ added in v0.17.0
func (ChildOutcome) JSONSchemaAlias() any
func (ChildOutcome) Key ¶
func (c ChildOutcome) Key() ChildKey
Key returns the parent-scoped logical child identity.
func (ChildOutcome) MarshalJSON ¶ added in v0.17.0
func (c ChildOutcome) MarshalJSON() ([]byte, error)
func (ChildOutcome) Result ¶
func (c ChildOutcome) Result() Result
Result returns the child's immutable terminal result.
func (*ChildOutcome) UnmarshalJSON ¶ added in v0.17.0
func (c *ChildOutcome) UnmarshalJSON(data []byte) error
func (ChildOutcome) Valid ¶
func (c ChildOutcome) Valid() bool
type ChildSpec ¶
type ChildSpec struct {
// Key is the parent-scoped logical identity of this child start.
Key ChildKey `json:"key"`
// DeploymentRef identifies the exact child behavior binding.
DeploymentRef DeploymentRef `json:"deployment_ref"`
// Input is the portable input validated by the target Descriptor.
Input Input `json:"input"`
// Budget is permanently allocated from the parent to this child.
Budget Budget `json:"budget"`
// Capabilities is the attenuated authority granted to this child.
Capabilities CapabilitySet `json:"capabilities"`
}
ChildSpec is the complete Strategy-declared intent for one child Process. Input is validated by the target Deployment before any Process is created.
type ChildStartResult ¶
type ChildStartResult struct {
// contains filtered or unexported fields
}
ChildStartResult is the definite result of one StartChild Effect. Success contains the Engine-created child ProcessID; failure contains a stable Framework Failure and never masquerades as an unknown external outcome.
func ParseChildStartResult ¶
func ParseChildStartResult(signal Signal) (ChildStartResult, error)
ParseChildStartResult decodes a Framework-owned child-start settlement Signal. The Signal must not address a wait.
func (ChildStartResult) DeploymentRef ¶
func (c ChildStartResult) DeploymentRef() DeploymentRef
DeploymentRef returns the exact child execution binding.
func (ChildStartResult) Failure ¶
func (c ChildStartResult) Failure() (Failure, bool)
Failure returns the definite start failure and true when no child was created.
func (ChildStartResult) JSONSchemaAlias ¶ added in v0.17.0
func (ChildStartResult) JSONSchemaAlias() any
func (ChildStartResult) Key ¶
func (c ChildStartResult) Key() ChildKey
Key returns the logical child identity declared by the Execution.
func (ChildStartResult) MarshalJSON ¶ added in v0.17.0
func (c ChildStartResult) MarshalJSON() ([]byte, error)
func (ChildStartResult) ProcessID ¶
func (c ChildStartResult) ProcessID() (ProcessID, bool)
ProcessID returns the created child identity and true on success.
func (*ChildStartResult) UnmarshalJSON ¶ added in v0.17.0
func (c *ChildStartResult) UnmarshalJSON(data []byte) error
func (ChildStartResult) Valid ¶
func (c ChildStartResult) Valid() bool
type ChildWaitBoundary ¶ added in v0.17.0
type ChildWaitBoundary string
ChildWaitBoundary selects the lifecycle fact counted by a child wait.
const ( ChildWaitBoundaryResult ChildWaitBoundary = "terminal_result" ChildWaitBoundaryDrained ChildWaitBoundary = "subtree_drained" )
func (ChildWaitBoundary) String ¶ added in v0.17.0
func (c ChildWaitBoundary) String() string
func (ChildWaitBoundary) Valid ¶ added in v0.17.0
func (c ChildWaitBoundary) Valid() bool
type ChildWaitCondition ¶
type ChildWaitCondition struct {
// contains filtered or unexported fields
}
ChildWaitCondition identifies when a set of child Processes releases its parent. It counts children at the requested boundary; it does not cancel unfinished children or reinterpret child terminal statuses.
func AllChildren ¶
func AllChildren() ChildWaitCondition
AllChildren waits until every named child reaches the requested boundary.
func AnyChild ¶
func AnyChild() ChildWaitCondition
AnyChild waits until at least one named child reaches the requested boundary.
func ChildQuorum ¶
func ChildQuorum(count uint32) (ChildWaitCondition, error)
ChildQuorum waits until count named children reach the requested boundary.
func (ChildWaitCondition) Valid ¶
func (c ChildWaitCondition) Valid() bool
type ChildWaitOpened ¶
type ChildWaitOpened struct {
// contains filtered or unexported fields
}
ChildWaitOpened is the definite acknowledgement that the Engine registered a child wait and minted its WaitID.
func ParseChildWaitOpened ¶
func ParseChildWaitOpened(signal Signal) (ChildWaitOpened, error)
ParseChildWaitOpened decodes the settlement Signal produced by WaitForChildren and verifies its Engine-attached WaitID.
func (ChildWaitOpened) Spec ¶
func (c ChildWaitOpened) Spec() ChildWaitSpec
Spec returns the immutable child-wait request acknowledged by Engine.
func (ChildWaitOpened) Valid ¶
func (c ChildWaitOpened) Valid() bool
func (ChildWaitOpened) WaitID ¶
func (c ChildWaitOpened) WaitID() WaitID
WaitID returns the Engine-minted wait identity to store in Execution state.
type ChildWaitSatisfied ¶ added in v0.17.0
type ChildWaitSatisfied struct {
// contains filtered or unexported fields
}
ChildWaitSatisfied is one condition-satisfying, request-ordered child result set. For any or quorum it includes every child at the requested boundary at the atomic satisfaction check, without canceling or omitting based on status.
func ParseChildWaitSatisfied ¶ added in v0.17.0
func ParseChildWaitSatisfied(signal Signal) (ChildWaitSatisfied, error)
ParseChildWaitSatisfied decodes an Engine-generated, WaitID-addressed child wait-satisfaction Signal.
func (ChildWaitSatisfied) Boundary ¶ added in v0.17.0
func (c ChildWaitSatisfied) Boundary() ChildWaitBoundary
Boundary identifies the lifecycle fact established by this wait.
func (ChildWaitSatisfied) Key ¶ added in v0.17.0
func (c ChildWaitSatisfied) Key() WaitKey
Key returns the logical wait key declared by the Execution.
func (ChildWaitSatisfied) Outcomes ¶ added in v0.17.0
func (c ChildWaitSatisfied) Outcomes() []ChildOutcome
Outcomes returns terminal children in the original ChildWaitSpec order.
func (ChildWaitSatisfied) Valid ¶ added in v0.17.0
func (c ChildWaitSatisfied) Valid() bool
func (ChildWaitSatisfied) WaitID ¶ added in v0.17.0
func (c ChildWaitSatisfied) WaitID() WaitID
WaitID returns the addressed wait identity.
type ChildWaitSpec ¶
type ChildWaitSpec struct {
// Key is the Execution-owned logical identity of this wait request.
Key WaitKey
// Children lists direct child identities in result order.
Children []ProcessID
// Boundary explicitly selects terminal results or joined subtrees. A joined
// subtree has completed its owned local work and required acknowledgments in
// this runtime, as defined by Process.Join; remote uncertainty may remain.
Boundary ChildWaitBoundary
// Condition declares how many listed children must reach Boundary.
Condition ChildWaitCondition
}
ChildWaitSpec names one stable logical wait, its direct children in result order, lifecycle boundary, and count predicate.
func (ChildWaitSpec) Valid ¶
func (c ChildWaitSpec) Valid() bool
type Definition ¶
type Definition interface {
// Descriptor returns the immutable, portable contract shared by every
// Execution created from this definition. Repeated and concurrent calls must
// return an equivalent value; runtime configuration and mutable state do not
// belong in the descriptor.
Descriptor() Descriptor
// Start validates input against Descriptor and creates a fresh, isolated
// Execution without performing external I/O. The returned Execution has not
// executed a Step and must not share mutable state with another Process.
Start(input Input) (Execution, error)
// Restore reconstructs one Execution from a state previously produced by
// Snapshot for this exact definition. The caller must supply the matching
// definition; Engine enforces this with the snapshot's exact DeploymentRef.
// Restore validates state structure and strategy invariants without replaying
// external work. Opaque state need not independently identify its deployment.
Restore(state ExecutionState) (Execution, error)
}
Definition is an immutable Agent behavior definition. Its methods may be called concurrently for different Processes. Implementations create a fresh Execution from validated Input or restore one from their own opaque ExecutionState. Definition methods must not depend on Host product identities, storage protocols, or mutable global registration.
Example ¶
An independently authored Definition binds through the same Deployment and Engine contracts as built-in strategies. TestExternalPackageCanComposeAndRunDefinition checks this implementation with agenttest.RunDefinitionConformance.
package main
import (
"context"
"encoding/json"
jsonv2 "encoding/json/v2"
"fmt"
"sync/atomic"
"github.com/Tangerg/scope/agent"
)
type echoInput struct {
Value string `json:"value"`
}
type echoOutput struct {
Value string `json:"value"`
}
type echoDefinition struct {
descriptor agent.Descriptor
}
type echoState struct {
Phase string `json:"phase"`
Value string `json:"value"`
}
func (e echoDefinition) Descriptor() agent.Descriptor { return e.descriptor }
func (e echoDefinition) Start(input agent.Input) (agent.Execution, error) {
if err := e.descriptor.ValidateInput(input); err != nil {
return nil, err
}
value, err := input.Decode[echoInput]()
if err != nil {
return nil, err
}
return &echoExecution{state: echoState{Phase: "ready", Value: value.Value}}, nil
}
func (echoDefinition) Restore(state agent.ExecutionState) (agent.Execution, error) {
if !state.Valid() || state.Kind() != "example.echo" {
return nil, agent.ErrInvalidExecutionState
}
var value echoState
if err := jsonv2.Unmarshal(state.Payload(), &value, jsonv2.RejectUnknownMembers(true)); err != nil {
return nil, err
}
switch value.Phase {
case "ready", "awaiting_echo", "completed":
return &echoExecution{state: value}, nil
default:
return nil, agent.ErrInvalidExecutionState
}
}
type echoExecution struct {
state echoState
}
func (e *echoExecution) Step(ctx context.Context, signals []agent.Signal) (agent.Transition, error) {
if err := ctx.Err(); err != nil {
return agent.Transition{}, err
}
switch e.state.Phase {
case "ready":
if len(signals) != 0 {
return agent.Transition{}, agent.ErrInvalidSignal
}
payload, err := json.Marshal(echoInput{Value: e.state.Value})
if err != nil {
return agent.Transition{}, err
}
effect, err := agent.NewDispatcherEffect(payload)
if err != nil {
return agent.Transition{}, err
}
e.state.Phase = "awaiting_echo"
return agent.Continue(0, effect)
case "awaiting_echo":
if len(signals) != 1 {
return agent.Transition{}, agent.ErrInvalidSignal
}
var result echoOutput
if err := jsonv2.Unmarshal(signals[0].Payload(), &result, jsonv2.RejectUnknownMembers(true)); err != nil {
return agent.Transition{}, err
}
output, err := agent.EncodeOutput(result)
if err != nil {
return agent.Transition{}, err
}
e.state.Phase = "completed"
return agent.Complete(1, output)
default:
return agent.Transition{}, agent.ErrInvalidExecutionState
}
}
func (e *echoExecution) Snapshot() (agent.ExecutionState, error) {
payload, err := json.Marshal(e.state)
if err != nil {
return agent.ExecutionState{}, err
}
return agent.NewExecutionState("example.echo", payload)
}
func newEchoDefinition() (echoDefinition, error) {
inputSchema, err := agent.SchemaFor[echoInput]()
if err != nil {
return echoDefinition{}, err
}
outputSchema, err := agent.SchemaFor[echoOutput]()
if err != nil {
return echoDefinition{}, err
}
descriptor, err := agent.NewDescriptor(agent.DescriptorConfig{
Name: "example.echo", Description: "Echoes a value through an Engine-managed Effect.",
InputSchema: inputSchema, OutputSchema: outputSchema,
})
if err != nil {
return echoDefinition{}, err
}
return echoDefinition{descriptor: descriptor}, nil
}
// echoDispatcher has no external mutation, so repeating an identity is safe.
type echoDispatcher struct{}
func (echoDispatcher) Dispatch(ctx context.Context, request agent.EffectRequest, emit agent.DeltaEmitter) (agent.Settlement, error) {
if err := ctx.Err(); err != nil {
return agent.Settlement{}, err
}
payload := request.Effect().Payload()
emit(payload)
return agent.NewSettlement(request.ID(), agent.SettlementStatusSucceeded, payload)
}
func (echoDispatcher) ReplayPolicy(agent.Effect) agent.ReplayPolicy {
return agent.ReplayPolicySameIdentity
}
// countingDispatcher counts attempts, including replay, rather than logical operations.
type countingDispatcher struct {
next agent.Dispatcher
attempts atomic.Int64
}
func (c *countingDispatcher) Dispatch(ctx context.Context, request agent.EffectRequest, emit agent.DeltaEmitter) (agent.Settlement, error) {
c.attempts.Add(1)
return c.next.Dispatch(ctx, request, emit)
}
func (c *countingDispatcher) ReplayPolicy(effect agent.Effect) agent.ReplayPolicy {
return c.next.ReplayPolicy(effect)
}
// An independently authored Definition binds through the same Deployment and
// Engine contracts as built-in strategies. TestExternalPackageCanComposeAndRunDefinition
// checks this implementation with agenttest.RunDefinitionConformance.
func main() {
ctx := context.Background()
definition, err := newEchoDefinition()
if err != nil {
panic(err)
}
dispatcher := &countingDispatcher{next: echoDispatcher{}}
deployment, err := agent.NewDeployment(agent.DeploymentConfig{
Definition: definition, Dispatcher: dispatcher,
ImplementationDigest: agent.ComputeDigest([]byte("example-echo-implementation")),
ConfigurationDigest: agent.ComputeDigest([]byte("example-echo-configuration")),
})
if err != nil {
panic(err)
}
engine, err := agent.NewEngine(agent.EngineConfig{})
if err != nil {
panic(err)
}
defer func() {
if closeErr := engine.Close(ctx); closeErr != nil {
panic(closeErr)
}
}()
input, err := definition.Descriptor().EncodeInput(echoInput{Value: "hello"})
if err != nil {
panic(err)
}
process, err := engine.Start(ctx, deployment, input)
if err != nil {
panic(err)
}
result, err := process.Await(ctx)
if err != nil {
panic(err)
}
if joinErr := process.Join(ctx); joinErr != nil {
panic(joinErr)
}
output, ok := result.Output()
if !ok {
panic("completed Result has no Output")
}
value, err := definition.Descriptor().DecodeOutput[echoOutput](output)
if err != nil {
panic(err)
}
inspection, err := engine.InspectTree(ctx, result.ProcessID())
if err != nil {
panic(err)
}
report, found := inspection.Process(result.ProcessID())
if !found {
panic("completed Process is absent from its tree")
}
if err := engine.ReleaseTree(context.Background(), result.ProcessID()); err != nil {
panic(err)
}
fmt.Println(result.Status(), value.Value, dispatcher.attempts.Load())
fmt.Println("inspected:", report.Snapshot.Status(), report.Snapshot.Usage().PreparedEffects)
}
Output: completed hello 1 inspected: completed 1
type Delta ¶
type Delta struct {
// contains filtered or unexported fields
}
Delta is a bounded, best-effort stream increment from one Effect attempt. EffectSequence preserves emitter admission order. Delta is never replayed from a snapshot and never contributes to the authoritative final Output.
func (Delta) EffectID ¶
EffectID identifies the logical Effect and remains stable across replay attempts.
func (Delta) EffectSequence ¶
EffectSequence returns the one-based emitter admission order within the Effect attempt. Delivered sequences increase; dropped payloads leave gaps.
func (Delta) MarshalJSON ¶
func (Delta) Payload ¶
func (d Delta) Payload() json.RawMessage
Payload returns an independently owned Strategy-defined increment.
func (Delta) TreeIncarnationID ¶
func (d Delta) TreeIncarnationID() (TreeIncarnationID, bool)
TreeIncarnationID returns the active durable writer that emitted this delta. Deltas from ephemeral trees return false.
func (*Delta) UnmarshalJSON ¶
type DeltaDroppedFact ¶
type DeltaDroppedFact struct {
// contains filtered or unexported fields
}
DeltaDroppedFact reports the number of increments rejected during one Effect attempt because validation failed or the bounded observation queue was full.
func (DeltaDroppedFact) Count ¶
func (d DeltaDroppedFact) Count() uint64
func (DeltaDroppedFact) Valid ¶
func (d DeltaDroppedFact) Valid() bool
type DeltaEmitter ¶
type DeltaEmitter func(payload json.RawMessage)
DeltaEmitter accepts Strategy-owned streaming payloads while Dispatch is active. The Engine validates, orders, bounds, and publishes each payload as a best-effort Delta. Concurrent calls are serialized in emitter admission order; delivered EffectSequence values increase, with gaps for dropped payloads. It intentionally returns no observer error. A Dispatcher must join concurrent emissions before returning and must not retain or call emit afterward.
type DeltaListener ¶
type DeltaListener interface {
// OnDelta receives an accepted best-effort increment in queue order. Delivery
// is sequential per listener but may lag Process execution; slow callbacks can
// cause later increments to be dropped. It has no acknowledgment authority;
// Engine.Close and FlushDeltas still wait for accepted callback delivery.
// Close and FlushDeltas using this context, or a derived context, return
// [ErrListenerReentrancy] while this invocation is active because both would
// wait for the worker delivering this callback.
OnDelta(ctx context.Context, delta Delta)
}
DeltaListener observes best-effort Strategy streaming increments. Panics are isolated; all listeners and trees share one Engine queue and delivery worker. A slow callback delays the other listeners and trees and can cause bounded queue drops. Implementations must return in bounded time without closing or flushing their Engine.
type DeltaListenerFunc ¶
DeltaListenerFunc adapts a plain function to the delta listener interface. It returns nothing for the same reason as EventListenerFunc, and because a dropped delta must never change execution.
type Deployment ¶
type Deployment struct {
// contains filtered or unexported fields
}
Deployment is an immutable binding of one Definition, its optional external Dispatcher, and an exact value reference used by Process snapshots.
func NewDeployment ¶
func NewDeployment(config DeploymentConfig) (Deployment, error)
NewDeployment freezes a Definition and Dispatcher under explicit implementation and configuration digests. That binding lets recovery resolve the exact behavior a snapshot names instead of whatever now answers to the same Definition name.
func (Deployment) Definition ¶
func (d Deployment) Definition() Definition
Definition returns the erased behavior definition bound to this Deployment.
func (Deployment) DeploymentRef ¶
func (d Deployment) DeploymentRef() DeploymentRef
DeploymentRef returns the exact value identity stored in Process snapshots.
func (Deployment) Descriptor ¶
func (d Deployment) Descriptor() Descriptor
Descriptor returns the frozen static Definition contract.
func (Deployment) Valid ¶
func (d Deployment) Valid() bool
Valid checks the frozen binding without invoking user code. The Engine checks the live Definition contract at startup and restoration boundaries.
type DeploymentConfig ¶
type DeploymentConfig struct {
// Definition owns the Strategy contract and creates per-Process execution.
Definition Definition
// Dispatcher interprets this Definition's external Effects. Nil binds a
// Definition that uses only Framework Effects; a dispatcher-targeted Effect
// then fails admission before any Effect in its Step can execute.
Dispatcher Dispatcher
// ImplementationDigest identifies the exact executable Definition artifact.
ImplementationDigest Digest
// ConfigurationDigest identifies all frozen behavior-affecting Definition
// and Dispatcher configuration.
ConfigurationDigest Digest
}
DeploymentConfig contains the complete behavior binding of one Deployment. The digests must cover the exact code artifact and all frozen dispatcher or Strategy configuration that can affect execution or restoration.
type DeploymentRef ¶
type DeploymentRef struct {
// contains filtered or unexported fields
}
DeploymentRef is the immutable value identity of one exact Definition implementation and frozen execution configuration. It contains no registry pointer and is sufficient to reject restore against a different Deployment.
func (DeploymentRef) ConfigurationDigest ¶
func (d DeploymentRef) ConfigurationDigest() Digest
ConfigurationDigest returns the frozen behavior-affecting configuration identity, including dispatcher configuration.
func (DeploymentRef) ContractDigest ¶
func (d DeploymentRef) ContractDigest() Digest
ContractDigest returns the exact Descriptor contract identity.
func (DeploymentRef) Digest ¶
func (d DeploymentRef) Digest() Digest
Digest returns the complete Deployment value identity.
func (DeploymentRef) ImplementationDigest ¶
func (d DeploymentRef) ImplementationDigest() Digest
ImplementationDigest returns the exact executable implementation identity.
func (DeploymentRef) JSONSchemaAlias ¶ added in v0.17.0
func (DeploymentRef) JSONSchemaAlias() any
func (DeploymentRef) MarshalJSON ¶
func (d DeploymentRef) MarshalJSON() ([]byte, error)
func (DeploymentRef) Name ¶
func (d DeploymentRef) Name() string
Name returns the stable Definition name.
func (DeploymentRef) String ¶
func (d DeploymentRef) String() string
func (*DeploymentRef) UnmarshalJSON ¶
func (d *DeploymentRef) UnmarshalJSON(data []byte) error
func (DeploymentRef) Valid ¶
func (d DeploymentRef) Valid() bool
type DeploymentResolver ¶
type DeploymentResolver interface {
// Resolve returns the immutable binding for exactly reference. It must not
// fall back by name, perform routing or remote discovery, or retain
// caller state. Missing and mismatched bindings are errors; concurrent calls
// must be safe.
Resolve(reference DeploymentRef) (Deployment, error)
}
DeploymentResolver performs one bounded, deterministic, context-free lookup of an exact immutable Deployment. The Engine accepts only a result whose reference exactly matches the requested reference. Implementations must be safe for concurrent use, must not perform remote I/O, and must not re-enter any Process. Routing and caller-specific selection happen before an exact DeploymentRef reaches this contract.
type Descriptor ¶
type Descriptor struct {
// contains filtered or unexported fields
}
Descriptor is an immutable Definition contract. It contains no executable behavior or Deployment configuration.
func NewDescriptor ¶
func NewDescriptor(config DescriptorConfig) (Descriptor, error)
NewDescriptor validates the schemas at construction because they enter the Deployment digest. A schema accepted here and rejected later would change a Deployment's identity after Processes had already been started against it.
Example ¶
package main
import (
"fmt"
"github.com/Tangerg/scope/agent"
)
func main() {
schema, err := agent.SchemaFor[string]()
if err != nil {
panic(err)
}
descriptor, err := agent.NewDescriptor(agent.DescriptorConfig{
Name: "example.echo",
Description: "Returns the supplied text.",
InputSchema: schema,
OutputSchema: schema,
})
if err != nil {
panic(err)
}
fmt.Println(descriptor.Name(), descriptor.Valid())
}
Output: example.echo true
func (Descriptor) DecodeOutput ¶
func (d Descriptor) DecodeOutput[T any](output Output) (T, error)
DecodeOutput validates output against this Descriptor's authoritative output schema and strictly decodes it into T.
func (Descriptor) Description ¶
func (d Descriptor) Description() string
Description returns the human-readable purpose of the Definition.
func (Descriptor) Digest ¶
func (d Descriptor) Digest() Digest
Digest returns the SHA-256 identity of the complete descriptor contract.
func (Descriptor) EncodeInput ¶
func (d Descriptor) EncodeInput[T any](value T) (Input, error)
EncodeInput converts value into an Input and validates it against this Descriptor's authoritative input schema.
func (Descriptor) InputSchema ¶
func (d Descriptor) InputSchema() Schema
InputSchema returns an independently owned schema value.
func (Descriptor) JSONSchemaAlias ¶ added in v0.18.0
func (Descriptor) JSONSchemaAlias() any
func (Descriptor) MarshalJSON ¶
func (d Descriptor) MarshalJSON() ([]byte, error)
func (Descriptor) OutputSchema ¶
func (d Descriptor) OutputSchema() Schema
OutputSchema returns an independently owned schema value.
func (*Descriptor) UnmarshalJSON ¶
func (d *Descriptor) UnmarshalJSON(data []byte) error
func (Descriptor) Valid ¶
func (d Descriptor) Valid() bool
func (Descriptor) ValidateInput ¶
func (d Descriptor) ValidateInput(input Input) error
func (Descriptor) ValidateOutput ¶
func (d Descriptor) ValidateOutput(output Output) error
type DescriptorConfig ¶
type DescriptorConfig struct {
// Name is a stable lowercase qualified Definition name.
Name string
// Description states the Definition's behavior for human and model-facing
// discovery without execution-specific state.
Description string
// InputSchema is the authoritative structural contract for Process input.
InputSchema Schema
// OutputSchema is the authoritative structural contract for completed output.
OutputSchema Schema
}
DescriptorConfig contains the complete static contract of a Definition. Executable implementation and frozen configuration identity belong to a Deployment, not this contract.
type Digest ¶
type Digest struct {
// contains filtered or unexported fields
}
Digest is a canonical SHA-256 content identity. Its zero value is invalid.
func ComputeDigest ¶
ComputeDigest returns the canonical SHA-256 identity of data. Callers that assemble a Deployment use it for reproducible implementation artifacts and canonical frozen configuration bytes.
func ParseDigest ¶
ParseDigest validates a canonical sha256:<lowercase-hex> identity.
func (Digest) JSONSchemaAlias ¶ added in v0.17.0
func (Digest) MarshalText ¶
func (*Digest) UnmarshalText ¶
type Dispatcher ¶
type Dispatcher interface {
// Dispatch performs one frozen Strategy Effect outside Execution.Step.
// Settlement must address request.ID; a non-nil error means the external
// outcome is unknown, not definitely failed. emit is valid only during this
// call. The runtime cancels ctx when it applies terminal intent to this
// Process or an ancestor. It still collects the returned settlement; ctx
// cancellation alone proves no external outcome. Host context values are
// preserved. Implementations honor ctx and may be called concurrently.
Dispatch(ctx context.Context, request EffectRequest, emit DeltaEmitter) (Settlement, error)
// ReplayPolicy declares, without I/O or mutable side effects, whether this
// exact Effect can be repeated under its original EffectID when restoring
// a pending attempt. A settled Unknown requires explicit adjudication, and
// terminal intent forbids replay. The answer is deterministic for equivalent
// Effects.
ReplayPolicy(effect Effect) ReplayPolicy
}
Dispatcher executes Strategy-owned Effects outside Execution.Step. It must return a Settlement addressed to request.ID. A returned error means the Engine cannot prove the external result and records an unknown settlement. The same Dispatcher may serve Processes concurrently; implementations must be concurrency-safe, return in bounded time, not mutate an Execution, and not start unowned goroutines. ReplayPolicy must be a pure, deterministic declaration for the supplied immutable Effect. The Engine always supplies a non-nil context. Direct callers must do the same; a nil context is a programming error, not an unknown external outcome.
A transparent decorator preserves the context, complete request identity, emitter, Settlement, and error of its wrapped Dispatcher. Its ReplayPolicy must also account for its own behavior: forwarding a SameIdentity claim is valid only when the added work is safe to repeat under the original identity. Observation counters may count dispatch attempts, including replay; they do not count distinct logical external operations. See the Definition example for a concurrency-safe attempt counter around a bound Dispatcher.
type Effect ¶
type Effect struct {
// contains filtered or unexported fields
}
Effect is an immutable request for an operation outside Execution.Step. Payload is frozen before dispatch and interpreted only by Target's owner. EffectID is deliberately absent because the Engine assigns it during prepare.
func CancelChild ¶ added in v0.18.0
CancelChild declares cancellation of an exact direct child's subtree. The receipt confirms the recorded intent, not termination or resource release; use a drained child wait before reusing exclusive resources. An already terminal direct child succeeds without changing its result.
func NewDispatcherEffect ¶
func NewDispatcherEffect(payload json.RawMessage, required ...Capability) (Effect, error)
NewDispatcherEffect carries an opaque payload plus the capabilities it requires, so the Engine can refuse an effect the Process was never granted without understanding what the effect does. Keeping the payload opaque is what stops model and tool vocabulary from entering the kernel.
func RequestWait ¶
func RequestWait(key WaitKey, signalPayload json.RawMessage) (Effect, error)
RequestWait creates the Framework Effect that asks the Engine to mint one WaitID for key. signalPayload remains Strategy-owned and is returned unchanged in the internal Signal that carries the minted WaitID back to the Execution.
func SignalChild ¶ added in v0.18.0
func SignalChild(childID ProcessID, signal SignalRequest) (Effect, error)
SignalChild declares delivery through the child's ordinary mailbox contract. It cannot release an unrelated wait or preempt in-flight external work. Delivery and the parent Effect settlement share one tree acknowledgment. The exact SignalRequest retains its caller-chosen deduplication identity. Cross-tree delivery remains a Host-authorized messaging operation.
func StartChild ¶
StartChild creates a Framework-owned Effect requesting one independently managed child Process. The Engine derives the child ProcessID; Execution code cannot construct or start the Process directly.
func WaitForChildren ¶
func WaitForChildren(spec ChildWaitSpec) (Effect, error)
WaitForChildren creates a Framework Effect that opens an Engine-owned wait over direct children. Dispatch returns immediately with a WaitID; child work never blocks Execution.Step or holds a prepared Step open.
func (Effect) MarshalJSON ¶
func (Effect) Payload ¶
func (e Effect) Payload() json.RawMessage
Payload returns an independently owned copy of the operation intent.
func (Effect) RequiredCapabilities ¶
func (e Effect) RequiredCapabilities() CapabilitySet
RequiredCapabilities returns the immutable authority set the Process must possess before this Dispatcher Effect may be prepared.
func (Effect) Target ¶
func (e Effect) Target() EffectTarget
Target returns the owner responsible for interpreting Payload.
func (*Effect) UnmarshalJSON ¶
type EffectBoundary ¶
type EffectBoundary struct {
// contains filtered or unexported fields
}
EffectBoundary binds an Effect fact to its prospective tree so a Host cannot acknowledge dispatch or settlement independently of recovery state. External dispatch uses a pending permission followed by settlement. Tree-local child controls settle directly, atomically with the recipient's mailbox or intent; they perform no external I/O requiring a pending dispatch permission.
func (EffectBoundary) Kind ¶
func (e EffectBoundary) Kind() EffectBoundaryKind
func (EffectBoundary) PreviousTreeDigest ¶
func (e EffectBoundary) PreviousTreeDigest() Digest
func (EffectBoundary) Request ¶
func (e EffectBoundary) Request() EffectRequest
func (EffectBoundary) Settlement ¶
func (e EffectBoundary) Settlement() (Settlement, bool)
func (EffectBoundary) TreeSnapshot ¶
func (e EffectBoundary) TreeSnapshot() TreeSnapshot
func (EffectBoundary) Valid ¶
func (e EffectBoundary) Valid() bool
type EffectBoundaryKind ¶
type EffectBoundaryKind string
EffectBoundaryKind is closed because recovery needs a defined continuation for every acknowledged external Effect boundary.
const ( EffectBoundaryInvalid EffectBoundaryKind = "" EffectBoundaryPending EffectBoundaryKind = "pending" EffectBoundarySettled EffectBoundaryKind = "settled" EffectBoundaryResolved EffectBoundaryKind = "resolved" )
func (EffectBoundaryKind) String ¶
func (e EffectBoundaryKind) String() string
func (EffectBoundaryKind) Valid ¶
func (e EffectBoundaryKind) Valid() bool
type EffectFinishedFact ¶
type EffectFinishedFact struct {
// contains filtered or unexported fields
}
EffectFinishedFact is the immutable settlement observation for one Effect attempt. It does not replace the durable Effect boundary.
func (EffectFinishedFact) Duration ¶
func (e EffectFinishedFact) Duration() time.Duration
func (EffectFinishedFact) Failure ¶ added in v0.18.0
func (e EffectFinishedFact) Failure() (FailureKind, string, bool)
Failure classifies a Dispatcher error that made its outcome Unknown. It contains no diagnostic message and does not change the settlement semantics. An Unknown returned directly by the Dispatcher has no error classification.
func (EffectFinishedFact) SettlementStatus ¶
func (e EffectFinishedFact) SettlementStatus() SettlementStatus
func (EffectFinishedFact) Target ¶
func (e EffectFinishedFact) Target() EffectTarget
func (EffectFinishedFact) Valid ¶
func (e EffectFinishedFact) Valid() bool
type EffectID ¶
type EffectID struct {
// contains filtered or unexported fields
}
EffectID identifies one Effect at a stable Process, Step, and batch index.
func ParseEffectID ¶
ParseEffectID validates an externally encoded Effect identity.
func (EffectID) JSONSchemaAlias ¶ added in v0.17.0
func (EffectID) JSONSchemaAlias() any
func (EffectID) MarshalText ¶
func (*EffectID) UnmarshalText ¶
type EffectRequest ¶
type EffectRequest struct {
// contains filtered or unexported fields
}
EffectRequest is the immutable dispatch context prepared by the Engine.
func (EffectRequest) BatchIndex ¶
func (e EffectRequest) BatchIndex() uint32
BatchIndex returns the zero-based declaration order within the Step Effect batch.
func (EffectRequest) DeploymentRef ¶
func (e EffectRequest) DeploymentRef() DeploymentRef
DeploymentRef returns the exact behavior binding executing the Effect.
func (EffectRequest) Effect ¶
func (e EffectRequest) Effect() Effect
Effect returns an independently owned copy of the frozen intent.
func (EffectRequest) ID ¶
func (e EffectRequest) ID() EffectID
ID returns the stable identity assigned during Step preparation.
func (EffectRequest) ProcessID ¶
func (e EffectRequest) ProcessID() ProcessID
ProcessID returns the Process that owns the Effect.
func (EffectRequest) Relation ¶
func (e EffectRequest) Relation() ProcessRelation
Relation returns the immutable Process tree location executing the Effect.
func (EffectRequest) StepSequence ¶
func (e EffectRequest) StepSequence() uint64
StepSequence returns the one-based Step sequence that declared the Effect.
func (EffectRequest) TreeIncarnationID ¶ added in v0.16.0
func (e EffectRequest) TreeIncarnationID() (TreeIncarnationID, bool)
TreeIncarnationID identifies the active durable writer for observation and correlation. Ephemeral requests return false. It does not participate in the Effect's stable idempotency identity, which remains ID across restoration.
func (EffectRequest) Valid ¶
func (e EffectRequest) Valid() bool
Valid reports whether the request contains one complete Engine-minted dispatch identity and immutable Effect.
type EffectStartedFact ¶
type EffectStartedFact struct {
// contains filtered or unexported fields
}
EffectStartedFact identifies the target of one Effect attempt.
func (EffectStartedFact) Target ¶
func (e EffectStartedFact) Target() EffectTarget
func (EffectStartedFact) Valid ¶
func (e EffectStartedFact) Valid() bool
type EffectTarget ¶
type EffectTarget string
EffectTarget identifies which of the two execution boundaries owns an Effect. Framework Effects are interpreted by the Engine; Dispatcher Effects remain opaque to the Engine and are interpreted by the Deployment-bound dispatcher.
const ( // EffectTargetInvalid is the invalid zero value. EffectTargetInvalid EffectTarget = "" // EffectTargetFramework identifies an Engine-interpreted Effect. EffectTargetFramework EffectTarget = "framework" // EffectTargetDispatcher identifies a Strategy dispatcher Effect. EffectTargetDispatcher EffectTarget = "dispatcher" )
func (EffectTarget) String ¶
func (e EffectTarget) String() string
func (EffectTarget) Valid ¶
func (e EffectTarget) Valid() bool
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine keeps admission, publication, and execution under one owner because resource reservations and recoverable tree state must describe the same lifecycle. Construct it with NewEngine; copying an Engine would share its registries while duplicating their synchronization.
func NewEngine ¶
func NewEngine(config EngineConfig) (*Engine, error)
NewEngine validates the whole configuration up front because an Engine owns Process lifecycle: a defect discovered after Processes exist has no safe remedy, since stopping the Engine would abandon in-flight effects whose settlement is still unknown.
func (*Engine) CaptureTree ¶
CaptureTree quiesces one complete Engine-owned tree at Strategy-safe boundaries and captures a consistent portable cut. In-flight Effects settle according to their existing contract before a Process joins the barrier. Cancellation remains available while the active work drains.
func (*Engine) Close ¶
Close rejects pending starts or restorations, Processes whose result publication or parent/child bookkeeping is incomplete, and trees that still own asynchronous work or a freeze. Process.Join or Run establishes subtree completion; callers must finish every tree and release any freeze before closing the Engine. Once closing begins, the Engine drains accepted Delta delivery and stops observation workers. Canceling ctx stops only this caller's wait; it does not interrupt that owned shutdown. A later Close joins the same shutdown. Concurrent callers join the same closure; existing handles retain results and RuntimeErrors for later reads.
func (*Engine) FlushDeltas ¶
FlushDeltas provides the ordering barrier needed before publishing a final value that must not overtake accepted streaming observations. Dropped Deltas remain lost because flushing cannot strengthen best-effort delivery. Closing the Engine prevents new flush barriers, even when no listeners are configured.
func (*Engine) InspectTree ¶ added in v0.16.0
InspectTree samples a registered root tree without freezing it or waiting for storage acknowledgment. It remains available during a commit, while a freeze is acquired or held, and after the owner stops or Engine.Close returns. ReleaseTree removes the lookup; an overlapping inspection may return its earlier valid sample. ctx bounds both admission and response waiting. The owner never calls user execution code to construct a report. Dependencies must still return in bounded time: synchronous EventListeners must not query or control their own tree. Query failures are returned as errors; runtime failures are reported through ProcessInspection.RuntimeError.
func (*Engine) ObservationFailures ¶
func (e *Engine) ObservationFailures() ObservationFailures
ObservationFailures returns consistent panic counts and the latest bounded diagnostic for each listener kind. Listener failures cannot veto execution.
func (*Engine) ReleaseTree ¶ added in v0.15.0
ReleaseTree waits for the complete root tree to settle and removes its in-memory registry entries and execution state. It does not cancel work or delete Host persistence. Capture any required TreeSnapshot before releasing. Existing Process handles retain their Result or RuntimeError; Engine.Process and tree operations no longer find the released identities. Canceling ctx before settlement leaves the tree registered and usable.
func (*Engine) RestoreTree ¶
func (e *Engine) RestoreTree( ctx context.Context, rootDeployment Deployment, snapshot TreeSnapshot, ) (*Process, error)
RestoreTree recreates a complete Process tree from one strict TreeSnapshot. rootDeployment must exactly bind the captured root; same-reference children reuse it, while other exact references are resolved through EngineConfig's DeploymentResolver. Registration is all-or-nothing within this Engine. Committed states and nonterminal prepared candidates must restore through their exact Definition before registration, activation, or Effect dispatch. Interrupted terminal candidates remain inert evidence and are not restored. Both completed and prepared completion outputs must satisfy that Definition's output schema before admission.
Snapshot capabilities, limits, budgets, and usage remain authoritative. Current EngineConfig start defaults do not revoke or rewrite captured grants. The Host must authorize the snapshot before calling RestoreTree; ProcessAdmitter and initialization acknowledgment are not repeated for captured Processes.
func (*Engine) Run ¶
Run starts one root Process and joins its entire subtree before returning the root's terminal Result. It keeps waiting after ctx cancellation because owned work and required acknowledgments must finish. A runtime failure anywhere in the subtree returns a RuntimeError and no Result, even when the root already completed; its acknowledged result remains available through Process.Await. Ordinary execution failure returns the root's valid Result and nil error.
func (*Engine) Start ¶
Start keeps ctx attached to the resulting tree so Host cancellation and deadlines reach accepted work. Execution that outlives a request therefore needs a longer-lived context.
Example (SuccessiveEpisodes) ¶
This example keeps continuation in the embedding Host. Its teaching store atomically links successor admission to the initial recoverable tree. A real database must perform those writes in one transaction. Engine.Start itself remains a fresh start; ambiguous creation is reconciled through that record.
package main
import (
"context"
"errors"
"fmt"
"github.com/Tangerg/scope/agent"
"github.com/Tangerg/scope/agent/strategy/workflow"
)
type episodeState struct {
Revision uint32 `json:"revision"`
Summary string `json:"summary"`
}
func episodeDeployment() (agent.Deployment, error) {
stage, err := workflow.Transform("revise", func(_ context.Context, state episodeState) (episodeState, error) {
if state.Revision >= 3 {
return episodeState{}, errors.New("episode revision bound reached")
}
state.Revision++
return state, nil
})
if err != nil {
return agent.Deployment{}, err
}
definition, err := workflow.NewDefinition(workflow.DefinitionConfig{
Name: "example.episode", Description: "Advance one bounded revision.", Stages: []workflow.Stage{stage},
})
if err != nil {
return agent.Deployment{}, err
}
return episodeBinding(definition)
}
func episodeBinding(definition agent.Definition) (agent.Deployment, error) {
return agent.NewDeployment(agent.DeploymentConfig{
Definition: definition,
ImplementationDigest: agent.ComputeDigest([]byte("example-episode-implementation")),
ConfigurationDigest: agent.ComputeDigest([]byte(definition.Descriptor().Name() + "/revision-bound-3")),
})
}
// The Host chooses an explicit new allocation; unused predecessor budget is
// never refunded. Request equality freezes state, behavior, limits, and authority.
type successorRequest struct {
Predecessor agent.ProcessID `json:"predecessor"`
DeploymentRef agent.DeploymentRef `json:"deployment_ref"`
Input agent.Input `json:"input"`
Limits agent.Limits `json:"limits"`
TreeLimits agent.TreeLimits `json:"tree_limits"`
Capabilities agent.CapabilitySet `json:"capabilities"`
}
func (s successorRequest) identity() (agent.Digest, error) {
if !s.Predecessor.Valid() || !s.DeploymentRef.Valid() || !s.Input.Valid() || !s.Limits.Valid() || !s.TreeLimits.Valid() || !s.Capabilities.Valid() {
return agent.Digest{}, errors.New("invalid successor request")
}
encoded, err := agent.EncodeInput(s)
if err != nil {
return agent.Digest{}, err
}
return agent.ComputeDigest(encoded.JSON()), nil
}
// This example keeps continuation in the embedding Host. Its teaching store
// atomically links successor admission to the initial recoverable tree. A real
// database must perform those writes in one transaction. Engine.Start itself
// remains a fresh start; ambiguous creation is reconciled through that record.
func main() {
ctx := context.Background()
store := newEpisodeStore()
deployment, err := episodeDeployment()
if err != nil {
panic(err)
}
engine, err := agent.NewEngine(agent.EngineConfig{TreeDurability: store.trees})
if err != nil {
panic(err)
}
defer func() {
if closeErr := engine.Close(ctx); closeErr != nil {
panic(closeErr)
}
}()
initial, err := agent.EncodeInput(episodeState{Summary: "reviewed plan"})
if err != nil {
panic(err)
}
previous, err := engine.Start(ctx, deployment, initial)
if err != nil {
panic(err)
}
result, err := store.sealEpisode(ctx, previous)
if err != nil {
panic(err)
}
output, present := result.Output()
if !present {
panic("completed episode has no output")
}
state, err := output.Decode[episodeState]()
if err != nil {
panic(err)
}
transfer, err := agent.EncodeInput(state)
if err != nil {
panic(err)
}
request := successorRequest{
Predecessor: previous.ID(), DeploymentRef: deployment.DeploymentRef(), Input: transfer,
Limits: agent.Limits{MaxSteps: 8, MaxEffects: 4, MaxSignals: 8, MaxPendingSignals: 8},
TreeLimits: agent.DefaultTreeLimits(),
}
host := &episodeHost{store: store}
defer func() {
if closeErr := host.close(ctx); closeErr != nil {
panic(closeErr)
}
}()
next, err := host.start(ctx, deployment, request)
if err != nil {
panic(err)
}
duplicate, err := host.start(ctx, deployment, request)
if err != nil {
panic(err)
}
final, err := next.Await(ctx)
if err != nil {
panic(err)
}
if joinErr := next.Join(ctx); joinErr != nil {
panic(joinErr)
}
finalOutput, present := final.Output()
if !present {
panic("successor has no output")
}
nextState, err := finalOutput.Decode[episodeState]()
if err != nil {
panic(err)
}
fmt.Println("revision:", state.Revision, "->", nextState.Revision)
fmt.Println("same successor:", next.ID() == duplicate.ID())
fmt.Println("new allocations:", store.allocations)
}
// Each Host owns its runtime instances. A replacement Host has no live handles
// and restores the already admitted tree; it does not create another successor.
type episodeHost struct {
store *episodeStore
engines []*agent.Engine
}
func (e *episodeHost) start(ctx context.Context, deployment agent.Deployment, request successorRequest) (*agent.Process, error) {
if deployment.DeploymentRef() != request.DeploymentRef {
return nil, agent.ErrInvalidDeployment
}
if err := deployment.Descriptor().ValidateInput(request.Input); err != nil {
return nil, err
}
attempt, existing, err := e.store.claim(request)
if err != nil {
return nil, err
}
if existing.Valid() {
for _, engine := range e.engines {
if process, present := engine.Process(existing); present {
return process, nil
}
}
}
return e.activate(ctx, deployment, request, attempt, existing)
}
func (e *episodeHost) activate(ctx context.Context, deployment agent.Deployment, request successorRequest, attempt *episodeAttempt, existing agent.ProcessID) (*agent.Process, error) {
engine, err := agent.NewEngine(agent.EngineConfig{
TreeDurability: attempt, ProcessAdmitter: attempt,
Limits: request.Limits, TreeLimits: request.TreeLimits, Capabilities: request.Capabilities,
})
if err != nil {
return nil, err
}
e.engines = append(e.engines, engine)
if !existing.Valid() {
return engine.Start(ctx, deployment, request.Input)
}
head, present, err := e.store.trees.LoadTree(ctx, existing)
if err != nil {
return nil, err
}
if !present {
return nil, errors.New("successor record has no committed tree")
}
return engine.RestoreTree(ctx, deployment, head)
}
func (e *episodeHost) close(ctx context.Context) error {
var failures []error
for _, engine := range e.engines {
failures = append(failures, engine.Close(ctx))
}
return errors.Join(failures...)
}
Output: revision: 1 -> 2 same successor: true new allocations: 1
type EngineConfig ¶
type EngineConfig struct {
// TreeDurability makes publication wait for acknowledgment of a recoverable
// tree. Nil selects ephemeral execution without storage acknowledgment.
TreeDurability TreeDurability
// ProcessInitializationOutcomeAcknowledger optionally accepts initialization outcomes
// before publication. Its acknowledgment is separate from TreeDurability;
// nil omits this Host acceptance step.
ProcessInitializationOutcomeAcknowledger ProcessInitializationOutcomeAcknowledger
// Exact local bindings prevent restoration from silently selecting different
// behavior. Same-Deployment recursion needs no resolver.
DeploymentResolver DeploymentResolver
// ProcessAdmitter optionally applies Host policy before root or child
// initialization. Nil admits every start that satisfies Engine constraints.
ProcessAdmitter ProcessAdmitter
// EventListeners receive synchronous Framework facts. An empty slice disables
// delivery. Callbacks must be bounded and must not query or control their tree.
EventListeners []EventListener
// DeltaListeners receive queued, best-effort Strategy increments. An empty
// slice disables delivery. Callbacks run serially and must return so Engine
// shutdown can drain the queue and join its delivery worker.
DeltaListeners []DeltaListener
// A bounded queue prevents slow listeners from retaining unlimited Deltas.
// Zero selects the library default; negative capacities are invalid.
DeltaBufferCapacity int
// Zero fields inherit DefaultLimits so partial overrides still produce
// complete per-Process resource bounds.
Limits Limits
// TreeLimits bounds descendant count, depth, and active children. Zero fields
// inherit DefaultTreeLimits independently of per-Process Limits.
TreeLimits TreeLimits
// Capabilities grants authority to new roots. Children receive only subsets
// of their parent's captured authority, including after restoration.
Capabilities CapabilitySet
}
EngineConfig keeps scheduling and authority policy outside Deployments so a strategy cannot change its constraints through its behavior binding. Limits, TreeLimits, and Capabilities apply to newly started root trees. RestoreTree retains their captured values; the Host authorizes snapshots before recovery.
type Event ¶
type Event struct {
// contains filtered or unexported fields
}
Event is an immutable, ordered fact published by the Framework. Observers may project or instrument it, but observer failure never changes Process state. Payload is descriptive data, never a Signal or state mutation command.
func (Event) DeltaDropped ¶
func (e Event) DeltaDropped() (DeltaDroppedFact, bool)
DeltaDropped returns the typed loss fact for EventDeltaDropped.
func (Event) DeploymentRef ¶
func (e Event) DeploymentRef() DeploymentRef
DeploymentRef returns the exact execution binding that emitted the fact.
func (Event) EffectFinished ¶
func (e Event) EffectFinished() (EffectFinishedFact, bool)
EffectFinished returns the typed settlement fact for EventEffectFinished.
func (Event) EffectID ¶
EffectID returns the related Effect identity and true when this is an Effect fact.
func (Event) EffectStarted ¶
func (e Event) EffectStarted() (EffectStartedFact, bool)
EffectStarted returns the typed target fact for EventEffectStarted.
func (Event) MarshalJSON ¶
func (Event) OccurredAt ¶
OccurredAt returns when the fact occurred.
func (Event) Payload ¶
func (e Event) Payload() json.RawMessage
Payload returns an independently owned descriptive payload.
func (Event) Phase ¶
func (e Event) Phase() EventPhase
Phase returns whether the fact describes an attempt or committed state.
func (Event) ProcessFinished ¶
func (e Event) ProcessFinished() (ProcessFinishedFact, bool)
ProcessFinished returns the typed terminal fact for EventProcessFinished.
func (Event) ProcessSequence ¶
ProcessSequence returns the Process-local publication order within one tree runtime activation, starting at one. Restoration starts a new sequence; publication progress is observation state and is not part of a TreeSnapshot.
func (Event) Relation ¶
func (e Event) Relation() ProcessRelation
Relation returns the Process tree location that emitted the fact.
func (Event) RuntimeStopped ¶ added in v0.16.0
func (e Event) RuntimeStopped() (RuntimeStoppedFact, bool)
RuntimeStopped returns the typed instance failure for EventRuntimeStopped.
func (Event) SignalAccepted ¶
func (e Event) SignalAccepted() (SignalAcceptedFact, bool)
SignalAccepted returns the typed delivery fact for EventSignalAccepted.
func (Event) StepCommitted ¶
func (e Event) StepCommitted() (StepCommittedFact, bool)
StepCommitted returns the typed state fact for EventStepCommitted.
func (Event) StepFinished ¶
func (e Event) StepFinished() (StepFinishedFact, bool)
StepFinished returns the typed attempt fact for EventStepFinished.
func (Event) StepSequence ¶
StepSequence returns the one-based Step sequence and true, or zero and false for a Process fact outside a Step.
func (Event) TreeIncarnationID ¶
func (e Event) TreeIncarnationID() (TreeIncarnationID, bool)
TreeIncarnationID returns the active durable writer that emitted this event. Events from ephemeral trees return false.
func (*Event) UnmarshalJSON ¶
type EventListener ¶
type EventListener interface {
// OnEvent receives one committed or attempted Framework fact in increasing
// ProcessSequence for its Process within one tree runtime activation. A
// restored nonterminal Process starts with EventProcessRestored; durable
// activations also carry distinct TreeIncarnationIDs. Different tree runtimes
// may call the listener concurrently. It runs synchronously on the
// observed tree's owner, so it must return in bounded time without querying or
// controlling that tree, or calling Process.Await on it. Calls using this
// context, or a derived context, return [ErrListenerReentrancy] while the
// callback is active. The restriction ends when this invocation returns,
// including after a panic. Calls to other trees must still return in bounded
// time; distinct owners do not prevent cyclic waits between callbacks.
// The listener has no veto or acknowledgment authority.
OnEvent(ctx context.Context, event Event)
}
EventListener observes ordered Framework facts. Panics are isolated from Process execution and never alter committed state. Implementations must return in bounded time and must not query or control the observed tree.
type EventListenerFunc ¶
EventListenerFunc adapts a plain function to the event listener interface. A listener observes and must not steer execution, so the signature returns nothing to make that boundary hard to violate by accident.
type EventPhase ¶
type EventPhase string
EventPhase distinguishes runtime observations from facts supported by authoritative Process state. Durable trees publish committed facts only after TreeDurability acknowledges the resulting tree state. Attempt facts do not assert a committed Process state change.
const ( // EventPhaseInvalid is the invalid zero value. EventPhaseInvalid EventPhase = "" // EventPhaseAttempt identifies runtime work without a state commit guarantee. EventPhaseAttempt EventPhase = "attempt" // EventPhaseCommitted identifies a fact whose resulting state is acknowledged. EventPhaseCommitted EventPhase = "committed" )
func (EventPhase) String ¶
func (e EventPhase) String() string
func (EventPhase) Valid ¶
func (e EventPhase) Valid() bool
type Execution ¶
type Execution interface {
// Step reduces the current private state and the supplied ordered Signal
// prefix into one candidate Transition. It must honor ctx for bounded CPU
// work, perform no I/O, consume no hidden input, and never retain signals.
// The Engine serializes calls for one Execution.
Step(ctx context.Context, signals []Signal) (Transition, error)
// Snapshot returns a complete, independently owned state from
// which Definition.Restore can reproduce the current Execution exactly. It
// must fail rather than omit state required for deterministic continuation.
Snapshot() (ExecutionState, error)
}
Execution is the single Strategy-owned state machine inside one Process. Step must be a bounded, deterministic state reduction over the current state and the supplied Signal prefix. It must not perform external I/O, read clock, random or global state, or start ownerless goroutines. External operations are returned as Effects. Snapshot must fail rather than return partial state.
The Engine is the sole caller and never invokes Step concurrently for the same Execution. If Step or Snapshot fails, the instance is discarded and may only be rebuilt from the committed ExecutionState. The Engine always supplies a non-nil Step context.
type ExecutionState ¶
type ExecutionState struct {
// contains filtered or unexported fields
}
ExecutionState is an immutable envelope owned by one Execution Strategy. The Engine persists and returns Payload without interpreting it. Its zero value is invalid.
func NewExecutionState ¶
func NewExecutionState(kind string, payload json.RawMessage) (ExecutionState, error)
NewExecutionState pairs a strategy kind with an opaque payload. The kind exists so a snapshot can be rejected when restored into the wrong strategy; the payload stays opaque so adding a strategy never widens the kernel.
func (ExecutionState) Kind ¶
func (e ExecutionState) Kind() string
Kind returns the Strategy that exclusively interprets Payload.
func (ExecutionState) MarshalJSON ¶
func (e ExecutionState) MarshalJSON() ([]byte, error)
func (ExecutionState) Payload ¶
func (e ExecutionState) Payload() json.RawMessage
Payload returns an independently owned copy of the opaque Strategy state.
func (*ExecutionState) UnmarshalJSON ¶
func (e *ExecutionState) UnmarshalJSON(data []byte) error
func (ExecutionState) Valid ¶
func (e ExecutionState) Valid() bool
type Failure ¶
type Failure struct {
// contains filtered or unexported fields
}
Failure separates stable codes from diagnostic text so wording changes cannot alter control flow. Its bounded UTF-8 message must survive snapshot JSON and must exclude secrets.
func NewFailure ¶
func NewFailure(kind FailureKind, code, message string) (Failure, error)
NewFailure requires a kind and code alongside the message so callers classify failures programmatically. Matching on message text is what makes error handling break on wording changes, and it does not survive the snapshot round trip. Message must be trimmed, valid UTF-8 and contain at most 4096 bytes.
func (Failure) JSONSchemaAlias ¶ added in v0.17.0
func (Failure) Kind ¶
func (f Failure) Kind() FailureKind
func (Failure) MarshalJSON ¶
func (*Failure) UnmarshalJSON ¶
type FailureKind ¶
type FailureKind string
FailureKind stays independent of retryability so classifying a failure cannot silently select a recovery or business policy.
const ( FailureKindInvalid FailureKind = "" FailureKindExecution FailureKind = "execution" FailureKindContract FailureKind = "contract" FailureKindExternal FailureKind = "external" FailureKindPanic FailureKind = "panic" )
func (FailureKind) String ¶
func (f FailureKind) String() string
func (FailureKind) Valid ¶
func (f FailureKind) Valid() bool
type Input ¶
type Input struct {
// contains filtered or unexported fields
}
Input is the immutable JSON value used to start a Process. Its zero value is invalid. ParseInput and EncodeInput take ownership by copying and normalizing their input.
func EncodeInput ¶
EncodeInput converts a typed value into an independently owned Input.
Example ¶
package main
import (
"fmt"
"github.com/Tangerg/scope/agent"
)
func main() {
type request struct {
Topic string `json:"topic"`
}
input, err := agent.EncodeInput(request{Topic: "agent runtimes"})
if err != nil {
panic(err)
}
decoded, err := input.Decode[request]()
if err != nil {
panic(err)
}
fmt.Println(decoded.Topic, input.Valid())
}
Output: agent runtimes true
func ParseInput ¶
func ParseInput(data json.RawMessage) (Input, error)
ParseInput validates one JSON value and returns an independently owned Input.
func (Input) Decode ¶
Decode strictly decodes i into a typed value. Unknown object fields are rejected when T is a struct.
func (Input) JSON ¶
func (i Input) JSON() json.RawMessage
JSON returns an independently owned JSON representation.
func (Input) JSONSchemaAlias ¶ added in v0.17.0
func (Input) MarshalJSON ¶
func (*Input) UnmarshalJSON ¶
type Limits ¶
type Limits struct {
// MaxSteps bounds committed Steps.
MaxSteps uint64 `json:"max_steps"`
// MaxEffects bounds Effects prepared across all Steps.
MaxEffects uint64 `json:"max_effects"`
// MaxSignals bounds all accepted external and Engine-generated Signals.
MaxSignals uint64 `json:"max_signals"`
// MaxPendingSignals bounds the current unconsumed mailbox suffix and the
// suffix after the prepared Step consumes inputs and appends settlements.
// Every arriving Signal preserves both bounds regardless of its source.
MaxPendingSignals uint64 `json:"max_pending_signals"`
}
Limits bounds Framework-owned execution growth. Zero-valued fields in EngineConfig inherit DefaultLimits; ProcessSnapshot stores effective non-zero values so restoration preserves the same execution contract.
func DefaultLimits ¶
func DefaultLimits() Limits
DefaultLimits returns conservative hard bounds for one Process.
type ListenerPanic ¶ added in v0.18.0
type ListenerPanic struct {
ListenerIndex int
ListenerType string
ProcessID ProcessID
Message string
Stack string
}
ListenerPanic identifies one isolated listener failure. ListenerIndex is the zero-based position in EngineConfig.EventListeners or DeltaListeners, and ListenerType is its Go type. Message retains at most 4 KiB of the formatted panic value; Stack retains at most 64 KiB of the failing goroutine's stack.
type ObservationFailures ¶ added in v0.18.0
type ObservationFailures struct {
// contains filtered or unexported fields
}
ObservationFailures is an immutable snapshot of listener panics isolated by one Engine. Counts are monotonic and saturate at math.MaxUint64. Only the latest event-listener panic and delta-listener panic are retained.
func (ObservationFailures) DeltaListenerPanics ¶ added in v0.18.0
func (o ObservationFailures) DeltaListenerPanics() uint64
func (ObservationFailures) EventListenerPanics ¶ added in v0.18.0
func (o ObservationFailures) EventListenerPanics() uint64
func (ObservationFailures) LastDeltaPanic ¶ added in v0.18.0
func (o ObservationFailures) LastDeltaPanic() (ListenerPanic, bool)
LastDeltaPanic reports the latest failure in the delta-listener list.
func (ObservationFailures) LastEventPanic ¶ added in v0.18.0
func (o ObservationFailures) LastEventPanic() (ListenerPanic, bool)
LastEventPanic reports the latest failure in the event-listener list.
type Output ¶
type Output struct {
// contains filtered or unexported fields
}
Output is the immutable final semantic result of a completed Process. Its zero value is invalid and it never represents streamed Delta content.
func EncodeOutput ¶
EncodeOutput converts a typed value into an independently owned Output.
func ParseOutput ¶
func ParseOutput(data json.RawMessage) (Output, error)
ParseOutput validates one JSON value and returns an independently owned Output.
func (Output) Decode ¶
Decode strictly decodes o into a typed value. Unknown object fields are rejected when T is a struct.
func (Output) JSON ¶
func (o Output) JSON() json.RawMessage
JSON returns an independently owned JSON representation.
func (Output) JSONSchemaAlias ¶ added in v0.17.0
func (Output) MarshalJSON ¶
func (*Output) UnmarshalJSON ¶
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process is an Engine-issued handle to one managed execution. Its fields and construction remain private so a caller cannot create a second lifecycle owner. Identity and allocation are immutable; Engine.InspectTree owns live inspection. The zero value and nil receiver are invalid; methods require an Engine-issued handle and may panic otherwise. A finished Process remains a valid handle. Control methods submit requests to the owning tree runtime. Except for RequestCancellation, ctx bounds both submission and response waiting. Once a command enters the runtime queue, canceling ctx does not revoke it. A context already canceled before submission never admits a command.
func (*Process) Await ¶
Await waits for the immutable terminal result and the Engine's immediate parent/child bookkeeping for that termination. Canceling ctx stops only the wait; Process cancellation is explicit or follows the context passed to Start. A durability failure stops this instance and returns a RuntimeError with no Result. A failed logical execution returns a valid Result and nil error. Descendants may still be settling after this Process's result is ready.
func (*Process) Budget ¶
Budget returns the fixed non-renewable allocation assigned to this Process.
func (*Process) Capabilities ¶
func (p *Process) Capabilities() CapabilitySet
Capabilities returns the immutable authority set assigned to this Process.
func (*Process) DeliverSignals ¶
func (p *Process) DeliverSignals(ctx context.Context, requests ...SignalRequest) (accepted bool, err error)
DeliverSignals submits one or more immutable Strategy inputs as an ordered, atomic batch. Unaddressed input queues for the next Strategy-safe Step, including while Paused or waiting for child completion. It never resumes either state by itself. An externally addressable wait requires an answer. An addressed answer while Waiting must name the current WaitID; any other external wait answer returns ErrSignalRejected. The batch is accepted or the mailbox remains unchanged. Reusing a SignalID with different normalized payload bytes or a different WaitID returns ErrSignalConflict. If any SignalID repeats with identical content, accepted is false with nil error and the whole batch is unchanged, including resource usage. In durable mode, accepted is true only after the mailbox and budget changes commit to the authoritative tree head. A caller timeout does not revoke an admitted command; retry the identical batch to reconcile uncertain delivery.
func (*Process) DeploymentRef ¶
func (p *Process) DeploymentRef() DeploymentRef
DeploymentRef returns the exact Definition and dispatcher binding identity.
func (*Process) Join ¶ added in v0.17.0
Join waits for this Process and every descendant to finish their owned work and required acknowledgments in this runtime. It does not cancel execution or release registry entries. Canceling ctx stops only this wait. Ordinary execution failure and terminal Unknown settlements do not prevent a successful join; Await reports the Process result. A runtime failure in this subtree returns a RuntimeError after its local jobs have returned, even when this Process published its result before a descendant failed. Join makes no claim that a remote operation or a previous writer has stopped. Strategies wait without blocking a Dispatcher through WaitForChildren.
func (*Process) Kill ¶
Kill records the Engine control plane's highest-priority terminal intent. It signals owned work throughout the subtree and collects in-flight Effects before termination. It cannot force a goroutine or a remote operation to stop. A nil error acknowledges the local intent. Await establishes whether the resulting termination committed or this instance stopped with a RuntimeError.
func (*Process) Pause ¶
Pause requests a scheduling pause at the next safe Step boundary. An in-flight Effect is allowed to settle before the pause becomes visible. A nil error acknowledges the local control intent, not its durable publication or completion; Engine.InspectTree reports StatusPaused only after a tree commit acknowledges the paused state in durable mode.
func (*Process) Relation ¶
func (p *Process) Relation() ProcessRelation
Relation returns the immutable parent/root/depth location assigned by the Engine. It is a root relation for Processes created through Engine.Start.
func (*Process) RequestCancellation ¶
RequestCancellation submits a caller-owned cancellation intent. A nil error means the request entered the owning tree runtime's queue; it does not mean the Process has reached a safe boundary or become terminal. Once submitted, ctx cancellation cannot revoke the request. The first committed cancellation intent maps to StatusCanceled with a host-cancellation cause. A pending tree commit must finish before the owner can apply this queued intent. Storage acknowledgment latency therefore also delays cancellation of owned contexts; submission alone does not interrupt an in-flight commit. Applying the intent cancels owned Step, Dispatch, and child-admission contexts throughout the subtree before waiting for their results. Already started external work still settles; remaining planned Effects do not start. Required initialization and persistence acknowledgments retain independent contexts. A surviving parent receives the ordinary child-completion Signal and its Strategy decides how to continue. Await reports this Process's acknowledged terminal result; every descendant retains its own settlement.
func (*Process) ResolveUnknownEffect ¶
func (p *Process) ResolveUnknownEffect(ctx context.Context, settlement Settlement) error
ResolveUnknownEffect supplies a definite result after an Effect attempt became unknown. The Engine never converts unknown into retry or success implicitly. Terminal intent or a committed terminal result returns ErrProcessFinished; retained interrupted-batch evidence cannot resume a terminated execution.
func (*Process) Resume ¶
Resume makes an explicitly Paused Process schedulable again. External waits require an answer addressed to their WaitID; child waits require Framework child completion. Resume does not satisfy either wait. A nonterminal Process that is not Paused returns ErrInvalidProcessControl. A nil error acknowledges local resumption. Subsequent durable boundaries publish the resumed state before reporting their own acknowledgments.
type ProcessAdmission ¶
type ProcessAdmission struct {
// contains filtered or unexported fields
}
ProcessAdmission is the immutable Framework-owned information supplied to a ProcessAdmitter immediately before one root or child Process starts. It does not expose Input, Execution, Dispatcher, product identity, or Host state.
func (ProcessAdmission) Budget ¶
func (p ProcessAdmission) Budget() Budget
Budget returns the prospective Process's fixed non-renewable allocation.
func (ProcessAdmission) Capabilities ¶
func (p ProcessAdmission) Capabilities() CapabilitySet
Capabilities returns the prospective Process's immutable authority set.
func (ProcessAdmission) DeploymentRef ¶
func (p ProcessAdmission) DeploymentRef() DeploymentRef
DeploymentRef returns the exact prospective Deployment identity.
func (ProcessAdmission) Descriptor ¶
func (p ProcessAdmission) Descriptor() Descriptor
Descriptor returns the prospective Definition's static contract.
func (ProcessAdmission) Relation ¶
func (p ProcessAdmission) Relation() ProcessRelation
Relation returns the prospective Process identity and tree location.
func (ProcessAdmission) Valid ¶
func (p ProcessAdmission) Valid() bool
type ProcessAdmitter ¶
type ProcessAdmitter interface {
// Admit decides whether the immutable prospective Process may initialize.
// Returning nil accepts only the supplied identity and resources; it cannot
// enlarge Budget or Capabilities. Returning an error prevents initialization
// and publication. Implementations honor ctx, are bounded and concurrency-
// safe, and must tolerate the same prospective identity after recovery.
Admit(ctx context.Context, admission ProcessAdmission) error
}
ProcessAdmitter decides whether one prospective root or child Process may initialize. Implementations may coordinate caller-owned external admission work, but must not create a Process, mutate the admission, or allocate Framework resources. A prepared Step may replay the same child admission with the same prospective Process identity after recovery. The runtime cancels an active child admission when its parent terminates; an accepted admission still receives its required initialization outcome.
Implementations must respect ctx, return in bounded time, be safe for concurrent calls when shared, and must not re-enter the Engine or a Process. Framework identity is stable, but persistence, transactionality, charging, and business idempotency remain implementation responsibilities. Returning an error rejects only this prospective Process. Budget allocation, capability attenuation, and tree limits remain Engine invariants and cannot be changed by an admitter. Every accepted admission concludes with exactly one ProcessInitializationOutcome when an acknowledger is configured. Restore repeats neither admission nor its outcome for a captured Process.
type ProcessAdmitterFunc ¶
type ProcessAdmitterFunc func(ctx context.Context, admission ProcessAdmission) error
ProcessAdmitterFunc adapts a plain function to the admitter interface, so a host quota or policy check does not require a named type.
func (ProcessAdmitterFunc) Admit ¶
func (p ProcessAdmitterFunc) Admit(ctx context.Context, admission ProcessAdmission) error
type ProcessFinishedFact ¶
type ProcessFinishedFact struct {
// contains filtered or unexported fields
}
ProcessFinishedFact is the immutable terminal fact carried by a finished Process Event. Usage is the authoritative Framework-owned terminal usage.
func (ProcessFinishedFact) Cause ¶
func (p ProcessFinishedFact) Cause() TerminationCause
func (ProcessFinishedFact) Failure ¶
func (p ProcessFinishedFact) Failure() (FailureKind, string, bool)
func (ProcessFinishedFact) Status ¶
func (p ProcessFinishedFact) Status() Status
func (ProcessFinishedFact) Usage ¶
func (p ProcessFinishedFact) Usage() Usage
func (ProcessFinishedFact) Valid ¶
func (p ProcessFinishedFact) Valid() bool
type ProcessID ¶
type ProcessID struct {
// contains filtered or unexported fields
}
ProcessID is the stable identity of one Engine-owned Process.
func ParseProcessID ¶
ParseProcessID validates an externally encoded Process identity.
func (ProcessID) JSONSchemaAlias ¶ added in v0.17.0
func (ProcessID) JSONSchemaAlias() any
func (ProcessID) MarshalText ¶
func (*ProcessID) UnmarshalText ¶
type ProcessInitializationOutcome ¶ added in v0.19.0
type ProcessInitializationOutcome struct {
// contains filtered or unexported fields
}
ProcessInitializationOutcome separates initialization acceptance from publication: persistence can still fail after an initialized outcome is accepted.
func (ProcessInitializationOutcome) Admission ¶ added in v0.19.0
func (p ProcessInitializationOutcome) Admission() ProcessAdmission
func (ProcessInitializationOutcome) Failure ¶ added in v0.19.0
func (p ProcessInitializationOutcome) Failure() (Failure, bool)
func (ProcessInitializationOutcome) StartedAt ¶ added in v0.19.0
func (p ProcessInitializationOutcome) StartedAt() (time.Time, bool)
StartedAt returns the observed UTC lifecycle start time recorded before initialization. It is available only after successful initialization and does not identify the later Process publication boundary.
func (ProcessInitializationOutcome) Status ¶ added in v0.19.0
func (p ProcessInitializationOutcome) Status() ProcessInitializationOutcomeStatus
func (ProcessInitializationOutcome) Valid ¶ added in v0.19.0
func (p ProcessInitializationOutcome) Valid() bool
type ProcessInitializationOutcomeAcknowledger ¶ added in v0.19.0
type ProcessInitializationOutcomeAcknowledger interface {
// AcknowledgeProcessInitializationOutcome must return before publication so a Host
// can reject initialization without exposing a usable Process.
AcknowledgeProcessInitializationOutcome(ctx context.Context, outcome ProcessInitializationOutcome) error
}
ProcessInitializationOutcomeAcknowledger lets a Host close each accepted admission even when initialization fails before a Process exists. Rejecting an initialized outcome prevents publication; accepting it does not guarantee later persistence. Implementations must be bounded, concurrency-safe, idempotent by admission identity, and must not re-enter Engine or Process, because initialization waits for this call. Restore produces no outcome because it does not initialize. ctx retains Host values but excludes cancellation and deadlines so an accepted admission can finish acknowledgment even when its parent is terminating. The Host must apply an independent bounded deadline and reconcile an uncertain acknowledgment by admission identity; timeout alone does not prove rejection.
type ProcessInitializationOutcomeAcknowledgerFunc ¶ added in v0.19.0
type ProcessInitializationOutcomeAcknowledgerFunc func( ctx context.Context, outcome ProcessInitializationOutcome, ) error
func (ProcessInitializationOutcomeAcknowledgerFunc) AcknowledgeProcessInitializationOutcome ¶ added in v0.19.0
func (p ProcessInitializationOutcomeAcknowledgerFunc) AcknowledgeProcessInitializationOutcome( ctx context.Context, outcome ProcessInitializationOutcome, ) error
type ProcessInitializationOutcomeStatus ¶ added in v0.19.0
type ProcessInitializationOutcomeStatus string
const ( ProcessInitializationOutcomeStatusInvalid ProcessInitializationOutcomeStatus = "" ProcessInitializationOutcomeStatusInitialized ProcessInitializationOutcomeStatus = "initialized" ProcessInitializationOutcomeStatusFailed ProcessInitializationOutcomeStatus = "failed" )
func (ProcessInitializationOutcomeStatus) String ¶ added in v0.19.0
func (p ProcessInitializationOutcomeStatus) String() string
func (ProcessInitializationOutcomeStatus) Valid ¶ added in v0.19.0
func (p ProcessInitializationOutcomeStatus) Valid() bool
type ProcessInspection ¶ added in v0.16.0
type ProcessInspection struct {
Snapshot ProcessSnapshot
Work ProcessWork
Stale bool
EffectID EffectID
RuntimeError *RuntimeError
}
ProcessInspection combines an existing execution capture with current work. A stale job is still draining but cannot publish its result. RuntimeError reports an instance failure; its unresolved Effects may exceed the Unknown settlements already present in Snapshot.
type ProcessRelation ¶
type ProcessRelation struct {
// contains filtered or unexported fields
}
ProcessRelation is the immutable location of one Process in an Engine-owned tree. Roots identify themselves as RootID at depth zero. Children have one parent and one stable ChildKey; a Process never has multiple parents.
func (ProcessRelation) ChildKey ¶
func (p ProcessRelation) ChildKey() (ChildKey, bool)
ChildKey returns the parent-scoped logical child identity and true for a child, or zero and false for a root.
func (ProcessRelation) Depth ¶
func (p ProcessRelation) Depth() uint32
Depth returns zero for a root and parent depth plus one for every child.
func (ProcessRelation) IsRoot ¶
func (p ProcessRelation) IsRoot() bool
IsRoot reports whether p identifies the root of its tree.
func (ProcessRelation) ParentID ¶
func (p ProcessRelation) ParentID() (ProcessID, bool)
ParentID returns the direct parent and true for a child, or zero and false for a root.
func (ProcessRelation) ProcessID ¶
func (p ProcessRelation) ProcessID() ProcessID
ProcessID returns the Process located by this relation.
func (ProcessRelation) RootID ¶
func (p ProcessRelation) RootID() ProcessID
RootID returns the stable root identity shared by the complete Process tree.
func (ProcessRelation) Valid ¶
func (p ProcessRelation) Valid() bool
type ProcessSnapshot ¶
type ProcessSnapshot struct {
// contains filtered or unexported fields
}
ProcessSnapshot is an immutable diagnostic capture of one Engine-owned Process. Strategy state and Effect payloads remain opaque. A ProcessSnapshot is not a recovery unit; only a complete TreeSnapshot can be restored. An interrupted terminal Process retains its prepared batch as evidence: settled operations keep their actual results, planned operations never run, and the candidate state and input cursor were not adopted. Parsing validates the captured state, not storage acknowledgment. Engine.InspectTree identifies the acknowledged head of its durable captures.
func ParseProcessSnapshot ¶
func ParseProcessSnapshot(data json.RawMessage) (ProcessSnapshot, error)
ParseProcessSnapshot strictly validates one Process snapshot wire value, including single-answer wait history and an open, unanswered current wait when the Process is Waiting. Prepared Effects must fit the captured Process capability grant. Terminal prepared batches contain no pending attempt and their unknown identities must exactly match the Termination.
func (ProcessSnapshot) Budget ¶
func (p ProcessSnapshot) Budget() Budget
Budget returns the Process work allocation captured by this snapshot.
func (ProcessSnapshot) Capabilities ¶
func (p ProcessSnapshot) Capabilities() CapabilitySet
Capabilities returns the Process authority set captured by this snapshot.
func (ProcessSnapshot) CommittedExecutionState ¶
func (p ProcessSnapshot) CommittedExecutionState() ExecutionState
CommittedExecutionState returns the latest committed opaque Strategy state. A prepared candidate, when present, remains an uncommitted Engine detail. Only the owning Definition or its typed inspection helpers may interpret the returned state's payload.
func (ProcessSnapshot) DeploymentRef ¶
func (p ProcessSnapshot) DeploymentRef() DeploymentRef
DeploymentRef returns the exact execution binding required for restoration.
func (ProcessSnapshot) JSON ¶
func (p ProcessSnapshot) JSON() json.RawMessage
JSON returns an independently owned snapshot representation.
func (ProcessSnapshot) MarshalJSON ¶
func (p ProcessSnapshot) MarshalJSON() ([]byte, error)
func (ProcessSnapshot) ProcessID ¶
func (p ProcessSnapshot) ProcessID() ProcessID
ProcessID returns the captured Process identity.
func (ProcessSnapshot) Relation ¶
func (p ProcessSnapshot) Relation() ProcessRelation
Relation returns the immutable parent/root/depth location captured with the Process.
func (ProcessSnapshot) SignalReceipts ¶ added in v0.17.0
func (p ProcessSnapshot) SignalReceipts() []SignalReceipt
SignalReceipts returns admitted Signal facts in mailbox arrival order. The committed cursor distinguishes consumption from admission, including inputs accepted after a final Step obtained its Signal window. These facts have the same acknowledgment boundary as this snapshot; absence in an older capture does not prove rejection. No mailbox or consumption authority is transferred.
func (ProcessSnapshot) Status ¶
func (p ProcessSnapshot) Status() Status
Status returns the captured common lifecycle state.
func (ProcessSnapshot) UnknownEffectIDs ¶ added in v0.16.0
func (p ProcessSnapshot) UnknownEffectIDs() []EffectID
UnknownEffectIDs returns Effects whose captured settlement requires explicit resolution. RuntimeError separately owns outcomes an instance could not confirm. A terminal capture retains unresolved evidence; its Process cannot resume or accept further resolution commands.
func (*ProcessSnapshot) UnmarshalJSON ¶
func (p *ProcessSnapshot) UnmarshalJSON(data []byte) error
func (ProcessSnapshot) Usage ¶ added in v0.16.0
func (p ProcessSnapshot) Usage() Usage
Usage returns the Framework counters recorded in this capture.
func (ProcessSnapshot) Valid ¶
func (p ProcessSnapshot) Valid() bool
func (ProcessSnapshot) WaitID ¶
func (p ProcessSnapshot) WaitID() (WaitID, bool)
WaitID returns the current Engine-minted wait identity and true when the captured Process is Waiting.
func (ProcessSnapshot) WaitKind ¶ added in v0.16.0
func (p ProcessSnapshot) WaitKind() (WaitKind, bool)
WaitKind distinguishes Host input from Framework child completion while the captured Process is Waiting. It derives from the existing wait authority.
type ProcessWork ¶ added in v0.16.0
type ProcessWork string
ProcessWork describes work owned by the current runtime, independently of the lifecycle state in its last acknowledged snapshot. Queued means waiting for an owner turn; a commit or freeze can still block it. Idle means no queued work or job, not a terminal Process or a successful execution.
const ( ProcessWorkIdle ProcessWork = "idle" ProcessWorkQueued ProcessWork = "queued" ProcessWorkStep ProcessWork = "step" ProcessWorkRestore ProcessWork = "restore" ProcessWorkDispatch ProcessWork = "dispatch" ProcessWorkChildStart ProcessWork = "child_start" )
type ReplayPolicy ¶
type ReplayPolicy string
ReplayPolicy states whether a Dispatcher can prove that repeating an Effect with the same EffectID is the same logical external operation. It does not claim transactionality or allow replay under a different identity.
const ( // ReplayPolicyInvalid is the invalid zero value. ReplayPolicyInvalid ReplayPolicy = "" // ReplayPolicyNever forbids automatic replay of a restored pending Effect. ReplayPolicyNever ReplayPolicy = "never" // ReplayPolicySameIdentity permits replay only with the original EffectID. ReplayPolicySameIdentity ReplayPolicy = "same_identity" )
func (ReplayPolicy) String ¶
func (r ReplayPolicy) String() string
func (ReplayPolicy) Valid ¶
func (r ReplayPolicy) Valid() bool
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result is the immutable terminal outcome of one Process. A failed or canceled execution is represented by Termination, not by Await's error.
func (Result) FinishedAt ¶
FinishedAt returns the observed UTC time of committed termination. Wall-clock adjustments and restoration on another writer can make it earlier than StartedAt.
func (Result) Termination ¶
func (r Result) Termination() Termination
Termination returns the stable terminal cause and optional Failure.
type RuntimeError ¶ added in v0.16.0
type RuntimeError struct {
// contains filtered or unexported fields
}
RuntimeError reports that the active writer stopped without establishing the requested Process result or subtree completion. A result acknowledged before a descendant failed remains available through Process.Await. The Host may reconcile storage and restore its authoritative tree head in another Engine. This error does not terminate the durable execution or authorize replay of an uncertain Effect. Engine constructs these errors; the zero value carries no runtime identity. Process methods and tree reports return independent RuntimeError values; Unwrap preserves the original cause.
func (*RuntimeError) Error ¶ added in v0.16.0
func (r *RuntimeError) Error() string
func (*RuntimeError) HeadDigest ¶ added in v0.16.0
func (r *RuntimeError) HeadDigest() Digest
HeadDigest identifies the last tree head acknowledged to this instance. The store may have advanced further if a commit response was lost or a new writer acquired ownership; recovery must read the store's authoritative head.
func (*RuntimeError) IncarnationID ¶ added in v0.16.0
func (r *RuntimeError) IncarnationID() TreeIncarnationID
IncarnationID identifies the durable writer that stopped.
func (*RuntimeError) ProcessID ¶ added in v0.16.0
func (r *RuntimeError) ProcessID() ProcessID
ProcessID identifies the affected Process handle in the stopped instance.
func (*RuntimeError) UnresolvedEffectIDs ¶ added in v0.16.0
func (r *RuntimeError) UnresolvedEffectIDs() []EffectID
UnresolvedEffectIDs returns the sorted, distinct identities whose external outcomes this instance could not establish durably. Pending Effects that were never dispatched by this instance are not added solely for a failed pending-boundary acknowledgment.
func (*RuntimeError) Unwrap ¶ added in v0.16.0
func (r *RuntimeError) Unwrap() error
Unwrap preserves the durability failure, including ownership and content conflicts, for errors.Is and errors.As.
type RuntimeStoppedFact ¶ added in v0.16.0
type RuntimeStoppedFact struct {
// contains filtered or unexported fields
}
RuntimeStoppedFact describes an instance failure, not a logical Process termination. It contains only the failure classification, never storage error messages or application payloads. Event carries the Process and incarnation.
func (RuntimeStoppedFact) FailureCode ¶ added in v0.16.0
func (r RuntimeStoppedFact) FailureCode() string
func (RuntimeStoppedFact) FailureKind ¶ added in v0.16.0
func (r RuntimeStoppedFact) FailureKind() FailureKind
func (RuntimeStoppedFact) Valid ¶ added in v0.16.0
func (r RuntimeStoppedFact) Valid() bool
type Schema ¶
type Schema struct {
// contains filtered or unexported fields
}
Schema is an immutable, resolved JSON Schema used by Framework input and output contracts. Its zero value is invalid.
func ParseSchema ¶
func ParseSchema(data json.RawMessage) (Schema, error)
ParseSchema validates and resolves one JSON Schema.
func SchemaFor ¶
SchemaFor derives and resolves a JSON Schema for T. Named types contribute package-qualified schema names, so relocating them can change Descriptor digests and exact Deployment bindings even when their JSON fields stay equal.
func (Schema) JSON ¶
func (s Schema) JSON() json.RawMessage
JSON returns an independently owned JSON representation.
func (Schema) MarshalJSON ¶
func (*Schema) UnmarshalJSON ¶
func (Schema) ValidateInput ¶
func (Schema) ValidateOutput ¶
type Settlement ¶
type Settlement struct {
// contains filtered or unexported fields
}
Settlement is the immutable final fact for one EffectID. Payload is owned by the Effect target and becomes opaque Signal data for the next Step. The Engine uses Status only to preserve definite versus unknown execution facts.
func NewSettlement ¶
func NewSettlement(effectID EffectID, status SettlementStatus, payload json.RawMessage) (Settlement, error)
NewSettlement binds a result to the exact effect identity it settles, so a dispatcher cannot close an effect other than the one it was given. Ordering by completion time instead would let a slow settlement overwrite a newer one.
func (Settlement) EffectID ¶
func (s Settlement) EffectID() EffectID
EffectID returns the Effect this result settles.
func (Settlement) MarshalJSON ¶
func (s Settlement) MarshalJSON() ([]byte, error)
func (Settlement) Payload ¶
func (s Settlement) Payload() json.RawMessage
Payload returns an independently owned owner-defined result.
func (Settlement) Status ¶
func (s Settlement) Status() SettlementStatus
Status returns whether the external result is definite or unknown.
func (*Settlement) UnmarshalJSON ¶
func (s *Settlement) UnmarshalJSON(data []byte) error
func (Settlement) Valid ¶
func (s Settlement) Valid() bool
type SettlementStatus ¶
type SettlementStatus string
SettlementStatus records whether an Effect definitely succeeded, definitely failed, or has an unknown external result. Unknown never implies safe retry.
const ( // SettlementStatusInvalid is the invalid zero value. SettlementStatusInvalid SettlementStatus = "" // SettlementStatusSucceeded records a definite successful outcome. SettlementStatusSucceeded SettlementStatus = "succeeded" // SettlementStatusFailed records a definite failed outcome. SettlementStatusFailed SettlementStatus = "failed" // SettlementStatusUnknown records an externally indeterminate outcome. SettlementStatusUnknown SettlementStatus = "unknown" )
func (SettlementStatus) String ¶
func (s SettlementStatus) String() string
func (SettlementStatus) Valid ¶
func (s SettlementStatus) Valid() bool
type Signal ¶
type Signal struct {
// contains filtered or unexported fields
}
Signal is the immutable input envelope delivered by the Engine to an Execution. Dispatcher and ordinary wait payloads belong exclusively to the Strategy; Framework composition payloads are decoded only through their public typed helpers. SignalID identifies delivery, while an optional WaitID identifies the Engine-created wait target.
func (Signal) JSONSchemaAlias ¶ added in v0.17.0
func (Signal) MarshalJSON ¶
func (Signal) Payload ¶
func (s Signal) Payload() json.RawMessage
Payload returns an independently owned copy. Strategy-owned payloads are interpreted only by their Strategy; Framework-owned payloads should be read through the corresponding typed parser rather than decoded ad hoc.
func (*Signal) UnmarshalJSON ¶
type SignalAcceptedFact ¶
type SignalAcceptedFact struct {
// contains filtered or unexported fields
}
SignalAcceptedFact is the immutable delivery identity carried by an accepted Signal Event. WaitID is present only for a wait-addressed Signal.
func (SignalAcceptedFact) SignalID ¶
func (s SignalAcceptedFact) SignalID() SignalID
func (SignalAcceptedFact) Valid ¶
func (s SignalAcceptedFact) Valid() bool
func (SignalAcceptedFact) WaitID ¶
func (s SignalAcceptedFact) WaitID() (WaitID, bool)
type SignalID ¶
type SignalID struct {
// contains filtered or unexported fields
}
SignalID is the stable identity used to deduplicate one Signal delivery.
func ParseSignalID ¶
ParseSignalID validates an externally supplied Signal delivery identity. Parsing does not accept or deliver the Signal.
func (SignalID) JSONSchemaAlias ¶ added in v0.17.0
func (SignalID) JSONSchemaAlias() any
func (SignalID) MarshalText ¶
func (*SignalID) UnmarshalText ¶
type SignalReceipt ¶ added in v0.17.0
type SignalReceipt struct {
// contains filtered or unexported fields
}
SignalReceipt is an immutable admission and consumption fact from a ProcessSnapshot. Consumed payload bytes are released while their normalized digest and recipient WaitID remain available for duplicate reconciliation. Its Process owner and durability boundary are supplied by that snapshot.
func (SignalReceipt) ArrivalSequence ¶ added in v0.17.0
func (s SignalReceipt) ArrivalSequence() uint64
func (SignalReceipt) Consumed ¶ added in v0.17.0
func (s SignalReceipt) Consumed() bool
Consumed reports committed consumption, not delivery to a candidate Step.
func (SignalReceipt) ID ¶ added in v0.17.0
func (s SignalReceipt) ID() SignalID
func (SignalReceipt) Matches ¶ added in v0.17.0
func (s SignalReceipt) Matches(request SignalRequest) bool
Matches reports whether this receipt proves admission of the external request. Internal wait-opening and child-wait settlement Signals cannot prove external admission. A different WaitID or normalized payload remains an identity conflict.
func (SignalReceipt) PayloadDigest ¶ added in v0.17.0
func (s SignalReceipt) PayloadDigest() Digest
func (SignalReceipt) PendingSignal ¶ added in v0.17.0
func (s SignalReceipt) PendingSignal() (Signal, bool)
PendingSignal returns the retained input only while it remains unconsumed.
func (SignalReceipt) WaitID ¶ added in v0.17.0
func (s SignalReceipt) WaitID() (WaitID, bool)
type SignalRequest ¶
type SignalRequest struct {
// contains filtered or unexported fields
}
SignalRequest is an immutable request to deliver Strategy-owned input to a Process. ID supplies caller-stable deduplication. WaitID is zero for ordinary next-boundary input and Engine-minted for an external wait answer.
func NewSignalRequest ¶
func NewSignalRequest(id SignalID, waitID WaitID, payload json.RawMessage) (SignalRequest, error)
NewSignalRequest requires a caller-chosen signal identity so that resubmitting the same delivery is exactly one logical consumption. Without it, a host retry after an ambiguous network failure would be indistinguishable from a second answer.
func (SignalRequest) ID ¶
func (s SignalRequest) ID() SignalID
ID returns the stable delivery and deduplication identity.
func (SignalRequest) JSONSchemaAlias ¶ added in v0.18.0
func (SignalRequest) JSONSchemaAlias() any
func (SignalRequest) MarshalJSON ¶ added in v0.18.0
func (s SignalRequest) MarshalJSON() ([]byte, error)
func (SignalRequest) Payload ¶
func (s SignalRequest) Payload() json.RawMessage
Payload returns an independently owned Strategy-defined value.
func (*SignalRequest) UnmarshalJSON ¶ added in v0.18.0
func (s *SignalRequest) UnmarshalJSON(data []byte) error
func (SignalRequest) Valid ¶
func (s SignalRequest) Valid() bool
func (SignalRequest) WaitID ¶
func (s SignalRequest) WaitID() (WaitID, bool)
WaitID returns the addressed wait and true, or a zero WaitID and false.
type Status ¶
type Status string
Status is the complete common lifecycle state of a Process. Strategy-specific conditions such as a Planning no-plan result do not add common statuses.
const ( // StatusInvalid is the invalid zero value. StatusInvalid Status = "" // StatusNotStarted identifies a Process before execution begins. StatusNotStarted Status = "not_started" // StatusRunning identifies a Process eligible to advance. StatusRunning Status = "running" // StatusWaiting identifies a Process awaiting a WaitID-addressed Signal. StatusWaiting Status = "waiting" // StatusPaused identifies an explicitly suspended Process. StatusPaused Status = "paused" // StatusCompleted identifies successful semantic completion. StatusCompleted Status = "completed" // StatusFailed identifies terminal execution failure. StatusFailed Status = "failed" // StatusCanceled identifies cooperative cancellation. StatusCanceled Status = "canceled" // StatusTimedOut identifies deadline termination. StatusTimedOut Status = "timed_out" // StatusKilled identifies an explicit Engine kill. StatusKilled Status = "killed" )
func (Status) MarshalText ¶
func (*Status) UnmarshalText ¶
type StepCommittedFact ¶
type StepCommittedFact struct {
// contains filtered or unexported fields
}
StepCommittedFact is the Process status installed by one committed Step.
func (StepCommittedFact) Status ¶
func (s StepCommittedFact) Status() Status
func (StepCommittedFact) Valid ¶
func (s StepCommittedFact) Valid() bool
type StepFinishedFact ¶
type StepFinishedFact struct {
// contains filtered or unexported fields
}
StepFinishedFact is the immutable outcome of one Execution.Step attempt.
func (StepFinishedFact) Duration ¶
func (s StepFinishedFact) Duration() time.Duration
func (StepFinishedFact) Status ¶
func (s StepFinishedFact) Status() StepStatus
func (StepFinishedFact) Valid ¶
func (s StepFinishedFact) Valid() bool
type StepStatus ¶
type StepStatus string
StepStatus reports whether one Step reduction succeeded, and is deliberately narrower than Status: a failed Step does not by itself terminate a Process, because the terminal decision also depends on recorded control intent.
const ( StepStatusSucceeded StepStatus = "succeeded" StepStatusFailed StepStatus = "failed" )
Step status is separate from Process status because a failed Step does not by itself terminate a Process; the terminal decision also weighs recorded control intent.
func (StepStatus) String ¶
func (s StepStatus) String() string
func (StepStatus) Valid ¶
func (s StepStatus) Valid() bool
type Termination ¶
type Termination struct {
// contains filtered or unexported fields
}
Termination is the immutable result of applying the terminal priority matrix.
func (Termination) Cause ¶
func (t Termination) Cause() TerminationCause
Cause returns the stable machine-readable terminal category.
func (Termination) Failure ¶
func (t Termination) Failure() (Failure, bool)
Failure returns the classified failure for StatusFailed.
func (Termination) JSONSchemaAlias ¶ added in v0.17.0
func (Termination) JSONSchemaAlias() any
func (Termination) MarshalJSON ¶
func (t Termination) MarshalJSON() ([]byte, error)
func (Termination) Reason ¶
func (t Termination) Reason() string
Reason returns a bounded diagnostic reason. Completion has an empty reason.
func (Termination) Status ¶
func (t Termination) Status() Status
Status returns the resolved terminal Process status.
func (*Termination) UnmarshalJSON ¶
func (t *Termination) UnmarshalJSON(data []byte) error
func (Termination) UnresolvedEffectIDs ¶
func (t Termination) UnresolvedEffectIDs() []EffectID
UnresolvedEffectIDs returns the canonical identities of external operations that may have occurred but were not durably resolved when the tree stopped.
func (Termination) Valid ¶
func (t Termination) Valid() bool
type TerminationCause ¶
type TerminationCause string
TerminationCause is the stable reason category of a terminal Process.
const ( // TerminationCauseInvalid is the invalid zero value. TerminationCauseInvalid TerminationCause = "" // TerminationCauseCompletion identifies successful semantic completion. TerminationCauseCompletion TerminationCause = "completion" // TerminationCauseEngineKill identifies an explicit Engine kill. TerminationCauseEngineKill TerminationCause = "engine_kill" // TerminationCauseProcessDeadline identifies the Process's own deadline. TerminationCauseProcessDeadline TerminationCause = "process_deadline" // TerminationCauseParentDeadline identifies deadline propagation from a parent. TerminationCauseParentDeadline TerminationCause = "parent_deadline" // TerminationCauseHostDeadline identifies expiry of the Host context. TerminationCauseHostDeadline TerminationCause = "host_deadline" // TerminationCauseParentCancellation identifies cancellation by a parent Process. TerminationCauseParentCancellation TerminationCause = "parent_cancellation" // TerminationCauseHostCancellation identifies cancellation by the Host context. TerminationCauseHostCancellation TerminationCause = "host_cancellation" // TerminationCauseExecutionFailure identifies an ordinary Strategy failure. TerminationCauseExecutionFailure TerminationCause = "execution_failure" // TerminationCauseContractFailure identifies a contract violation. TerminationCauseContractFailure TerminationCause = "contract_failure" // TerminationCauseExternalFailure identifies failed external infrastructure. TerminationCauseExternalFailure TerminationCause = "external_failure" // TerminationCausePanic identifies a recovered execution-boundary panic. TerminationCausePanic TerminationCause = "panic" )
func (TerminationCause) String ¶
func (t TerminationCause) String() string
func (TerminationCause) Valid ¶
func (t TerminationCause) Valid() bool
type Transition ¶
type Transition struct {
// contains filtered or unexported fields
}
Transition is an immutable candidate lifecycle intent. The Engine validates ConsumedSignals against the delivered Signal window, captures the candidate ExecutionState, and assigns EffectID values before committing anything.
func Complete ¶
func Complete(consumedSignals uint32, output Output) (Transition, error)
Complete supplies the final semantic Output. The Engine must validate it against the Definition Descriptor before committing Completed.
func Continue ¶
func Continue(consumedSignals uint32, effects ...Effect) (Transition, error)
Continue keeps the Process schedulable after consuming the stated Signal prefix. Effects are dispatched only after the Engine prepares the Step.
func Fail ¶
func Fail(consumedSignals uint32, failure Failure) (Transition, error)
Fail supplies a stable Strategy-declared failure without making the Execution instance untrusted. A Step error follows the separate discard path.
func Pause ¶
func Pause(consumedSignals uint32, reason string) (Transition, error)
Pause requests an explicit scheduling pause with a bounded diagnostic reason.
func Wait ¶
func Wait(consumedSignals uint32, waitID WaitID) (Transition, error)
Wait moves the Process to Waiting for an Engine-minted WaitID already stored in the candidate ExecutionState.
func (Transition) ConsumedSignals ¶
func (t Transition) ConsumedSignals() uint32
ConsumedSignals returns the length of the delivered Signal prefix to commit.
func (Transition) Effects ¶
func (t Transition) Effects() []Effect
Effects returns independently owned operation intents in declaration order.
func (Transition) Failure ¶
func (t Transition) Failure() (Failure, bool)
Failure returns the terminal failure for a Fail transition.
func (Transition) Kind ¶
func (t Transition) Kind() TransitionKind
Kind returns the requested lifecycle intent.
func (Transition) MarshalJSON ¶
func (t Transition) MarshalJSON() ([]byte, error)
func (Transition) Output ¶
func (t Transition) Output() (Output, bool)
Output returns the final result for a Complete transition.
func (Transition) Reason ¶
func (t Transition) Reason() (string, bool)
Reason returns the pause reason for a Pause transition.
func (*Transition) UnmarshalJSON ¶
func (t *Transition) UnmarshalJSON(data []byte) error
func (Transition) Valid ¶
func (t Transition) Valid() bool
func (Transition) WaitID ¶
func (t Transition) WaitID() (WaitID, bool)
WaitID returns the wait target for a Wait transition.
type TransitionKind ¶
type TransitionKind string
TransitionKind is the lifecycle intent produced by one bounded Step.
const ( // TransitionKindInvalid is the invalid zero value. TransitionKindInvalid TransitionKind = "" // TransitionKindContinue advances to another runnable Step. TransitionKindContinue TransitionKind = "continue" // TransitionKindWait enters an Engine-minted wait. TransitionKindWait TransitionKind = "wait" // TransitionKindPause enters an explicit scheduling pause. TransitionKindPause TransitionKind = "pause" // TransitionKindComplete commits a validated semantic Output. TransitionKindComplete TransitionKind = "complete" // TransitionKindFail commits a classified failure. TransitionKindFail TransitionKind = "fail" )
func (TransitionKind) String ¶
func (t TransitionKind) String() string
func (TransitionKind) Valid ¶
func (t TransitionKind) Valid() bool
type TreeActivation ¶
type TreeActivation struct {
// contains filtered or unexported fields
}
TreeActivation changes writer identity and recovery state together so the previous Engine cannot continue committing after restoration takes ownership.
func (TreeActivation) IncarnationID ¶
func (t TreeActivation) IncarnationID() TreeIncarnationID
func (TreeActivation) PreviousIncarnationID ¶
func (t TreeActivation) PreviousIncarnationID() TreeIncarnationID
func (TreeActivation) PreviousTreeDigest ¶
func (t TreeActivation) PreviousTreeDigest() Digest
func (TreeActivation) TreeSnapshot ¶
func (t TreeActivation) TreeSnapshot() TreeSnapshot
func (TreeActivation) Valid ¶
func (t TreeActivation) Valid() bool
type TreeCheckpoint ¶
type TreeCheckpoint struct {
// contains filtered or unexported fields
}
TreeCheckpoint keeps child publication, input acceptance, and execution progress on the same head so recovery cannot observe partially accepted work. Input, child, and progress cuts can coexist with sibling jobs because those jobs expose only committed Execution state or already recorded Effect intent.
func (TreeCheckpoint) Kind ¶
func (t TreeCheckpoint) Kind() TreeCheckpointKind
func (TreeCheckpoint) PreviousTreeDigest ¶
func (t TreeCheckpoint) PreviousTreeDigest() Digest
func (TreeCheckpoint) TreeSnapshot ¶
func (t TreeCheckpoint) TreeSnapshot() TreeSnapshot
func (TreeCheckpoint) Valid ¶
func (t TreeCheckpoint) Valid() bool
type TreeCheckpointKind ¶
type TreeCheckpointKind string
TreeCheckpointKind distinguishes absent-head creation from writer-fenced updates, and stable owner cuts from fully parked or terminal trees.
const ( TreeCheckpointInvalid TreeCheckpointKind = "" TreeCheckpointStart TreeCheckpointKind = "start" TreeCheckpointChild TreeCheckpointKind = "child" TreeCheckpointInput TreeCheckpointKind = "input" TreeCheckpointProgress TreeCheckpointKind = "progress" TreeCheckpointParked TreeCheckpointKind = "parked" TreeCheckpointTerminal TreeCheckpointKind = "terminal" )
func (TreeCheckpointKind) String ¶
func (t TreeCheckpointKind) String() string
func (TreeCheckpointKind) Valid ¶
func (t TreeCheckpointKind) Valid() bool
type TreeDurability ¶
type TreeDurability interface {
// ActivateTree must fence the previous writer before restored work can run.
ActivateTree(ctx context.Context, activation TreeActivation) error
// CommitEffect must keep the Effect fact and tree head atomic so recovery
// cannot disagree with the dispatch or settlement that was acknowledged.
CommitEffect(ctx context.Context, boundary EffectBoundary) error
// CommitCheckpoint must compare an absent head for start, or the current
// head otherwise, to prevent publication from overwriting another writer.
CommitCheckpoint(ctx context.Context, checkpoint TreeCheckpoint) error
}
TreeDurability keeps all recoverable state on one authoritative head so a restored writer cannot race its predecessor. Every commit must atomically compare and advance that head; accepting a duplicate requires identical content and a head that still matches the proposal. Hosts own storage, deadlines, and reconciliation when a commit response is lost. The supplied context retains Host values but removes cancellation and deadlines. Hosts must apply an independent bounded storage deadline; a timeout does not prove that the authoritative head was unchanged and requires reconciliation.
A start checkpoint requires an absent head and a zero PreviousTreeDigest. Other checkpoints and Effects require the current incarnation and digest. Activation must replace both together to fence the previous writer before restoration can publish a Process. Initialization acknowledgment is separate because failed root initialization has no execution tree to persist.
type TreeFreezePhase ¶ added in v0.16.0
type TreeFreezePhase string
TreeFreezePhase describes the current scheduling barrier. Acquiring blocks scheduling while in-flight Effects settle. Held also stops completion adoption; an in-flight Step may still be computing against its isolated state.
const ( TreeFreezeNone TreeFreezePhase = "none" TreeFreezeAcquiring TreeFreezePhase = "acquiring" TreeFreezeHeld TreeFreezePhase = "held" )
type TreeIncarnationID ¶
type TreeIncarnationID struct {
// contains filtered or unexported fields
}
TreeIncarnationID identifies the one active writer generation of a durable Process tree. Its zero value is invalid.
func ParseTreeIncarnationID ¶
func ParseTreeIncarnationID(value string) (TreeIncarnationID, error)
ParseTreeIncarnationID validates the canonical wire representation of a tree incarnation identity.
func (TreeIncarnationID) MarshalText ¶
func (t TreeIncarnationID) MarshalText() ([]byte, error)
func (TreeIncarnationID) String ¶
func (t TreeIncarnationID) String() string
func (*TreeIncarnationID) UnmarshalText ¶
func (t *TreeIncarnationID) UnmarshalText(text []byte) error
func (TreeIncarnationID) Valid ¶
func (t TreeIncarnationID) Valid() bool
type TreeInspection ¶ added in v0.16.0
type TreeInspection struct {
RootID ProcessID
IncarnationID TreeIncarnationID
HeadDigest Digest
CommitPending bool
Freeze TreeFreezePhase
Stopped bool
Processes []ProcessInspection
}
TreeInspection is a caller-owned report from one runtime owner turn. In durable mode, snapshots and HeadDigest come only from the last head this instance acknowledged. A lost response or a replacement writer may have advanced storage further. Recovery must load the authoritative stored tree. IncarnationID and HeadDigest are zero in ephemeral mode. Work and barriers describe the sampling turn and may be newer than the acknowledged snapshots. Stopped means the owner has exited after draining its work. Reports contain no recovery or scheduling authority and are not a persistence schema.
func (TreeInspection) Process ¶ added in v0.16.0
func (t TreeInspection) Process(processID ProcessID) (ProcessInspection, bool)
Process finds a published Process in the report's canonical depth/ID order.
type TreeLimits ¶
type TreeLimits struct {
// MaxDepth bounds the root-relative depth of any Process.
MaxDepth uint32 `json:"max_depth"`
// MaxChildren bounds the lifetime child count of one Process.
MaxChildren uint32 `json:"max_children"`
// MaxActiveChildren bounds concurrent non-terminal children of one Process.
MaxActiveChildren uint32 `json:"max_active_children"`
// MaxTreeProcesses bounds the lifetime Process count of one tree.
MaxTreeProcesses uint32 `json:"max_tree_processes"`
}
TreeLimits bounds structural expansion independently of per-Process work limits. Every zero field in EngineConfig inherits DefaultTreeLimits.
func DefaultTreeLimits ¶
func DefaultTreeLimits() TreeLimits
DefaultTreeLimits returns conservative structured-concurrency bounds.
func (TreeLimits) Valid ¶
func (t TreeLimits) Valid() bool
type TreeSnapshot ¶
type TreeSnapshot struct {
// contains filtered or unexported fields
}
TreeSnapshot is an immutable, portable capture of one complete Process tree. It owns Framework execution facts, a canonical content digest, and the optional active-writer identity of durable state. Persistence, transactions, revisions, and cleanup policy remain Host responsibilities.
func ParseTreeSnapshot ¶
func ParseTreeSnapshot(data json.RawMessage) (TreeSnapshot, error)
ParseTreeSnapshot validates the current wire shape and domain constraints of one complete Process tree. Unknown members are rejected. Every active child wait must have a registration belonging to its Process and matching its opening Signal. Pending satisfaction Signals must agree with that boundary and the terminal results in the captured tree.
func (TreeSnapshot) Digest ¶
func (t TreeSnapshot) Digest() Digest
Digest returns the canonical content identity of this complete tree state.
func (TreeSnapshot) IncarnationID ¶
func (t TreeSnapshot) IncarnationID() (TreeIncarnationID, bool)
IncarnationID returns the active writer identity carried by a durable tree. Ephemeral snapshots return false.
func (TreeSnapshot) JSON ¶
func (t TreeSnapshot) JSON() json.RawMessage
JSON returns an independently owned tree snapshot representation.
func (TreeSnapshot) MarshalJSON ¶
func (t TreeSnapshot) MarshalJSON() ([]byte, error)
func (TreeSnapshot) ProcessSnapshots ¶
func (t TreeSnapshot) ProcessSnapshots() []ProcessSnapshot
ProcessSnapshots returns immutable captures ordered by depth and ProcessID.
func (TreeSnapshot) RootID ¶
func (t TreeSnapshot) RootID() ProcessID
RootID returns the identity of the tree's root Process.
func (*TreeSnapshot) UnmarshalJSON ¶
func (t *TreeSnapshot) UnmarshalJSON(data []byte) error
func (TreeSnapshot) Valid ¶
func (t TreeSnapshot) Valid() bool
type Usage ¶
type Usage struct {
// CommittedSteps counts finalized Steps.
CommittedSteps uint64 `json:"committed_steps"`
// PreparedEffects counts stable logical Effect identities, not replay attempts.
PreparedEffects uint64 `json:"prepared_effects"`
// AcceptedSignals counts external and Engine-generated mailbox entries.
AcceptedSignals uint64 `json:"accepted_signals"`
// DroppedDeltas counts increments rejected by validation or the bounded queue.
DroppedDeltas uint64 `json:"dropped_deltas"`
}
Usage contains monotonic Framework-owned counters. It deliberately excludes provider pricing and Strategy-specific concepts such as tokens or tool calls.
type WaitID ¶
type WaitID struct {
// contains filtered or unexported fields
}
WaitID identifies one Engine-created wait target owned by a Process. Parsing a WaitID does not create a wait; the Engine rejects identities it did not mint.
func ParseWaitID ¶
ParseWaitID validates the wire representation of a Wait identity.
func (WaitID) JSONSchemaAlias ¶ added in v0.17.0
func (WaitID) JSONSchemaAlias() any
func (WaitID) MarshalText ¶
func (*WaitID) UnmarshalText ¶
type WaitKey ¶
type WaitKey struct {
// contains filtered or unexported fields
}
WaitKey is an Execution-owned logical key used to associate a requested wait with the WaitID later minted by the Engine.
func ParseWaitKey ¶
ParseWaitKey validates an Execution-owned logical wait key.
func (WaitKey) JSONSchemaAlias ¶ added in v0.17.0
func (WaitKey) JSONSchemaAlias() any
func (WaitKey) MarshalText ¶
func (*WaitKey) UnmarshalText ¶
Source Files
¶
- capability.go
- child.go
- child_control.go
- child_start.go
- child_wait.go
- definition.go
- delta.go
- deployment.go
- deployment_ref.go
- descriptor.go
- digest.go
- dispatcher.go
- doc.go
- effect.go
- effect_dispatch.go
- effect_phase.go
- engine.go
- event.go
- event_payload.go
- execution_boundary.go
- execution_state.go
- failure.go
- identity.go
- mailbox.go
- mailbox_admission.go
- name.go
- observation.go
- observation_failure.go
- observation_reentrancy.go
- prepared_step.go
- process.go
- process_admission.go
- process_capture.go
- process_handle_state.go
- process_initialization_outcome.go
- process_relation.go
- process_restore.go
- process_snapshot.go
- process_start_registration.go
- process_state.go
- resource.go
- runtime_error.go
- schema.go
- settlement.go
- signal.go
- signal_receipt.go
- signal_request.go
- status.go
- step_commit.go
- termination.go
- transition.go
- tree_child_control.go
- tree_commit.go
- tree_control.go
- tree_durability.go
- tree_events.go
- tree_head.go
- tree_incarnation.go
- tree_inspection.go
- tree_jobs.go
- tree_join.go
- tree_lifecycle.go
- tree_membership.go
- tree_operation.go
- tree_release.go
- tree_restore.go
- tree_runtime.go
- tree_snapshot.go
- tree_snapshot_control.go
- tree_snapshot_wait.go
- tree_step.go
- wire.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package agenttest provides deterministic consumer-side fixtures and reusable conformance suites for the Agent Framework's public execution boundaries.
|
Package agenttest provides deterministic consumer-side fixtures and reusable conformance suites for the Agent Framework's public execution boundaries. |
|
examples
|
|
|
autonomous
command
Command autonomous demonstrates an Interaction in which the model chooses a Tool from environment feedback and decides when to stop.
|
Command autonomous demonstrates an Interaction in which the model chooses a Tool from environment feedback and decides when to stop. |
|
composition
command
Command composition demonstrates that direct Engine embedding and a cross-Strategy composed Agent use the same Definition/Execution/Process contracts.
|
Command composition demonstrates that direct Engine embedding and a cross-Strategy composed Agent use the same Definition/Execution/Process contracts. |
|
direct_vs_managed
command
Command direct_vs_managed contrasts a direct model call with the same model capability managed as a recoverable agent Process.
|
Command direct_vs_managed contrasts a direct model call with the same model capability managed as a recoverable agent Process. |
|
evaluator_optimizer
command
Command evaluator_optimizer demonstrates bounded evaluator-optimizer composition with exact managed child Processes.
|
Command evaluator_optimizer demonstrates bounded evaluator-optimizer composition with exact managed child Processes. |
|
orchestrator_workers
command
Command orchestrator_workers demonstrates model-directed task decomposition, deterministic managed worker fan-out, and model synthesis without a collaboration Strategy.
|
Command orchestrator_workers demonstrates model-directed task decomposition, deterministic managed worker fan-out, and model synthesis without a collaboration Strategy. |
|
workflow
command
Command workflow demonstrates an ordered managed Workflow whose Call and Fork Stages create independently recoverable child Processes.
|
Command workflow demonstrates an ordered managed Workflow whose Call and Fork Stages create independently recoverable child Processes. |
|
workflow_patterns
command
Command workflow_patterns demonstrates prompt chaining, routing, parallel sectioning, and parallel voting through one managed Workflow.
|
Command workflow_patterns demonstrates prompt chaining, routing, parallel sectioning, and parallel voting through one managed Workflow. |
|
internal
|
|
|
conformancetest
Package conformancetest captures real Engine boundaries for built-in Strategy tests.
|
Package conformancetest captures real Engine boundaries for built-in Strategy tests. |
|
Package messaging delivers intermediate input through ordinary Dispatcher Effects.
|
Package messaging delivers intermediate input through ordinary Dispatcher Effects. |
|
strategy
|
|
|
collaboration
Package collaboration provides bounded, decision-driven multi-agent work.
|
Package collaboration provides bounded, decision-driven multi-agent work. |
|
coordination
Package coordination provides bounded coordination through ordinary Agent Definitions.
|
Package coordination provides bounded coordination through ordinary Agent Definitions. |
|
interaction
Package interaction provides the model-directed execution Strategy for the Agent Framework.
|
Package interaction provides the model-directed execution Strategy for the Agent Framework. |
|
internal/childcall
Package childcall owns Framework child response correlation and recoverable single-child handshake progress.
|
Package childcall owns Framework child response correlation and recoverable single-child handshake progress. |
|
planning
Package planning provides goal-directed state planning as an Agent execution strategy.
|
Package planning provides goal-directed state planning as an Agent execution strategy. |
|
planning/goap
Package goap provides deterministic goal-oriented action planning over immutable planning.WorldState values.
|
Package goap provides deterministic goal-oriented action planning over immutable planning.WorldState values. |
|
workflow
Package workflow provides deterministic orchestration of Framework-managed child Processes.
|
Package workflow provides deterministic orchestration of Framework-managed child Processes. |