Optional Rerun simulation inspection
An explicitly selected live physics session can retain poses, model observations, accepted inputs, contact events, rule firing markers, rule-wave outputs and step metrics. Export this…
Optional Rerun simulation inspection
An explicitly selected live physics session can retain poses, model observations, accepted inputs, contact events, rule firing markers, rule-wave outputs and step metrics. Export this retained data to Rerun for correlated engineering inspection. The export process reads a completed capture; it does not execute Grid formulas or reconstruct missing observations by replaying the current model.
Record the diagnostic
The example is a real native Grid/Rapier run with an intentionally faulty authored cleanup rule: the first landing removes the supporting floor. The diagnostic question is why the ball appears to fall through its support.
CARGO_INCREMENTAL=0 cargo run --locked --offline --manifest-path rust/Cargo.toml \
--config .cargo/no-debug-symbols.toml -j 2 -p grid-runtime-host \
--features process-runtime --example record_physics_inspection -- \
examples/simulation/15-support-removal-diagnostic.grid /tmp/support-removal.json
python3 -m venv /tmp/grid-rerun
/tmp/grid-rerun/bin/python -m pip install -r scripts/rerun-export-requirements.txt
PATH=/tmp/grid-rerun/bin:$PATH pnpm simulation:export:rerun \
/tmp/support-removal.json /tmp/support-removal.rrd
/tmp/grid-rerun/bin/rerun /tmp/support-removal.rrd
The SDK is pinned to 0.29.1 in separate optional tooling. A product Build never installs it. Missing or incompatible SDKs refuse export with a concrete message. The exporter validates timeline continuity and input/body identity before writing an RRD; an existing output is preserved. The SDK owns the RRD encoding. Standard temporary-file/exclusive publication prevents incomplete recordings from replacing a user's output. No remote viewer or upload is started by export.
For other engineering scenarios, use
RuntimeHost::start_physics_live_inspection instead of start_physics_live.
It returns the same session start response plus a receiver containing the
capture result at completion. Stop and collect the session using the existing
host owner. Serialize PhysicsInspectionRecording with serde and supply
source/run provenance alongside it. The public HTTP live-session endpoint and
existing UI remain unchanged; this first increment is a native API and offline
exporter, not a product-view redesign or retroactive export of older runs.
The recorder accepts any authored source with a physics world, plus
--seconds N (default 1.5, maximum 600). The default capture limit still applies;
use explicit native API limits for longer captures. It aliases rule outputs using
the exact compiler result, including targets that are neither observed nor
driven. The user-facing export command supports repeatable --focus-body and
--focus-observation options for the initial plot selection. All retained signals
remain in the recording. The optional environment must be active or first on PATH.
Inspect an existing multi-body controller
The existing 14-sisyphus-breakout.grid model already documents collision-seam
energy changes and a speed controller. Its unchanged source provides a second
actual Grid/Rapier recording with 26 bodies, 360 ticks and 17 accepted inputs:
CARGO_INCREMENTAL=0 cargo run --locked --offline --manifest-path rust/Cargo.toml \
--config .cargo/no-debug-symbols.toml -j 2 -p grid-runtime-host \
--features process-runtime --example record_physics_inspection -- \
examples/simulation/14-sisyphus-breakout.grid /tmp/breakout.json --seconds 6
PATH=/tmp/grid-rerun/bin:$PATH pnpm simulation:export:rerun \
/tmp/breakout.json /tmp/breakout.rrd --focus-body ball \
--focus-observation ball_x --focus-observation ball_y \
--focus-observation ball_vx --focus-observation ball_vy \
--focus-observation gutter_hits
At tick 67 (1.116667 s), gutter contact coincides with a speed dip to
5.807412 m/s and a rule-driven relaunch. The accepted [2,6,0] velocity and
return-pose inputs produce a 6.324555 m/s speed at tick 68. The reset lifts the
override, the base speed controller emits [1.8973665961,5.6920997883,0], and
its accepted input produces speed 6 at tick 69 (1.150 s). The recording separates
contact effects, relaunch commands and subsequent correction. It demonstrates
an existing physics-control diagnostic, rather than an industrial workflow or
a universal solver-defect claim.
breakout-inspection-complete.rrd and its capture, preview, source/replay identities and
reading notes are retained alongside the support-removal recording in the
2026-10-06 evidence directory. Body speed and accepted-velocity speed are norms
derived from retained vectors. Numeric single-row rule arrays are plotted by
component; their full typed payload remains in the event log.
Read the recording
The embedded blueprint supplies a replayable workspace and requests paused playback.
A viewer connected to a live proxy may follow the latest time; use Pause before
scrubbing. The local inspection preview is left paused. Its 3D poses,
observation plots, body-state plots, metrics and event log share
simulation_time in seconds and simulation_tick as a sequence. The static
reading guide retains model/engine identity, capture digest, source and replay
evidence when supplied by the recorder.
- Find the first ball/floor contact and the increase in
landings. - At that simulation tick, inspect the actual rule firing marker and the
rule-wave output containing
floor_gone. - Inspect the accepted
removeinput. Its tick is the boundary before the next physics step; its effect is visible in that next pose. - Compare the removed-floor signal, ball height and vertical velocity. The support disappeared through control logic: the recording distinguishes this from collision tunneling or missing pose frames.
Only inputs whose LiveWorld::apply succeeded are exported. Requested or
dropped drives are not mislabeled as applied. All poses/observations are
post-step; computed readings remain available even when the exchange status
reports that the host lock was skipped. A committed exchange means readings
reached model cells; rule-error also identifies a subsequent rule failure.
Rule-wave outputs include recomputed dependents and must not be interpreted as
individual assignments attributed to each firing rule. Firing markers compare
the existing scheduler's last-fired timestamp and monotonic run identity. A
same-millisecond repeated legacy firing without a changed run identity cannot
be distinguished; this capture does not introduce a new rule execution journal.
Ball and cuboid geometry is rendered to scale. Other collider shapes retain
captured poses and an explicitly labeled point glyph, not an approximate collider.
The SDK's 3D transforms use float32. Full float64 positions, XYZW quaternions,
linear/angular velocity and removal state remain under raw_poses/<body> as
native Arrow components for numeric inspection, including removed bodies.
Select the Full precision poses tab beside the reading guide to inspect them.
Removed geometry is cleared while its scalar state remains inspectable. Step
wall time is a host measurement, not simulation time. Metric plots also expose
contact starts and exchange delivery. Pause before inspection; scrubbing requires
no animation and does not alter the product's motion preferences.
Isolation, bounds and storage reuse
The ordinary path uses a zero-sized NoInspection through static dispatch;
inline empty callbacks carry no observer pointer or capability branch. It
creates no capture collection, channel, clock read, file, socket, worker or
serializer. LiveState, Shared, LiveSession and the ordinary model resolve
path retain their prior layout and state. There is still one native evaluator and
one physics worker/solver. The additional clock, state copies, rule snapshots and
serialization accounting belong only to an admitted capture.
Admission limits captures to 128 bodies, 128 observed cells, at most 1 MiB of metadata, and a chosen sample/serialized-byte budget (defaults: 2,048 samples, 16 MiB; absolute ceilings: 100,000 samples, 64 MiB). Initial and final post-step frames are retained. Saturation returns an explicit capture error and releases retained samples; the simulation continues with its ordinary limits. The byte budget accounts serialized payload, not allocator overhead or transient rule state clones. This is a bounded diagnostic for small models, not an assurance or hard-RSS logging capability. Dropping the receiver never blocks stop.
The existing temporal ledger remains the authoritative replay mechanism for accepted inputs. Its run identity and replay verification are included by the QA recorder. Its disposable model/ledger are removed after the example run; the capture retains the source, admitted world, inputs and replay result. The production ledger does not retain per-tick observations and rule waves, so the selected observer adds an ephemeral serde export DTO for those signals. It creates no new journal, recovery authority, framed-log protocol or storage service. The RRD is a derived inspection artifact, not a substitute for the ledger or proof of general solver correctness.
Run focused native Testing with --test physics_inspection and existing
--test physics_live_sessions; run exporter Testing in the separate environment:
PATH=/tmp/grid-rerun/bin:$PATH /tmp/grid-rerun/bin/python -B \
tools/testing/simulation-rerun-export-test.py
These are local independent Testing/QA operations. They never authorize or dispatch a paid operation and are not consumed by Build or Release.
Retained local cost assessment
The 2026-10-06 local macOS/aarch64 debug measurement alternates seven ordinary and capture runs of the same source. Every pair matches completed ticks, accepted input count, final bodies and replay verification. The declared selected-capture budget includes host/model admission, the 1.5-second simulation, stop, replay and JSON publication: p95 at most 3 seconds and peak RSS at most 256 MiB.
The first measurement missed that budget (capture p95 3.621 s). Buffered JSON publication repairs the recorder's avoidable per-field file writes. The retained repeat has capture median 1.589 s, p95 1.602 s and maximum RSS 89,767,936 bytes; median paired wall delta is +0.002685 s. The control has a 6.483 s outlier, which remains in the distribution and precludes a general speedup claim. Separate Rerun publication of the retained recording took 0.30 s and produced about 604 kB of native RRD data. These small local distributions are engineering cost evidence, not an optimized product-profile certification.
See the retained reports under
docs/operations/evidence/rerun-simulation-inspection-2026-10-06/ and the local
tools/perf/simulation-inspection.py command. The default-off resource proof is
structural: zero-sized static callbacks, unchanged session layout, no SDK/runtime
dependency, and no capture factory reached from ordinary admission. The new
source-bound worker probe measures the changed boundary with opt-level=3
and common prepared debug physics/serde libraries. Across 100 alternating pairs,
ordinary median is 0.9910 ms versus 0.9907 ms before the change; paired median ratio
is 0.9996 and p95 ratio 1.8776. Candidate p95 is 2.633 ms versus control 2.467 ms.
The wider tails remain retained alongside the earlier 1.0439 p95 ratio; this
shared-machine result does not isolate their cause. Both arms allocate exactly 171 times / 62,955 bytes.
The selected pose-copy/byte-accounting probe returns the same payload as a full
body-state reference: median ratio 1.0738, p95 3.421 ms for 200 samples, with
2,082 allocations / 1,057,625 bytes versus 3,282 / 1,290,625 for the reference.
Common probe peak RSS is 4,947,968 bytes. The selected probe applies its logged
impulse successfully before retaining the resulting sample.
These focused comparisons pass the existing 1.3x paired-median ordinary and 3x
strong selected bands and their declared local absolute/resource budgets.
source-worker-cost-final.json retains all final samples, source/library identities and
limits. Worker/layout/lock source identity establishes no added locks, threads,
clock reads or I/O; these are not OS tracing counts. The probe runs the unbound
worker on its calling thread and measures the selected pose mechanism. Full
optimized product packaging, bound native/HTTP exchange performance, binary footprint
and per-arm RSS are outside this receipt. Historical baselines remain unchanged;
no whole-product performance certification or speedup is claimed.