Skip to content

Host limits wait for free disk space (#2091) - #2104

Merged
JacobStephens2 merged 4 commits into
mainfrom
issue-2091
Nov 12, 2026
Merged

JacobStephens2 merged 4 commits into
mainfrom
issue-2091

Conversation

@JacobStephens2

@JacobStephens2 JacobStephens2 commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Host limits gain a third check, free disk space. It is on by default, so a full disk delays new sessions instead of letting them fail on git worktree add or Session trace writes.

 [resources]
 min_available_memory_mb = 0   # 0 disables; default 0
 max_load_per_cpu_percent = 0  # 0 disables; default 0
+min_available_disk_mb = 5120  # free MB where worktrees and temporary files go; 0 disables; default 5120
 Limits::assess(host)
   memory below minimum?  -> reason
   load above maximum?    -> reason
+  disk below minimum?    -> "available disk 412 MB is below 5120 MB"
   ready = no reasons

 observe()
+  available_disk_mb = min(free(parent of the repository holding cwd), free(temp dir))   # statvfs f_bavail

 resources::wait() / Console header
-  skip when limits == Limits::default()
+  skip when every limit is 0 (Limits::OFF)
  • The default is 5120 MB, enough room for a typical session's worktree and build output.
  • The CLI Snapshot, the Console Resources page, the header indicator and the OpenAPI schema all show available disk and its minimum.
  • [resources] was missing from the guide's copy of the setup defaults. This PR adds it.

Seams tested:

  • Limits::assess and worktree_parent: unit tests.
  • User config DEFAULTS and parsing: unit tests.
  • thirdshift config resources.min_available_disk_mb round-trip: tests/user_config.rs.
  • thirdshift resources [--json]: tests/resources.rs.
  • The Console Resources page and header: tests/console/resources.rs and console/tests/resources.test.cjs.

Evidence

Execution evidence

The User config sets [resources] min_available_disk_mb = 9007199254740991, then the command thirdshift resources runs.

  • Before (main):
    thirdshift: invalid [resources] in the User config …/config.toml: unknown field `min_available_disk_mb`, expected `min_available_memory_mb` or `max_load_per_cpu_percent`
    exit=1
    
  • After:
    Available memory: 7301 / 8307 MB
    Available disk: 55262 MB
    Logical CPUs: 4
    One-minute load: 3.15 (78.8% per CPU)
    Minimum available memory: 0 MB; maximum load per CPU: 0%; minimum available disk: 9007199254740991 MB (0 disables each limit)
    Waiting for host resources: available disk 55262 MB is below 9007199254740991 MB
    exit=0
    

cargo test --bin thirdshift resources::tests:

test result: ok. 5 passed; 0 failed

The run covers these tests:

  • disk below its minimum waits, with the exact reason;
  • equality admits;
  • a minimum of 0 never blocks;
  • all three failing reasons are listed together;
  • the default waits on a full disk;
  • the worktree-parent rule.

Final validation: scripts/affected-tests main.

  • Passed: site, cargo build --locked and the Console browser tests.

  • cargo test: two runs each hit one flaky failure in an unrelated binary, and both of those tests pass when run alone.

    • tests/process/findings.rs: 18/18 passed, twice.
    • working-targets.test.cjs: 3/3 passed.
  • cargo test --no-fail-fast over the whole Rust suite then ran on the final head. Every binary passed except tests/process.rs, where 238 passed and 2 failed:

    • findings::fixing_dispatches_each_reproduced_finding_and_keeps_unreproduced_findings_private
    • findings::closing_rechecks_each_merged_base_and_leaves_a_failing_finding_for_the_day_shift

    Both fail with "created public issue(s) outside the staged path: Keeping the PR mergeable: merge the Base branch and conflict Repair #8". The fake gh stamps issues to the second, so a second publishing session's issues_created_since window can catch the first session's issue. Nothing in this PR touches Security fix publishing. Rerun on their own, both pass: cargo test --test process gave 240 passed and 0 failed. CI is the independent run.

Visual evidence

Console Resources page, /resources, with memory 2048 MB and load 100%; the disk minimum is left at its default.

Desktop, 1440×900

Before
After

Mobile, 390×844

Before
After

Merge Danger

Door: two-way

Setting min_available_disk_mb = 0 or reverting restores today's behaviour. No data is migrated.

Blast Radius: machine-wide

  • Every machine without [resources] now measures the host before each session, where it used to skip measuring altogether.
    • A host with less than 5120 MB free waits rather than starting a session.
    • A failed memory, load or statvfs read now fails the Command.
  • "Host limits off" now appears only when all three limits are 0.
  • The header indicator now shows live measurements on every Console page by default.
  • The Console and thirdshift resources measure the directory they were started in. See the triage issue below.

Review

Fixed point: refs/remotes/origin/main. The Standards reviewer raised 7 findings and the Spec reviewer raised 3.

Fixed:

  • Standards 1: site/architecture/index.html now names the disk wait.
  • Standards 2: the glossary and guide now say "memory, load and disk waits".
  • Standards 4: renamed the function to worktree_parent(cwd).
  • Standards 6: I ran the reviewer's command as written, with TMPDIR on a 100 MB tmpfs. resources::console_header_shows_host_admission_and_reloads_limits failed at tests/console/resources.rs:54, as the finding said. Tests that expect a ready host now set min_available_disk_mb = 1, both in Rust and in the browser test. Rerunning the command, both console resources tests pass.
  • Standards 7: the unit test now asserts is_ok().

Full-suite validation also caught tests/console/github.rs::history_freezes_do_not_wake_an_unchanged_inbox. It compared two full Inbox renders, and the header now carries live measurements, so it now compares the page below </header>.

Review coverage:

  • Excluded as generated output: site/docs/index.html. npm run docs:check --prefix site passes.
  • Changed by the fix commits after the review and not read by either reviewer:
    • GLOSSARY.md
    • site/architecture/index.html
    • console/tests/resources.test.cjs
    • tests/console/github.rs

Unaddressed findings

Standards

  • 3. Worktree placement is decided in two places.
    • src/worktree.rs sibling() needs a Git for the launch repository and runs git rev-parse --show-toplevel.
    • resources::observe has no Git. It runs on every 10-second Console header poll and outside any repository, for example a Console started from ~.
    • So worktree_parent (src/resources.rs) walks to the nearest .git without spawning git, and falls back to the directory itself.
  • 5. Shotgun Surgery in adding a limit. The reviewer noted it as following the existing pattern for memory and load, not as a request. Restructuring how limits are declared is beyond Host limits: wait for free disk space instead of starting sessions that fail on a full disk #2091.
  • 6, remaining part: every session-starting test waits on a runner with less than 5 GB free.

Spec

Closes #2091

Built with claude 2.1.314 · opus · default effort

Security review outcome

No unaddressed introduced findings.

A new [resources] min_available_disk_mb, 5120 by default, delays new
sessions while free space on the worktrees' filesystem, or the temporary
directory's when lower, is below it. The CLI and Console Resources
snapshot show available disk and its minimum.
…adiness tests

Name the disk wait on the architecture page, in the Command limit's
glossary entry and guide; rename worktree_parent; tests that expect a
ready host set a 1 MB disk minimum so a small TMPDIR can't flip them.
@JacobStephens2
JacobStephens2 merged commit 023559b into main Nov 12, 2026
21 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-2091 branch November 12, 2026 13:43
@JacobStephens2 JacobStephens2 mentioned this pull request Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Host limits: wait for free disk space instead of starting sessions that fail on a full disk

1 participant