# How Save-Game Context Compaction Fixes Spec Drift in Multi-Step Coding Agents (-91.9% Input Tokens)

> Source: <https://dev.to/tappers_/how-save-game-context-compaction-fixes-spec-drift-in-multi-step-coding-agents-919-input-tokens-13ic>
> Published: 2026-11-01 06:15:48+00:00

💡 **AI Labo Benchmark Series — Experiment `E12` (Ranked #6 out of 41 Patterns)**

This post is part of our empirical benchmark series testing AI coding agent harness patterns inside network-isolated Proxmox VMs against a hidden 20-case grading suite.

`E12` (Backlog Candidate `C008`)` e12-20261028-vm216-01`
`VM216` (`ai-e12-216`, 0 NICs, `virtio-serial` QGA relay, `systemd` UID separation)`gemini-3.8-flash` (`thinkingLevel: LOW`)`/compact` at Milestones) — When an AI coding agent tackles a multi-step engineering task across several modules, keeping every prior file dump, telemetry log, and intermediate code output inside a single growing `messages[]` array (**Unbounded Context Accumulation**) causes two compounding problems:

`6,556` ➔ `11,769` ➔ `17,544` input tokens).
To test the solution—**Milestone Context Compaction (the "Save-Game" Pattern)**—we benchmarked a 3-milestone power-grid telemetry and carbon-credit clearing pipeline (Milestone 1: `collector.py` ➔ Milestone 2: `clearing.py` ➔ Milestone 3: `dispatch.py`) inside isolated Proxmox VM `VM216`:

`AccumulatedHistoryRunner`):` VERBOSE_TELEMETRY_AUDIT_DUMP`) into one continuous chat thread (` 0` compactions).`MilestoneCompactionRunner`):` 120-token` structured JSON checkpoint (`SAVE_GAME_COMPACTION_V1`)
Mode A's accumulated history (`35,869` cumulative input tokens) suffered a classic **Lost-in-the-Middle failure** on Milestone 2 (`clearing.py`), forgetting to apply `.strip().upper()` to `contract_tier` and failing **2 out of 20** hidden E2E tests (`18 / 20`, 90.0%). Mode B's **Save-Game Milestone Compaction** kept every turn under `1,400` input tokens (`2,922` cumulative input tokens, **`-91.9%` reduction**), cut API cost by **`-72.2%` (`$0.0340` ➔ `$0.0095`)**, and achieved a flawless **` 20 / 20` (100%) pass**.

| Metric | Mode A: Accumulated History ( `AccumulatedHistory` ) | Mode B: Milestone State Compaction ( `MilestoneCompaction` ) | Delta / Improvement | 
|---|---|---|---|
| **Hidden Grading Suite Score (20 Cases)** | `18 / 20` (90.0% — failed 2 E2E cases) | **`20 / 20` (100% Perfect Pass)** | **+10.0 pt (Zero spec drift)** | 
| **Context Compactions (`compactions`)** | `0 compactions` | **`2 compactions` (After M1 & M2)** | Reset history at each milestone gate | 
| **Turn 1 Input Tokens (M1: `collector.py`)** | `6,556 tokens` (`$0.00725` ) | **`650 tokens` (`$0.00290`)** | **-90.1% reduction** | 
| **Turn 2 Input Tokens (M2: `clearing.py`)** | `11,769 tokens` (`$0.01247` ) | **`1,388 tokens` (`$0.00461`)** | **-88.2% reduction** | 
| **Turn 3 Input Tokens (M3: `dispatch.py`)** | `17,544 tokens` (`$0.01429` ) | **`884 tokens` (`$0.00195`)** | **-95.0% reduction on final turn** | 
| **Cumulative Input Tokens (`promptTokenCount`)** | `35,869 tokens` | **`2,922 tokens`** | **-91.9% (12.28x token efficiency)** | 
| **Cumulative Output Tokens (`candidatesTokenCount`)** | `1,894 tokens` | **`1,937 tokens`** | Equivalent code generation volume | 
| **LLM Calls (`model_calls`)** | `3 calls` | **`3 calls` (1 per milestone)** | Identical call count | 
| **Elapsed Execution Time (`elapsed_seconds`)** | `24.81 sec` | **`22.52 sec`** | **-9.2% (1.10x faster)** | 
| **Estimated API Cost (`estimated_micro_usd`)** | `$0.0340` (`34,005 micro-USD` ) | **`$0.0095` (`9,457 micro-USD`)** | **-72.2% (3.60x cheaper)** | 

```
+-------------------------------------------------------------------------+
| Proxmox Isolated VM216 (0 NICs, virtio-serial QGA, systemd UID split)   |
|  Target Task: 3-Milestone Power Grid & Carbon Clearing Pipeline         |
|               (M1: collector.py --> M2: clearing.py --> M3: dispatch.py)|
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode A: AccumulatedHistoryRunner (No Compaction)                  |  |
|  |  - Turn 1 (M1): 6,556 in  --> collector.py PASS                   |  |
|  |  - Turn 2 (M2): 11,769 in --> Audit logs drown out M2 spec!       |  |
|  |                               Forgets contract_tier.strip().upper()|  |
|  |  - Turn 3 (M3): 17,544 in --> Cumulative 35,869 input tokens      |  |
|  |  --> Final Score: 18 / 20 (Crashes on lowercase/padded tiers!)    |  |
|  +-------------------------------------------------------------------+  |
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode B: MilestoneCompactionRunner (Save-Game JSON Compaction)     |  |
|  |  - Turn 1 (M1): 650 in   --> collector.py PASS                    |  |
|  |  - [Compaction #1]: Discards raw logs; writes 120-tok JSON state  |  |
|  |  - Turn 2 (M2): 1,388 in --> Fresh context nails all M2 rules!    |  |
|  |  - [Compaction #2]: Updates verified_contracts in JSON checkpoint |  |
|  |  - Turn 3 (M3): 884 in   --> Cumulative 2,922 input tokens (-91.9%)| |
|  |  --> Final Score: 20 / 20 (100% Perfect Pass)                     |  |
|  +-------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+
```

`AccumulatedHistory`): The Missing `.strip().upper()` on Turn 2
Inspecting `accum-bundle.json` (Mode A's final submitted code) reveals a textbook example of **Attention Dilution**:

`collector.py`)` station_id` and `grid_zone`.` clearing.py`)` VERBOSE_TELEMETRY_AUDIT_DUMP_M1` plus the full Turn 1 code had bloated the prompt to `11,769 tokens`` contract_tier` via 

```
# ❌ Mode A (accum-bundle.json — clearing.py generated at 11,769 input tokens)
def settle_grid(readings, contract_tier="BASE", credit_offset=0):
    if not isinstance(readings, list) or len(readings) == 0:
        raise ValueError("readings must be a non-empty list")
    # BUG: Forgot isinstance(contract_tier, str) and contract_tier.strip().upper()!
    if contract_tier not in ALLOWED_TIERS:
        raise ValueError(f"contract_tier must be one of {ALLOWED_TIERS}")
```

Because of that single omitted `.strip().upper()`, Mode A crashed with a `ValueError` on two hidden E2E integration tests that passed padded/lowercase tier strings (`contract_tier=" green "` in `e2e_01` and `contract_tier="hydro"` in `e2e_02`).

`MilestoneCompaction`): The Exact Save-Game JSON Checkpoint
In Mode B, as soon as Milestone 1 (`collector.py`) passed verification, the harness wiped the raw conversation history and started Turn 2 with this compact **`SAVE_GAME_COMPACTION_V1` JSON checkpoint**:

```
{
  "checkpoint_type": "SAVE_GAME_COMPACTION_V1",
  "completed_modules": ["collector.py"],
  "history_compacted": true,
  "milestone_completed": 1,
  "next_target_module": "clearing.py",
  "verified_contracts": {
    "collector.collect_readings": "PASS (returns list of dicts with station_id, grid_zone in NORTH/SOUTH/WEST, mwh_units>0, rate_cents>=0, 0<=carbon_bps<=1500, non-mutating)"
  }
}
```

Because Turn 2 ran in a fresh **`1,388-token`** context containing only the verified upstream contract and Milestone 2's specification, Mode B had zero attention dilution—properly implementing `clean_tier = contract_tier.strip().upper()` and passing all **20 / 20** test cases:

| Test Case Group | Verification Target | Mode A ( `Accumulated` ) | Mode B ( `Save-Game Compact` ) | 
|---|---|---|---|
| `collector_01` –`collector_06` | Milestone 1: Non-mutation, type checks, bounds ( `0..1500` bps) | `6 / 6` PASS | **`6 / 6` PASS** | 
| `clearing_01` –`clearing_08` | Milestone 2: First-seen order, `400 vs 401` bps levy,`12000` tier boundary | `8 / 8` PASS | **`8 / 8` PASS** | 
| `e2e_01_green_below_12000_minus_zero_and_at_separator` | **E2E: Normalize `contract_tier=" green "` + `@` delimiter + `-0`** | **❌ FAIL (` ValueError`)** | **✅ PASS** | 
| `e2e_02_hydro_levy_and_credit_dispatch` | **E2E: Normalize `contract_tier="hydro"` + 20% discount + credit offset** | **❌ FAIL (`ValueError`)** | **✅ PASS** | 
| `e2e_03` –`e2e_06` | E2E: Zero rate cents, line order preservation, cross-stage error propagation | `4 / 4` PASS | **`4 / 4` PASS** | 
| **Total** | **20 Hidden Cases** | **`18 / 20` (90.0%)** | **`20 / 20` (100%)** | 

When building multi-step agent workflows (or using `/compact` in interactive coding agents):

`Lost-in-the-Middle`) starts happening well above 10,000–15,000 tokens of noisy tool logs. Compact `E05` (Subagent Folding), natural-language summaries often drop exact type contracts. Instead, record a structured JSON object containing `completed_modules`, `verified_contracts` (exact function signatures & invariants), and `next_target_module`.` E20`):` MEMORY.md``E21`):` E16`):` E19`):` E14`):
