Invariants / OP-MEM-02

OP-MEM-02

OP operational enforced

Ade's owned resident memory (Private_Dirty/RssAnon) under a representative venue stays clearly below the reference Haskell cardano-node's on the same chain, WITHOUT changing ledger semantics, chain selection, persisted bytes, or replay-equivalence.

Source

Project constitution §4b; bounty BA-08; MEM-OPT cluster plan (docs/planning/mem-opt-cluster-plan.md)

Introduced in
MEM-OPT-UTXO-DISK

Enforcement trace

Cross-references

Evidence notes

Declared at MEM-OPT scoping (2026-06-15). The bounty BA-08 win criterion made an invariant. Baseline (MEM-COMPARE-D, docs/evidence/mem-compare-d-preprod.{jsonl,md}): Ade 6.56 GB vs Haskell 5.50 GB on preprod (verdict ade_heavier, +19%). Target <=3.0 GB owned (aim 2.0-2.5). The MEM-OPT clusters (OPS allocator+streaming-import, UTXO-DISK on-disk UTxO, COMPACT representation) drive it; flips when the committed comparison verdict becomes ade_below + the RSS-ceiling gate is green. Every lever is a representation/storage change proven replay-equivalent (DC-MEM-05) and measured with the A2 RSS<->replay-verdict pairing. MEM-OPT-OPS S1 (ALLOC) data point (2026-06-15, docs/evidence/mem-opt-ops-s1-alloc-preprod-memory.{jsonl,md}, sha256 1ea71f1c...): swapping the glibc allocator -> mimalloc dropped VmRSS p50 6874024 -> 4824884 kiB (-29.8%) on the identical A2 protocol, replay_verdict agreed, 0 diverged -- now 0.90 GiB BELOW the 5.50 GiB Haskell reference on VmRSS (ci_check_mem_opt_s1_reduction.sh + ci_check_mem_measure_evidence.sh green). STAYS declared: this is VmRSS, NOT the owned Private_Dirty/RssAnon metric (MEM-OPT-OPS S3), and -16% vs the reference is not yet 'clearly below' the <=3 GB target; the streaming import (S2), on-disk UTxO, and the formal MEM-COMPARE-D verdict flip (S3) remain. MEM-OPT-OPS S2 (IMPORT) data point (2026-06-15, docs/evidence/mem-opt-ops-s2-import-preprod-memory.{jsonl,md}, sha256 70151e45...): the streaming seed import HALVES the import peak (seed_import VmHWM 6874028 -> 3405288 kiB, -50.5%), byte-identical (bootstrap initial_ledger_fp == S1's fb7cb12a...), replay_verdict agreed, 0 diverged. S2 ALSO surfaced the dominant remaining peak: the UTxO->chain.db snapshot serialization (run-end VmHWM 8 GiB transient + the redb chain.db mmap into gross VmRSS ~6.9 GiB) -- NOT the import; a separate next target (likely MEM-OPT-UTXO-DISK), and the reason the owned Private_Dirty metric (S3) is what matters, not gross VmRSS. STILL declared (no flip from VmRSS/VmHWM alone). MEM-OPT-OPS S3 (MEASURE) data point (2026-06-15, docs/evidence/mem-opt-ops-s3-owned-preprod-memory.{jsonl,md}, sha256 f50bf97c...): the OWNED metric measured for the first time (RssAnon, excludes file-backed; readable for Ade AND the Haskell node). RssAnon ~= VmRSS at every point -- Ade's resident memory is almost entirely OWNED anonymous heap, so the S2 'chain.db mmap pollutes gross VmRSS' hypothesis was WRONG: redb's admission cost is anonymous write buffers + the seed_to_snapshot serialization, counted in RssAnon. Ade idle/recovered owned 2042968 kiB (1.95 GiB, BELOW the <=3 GB target -- the import-side S1+S2 wins are real), BUT active-admission owned p50 4813052 kiB (4.59 GiB, ABOVE target). Honest owned comparison (ci_check_mem_opt_s3_owned.sh; mem-opt-ops-s3-owned-compare-preprod.jsonl, 15-sample window): Ade owned p50 4.59 GiB vs Haskell windowed owned p50 2.57 GiB (GC-variable 2.57-3.95) -> VERDICT ade_heavier on the OWNED metric, the OPPOSITE of the gross-VmRSS signal. MEM-OPT-OPS alone does NOT clear the preprod owned posture; the dominant owned cost during admission is the seed_to_snapshot/chain.db serialization -> MEM-OPT-UTXO-DISK. STAYS declared (owned NOT clearly below -- honest, no flip). FLIPPED to enforced at MEM-OPT-UTXO-DISK S2b-2c.1b-A.2 (2026-06-16), SCOPED to the CURRENT live track_utxo=false admission path (owned RssAnon vs the preprod Haskell baseline). The live admission runs track_utxo=false -> it does NOT mutate the UTxO per block, so the retained 1.9M-entry in-memory UTxO was accidental retention, re-scanned per block to recompute a CONSTANT fingerprint. A.2 drops it: bootstrap computes the constant UTxO-component fingerprint ONCE (ade_ledger::fingerprint::StaticUtxoFp -- fail-closed under track_utxo=true / version mismatch) BEFORE drop(utxo); post_fp uses the static component; the durable copy is the existing snapshot. Live re-measure (docs/evidence/mem-opt-utxo-disk-s2b-2cA-owned-rss-remeasure.{jsonl,md}; preprod docker peer, epoch 295, FRESH 3.8 GB seed): active-admission owned RssAnon 1.94 GiB (2,037,588 kiB, p50==peak, n=33) vs Haskell 2.57 GiB -> VERDICT ade_below (25% below; 58% below the 4.59 GiB pre-A.2 baseline; conservative -- the A.2 run's UTxO is LARGER, 3.8 GB vs 554 MB). Correctness: 36 blocks admitted, 1 agreed + 35 lagging, 0 diverged, 0 hash mismatches, replay_verdict agreed (DC-MEM-05 replay-equivalence preserved -- post_fp byte-identical: fingerprint_v2_with_utxo ignores state.utxo_state, so the empty-UTxO live ledger == the full-UTxO post_fp). ci_check_utxo_fp_cache.sh asserts StaticUtxoFp + drop(utxo) + the fail-closed guard. SCOPE / NO OVER-CLAIM: (1) enforced for the CURRENT live track_utxo=false header/tip-following admission path ONLY -- NOT full live UTxO application; B (LIVE-LEDGER-APPLY, track_utxo=true) remains OWED. (2) Proven on a 36-block live run; the BOUNTY BA-08 full criterion is a SUSTAINED ~10-day run, CERTIFIED only by that sustained measurement (owed) -- the current evidence POSITIONS Ade to win the 10-day window but does NOT yet certify it.