Expand description
Tatara-lisp host bindings + framework intrinsics for vigy.
§The host
VigyHost is the per-tick context handed to a vigy program.
It carries five buffers the program populates via intrinsics:
- actions — ReconcileActions emitted (
vigy-emitfamily) - desired — keyed declarative “what should be true”
- observed — keyed recorded “what currently is true”
- conditions — kubernetes-style health/readiness signals
- log — structured log lines
- trace — typed kv traces for the run’s audit record
- metrics — named numeric metrics for observability
- events — kubernetes-style events for tail consumers
Plus two state surfaces the runtime manages (not the program):
- tick_start_ms — readable via
(vigy-tick) - kv — persistent k/v store, hydrated at tick start,
readable + writable via
(vigy-get/set/incr), saved back to the store at tick end
§Framework verb surface
§Actions (typed ReconcileKind)
(vigy-noop) — recorded; "nothing to do"
(vigy-defer reason) — "skip this tick; try next"
(vigy-pull payload) — fetch upstream state locally
(vigy-push payload) — push local state to upstream
(vigy-create payload) — target doesn't exist; create
(vigy-update payload) — target exists; modify
(vigy-delete payload) — target should not exist
(vigy-apply payload) — idempotent "make it match"
(vigy-restart payload) — runtime stuck; restart
(vigy-emit kind payload?) — escape hatch for unusual kinds§Structured state
(vigy-desired k v) — declare what should be true
(vigy-observed k v) — record what currently is true
(vigy-condition name status — kubernetes-style condition.
reason? message?) status: "true"|"false"|"unknown"§Persistent KV (survives across ticks; per-vigy scope)
(vigy-get k default?) — read; default if absent
(vigy-set k v) — write; saved on tick end
(vigy-incr k delta) — atomic numeric increment
(vigy-has? k) — presence check
(vigy-del k) — remove§Convergence / idempotency
(vigy-once k) — true exactly once per vigy lifetime
(vigy-mark-converged k) — record permanent achievement
(vigy-converged? k) — read convergence flag§Scheduling helpers
(vigy-tick) — epoch ms of this tick's start
(vigy-tick-count) — N (Nth tick of this vigy)
(vigy-since-last-tick) — ms since previous tick
(vigy-rate-limited? k min-ms) — token-bucket gate; returns true
if k was acted on within min-ms
(vigy-backoff-ms attempt) — capped exponential (2^attempt * 1000ms, max 30s)§Diagnostics
(vigy-log level msg) — text log line
(vigy-trace k v) — typed kv on the audit record
(vigy-metric name f) — numeric metric
(vigy-event kind message) — kubernetes-style eventPlus the full tatara-lisp stdlib — arithmetic, comparison, list ops, strings, channels, fibers, higher-order helpers.
§Entry point
evaluate takes a program + a fresh host (with kv pre-loaded by
the runtime), evaluates, returns the host (now populated). The
runtime drains buffers + persists dirty kv keys.
Structs§
- Actions
Extension - Typed action verbs: vigy-noop / defer / pull / push / create / update / delete-action / apply / restart / emit.
- Chain
Reconciler - Composite reconciler — runs its children in order, threading the host through. Each child sees the buffer state the previous child wrote, so a chain can stack: “first reconciler observes from RPC, second writes a tatara-lisp policy over those observations.”
- Convergence
Extension - Convergence: vigy-once / mark-converged / converged?.
- Diagnostics
Extension - Diagnostics: vigy-log / trace / metric / event.
- Host
Event - Interpreter
Re - An embedded tatara-lisp evaluator, parameterized over the host context
Hthat registered functions read/write. - KvExtension
- Persistent KV: vigy-get / set / incr / has? / del.
- Lisp
Reconciler - The default reconciler — evaluates a tatara-lisp program with the supplied extension bundle. Constructible two ways:
- LogEntry
- Noop
Reconciler - A reconciler that does nothing. Tests + the “vigy is disabled” path use this to drive the runtime without any program. Returns the host unchanged.
- Scheduling
Extension - Scheduling: vigy-tick / tick-count / since-last-tick / rate-limited? / backoff-ms.
- Span
- A half-open byte range
[start, end)into the source. - State
Extension - Structured state: vigy-desired / observed / condition.
- Vigy
Host - Per-tick host. Programs populate buffers via intrinsics; the runtime drains them after the tick + persists dirty kv keys.
Enums§
- ArityRe
- How many arguments a registered function accepts.
- EvalErr
- Eval
Error Re - Lisp
Value Re - An evaluated runtime value.
- LogLevel
Traits§
- Host
Extension - Pluggable intrinsic pack. The framework ships six standard
extensions (
Actions,State,Kv,Convergence,Scheduling,Diagnostics) — together they formstandard_extensions(). Hosts add their own by implementing this trait and passing their impls toevaluate_with_extensionsalongside the standard set. - Reconciler
- Typed reconciler — what runs each tick. tatara-lisp evaluation is
the default implementation (
LispReconciler) but the trait lets any execution model (Rust-native, Wasm, HTTP webhook) participate in the same runtime loop.
Functions§
- closure_
extension - Construct a HostExtension from a closure. Useful for one-off host-specific intrinsics that don’t deserve their own named struct:
- evaluate
- Evaluate a vigy program against a fresh host. Convenience wrapper
over the trait-based path with the standard extension bundle —
the entrypoint vigy-runtime uses by default. Embedders that want
additional intrinsics call
evaluate_with_extensionsdirectly. - evaluate_
with_ extensions - Evaluate a program with a custom extension bundle. Hosts (mado,
tear-daemon) compose
standard_extensions()with their ownHostExtensionimpls — e.g. mado addsMadoTearExtensionthat registers(mado-tear-list-sessions)/(mado-tear-attach)intrinsics, the rest of the framework keeps working unchanged. - install_
vigy_ intrinsics - Register every vigy framework intrinsic. Kept as a free function for
the rare embedder that wants the entire bundle in one call without
touching
Box<dyn HostExtension>. Equivalent to installing thestandard_extensions()list one at a time. - standard_
extensions - The six standard extensions, in the order they install on a fresh interpreter. Order doesn’t matter today (no two extensions share an intrinsic name) but is documented for stability.
Type Aliases§
- ExtArity
- Re-exported
tatara_lisp_eval::Arity. Host extensions specify the arity of their custom intrinsics with this. - ExtEval
Error - Re-exported
tatara_lisp_eval::EvalError. Host intrinsics return this for type mismatches / runtime errors. - ExtInterpreter
- Re-exported
tatara_lisp_eval::Interpreter<VigyHost>— the second argument toHostExtension::install. - ExtValue
- Re-exported
tatara_lisp_eval::Value. Host intrinsics return this from their callable. - Extension
Handle - Shared handle for a HostExtension.
Arcchosen overBoxso the reconciler can hand its extension list to spawn_blocking without requiring every extension to beClone(some impls might hold non-cloneable resources like atonic::Channel). - Result