Sandbox model
How forks work, what they cost, where the clinician commit boundary lives, and what the v1 mock simulates.
Updated May 28, 2026
The Nyra sandbox is a session-scoped fork of a patient graph. Every write an agent makes (drafts, simulations, candidate plans) lives in the fork. Nothing in the fork reaches the live patient record until a licensed clinician promotes it. The boundary is at the auth layer, not at the prompt layer.
What you can fork
const sb = await client.forkSandbox(patientId, "ideation-pass");
sb.id; // "sb_..."
sb.patientId; // back-reference to the live patient
sb.forkedFromAuditRef; // the live-graph audit event the fork branched from
sb = await client.fork_sandbox(patient_id, label="ideation-pass")
A fork carries the live graph at forkedFromAuditRef. Subsequent reads on the fork return the projection that was in place at that time. The fork is yours for the session.
Three write surfaces, all sandbox-only from the SDK
| Surface | Lives in fork | Reaches live record without clinician commit |
|---|---|---|
sandbox.fork | yes | no |
simulation.run | yes | no |
draft.create | yes | no |
| (anything else) | - | not exposed by the SDK |
There is no commit.run tool. There is no admin override. The marketing spec calls this out: "Clinician commits. Never the agent." The SDK's CommitNotAllowedError is the runtime expression of that promise.
Simulation modes
simulation.run accepts three modes:
forecast. Predict a trajectory N days out under a proposed plan. Returns a transcript and a confidence band.rehearse. Walk a single clinician-facing scenario against a graph-grounded surrogate. Clinician-only in production; the SDK surfaces it for agents that draft rehearsal material.compare. Side-by-side delta across two or more candidate plans. Returns a confidence band per variant.
All three modes write to the sandbox subgraph. None of them autonomously enter the live record. The audit log captures the entire simulation history.
v0.1.0 status
v0.1.0 ships the contract for sandbox.fork, simulation.run, and draft.create as typed methods on NyraClient and as function-call schemas your LLM can emit. There is no backing surrogate yet, so calling any of them through HttpTransport raises NotLiveYetError. The shapes are committed; when the auth server and surrogate land, only the bodies change. No client-side code rewrite required.
Drafts vs. simulations vs. forks
A fork is the container. A simulation is a forward-looking probe inside the fork. A draft is a structured proposal (note, plan, follow-up) inside the fork. A fork can hold many simulations and many drafts. The clinician's commit selects one draft per surface and promotes it.
What costs what
The marketing spec prices on simulation-seconds; reads are free. v1 has no metering surface (the auth server is not live), but the SDK's transport interface exposes the call points where a future client will report usage back to the audit log. No accounting code lives in your agent.
Next: Audit + rate limits.