✓
Same input ⇒ same output. Two engine runs on the same (spec, bars)
produce m1.model_dump() == m2.model_dump() bit-for-bit. No
time.time() in the engine. No thread-local randomness.
✓
Same record ⇒ same input. Each RunRecord carries
spec_hash = sha256(StrategySpec.json)[:16]. The audit story is:
load the spec from the DB, re-run, check metrics match.
✓
Stable run_id. run_id = sha1(sweep_id, sorted(cell_params))[:16].
The pre-write of PENDING and the post-execution upsert target the same row.
A crash mid-sweep leaves a recoverable state, never a duplicated one.
✓
Forbid extra fields. Pydantic extra='forbid' on every
schema. The LLM cannot inject a field that "looks like it should work" and have
it silently propagate downstream.