DENSE PREFIX TIER, END TO END ON A CARD — 2026-09-09
====================================================

WHAT THIS ANSWERS. The KV offload was built for hybrids, where a recurrent
state cannot be sliced and a savepoint IS the prefix cache. The dense half was
never driven on a card. This is that run: does a dense model get the cache
hit, does the warm tier extend it past the KV pool, and does a dense
deployment pay for savepoint machinery it cannot use.

RIG
  box 206, GPU 0, container dense-chk, port 8126
  image registry.arbi.work/arbi-serve:test-latest + working-tree bind mount
  model /models/MiniCPM5-1B-exl3-4bit  (LlamaForCausalLM — dense, no
        recurrence keys; confirmed off the checkpoint, not off the name)
  compose.serve.yaml + compose.bindmount.yaml, ARBI_SAVEPOINT_ENABLED=1,
        ARBI_PREFIX_TIER=1, --kv-cache-dtype=auto --mtp-n-draft=0
  geometry, read off the boot rather than assumed:
        256 tok/page, 3680 servable pages = 942,080 tokens
        warm tier 682 slots x 6,291,456 B = 4,290,772,992 B pinned host
        break-even warm/cold 512/2048 tok

1. A DENSE DEPLOYMENT PAYS NOTHING FOR THE SAVEPOINT MACHINERY
   Boot line, with the master switch still ON:

     savepoint store: disabled (no recurrent state, max_bytes=0, or prefix
     caching off [ARBI_USE_RADIX_PAGETABLE=0]) — note this is NOT the master
     switch; ARBI_SAVEPOINT_ENABLED=0 is, and it is still 1 here

   That is the machinery declining ITSELF on the model's shape, which is a
   stronger statement than a flag being off: an operator cannot mis-set it.
   Beside it, the freeze ledger:

     state.gdn_recurrent   0M reserved   0M live   0M pinned   0 segs

   No ring, no pinned savepoint bytes, no pair sink. The only page-locked row
   is the prefix tier arena, which is the KV feature and is opt-in.

2. THE CACHE HIT, AT LONG CONTEXT WITH SHORT TURNS
   Shared 8.8k-token prefix, three short turns:

     turn 0   0.20 s   prompt 8833   cached    0
     turn 1   0.05 s   prompt 8833   cached 8704   (98.5%)
     turn 2   0.05 s   prompt 8833   cached 8704   (98.5%)

   8704 of 8833 is 34 whole pages of 256; the 129-token remainder is the
   turn itself plus the partial tail page. The uncached tokens are the
   genuinely new ones.

3. THE WARM TIER EXTENDS THE REACH PAST THE KV POOL — MEASURED, NOT ASSUMED
   Lay a target prefix down, push it back N distinct 8.8k prompts, ask for it
   again. Fresh seed space per depth.

     depth  revisit   cached    of     tier_restore_total
     ------ --------- --------- ------ ------------------
        60    0.04 s      8704   8840   0      radix still holds it
       100    0.04 s      8704   8848   0      radix still holds it
       115    0.09 s      8704   8831   +34    RADIX LOST IT, TIER SERVED IT
       125    0.09 s      8704   8800   +34    same
       130    0.17 s         0   8796    0     past both tiers
       135    0.17 s         0   8807    0     past both tiers
       145    0.17 s         0   8775    0     past both tiers

   +34 pages is the WHOLE prefix (34 x 256 = 8704), faulted back out of
   pinned host RAM after the radix had evicted it. The window runs from the
   radix edge (~110 prompts) to ~128, which is 682 slots / 34 pages =
   20 prompts of extra reach — the arena's own bound, arrived at from the
   other side.

   The three latencies are the three states and they separate cleanly:
   0.04 s radix hit, 0.09 s tier restore, 0.17 s full re-prefill. The
   restore costs ~50 ms over a hot hit and saves ~80 ms against re-prefilling.

   Byte-identity of a restored page is proven separately and exactly, on CPU
   over a real backing slab, in tests/test_radix_tier_restore.py.

4. WHAT THIS RUN FIRST GOT WRONG, AND WHY IT IS IN THE RECEIPT
   The first pass of §3 read tier_restore_total as ZERO at every depth and
   was reported as "4244 pages demoted, not one came back". The counter has
   no forwarding path: it is written in radix_pagetable_tier and appears in
   no OTEL instrument table, so on a live server the series does not exist.
   An absent series is indistinguishable from a zero one.

   The numbers in §3 are from the re-run after the forwarding was added.
   Widening tests/test_savepoint_metric_forwarding_guard.py — which was built
   for exactly this failure and had been scoped to arbi_serve.savepoint., so
   it was blind one namespace over — found five more unreadable counters in
   the same namespace on its first run.

5. WHAT IS NOT ESTABLISHED HERE
   - The warm tier is 4 GiB against a 21.56 GiB KV pool, so it extends the
     servable prefix working set by about 18%, not by a multiple. Under a
     working set well past the pool the arena is at permanent saturation
     (exhausted moves 1:1 with releases) and the extension is the last
     ~174k tokens of what the radix shed, nothing older.
   - Cold/disk tier is off in this boot (cold=off). Nothing here says
     anything about it.
   - One model, one card, TP1. No claim about TP>1, where the SPMD worker
     path deliberately does not restore from the tier at all.
