engine

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package engine implements the v1 workflow engine core: procedure specs parsed from kind: procedure graph entries, a typed variable store per running instance, guards as boolean combinations of named Go predicates, a closed function registry (predicates, queries, commands), gate-transition cascade with chooser stops, and append-only JSONL session persistence.

Everything semantic lives in named Go functions composed by name in the procedure spec — the spec language has no expressions, no literals, no assignment. See the v1 surface spec (plan 20260702-220449-d-tac-ry0) and the engine directive (20260702-174833-d-cpt-3yw).

Index

Constants

View Source
const (
	EndCompleted = "end(completed)"
	EndAbandoned = "end(abandoned)"
)

Terminal transition targets. A procedure ends by transitioning to one of these instead of a step ID.

View Source
const LogVersion = 1

LogVersion stamps every event line. A session generally does not survive an sdd upgrade mid-flight — replay rejects unknown versions rather than guessing (accepted per the surface spec). Exported for shells that append terminal events to a parked log without replaying it (teardown by handle).

Variables

This section is empty.

Functions

func ComposeInstructions

func ComposeInstructions(unitText string, diagnostics []string) string

ComposeInstructions joins a rendered unit (or a shell-substituted reminder) with stall diagnostics — the one composition rule for the Instructions field, shared by the engine's serve and shells recomposing around served-instruction memory.

func IsEndTarget

func IsEndTarget(to string) bool

IsEndTarget reports whether a transition target is a terminal rather than a step ID.

Types

type BaseType

type BaseType string

BaseType is one of the closed set of domain types a procedure variable can declare. Adding a domain type means adding it here, once, with its validation — no other types exist.

const (
	TypeText              BaseType = "text"
	TypeBool              BaseType = "bool"
	TypeEntryID           BaseType = "entry-id"
	TypeRef               BaseType = "ref"
	TypeLabel             BaseType = "label"
	TypeParticipant       BaseType = "participant"
	TypeEntryKind         BaseType = "entry-kind"
	TypeLayer             BaseType = "layer"
	TypeConfidence        BaseType = "confidence"
	TypeIntent            BaseType = "intent"
	TypeAttachmentHandle  BaseType = "attachment-handle"
	TypePreflightFindings BaseType = "preflight-findings"
)

type ChooserKind

type ChooserKind string

ChooserKind classifies who advances a step: the engine (gate, auto-advance on guards), the agent (advisory pick, logged with evidence), or the user (dialogue-presence made structural).

const (
	ChooserGate  ChooserKind = "gate"
	ChooserAgent ChooserKind = "agent"
	ChooserUser  ChooserKind = "user"
)

type ChooserOption

type ChooserOption struct {
	Choice  string
	Collect []CollectField
}

ChooserOption is one selectable choice in a served chooser.

type ChooserServe

type ChooserServe struct {
	Chooser string
	Kind    ChooserKind
	Options []ChooserOption
}

ChooserServe is the pending-chooser part of a serve: which step's chooser is pending, who answers, and what the options are. Chooser is the step ID the caller must name in a chooser answer — carried here so the value the answer requires appears in the payload it answers.

type CollectField

type CollectField struct {
	Name     string
	Optional bool
}

CollectField names a state field a report may write at a step; Optional fields don't gate the cascade.

type Command

type Command struct {
	Doc FuncDoc
	Fn  CommandFunc
	// MutatesGraph declares that running this command changes the on-disk graph
	// (a new entry, a rewritten summary). The engine invalidates the graph
	// provider after such a command so later reads in the same advance reload
	// and see the write — post-write freshness driven by the command's own
	// declaration, replacing the shell's hand-maintained refresh calls.
	MutatesGraph bool
}

Command is a registered command.

type CommandFunc

type CommandFunc func(ctx *Context) error

CommandFunc executes a side effect (gate ops and chooser calls only). Its store writes go through Store.WriteEngine per the declared contract.

type Context

type Context struct {
	Store *Store
	Graph *model.Graph
	// Step is the step the function runs at — commands like confirmPlayback
	// record it (the reopen target when a confirmation goes stale).
	Step string
	// Reads is the session's folded read set — the deepest depth each entry
	// was served at (refsInspected evaluates it). Nil means nothing was
	// served; reading a nil map is safe.
	Reads map[string]ReadDepth
}

Context is what registry functions see: the running instance's store and the graph, read-only by convention for predicates and queries. Commands additionally reach their side-effect dependencies through the closures they were registered with — the registry itself stays dependency-free.

type Dispatch

type Dispatch struct {
	// Procedure optionally names the child canonical this option dispatches.
	// When set, it guards the handoff — the seed applies only to a child of
	// that procedure. Omit it for a generic junction whose child is chosen at
	// runtime (e.g. engage's move), where the seed applies to whatever is
	// dispatched next.
	Procedure string
	// Seed maps child field ← parent field: the key is the field the child
	// declares as state, the value is this parent's own declared field carrying
	// the evidence. Required — a Dispatch with no seed has nothing to carry.
	Seed map[string]string
}

Dispatch is a junction option's declaration of the grounding it seeds into a child dispatched after this option is answered. The seeding contract (d-tac-tlo) keeps the declaration entirely in the parent's spec: answering an option carrying a Dispatch stashes its Seed on the parent instance, and the next child started under that parent inherits exactly that mapping. There is no engine-wide default — a handoff happens only where a junction declares one, so every inheritance is readable at the junction that grants it.

type Engine

type Engine struct {
	Registry *Registry
	Graphs   Graphs
}

Engine executes procedure instances against a graph provider and a registry. It is pure Go over data — shells (MCP, webapp) sit on top; side-effectful commands come in through the registry with their own dependencies. The graph is not held as a mutable field: the engine reads it through Graphs, so ownership of "what the current graph is" stays on the read side.

func New

func New(registry *Registry, graphs Graphs) *Engine

New creates an engine reading the current graph through graphs.

func (*Engine) NewSession

func (e *Engine) NewSession(id, participant string, sink EventSink, opts ...SessionOption) *Session

NewSession creates an empty session appending to sink.

func (*Engine) ReplaySession

func (e *Engine) ReplaySession(id, participant string, events []Event, resolve SpecResolver, sink EventSink, opts ...SessionOption) (*Session, error)

ReplaySession reconstructs a session by folding its event log: state is applied directly from the logged values — reports, op results, and transitions — never by re-running commands, so replay is free of side effects. The returned session continues appending to sink.

type Event

type Event struct {
	V        int            `json:"v"`
	TS       time.Time      `json:"ts"`
	Session  string         `json:"session"`
	Seq      int            `json:"seq"`
	Instance string         `json:"instance,omitempty"`
	Event    EventType      `json:"event"`
	Data     map[string]any `json:"data,omitempty"`
}

Event is one line of the append-only session log. Memory is the runtime source of truth; the log is the persistence, the session protocol, and the forensic record — transition reports are the trajectory evidence.

func ReadEvents

func ReadEvents(r io.Reader) ([]Event, error)

ReadEvents parses a JSONL session log.

type EventSink

type EventSink interface {
	Append(Event) error
}

EventSink receives events as they happen. The shell wires it to an append-only JSONL file; tests use an in-memory sink.

type EventType

type EventType string

EventType is one of the closed set of session-log events.

const (
	// EventSessionMeta is the session-level header line (no instance):
	// participant identity, so a log is self-describing for list_sessions
	// descriptors without resolving any procedure spec.
	EventSessionMeta EventType = "session_meta"
	// EventLabeled carries a human-meaningful session label (no instance):
	// the dialogue's subject, agent-supplied and updatable as it sharpens.
	// Last one wins on fold and replay.
	EventLabeled       EventType = "labeled"
	EventStarted       EventType = "started"
	EventReport        EventType = "report"
	EventChooserAnswer EventType = "chooser_answer"
	EventOpResult      EventType = "op_result"
	EventServed        EventType = "served"
	EventTransition    EventType = "transition"
	EventCompleted     EventType = "completed"
	EventAbandoned     EventType = "abandoned"
	// EventRead records what a read surface served to the session: the tool,
	// the entry IDs, and the depth — metadata only, never payloads. Reads stay
	// free and ungated; tracking is logging, not gating (d-tac-dbk). No
	// instance — the read set is session-level, so evidence inspected by a
	// dispatching parent counts for its seeded children.
	EventRead EventType = "read"
	// EventParked records that a running move was deliberately parked back to
	// the session junction — state kept, resumable through next. Forensic
	// only: a resuming agent can tell a shelved move from one that drifted.
	EventParked EventType = "parked"
)

type ExportedValue

type ExportedValue struct {
	Value      any        `json:"value"`
	Provenance Provenance `json:"provenance"`
}

ExportedValue is the persisted form of one store value.

type FailedPredicate

type FailedPredicate struct {
	Name    string
	Message string
}

FailedPredicate names a predicate that held a gate, with its registered failure message — the message becomes the served instruction.

type FuncClass

type FuncClass string

FuncClass is one of the registry's three function classes.

const (
	ClassPredicate FuncClass = "predicate"
	ClassQuery     FuncClass = "query"
	ClassCommand   FuncClass = "command"
)

type FuncDoc

type FuncDoc struct {
	Name   string
	Class  FuncClass
	Doc    string
	Reads  []string
	Writes []string
}

FuncDoc is a registry function's documented contract: what it reads from and writes into the store. YAML never maps fields — it only names functions; these contracts are what spec authors consult (registryList, the MCP registry tool) and what load-time collision checks enforce.

type Graphs added in v0.14.1

type Graphs interface {
	Current() (*model.Graph, error)
	Invalidate()
}

Graphs is the engine's read-through to the current graph. The read side owns loading and freshness (a finders.GraphSource); the engine only reads through this value — Current returns the current graph (memoized by the source), Invalidate drops that memo after a graph write so the next read reloads. Declared here as an interface so the engine takes no finders import.

type GuardExpr

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

GuardExpr is a parsed guard expression.

func ParseGuard

func ParseGuard(src string) (*GuardExpr, error)

ParseGuard parses a guard expression. Whitespace (including newlines from folded YAML scalars) separates tokens.

func (*GuardExpr) Eval

func (g *GuardExpr) Eval(eval func(name string) (bool, error)) (bool, error)

Eval evaluates the expression against a predicate evaluator. Predicates are pure, so full evaluation (no short-circuit) is safe and keeps stall diagnostics complete.

func (*GuardExpr) Predicates

func (g *GuardExpr) Predicates() []string

Predicates returns the distinct predicate names the expression references, in first-appearance order. Used by spec validation (every name must exist in the registry) and by stall diagnostics.

func (*GuardExpr) String

func (g *GuardExpr) String() string

String returns the original expression source.

type InjectCall

type InjectCall struct {
	Fn   string
	Args map[string]any
}

InjectCall is a query op the engine runs before serving a step's unit. Args are literals or Go templates rendered against the store.

type Instance

type Instance struct {
	ID     string
	Spec   *Spec
	Store  *Store
	Step   string
	Status InstanceStatus
	// Outcome is the end(...) label the instance finished with.
	Outcome string
	// Parent is the spawning instance's ID for sub-procedures, empty at the
	// top level.
	Parent string
	// contains filtered or unexported fields
}

Instance is one running procedure — a spec, its typed store, and a step position. Instances belong to a session; sub-procedures carry a parent link.

type InstanceStatus

type InstanceStatus string

InstanceStatus is a procedure instance's lifecycle state.

const (
	StatusRunning   InstanceStatus = "running"
	StatusCompleted InstanceStatus = "completed"
	StatusAbandoned InstanceStatus = "abandoned"
)

type Option

type Option struct {
	Choice  string
	Call    string // command run on selection, per its Go contract
	Collect []CollectField
	To      string
	// Dispatch declares the grounding this junction option seeds into a child
	// dispatched after it is answered (child field ← parent field, named in the
	// parent's own spec). Nil means this option hands nothing down.
	Dispatch *Dispatch
}

Option is one choice on an agent or user chooser step.

type Predicate

type Predicate struct {
	Doc         FuncDoc
	Fn          PredicateFunc
	FailMessage string
	// FailDetail, when set, renders the failure message against the live
	// context — for gates whose rejection must name the offending values
	// (refsInspected naming the un-inspected IDs). Empty results fall back
	// to FailMessage.
	FailDetail func(ctx *Context) string
}

Predicate is a registered predicate with its contract and failure text — the message served as instruction when the predicate stalls a gate.

type PredicateFunc

type PredicateFunc func(ctx *Context) (bool, error)

PredicateFunc is a pure check over the store (and graph): no side effects, deterministic for a given state.

type Provenance

type Provenance string

Provenance classifies who wrote a store value. The split carries the trust property from the surface spec: reports can only write declared state fields; params are fixed at start; everything trust-bearing (created IDs, findings, confirmation records) is engine-written via ops and chooser calls, structurally out of a report's reach.

const (
	ProvenanceParam  Provenance = "param"
	ProvenanceState  Provenance = "state"
	ProvenanceEngine Provenance = "engine"
)

type Query

type Query struct {
	Doc FuncDoc
	Fn  QueryFunc
}

Query is a registered query.

type QueryFunc

type QueryFunc func(ctx *Context, args map[string]any) (any, error)

QueryFunc serves data for dynamic injection: pure read, result enters the template context (not the store).

type ReadDepth

type ReadDepth string

ReadDepth classifies how deeply an entry was served: full means the body was served (a show primary, an injected chain's primary, or a same-session write); summary covers chain bullets, search headers, and snippets.

const (
	ReadSummary ReadDepth = "summary"
	ReadFull    ReadDepth = "full"
)

type Ref

type Ref struct {
	ID   string `json:"id"`
	Kind string `json:"kind"`
	Desc string `json:"desc,omitempty"`
}

Ref is the engine-side value of a ref-typed variable: the same closed-kind reference shape entries carry, before it becomes a model.Ref at the write gate.

type Registry

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

Registry is the closed set of Go functions a procedure spec may name. All semantics live here, composed by name in YAML — the spec language itself carries no logic. Enumerable so spec authors and lint can check every referenced name.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns a registry pre-populated with the built-in predicates (largely the mechanical pre-flight checks re-exposed — single path, no duplicated validation). Queries and commands with side-effect dependencies are registered by the shell that owns those dependencies.

func (*Registry) Command

func (r *Registry) Command(name string) (*Command, bool)

Command looks up a command by name.

func (*Registry) Docs

func (r *Registry) Docs(class FuncClass) []FuncDoc

Docs enumerates registered function contracts, optionally filtered by class, sorted by name — the registryList query's data.

func (*Registry) Predicate

func (r *Registry) Predicate(name string) (*Predicate, bool)

Predicate looks up a predicate by name.

func (*Registry) Query

func (r *Registry) Query(name string) (*Query, bool)

Query looks up a query by name.

func (*Registry) RegisterCommand

func (r *Registry) RegisterCommand(c Command) error

RegisterCommand adds a command. Names are unique across all classes.

func (*Registry) RegisterPredicate

func (r *Registry) RegisterPredicate(p Predicate) error

RegisterPredicate adds a predicate. Names are unique across all classes.

func (*Registry) RegisterQuery

func (r *Registry) RegisterQuery(q Query) error

RegisterQuery adds a query. Names are unique across all classes.

type Serve

type Serve struct {
	Instance  string
	Procedure string
	Status    InstanceStatus
	Outcome   string
	Step      string
	// Goal is a one-line statement of what advances the instance from here.
	Goal string
	// Instructions is the step's instruction unit rendered against the
	// store, with stall diagnostics appended when a gate is held.
	Instructions string
	// Unit names the instruction unit rendered into Instructions (empty when
	// the step has none). Shells key their served-instruction memory on it.
	Unit string
	// UnitText is the rendered unit alone, without diagnostics — what a
	// shell replaces with a one-line reminder once the unit was served.
	UnitText string
	// Diagnostics are the stall messages appended to Instructions ("Gate
	// held" lines), kept separate so shells can recompose around UnitText.
	Diagnostics []string
	// Missing names the current step's required collect fields not yet in
	// the store.
	Missing []string
	// Failing lists predicates currently holding the gate.
	Failing []FailedPredicate
	// ReportSchema is the JSON Schema for the current step's report.
	ReportSchema map[string]any
	// Chooser is set when the step awaits an agent or user choice.
	Chooser *ChooserServe
	// Produced carries the engine-written results on completion (e.g. the
	// created entry ID), excluding internal trust machinery.
	Produced map[string]any
}

Serve is what the engine returns after every advance — the current step's rendered instructions, the report schema, chooser material when one is pending, and stall diagnostics naming exactly what's missing.

type Session

type Session struct {
	ID          string
	Participant string
	// Label is the session's human-meaningful subject line — what a user
	// picks a parked dialogue by. Agent-supplied via SetLabel, updatable;
	// empty until supplied.
	Label string
	// contains filtered or unexported fields
}

Session is one dialogue session: N procedure instances interleaved serially, one append-only event log. Per-participant; the shell owns file placement and lifecycle.

func (*Session) Abandon

func (s *Session) Abandon(instanceID, reason string) error

Abandon explicitly discards a running instance, logged as an abandonment transition. It never cleans up implicitly — anything the instance holds (a WIP marker, staged attachments) is left standing for resume or groom.

func (*Session) Answer

func (s *Session) Answer(instanceID, chooser, choice string, fields map[string]any, userWords string) (*Serve, error)

Answer resolves the pending chooser at the instance's current step: the named chooser must be the current step (no early, late, or double answers), the choice must be one of its options, and any carried fields are limited to the option's collect list. User answers carry the user's words verbatim for the auditable-relay record.

func (*Session) Instance

func (s *Session) Instance(id string) (*Instance, bool)

Instance returns a session instance by ID.

func (*Session) Instances

func (s *Session) Instances() []*Instance

Instances returns the session's instances in start order.

func (*Session) LogRead

func (s *Session) LogRead(tool string, full, summary []string)

LogRead records what a read surface served to the session: entry IDs at full depth (body served) and summary depth (headers, chain bullets, snippets), attributed to the serving tool. Every call appends a read event — re-reads are part of the forensic record — and folds into the session's read set, where full depth never downgrades. Empty calls append nothing.

func (*Session) Park

func (s *Session) Park(instanceID, note string) error

Park records that a running move was deliberately parked back to the session junction: state kept, position kept, resumable through the normal advance path. The event is forensic — nothing about the instance changes — but it makes the shelving auditable and legible to a resuming agent.

func (*Session) ReadDepthOf

func (s *Session) ReadDepthOf(id string) ReadDepth

ReadDepthOf returns the deepest depth the entry was served to this session at (empty when never served).

func (*Session) Report

func (s *Session) Report(instanceID string, fields map[string]any) (*Serve, error)

Report applies state fields from a transition report, re-evaluates, and cascades. Reports can only write declared state fields; batched fields for later steps are accepted. A report does not answer a pending chooser.

func (*Session) Serve

func (s *Session) Serve(instanceID string) (*Serve, error)

Serve re-serves the instance's current position without advancing it — shells use it to rehydrate an agent after resume_session.

func (*Session) SetLabel

func (s *Session) SetLabel(label string)

SetLabel records the session's subject label. Idempotent per value — a resent identical label appends nothing, so agents may safely carry the label on every call.

func (*Session) Start

func (s *Session) Start(spec *Spec, params map[string]any, parent string) (*Serve, error)

Start begins a procedure instance from a loaded spec with typed params, then cascades and serves. Parent links a sub-procedure to its spawning instance.

type SessionOption

type SessionOption func(*Session)

SessionOption configures a session.

func WithClock

func WithClock(now func() time.Time) SessionOption

WithClock injects the timestamp source (tests use a fixed clock).

type Spec

type Spec struct {
	// EntryID is the graph entry the spec was loaded from.
	EntryID string
	// Canonical is the procedure's stable identity (capture, engage, …).
	Canonical string
	// Class is the procedure's execution role: a move is started through the
	// loop, a shell is a session base auto-started by the session door.
	Class model.ProcedureClass
	// Params are the typed inputs accepted at start_procedure.
	Params map[string]VarDecl
	// State is the report-writable variable store declaration. Engine-
	// written values are deliberately not declared — they enter the store
	// per the Go contracts of the functions the spec names, and collisions
	// with these declarations are rejected at load.
	State map[string]VarDecl
	// Steps is the state graph, in declaration order. The first step is the
	// entry step.
	Steps []*Step
	// StepByID indexes Steps.
	StepByID map[string]*Step
	// Units are the body's instruction units by name (`## unit: <name>`
	// sections), rendered as Go templates against the store at serve time.
	Units map[string]string
}

Spec is the typed, validated form of a procedure entry's state machine — what the engine executes. Parsed from the raw YAML the model retains on kind: procedure entries (structural validation happens here, at engine load time, per the type-system revision contract) plus the body's per-step instruction units.

func LoadSpec

func LoadSpec(entry *model.Entry, reg *Registry) (*Spec, error)

LoadSpec parses and fully validates a procedure entry against the registry — the one-call path the engine and lint use.

func ParseSpec

func ParseSpec(entry *model.Entry) (*Spec, error)

ParseSpec parses a procedure entry into a typed Spec: variable declarations, the step graph with parsed guards, and the body's instruction units. Registry-independent validation happens here (types, step wiring, guard syntax, collect declarations); function existence and write-collision checks need the registry and run in Validate.

func (*Spec) AnswerSchemaForStep

func (s *Spec) AnswerSchemaForStep(step *Step) map[string]any

AnswerSchemaForStep generates the JSON Schema for a chooser step's answer: the chooser to name (its step id), the choice to pick, the user's verbatim words for a user chooser, and the option-collected fields nested under `fields`. A flat report schema at a chooser step misled callers into placing collected fields at the top level (rejected); this envelope makes the required nesting explicit. `fields` unions every option's collect fields — each option enforces its own required set at answer time, so the envelope marks none of them required.

func (*Spec) ReportSchemaForStep

func (s *Spec) ReportSchemaForStep(step *Step) map[string]any

ReportSchemaForStep generates the JSON Schema for a step's report from the spec's variable declarations: the step's collect fields are the named, described properties (required unless marked optional), and every other declared state field is accepted too — reports may batch fields for later steps, and the cascade rule makes the one-shot full draft as fast as today. The same desc that feeds instruction text feeds the schema.

func (*Spec) Validate

func (s *Spec) Validate(reg *Registry) []string

Validate runs the registry-dependent load checks: every function a spec names exists in the right class, and no named command writes into a declared param or state field (engine-written values must stay structurally out of the report-writable surface). Returns all problems.

type SpecResolver

type SpecResolver func(canonical string) (*Spec, error)

SpecResolver resolves a procedure canonical to its loaded spec — replay uses it to rebind logged instances to their procedure definitions.

type StaticGraphs added in v0.14.1

type StaticGraphs struct{ Graph *model.Graph }

StaticGraphs is a Graphs backed by a fixed in-memory graph — for tests and callers with no reload need. Invalidate is a no-op: there is nothing behind the value to re-read.

func (StaticGraphs) Current added in v0.14.1

func (s StaticGraphs) Current() (*model.Graph, error)

Current returns the fixed graph.

func (StaticGraphs) Invalidate added in v0.14.1

func (s StaticGraphs) Invalidate()

Invalidate is a no-op for a static graph.

type Step

type Step struct {
	ID          string
	Collect     []CollectField
	Inject      []InjectCall
	Render      string
	Chooser     ChooserKind
	Options     []Option
	Guard       *GuardExpr
	Op          string
	Transitions []Transition
	// Goal overrides the serve's generic per-chooser goal line for this
	// step. Built for resident steps whose standing posture the generic
	// wording would misstate (a session shell's junction is "dialogue
	// freely", not "put the choice to the user").
	Goal string
}

Step is one node of the state graph.

type Store

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

Store is the typed variable store of one procedure instance. Declared params and state come from the spec; engine-written values enter through command contracts (their Writes set) and are validated against declaration collisions at spec load time, not here.

func NewStore

func NewStore(spec *Spec) *Store

NewStore creates an empty store bound to the spec that declares its params and state fields.

func (*Store) Export

func (s *Store) Export() map[string]ExportedValue

Export returns all values with provenance for session-log persistence.

func (*Store) Get

func (s *Store) Get(name string) (any, bool)

Get returns the value and whether it is present.

func (*Store) Has

func (s *Store) Has(name string) bool

Has reports whether the field is present and non-empty. Empty strings, empty lists, and nil don't count as present — a presence predicate asking hasBody wants substance, not a key.

func (*Store) SetParams

func (s *Store) SetParams(params map[string]any) error

SetParams validates and writes the start-time params. Required params must be present; unknown params are rejected.

func (*Store) SetStart

func (s *Store) SetStart(inputs map[string]any) error

SetStart applies the start-time input map, the shared seeding primitive (d-tac-tlo): a key naming a declared param sets that param (fixed at start), a key naming a declared state field seeds it — a start-time state write, equivalent to an immediate report, so an entry gate reading it is satisfied on entry. Move dispatch and direct start share this: a caller passing an anchor a procedure declares as state seeds the resolver, and the parent handoff seeds the same fields from the parent's store. Unknown keys are rejected.

func (*Store) StateSnapshot

func (s *Store) StateSnapshot() string

StateSnapshot returns a deterministic fingerprint over the report-writable state values. confirmPlayback binds a confirmation to this fingerprint; playbackConfirmed compares it — any state edit after confirmation changes the snapshot and reopens playback.

func (*Store) TemplateContext

func (s *Store) TemplateContext() map[string]any

TemplateContext exposes every store value by name for instruction-unit and inject-arg template rendering.

func (*Store) WriteEngine

func (s *Store) WriteEngine(name string, v any)

WriteEngine writes an engine-produced value (an op result or chooser-call effect) per the producing function's Go contract. Never reachable from a report.

func (*Store) WriteState

func (s *Store) WriteState(fields map[string]any) ([]string, error)

WriteState validates and writes report-supplied state fields. Only fields declared in the spec's state block are writable — this is the report trust boundary. Returns the names actually written, sorted.

type Transition

type Transition struct {
	When      *GuardExpr
	Otherwise bool
	To        string
}

Transition is one ordered {when, to} entry; the final entry may be an otherwise fallback (When nil).

type VarDecl

type VarDecl struct {
	Type     VarType
	Optional bool
	Desc     string
}

VarDecl declares one typed variable. The desc seeds both the generated report schema and the "provide the following" instruction text — one declaration, both surfaces.

type VarType

type VarType struct {
	Base BaseType
	List bool
}

VarType is a declared variable type: a base domain type, optionally wrapped as list<T>.

func ParseVarType

func ParseVarType(s string) (VarType, error)

ParseVarType parses a type string from a variable declaration: a base domain type name or list<T> around one.

func (VarType) String

func (t VarType) String() string

func (VarType) ValidateValue

func (t VarType) ValidateValue(v any) (any, error)

ValidateValue checks a raw value (as decoded from a JSON report or supplied by Go code) against the type, returning a normalized value. Lists validate per element.

type WriterSink

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

WriterSink appends events as JSON lines to an io.Writer.

func NewWriterSink

func NewWriterSink(w io.Writer) *WriterSink

NewWriterSink wraps a writer as an EventSink emitting one JSON line per event.

func (*WriterSink) Append

func (s *WriterSink) Append(e Event) error

Append writes the event as one JSON line.

Jump to

Keyboard shortcuts

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