action

package
v0.3.0-alpha.2 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: Apache-2.0 Imports: 23 Imported by: 3

Documentation

Overview

Package action defines typed governed operations and the Runtime that applies schema validation, authorization, Preview binding, idempotency, transactions, and audit semantics consistently across consumer channels.

Stability: alpha. Consumers should pin an exact pre-v1 Modary version.

Index

Constants

View Source
const (
	// CodeActionNotFound identifies a request for an unregistered Action.
	CodeActionNotFound = "ACTION_NOT_FOUND"
	// CodeValidationFailed identifies an invalid request or JSON value.
	CodeValidationFailed = "VALIDATION_FAILED"
	// CodeAuthzDenied identifies a denied authorization decision.
	CodeAuthzDenied = "AUTHZ_DENIED"
	// CodePreconditionFailed identifies an unmet Action precondition.
	CodePreconditionFailed = "PRECONDITION_FAILED"
	// CodePlanRequired identifies execution attempted without a required Preview plan.
	CodePlanRequired = "PLAN_REQUIRED"
	// CodePlanNotFound identifies a requested Preview plan that does not exist.
	CodePlanNotFound = "PLAN_NOT_FOUND"
	// CodePlanStale identifies a Preview plan whose bindings are no longer current.
	CodePlanStale = "PLAN_STALE"
	// CodeLimitExceeded identifies an authorized impact that exceeds its constraints.
	CodeLimitExceeded = "LIMIT_EXCEEDED"
	// CodeIdempotencyRequired identifies a missing required idempotency key.
	CodeIdempotencyRequired = "IDEMPOTENCY_REQUIRED"
	// CodeIdempotencyConflict identifies reuse of a key for a different execution.
	CodeIdempotencyConflict = "IDEMPOTENCY_CONFLICT"
	// CodeIdempotencyProgress identifies an execution already in progress for a key.
	CodeIdempotencyProgress = "IDEMPOTENCY_IN_PROGRESS"
	// CodeUnavailable identifies a Runtime that is no longer accepting execution.
	CodeUnavailable = "UNAVAILABLE"
	// CodeInternal identifies an unexpected framework, adapter, or Handler failure.
	CodeInternal = "INTERNAL_ERROR"
)
View Source
const (
	// MaxIdempotencyKeyBytes bounds the portable ASCII request token.
	MaxIdempotencyKeyBytes = 256
	// IdempotencyKeyPattern is the JSON Schema and Go validation grammar used
	// consistently by every Action channel.
	IdempotencyKeyPattern = `^[A-Za-z0-9][A-Za-z0-9._~:/+-]{0,255}$`
)
View Source
const (
	MaxJSONDocumentBytes = int64(1 << 20)
	MaxJSONNestingDepth  = 256
	MaxJSONValueNodes    = 65_536
	MaxJSONNumberBytes   = 4_096
)

Action JSON resource limits apply independently to every schema, request input, handler plan value, preview value, result, and persisted JSON value. Protocol envelopes have their own byte budget and revalidate embedded Action values against this contract.

View Source
const (
	MaxSchemaNodes                   = 2_048
	MaxSchemaCollectionEntries       = 512
	MaxSchemaEnumValues              = 256
	MaxSchemaLiteralBytes            = 16 << 10
	MaxSchemaPatternBytes            = 4 << 10
	MaxSchemaSameInstanceVisits      = 1_024
	MaxSchemaNumericCompileWorkUnits = 64 << 20
	MaxSchemaEvaluationWorkUnits     = 64 << 20
	MaxSchemaMismatchEvents          = 4_096
	MaxSchemaEvaluationFrames        = 4_096
)

JSON Schema execution limits apply independently to each compiled Action schema and each validation call.

View Source
const (

	// MaxErrorMessageRunes bounds every consumer-visible Action error message.
	MaxErrorMessageRunes = 512
)

Variables

View Source
var ErrCallbackPanic = errors.New("action callback panic")

ErrCallbackPanic identifies a recovered panic from an Action callback.

Functions

func ErrorCode

func ErrorCode(err error) string

ErrorCode returns the code of the first Error in the bounded trusted unwrap graph, or CodeInternal when no Action error is found. Caller-defined Is, As, and Unwrap methods are never invoked.

func GenerateTypeScriptCatalog

func GenerateTypeScriptCatalog(descriptors []Descriptor) ([]byte, error)

GenerateTypeScriptCatalog derives channel-facing TypeScript contracts from the same schemas registered by the Action Runtime. Exact numeric literals outside JavaScript's safe integer range are rejected rather than rounded.

func IsCode

func IsCode(err error, code string) bool

IsCode reports whether err contains an Error with the supplied code using the same bounded traversal as ErrorCode.

func IsKind

func IsKind(err error, kind ErrorKind) bool

IsKind reports whether err contains an Error with the supplied governed semantic kind.

func ValidCustomErrorCode

func ValidCustomErrorCode(code string) bool

ValidCustomErrorCode reports whether code is a bounded namespace-qualified consumer error code. Descriptor validation additionally rejects framework codes and duplicate declarations.

func ValidErrorMessage

func ValidErrorMessage(message string) bool

ValidErrorMessage reports whether message is safe for direct presentation across Action transports and audit records.

func ValidIdentifier

func ValidIdentifier(value string) bool

ValidIdentifier reports whether value is a canonical Action identifier or permission. Dot-separated segments are URL-path safe and deterministic across HTTP, CLI, MCP, generated code, and storage adapters.

func ValidateDecisionFingerprint

func ValidateDecisionFingerprint(value string) error

ValidateDecisionFingerprint validates a required authorization policy fingerprint. Fingerprints are opaque, whitespace-free tokens bounded by the authz contract.

func ValidateDescriptor

func ValidateDescriptor(descriptor Descriptor) error

ValidateDescriptor compiles every schema and validates the static Action contract without creating or invoking a Handler.

func ValidateIdempotencyKey

func ValidateIdempotencyKey(value string) error

ValidateIdempotencyKey validates one non-empty portable Action retry token.

func ValidateJSON

func ValidateJSON(schema, input json.RawMessage) error

ValidateJSON compiles schema and validates one JSON input against it.

func ValidateJSONDocument

func ValidateJSONDocument(document json.RawMessage) error

ValidateJSONDocument checks one Action JSON document for the shared byte, nesting, node, numeric-token, UTF-8, single-value, and duplicate-member contract. Schema conformance is intentionally separate.

func ValidatePlanHash

func ValidatePlanHash(value string) error

ValidatePlanHash validates a canonical Action plan SHA-256 digest.

func ValidateSchema

func ValidateSchema(schema json.RawMessage) error

ValidateSchema reports whether schema is a supported JSON Schema document.

func ValidateSnapshotHash

func ValidateSnapshotHash(value string) error

ValidateSnapshotHash validates an optional optimistic-concurrency snapshot. Non-empty values are canonical lowercase SHA-256 digests.

func WithRequest

func WithRequest(err error, request Request, permission string) error

WithRequest enriches err with request and permission context without mutating an existing Error in its chain.

Types

type AuditLevel

type AuditLevel string

AuditLevel controls how much normalized Action detail an audit event retains.

const (
	// AuditMetadata records bounded decision metadata without impact or result details.
	AuditMetadata AuditLevel = "metadata"
	// AuditDetailed records bounded decision metadata, impact, summary, and references.
	AuditDetailed AuditLevel = "detailed"
)

type CallbackPanicError

type CallbackPanicError struct {
	Operation string
}

CallbackPanicError reports which Action callback panicked without retaining the recovered value. Panic values may contain secrets or implement unsafe formatting methods, so they never cross the Runtime boundary.

func (*CallbackPanicError) Error

func (err *CallbackPanicError) Error() string

Error returns a stable description that never formats the recovered value.

func (*CallbackPanicError) Unwrap

func (err *CallbackPanicError) Unwrap() error

Unwrap identifies the failure as ErrCallbackPanic.

type CatalogEntry

type CatalogEntry struct {
	Descriptor   Descriptor `json:"descriptor"`
	ModuleID     string     `json:"module_id"`
	ContractHash string     `json:"contract_hash"`
}

CatalogEntry is the read-only discovery view of an Action. It intentionally omits the Handler so callers cannot bypass the governed Runtime.

type Channel

type Channel string

Channel identifies an execution surface. The standard framework transports use the constants below; consumers may define additional non-empty channels.

const (
	// ChannelCLI identifies the command-line execution surface.
	ChannelCLI Channel = "cli"
	// ChannelHTTP identifies the HTTP execution surface.
	ChannelHTTP Channel = "http"
	// ChannelMCP identifies the Model Context Protocol execution surface.
	ChannelMCP Channel = "mcp"
)

type Descriptor

type Descriptor struct {
	ID                  string          `json:"id"`
	Version             string          `json:"version"`
	Title               string          `json:"title"`
	Description         string          `json:"description,omitempty"`
	InputSchema         json.RawMessage `json:"input_schema"`
	PreviewSchema       json.RawMessage `json:"preview_schema,omitempty"`
	OutputSchema        json.RawMessage `json:"output_schema"`
	Permission          string          `json:"permission"`
	Preview             PreviewPolicy   `json:"preview"`
	AuditLevel          AuditLevel      `json:"audit_level"`
	Channels            []Channel       `json:"channels,omitempty"`
	Errors              []ErrorSpec     `json:"errors,omitempty"`
	RequiresIdempotency bool            `json:"requires_idempotency"`
}

Descriptor is the complete static governance, schema, and public error contract for an Action. Errors declares only consumer-owned codes; framework codes and their kinds are defined by BuiltinErrorKind.

type Error

type Error struct {
	Code               string           `json:"error_code"`
	Kind               ErrorKind        `json:"error_kind"`
	Message            string           `json:"human_readable_reason"`
	ActionID           string           `json:"action_id,omitempty"`
	RequiredPermission string           `json:"required_permission,omitempty"`
	ActorID            string           `json:"actor_id,omitempty"`
	Scope              *scope.Execution `json:"scope,omitempty"`
	RequestID          string           `json:"request_id,omitempty"`
	Cause              error            `json:"-"`
}

Error is the stable, request-aware error envelope returned by the Action Runtime. Cause participates in errors.Is and errors.As through an opaque boundary that never dispatches caller-defined error methods. It is not serialized.

func NewError

func NewError(code, message string) *Error

NewError constructs an Action error with the supplied stable code and message.

func (*Error) Error

func (e *Error) Error() string

Error returns the stable public code and message without formatting Cause.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap exposes Cause through a safe opaque error-chain boundary.

type ErrorKind

type ErrorKind string

ErrorKind is the transport-independent semantic class of a governed Action error. Transports may map a kind to their native status representation, while the declared error code remains the stable consumer-facing identifier.

const (
	// ErrorKindValidation identifies malformed or semantically invalid caller input.
	ErrorKindValidation ErrorKind = "validation"
	// ErrorKindDenied identifies an authorization denial.
	ErrorKindDenied ErrorKind = "denied"
	// ErrorKindNotFound identifies a requested resource that does not exist.
	ErrorKindNotFound ErrorKind = "not_found"
	// ErrorKindPrecondition identifies a supplied precondition that is not current.
	ErrorKindPrecondition ErrorKind = "precondition"
	// ErrorKindPreconditionRequired identifies a required precondition that is absent.
	ErrorKindPreconditionRequired ErrorKind = "precondition_required"
	// ErrorKindConflict identifies a request that conflicts with current state.
	ErrorKindConflict ErrorKind = "conflict"
	// ErrorKindLimit identifies a request or authorized impact outside a declared limit.
	ErrorKindLimit ErrorKind = "limit"
	// ErrorKindUnavailable identifies a temporarily unavailable governed operation.
	ErrorKindUnavailable ErrorKind = "unavailable"
	// ErrorKindInternal identifies an unexpected framework or consumer failure.
	ErrorKindInternal ErrorKind = "internal"
)

func BuiltinErrorKind

func BuiltinErrorKind(code string) (ErrorKind, bool)

BuiltinErrorKind returns the semantic kind of a framework-owned error code. Descriptor.Errors cannot redeclare these codes.

func ErrorKindOf

func ErrorKindOf(err error) ErrorKind

ErrorKindOf returns the authoritative semantic kind carried by the first Error in the bounded trusted unwrap graph. A missing or invalid kind falls back to the stable built-in code mapping; otherwise it fails closed as ErrorKindInternal.

func (ErrorKind) Valid

func (kind ErrorKind) Valid() bool

Valid reports whether kind is one of the closed ErrorKind values understood by the framework.

type ErrorSpec

type ErrorSpec struct {
	Code string    `json:"code"`
	Kind ErrorKind `json:"kind"`
}

ErrorSpec declares one consumer-owned public error code and its stable semantic kind. Code must contain exactly two uppercase dot-separated segments and must not reuse a framework-owned code.

type Field

type Field struct {
	Schema   Schema
	Required bool
}

Field associates a property Schema with its required-presence flag for Object.

func OptionalField

func OptionalField(schema Schema) Field

OptionalField returns an Object field that may be omitted.

func RequiredField

func RequiredField(schema Schema) Field

RequiredField returns an Object field that must be present.

type Handler

type Handler interface {
	Plan(context.Context, Request) (PlanData, error)
	Execute(context.Context, Plan) (Result, error)
}

Handler supplies Action-specific planning and mutation behavior. The same Handler instance may receive concurrent Plan and Execute calls and must be safe for concurrent use. Implementations must honor context cancellation and deadlines, return promptly after cancellation, and treat Request and Plan values as immutable for the duration of a call.

Runtime calls Execute only after validation and authorization and within its transaction boundary. A Handler may return one *Error, directly or through a bounded trusted standard-library error chain, using an allowed framework business code or a code declared by Descriptor.Errors. A declared denied code is reserved for Authorizer decisions. Invalid envelopes, ordinary errors, and panics are classified as CodeInternal.

type Plan

type Plan struct {
	Hash                string          `json:"plan_hash"`
	ActionID            string          `json:"action_id"`
	ActionVersion       string          `json:"action_version"`
	ContractHash        string          `json:"contract_hash"`
	ActorID             string          `json:"actor_id"`
	ActorType           string          `json:"actor_type"`
	Channel             Channel         `json:"channel"`
	Scope               scope.Execution `json:"scope"`
	InputHash           string          `json:"input_hash"`
	Payload             json.RawMessage `json:"payload"`
	Impact              authz.Impact    `json:"impact"`
	SnapshotHash        string          `json:"snapshot_hash,omitempty"`
	DecisionFingerprint string          `json:"decision_fingerprint"`
	CreatedAt           time.Time       `json:"created_at"`
	ExpiresAt           time.Time       `json:"expires_at"`
}

Plan binds execution to an Action contract, caller identity, scope, input, authorized impact, and expiration. SnapshotHash, when present, is a lowercase SHA-256 digest. DecisionFingerprint is an opaque policy token bounded by authz.MaxFingerprintRunes.

type PlanData

type PlanData struct {
	Payload      json.RawMessage `json:"payload"`
	Summary      json.RawMessage `json:"summary"`
	Impact       authz.Impact    `json:"impact"`
	SnapshotHash string          `json:"snapshot_hash,omitempty"`
}

PlanData is the Handler-produced execution payload, preview summary, impact, and optional optimistic-concurrency snapshot used to create a Plan. SnapshotHash, when present, is a lowercase SHA-256 digest.

type PreparedDescriptor

type PreparedDescriptor struct {
	// contains filtered or unexported fields
}

PreparedDescriptor is an immutable, precompiled Action contract. Its validators are intentionally opaque so a Module Host can validate before startup and later bind a Handler without recompiling schemas.

func PrepareDescriptor

func PrepareDescriptor(descriptor Descriptor) (PreparedDescriptor, error)

PrepareDescriptor validates and compiles an Action contract without creating or invoking a Handler.

func (PreparedDescriptor) ContractHash

func (prepared PreparedDescriptor) ContractHash() string

ContractHash returns the canonical hash of the prepared Action contract.

func (PreparedDescriptor) Descriptor

func (prepared PreparedDescriptor) Descriptor() Descriptor

Descriptor returns a defensive copy of the prepared static contract.

func (PreparedDescriptor) Valid

func (prepared PreparedDescriptor) Valid() bool

Valid reports whether the value is a complete descriptor produced by PrepareDescriptor rather than a zero or partially copied value.

func (PreparedDescriptor) ValidateInput

func (prepared PreparedDescriptor) ValidateInput(value []byte) error

ValidateInput validates one canonical input value against the prepared Action contract without recompiling its schema.

func (PreparedDescriptor) ValidateOutput

func (prepared PreparedDescriptor) ValidateOutput(value []byte) error

ValidateOutput validates one canonical result value against the prepared Action contract without recompiling its schema.

func (PreparedDescriptor) ValidatePreview

func (prepared PreparedDescriptor) ValidatePreview(value []byte) error

ValidatePreview validates one canonical Preview summary against the prepared Action contract without recompiling its schema.

type Preview

type Preview struct {
	PlanHash  string          `json:"plan_hash"`
	Summary   json.RawMessage `json:"summary"`
	Impact    authz.Impact    `json:"impact"`
	ExpiresAt time.Time       `json:"expires_at"`
}

Preview is the caller-visible summary and hash of an authorized execution Plan.

type PreviewPolicy

type PreviewPolicy string

PreviewPolicy controls whether callers may or must provide a Preview plan for execution.

const (
	// PreviewNone disables caller-visible Preview and rejects supplied plan hashes.
	PreviewNone PreviewPolicy = "none"
	// PreviewOptional permits execution with either a prior Preview plan or internal planning.
	PreviewOptional PreviewPolicy = "optional"
	// PreviewRequired requires execution to bind to a prior Preview plan.
	PreviewRequired PreviewPolicy = "required"
)

type Request

type Request struct {
	RequestID      string          `json:"request_id"`
	Actor          identity.Actor  `json:"actor"`
	Channel        Channel         `json:"channel"`
	ActionID       string          `json:"action_id"`
	Scope          scope.Execution `json:"scope"`
	Input          json.RawMessage `json:"input"`
	IdempotencyKey string          `json:"idempotency_key,omitempty"`
	PlanHash       string          `json:"plan_hash,omitempty"`
}

Request is the channel-independent execution envelope submitted to a Runtime.

type Result

type Result struct {
	Data       json.RawMessage   `json:"data"`
	Summary    string            `json:"summary,omitempty"`
	References []audit.Reference `json:"references,omitempty"`
}

Result is the validated Action output together with bounded audit-facing metadata.

type Runtime

type Runtime interface {
	Preview(context.Context, Request) (Preview, error)
	Execute(context.Context, Request) (Result, error)
	CleanupExpiredPlans(context.Context) (int64, error)
}

Runtime is the governed execution surface for registered Actions. It never exposes the mutable binding table or raw Handlers owned by framework assembly. Runtime methods are safe for concurrent use. Callers control each supplied context independently, and trusted dependencies must return promptly after its cancellation.

type RuntimePolicy

type RuntimePolicy struct {
	// Clock may be called concurrently by Runtime methods. It must be safe for
	// concurrent use and return promptly.
	Clock   func() time.Time
	PlanTTL time.Duration
	// AuditTimeout bounds detached Audit persistence and each AuditFailure
	// notification independently.
	AuditTimeout time.Duration
	// AuditFailure reports an Audit persistence failure without replacing the
	// primary Runtime result. It may be called concurrently. The callback must be
	// safe for concurrent use, honor the supplied context, and return promptly
	// after cancellation. The Event is a defensive copy.
	AuditFailure func(context.Context, error, audit.Event)
}

RuntimePolicy controls timing and audit-reporting policy without accepting governance services. Framework assembly resolves those services from the canonical Module Host capabilities.

type Schema

type Schema struct {
	// contains filtered or unexported fields
}

Schema is an immutable JSON Schema node assembled through typed builders. JSON adds the Draft 7 declaration when the node becomes a public root schema.

func AnyObject

func AnyObject(options ...SchemaOption) Schema

AnyObject builds an object Schema that accepts arbitrary properties.

func Array

func Array(items Schema, options ...SchemaOption) Schema

Array builds an array Schema whose elements must satisfy items.

func Boolean

func Boolean(options ...SchemaOption) Schema

Boolean builds a boolean Schema with the supplied compatible options.

func ConstString

func ConstString(value string, options ...SchemaOption) Schema

ConstString builds a string Schema restricted to value.

func Integer

func Integer(options ...SchemaOption) Schema

Integer builds an integer Schema with the supplied compatible options.

func Number

func Number(options ...SchemaOption) Schema

Number builds a numeric Schema with the supplied compatible options.

func Object

func Object(fields map[string]Field, options ...SchemaOption) Schema

Object builds a closed object Schema from named fields. Properties not listed in fields are rejected.

func OneOf

func OneOf(schemas ...Schema) Schema

OneOf builds a Schema that requires exactly one supplied Schema to match.

func ParseSchema

func ParseSchema(data json.RawMessage) (Schema, error)

ParseSchema parses and validates one Draft 7 JSON Schema into an immutable Schema.

func String

func String(options ...SchemaOption) Schema

String builds a string Schema with the supplied compatible options.

func StringEnum

func StringEnum(values ...string) Schema

StringEnum builds a string Schema restricted to the supplied values.

func (Schema) JSON

func (schema Schema) JSON() json.RawMessage

JSON returns the immutable Schema as a Draft 7 JSON document.

func (Schema) With

func (schema Schema) With(options ...SchemaOption) Schema

With returns a new Schema with compatible options applied.

type SchemaOption

type SchemaOption struct {
	// contains filtered or unexported fields
}

SchemaOption is a sealed mutation applied while a Schema is being built. Callers use the typed option constructors below; the internal map never escapes a builder.

func Description

func Description(value string) SchemaOption

Description adds human-readable description metadata to a Schema.

func Format

func Format(value string) SchemaOption

Format sets the JSON Schema format annotation for a string Schema.

func MaxItems

func MaxItems(value int) SchemaOption

MaxItems sets the maximum number of elements accepted by an array Schema.

func MaxLength

func MaxLength(value int) SchemaOption

MaxLength sets the maximum string length.

func Maximum

func Maximum(value int) SchemaOption

Maximum sets the inclusive upper bound for an integer or number Schema.

func MinLength

func MinLength(value int) SchemaOption

MinLength sets the minimum string length.

func Minimum

func Minimum(value int) SchemaOption

Minimum sets the inclusive lower bound for an integer or number Schema.

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator is an immutable, concurrency-safe compiled JSON Schema.

func CompileValidator

func CompileValidator(schema json.RawMessage) (*Validator, error)

CompileValidator validates schema and returns a reusable concurrency-safe Validator.

func (*Validator) Validate

func (validator *Validator) Validate(input json.RawMessage) error

Validate checks one complete JSON value against the compiled Schema.

Jump to

Keyboard shortcuts

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