The two modes
sandbox (default)
Mock and staging behavior, merged. No real-world effect is possible. Guarded
actions run through per-primitive sandbox adapters (synthetic cards, paper
trades, on-box email, …) and the egress gateway refuses real credential
injection. Policy still runs — approvals still freeze — so you exercise the full
governance path with zero real consequences.
production
Live. Actions route to real rails, subject to policy, budgets, and approvals.
The only difference from sandbox is where an allowed action lands — the config
is identical.
Promote & demote
POST /v1/users/:user_id/environment { environment } flips only the kit’s
mode. The resource semantics are strict, and they are the whole point:
- Sandbox residue is never laundered. Every resource row is stamped with
the environment it was created in (
cards,email,phone,domains,trading,queues, plusapprovals, spend events, and activity). Promoting does not re-stamp anything: sandbox rows keep theirsandboxstamp forever. - Reads filter to the current mode. Listings return only rows stamped for
the operator’s current environment, so a promoted operator does not see its
sandbox junk. Pass
?environment=sandbox|production|allto override the filter explicitly. - Budgets are per-stamp. Spend is summed and reserved within the stamp’s
window, so sandbox spend never counts against a production cap (and a sandbox
over-cap
402leaves the production window untouched). - The governor refuses replay across a stamp mismatch. A frozen approval
carries the stamp of the environment it was created in; if the operator’s
current mode differs,
replay/authorizereturnsenvironment_mismatchand the row stays pending. Re-request the action in the current environment — a sandbox-approved action can never silently execute in production.
Stamps are set from the governor’s verdict (
environmentStamp() in the data
layer), never trusted from the client. The DB default is sandbox — a fail-safe.naive env
reset deletes sandbox-stamped resource rows so you can start a clean run. It
never deletes audit or trajectory events — those are retained by design (see
below).
Trajectories are the promotion evidence
Because sandbox activity is stamped and retained across promote, the sandbox run is the record you promote on.GET /v1/users/:user_id/trajectories
(filterable by ?environment= and ?since=) groups stamped activity into runs
— per approval/action chain — so you can review exactly what the agent did in
sandbox, then diff its production behavior against that baseline. Audit and
trajectories stay queryable across both stamps, always.
Everywhere the primitive appears
The same mode flows through every surface:- CLI —
naive env status | promote | reset. - Server SDK —
provision(..., { environment }),op.promote(),op.environment(). - IaC —
agent({ environment })(same config, two modes). - Panel — an environment badge on the operator with promote / demote / reset actions.
The card line
“Same config, two modes. Sandbox proves it; production ships it — and sandbox
residue is never laundered into production.”