axiom

package module
v0.0.0-...-83ab7ba Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

README

Axiom

Русский · English

CI Go License

Axiom — Go-библиотека для проверяемых переходов состояния, бизнес-процессов и таблиц решений.

Она нужна там, где недостаточно просто изменить struct в памяти: переход должен иметь явные правила, пройти инварианты, записаться в историю, безопасно вызвать внешний эффект и оставаться объяснимым после выполнения.

Для нового Go-проекта рекомендуемый frontend — пакет model.

Модель за 30 секунд

Основной declarative lifecycle один и тот же независимо от того, где описан процесс:

Go model / AXM / TOML
         ↓
      axiom.Plan
         ↓
       Engine
         ↓
Run = engine.Execution(id)
  • Definition описывает состояние, события, rules, claims, activities и policies.
  • Plan — canonical compiled representation.
  • Engine объединяет Plan, store, activity implementations и runtime options.
  • Run — основной handle одного durable execution: Dispatch, State, Status, History, Explain, Cancel.

axiom.Flow существует отдельно как компактный typed reducer API для сценариев, которым не нужен статический граф модели.

Когда Axiom подходит

Хорошие кандидаты: заказы, заявки, оборудование, технологические циклы, партии продукции, платежи, approval flows и другие объекты с собственным lifecycle.

Axiom особенно полезен, если нужны одновременно:

  • явные допустимые переходы;
  • инварианты (claim), которые нельзя нарушить;
  • воспроизводимая history/replay модель;
  • внешние activities с retry/timeout/idempotency;
  • объяснение текущего состояния и выполненных решений;
  • один runtime для Go model, AXM и TOML definitions.

Axiom не является брокером сообщений, распределённым scheduler, distributed lock manager или заменой простого CRUD.

Какой API выбрать

Frontend Пакет Выбирать когда Static analysis
Declarative Go github.com/Homiakus/axiom/model по умолчанию для нового Go-кода Да
Typed Go Flow github.com/Homiakus/axiom маленький reducer, важнее произвольный Go Нет (opaque)
AXM github.com/Homiakus/axiom/axm definition должна жить вне Go Да
TOML table github.com/Homiakus/axiom/table задача естественно является decision table Да

Подробный decision guide: docs/api-guide.md.

Требования и установка

  • Go 1.26+.
  • Для in-memory режима не нужны внешние сервисы.
  • Для durable storage есть встроенная интеграция с CockroachDB Pebble.
go get github.com/Homiakus/axiom

До первого стабильного v1 действует pre-v1 compatibility policy: docs/versioning.md.

Быстрый старт

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/Homiakus/axiom"
    "github.com/Homiakus/axiom/model"
)

type Counter struct {
    Value int `json:"value"`
}

type SetValue struct {
    Value int `json:"value"`
}

func main() {
    definition := model.New("Counter")
    current := model.Bind[Counter](definition, "Current")
    setValue := model.EventOf[SetValue](definition)

    definition.Rule("set").
        On(setValue.Trigger()).
        Set(current.Int("Value"), setValue.Int("Value"))

    definition.Claim(
        "nonNegative",
        current.Int("Value").GreaterOrEqual(0),
    )

    engine, err := axiom.Open(definition)
    if err != nil {
        log.Fatal(err)
    }

    run := engine.Execution("counter-1")
    ctx := context.Background()

    if err := run.Dispatch(ctx, SetValue{Value: 7}); err != nil {
        log.Fatal(err)
    }

    var state Counter
    if err := run.State(ctx, &state); err != nil {
        log.Fatal(err)
    }

    fmt.Println(state.Value) // 7
}

axiom.Open(definition) компилирует model.Definition в Plan и создаёт Engine. Dispatch создаёт execution при первом обращении, применяет событие и drain'ит доступные inline activities до idle или до durable retry boundary.

Большие модели: меньше строковых имён

Короткие helpers вроде order.Int("Total") удобны в маленькой модели. Когда одно поле используется десятки раз, строка начинает размножаться по rules/claims/activities и хуже переживает рефакторинг.

Для этого есть reusable typed field keys:

type Order struct {
    Status string `json:"status"`
    Total  int    `json:"total"`
}

var (
    orderStatus = model.Key[Order, string]("Status")
    orderTotal  = model.Key[Order, int]("Total")
)

definition := model.New("Orders")
order := model.Bind[Order](definition, "Order")

status := model.StateField(order, orderStatus)
total := model.StateField(order, orderTotal)

model.StateDefault(order, orderStatus, "new")
definition.Claim("totalNonNegative", total.GreaterOrEqual(0))

FieldKey[Owner, Value] локализует имя поля в одном месте. Owner type не позволяет применить ключ к чужому state/event type, а Value type сверяется с реальным Go field при использовании. Для optional pointer fields можно использовать pointed-to logical type.

Для событий используется model.EventField, для changed(...) trigger — model.StateChanged.

Это не code generation: имена по-прежнему связываются через reflection и axiom/json tags, но typo surface и повторение строк заметно уменьшаются.

Typed expressions

TypedField[T] сохраняет compatibility operators (EQ, GT, Add и др.), но новый код лучше писать через строгие helpers:

total.GreaterOrEqual(0)
status.Equal("paid")
left.EqualField(right)
subtotal.PlusField(tax)

Literal helpers принимают тот же T, а field-to-field helpers требуют одинаковый TypedField[T]. Поэтому часть ошибок ловится компилятором Go ещё до compilation модели.

Activities

Для application code предпочитайте ActTyped:

type ChargeInput struct {
    OrderID string `json:"orderId"`
    Amount  int    `json:"amount"`
}

type ChargeOutput struct {
    PaymentID string `json:"paymentId"`
}

engine, err := axiom.Open(
    definition,
    axiom.ActTyped("Charge", func(
        ctx context.Context,
        input ChargeInput,
    ) (ChargeOutput, error) {
        return ChargeOutput{PaymentID: "pay-1"}, nil
    }),
)

Input/output ActTyped должны быть struct, pointer-to-struct или map со string keys. Unsupported shape и nil handler отклоняются при создании Engine (AX507), а не превращаются в позднюю ошибку activity.

axiom.Act с axiom.Input / axiom.Output оставлен для dynamic integration boundaries, где map[string]any уже является естественным контрактом.

Durable storage и production mode

По умолчанию используется memory store. Для Pebble:

store, err := axiom.OpenPebble("data/axiom")
if err != nil {
    return err
}
defer store.Close()

engine, err := axiom.Open(
    definition,
    axiom.WithStore(store),
    axiom.WithProductionMode(),
)

WithProductionMode() требует TransactionalStore и включает strict fast runtime.

Текущие activity guarantees:

  • retry сохраняет Attempt, MaxAttempts и NextAttemptAt в store и может продолжиться новым Engine после process restart при durable store;
  • timeout применяется к каждой попытке отдельно;
  • parallel не добавляет сериализацию;
  • once сериализует activity внутри одного Engine;
  • first оставляет первый active task в lane execution + activity;
  • latest заменяет более старые pending tasks, но не пытается небезопасно force-cancel уже running Go handler;
  • external activity всё равно должна быть идемпотентной: durable retry даёт at-least-once execution, а не exactly-once внешний эффект.

Детальный контракт: docs/runtime-semantics.md.

Runtime API

Для одного execution используйте Run:

run := engine.Execution("order-42")

if err := run.Dispatch(ctx, Submitted{Total: 1500}); err != nil {
    return err
}

var state Order
if err := run.State(ctx, &state); err != nil {
    return err
}

status, err := run.Status(ctx)
history, err := run.History(ctx)
explanation, err := run.Explain(ctx)

Также доступны Signal, Patch, PendingActivities и Cancel. Низкоуровневые Engine methods, где execution ID приходится передавать каждый раз, в основном нужны integration/tooling слоям.

Примеры

Каталог examples/ теперь является runnable learning path:

Пример Команда Назначение
model go run ./examples/model рекомендуемый declarative Go API
go-first go run ./examples/go-first typed reducer Flow
order go run ./examples/order Pebble + production activity semantics
axiom-files go run ./examples/axiom-files AXM file frontend
table go run ./examples/table TOML decision table frontend
triz go run ./examples/triz normalization + diagnostics + source map
coffee-machine go run ./examples/coffee-machine большой end-to-end reference

Подробности: examples/README.md.

Code generation

axiomgen генерирует typed activity boundary из AXM/TOML:

go run ./cmd/axiomgen \
  --file examples/axiom-files/welcome.axm \
  --out ./generated \
  --package generated

Подробнее: docs/axiomgen.md.

Проверка проекта

go mod tidy
git diff --exit-code -- go.mod go.sum
go test ./...
go test -race . ./internal/runtime/... ./internal/store/...
go vet ./...
go run ./examples/coffee-machine

CI дополнительно выполняет vulnerability scan, fuzz smoke tests, внешний consumer module и performance job. Это важно для библиотеки: публичный API проверяется не только внутренними тестами, но и из отдельного downstream Go module.

Benchmark runner и актуальный baseline: benchmarks/latest.md.

Границы гарантий

  1. Lock одного execution ID действует внутри одного Engine, а не является distributed ownership protocol.
  2. once также локален одному Engine; first/latest атомарны в пределах гарантий выбранного TransactionalStore.
  3. latest означает latest pending wins, а не force-cancel произвольного running Go handler.
  4. Durable retry не делает внешний side effect exactly-once — idempotency остаётся обязанностью integration boundary.
  5. Flow выполняет effects до FlowStore.Save; effect handlers должны быть идемпотентными.
  6. Memory store подходит для разработки/тестов и не переживает restart процесса.

Документация

License

Apache-2.0. См. LICENSE.

Documentation

Overview

Package axiom is the public API for loading .axm modules, wiring Go activities, and running Axiom executions.

Quick Start

// One-liner for simple cases:
engine, err := axiom.CompileAndNew(source, axiom.Act("SendEmail", sendEmail))

// From file with full control:
app, err := axiom.Load("module.axm")
engine := app.MustNew(
    axiom.Act("SendEmail", sendEmail),
    axiom.WithProductionMode(),
)
engine.Start(ctx, "exec-1", nil)

Stores

Memory store is the default (no option needed). For durability use Pebble:

store, err := axiom.OpenPebble("data/axiom")
engine := app.MustNew(axiom.WithStore(store))

Activity Registration

Use ActTyped for application code when inputs and outputs have stable Go shapes. Use Act/Acts for dynamic integration boundaries that naturally use map payloads. The engine validates that every .axm activity with effect!=none has a Go handler.

Index

Constants

View Source
const (
	StatusStarted   = runtimepkg.StatusStarted
	StatusRunning   = runtimepkg.StatusRunning
	StatusWaiting   = runtimepkg.StatusWaiting
	StatusCompleted = runtimepkg.StatusCompleted
	StatusFailed    = runtimepkg.StatusFailed
	StatusCanceled  = runtimepkg.StatusCanceled

	TaskPending    = runtimepkg.TaskPending
	TaskRunning    = runtimepkg.TaskRunning
	TaskCompleted  = runtimepkg.TaskCompleted
	TaskFailed     = runtimepkg.TaskFailed
	TaskSuperseded = runtimepkg.TaskSuperseded
)
View Source
const DSLVersion = "axm/v1"

Variables

View Source
var ErrRetryScheduled = runtimepkg.ErrRetryScheduled

ErrRetryScheduled can be matched with errors.Is when low-level callers need to distinguish deferred retry work from terminal activity failure.

View Source
var PebbleGobCodec = pebblestore.WithGobCodec

PebbleGobCodec uses Gob encoding (opt-in alternative codec).

View Source
var PebbleJSONCodec = pebblestore.WithJSONCodec

PebbleJSONCodec uses JSON for encoding records (default).

View Source
var PebbleNoSync = pebblestore.WithNoSync

PebbleNoSync disables WAL sync (fast, less durable).

View Source
var PebbleSyncEvery = pebblestore.WithSyncEvery

PebbleSyncEvery batches syncs at the given interval.

Functions

func AddClaim

func AddClaim[S any](flow *Flow[S], claim func(S) error)

func EffectHandler

func EffectHandler[S, C any](flow *Flow[S], handler func(context.Context, C) error)

func FlowEffectIDFromContext

func FlowEffectIDFromContext(ctx context.Context) (string, bool)

FlowEffectIDFromContext returns the stable idempotency key of a durable Flow effect delivery. It is present while an EffectHandler is invoked by a Flow opened with WithDurableFlowEffects.

func Handle

func Handle[S, E any](flow *Flow[S], handler func(context.Context, S, E) (FlowResult[S], error))

func RuntimeQueryProjectionNames

func RuntimeQueryProjectionNames() []string

RuntimeQueryProjectionNames returns the stable runtime.* query namespace.

func ValidateRuntimeQueryProjections

func ValidateRuntimeQueryProjections(module *Module) error

ValidateRuntimeQueryProjections rejects misspelled or unsupported runtime.* fields before a Plan is exposed to the runtime. The compiler already limits runtime.* references to query scope; this validation narrows that namespace to the stable execution metadata contract.

Types

type Activity

type Activity func(ctx context.Context, input Input) (Output, error)

Activity is a Go function that implements a .axm activity block. ctx is canceled when the execution is canceled or times out.

type ActivityID

type ActivityID = runtimepkg.ActivityID

type ActivityRegistry

type ActivityRegistry map[string]Activity

ActivityRegistry maps .axm activity names to their Go implementations.

type ActivityTask

type ActivityTask = runtimepkg.ActivityTask

type AnalysisLevel

type AnalysisLevel string

AnalysisLevel describes how much static analysis a Plan supports.

const (
	AnalysisOpaque AnalysisLevel = "opaque"
	AnalysisStatic AnalysisLevel = "static"
)

type App

type App struct {
	Path   string
	Module *Module
}

App holds a parsed and compiled .axm module, ready to create engines.

func Load

func Load(path string) (*App, error)

Load reads a .axm file from disk, compiles it, and returns an App.

app, err := axiom.Load("module.axm")
engine := app.MustNew(axiom.Act("MyActivity", myFunc))

func MustLoad

func MustLoad(path string) *App

MustLoad is like Load but panics on error. Use in tests and init scripts.

func (*App) MustNew

func (a *App) MustNew(opts ...Option) *Engine

MustNew builds an Engine from this App, panicking on error.

func (*App) New

func (a *App) New(opts ...Option) (*Engine, error)

New builds an Engine from this App.

type AtomID

type AtomID = runtimepkg.AtomID

type BundleDiff

type BundleDiff struct {
	AddedActivities   []string
	RemovedActivities []string
	AddedFields       []string
	RemovedFields     []string
	AddedRules        []string
	RemovedRules      []string
	AddedClaims       []string
	RemovedClaims     []string
}

type Clock

type Clock interface {
	Now() time.Time
}

Clock is the minimal semantic time source required for deterministic testing and simulation.

type CompileOption

type CompileOption func(*compileConfig)

CompileOption configures the compiler.

func WithSourceName

func WithSourceName(name string) CompileOption

WithSourceName sets the filename used in error messages.

type Diagnostic

type Diagnostic = compiler.Diagnostic

type Diagnostics

type Diagnostics = compiler.Diagnostics

type DurabilityProvider

type DurabilityProvider = runtimepkg.DurabilityProvider

DurabilityProvider is implemented by stores that declare their persistence semantics. Custom production stores should implement this in addition to TransactionalStore.

type DurableFlowStore

type DurableFlowStore interface {
	FlowStore
	IncrementalFlowStore
	DurabilityProvider
	AtomicFlowCommit()
}

DurableFlowStore is the storage capability required by WithDurableFlowEffects. SaveStateAndAppend must atomically commit the state bytes and every supplied history entry as one durable unit.

type Effect

type Effect struct{ Command any }

Effect is an opaque command emitted by a Go-first reducer.

func Call

func Call(command any) Effect

type Engine

type Engine = runtimepkg.Engine

func CompileAndNew

func CompileAndNew(source []byte, opts ...Option) (*Engine, error)

CompileAndNew compiles source and builds an Engine in one call. Memory store is used by default. Use WithStore for Pebble.

engine, err := axiom.CompileAndNew(source, axiom.Act("MyActivity", myFunc))

func MustCompileAndNew

func MustCompileAndNew(source []byte, opts ...Option) *Engine

MustCompileAndNew is like CompileAndNew but panics on error.

func MustNew

func MustNew(module *Module, opts ...Option) *Engine

MustNew is like New but panics on error.

func New

func New(module *Module, opts ...Option) (*Engine, error)

New builds an Engine from a compiled Module.

Memory store is used by default. Pass WithStore for Pebble durability. Every .axm activity with effect != "none" must have a Go handler registered via Act/Acts/WithActivity.

engine, err := axiom.New(module,
    axiom.Act("SendEmail", sendEmail),
    axiom.WithTraceLevel(axiom.TraceFull),
)

func NewEngine deprecated

func NewEngine(module *Module, store Store, activities ActivityRegistry) *Engine

NewEngine is a compatibility wrapper. Use New with options.

Deprecated: Use New(module, WithStore(store), WithActivities(activities)).

func Open

func Open(source PlanSource, opts ...Option) (*Engine, error)

Open compiles a source and creates an Engine in one operation.

type Error

type Error = diag.Error

type Errors

type Errors = diag.Errors

type EventNamer

type EventNamer = runtimepkg.EventNamer

type Execution

type Execution = runtimepkg.Execution

func ReplayFromHistory

func ReplayFromHistory(module *Module, history []HistoryEntry) (*Execution, error)

ReplayFromHistory reconstructs an Execution state from its history entries.

type ExecutionState

type ExecutionState = runtimepkg.ExecutionState

type Explanation

type Explanation = runtimepkg.Explanation

type FactValue

type FactValue = runtimepkg.FactValue

type FieldID

type FieldID = runtimepkg.FieldID

type Flow

type Flow[S any] struct {
	// contains filtered or unexported fields
}

Flow is the file-free typed reducer frontend. Its analysis level is opaque because arbitrary Go handlers cannot be statically inspected.

func NewFlow

func NewFlow[S any](name string, initial S) *Flow[S]

func (*Flow[S]) Analysis

func (f *Flow[S]) Analysis() AnalysisLevel

func (*Flow[S]) Name

func (f *Flow[S]) Name() string

type FlowEffectAcknowledgeError

type FlowEffectAcknowledgeError struct {
	EffectID string
	Name     string
	Err      error
}

FlowEffectAcknowledgeError means the effect handler returned success but its durable completion marker could not be committed. The effect may be delivered again; handlers should deduplicate using FlowEffectIDFromContext.

func (*FlowEffectAcknowledgeError) Error

func (*FlowEffectAcknowledgeError) StateCommitted

func (e *FlowEffectAcknowledgeError) StateCommitted() bool

func (*FlowEffectAcknowledgeError) Unwrap

func (e *FlowEffectAcknowledgeError) Unwrap() error

type FlowEffectCompletion

type FlowEffectCompletion struct {
	ID string `json:"id"`
}

FlowEffectCompletion records the durable acknowledgement for an outbox item.

type FlowEffectDeliveryError

type FlowEffectDeliveryError struct {
	EffectID string
	Name     string
	Err      error
}

FlowEffectDeliveryError means reducer state and the effect intent are already committed, but the external handler failed. Retrying the business event would apply the reducer again; call DrainEffects to retry only the pending effect.

func (*FlowEffectDeliveryError) Error

func (e *FlowEffectDeliveryError) Error() string

func (*FlowEffectDeliveryError) StateCommitted

func (e *FlowEffectDeliveryError) StateCommitted() bool

func (*FlowEffectDeliveryError) Unwrap

func (e *FlowEffectDeliveryError) Unwrap() error

type FlowEffectIntent

type FlowEffectIntent struct {
	ID      string          `json:"id"`
	Name    string          `json:"name"`
	Payload json.RawMessage `json:"payload"`
}

FlowEffectIntent is the durable outbox representation of an emitted effect. ID is deterministic for a flow execution, handled-event sequence, and effect position. Payload contains the canonical JSON command to deliver.

type FlowEngine

type FlowEngine[S any] struct {
	// contains filtered or unexported fields
}

func OpenFlow

func OpenFlow[S any](flow *Flow[S], opts ...FlowOption) (*FlowEngine[S], error)

func (*FlowEngine[S]) Execution

func (e *FlowEngine[S]) Execution(id string) *FlowExecution[S]

type FlowExecution

type FlowExecution[S any] struct {
	// contains filtered or unexported fields
}

func (*FlowExecution[S]) Dispatch

func (e *FlowExecution[S]) Dispatch(ctx context.Context, event any) error

func (*FlowExecution[S]) DrainEffects

func (e *FlowExecution[S]) DrainEffects(ctx context.Context) error

DrainEffects retries durable outbox items that have no EffectCompleted acknowledgement. Delivery is at-least-once; use FlowEffectIDFromContext as the downstream idempotency key when exactly-once business effects matter.

func (*FlowExecution[S]) History

func (e *FlowExecution[S]) History(ctx context.Context) ([]FlowHistoryEntry, error)

func (*FlowExecution[S]) State

func (e *FlowExecution[S]) State(ctx context.Context) (S, error)

type FlowHistoryEntry

type FlowHistoryEntry struct {
	Sequence  int
	Type      string
	Name      string
	Data      any
	CreatedAt time.Time
}

type FlowOption

type FlowOption func(*flowConfig) error

func WithDurableFlowEffects

func WithDurableFlowEffects() FlowOption

WithDurableFlowEffects enables a transactional outbox for reducer effects. The configured store must implement DurableFlowStore and report synchronous durability. External effect delivery then happens only after state and EffectPending intents are committed. Delivery is at-least-once; use FlowEffectIDFromContext for downstream deduplication.

func WithFlowStore

func WithFlowStore(store FlowStore) FlowOption

type FlowResult

type FlowResult[S any] struct {
	State   S
	Effects []Effect
}

func Next

func Next[S any](state S, effects ...Effect) FlowResult[S]

type FlowStore

type FlowStore interface {
	Load(ctx context.Context, flow, id string) (state []byte, history []FlowHistoryEntry, found bool, err error)
	Save(ctx context.Context, flow, id string, state []byte, history []FlowHistoryEntry) error
}

FlowStore is the compatibility storage contract for typed Go flows. Stores that also implement IncrementalFlowStore avoid loading and rewriting the complete history on every dispatch.

type HistoryEntry

type HistoryEntry = runtimepkg.HistoryEntry

type ImpactReport

type ImpactReport struct {
	Fields     []string
	Rules      []string
	Activities []string
	Claims     []string
	Queries    []string
}

type IncrementalFlowStore

type IncrementalFlowStore interface {
	LoadState(ctx context.Context, flow, id string) (state []byte, historyLength int, found bool, err error)
	SaveStateAndAppend(ctx context.Context, flow, id string, state []byte, entries []FlowHistoryEntry) error
	LoadHistory(ctx context.Context, flow, id string) ([]FlowHistoryEntry, error)
}

IncrementalFlowStore is an optional capability for append-only history. It preserves FlowStore compatibility while reducing a long-lived execution from quadratic history copying to constant work per newly appended entry.

type Input

type Input = map[string]any

Input is the payload passed into a signal or an activity.

type MemoryFlowStore

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

func NewMemoryFlowStore

func NewMemoryFlowStore() *MemoryFlowStore

func (*MemoryFlowStore) Durability

func (*MemoryFlowStore) Durability() StoreDurability

Durability reports that the built-in Flow store is process-local. It is intentionally not a DurableFlowStore because it cannot survive a crash.

func (*MemoryFlowStore) Load

func (s *MemoryFlowStore) Load(ctx context.Context, flow, id string) ([]byte, []FlowHistoryEntry, bool, error)

func (*MemoryFlowStore) LoadHistory

func (s *MemoryFlowStore) LoadHistory(ctx context.Context, flow, id string) ([]FlowHistoryEntry, error)

func (*MemoryFlowStore) LoadState

func (s *MemoryFlowStore) LoadState(ctx context.Context, flow, id string) ([]byte, int, bool, error)

func (*MemoryFlowStore) Save

func (s *MemoryFlowStore) Save(ctx context.Context, flow, id string, state []byte, history []FlowHistoryEntry) error

func (*MemoryFlowStore) SaveStateAndAppend

func (s *MemoryFlowStore) SaveStateAndAppend(ctx context.Context, flow, id string, state []byte, entries []FlowHistoryEntry) error

type Module

type Module = compiler.Module

func Compile

func Compile(source []byte, opts ...CompileOption) (*Module, error)

Compile parses and compiles raw .axm source into a compiled Module. Use WithSourceName to set the source name for error messages.

func CompileAny

func CompileAny(source []byte, opts ...CompileOption) (*Module, error)

CompileAny compiles either the stable Axiom v0 syntax (`domain ...`) or the user-facing TRIZ syntax (`system ...`). Existing Compile remains v0-only for compatibility with older callers.

func LoadModule deprecated

func LoadModule(source []byte) (*Module, error)

LoadModule is a compatibility wrapper. Use Compile instead.

Deprecated: Use Compile(source).

func MustCompile

func MustCompile(source []byte, opts ...CompileOption) *Module

MustCompile is like Compile but panics on error.

type ModuleBundle

type ModuleBundle struct {
	Module        *Module
	SourceHash    string
	CompiledHash  string
	DSLVersion    string
	Activities    []string
	ContextFields []string
	Rules         []string
	Claims        []string
}

func CompileBundle

func CompileBundle(source []byte, opts ...CompileOption) (*ModuleBundle, error)

func (*ModuleBundle) Diff

func (b *ModuleBundle) Diff(other *ModuleBundle) BundleDiff

func (*ModuleBundle) Impact

func (b *ModuleBundle) Impact(changeSet []string) ImpactReport

func (*ModuleBundle) ValidateCompatibility

func (b *ModuleBundle) ValidateCompatibility(previous *ModuleBundle) error

type Option

type Option func(*engineConfig) error

Option configures an Engine before it is built. Options are validated at Build/New time (fail-fast).

func Act

func Act(name string, fn Activity) Option

Act registers a single activity. Shorthand for WithActivity.

axiom.Act("SendWelcomeEmail", func(ctx context.Context, in axiom.Input) (axiom.Output, error) {
    return axiom.Output{"sent": true}, nil
})

func ActTyped

func ActTyped[In any, Out any](name string, fn func(ctx context.Context, input In) (Out, error)) Option

ActTyped registers an activity with typed Go inputs and outputs. Input and output types must be structs (or pointers to structs) or maps with string keys. Unsupported shapes fail during Engine construction instead of producing a late decode error or a silently empty output.

axiom.ActTyped("SendWelcomeEmail", func(ctx context.Context, in WelcomeInput) (WelcomeOutput, error) {
    return WelcomeOutput{Sent: true}, nil
})

func Acts

func Acts(registry ActivityRegistry) Option

Acts registers multiple activities from a registry.

engine := app.MustNew(axiom.Acts(axiom.ActivityRegistry{
    "CheckInventory": checkInventory,
    "ChargeCard":     chargeCard,
}))

func Register deprecated

func Register(name string, fn Activity) Option

Register is a deprecated alias for WithActivity. Use Act.

Deprecated: Use Act(name, fn) instead.

func WithActivities

func WithActivities(registry ActivityRegistry) Option

WithActivities registers multiple activities (alias for Acts).

func WithActivity

func WithActivity(name string, fn Activity) Option

WithActivity registers a single activity (alias for Act).

func WithClock

func WithClock(clock Clock) Option

WithClock sets a custom semantic Clock for deterministic time and timers.

func WithProductionMode

func WithProductionMode() Option

WithProductionMode enables production safeguards:

  • Strict fast runtime (no slow-path fallback)
  • Transactional store required for atomic checkpoints and task decisions
  • Synchronous durability declaration required for acknowledged commits
  • durable retry/backoff and per-attempt timeout
  • concurrency: once is serialized per activity within an Engine
  • concurrency: parallel remains unrestricted
  • concurrency: first/latest use transactional pending-task supersession

func WithStore

func WithStore(store Store) Option

WithStore sets an explicit store. Use this when you need Pebble durability or a custom Store implementation. For simple cases the default memory store is used automatically.

func WithStrictFastRuntime

func WithStrictFastRuntime() Option

WithStrictFastRuntime enables strict mode: refuses to fall back to the slow path. Use in tests to catch unsupported .axm patterns early.

func WithTraceLevel

func WithTraceLevel(level TraceLevel) Option

WithTraceLevel controls how much execution detail is recorded in history.

  • TraceMinimal: only errors and lifecycle events
  • TraceAggregate: summary of rule evaluation per turn (default)
  • TraceFull: every rule attempt, every activity scheduling

type Output

type Output = map[string]any

Output is the result returned by an activity.

type Patch

type Patch = map[string]any

Patch is a set of context field changes.

type PebbleFlowStore

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

PebbleFlowStore is the built-in crash-durable store for typed Flow state, append-only history, and durable effect outbox intents. Each SaveStateAndAppend call is committed as one synchronously flushed Pebble batch, satisfying DurableFlowStore.

func OpenPebbleFlowStore

func OpenPebbleFlowStore(path string) (*PebbleFlowStore, error)

OpenPebbleFlowStore opens a dedicated Pebble database for typed Flow state. Do not open the same directory concurrently through another Pebble handle.

func (*PebbleFlowStore) AtomicFlowCommit

func (*PebbleFlowStore) AtomicFlowCommit()

func (*PebbleFlowStore) Close

func (s *PebbleFlowStore) Close() error

func (*PebbleFlowStore) Durability

func (*PebbleFlowStore) Durability() StoreDurability

func (*PebbleFlowStore) Load

func (s *PebbleFlowStore) Load(ctx context.Context, flow, id string) ([]byte, []FlowHistoryEntry, bool, error)

func (*PebbleFlowStore) LoadHistory

func (s *PebbleFlowStore) LoadHistory(ctx context.Context, flow, id string) ([]FlowHistoryEntry, error)

func (*PebbleFlowStore) LoadState

func (s *PebbleFlowStore) LoadState(ctx context.Context, flow, id string) ([]byte, int, bool, error)

func (*PebbleFlowStore) Save

func (s *PebbleFlowStore) Save(ctx context.Context, flow, id string, state []byte, history []FlowHistoryEntry) error

func (*PebbleFlowStore) SaveStateAndAppend

func (s *PebbleFlowStore) SaveStateAndAppend(ctx context.Context, flow, id string, state []byte, entries []FlowHistoryEntry) error

type PebbleOption

type PebbleOption = pebblestore.Option

PebbleOption configures a Pebble store.

type PebbleStore

type PebbleStore = pebblestore.Store

PebbleStore is a durable on-disk Store backed by CockroachDB Pebble.

func OpenPebble

func OpenPebble(path string, opts ...PebbleOption) (*PebbleStore, error)

OpenPebble opens a Pebble-backed durable store using JSON encoding by default. The store's schema version and selected codec are persisted in metadata. Reopening an existing store with a conflicting codec or an unsupported schema version fails fast with an error. Legacy unmarked stores are automatically detected and adopted on open. See docs/runtime-semantics.md for full details.

store, err := axiom.OpenPebble("data/axiom", axiom.PebbleNoSync())
engine := app.MustNew(axiom.WithStore(store))

type Plan

type Plan struct {
	Name     string
	Version  string
	Digest   string
	Format   string
	Analysis AnalysisLevel
	// contains filtered or unexported fields
}

Plan is the canonical executable representation consumed by Axiom. Frontends such as Go builders, AXM and TOML all compile into this type.

func CompilePlan

func CompilePlan(source []byte, opts ...CompileOption) (*Plan, error)

CompilePlan compiles AXM or TRIZ source into a canonical Plan.

func NewPlan

func NewPlan(module *Module, format, version string, analysis AnalysisLevel) (*Plan, error)

NewPlan wraps a validated compiled module as a canonical Plan.

func (*Plan) CompilePlan

func (p *Plan) CompilePlan() (*Plan, error)

CompilePlan lets a Plan satisfy PlanSource.

func (*Plan) Module

func (p *Plan) Module() *Module

Module returns the validated runtime module backing the Plan.

func (*Plan) New

func (p *Plan) New(opts ...Option) (*Engine, error)

New creates an Engine from the Plan.

type PlanSource

type PlanSource interface {
	CompilePlan() (*Plan, error)
}

PlanSource is implemented by AXM, TOML and Go model frontends.

type RetryScheduledError

type RetryScheduledError = runtimepkg.RetryScheduledError

RetryScheduledError describes a durable activity retry checkpoint returned by the low-level Engine.RunUntilIdle API. The higher-level Run API handles this condition automatically.

type RuleID

type RuleID = runtimepkg.RuleID

type Run

type Run = runtimepkg.Run

type SignalID

type SignalID = runtimepkg.SignalID

type SourceMapEntry

type SourceMapEntry struct {
	TRIZKind string
	TRIZName string
	TRIZLine int
	V0Kind   string
	V0Name   string
	V0Line   int
}

type Status

type Status = runtimepkg.Status

type Store

type Store = runtimepkg.Store

func NewMemoryStore

func NewMemoryStore() Store

NewMemoryStore creates an in-memory store. Use when you need explicit store ownership (e.g. passing the same store to multiple engines).

type StoreDurability

type StoreDurability = runtimepkg.StoreDurability

StoreDurability describes how strongly a Store persists committed writes.

const (
	StoreDurabilityEphemeral   StoreDurability = runtimepkg.StoreDurabilityEphemeral
	StoreDurabilityBestEffort  StoreDurability = runtimepkg.StoreDurabilityBestEffort
	StoreDurabilityBuffered    StoreDurability = runtimepkg.StoreDurabilityBuffered
	StoreDurabilitySynchronous StoreDurability = runtimepkg.StoreDurabilitySynchronous
)

type StoreTransaction

type StoreTransaction = runtimepkg.StoreTransaction

StoreTransaction is the transaction surface used by TransactionalStore.

type TRIZNormalization

type TRIZNormalization struct {
	Source           []byte
	NormalizedSource []byte
	Module           *Module
	Diagnostics      Diagnostics
	SourceMap        []SourceMapEntry
}

func NormalizeTRIZ

func NormalizeTRIZ(source []byte, opts ...CompileOption) (*TRIZNormalization, error)

NormalizeTRIZ parses TRIZ DSL, emits equivalent Axiom v0 source, compiles it, and returns source-map and diagnostic data for tools such as Axiom Studio.

type TaskStatus

type TaskStatus = runtimepkg.TaskStatus

type TraceLevel

type TraceLevel = runtimepkg.TraceLevel

type TransactionalStore

type TransactionalStore = runtimepkg.TransactionalStore

TransactionalStore exposes atomic store transactions.

type Value

type Value = runtimepkg.Value

type ValueKind

type ValueKind = runtimepkg.ValueKind

type WorkerOptions

type WorkerOptions = runtimepkg.WorkerOptions

Directories

Path Synopsis
Package adgo implements Axiom Adaptive Durable Graph Orchestration: a production durable execution engine for long-running graphs, agents, LLM/tool workflows and human-in-the-loop processes.
Package adgo implements Axiom Adaptive Durable Graph Orchestration: a production durable execution engine for long-running graphs, agents, LLM/tool workflows and human-in-the-loop processes.
examples/iris command
Package axm implements the optional AXM frontend.
Package axm implements the optional AXM frontend.
cmd
axiombench command
axiomgen command
examples
axiom-files command
coffee-machine command
go-first command
model command
order command
table command
triz command
internal
jsonx
Package jsonx contains JSON boundary helpers used by runtime and stores.
Package jsonx contains JSON boundary helpers used by runtime and stores.
syncx
Package syncx contains small synchronization primitives shared by Axiom frontends.
Package syncx contains small synchronization primitives shared by Axiom frontends.
testutil
Package testutil provides shared helpers for Axiom's test and benchmark infrastructure.
Package testutil provides shared helpers for Axiom's test and benchmark infrastructure.
Package model provides a file-free declarative Go builder that compiles into the same canonical Plan as AXM and TOML.
Package model provides a file-free declarative Go builder that compiles into the same canonical Plan as AXM and TOML.
store
pebble
Package pebble exposes the durable Pebble-backed Axiom store.
Package pebble exposes the durable Pebble-backed Axiom store.
Package table implements a TOML decision-table frontend.
Package table implements a TOML decision-table frontend.

Jump to

Keyboard shortcuts

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