Documentation Index
Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt
Use this file to discover all available pages before exploring further.
RMAT: Rust Machine Authority Theory
This document defines the authority model Meerkat uses for canonical state machines. The short version:- canonical semantic truth must come from machine definitions
- generated machine authority code must be the only place allowed to mutate canonical state
- handwritten code may capture evidence, route, persist, schedule, and execute effects
- handwritten code may not invent parallel semantic state or handwritten reducers
- semantically meaningful async seams must be modeled and closed through the formal composition layer, not left to shell folklore
Core Rule
For any canonical domain, there must be exactly one answer to:What state is this in, what transitions are legal, and what state change happens next?That answer must be:
- the machine definition in
meerkat-machine-schema - executed through generated authority code in
meerkat-machine-kernels
What Counts As Canonical Truth
Canonical truth includes:- lifecycle phase/state
- legality of transitions
- terminal outcomes
- rollback/requeue/consume semantics
- orchestration decisions that change semantic state
- any state mutation that changes what the system is, not merely how effects are delivered
What Handwritten Code May Still Do
Handwritten shell code is allowed to:- classify raw inputs into typed machine inputs when that classification is already constrained by machine or protocol truth
- route inputs to the right machine owner
- schedule and execute effects
- manage channels, tasks, notifiers, and completion waiters
- persist and load state snapshots
- perform transport, IO, and adapter work
- decide transition legality
- mutate canonical semantic state directly
- implement alternate reducers in parallel
- invent duplicate semantic enums/status models
- hide transition-relevant truth in side maps/booleans that the machine does not own
- choose ad hoc semantic feedback for a machine-owned async seam
- invent surfaced terminal classification branches that diverge from machine terminal truth
Seams And Handoffs
Single-machine sealed mutators are necessary, but they are not the whole story. Meerkat also has semantic seams between:- a machine and owner-realized async work
- a machine phase and the associated wait-set or obligation that gives that phase meaning
- a machine terminal outcome and the surfaced result/error classification
- composition actors that may be
MachineorOwner - effect handoff protocols attached to existing effect-disposition rules
- outstanding-obligation validation in closed-world compositions
- generated seam helper APIs for owner feedback
- generated terminal classification derived from machine truth
Enforcement Model
The enforcement mechanism must be compile-time, not convention. For each canonical machine, generated code should own:- canonical machine state
- canonical machine input/event types
- canonical machine effect types
- a sealed mutator trait
- the only implementation of that trait
- hold machine-owned state
- call the generated mutator
- execute returned effects
- create a second semantic mutation path
- directly set canonical phases
- implement a shadow reducer
Transient vs Persistent Canonical State
Not all canonical states have to be persisted. Example:Attached is canonical runtime state while a runtime is alive and
listening, but it may be intentionally persisted as Idle and re-derived on
recovery.
That is valid if:
- the machine defines
Attachedas a real state - the shell observes lifecycle facts such as executor/task/channel existence
- the shell re-enters the transient state by calling a generated machine input
such as
AttachExecutor
- what states exist
- what transitions are legal
The “When To Call” Boundary
The shell does decide when to call the machine. Example:- raw inbox item arrives
- shell classifies it as peer message / silent intent / lifecycle notice
- shell calls the corresponding machine input
- classification is shell work
- classified outputs must become typed machine inputs
Composition Authority
Single-machine sealed mutators solve local authority, not full composed authority. Some canonical truth is emergent across multiple machines, for example:- runtime control
- runtime ingress
- input lifecycle
- turn execution
- single-machine authority is enforced by generated mutators
- cross-machine invariants are still enforced by:
- composition definitions
- composition witnesses
- TLC / model checking
- integration and owner tests
- transport disposition still stays inside
Local,External, orRouted - an effect may additionally declare a handoff protocol when owner realization and later feedback are semantically meaningful
- compositions then prove structural coverage and safety for those obligations, plus scoped liveness only where explicitly modeled
Proof Classes
Every important RMAT claim should be labeled explicitly:- Structural coverage: the seam is named, protocolized, and wired
- Safety: no invalid seam state or transition is reachable
- Liveness: under explicit fairness assumptions, required feedback eventually arrives
- structural coverage for all owner handoffs (protocol exists, realization sites declared, feedback constrained to generated helpers)
- safety for comms drain seam closure (obligation invariants, no shell bypass)
- safety for turn-execution barrier (barrier satisfaction gated by authority,
ToolCallsResolvedrequiresbarrier_satisfied == true) - safety for terminal outcome alignment (exhaustive generated classifier, no default arm)
- one explicit liveness claim for comms drain feedback closure (spawn protocol under task-scheduling fairness)
- cross-machine barrier composition (OpsLifecycle
WaitAllSatisfiedrouted to TurnExecutionOpsBarrierSatisfiedthrough declared handoff protocol)
Shell vs Authority Boundary
Generated authority owns:- semantic state
- legal transitions
- semantic outcomes
- transition-produced effects
- task lifetime
- channels
- async waiting
- persistence adapters
- effect execution
- transport plumbing
- shell may notice that a task exited or a wait completed
- shell may not choose an arbitrary semantic exit reason or closure class
- shell may assemble result payload data
- shell may not invent terminal classification outside generated machine-derived helpers
Forbidden Patterns
For canonical domains, these are bugs:- handwritten reducer/helper methods that decide transitions
- extra semantic booleans/maps/status fields outside machine-owned state
- duplicate lifecycle enums/status structs outside the generated authority
- replay or recovery that depends on hidden shell-local semantic truth
- docs/contracts that claim generated ownership while handwritten code still owns semantics
Practical Test
For any canonical domain, ask:If I removed the handwritten shell code, would I lose semantic truth?If the answer is yes, then machine authority is not complete.
Proving Ground
The best proving ground for this model is the ugliest handwritten owner first, not the easiest.FlowRunMachine is the best stress test because it forces the authority model
to handle:
- dependency resolution
- quorum and branch winner selection
- retry/failure policy
- in-flight bookkeeping
- durable replay implications
flow.rs, it will likely survive the
rest of the platform. If it fails there, we learn whether:
- the schema language needs richer guards/effects
- the kernel API shape needs to grow
- or the approach has real limits
Adding a New Handoff Protocol
When adding a new async boundary that crosses an ownership seam:-
Annotate the effect — set
handoff_protocol: Some("protocol_name")on theEffectDispositionRulein the machine catalog file. -
Declare the protocol — add an
EffectHandoffProtocolto every composition that includes the producing machine. Specify the realizing actor, allowed feedback inputs, correlation fields, and closure policy. -
Run schema validation —
./scripts/repo-cargo nextest run -p meerkat-machine-schemacatches missing protocols in closed-world compositions. -
Generate protocol helpers —
./scripts/repo-cargo run -p xtask -- protocol-codegencreates typed feedback submitters and (forTerminalClosureprotocols) terminal classification helpers. -
Wire the shell — replace handwritten feedback submission with calls to the
generated protocol helpers. Generated code carries
// @generatedmarkers. -
Run the RMAT audit —
./scripts/repo-cargo run -p xtask -- rmat-audit --strictcatches:- effects with
handoff_protocolbut no matching composition protocol - protocols without generated helper files
- feedback submitted outside generated helpers
- terminal classification without generated classifiers
--update-baseline. The baseline lives atxtask/rmat-baseline.toml. - effects with
- Add composition witnesses — witnesses exercise the handoff path and verify that the protocol’s feedback inputs are reachable.
CI Enforcement
make ci runs rmat-audit --strict as a hard gate. New handoff-annotated effects
without protocols, protocol feedback outside generated helpers, and terminal
classification outside generated classifiers all fail the build unless baselined.
Read-seam violations — shell code that reads canonical authority state or
declares shadow-state counters — are caught by the ForbiddenShellAuthorityReads
AST rule inside rmat-audit. Policy entries in xtask/src/rmat_policy.rs bind
each rule to a file path and an AST pattern (method call, field declaration, or
field access). Exceptions must be annotated inline:
xtask/rmat-baseline.toml) must be kept current. Stale entries
(findings in the baseline that no longer reproduce) also fail strict mode.
End State
The intended end state is:- one canonical machine authority per domain
- generated code as the only semantic mutator
- handwritten code reduced to shell/effect plumbing
- no parallel semantic owner path
- no second source of truth
