Architecture
RustAG is a dual-layer system. The Ingest layer resolves every account a proposed transaction will touch. The Sealed Rehearsal layer executes it in isolation, diffs the state, fires invariant alarms, and signs the result as a cryptographic EvidenceBundle.
Architecture overview
The core design principle: the rehearser must be independently verifiable. That means the input (pre-state closure) must be content-addressable from public mainnet data, and the output (EvidenceBundle) must be byte-for-byte reproducible by anyone who runs the same closure through the same payload.
RustAG achieves this by splitting responsibility into two layers that share no mutable state with each other.
Ingest layer
The ingest layer's job is to resolve the exact set of accounts the proposed payload will read or write — called the touch set. It never executes anything; it only reads mainnet.
- SquadsDecoder — Borsh-decodes a multisig
VaultTransactionfrom its on-chain proposal address. - TouchSetResolver — static analysis walk of instruction account metas to produce the minimal pubkey set.
- MultiRpcFetcher — batches
getMultipleAccountscalls (≤100 keys per call) over raw reqwest withoutsolana-rpc-client— this keeps EVM sandbox 0.12 dep compatibility. - ForwardRecorder — optional corpus recorder that serializes the resolved closure to disk for CI replay.
Sealed rehearsal layer
The rehearsal layer receives the sealed closure (pubkey → AccountData snapshot at a known slot). It runs a deterministic two-pass process and produces a signed artifact:
- Pass 1 — Pre-state root: load the closure into an isolated EVM sandbox instance, SHA-256 hash every account in pubkey order →
pre_state_root. - Pass 2 — Execute + diff: execute the payload, capture post-state, run
SemanticDiff(11 change types) andInvariantPolicy(6 alarm rules), derivepost_state_root, assignFidelityGrade. - Signing: Ed25519-sign the concatenation of pre_state_root + post_state_root + semantic_diff + alarms + grade → write
EvidenceBundle.jsonand portableclosure.json.
End-to-end data flow
Wallet / multisig UI / Multisig signer / CI pipeline │ POST /api/rehearse { proposal | payload } ▼┌─────────────────────────────────────────────────────────┐│ INGEST LAYER ││ SquadsDecoder — Borsh-decode VaultTransaction ││ TouchSetResolver — walk instruction accounts ││ MultiRpcFetcher — getMultipleAccounts (≤100/call) ││ ForwardRecorder — record traffic corpus │└─────────────────────────────────────────────────────────┘ │ sealed pre-state closure (pubkey → AccountData) ▼┌─────────────────────────────────────────────────────────┐│ SEALED REHEARSAL (rustag-rehearse) ││ Pass 1 (Pre-state) ││ • load closure into isolated EVM sandbox instance ││ • content-hash every account → pre_state_root ││ Pass 2 (Execution) ││ • execute payload → capture post-state ││ • SemanticDiff — 11 change types ││ • InvariantPolicy — 6 alarm rules ││ • FidelityGrade — Grade A / Grade B ││ Signing ││ • Ed25519 sign over pre+post root + diff + alarms ││ → EvidenceBundle.json + closure.json │└─────────────────────────────────────────────────────────┘ │ signed EvidenceBundle ▼ Signer review / offline verify / CI gate / registryCrate map
RustAG is a Cargo workspace under crates/. The core dependency direction is rustag-cli → rustag-rpc → rustag-rehearse → rustag-sim + rustag-attest → rustag-mirror → rustag-core. Every Phase 2/3 crate is pure Rust with no external service dependency.
| Crate | Responsibility | Phase |
|---|---|---|
| rustag-rehearse | Sealed two-pass rehearsal engine: PortableBundle, EvidenceBundle, FidelityGrade (A/B). The core GroundTruth primitive. | 1 |
| rustag-mirror | Ingest layer: TouchSetResolver, SquadsDecoder, MultiRpcFetcher (≤100 keys/call, no solana-rpc-client), ForwardRecorder corpus builder. | 1 · realtime 2 |
| rustag-sim | SemanticDiff (11 change types), InvariantPolicy (6 alarm rules), fuzzing, exploit scanning, differential execution. | 1 / 2 |
| rustag-attest | Ed25519 signing, Merkle state_root, offline verify, EvidenceBundle wrapper, hash-chained AuditLog. | 1 / 3 |
| rustag-core | Persistent EVM stagenet runtime: EVM sandbox + AccountSync state machine (Unknown→Clean→Dirty→Pinned) + SQLite via sqlx. | 1 |
| rustag-rpc | axum server: POST /api/rehearse, POST /api/verify, Robinhood Chain-compatible JSON-RPC, WebSocket, REST API. | 1 |
| rustag-cli | The rustag binary: rehearse, verify, forensics, record, serve, and full stagenet management surface. | 1 + 2/3 |
| rustag-scheduler | Activity Scheduler: @every / cron actions (airdrop / transfer / raw-tx) for the stagenet dev-tool surface. | 2 |
| rustag-cloud | Multi-tenant control plane: isolated child processes behind a reverse proxy with Bearer rk_… API-key auth. | 2 |
| rustag-replay | Time-travel: content-addressed Checkpoint, deterministic Journal replay, Timeline diffs, fork-of-fork Lineage. | 3 |
| rustag-compression | Off-chain spl-account-compression-compatible ConcurrentMerkleTree (keccak-256, changelog, root-history, canopy). | 3 |
| packages/sdk | @rustag/sdk — TypeScript client for POST /api/rehearse, POST /api/verify, and the full REST surface. | 1 |
Phase 2 & 3
The invariant across all phases: the pre-state closure is always sealed before execution and never mutated after. Every Phase 2/3 extension is additive — it does not change how Phase 1 bundles are produced or verified.
Phase 2 features Phase 2 · Preview
- Yellowstone gRPC recording — real-time traffic corpus from a Geyser stream; replaces
ForwardRecorder's poll-based approach with a push source for sub-second latency corpus building. - Evidence Registry — hosted, append-only store for signed bundles with N-of-M signer provenance. A multisig vault can require M-of-N reviewers to submit a valid Grade A bundle before a proposal can be approved.
- multisig web UI embed — a signer-review panel that fetches and renders the EvidenceBundle inline in the multisig proposal UI, without requiring any CLI.
- Activity Scheduler — recurring on-chain actions for the stagenet dev surface (
@every / cron). - Real-time mirror push —
accountSubscribeWebSocket / Yellowstone gRPC → oracle prices under 2s staleness. - Cloud control plane (
rustag-cloud) — multi-tenant hosted rehearsal service withBearer rk_…API-key auth.
// A sample of the SemanticChange variants produced by SemanticDiffSemanticChange::LamportsDrained { from, to, delta }SemanticChange::UpgradeAuthority { from, to } // CRITICAL alarmSemanticChange::ProgramUpgraded { pubkey, old_hash, new_hash }SemanticChange::TokenAuthorityChanged { mint, from, to }SemanticChange::AccountClosed { pubkey, recovered_lamports }SemanticChange::DataWritten { pubkey, len }// + 5 more: Created, Frozen, Thawed, NonceDerived, SysvarMutatedPhase 3 features Phase 3 · Experimental
- Per-flow pricing & quota — usage-metered rehearsal API with tiered plans (free / pro / enterprise).
- Time-travel & replay (
rustag-replay) — content-addressedCheckpoints, deterministicJournalreplay,Timelinediffs, and fork-of-forkLineage. - Adversarial simulation (
rustag-sim) — atomic MEV-style bundles with tip accounting, deterministic invariant fuzzing, and a reproducible exploit-signature scanner. - State / ZK compression testing (
rustag-compression) — a keccak-256ConcurrentMerkleTreematchingspl-account-compressionso compressed-state programs verify deterministically off-chain.