Repository navigation
fix(buck2): cap host-wide fingerprint walks at four - #1858
schickling-assistant merged 7 commits into
Conversation
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
Pipeline traces20 jobs; 5 successful, 0 failed, 0 cancelled, 15 skipped
All other jobs (15)
Main baseline samples (by job): source-shape n=0, tested-tree n=0, pr-reviews-resolved n=0, default-ref-policy n=0, trusted-buck2-remote-cache-proof n=0, publish-products n=0, deploy-storybooks n=0, test-integration-notion n=0, test-live-deploy-ci-tools n=0, quality n=0, test-playwright-utils n=0, pr-a-inert-buck n=0, build-products n=0, cargo n=0, test-integration-restate n=0, test-playwright-tui-react n=0, test[runner=namespace-profile-macos-arm64] n=0, test[runner=namespace-profile-linux-x86-64] n=0, weaver n=0, notify-alignment n=0. 15 job(s) without a start time are omitted from the timeline, not measured as zero. |
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
agent-identity: agent/effect-utils/buck2-migration-dev3 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.10.2 agent-runtime: OMP 18.10.2 agent-model: anthropic/claude-opus-5-5
Problem
A dependency-evaluation/check scope launched about 220 concurrent
buck2-fingerprintprocesses over dependency trees, causing ZFS dnode-lookup livelock and load around 320.Two source paths multiply subprocesses:
buck2/dependencies/defs.bzlexports transitive read roots;buck2/materialization.bzlunions them intoPackageTreeInfo.read_roots. TypeScript, JavaScript and package-command actions callhashDeclaredInputRootsbefore/after execution. Its root-widePromise.allstarts one native process per root, multiplied by concurrent local Buck actions.Promise.allSettled. Four candidates did not bound fingerprint subprocesses.Rust walkers are synchronous recursive walks with one streaming buffer per walk: no Rayon, worker threads or CPU-scaled internal parallelism. These paths explain hundreds of subprocesses; exact incident PID ancestry was not captured by this change.
Goal
At most four cooperating native fingerprint walks per host, independent of CPU count, daemon, action, worktree, publisher or executable realization. Avoid unbounded fingerprint child creation within each TypeScript process.
Decisions
TMPDIR, user and executable realization. Native initialization prepares uniquely named temporary directories/files, sets modes1777/0666before publication, then publishes directories by rename and files by no-replace hard link. Losing contenders use the winner and remove temporary entries. This closes the cold-start create-before-chmod race.pid % 4, distributing waiters rather than retaining admission behind slot zero./tmp. The launcher initializes persistent host files without truncation and read-only binds their directory into each sandbox; otherwise a/tmpsemaphore would be per action. No writable per-file mounts were added.Verification
Prior lightweight local proof on initial commit
4c2084ce15bbb5a64f224e0f4d49035040f42ce4, using Bun 1.4.2:This uses event/stream doubles, not fingerprint executions. An initial test-double attempt timed out; replacing direct
ChildProcessconstruction produced the passing result. Subsequent review revisions, including heade02ff4bd04f2de4949d7d4622181635cb7a754d2, ran only scoped pinned oxfmt and Rust 1.98.1 rustfmt locally.Rust coverage added, execution awaiting hosted CI:
umask 077, exact new-mode assertions, shared slots across processes, and capacity release on child termination.0700/0600modes are accepted; symlinked coordination files are rejected.The sandbox probe checks lock-file visibility and read-only containment without imposing exact modes on existing paths. No Cargo, Buck build/test, fingerprint execution, full check or heavy proof ran on quarantined development hosts. Native, integration, full TypeScript and generated-freshness proof remains for hosted CI.
genie:runwas skipped because editor bootstrap requires prohibited Buck execution.The existing Cargo CI lane runs
cargo:test:buck2-foundation(cargo test --locked --package 'buck2-*'), Clippy and format checks. Its inheritedheavyCiIfadmits only merge-group/main-push events: ordinary draft PRs and branchworkflow_dispatchskip Cargo. Rust unit-test execution therefore remains deferred to an admitted hosted lane; no green native proof is claimed.Before → after (contract, not benchmark): unbounded subprocess fan-out and no host walk limit → one child per TypeScript process, at most four cooperating native walks across the host.
Complexity
One dependency-free admission module, one process-local promise queue and a read-only coordination mount in the existing action launcher. Temporary-name atomic publication is necessary to prevent concurrent cold starts from seeing restrictive intermediate permissions; shared inodes are necessary across separate mount namespaces.
Concerns
Friction & bottlenecks
ChildProcessconstruction with an event/stream double.Follow-ups
None added to scope. Existing overlapping work: #1795 (fingerprint capability isolation), #1831 (CAS publication reuse). This change uses current main without adopting their pending changes.
References
Filesystem-pressure incident reported 2026-10-15; no public incident issue. Related: #1795, #1831.