This tutorial walks through a disciplined loop for evolving calculator behavior from basic arithmetic to scientific coverage.
- keep measurement trustworthy,
- improve capability breadth,
- avoid regressions while adding new behavior.
- repository set up (
mise, Ruby deps), - working knowledge of
docs/simulation-readiness.md, - provider key set for live-shadow steps.
Run core deterministic pack:
cd runtimes/ruby
mise exec -- ruby bin/recurgent-sim \
--pack ../../specs/contract/v1/simulation/scenario-packs/calculator-core-v1.yaml \
--mode fixture \
--fixture-root ../../tmp/simulation/fixtures \
--ledger-path ../../tmp/simulation/run-ledger.jsonl \
> ../../tmp/simulation/calculator-core-fixture.json
mise exec -- ruby bin/recurgent-sim \
--pack ../../specs/contract/v1/simulation/scenario-packs/calculator-core-v1.yaml \
--mode replay \
--fixture-root ../../tmp/simulation/fixtures \
--ledger-path ../../tmp/simulation/run-ledger.jsonl \
> ../../tmp/simulation/calculator-core-replay.jsonInspect gate snapshot:
jq '{g0:.gates.G0.status,g1:.gates.G1.status,g2:.gates.G2.status,score:.score_vector}' \
../../tmp/simulation/calculator-core-replay.jsonExpected:
G0=pass,G1=passon stable replay,G2may start as advisory until comparable replay exists.
Create an experiment pack by extending calculator coverage (example: trig). Start from existing class-1 pack and add new scripted oracle steps.
cp ../../specs/contract/v1/simulation/scenario-packs/calculator-core-v1.yaml \
../../tmp/simulation/calculator-scientific-experiment-v1.yamlEdit ../../tmp/simulation/calculator-scientific-experiment-v1.yaml and add scenario expectations like:
oracles:
- id: trig-sin-0
expect:
equals: 0.0
tolerance: 0.0001Keep each new oracle narrow and measurable.
Run fixture/replay on experiment pack:
mise exec -- ruby bin/recurgent-sim \
--pack ../../tmp/simulation/calculator-scientific-experiment-v1.yaml \
--mode fixture \
--fixture-root ../../tmp/simulation/fixtures \
--ledger-path ../../tmp/simulation/run-ledger.jsonl \
> ../../tmp/simulation/calculator-scientific-fixture.json
mise exec -- ruby bin/recurgent-sim \
--pack ../../tmp/simulation/calculator-scientific-experiment-v1.yaml \
--mode replay \
--fixture-root ../../tmp/simulation/fixtures \
--ledger-path ../../tmp/simulation/run-ledger.jsonl \
> ../../tmp/simulation/calculator-scientific-replay.jsonWhy first deterministic:
- verifies your new oracle contract is coherent,
- prevents chasing live noise caused by a bad pack.
mise exec -- ruby bin/recurgent-sim \
--pack ../../tmp/simulation/calculator-scientific-experiment-v1.yaml \
--mode live \
--live-shadow-root ../../tmp/simulation/live-shadow \
--ledger-path ../../tmp/simulation/run-ledger.jsonl \
> ../../tmp/simulation/calculator-scientific-live.jsonInspect lane-aware output:
jq '{lane:.execution_lane,run_scope_id:.run_scope_id,gates:.gates,score:.score_vector}' \
../../tmp/simulation/calculator-scientific-live.jsonFind run trace:
find ../../tmp/simulation/live-shadow -name recurgent.jsonl | tail -n 1Inspect step failures:
jq -r '[.timestamp,.role,.method,.attempt_id,.attempt_stage,.outcome_status,.outcome_error_type] | @tsv' \
<trace-path>Inspect generated code for failing methods:
jq -r 'select(.method=="solve" or .method=="sin") | .code' <trace-path>Use this evidence to decide if you need:
- prompt-policy refinement,
- role-profile constraint update,
- guardrail-policy change,
- pack/oracle correction.
After each change:
- run full test/lint locally,
- rerun deterministic pack,
- rerun live-shadow pack,
- compare score vector and gate status.
Compare recent ledger entries:
tail -n 10 ../../tmp/simulation/run-ledger.jsonl | jq '{pack_id:.pack_id,lane:.execution_lane,gates:.gates,score:.score_vector.overall,at:.timestamp}'Promotion checklist:
- deterministic gates stable,
- replay consistency demonstrated,
- live-shadow advisory trend improving,
- failure signatures understood,
- no new critical regressions in baseline packs.
Only then promote the new pack or behavior profile into regular readiness workflow.
- Expanding pack scope before deterministic stability.
- Treating one successful live run as proof.
- Changing runtime semantics and pack oracles in the same commit.
- Promoting live-shadow to gating before observation window criteria are met.