The Gauntlet's auto-ramp had a step ceiling but no memory ceiling. GRID TITAN
ramps grid side S with cost ~ S*S, but renders into a fixed viewport so frame
time can stay under budget while allocation runs away -- observed hard-locking
the desktop mid grid-allocation (all RAM consumed, forced logout).
#353 -- memory safety (defense in depth, weakest failure mode last):
* tests/benchmarks/gauntlet/safety.py: rss_mb/vmsize_mb probes +
install_address_space_cap() (RLIMIT_AS backstop; a runaway Grid() then
aborts THIS process via std::bad_alloc instead of taking the machine down).
* Trial.predict_bytes(load) + Trial.max_load: a trial refuses a load whose
predicted footprint exceeds a 512 MB budget BEFORE allocating it. GRID
TITAN implements both (S*S*~28 B; max_load=4300 ~= 494 MB).
* RampController: pre-allocation predict/cap check + post-set_load RSS
watchdog; records stop_reason (budget/hard_cap/max_load/mem_predict/
mem_rss/max_steps). run_gauntlet.py installs the address-space cap at start.
* tests/unit/gauntlet_safety_test.py proves the ramp bails on the memory
guards before over-allocating (synthetic runaway trial records the largest
load it was asked to build).
#354 -- The Crucible (tests/benchmarks/crucible.py): a headless, deterministic
wall-clock microbenchmark of fixed "comically extreme but tractable" configs
(grid alloc, cell fill, layer writes, turn-manager swarm, FOV, A*, entity
churn). Safe (<512 MB, ~seconds), display-free, cross-version (missing APIs
report "unsupported"). Emits JSON; MCRF_CRUCIBLE_BASELINE diffs two builds.
This is the safe replacement for the windowed-Gauntlet A/B that crashed the
desktop. First result, current master vs the 0.2.8 release artifact (both
headless): grid_alloc -58.9%, grid_fill -25.4%, layer_fill -56.1%,
entity_churn -43.0%, fov_storm -10.3%, step_swarm -6.2%, path_queries -3.2%;
geomean 0.673 (32.7% faster overall), peak RSS ~103 vs ~119 MB. Tracks the
#332 SoA rewrite + #329 entity indexing.
Suite 314/314.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>