Agent Snapshot

Drain → snapshot in-flight state; restart → restore + resume. The last substrate slice: makes the orchestrator + idempotency + stream + event-bus + tenant + saga + posture-chain + trace stack operationally durable across deploys + crashes.

Snapshot captures (registry of agents, in-flight streams' last- seen cursors, half-completed saga state, pending event-bus deliveries, idempotency cache hot-subset). Restore re-elects shards, replays buffered events (composes v0.9.22 idempotency to prevent double-execute), resumes sagas from their persisted step pointer.

var snapshot = b.agent.snapshot.create({
  orchestrator: orch,
  backend:      operatorBackend,         // { put, get, list, delete }
  audit:        b.audit,
  policy: {
    drainTimeoutMs:     C.TIME.minutes(2),
    snapshotIntervalMs: C.TIME.minutes(5),
    maxSnapshotBytes:   C.BYTES.mib(50),
  },
});

// At SIGTERM:
await orch.drain({});
var snap = await snapshot.takeSnapshot();
await snapshot.persist(snap);

// At restart:
var loaded = await snapshot.loadLatest();
if (loaded) await snapshot.restore(loaded);

b.agent.snapshot.create(opts) #

stable0.9.30
{
  orchestrator: b.agent.orchestrator,    // required
  backend:      { put, get, list, delete },  // required
  audit:        b.audit namespace,             // optional
  policy:       { drainTimeoutMs, snapshotIntervalMs, maxSnapshotBytes },
}

Create the snapshot facade. Operator wires the durable storage backend; framework owns the envelope shape + drain/restore coordination.

var snapshot = b.agent.snapshot.create({
  orchestrator: orch, backend: myBackend,
});
var snap = await snapshot.takeSnapshot();
await snapshot.persist(snap);

b.agent.snapshot.reseal(opts) #

stable0.14.12
{
  backend:     { put, get, list },  // the same backend create() was wired with
  oldRootJson: string,              // b.vault.getKeysJson() of the OLD keypair
  newRootJson: string,              // b.vault.getKeysJson() of the NEW keypair
}

Re-seal every persisted snapshot envelope from the OLD vault root to the NEW vault root under the SAME column-shaped AAD, for a vault-key rotation. The snapshot seal is a vault.aad: ciphertext hidden behind the snap-sealed-v1: wrapper prefix and written to an operator backend, so a db.enc scan for the bare vault.aad: prefix can neither detect nor reach it — the rotation pipeline drives the re-key through this explicit backend walk. Each row is unsealed under the old root and re-sealed under the new root in memory (composing b.vault.aad.resealRoot); the plaintext envelope is never written to operator-readable storage. The decorative wrapper fields the backend's list() filters on (snapshotId / takenAt / tenantId) are preserved, so the index is untouched.

allowPlaintext envelopes (no sealed wrapper) carry no AAD-sealed blob to re-key and are skipped; the returned resealed count reflects only re-sealed rows. A row sealed by a non-default KMS sealer (the inner blob is not a vault.aad: value) is refused — re-key it through the operator's own KMS, not this path.

var result = await b.agent.snapshot.reseal({
  backend:     operatorBackend,
  oldRootJson: oldKeysJson,
  newRootJson: newKeysJson,
});
result.table;      // → "agent.snapshot"
result.resealed;   // → 

Last updated 2026-08-08T16:39:49.652Z by seeder.