Research log / RL-015

RL-015 Served context, tail continuation for reasoning models, failure attribution

Evidence grade BCD

Field Value
Date 2026-09-13
Harness version 2026-09-13-profiled-context-patch-edit-1 (another session, not logged) → 2026-09-13-reasoning-continuation-3
Models observed: qwen3:4b-thinkingqwen3:8b (switched during the run). Measured: qwen3:8b on local Ollama. Tests: scripted clients with real capability profiles
Evidence grade B (controlled live measurement of served context) + C (tests) + D (journal)
Pre-registered yes: observation, mechanism hypotheses and baseline recorded before the code change
Source record journal turn 120, run 389; RL-014

Observation

After the context default was raised to a per-model profile (8,192 for qwen3) by a concurrent, unlogged change, the user sent a third continue on the unfinished 5,532-char dogs draft (RL-014).

Field Value
Turn / run 120 / 389, 2026-09-13 00:39:19 UTC
Elapsed 193,324 ms
Run model (at start) qwen3:4b-thinking
Turn model (at end) qwen3:8b
Outcome error: "the model spent its reply budget on reasoning and returned no answer"
agent_runs.failure null
Visible reasoning ≈ 10,000 chars: debating "10 different pages" vs sections, re-deriving the nav ids from the head, then retyping the whole file inside the reasoning, cut off in the 8th section

/api/ps after the run: qwen3:8b context_length=4096, although the harness resolved 8,192.

Five defects, found by reading the code paths involved:

  1. Whole rewrite selected. The fit test compared reply room (≈ 4,024 allowed: 3,000 code reply + 1,024 reasoning reserve; derived from the budget formula, not logged) with the draft (≈ 2,588 needed). It "fitted", so the tail mode of RL-014 was not used — but the reasoning alone was ≈ 2,500–3,000 tokens.
  2. Keep-warm reloads at 4,096. ping() used /v1/chat/completions, which cannot carry num_ctx.
  3. Category lost twice. The code path's catch called finish without a failure; separately the desktop host's second finishRun (when website checks were planned) wrote failure = null over whatever was recorded.
  4. Mislabelled category. The client raised reasoning exhaustion as context_overflow, advising LOCAL_LLM_MAX_REPLY_TOKENS, which the code path does not use.
  5. Attribution. The turn recorded llm.model at the end of the run; the model was switched mid-run.

Hypotheses

Baseline

Measure Before
Served context after keep-warm ping 4,096 (live, below)
Continuation mode, reasoning model, rewrite nominally fits whole rewrite
agent_runs.failure for run 389 null
Failed runs with no category (journal, all history) 20/25 (RL-007 snapshot)

Intervention

Method

  1. Live, controlled (H1): local Ollama, qwen3:8b, alternating requests, /api/ps read after each: compatibility ping (max_tokens: 1) → native /api/generate (num_ctx: 8192) → compatibility → native. n = 2 per request type.
  2. Harness (H2–H4): tests/reasoningContinuation.test.ts with scripted clients carrying real capability profiles and 6,000 tokens of room (so only reasoning can select tail mode); tests/ollamaNative.test.ts ping body.
  3. Full suite, typecheck, build.

Results

H1 — served context (live)

Step Request context_length Wall time
0 (state after run 389) 4,096
1 compatibility ping 4,096 0.1 s (no reload)
2 native load, num_ctx 8,192 8,192 8.0 s
3 compatibility ping 4,096 9.4 s
4 native load, num_ctx 8,192 8,192 11.2 s

Every switch between request types reloaded the model (8–11 s). With keep-warm pinging every 4 minutes during use, a real request after a ping paid a reload and a ping after a real request undid the profiled window.

H2/H3 — harness

Case Prompt Result
qwen3:4b-thinking (always), room for rewrite tail + outline (links with no section yet: border) draft joined, complete
qwen3:8b, thinking on tail + outline draft joined, complete
qwen3:8b, thinking off, room whole draft unchanged behaviour
qwen2.5-coder:7b, room whole draft unchanged behaviour

Outline for the test draft: ids already written: labrador, beagle / links with no section yet: border / classes in use: breed.

H4 — a thrown reasoning-exhaustion error in the code path is recorded with category reasoning_budget_exhausted; explain names the model.

Suite683 tests, 0 failures (5 new); typecheck clean; build passes.

Threats to validity

Conclusion

Follow-ups

  1. Live: restore turn 117's draft; continue on qwen3:4b-thinking, qwen3:8b (thinking on) and qwen2.5-coder:7b, n = 5 each; record outcome, reasoning tokens (server eval_count), elapsed, seam validity, verifier pass count.
  2. After a week of use, snapshot failure categories: expect no new unrecorded or unknown for reasoning exhaustion.
  3. Consider salvaging a fenced block from reasoning when the answer is empty, gated by the same no-progress and verifier checks — only with live evidence it helps.
  4. Log the concurrent context-profile and patch-edit change as its own entry.

Reproduce

npm test
npm run typecheck
Invoke-RestMethod http://127.0.0.1:11434/api/ps