Repository navigation
A computer's disk is read after each start and save, and its owner told as it fills - #1015
futurepaul wants to merge 3 commits into
Conversation
…ld as it fills
A computer whose disk filled could not start again, and nothing told its
owner it was filling. Now the cell reads its container's disk (df -P -B1
/, one exec, best effort) after each start comes up and after each save:
the restored and saved log lines carry {total, free}, its saves keep the
last read, and a new notice, disk_filling {total, free} (add-only),
tells its owner the room left once a read finds it used past 80% with at
most 5 GB free (a computer's own 20 GB disk at 4 GB; a dev box's or CI's
shared disk is not told of room it has plenty of). Its words live beside
the set-aside ones in cell/shell/computer.js.
Kept small for the Wasm budget: no view field (the notice carries what
it needs, the log lines the rest) and no test lever; the computers lane
reads the real disk as a start comes up and after a save, and the core's
and shell's tests prove when it is told.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
futurepaul
left a comment
There was a problem hiding this comment.
Codex review @ 6da69fa: CHANGES
-
Keep best-effort disk reads outside the start-success deadline —
cell/src/computer.rs:1152.try_starthas succeeded, butEvent::Readyis not returned until the new five-secondread_diskawait completes. The lifecycle remains Starting meanwhile, and its deadline alarm can mark it failed. For example, a restore/check/gate completed at 899 seconds previously succeeded; a timed-outdfnow lets the 900-second alarm fire, and the later Ready is ignored in Asleep. The current restore budget already allocates all 900 seconds and neither it nor the timing assertions includesDISK_READ_MS. A deterministic lifecycle probe reproduces the failed transition. Apply successful readiness before awaiting telemetry, or explicitly budget/skip the read so it cannot push success past the deadline; cover this ordering without sleeps and update affected timing guards. -
Add a separate clearing threshold to prevent notice flapping —
crates/core/src/computer.rs:2017and:2254. The notice uses the same instantaneous threshold to appear and disappear. On a 20 GB disk, consecutive readings of 3,999,995,904 and 4,000,004,096 free bytes alternate the notice on/off; the same issue exists around the 5 GB cutoff on larger disks. I reproduced[true, false, true, false]throughSaves::measuredandnotices. Ordinary temporary-file/cache changes can therefore repeatedly remove and re-add the warning. Keep the warning latched until a clearly higher free-space/lower-used threshold is reached, with compatible persisted state and tests that oscillate around both boundaries.
Reviewed only this PR's diff above #1007. Ordinary exec/parse/storage failures are swallowed as intended, and older Saves JSON defaults the disk cache to absent. Validation: 57 core computer tests, 5 proto computer tests, and both shell disk tests passed; the additional deterministic probes exposed the cases above. No Docker or e2e run.
"Your computer is almost full (3.2 GB left). Delete files you don't need, or ask an agent to tidy up.", the number its real free space as the notice carries it. One line, as the updating notice is; its test holds the words exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex on #1015: the disk read sat between a start's restore and its Ready, so a restore that ended near the deadline plus a slow df could let the deadline fail the start, its late Ready ignored. The read now comes after the event is applied (reads_disk_after): once a start's Ready made it awake, or an awake save worked; never a sleep's save, whose stop follows. It logs a disk line of its own. And the notice flapped: one threshold showed and cleared it, so reads a few KB apart at the edge told and untold it in turn. It now latches (Saves' disk_told, a cache like the read): told at 80% used with at most 5 GB free, cleared only at 70% used or 6 GB free. Tested around both edges, a computer's disk and a host's shared one; the lane reads the disk once a start is ready, after an awake save, and at the next start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
futurepaul
left a comment
There was a problem hiding this comment.
Codex review @ 089e586: PASS
The disk read now follows application of Ready/Saved and their actions, so it no longer holds a successful start in Starting or delays a sleep's save. The persisted defaulted latch has distinct set/clear thresholds, covers oscillation at both boundaries, and preserves stale-read rejection; Paul's wording is reflected in the shell tests. All 58 core computer tests, 5 proto computer tests, and both shell disk tests passed; no Docker or e2e run.
Stacked on #1007. A production computer whose disk filled could not start again, and nothing told its owner it was filling.
The change
df -P -B1 /(DISK_READ, best effort, 5 s), after each start comes up and after each save.ComputerDisk {total, free, at}). That's a cache: a release from before it drops the value, and the next read restores it.restoredandsavedlog lines carry{total, free}.disk_of_dfparses both GNU's output (the Hermes image) and BusyBox's (the stub).disk_filling {total, free}(add-only), tells the owner the room left once a read finds the disk used past 80% (DISK_TOLD_USED_PCT) and at most 5 GB free (DISK_TOLD_FREE_MAX).cell/shell/computer.js(diskSaid): "Your computer is almost full (3.2 GB left). Delete files you don't need, or ask an agent to tidy up." The number is the real free space the notice carries, in GB, or in MB under a GB.Tests
a_disk_is_read_from_df: GNU and BusyBox output, and every malformed case;a_disk_filling_is_told_until_a_read_finds_room: the 80% and 5 GB edges, a shared host disk, order and replay, a read with more free than its size refused, and saves stored before it;disk_fillingit tells.cell/shell-tests/computer-disk.test.mjs(node --test) checks the words exactly, in GB and in MB.DISK_CHECKS: the real disk is read as a start comes up, and read again, newer, after a save. Thesaveslever shows the reading, and each read is judged by what made it, never a fixed wait.cargo xtask checkexit 0, andcargo xtask e2e --only computers: 284 passed, 0 failed, both on this head (A folder that will not fit is set aside, never a computer that will not start #1007'sbc9e302d9plus this commit).🤖 Generated with Claude Code