Rules & actions

Rules are the endogenous decision channel: a Rule pairs a state-contingent guard with an ordered action program, so decisions (raise capital, acquire an asset, kill a program) live in the model rather than in host patch code. Actions are a closed, serializable family (ActionStmt subtypes) applied by apply_action!; the engine fires enabled rules each step via fire_rules!.

ReactiveDynamics.RuleType
Rule(id, guard, action; fire_mode = :every_tick, enabled = true)

The endogenous decision channel (ADR 0010 §A, CONTRACT §12) — a (guard, action, fire_mode) triple evaluated once per tick at a fixed point in _step! (step 10, via fire_rules!). guard is an Expr/literal resolving to a Bool (fire once when true) or a numeric v (fire rand(rng, Poisson(v)) times, so the RNG-threaded rate stays deterministic); action is any ActionStmt. fire_mode ∈ {:every_tick, :once} — an :once rule latches its enabled flag off after it first fires. enabled is run-state reset by _reinit! (§4 D7). Unlike a transition's stateless per-tick guard, a Rule has no bound token, so its action must be one of the population/global verbs (SetTokens, not SetField).

source
ReactiveDynamics.ActionStmtType

Abstract supertype of the closed, serializable action whitelist (ADR 0010 §C / ADR 0011, CONTRACT §12). The concrete family is {SetSpecies, SetParams, SetField, SetTokens, AddToken, Activate, Deactivate, Invoke, Log, Seq} (plus the internal RawExpr legacy bridge). An ActionStmt is a declarative, eval-free record of a state mutation; apply_action! dispatches on the concrete type to perform it, and the closed set is the trust boundary for eval-free (de)serialization. Actions are the payload of a Rule (the endogenous decision channel) or a transition post-action; Seq composes them.

source
ReactiveDynamics.SetSpeciesType
SetSpecies(name, value, mode = :set)

Action (ActionStmt) that writes a plain-species pool column of state.u: for species name, evaluate value (an Expr/literal, through the seeded closure path) and either set it (mode = :set) or increment it (mode = :inc).

source
ReactiveDynamics.SetParamsType
SetParams(assigns)

Action (ActionStmt) that writes one or more model parameters in state.p. assigns is a vector of name => value-expr pairs; each value is evaluated through the seeded closure path.

source
ReactiveDynamics.SetFieldType
SetField(field, value)

Action (ActionStmt) that writes field on the FIRING transition instance's bound token(s) (ADR 0008 §D), evaluating value in the firing context. This is a transition post-action ONLY — a standalone Rule has no bound token, so apply_action! errors on it; use SetTokens for a Rule (validated at build).

source
ReactiveDynamics.SetTokensType
SetTokens(predicate, assigns)

Action (ActionStmt) that writes assigns (field => value-expr pairs) over the token population selected by predicate — the population generalization of SetField (ADR 0011 §A). Because it carries its own predicate it is legal in a Rule. Matched tokens are iterated in the (species, creation_index) total order (§9.2), and each value is evaluated IN THE SELECTED TOKEN's context (so @field(name) reads that token's own current attribute). predicate is a TokenPredicate (ADR 0008); a (kind, clauses) tuple form is also accepted.

source
ReactiveDynamics.AddTokenType
AddToken(kind, fields)

Action (ActionStmt) that creates a structured token of a registry-registered kind (ADR 0006 §C) — the acquisition lever. fields is a vector of name => value-expr pairs; the values are evaluated, passed to the kind's registered constructor, and the new token is entangled into the network's structured container.

source
ReactiveDynamics.ActivateType
Activate(transition)

Action (ActionStmt) that soft-activates a transition line (ADR 0004 soft gate) by setting its latching transActivated flag true. transition is matched by transName/transHash. Lowers to activate!.

source
ReactiveDynamics.DeactivateType
Deactivate(transition)

Action (ActionStmt) that soft-deactivates a transition line (ADR 0004 soft gate) by clearing its latching transActivated flag. transition is matched by transName/transHash. Lowers to deactivate!.

source
ReactiveDynamics.InvokeType
Invoke(fn, args = Any[])

Action (ActionStmt) — the general-code escape hatch (ADR 0011 §B). Lowers to registry[fn](state, transition, args…): the serialized action carries only the NAME fn, resolved against the per-network host-function registry (never eval'd); the body is trusted host Julia bound by obligations O1–O4. args value-exprs are evaluated before the call; the result is discarded.

source
ReactiveDynamics.LogType
Log(msg)

Action (ActionStmt) that appends msg to the state log (via log). If msg is an Expr/Symbol it is evaluated in context first, otherwise it is logged as-is.

source
ReactiveDynamics.SeqType
Seq(stmts)

Action (ActionStmt) that composes a vector of ActionStmts, applied in order. The composite that lets one Rule or transition post-action perform several mutations.

source
ReactiveDynamics.apply_action!Function
apply_action!(state, transition, a::ActionStmt)

Perform the action a against state, dispatching on the concrete ActionStmt type — the eval-free lowering table for the closed action family (ADR 0010 §C / ADR 0011 §C). transition is the firing transition instance for a transition post-action, or nothing when the action comes from a Rule; it carries through to the seeded-closure value eval (params/observables/time/Sample). SetField requires a non-nothing transition (it writes bound tokens); AddToken/Invoke resolve their name against the per-network registry and never eval. Seq applies its statements in order.

source
ReactiveDynamics.fire_rules!Function
fire_rules!(state)

Evaluate every enabled Rule in state.rules once, in order — the endogenous decision channel, invoked at _step! step 10 (ADR 0010 §A/§D). For each rule, the guard is evaluated (nothing transition context): a Bool fires the action 0/1 times, a numeric v fires it rand(state.rng, Poisson(v)) times (RNG-threaded for determinism). A :once rule that fired latches its enabled flag off (reset by _reinit!, §4 D7). Returns state.

source
ReactiveDynamics.activate!Function
activate!(state, t::Symbol)

Soft-activate the transition line named t (matched by transName/transHash) on a live state, by setting its latching transActivated gate true (ADR 0004 soft gate). Errors if no transition matches. The imperative twin of the Activate action.

source
ReactiveDynamics.deactivate!Function
deactivate!(state, t::Symbol)

Soft-deactivate the transition line named t (matched by transName/transHash) on a live state, by clearing its latching transActivated gate (ADR 0004 soft gate). Errors if no transition matches. The imperative twin of the Deactivate action.

source
ReactiveDynamics.set_guard!Function
set_guard!(state, t::Symbol, guard)

Attach a stateless per-tick guard to the transition named t (ADR 0010 §B). guard is an Expr/literal (e.g. :(cash >= phase3_cost)) compiled to the seeded closure and AND-ed with the latching transActivated gate in sample_transitions! — a transition whose guard evaluates false makes no genesis proposal that tick. Errors if no transition matches.

source

Per-program ledger

Cost/reward/valuation actions accumulate into a per-program ledger — the model's accounting side. These read the ledger a finished (or in-progress) run has built up.

ReactiveDynamics.ProgramLedgerType
ProgramLedger(species, creation_index)

Per-program (per-structured-token) ledger accumulator (CONTRACT §12, MVP finding D — the attribution logic lives in src/ledger.jl). Tracks one structured token's running economics: cost_incurred (capital burned on its behalf), reward_realized (reward credited when a transition it was bound to finished successfully), valuation (current mark-to-market), and entries — the append-only (t, kind, amount, transition_name) audit trail. species/creation_index identify the program. Per-program rows plus the state's unattributed_cost/unattributed_reward buckets sum exactly to the aggregate ledger rows.

source
ReactiveDynamics.program_ledgerFunction
program_ledger(state) -> DataFrame

Per-program (per-structured-token) cost/reward/valuation summary for a finished (or in-progress) run, in the deterministic (species, creation_index) token order (§4 D4) — the engine-level replacement for the BD demo's post-hoc reconstruction (MVP finding D). Columns:

program the token's stable network identity (AlgebraicAgents.getname) species the token's CURRENT species/kind (:removed if soft-retired) creation_index the per-species monotonic creation index (ADR 0006 §E) — the order key cost_incurred total capital burned on behalf of this program (sum of its bind-cost shares) reward_realized total reward credited when a transition it was bound to finished successfully valuation current mark-to-market = the species' specValuation (0 when none — see header) net rewardrealized − costincurred (the realized economics to date)

The per-program cost_incurred summed over ALL programs PLUS state.unattributed_cost equals the sum of the aggregate :valuation_cost rows (likewise reward). Pass the live state; only the structured tokens that have ever existed appear.

source
ReactiveDynamics.program_ledger_entriesFunction
program_ledger_entries(state, token_name) -> Vector{Tuple{Float64,Symbol,Float64,String}}

The append-only per-event audit trail for one program: (t, kind, amount, transition_name) rows (kind ∈ (:cost, :reward)), in attribution order. Empty for an unknown/never-bound program.

source