# 2026-05-07 · M3.9 Phase 0 validation — Mixed-disable hypothesis CONFIRMED

## Priority & ROI

**Priority**: P0 (gates Phase 1A v3 implementation by codex).

**ROI basis (data from this run)**:
- 7 logged split steps × ~1.2s = ~8.4 s of split (bulk work)
- 8 unlogged mixed steps × <100ms = <0.8 s of mixed (light work)
- **~10× ratio**: split steps dominate steady-state TIME
- Phase 1A v3 expected to route the 7 long steps to Mixed →
  ~10× per-step speedup on the long work
- Translates to long-ctx 4k/c=4 TTFT reduction ~3000 ms in
  pre-Phase 1A v3 baselines

**Negative case**: at HIGH-conc workloads (where Phase 1A v3
isn't needed because Mixed ISN'T blocked anyway), no benefit.
Current data shows mixed_batch_fallback all 0 across 14 reasons
— Phase 1A v3 doesn't fix any of those (those don't fire), only
addresses the deferred_decode_emit precondition exclusion.

**Kill criteria**: if Phase 1A v3 lands and longctx 4k/c=4 TTFT
reduction is < 30%, a deeper issue exists (the per-step cost
itself) — abandon Phase 1A v3, escalate to source archaeology
on what's actually costly in Split path.

## Goal

Validate the Phase 0 instrumentation
([`a84736a`](../../../infer/src/scheduler/cuda/decode.rs)) shows
the predicted Mixed-disabled pattern at long-context steady state.

## Command

ARLE server with M3.9 Phase 0 instrumentation:
```bash
target/release/infer --port 8000 --max-seq-len 12288 \
  --num-slots 8 --max-prefill-tokens 16384
```

Bench: longctx 4k/c=4 with codex's exact data shape:
```bash
guidellm benchmark run --profile concurrent --rate 4 \
  --data 'prompt_tokens=4096,...,output_tokens=256,...' \
  --max-seconds 60 --warmup 10 --random-seed 20260416
```

## Results

### Bench numbers

| Metric | This run | F4-Small longctx (`c63c31c`) | Δ |
|---|---:|---:|---|
| out tok/s mean | 114.8 | 122.5 | -6% (in scout noise) |
| Concurrency | 4.0 | 4.0 | flat |
| in tok/s | 2140 | 2400 | similar |

Numbers stable vs prior longctx benches. Phase 0 instrumentation
adds no measurable overhead.

### Prefill-path metrics (the actual diagnostic data)

```
infer_prefill_path_mixed_batch_total{outcome="ok_true",}  8
infer_prefill_path_mixed_batch_total{outcome="ok_false",} 0

infer_prefill_path_mixed_batch_fallback_total{reason="decode_slot_count_mismatch",}        0
infer_prefill_path_mixed_batch_fallback_total{reason="duplicate_prefill_slot",}             0
infer_prefill_path_mixed_batch_fallback_total{reason="empty_decode_batch",}                 0
infer_prefill_path_mixed_batch_fallback_total{reason="empty_prefill_batch",}                0
infer_prefill_path_mixed_batch_fallback_total{reason="empty_prefill_tokens",}               0
infer_prefill_path_mixed_batch_fallback_total{reason="inactive_paged_pool",}                0
infer_prefill_path_mixed_batch_fallback_total{reason="lora_enabled",}                       0
infer_prefill_path_mixed_batch_fallback_total{reason="prefill_seq_len_mismatch",}           0
infer_prefill_path_mixed_batch_fallback_total{reason="prefill_slot_in_decode_batch",}       0
infer_prefill_path_mixed_batch_fallback_total{reason="prefill_start_position_count_mismatch",} 0
infer_prefill_path_mixed_batch_fallback_total{reason="scheduler_pre_dispatch_fallback",}    0
infer_prefill_path_mixed_batch_fallback_total{reason="unsupported_kv_format",}              0
infer_prefill_path_mixed_batch_fallback_total{reason="unsupported_model",}                  0
```

**ok_false = 0 across all 14 reasons.** The unified
`decode_batch_with_prefill` path NEVER falls back when invoked —
all conditions for `Ok(true)` hold at long-ctx steady state.

### Server log step-plan distribution

```
step breakdown plan=prefill : 1 step
step breakdown plan=split   : 7 steps
step breakdown plan=mixed   : 0 steps  (none above 100ms log threshold)
```

(Steps under 100ms aren't logged. The 8 mixed_batch ok_true
counts come from those small steps.)

## Headline finding

**The H1 hypothesis from `26b7f86` + `28056b9` is confirmed**:

1. F4-Small precondition `deferred_decode_emit.is_none() &&`
   in `plan_step` (execution.rs:396) DOES disable Mixed when
   deferred is outstanding.
2. At long-ctx steady state, deferred is outstanding most of
   the time.
3. Plan_step routes to Split. Split steps take ~1.2 seconds
   each (10× the per-token cost of Mixed).
4. The few times Mixed DOES run (deferred briefly cleared),
   it succeeds (ok_true=8 ok_false=0). So the Mixed path is
   structurally correct — it's just not given the chance.

**Expected gain from Phase 1A v3** (multi-slot async readback
to remove the precondition):
- 7 long Split steps (~1.2s each) become Mixed (~0.1s each)
- 60s bench window: ~7 × 1.1s reduction = 7.7 s of net work
  saved in 60s window
- TTFT mdn at longctx 4k/c=4 expected to drop 3403 → ~1500 ms
- Out tok/s expected to roughly DOUBLE at long-ctx low-conc

## Bench Status

- Bench artifact: `bench-output/2026-05-07-m3.9-p0-metrics/`
  + `bench-output/2026-05-07-m3.9-phase0-validation/` (gitignored).
- Server log: `/tmp/m39-p0-r2.log`.
- Phase 1A v3 implementation pending (codex brief at
  `/tmp/codex-brief-m39-phase1a-v3.txt` ready).

## Decision

**Greenlight Phase 1A v3**:
- Mixed-disable confirmed by metric data
- All 14 fall-back reasons are 0 → simply removing the
  precondition would NOT trigger any of them, BUT silent
  token loss via in_flight guard remains the actual risk
- Multi-slot async readback (Phase 1A v3 design) addresses
  the silent-loss risk, then precondition can be safely removed

## Next actions

1. Brief codex with Phase 1A v3 design (already staged at
   `/tmp/codex-brief-m39-phase1a-v3.txt`).
2. Bench validation script ready at
   `/tmp/run-m39-phase1a-bench.sh`.
3. Expected codex implementation cycle: 1-2 hr per F4-Small/
   B.1.2 precedent (multi-round review).
4. Post-Phase 1A v3 bench → verify TTFT 3403 → ~1500 ms.
   If yes → proceed to M_pf (Opportunity D / prefetch wiring).
   If less than -30% TTFT → kill criteria fires, re-investigate
   per-step cost.

## Cross-references

- M3.9 plan: `63af21f`
- F4-Small Mixed-disable cause: `26b7f86`
- Race verification (silent token loss): `28056b9`
- Codex Phase 0 commit: `a84736a`
- M-final roadmap (Priority & ROI): `a06c5c9`
