Per-user build cache discipline — preventing cross-user Cargo races
editorial(patterns+architecture): enrich 2 thin articles — Key Takeaways for zero-execution-routing + cargo-target-per-user-discipline (EN+ES) — Phase 6
@@ -16,6 +16,13 @@ paired_with: cargo-target-per-user-discipline.es.md Cargo's incremental build cache lives under `target/`. By default that is a per-crate directory inside each crate. The workspace overrides this via the `CARGO_TARGET_DIR` environment variable pointing at a shared path, so the build cache is shared across all crates in the monorepo — saving disk space and rebuild time. ## Key Takeaways - With a shared `CARGO_TARGET_DIR`, two concurrent `cargo build` calls compete for `target/.cargo-lock` and interleave file ownership, causing sporadic `Permission denied` errors during incremental rebuilds — even when the crates being built are completely unrelated. - Fix: a system profile script sets `CARGO_TARGET_DIR` to `<shared-root>/$USER/`, giving each developer a private build cache subdirectory. Within-user incremental compilation is preserved; cross-user file-ownership collisions are eliminated. - `CARGO_TARGET_DIR` takes precedence over `~/.cargo/config.toml`'s `target-dir` setting. The change takes effect on any new shell without per-user dotfile edits — a system-level profile script is the enforcement point. - The lesson generalises beyond Cargo: any group-writable shared path needs explicit design around which operations are safe to share (reads, content appends) and which require per-user partitioning (build state, lock files, temporary directories). This works for a single developer. With two developers in the workspace group it becomes a race. Cargo's `target/.cargo-lock` serialises full-tree builds, so two `cargo build` invocations on different crates block one another. Worse, mixed file ownership — build artefacts written by one user interleaved with another user's — causes sporadic `Permission denied` errors during incremental rebuild, even when the crates appear to be unrelated. The fix: a system profile script exports `CARGO_TARGET_DIR` pointing at a per-user subdirectory (`<shared-root>/$USER/`). Each user gets a private subdirectory. The build cache stays shared within a user — the original optimisation is preserved — but no longer crosses users. The environment variable takes precedence over `~/.cargo/config.toml`'s `target-dir` setting, so the change takes effect on any new shell without per-user dotfile edits.