stepkind

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MIT Imports: 18 Imported by: 0

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

View Source
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

View Source
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

type DuplicateRegistrationError struct {
	Name    string
	Version string
}

DuplicateRegistrationError identifies an already registered name/version.

func (*DuplicateRegistrationError) Error

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) Error

func (e *ExecutionError) Error() string

Error implements error.

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 NewRegistry

func NewRegistry() *MemoryRegistry

NewRegistry returns an empty registry.

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

type ResolutionError struct {
	Name      string
	Version   string
	Available []string
	Cause     error
}

ResolutionError reports an unknown or ambiguous kind/version request.

func (*ResolutionError) Error

func (e *ResolutionError) Error() string

Error implements error.

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.

func (*SpecError) Error

func (e *SpecError) Error() string

Error implements error while retaining Diagnostics for callers that must not parse presentation strings.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL