State engine
The state engine (@carbon/state) is what makes a Carbon runtime
stateful rather than a mock. Every request routes through it, every
mutation lands in an in-memory resource store, and every write is
appended to a journal so you can walk history without replaying traffic.
Snapshots
Section titled “Snapshots”A snapshot is the entire state of the runtime — every resource, every counter, every relationship — serialized to a stable JSON shape. They travel with your code.
# Grab the runtime's current statecarbon snapshot save baseline
# Restore it later (same shell, another shell, CI job)carbon snapshot load baseline
# List and deletecarbon snapshot listcarbon snapshot delete baseline
# Push/pull to the shared control plane (Team+)carbon snapshot push baselinecarbon snapshot pull baselineLocally, snapshots live in .carbon/snapshots/*.json. Commit them.
CI restores them at the start of the run so every test starts from the
same known baseline.
From the SDK:
const snap = await replica.snapshot.save('after-refund');await replica.snapshot.restore(snap);The journal
Section titled “The journal”Every write goes through an append-only journal. The journal is what lets Carbon do more than snapshot-and-restore:
- Rewind. Roll state back to any journal position without replaying traffic.
- Forward. Re-apply journal entries after a rewind to test hypotheticals.
- Diff. Compare two positions and see which resources moved.
Fixtures
Section titled “Fixtures”A fixture is a snapshot that boots with the runtime. Point the runtime at a starting fixture and every request begins from that state instead of empty stores.
await carbon.emulate({ from: './spec.yaml', fixture: './fixtures/seed.json' });Record & replay
Section titled “Record & replay”Recordings are the traffic-side counterpart to snapshots: instead of
freezing state, they freeze the requests that produced state. The
proxy in @carbon/proxy captures every exchange (method, URL, request
and response bodies, redacted headers) and writes it to
projects/{slug}/recordings/{id}.jsonl in the control-plane storage.
# Capture traffic while pointing your app at the proxycarbon record https://api.example.com --port 8788The dashboard’s Recordings section reads that storage prefix and surfaces one row per capture — request count, first/last timestamp, upstream origin, and size — computed by parsing each stored recording. Clicking a row expands its exchanges inline; clicking Replay runs each captured request against a URL you supply and shows per-exchange diff results (status mismatch, body shape mismatch, or connectivity error).
Under the hood:
GET /v1/projects/:slug/recordings— list recordings.GET /v1/projects/:slug/recordings/:id/exchanges— dump the captured exchanges.POST /v1/projects/:slug/recordings/:id/replay— replay against a target and persist arecording_replaysrow so the history survives page reloads.
The carbon replay <recording> --target <url> CLI runs the same
comparison locally when you don’t want to go through the control
plane.
Runtime endpoints
Section titled “Runtime endpoints”The state engine is reachable over HTTP too, so anything that speaks
fetch can drive it:
POST /__carbon/state/snapshot → { snapshot: {...} }POST /__carbon/state/restore ← { snapshot: {...} }