Simulation

Simulated time

Simulated time

Simulation evaluates the resident model repeatedly over a hypothetical clock. It is separate from ledger time: a direct time-lane run is recorded as one replayable ledger event, while its internal steps do not create revisions or modify ordinary binding values.

Use STOCK(initial, net_flow) for integrated state, PREV(tracked, initial) for a one-step memory, and DELAY(tracked, lag_steps, initial) for a fixed history. SIM_TIME() and SIM_STEP() expose the current clock position. Outside a simulation resolve, state functions return their initializer and the clock functions return #N/A, so adding simulation formulas does not alter a point-estimate resolve.

{
  "simulation": { "t0": 0, "dt": 1, "steps": 52, "timeUnit": "week" }
}

Persisted clock defaults can be overridden per request. scenarioInputs apply only to that run. Euler is the default integrator; RK4 is available when every state is a STOCK and is rejected for models mixing discrete PREV/DELAY state. A materialize.frame request returns an immutable model-local frame with column t and one column per requested output.

Every run has a stable runId and records its normalized request plus result digest in model history. Simulation requests enforce configured step, sample, event, population, and wall-time limits.

The same simulation surface supports seeded Monte Carlo fan charts, parameter-matrix experiments and calibration, queue/process models, and spatial-agent playback. Each experiment row has a stable run ID in its persisted experiment record. The host also attempts a temporal replay entry, but that append is best-effort; replay is available only when the entry exists, and neither record is a generic governed artifact. See the executable model-time warehouse example for a complete portable model.

Experiment parameter, scenario-input and requested-output cell addresses use the same public coordinates as ordinary model edits. A1 and R1C1 addresses are bound once when the experiment is created and retained as explicit cell_<id> identities in results and replay. Named outputs and explicitly supplied cell IDs keep their identities; experiment runs do not mutate the base model inputs.

For a completed successful simulate experiment row, the read-only GET /api/models/:id/experiments/:eid/runs/:runId/trajectory query can replay the stored admitted configuration without accepting new inputs or overrides. New experiments capture a bounded canonical effective-input snapshot, compiled-model fingerprint, semantic executor identity, and an exact private compiled-model sidecar; each successful row retains a digest of its complete canonical simulation result. The host size/digest-verifies those experiment-owned bytes, evaluates in a fresh isolated session, and requires both the full-result digest and stored summary to match. Legacy rows without that evidence or owned bytes fail as unverifiable. Public disconnect and private-RPC deadlines cooperatively interrupt bounded native simulation work through the facade's reserved control connection; the native HTTP pool enforces the two-worker minimum required for that request to arrive concurrently. The response contains the complete simulation trajectory but is capped at 64 MiB; the Experiments surface renders no more than 500 evenly sampled points while retaining that complete response. Discrete-event, spatial-agent, active, and failed rows are not eligible. This query changes no model or experiment state and creates no Frame, artifact, evidence, approval, graduation, or release.

Model-scoped POST /api/models/:id/calibrate returns an ephemeral final optimum and counts. It publishes nothing. A deliberate POST /api/models/:id/calibration/evidence action reruns the same bounded solver against one exact resident model revision and pins the request, result, optimizer identity, and a bounded/hash-complete evaluation trace as grid.simulation.calibration-evidence.v1. That artifact is evidence input; it does not approve, promote, or release the model. Formula-context CALIBRATE still has no Solver Sim evaluator.

See the function catalog for signatures and rules-and-schedules.md for wall-clock reactions.