# Draft-head disentangling bench — PROTOCOL (pre-registration)

- **Authored (UTC):** 2026-08-18T23:05Z
- **Box:** the-gpu-box (`the-gpu-box`), ollama 0.32.13, `http://the-gpu-box[:port redacted]`
- **Target:** `qwen3.8:27b` — Q4_K_M, 27.3B, ctx 32768, **protected resident**
  (the live rulesage classifier seat)
- **Authoring order:** capability probe ran FIRST (per the coordination hold);
  this protocol pre-registers the timing matrix, which had **not** been run at
  authoring time and is now recorded **NOT-RUN**. The prediction below is left
  intact and unedited so a future quiet-window run can execute it unchanged.

## Question being closed

The "Reading is fast, writing is slow" draft states that *"how much of the speed
comes from the guesser … is a measurement we owe."* Exhibit fourteen's stopwatch
leg additionally flagged an unexplained ordering in the C5 decode medians:

| prompt tier | C5 decode median (tok/s) |
|---|---|
| ~1k  | 115.69 |
| ~8k  | 133.54 |
| ~32k | 126.995 |

All C5 rows: n=10, `think:false`, `num_ctx 32768`, ollama 0.32.13.

An 8k prompt decoding **faster** than a 1k prompt inverts the expected physics —
decode should decline gently and monotonically as KV-cache depth grows.

## Hypothesis (promise-register #8)

`qwen3.8:27b` ships `draft_num_predict 4` in its served defaults, i.e. it decodes
with a speculative **draft head**. Speculative decoding's throughput depends on
*draft acceptance rate*, which is a property of the **text being generated**, not
of prompt length. If acceptance happens to be higher for the continuations the
8k prompt elicits, that could swamp the gentle KV-depth penalty and produce the
inverted ordering.

## PREDICTION (pre-registered, stated before any matrix data)

> With the draft head **disabled** (`draft_num_predict 0`), the tier ordering
> will become **monotonic and gently declining**: 1k > 8k > 32k. With the draft
> head **enabled** (`draft_num_predict 4`), the 8k > 1k inversion will
> **reappear**. Disabling the draft head is expected to cost roughly 20–50% of
> decode throughput.

- **CONFIRMED** if draft-0 rows are monotonic-declining and the inversion is
  confined to draft-4 rows.
- **REFUTED** if draft-0 rows *also* show 8k > 1k — the inversion would then be
  something other than the draft head, and this is to be said plainly.

## Matrix design (NOT-RUN — pre-registered for a future quiet window)

- Cells: `draft_num_predict {0, 4}` × prompt tier `{~1k, ~8k, ~32k}` = 6 cells
- n = 10 per cell, 60 calls total
- Every call: `num_ctx 32768`, `think: false` (explicit, never omitted),
  `num_predict 256`, `temperature 0`, `seed 0`, `keep_alive -1`
- Prompts built by repetition; a per-call nonce at the **head** of the prompt so
  each call is a genuine prompt eval at its tier rather than a cache hit
- Draft-0 and draft-4 **interleaved** within each tier to cancel drift
- Sequential calls, 0.5s sleep between; medians + ranges reported per cell

## Standing safety laws for this lane

1. **Never** stop, unload, or reload a resident (`gemma4:26b`, `qwen3.8:27b`,
   `nomic-embed-text`). No `ollama stop`, no `keep_alive` below -1 on residents,
   no daemon restarts, no `systemctl`.
2. **Never** touch the two warm timers.
3. **Per-request options only.** No Modelfile edits, no model copies (a copy is a
   second 17.7GB load = VRAM pressure on a live box). If an option cannot be set
   per-request *within these laws*, that arm is **NOT-RUN** with the probe output
   as the receipt.
4. Between tiers: one health GET to `https://rulesage-live.strata2signal.com/`
   (front page only, never an ask). 5xx or gross slowness ⇒ pause 10 minutes.
5. All receipts UTC only.

## Capability gate (must pass before the matrix)

The matrix is only meaningful if `draft_num_predict` is genuinely controllable
per request. Ollama silently ignores unknown option names, so *acceptance alone
proves nothing*. The gate therefore requires positive evidence of both:

- **(a) recognition** — the server parses the option rather than discarding it;
- **(b) effect** — the setting actually changes decode behaviour.

---

## HOLD NOTE — appended 2026-08-18T23:06Z

Coordinator issued a **coordination hold**: another session's seat screen is
cycling five candidate models on the-gpu-box with `keep_alive 0`, reloading on every
call (~2.5h). That churn would smear timing medians. Orders: run the capability
probe, write this protocol, then **hold the 60-call matrix** pending a
`MATRIX GO` on a quiet box — and if the capability probe finds per-request
control does not work, report **NOT-RUN immediately** and skip the matrix
entirely, no window needed.

**Capability gate outcome: FAILED — matrix NOT-RUN, and no quiet window will fix
it.** The option is recognised and honoured, but ollama 0.32.13 implements
`draft_num_predict` as a **runner launch flag** (`--spec-draft-n-max`), not a
per-request sampling parameter. Changing it forces a full **restart of the
llama-server runner** — an unload + reload of the 17.5GB protected resident —
which Law 1 forbids. The blocker is the mechanism, not the box being busy.

Full verdict, receipts and analysis: `RESULTS.md`.
