Skip to content

Pre-push hooks start build-heavy jobs with no disk-space preflight #5470

Description

@MajorTal

Summary

A cold git push can take a developer machine from healthy to nearly full with no warning, because the pre-push hook launches several build-heavy jobs before anything checks free space.

lefthook.yml's pre-push runs just test-unit, just desktop-check, just desktop-typecheck, just desktop-test, just desktop-tauri-clippy && just desktop-tauri-test, and just mobile-test — in parallel, and with no disk preflight. On a cold Cargo target that is tens of GiB of build output committed to before the first byte is written.

Evidence

Measured on macOS with an empty ~/Developer/.cargo-target, pushing a branch that touched crates/** and desktop/**:

  • Free space before the push: 49 GiB
  • Free space ~2 minutes later, after aborting the hook mid-build: 34 GiB
  • ~/Developer/.cargo-target at that point: 12 GiB

That is ~15 GiB consumed in under two minutes, by a hook the developer invoked implicitly by typing git push. Left to run to completion it would have consumed substantially more. Nothing in the flow warns beforehand, and the failure mode when the disk does fill is not a clean "out of space" message — it is whichever of the parallel jobs happens to die first.

This is the local-workstation counterpart to #4302 (relay wedges on ENOSPC): same underlying hazard, different side of the system.

Why a guard rather than smaller jobs

The pre-push jobs are correctly scoped — they exist to catch what CI would catch, and shrinking them trades away local signal. The problem is not their size but that their cost is invisible until it has already been paid. A preflight makes the cost explicit and refusable.

Proposed shape

A small script the build-heavy hook entries call before their real command:

  • absolute thresholds rather than percentages, so behavior does not change with disk size
  • reserve a fixed budget for the checks, and require a fixed floor to remain afterward
  • documentation-only pushes stay unaffected (the existing globs already skip them)
  • fail open on unsupported/unparseable df output — the guard must never block a push it cannot reason about
  • tunable and independently bypassable via environment variables, so a developer with a warm target can opt out of only the disk guard without skipping the other hooks

Status

I filed this after the fact: #4531 already implements the above and is open. Filing it here per CONTRIBUTING.md's issue-first guidance, so the approach can be acknowledged (or redirected) separately from reviewing the diff — the thresholds and the fail-open choice are the parts worth a maintainer's opinion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions