added corpse hard-despawn gate (_CORPSE_DESPAWN_LIFECYCLE = -10.0) to stop replay-only freeze FX work on already-despawned corpses.
src/crimson/projectiles/runtime/collision.py
added _NATIVE_FIND_RADIUS_MARGIN_EPS = 0.001 to stabilize native-style find-radius branch parity under tiny float drift.
src/crimson/original/focus_trace.py
collision tracing now uses the same runtime predicate path used by gameplay collision checks.
src/crimson/original/capture.py
_tick_player_weapon_projectile_spawned now matches spawn type IDs via projectile_type_ids_from_weapon_id(weapon_id) (while preserving direct weapon-ID matching).
Tooling:
src/crimson/cli.py + src/crimson/original/diagnostics_daemon.py: original bisect-divergence now supports cached runner path and --no-cache.
src/crimson/cli.py: original verify-capture now supports --json-out.
Tests:
tests/test_original_capture_conversion.py: added regression for unknown-mode fire synthesis with mapped weapon projectile (weapon_id=14, projectile type 11).
tests/test_projectiles.py: updated secondary pool speed expectation to float32-fidelity value.
Current hard block: first surviving mismatch is a tiny cumulative movement/state drift (tick 5053) without RNG/collision branch evidence at focus, and this capture lacks creature movement micro telemetry required to isolate the first branch split.
Next required capture should use the current scripts/frida/gameplay_diff_capture.js defaults (creature micro telemetry on by default), then re-run baseline triage/focus around the first drift corridor (~4690..5060).