---
name: free-space-floor-blocks-golden
description: "hfenduleam's 32 GB CI floor killed 3 runs 2026-07-31, then FULL exhaustion (0 GB) 2026-08-01 surfacing as LNK1318 PDB errors; root cause = per-session scratchpad cargo targets (112 GB); reclaim recipe, by-path reap rail, measured before/after."
metadata: 
  node_type: memory
  type: project
  originSessionId: 19af1a2f-5196-41e5-8233-8bb5241f8280
  modified: 2026-08-01T10:36:23.064Z
---

The Windows CI jobs on `hfenduleam` assert a **32 GB free-space floor as step 2**, before any code runs. Below it the job fails with `RESOURCE=disk drive=C:\ free_bytes=… floor_bytes=34359738368`. **This reads as a red run but no test executed** — the sha is UNTESTED on that platform, not failing. Filed as `releases#56`.

**Three casualties on 2026-07-31:** main's thin ci at `dd1653e` (27.8 GB), then BOTH Windows golden legs of run 30660216982 at `2a66d78` (15.5 GB), which took an otherwise 7-of-9-green v0.49.0 candidate to `conclusion=failure`.

**I caused the golden one.** Running `cargo run -p xtask -- check` inside two throwaway worktrees left a **~7.3 GB target dir each** (14.6 GB), taking the box under the floor between pushing the golden ref and the Windows jobs starting. **Corrective: do not run `xtask check` in disposable worktrees on this host** — CI gates docs drift anyway, and running a local copy of the gate starved the real gate. If a local run is truly needed, point `CARGO_TARGET_DIR` at ONE reused scratch dir.

**Reclaim recipe (14.5 GB → 51.1 GB in two steps):**
1. `git worktree remove` your finished worktrees — verify each is clean AND its head is pushed first. Plain `remove` (no `--force`) refuses a dirty tree, which is the safety you want.
2. Stale Claude session scratchpads under `%LOCALAPPDATA%\Temp\claude\C--Users-decid-Documents-projects-spt-core\<session-uuid>\` hold redirected cargo targets — 5–14 GB each. **Delete only clearly-ended sessions (quote the mtime, not "age"), never one written today**: a live peer's build cache is recoverable but costs them a long rebuild, which is not yours to impose. Never touch the shared project `target/` (154 GB, in active use by other agents).

**Reading a preflight red:** it is NOT a rerun-to-get-green situation — the platform never ran the code. Still hand it to the gater as a red per protocol; doyle's standing rule is no same-sha rerun without his triage ruling. Evidence the fix took: the `twohost` legs ran on the same box AFTER the reclaim and passed. See [[instrument-soundness-guards]] and [[v0480-published]].

**2026-08-01 — the class recurred at FULL exhaustion (0.00 GB free) and the root cause is now measured, not guessed.** It surfaces as `LNK1318: Unexpected PDB error` — sub-code `FILE_SYSTEM (3)`, then `LIMIT (12)` on retry — i.e. **disk exhaustion wearing a linker error's clothes**. Do not read the first LNK1318 as linker contention (I did, and was wrong); check `(Get-PSDrive C).Free` before diagnosing any link failure on this box.

Where it went, measured: `spt-core/target` **156 GB**, `Temp\claude` **112 GB** (of which **111.5 GB was spt-core sessions alone**), `.worktrees/gate-target` 22.6 GB, `~/.cargo` 2.1 GB. **The 112 GB is not junk — it is per-session cargo target trees agents build inside their own scratchpads** (`scratchpad/tgt|target|target-merge/debug/`), ~7 GB each. The redirect instinct (avoid contending with the shared target) is RIGHT; the private-tree mechanism is WRONG. The fix is [[worktree-target-junction]] — junction the worktree's `target` onto ONE warm `.worktrees/gate-target`. Doyle called a fleet sweep (each agent drops its OWN scratch; ownership is not tellable from outside since all agents run as the same OS user) and is putting the junction in AGENTS.md.

**Deleting the shared `target/` is doyle-authorizable, not unilateral** — it is pure cache but it is others' warm cache. His safety rail before deleting: sweep the process table for executables whose **path starts with** `spt-core\target` and reap **by path only, never by name**; a surviving handle makes the delete partially fail, so delete around it and note it. Result 2026-08-01: no holders, clean delete, **12.37 GB → 174.42 GB free** (162 GB reclaimed vs a 32 GB floor), gate-target warmth preserved. **Log free-GB before AND after — measured, not inferred.** The v0.50.0 golden then went green on ATTEMPT 1, the first single-attempt golden since this class started biting.

**Second resource class, same day (attempt 2 at `2a66d78`):** floor PASSED (86.3 GB), then the
Windows test leg died at BUILD time — `rustc-LLVM ERROR: out of memory` compiling spt-daemon lib
test, cargo exit 101, no test binary. Same UNTESTED-not-failing reading. Jobs sequential, not
contention. Host: 63 GB RAM / 15360 MB pagefile (undersized commit limit + parallel rustc codegen
= the fitting shape, NOT measured at OOM — kept as shape, not finding). Doyle's rulings: ship-
Windows-untested REJECTED; lever = runner-level machine-scope `CARGO_BUILD_JOBS=4` + service
restart (SHA-PRESERVING — a workflow-file edit would mint a new commit and forfeit tested-sha ==
shipped-sha); pagefile resize = operator machine config, flagged needs-operator on #56.
