model

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package model defines the records that flow through Atlas and their on-disk binary encoding.

Everything the engine processes is a keyed Record discriminated by a (ValueType, Intent) pair. Commands are intentions and are never persisted; events are facts and are appended to the write-ahead log. State is the fold of all events. See docs/architecture/data-model.md for the full reference.

The encoding here is the internal log format: a hand-written binary layout behind an explicit version byte (ADR-0009). It is deliberately reflection- free so that encoding an event on the processor hot path does not allocate (invariant I1); callers reuse a single buffer across records.

Index

Constants

View Source
const HeaderSize = 1 +
	8 +
	8 +
	8 +
	8 +
	1 +
	1 +
	1 +

	2 // PartitionId

HeaderSize is the encoded size of the version byte plus the fixed header.

Variables

View Source
var (
	// ErrShortBuffer is returned when a buffer is too small to hold the record
	// or payload being read.
	ErrShortBuffer = errors.New("model: buffer too short")
	// ErrUnknownVersion is returned when a record's version byte is not one this
	// build can decode.
	ErrUnknownVersion = errors.New("model: unknown codec version")
)

Functions

func AppendRecord

func AppendRecord(dst []byte, r *Record) []byte

AppendRecord encodes r and appends it to dst, returning the extended slice. Passing a reused buffer (e.g. buf[:0]) makes encoding allocation-free, which the processor hot path relies on (invariant I1).

func AppendValue

func AppendValue(dst []byte, v Value) []byte

AppendValue appends v's payload bytes (no record header) to dst and returns the extended slice. The state store uses this to persist materialized values; the log uses AppendRecord, which frames a full header around the payload.

func CounterOf

func CounterOf(key uint64) uint64

CounterOf returns the per-partition counter component of key.

func DecodeValueInto

func DecodeValueInto(v Value, src []byte) error

DecodeValueInto decodes a payload from src into the caller-provided v. Unlike DecodeValue it allocates nothing, so a hot-path reader can decode into a reused struct (invariant I1). v must be the concrete type matching the bytes.

func NewKey

func NewKey(partition uint16, counter uint64) uint64

NewKey composes a globally unique 64-bit key from a partition id and a per-partition monotonic counter.

func PartitionOf

func PartitionOf(key uint64) uint16

PartitionOf returns the partition that owns key.

Types

type CompensableValue

type CompensableValue struct {
	ProcessInstanceKey uint64
	ProcessDefKey      uint64
	ScopeKey           uint64 // FlowScopeKey the compensable activity lived in
	ElementInstanceKey uint64 // the completed activity's element-instance key
	Seq                uint64 // the record's key sequence (log position), set on consume
	ElementId          int32  // the compensable activity's compiled node id
	HandlerNode        int32  // the compensation handler's compiled node id
}

CompensableValue is one completed compensable activity: an activity that bore a compensation boundary and finished successfully, retained so a later compensation throw can run its handler (ADR-0103). It is keyed under ScopeKey in completion order (by the event's log position), so a reverse scan yields reverse completion order. ElementId identifies the compensated activity (for activityRef matching); HandlerNode is the compensation handler to activate; Seq carries the record's key sequence back on the consume event so its index entry can be deleted. All fields are fixed-width.

func (*CompensableValue) ValueType

func (*CompensableValue) ValueType() ValueType

type DataObjectValue

type DataObjectValue struct {
	ScopeKey uint64 // owning scope (process instance key today)
	Name     string
	State    string // BPMN data state; "" when the object declares none
	Kind     VarKind
	Bool     bool
	Text     string // number canonical string, string contents, or canonical JSON; empty otherwise
}

DataObjectValue is a BPMN data object owned by a scope (the process instance root today). It is variable-shaped — a name and a typed value reusing the same VarKind machinery, so a data object can hold a structured VarJSON payload (ADR-0037) — plus a State: the BPMN data state (e.g. "received", "approved"). Its encoding mirrors VariableValue with the extra State string between the name and the kind byte; like a variable it carries genuine runtime data, so it is length-prefixed rather than fixed-size (ADR-0053).

func (*DataObjectValue) ValueType

func (*DataObjectValue) ValueType() ValueType

type DecisionEvaluationValue

type DecisionEvaluationValue struct {
	ProcessInstanceKey uint64 // owning instance (the scope this record is keyed under)
	ElementInstanceKey uint64 // the business rule task instance that evaluated
	ProcessDefKey      uint64 // the process definition, to map ElementId onto the diagram
	ElementId          int32  // interned diagram node id of the business rule task
	DecisionId         string // the evaluated DMN decision id
	InputsJSON         string // canonical JSON object: the decision's input context
	OutputsJSON        string // canonical JSON object: the decision's outputs (name → value)
	TraceJSON          string // temis trace JSON (which rules fired); "" when none
}

DecisionEvaluationValue is one business rule task's DMN decision evaluation, retained for debugging (ADR-0066). It freezes what the worker computed off the processor goroutine: the input context the decision was given, the outputs it produced, and the temis trace explaining which rules fired. The three payloads are canonical JSON text (InputsJSON and OutputsJSON are objects; TraceJSON is the temis trace tree, or "" when the evaluator produced none — e.g. a literal- expression decision or a remote decision whose connector returned no trace).

It is keyed under its owning ProcessInstanceKey as append-only history — one record per evaluation, never overwritten — so an operator can inspect after the fact exactly how a decision was made. ElementInstanceKey, ProcessDefKey and ElementId locate the business rule task on its instance and diagram. Like a variable it carries genuine runtime data, so its encoding is length-prefixed.

func (*DecisionEvaluationValue) ValueType

func (*DecisionEvaluationValue) ValueType() ValueType

type ElementInstanceValue

type ElementInstanceValue struct {
	ProcessInstanceKey uint64
	ProcessDefKey      uint64
	ElementId          int32  // INDEX into the compiled graph, not a string
	FlowScopeKey       uint64 // parent scope (subprocess instance), 0 = root
	BpmnElementType    uint8  // for fast dispatch
	// AttachedToKey links a boundary event's element instance to the host activity
	// instance it is attached to (0 for every non-boundary element). It lets an
	// interrupting boundary find and terminate its host, and a completing host find
	// and disarm its boundary events (ADR-0040).
	AttachedToKey uint64
	TokenID       uint64
	ParentTokenID uint64
	SourceFlowId  int32
	// MultiInstance marks an element instance's role in a multi-instance activity
	// (ADR-0077): 0 = not multi-instance, 1 = the body (the scope that seeds the
	// iterations), 2 = an inner iteration (running the node's real behavior, scoped
	// under the body). Append-compatible: an old record without it decodes to 0.
	MultiInstance uint8
	// EventGatewayKey labels a catch event armed by an event-based gateway with the
	// gateway's element-instance key — its race group (ADR-0110). The first armed catch to
	// fire cancels every other live instance sharing this key. 0 for every element not armed
	// by an event gateway. Append-compatible: an old record without it decodes to 0.
	EventGatewayKey uint64
}

ElementInstanceValue is the token-carrying state of one active BPMN element.

func (*ElementInstanceValue) ValueType

func (*ElementInstanceValue) ValueType() ValueType

type InboundDeliveryValue

type InboundDeliveryValue struct {
	SourceID  string
	SourceSeq uint64
}

InboundDeliveryValue advances an external event source's inbound high-water mark (ADR-0075). SourceID is an opaque per-source identifier (e.g. a clio connector + watched subject) the engine never interprets; SourceSeq is that source's monotonic sequence up to which delivery has been applied. Folding these into a per-source high-water mark lets a replayed at-least-once publish be skipped.

func (*InboundDeliveryValue) ValueType

func (*InboundDeliveryValue) ValueType() ValueType

type IncidentValue

type IncidentValue struct {
	ProcessInstanceKey uint64
	ElementInstanceKey uint64
	JobKey             uint64
	ElementId          int32 // the compiled-graph element the token is stuck on (maps to a BPMN element id for the operator)
	RaisedAt           int64 // unix nanoseconds the incident was raised; read at command time and frozen into the event (I6)
	Message            string
}

IncidentValue is a durable fault attached to the element instance where progress stalled — today, a job whose retries were exhausted (ADR-0061). It is keyed by ElementInstanceKey (one activity holds at most one job, so at most one incident) and points at the job, so resolving the incident can re-activate it. Message is the worker-reported failure reason; it is genuine runtime data, so the value is length-prefixed rather than fixed-size.

func (*IncidentValue) ValueType

func (*IncidentValue) ValueType() ValueType

type Intent

type Intent uint8

Intent is the verb of a record: what transition it represents. The element- instance lifecycle (Activating → Activated → Completing → Completed, plus Terminating → Terminated) is the heart of the model.

const (
	// ElementInstance lifecycle (every BPMN element goes through this).
	IntentActivating Intent = iota
	IntentActivated
	IntentCompleting
	IntentCompleted
	IntentTerminating
	IntentTerminated

	// SequenceFlow.
	IntentSequenceFlowTaken

	// Job.
	IntentJobCreated
	IntentJobActivated // picked up by a worker
	IntentJobCompleted
	IntentJobFailed
	IntentJobTimedOut
	IntentJobAssigned // user-task assignee set/changed/cleared (claim/unclaim, ADR-0042)

	// Timer.
	IntentTimerCreated
	IntentTimerTriggered

	// Message / Signal.
	IntentSubscriptionCreated
	IntentSubscriptionCorrelated
	IntentMessagePublished

	// Variable.
	IntentVariableCreated
	IntentVariableUpdated

	// Incident.
	IntentIncidentCreated
	IntentIncidentResolved

	// IntentJobCanceled retires a job whose element was interrupted (e.g. by an
	// interrupting boundary event) rather than completed by a worker. It applies
	// like JobCompleted/JobFailed (the job is deleted), and is appended here rather
	// than beside the other job intents so the existing intents keep their numeric
	// values on the log.
	IntentJobCanceled

	// IntentTimerCanceled retires a timer without firing it — used when a new
	// version of a process supersedes a prior version's timer start event, so the
	// old schedule stops (ADR-0051). It applies like TimerTriggered (the timer is
	// deleted from the due-date index) but, unlike it, drives no side effect: no
	// instance is created. Appended at the end so existing intents keep their log
	// values.
	IntentTimerCanceled

	// IntentTimerStartArm is a command-only intent (never persisted as an event):
	// it directs the processor to arm a freshly deployed definition's timer start
	// events, creating their durable timers and retiring any that a prior version
	// left armed (ADR-0051). Because commands are not replayed (invariant I6), its
	// numeric value never reaches the log.
	IntentTimerStartArm

	// DataObject. Appended after the existing intents so every prior intent keeps
	// its numeric value on the log (ADR-0053). Created seeds a data object under a
	// scope with its declared initial data state; StateChanged transitions the data
	// state (and, later, the value) as an activity writes to it.
	IntentDataObjectCreated
	IntentDataObjectStateChanged

	// IntentDecisionEvaluated records that a business rule task's DMN decision was
	// evaluated (ADR-0066). Appended after the existing intents so every prior
	// intent keeps its numeric value on the log. It is a pure history event: the
	// worker has already evaluated the decision off the processor goroutine, and the
	// resulting inputs/outputs/trace are frozen into the event so replay re-applies
	// them without re-evaluating (invariant I6).
	IntentDecisionEvaluated

	// IntentVariableDeleted removes a variable from its scope. It applies like the
	// inverse of VariableCreated (the variable is deleted rather than put), and is
	// appended at the end so every prior intent keeps its numeric value on the log.
	// Its use is dropping an activity-local variable scope when the activity
	// completes, after I/O output mappings have promoted the values that escape
	// (ADR-0068): the drop is emitted as one VariableDeleted per local variable, so
	// replay reproduces it exactly (invariant I6) rather than recomputing it.
	IntentVariableDeleted

	// IntentInboundDeliveryApplied advances an external source's inbound high-water
	// mark (ADR-0075). It applies by upserting the source's last-applied sequence,
	// and is appended at the end so every prior intent keeps its numeric value on the
	// log. It rides in the same batch as the message publish it guards, so the
	// dedup mark and the correlate/start effects it authorizes commit atomically.
	IntentInboundDeliveryApplied

	// IntentVariableModify is a command-only intent (never persisted as an event),
	// like IntentTimerStartArm: it directs the processor to set or overwrite
	// variables on a running instance's scope from outside the model — an operator
	// correction to a live instance (ADR-0095). The handler validates the target
	// scope, then emits a VariableCreated event for a new name or a VariableUpdated
	// event for an existing one, so the change is a durable, replayable fact recorded
	// in the instance's variable timeline (the audit trail), not a raw store write.
	// Because commands are not replayed (invariant I6), its numeric value never
	// reaches the log, so it is appended at the end without disturbing the persisted
	// intents' values.
	IntentVariableModify

	// IntentVariableAudited records that an external actor set a variable on a running
	// instance (ADR-0098). It is a pure history event, like IntentDecisionEvaluated:
	// emitted alongside the VariableCreated/VariableUpdated the override produces, it
	// freezes who made the change into the log so replay rebuilds the identical audit
	// trail without re-running the command (invariant I6). Appended at the end so every
	// prior intent keeps its numeric value on the log.
	IntentVariableAudited

	// IntentJobErrorThrown is a command-only intent (never persisted as an event): a
	// worker reports that its job threw a BPMN error code (ADR-0089). Its handler cancels
	// the job and propagates the error from the job's element to the nearest matching error
	// handler — so, unlike IntentJobFailed, it is control flow, not a retry/incident.
	// Because commands are not replayed (invariant I6), its numeric value never reaches the
	// log. Appended at the end so every prior intent keeps its numeric value.
	IntentJobErrorThrown

	// IntentCompensableRecorded records that a compensable activity (one bearing a
	// compensation boundary) completed successfully, so a later compensation throw can
	// run its handler (ADR-0103). It is a pure state event, keyed under the activity's
	// scope in completion order: applyToState writes it into the compensable index off
	// the completion event, so recovery rebuilds the identical index (invariant I6).
	// Appended at the end so every prior intent keeps its numeric value on the log.
	IntentCompensableRecorded
	// IntentCompensableConsumed removes a compensable record once its activity has been
	// compensated (the handler was activated), so it is compensated at most once (ADR-0103).
	// It carries the record's scope and sequence; applyToState deletes that index entry.
	IntentCompensableConsumed

	// IntentPurging is a command-only intent (never persisted as an event), like
	// IntentTimerStartArm: the retention sweep directs the processor to hard-delete a
	// finished instance's history (ADR-0115). Its handler emits IntentPurged for the
	// instance it carries. Because commands are not replayed (invariant I6), its numeric
	// value never reaches the log. Appended at the end so every prior intent keeps its
	// numeric value.
	IntentPurging
	// IntentPurged removes a finished process instance's history from the state store —
	// the terminal record and every per-instance family (ADR-0115). It is the durable
	// delete: applyToState folds it into the removals, so recovery reproduces the purge
	// (invariants I4/I6). Appended at the end so every prior intent keeps its numeric
	// value on the log.
	IntentPurged

	// IntentConditionRecheck is a command-only intent (never persisted as an event), like
	// IntentJobErrorThrown: after a batch writes one or more variables in an instance, the
	// processor schedules a re-check of that instance's armed conditional events (ADR-0137).
	// Its handler evaluates each armed conditional's FEEL condition over its scope chain and
	// drives the ones now true to Completing. Because commands are not replayed (invariant
	// I6) — the fire is the persisted Completing→Completed chain — its numeric value never
	// reaches the log. Appended at the end so every prior intent keeps its numeric value.
	IntentConditionRecheck
)

func (Intent) String

func (i Intent) String() string

type JobValue

type JobValue struct {
	ProcessInstanceKey uint64
	ElementInstanceKey uint64
	JobType            int32 // interned string → index
	Retries            int32
	Deadline           int64
	Assignee           string
	// RetryDueDate is the unix-nano instant a failed-but-retryable job may be handed to a
	// worker again — a retry backoff (ADR-0111). While it is non-zero and in the future the
	// job is held OFF the activatable index; a retry timer clears it when the backoff elapses.
	// 0 means "pullable now" (no backoff), which is every job's steady state. Append-compatible:
	// an old record without it decodes to 0.
	RetryDueDate int64
}

JobValue is service-task work waiting for an external worker. Variables are referenced via the element/instance scope, not embedded here. Assignee is the user-task assignee (ADR-0042): empty for a service-task job, and for a user task it starts at the model's default and is rewritten by claim/unclaim. It is the one variable-length field; for a service job it encodes as a 4-byte zero length and decodes to "" with no allocation, keeping the hot path clean (I1).

func (*JobValue) ValueType

func (*JobValue) ValueType() ValueType

type MessageFlowValue

type MessageFlowValue struct {
	SenderProcessInstanceKey   uint64
	ReceiverProcessInstanceKey uint64
	ReceiverProcessDefKey      uint64
	ReceiverElementId          int32 // INDEX into the receiver definition's graph
	MessageName                string
	CorrelationKey             string
}

MessageFlowValue is one delivered message flow, retained as history so the collaboration replay can show which message crossed to which receiving element and when (ADR-0038). It is produced when a message correlates a catch event or instantiates a message-start process. The receiving element identifies the message-flow edge on the diagram; the sender/receiver instance keys tie the two pools' instances together. ReceiverProcessInstanceKey is 0 when the message created the receiver via a message start event (no instance existed yet).

func (*MessageFlowValue) ValueType

func (*MessageFlowValue) ValueType() ValueType

type MessageSubscriptionValue

type MessageSubscriptionValue struct {
	ProcessInstanceKey uint64
	ElementInstanceKey uint64
	MessageName        string
	CorrelationKey     string // FEEL correlation key, evaluated at subscribe time
	// ProcessDefKey and ElementId identify the waiting catch event on its diagram.
	// They are carried so that when the subscription correlates, the retained
	// message-flow history record can name the receiving element without a lookup
	// (ADR-0038); they are set at subscribe time from the element instance.
	ProcessDefKey uint64
	ElementId     int32
}

MessageSubscriptionValue is an open subscription: an element instance (a message intermediate catch event) waiting for a named message whose correlation key matches. Like a variable it carries genuine runtime data (the message name and the evaluated correlation key), so its encoding is length-prefixed rather than fixed-size. The (MessageName, CorrelationKey) pair is the match key a publish scans for; see ADR-0020.

func (*MessageSubscriptionValue) ValueType

func (*MessageSubscriptionValue) ValueType() ValueType

type ProcessInstanceState

type ProcessInstanceState uint8

ProcessInstanceState marks where an instance is in its lifecycle. The zero value is Active; the terminal states are only ever stored in the history index (an active instance's record always carries Active). See ADR-0017.

const (
	PIActive     ProcessInstanceState = iota // running
	PICompleted                              // reached its end normally
	PITerminated                             // ended by termination
)

func (ProcessInstanceState) String

func (s ProcessInstanceState) String() string

type ProcessInstanceValue

type ProcessInstanceValue struct {
	ProcessDefKey  uint64
	State          ProcessInstanceState
	CompletedAt    int64  // unix nano when it reached a terminal state; 0 while active
	CreatedAt      int64  // unix nano when the instance was activated
	CorrelationKey string // message correlation key a message-start instance began with; "" otherwise
	// ParentElementInstanceKey is the call-activity element instance that started
	// this instance as its child, 0 for a root instance (API/message/timer start).
	// A completing child resumes its caller through it (ADR-0076).
	ParentElementInstanceKey uint64
	// ExpiryDueDate is the due date (unix nano) of this instance's TTL expiry timer,
	// 0 when the definition has no TTL (ADR-0085). Stored so completion/termination can
	// cancel that timer by key (the instance key) without scanning the timer index.
	ExpiryDueDate int64
	// CompletedPosition is the log position of the instance's terminal event, set only
	// on the history record (0 while active, and 0 on records written before this field,
	// ADR-0115). Since the terminal event is an instance's last, it is the instance's
	// highest position — so history retention can prove every event is exported
	// (CompletedPosition <= exported position) before hard-deleting the instance.
	CompletedPosition uint64
	// PurgeDueDate is when history retention is scheduled to hard-delete this finished
	// instance: CompletedAt + the definition's atlas:historyTtl, 0 when it declares none
	// (ADR-0146). Frozen on the terminal event so applyToState can index the instance by
	// it — and read back from the purge event to drop that index entry — without either
	// fold reading a clock or a definition.
	PurgeDueDate int64
}

ProcessInstanceValue is the running instance as a whole — the root scope a process's element instances live under. CreatedAt is set at activation (the activation event's timestamp, so it replays identically — invariant I6); CorrelationKey records the message key a message-start instance was created with ("" for API/timer/none starts, ADR-0035). State and CompletedAt are set only on the history record written when an instance ends (ADR-0017); while live, they carry their zero values (Active, 0).

func (*ProcessInstanceValue) ValueType

func (*ProcessInstanceValue) ValueType() ValueType

type Record

type Record struct {
	Header RecordHeader
	Value  Value
}

Record bundles a header with its typed payload. Value is nil for records whose ValueType carries no payload yet.

func ReadRecord

func ReadRecord(src []byte) (Record, error)

ReadRecord decodes a single record from the front of src. The payload (if any) is chosen by the header's ValueType.

type RecordHeader

type RecordHeader struct {
	Position    uint64 // monotonic log position (sequence number)
	SourcePos   uint64 // position of the record that caused this one (causality)
	Key         uint64 // entity key
	Timestamp   int64  // unix nano
	RecordType  RecordType
	ValueType   ValueType
	Intent      Intent
	PartitionId uint16
}

RecordHeader is the fixed-size metadata every record carries. SourcePos threads a causal chain through the log: every record points at the record that produced it.

type RecordType

type RecordType uint8

RecordType distinguishes the three kinds of record. Only events are written to the log; commands and rejections are processed but never persisted.

const (
	// RecordCommand is an intention submitted to the processor. It may be
	// rejected and is never persisted.
	RecordCommand RecordType = iota
	// RecordEvent is a fact that already happened. It is appended to the log
	// and is the only record type that is persisted.
	RecordEvent
	// RecordCommandRejection records that a command was refused. It is not
	// persisted; it is surfaced to the submitter.
	RecordCommandRejection
)

func (RecordType) String

func (t RecordType) String() string

type SignalSubscriptionValue

type SignalSubscriptionValue struct {
	ProcessInstanceKey uint64
	ElementInstanceKey uint64
	SignalName         string
	// ProcessDefKey and ElementId identify the waiting catch on its diagram; set at
	// subscribe time from the element instance and carried so the record locates its
	// own state index entry (invariant I4), mirroring MessageSubscriptionValue.
	ProcessDefKey uint64
	ElementId     int32
}

SignalSubscriptionValue is an open subscription to a broadcast signal: an element instance (a signal intermediate catch event, later a signal boundary or event subprocess) waiting for a named signal. It is the MessageSubscriptionValue shape (ADR-0020) minus the correlation key — a signal matches by name alone and fans out 1:n, so there is nothing to correlate on (ADR-0088). The SignalName is the sole match key a broadcast scans for.

func (*SignalSubscriptionValue) ValueType

func (*SignalSubscriptionValue) ValueType() ValueType

type TimerValue

type TimerValue struct {
	ProcessInstanceKey uint64
	ElementInstanceKey uint64
	TargetElementId    int32
	DueDate            int64
	Repetitions        int32 // remaining fires after this one; -1 = infinite (timer cycle), 0 = fire once
	// ProcessDefKey names the definition a *start* timer instantiates when it
	// fires (ADR-0051). It is 0 for an instance-owned timer (catch/boundary),
	// which is identified instead by ProcessInstanceKey/ElementInstanceKey. A
	// start timer is precisely one with ProcessInstanceKey == 0 and
	// ProcessDefKey != 0; TargetElementId then names its timer-start element.
	ProcessDefKey uint64
	// JobKey marks a retry-backoff timer (ADR-0111): non-zero means this timer, when due,
	// re-activates the failed job with that key rather than firing an element. 0 for every
	// ordinary (catch/boundary/start/TTL) timer. Append-compatible: an old record decodes to 0.
	JobKey uint64
}

TimerValue is a timer-event subscription. The due-date index makes "which timers are due now" a range scan; see data-model.md.

func (*TimerValue) ValueType

func (*TimerValue) ValueType() ValueType

type Value

type Value interface {
	// ValueType reports the discriminator a header should carry for this payload.
	ValueType() ValueType
	// contains filtered or unexported methods
}

Value is the typed payload of a record. Each implementation owns a fixed binary layout. encode appends to a caller-owned buffer (no allocation when the buffer has spare capacity, satisfying invariant I1); decode reads a payload back, returning ErrShortBuffer if src is truncated.

The methods are unexported on purpose: the set of value types is closed to this package, which keeps encode/decode and the newValue dispatch in lockstep.

func DecodeValue

func DecodeValue(vt ValueType, src []byte) (Value, error)

DecodeValue decodes a payload of the given value type from src into a freshly allocated Value. It returns an error if vt has no payload type or src is too short for it.

type ValueType

type ValueType uint8

ValueType identifies which entity a record concerns and therefore which payload struct its bytes carry. The set mirrors docs/architecture/data-model.md.

const (
	VTProcessInstance     ValueType = iota // the running instance as a whole
	VTElementInstance                      // a single active BPMN element instance (token carrier)
	VTJob                                  // service-task work for external workers
	VTTimer                                // timer-event subscription
	VTMessageSubscription                  // waiting for a message (receive task, message event)
	VTMessage                              // an incoming message (buffered)
	VTVariable                             // a process variable
	VTIncident                             // a fault state (job failed, expression error)
	VTSignal
	VTError             // error-event propagation
	VTProcessDefinition // a deployed definition
	// VTMessageFlow is a delivered message flow retained for history: one record
	// per message that correlated to a catch event or instantiated a message-start
	// process. Unlike VTMessageSubscription (an open wait, deleted on correlation)
	// it is never deleted, so the Operations collaboration view can replay the
	// exchange between pools after the fact (ADR-0038).
	VTMessageFlow
	// VTDataObject is a BPMN data object: a typed, named, scope-owned datum with a
	// declared lifecycle state. Unlike a plain variable it carries a data state
	// (order [received] → [approved]) whose every transition is a durable event,
	// so its state history and provenance rebuild from the log (ADR-0053).
	VTDataObject
	// VTDecisionEvaluation is one business rule task's DMN decision evaluation
	// retained for debugging: the input context it was given, the outputs it
	// produced, and the temis trace explaining which rules fired. Like VTMessageFlow
	// it is append-only history (one record per evaluation, never deleted), so an
	// operator can inspect after the fact exactly how a decision was made (ADR-0066).
	VTDecisionEvaluation
	// VTInboundDelivery is a per-source high-water mark for an at-least-once inbound
	// event bridge (ADR-0075): it records that an external source's deliveries up to
	// a sequence have been applied, so a replayed publish is skipped rather than
	// re-correlated (which would double-start a message-start process). It is generic
	// — the engine never interprets the opaque source id — and appended last so every
	// prior value type keeps its numeric value on the log.
	VTInboundDelivery
	// VTVariableAudit is one external variable override retained for audit (ADR-0098):
	// who set which variable, to what value, on which scope, keyed under its process
	// instance. Like VTMessageFlow and VTDecisionEvaluation it is append-only history
	// (one record per variable an operator sets, never deleted), so the "who changed
	// it" trail survives the instance and rebuilds from the log. Appended last so every
	// prior value type keeps its numeric value on the log.
	VTVariableAudit
	// VTCompensable is one completed compensable activity retained so a later
	// compensation throw can run its handler (ADR-0103). Written on the activity's
	// successful completion, keyed under its scope in completion order, and deleted when
	// compensated or when its scope tears down. Appended last so every prior value type
	// keeps its numeric value on the log.
	VTCompensable
)

func (ValueType) String

func (t ValueType) String() string

type VarKind

type VarKind uint8

VarKind tags the FEEL values Atlas persists for a variable: the scalars, plus VarJSON for the structured values (objects and arrays) an author or a script produces.

const (
	VarNull   VarKind = iota // no value
	VarBool                  // Bool is meaningful
	VarNumber                // Text is the canonical decimal string
	VarString                // Text is the string contents
	// VarJSON is a structured value (object or array). Text is its canonical
	// JSON encoding; it is re-parsed into a FEEL context/list when bound into an
	// evaluation. Kept as text so the durable record format is unchanged — a new
	// kind byte over the same length-prefixed Text (ADR-0009, ADR-0037).
	VarJSON
)

type VariableAuditValue

type VariableAuditValue struct {
	ProcessInstanceKey uint64 // owning instance (the scope this record is keyed under)
	ScopeKey           uint64 // the scope the variable was written to (root or a sub-scope)
	Actor              string // who performed the override; "" when auth is off / unidentified
	Name               string // the variable that was set
	Kind               VarKind
	Bool               bool
	Text               string // number canonical string, string contents, or canonical JSON; empty otherwise
}

VariableAuditValue records one external variable override for audit (ADR-0098): who set which variable, to what value, on which scope. It is keyed under its owning ProcessInstanceKey as append-only history — one record per variable an operator sets — so the "who changed it" trail folds into the same instance timeline as the variable snapshot at the same log position, and survives the instance finishing. Actor is the acting principal's username, or "" when auth is off (single-user) or the caller is unidentified. Name/Kind/Bool/Text mirror the VariableValue that was written, so the audit row is self-contained. Like a variable it carries genuine runtime data, so its encoding is length-prefixed.

func (*VariableAuditValue) ValueType

func (*VariableAuditValue) ValueType() ValueType

type VariableValue

type VariableValue struct {
	ScopeKey uint64 // owning scope (process instance key today)
	Name     string
	Kind     VarKind
	Bool     bool
	Text     string // number canonical string or string contents; empty otherwise
}

VariableValue is a process variable: a named value owned by a scope (the process instance root for now). Unlike the graph-derived payloads, a variable carries genuine runtime data (its name and contents), so its encoding is length-prefixed rather than fixed-size.

func (*VariableValue) ValueType

func (*VariableValue) ValueType() ValueType

Jump to

Keyboard shortcuts

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