Documentation
¶
Overview ¶
Package stepkind owns application-neutral step-kind metadata, registry, and executor contracts.
It is extraction-ready engine core. Imports are limited to the standard library and other workflow core packages; Hadron internal packages and concrete adapters are forbidden. Executors advertise immutable metadata at registration and implement only the lifecycle capabilities they declare. Memoization metadata is a fail-closed capability declaration: it cannot make mutate/destructive effects reusable, and materialize still requires host policy approval.
Index ¶
- Constants
- Variables
- func Resolve(registry Registry, name, version string) (StepKind, StepKindSpec, error)
- func ValidateSpec(spec StepKindSpec) error
- type CallInvocation
- type Canceler
- type CancellationMode
- type CancellationSpec
- type CompensationReceipt
- type CompensationSupport
- type DuplicateRegistrationError
- type ExecutionError
- type ExternalOperationRef
- type Finalization
- type Finalizer
- type Heartbeater
- type Invocation
- type InvocationIdentity
- type LifecycleSpec
- type MemoizationSupport
- type MemoryRegistry
- type Observation
- type ObservationMode
- type ObservationSpec
- type ObservationState
- type Observer
- type PreparedInvocation
- type Preparer
- type Registry
- type ResolutionError
- type RetryClassification
- type RetryClassifier
- type RetrySafety
- type ReversibilityEvidence
- type ReversibilityProvider
- type ReversibilityRequest
- type ServiceBinding
- type ServiceController
- type ServiceObservation
- type ServiceObservationState
- type ServicePhase
- type SpecError
- type StepKind
- type StepKindSpec
- type StepOutcome
- type StepResult
- type WaitContinuation
- type WaitResult
Constants ¶
const ( // CodeInvalidSpec identifies missing or invalid step-kind metadata. CodeInvalidSpec diagnostic.Code = "HADR-HOST-001" // CodeLifecycleMismatch identifies disagreement between advertised metadata // and implemented optional interfaces. CodeLifecycleMismatch diagnostic.Code = "HADR-HOST-002" // CodeInvalidConfig is available to step kinds for config diagnostics that // do not need a more specific source-validation assignment. CodeInvalidConfig diagnostic.Code = "HADR-SOURCE-100" )
Variables ¶
var ( // ErrUnknownStepKind identifies an unavailable exact registration. ErrUnknownStepKind = errors.New("unknown step kind") // ErrAmbiguousStepKind identifies an unpinned name with multiple versions. ErrAmbiguousStepKind = errors.New("ambiguous step kind version") )
Functions ¶
func Resolve ¶
func Resolve(registry Registry, name, version string) (StepKind, StepKindSpec, error)
Resolve returns a validated registration and defensive spec for an exact name/version. When version is empty, exactly one registered version may be selected; Resolve never chooses a latest version from multiple candidates.
func ValidateSpec ¶
func ValidateSpec(spec StepKindSpec) error
ValidateSpec validates metadata independently of an executor implementation. Schemas must compile under the core's local-only JSON Schema contract; adapter-specific config validation remains owned by ValidateConfig.
Types ¶
type CallInvocation ¶
type CallInvocation struct {
Spec graph.CallSpec `json:"spec"`
Lineage []graph.DefinitionRef `json:"lineage"`
}
CallInvocation carries the graph-native call declaration and the immutable active definition path supplied by the runtime host. Lineage contains the parent definition followed by every active inline/run ancestor; call executors append the newly resolved child only after cycle/depth checks. Hosts reconstruct this path from durable run/call state during recovery.
type Canceler ¶
type Canceler interface {
Cancel(ctx context.Context, ref ExternalOperationRef) error
}
Canceler optionally cancels an adapter-owned external operation.
type CancellationMode ¶
type CancellationMode string
CancellationMode describes how an invocation responds to cancellation.
const ( // CancellationNone means the kind does not support cancellation after // execution begins. CancellationNone CancellationMode = "none" // CancellationContext means Execute observes context cancellation. CancellationContext CancellationMode = "context" // CancellationExplicit means the kind implements Canceler for an external // operation. CancellationExplicit CancellationMode = "explicit" )
func (CancellationMode) Valid ¶
func (m CancellationMode) Valid() bool
Valid reports whether m is a supported cancellation mode.
type CancellationSpec ¶
type CancellationSpec struct {
Mode CancellationMode `json:"mode"`
}
CancellationSpec advertises cancellation behavior without embedding a concrete adapter's operation type.
type CompensationReceipt ¶
type CompensationReceipt struct {
Operation string `json:"operation"`
Values values.ValueSet `json:"values"`
ChildRunID string `json:"child_run_id,omitempty"`
}
CompensationReceipt is adapter-produced effect evidence. Values are persistable typed data; raw credentials and process-local handles are not.
type CompensationSupport ¶
type CompensationSupport string
CompensationSupport is a kind's immutable opt-in to operation-specific reversibility discovery. Receipt requires ReversibilityProvider and a truthful StepResult receipt whenever an applied effect is compensable.
const ( CompensationUnsupported CompensationSupport = "" CompensationReceiptRequired CompensationSupport = "receipt" )
func (CompensationSupport) Valid ¶
func (s CompensationSupport) Valid() bool
type DuplicateRegistrationError ¶
DuplicateRegistrationError identifies an already registered name/version.
func (*DuplicateRegistrationError) Error ¶
func (e *DuplicateRegistrationError) Error() string
Error implements error.
type ExecutionError ¶
type ExecutionError struct {
Code string `json:"code"`
Message string `json:"message"`
Classification RetryClassification `json:"retry_classification"`
Details map[string]string `json:"details,omitempty"`
Cause error `json:"-"`
}
ExecutionError is the structured application-neutral adapter failure used for persistence and retry policy. Message and Details are declarations that are safe to persist after known-secret masking. Cause is process-local and never serialized. Adapters should return an unstructured error when they cannot make that persistence-safety guarantee.
func (*ExecutionError) RetryClassification ¶
func (e *ExecutionError) RetryClassification() RetryClassification
RetryClassification implements RetryClassifier.
func (*ExecutionError) Unwrap ¶
func (e *ExecutionError) Unwrap() error
Unwrap exposes the process-local cause to errors.Is/errors.As.
func (ExecutionError) Validate ¶
func (e ExecutionError) Validate() error
Validate reports malformed structured execution failure metadata.
type ExternalOperationRef ¶
type ExternalOperationRef struct {
Kind string `json:"kind"`
ID string `json:"id"`
Metadata map[string]string `json:"metadata,omitempty"`
}
ExternalOperationRef identifies adapter-owned work for observation or cancellation. Every field crosses the durable persistence and event boundary, so Kind, ID, and Metadata must be stable non-secret identifiers and metadata. They must never contain bearer tokens, credentials, or resolved secret material; adapters resolve authorization separately.
func (ExternalOperationRef) Validate ¶
func (r ExternalOperationRef) Validate() error
Validate reports malformed durable external-operation identity.
type Finalization ¶
type Finalization struct {
Invocation PreparedInvocation
Result StepResult
ExecutionError error
}
Finalization supplies the execution outcome to an optional Finalizer.
type Finalizer ¶
type Finalizer interface {
Finalize(ctx context.Context, finalization Finalization) error
}
Finalizer optionally releases resources after execution completes.
type Heartbeater ¶
type Heartbeater interface {
Heartbeat(ctx context.Context, ref ExternalOperationRef) error
}
Heartbeater optionally refreshes or probes an adapter-owned external operation independently of the runtime's own claim lease heartbeat.
type Invocation ¶
type Invocation struct {
Identity InvocationIdentity `json:"identity"`
Config graph.Config `json:"config"`
Inputs values.ValueSet `json:"inputs"`
Call *CallInvocation `json:"call,omitempty"`
Continuation *WaitContinuation `json:"continuation,omitempty"`
Service *ServiceBinding `json:"service,omitempty"`
Compensation *ReversibilityEvidence `json:"compensation,omitempty"`
// Verification is the immutable graph modifier carried through durable
// external-operation recovery. Activity is a runtime-issued, process-local
// recorder; it is deliberately excluded from durable invocation JSON.
Verification *graph.VerificationSpec `json:"verification,omitempty"`
Activity *verification.ActivityRecorder `json:"-"`
IdempotencyKey string `json:"idempotency_key,omitempty"`
Deadline time.Time `json:"deadline,omitempty"`
}
Invocation is the application-neutral input to optional preparation. W04-T01 extends it with runtime context and typed values without replacing the executor interfaces.
func (Invocation) Validate ¶
func (i Invocation) Validate() error
Validate checks runtime identity, JSON-compatible config, and typed inputs.
type InvocationIdentity ¶
type InvocationIdentity struct {
RunID string `json:"run_id"`
NodeID string `json:"node_id"`
Iteration string `json:"iteration,omitempty"`
Attempt int `json:"attempt"`
}
InvocationIdentity is the application-neutral execution identity visible to adapters. String identities deliberately avoid coupling step kinds to a runtime store's concrete ID types.
func (InvocationIdentity) Validate ¶
func (i InvocationIdentity) Validate() error
Validate reports a malformed application-neutral invocation identity.
type LifecycleSpec ¶
type LifecycleSpec struct {
Prepare bool `json:"prepare,omitempty"`
Finalize bool `json:"finalize,omitempty"`
// Service routes polling, heartbeat, and explicit stop through the durable
// ServiceController lane instead of the generic external-operation lane.
Service bool `json:"service,omitempty"`
}
LifecycleSpec advertises optional lifecycle hooks not otherwise described by cancellation or observation metadata.
type MemoizationSupport ¶
type MemoizationSupport string
MemoizationSupport is an executor's immutable opt-in to result reuse. Default permits the runtime's safe read/compute default. Approved is the additional executor assertion required before materialize effects may be reused; host policy must still approve. Disabled rejects all memoization.
const ( MemoizationDefault MemoizationSupport = "" MemoizationApproved MemoizationSupport = "approved" MemoizationDisabled MemoizationSupport = "disabled" )
func (MemoizationSupport) Valid ¶
func (m MemoizationSupport) Valid() bool
Valid reports whether m is a supported memoization declaration.
type MemoryRegistry ¶
type MemoryRegistry struct {
// contains filtered or unexported fields
}
MemoryRegistry is a concurrency-safe in-memory Registry implementation.
func (*MemoryRegistry) List ¶
func (r *MemoryRegistry) List() []StepKindSpec
List returns defensive spec copies ordered by name and then version.
func (*MemoryRegistry) Lookup ¶
func (r *MemoryRegistry) Lookup(name, version string) (StepKind, bool)
Lookup returns the exact name/version registration. It does not select a latest version or apply version ranges.
func (*MemoryRegistry) Register ¶
func (r *MemoryRegistry) Register(kind StepKind) error
Register validates and registers kind under its immutable name and version.
type Observation ¶
type Observation struct {
State ObservationState `json:"state"`
Progress map[string]string `json:"progress,omitempty"`
Result *StepResult `json:"result,omitempty"`
Failure *ExecutionError `json:"failure,omitempty"`
}
Observation is a typed external-operation observation envelope. Progress is operational metadata, not workflow output data.
func (Observation) Validate ¶
func (o Observation) Validate() error
Validate checks the observation's closed state and mutually exclusive terminal outcome fields.
type ObservationMode ¶
type ObservationMode string
ObservationMode describes whether external work can be observed.
const ( // ObservationNone means the kind has no external observation hook. ObservationNone ObservationMode = "none" // ObservationPoll means the kind implements Observer for polling external // operation state. ObservationPoll ObservationMode = "poll" )
func (ObservationMode) Valid ¶
func (m ObservationMode) Valid() bool
Valid reports whether m is a supported observation mode.
type ObservationSpec ¶
type ObservationSpec struct {
Mode ObservationMode `json:"mode"`
Heartbeat bool `json:"heartbeat,omitempty"`
}
ObservationSpec advertises observation behavior.
type ObservationState ¶
type ObservationState string
ObservationState is the adapter-reported state of external work.
const ( ObservationPending ObservationState = "pending" ObservationSucceeded ObservationState = "succeeded" ObservationFailed ObservationState = "failed" ObservationCanceled ObservationState = "canceled" )
func (ObservationState) Valid ¶
func (s ObservationState) Valid() bool
Valid reports whether s is a supported observation state.
type Observer ¶
type Observer interface {
Observe(ctx context.Context, ref ExternalOperationRef) (Observation, error)
}
Observer optionally polls an adapter-owned external operation.
type PreparedInvocation ¶
type PreparedInvocation struct {
Invocation Invocation `json:"invocation"`
// State is process-local adapter state. Runtimes never persist, serialize,
// compare, or expose it outside the adapter lifecycle.
State any `json:"-"`
}
PreparedInvocation is the required input to Execute. Runtimes wrap an Invocation directly when a kind does not implement Preparer.
type Preparer ¶
type Preparer interface {
Prepare(ctx context.Context, invocation Invocation) (PreparedInvocation, error)
}
Preparer optionally prepares an invocation before Execute.
type Registry ¶
type Registry interface {
Register(kind StepKind) error
Lookup(name, version string) (StepKind, bool)
List() []StepKindSpec
}
Registry exposes deterministic registration and lookup by name and version.
type ResolutionError ¶
ResolutionError reports an unknown or ambiguous kind/version request.
func (*ResolutionError) Unwrap ¶
func (e *ResolutionError) Unwrap() error
Unwrap supports errors.Is against the resolution cause.
type RetryClassification ¶
type RetryClassification string
RetryClassification describes an individual execution failure. It is distinct from RetrySafety: the former classifies what happened, while the latter declares whether repeating the kind can ever be safe.
const ( RetryUnspecified RetryClassification = "unspecified" Retryable RetryClassification = "retryable" RetryPermanent RetryClassification = "permanent" )
func ClassifyError ¶
func ClassifyError(err error) RetryClassification
ClassifyError returns the first valid retry classification exposed by err's chain. Unknown, nil, or malformed classifiers remain unspecified.
func (RetryClassification) Valid ¶
func (c RetryClassification) Valid() bool
Valid reports whether c is a supported retry classification.
type RetryClassifier ¶
type RetryClassifier interface {
RetryClassification() RetryClassification
}
RetryClassifier may be implemented by adapter errors without requiring the concrete error type to cross the core boundary.
type RetrySafety ¶
type RetrySafety string
RetrySafety describes when the engine may retry an invocation. It is metadata only; runtime retry classification is added by W04-T01.
const ( // RetryUnsupported means the kind cannot safely be retried. RetryUnsupported RetrySafety = "unsupported" // RetrySafe means repeated execution is intrinsically safe. RetrySafe RetrySafety = "safe" // RetryRequiresIdempotency means retry requires an invocation-level // idempotency declaration accepted by policy. RetryRequiresIdempotency RetrySafety = "requires-idempotency" )
func (RetrySafety) Valid ¶
func (s RetrySafety) Valid() bool
Valid reports whether s is a supported retry-safety declaration.
type ReversibilityEvidence ¶
type ReversibilityEvidence struct {
Operation string `json:"operation"`
ReceiptSchema graph.Schema `json:"receipt_schema"`
}
ReversibilityEvidence is the config-specific, non-secret claim returned by the registered adapter before an operation is admitted as compensable.
func ResolveReversibility ¶
func ResolveReversibility(ctx context.Context, provider ReversibilityProvider, request ReversibilityRequest) (ReversibilityEvidence, error)
ResolveReversibility obtains one deterministic, validated operation claim from a registered kind. Separate deep-cloned calls prevent a provider from mutating the compiler/runtime request and make descriptor drift fail closed before an effect is admitted.
type ReversibilityProvider ¶
type ReversibilityProvider interface {
DescribeReversibility(context.Context, ReversibilityRequest) (ReversibilityEvidence, error)
}
ReversibilityProvider describes reversibility for the exact immutable node config. It must be deterministic and must not perform an external effect.
type ReversibilityRequest ¶
type ReversibilityRequest struct {
Config graph.Config `json:"config"`
Call *graph.CallSpec `json:"call,omitempty"`
}
ReversibilityRequest supplies the exact immutable graph declaration that can affect operation semantics. Config alone is insufficient for native modifiers such as call mode.
type ServiceBinding ¶
type ServiceBinding struct {
Phase ServicePhase `json:"phase"`
StartInvocation InvocationIdentity `json:"start_invocation"`
Ref ExternalOperationRef `json:"ref"`
// Absent is set only by the runtime when the start node never materialized
// provider work. It lets the generated finalizer succeed as an exact no-op.
Absent bool `json:"absent,omitempty"`
}
ServiceBinding is injected by the runtime only for generated teardown nodes. Ref is the immutable provider reference returned by the original service-start attempt; adapters must not accept an authored substitute.
func (ServiceBinding) Validate ¶
func (b ServiceBinding) Validate() error
Validate reports malformed service continuation state.
type ServiceController ¶
type ServiceController interface {
ObserveService(context.Context, ExternalOperationRef) (ServiceObservation, error)
RequestStop(context.Context, ExternalOperationRef, string) error
}
ServiceController is the extraction-ready host lifecycle port for one registered service kind. RequestStop must be idempotent for the immutable invocation identity and reference; ObserveService must be side-effect free.
type ServiceObservation ¶
type ServiceObservation struct {
State ServiceObservationState `json:"state"`
Progress map[string]string `json:"progress,omitempty"`
Outputs values.ValueSet `json:"outputs,omitempty"`
Failure *ExecutionError `json:"failure,omitempty"`
Heartbeat bool `json:"heartbeat,omitempty"`
}
ServiceObservation carries readiness/stopped outcomes plus bounded, non-secret operational progress. Outputs are published only at readiness.
func (ServiceObservation) Validate ¶
func (o ServiceObservation) Validate() error
Validate enforces the mutually exclusive service observation shapes.
type ServiceObservationState ¶
type ServiceObservationState string
ServiceObservationState is the provider-neutral durable service state.
const ( ServiceObservationStarting ServiceObservationState = "starting" ServiceObservationReady ServiceObservationState = "ready" ServiceObservationStopped ServiceObservationState = "stopped" ServiceObservationFailed ServiceObservationState = "failed" )
func (ServiceObservationState) Valid ¶
func (s ServiceObservationState) Valid() bool
Valid reports whether s is a supported service observation state.
type ServicePhase ¶
type ServicePhase string
ServicePhase distinguishes provider start/readiness from durable teardown.
const ( ServiceStart ServicePhase = "start" ServiceTeardown ServicePhase = "teardown" )
func (ServicePhase) Valid ¶
func (p ServicePhase) Valid() bool
Valid reports whether p is part of the closed service lifecycle vocabulary.
type SpecError ¶
type SpecError struct {
Diagnostics []diagnostic.Diagnostic
}
SpecError contains structured diagnostics for an invalid registration spec.
type StepKind ¶
type StepKind interface {
Spec() StepKindSpec
ValidateConfig(ctx context.Context, config graph.Config) []diagnostic.Diagnostic
Execute(ctx context.Context, invocation PreparedInvocation) (StepResult, error)
}
StepKind is the required executor lifecycle shared by all adapters.
type StepKindSpec ¶
type StepKindSpec struct {
Name string `json:"name"`
Version string `json:"version"`
ConfigSchema graph.Schema `json:"config_schema"`
InputSchema graph.Schema `json:"input_schema"`
OutputSchema graph.Schema `json:"output_schema"`
Effects graph.EffectSet `json:"effects"`
RequiredCapabilities []string `json:"required_capabilities,omitempty"`
Idempotency graph.IdempotencyMode `json:"idempotency"`
RetrySafety RetrySafety `json:"retry_safety"`
Cancellation CancellationSpec `json:"cancellation"`
Observation ObservationSpec `json:"observation"`
Lifecycle LifecycleSpec `json:"lifecycle,omitempty"`
Memoization MemoizationSupport `json:"memoization,omitempty"`
Compensation CompensationSupport `json:"compensation,omitempty"`
CanSuspend bool `json:"can_suspend,omitempty"`
EmbeddedModeSupported bool `json:"embedded_mode_supported,omitempty"`
}
StepKindSpec is immutable metadata used by compilers, policy evaluators, and runtimes before adapter execution. Empty schemas are valid JSON Schemas; nil schemas are missing metadata.
type StepOutcome ¶
type StepOutcome string
StepOutcome is the closed execution handoff produced by Execute.
const ( StepCompleted StepOutcome = "completed" StepWaiting StepOutcome = "waiting" StepExternal StepOutcome = "external" )
func (StepOutcome) Valid ¶
func (o StepOutcome) Valid() bool
Valid reports whether o is a supported execution handoff.
type StepResult ¶
type StepResult struct {
Outcome StepOutcome `json:"outcome"`
Outputs values.ValueSet `json:"outputs,omitempty"`
Wait *WaitResult `json:"wait,omitempty"`
External *ExternalOperationRef `json:"external,omitempty"`
// Compensation is durable proof that the forward effect was applied and
// carries the exact typed receipt required by its dormant handler.
Compensation *CompensationReceipt `json:"compensation,omitempty"`
}
StepResult is one mutually exclusive completed, waiting, or external outcome. Completed outputs are typed and persistable. Waiting delegates to the canonical generic-wait contract. External delegates to a durable operation record that recovery can observe independently of worker leases.
func (StepResult) Validate ¶
func (r StepResult) Validate() error
Validate checks that a completed result is safe to persist.
type WaitContinuation ¶
type WaitContinuation struct {
ID string `json:"id"`
Record workflowwait.Record `json:"record"`
Values values.ValueSet `json:"values"`
}
WaitContinuation is the durable resolved wait delivered when the runtime resumes the same logical attempt. Values are loaded from Record.ResumeValues and digest-checked; the raw one-time resume token never enters this envelope.
func (WaitContinuation) Validate ¶
func (c WaitContinuation) Validate() error
Validate requires an exact resumed wait and digest-bound persistable values.
type WaitResult ¶
type WaitResult struct {
ID string `json:"id"`
Record workflowwait.Record `json:"record"`
ResumeToken string `json:"-"`
}
WaitResult is the adapter-facing generic wait handoff. Record is the canonical workflow/wait contract and must be open. ResumeToken is a one-time process-local capability; only its matching digest enters Record.
func (WaitResult) Validate ¶
func (r WaitResult) Validate() error
Validate checks the canonical open wait handoff without persisting the raw resume token. Token/digest equality is enforced by runtime.WaitCoordinator.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package stepkindtest provides application-neutral fake step kinds for compiler, runtime, and conformance tests.
|
Package stepkindtest provides application-neutral fake step kinds for compiler, runtime, and conformance tests. |