fix(perf): stop loading hard-link-directory on every bit invocation; self-diagnosing fs-read guard - #10599
fix(perf): stop loading hard-link-directory on every bit invocation; self-diagnosing fs-read guard#10599luvkapur wants to merge 3 commits into
Conversation
…make fs-read guard self-diagnosing The nightly e2e_test_bbit job has been red since 2026-07-23: the released bundle's 'bit status' crossed the MAX_FILES_READ_STATUS=1515 guard (1532, creeping to 1541 by 2.0.74). Root cause, found by diffing BIT_DEBUG_READ_FILE output of bvm-installed 2.0.33 (last green) vs 2.0.35 (first red): #10515's dependency change reshaped the bundle's pnpm hoisted layout, so @teambit/toolbox.fs.hard-link-directory plus a private fs-extra tree load from a nested copy under the compiler package instead of a shared hoisted copy (~+21 reads). The nightly creep (+1-3) is the same mechanism - each nightly re-resolves transitive deps and hoisting shifts add nested duplicates. Three changes: - compiler.task.ts imports hard-link-directory lazily inside the build task - it is build-time-only, yet its top-level import pulled ~36 files into every bootstrap/status in the bundle layout. - the bit-status guard failure now prints WHICH files are new vs a snapshot (files-snapshot-status.txt, generated from the released 2.0.74 bundle), same as the bootstrap guard - a red is a 2-minute diagnosis, not a 3-week mystery. Layout-mismatched diffs (repo vs bundle flavor) degrade to a count + sample instead of noise. - threshold 1515 -> 1650: headroom for bundle-layout drift, which the diff in the error message now makes visible and attributable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR Summary by QodoLazy-load hard-link-directory and add self-diagnosing fs-read guard for bit status
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1.
|
…ten threshold to 1600; print full file list on failure Addresses the Qodo finding on #10599: the snapshot was generated from a local macOS run of the released bundle - correct flavor, but a superset of what CI's leaner fixture reads. Regenerated inside a linux/amd64 node:22.22.0 container from the released linux-x64 bundle (1,878 entries; the mac and linux sets share 1,860 of ~1,870 files, so flavor was never the issue - offline supersets are inherent). Two hardenings follow from accepting that limit: - the guard now calls makeSnapshot() on failure, printing the complete current install-file list, so every red carries the exact data to inspect masked files and regenerate a perfect snapshot from real CI output - threshold 1650 -> 1600: the post-fix baseline is a projection (1541 - ~36 lazy-import reads = ~1505) and drift events arrive in ~+20 lumps; 1600 = projection + error margin + two events. Re-tighten to measured + ~50 once post-fix nightlies establish the real baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l reads Replaces the threshold-bump approach. The raw-reads metric conflated two things: bit loading more code (the regression the guard exists to catch) and pnpm hoisting layout drift duplicating physical copies of the same modules (packaging noise that reshuffles every nightly bundle). Measured across the incident that motivated this: 2.0.33 -> 2.0.35 physical unique files went 1836 -> 1857 (dup copies 211 -> 232) while logical modules stayed exactly 1625 -> 1625 - the three-week nightly red was 100% duplication noise, 0% new code. The guard now counts unique logical modules (paths normalized past the last node_modules/ segment), which: - is immune to the entire layout-drift noise class - no headroom needed, the interim 1650/1600 bumps are gone - converges for both install flavors (repo .pnpm layout and released hoisted bundle), so one snapshot serves both (files-snapshot-status.txt is now logical ids, 1,645 entries from the released linux-x64 bundle) - still catches real regressions (verified: an injected module is reported by name; measured logical baselines 1625-1645 vs threshold 1700) Every run also prints a physical/logical/duplication report line so CI logs accumulate true per-environment baselines - the threshold tightens to measured+~30 once those land, and duplication trends stay visible without failing anyone. Bootstrap guard unchanged (stable, its own physical snapshot); migrate it the same way once its CI report lines accumulate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why
e2e_test_bbit(nightly, 32 nodes) has been red since 2026-07-23 — 19 of the last 21 failures are one single test out of ~2,900: thebit statusfilesystem-read guard (MAX_FILES_READ_STATUS = 1515, actual 1532 → 1541 and creeping).Root cause
Diffing
BIT_DEBUG_READ_FILEoutput of bvm-installed 2.0.33 (last green) vs 2.0.35 (first red) — only two commits apart — shows no new runtime reads. Instead, #10515's dependency change reshaped the released bundle's pnpm hoisted layout:@teambit/toolbox.fs.hard-link-directoryplus a full privatefs-extratree now load from a nested copy under the compiler package instead of a shared hoisted copy (~+21 reads). The nightly +1–3 creep is the same mechanism — every nightly bundle re-resolves latest transitive deps, and hoisting shifts occasionally add nested duplicates (p-limit,pify,ssri,mimic-fnappeared between 2.0.35 and 2.0.74).Changes
compiler.task.ts: lazy-importhard-link-directory— it is used only inside the build task, yet its top-level import pulled ~36 files into every bootstrap/bit statusin the bundle layout. Verified the compiled dist defers the require until the task executes. This alone puts the bundle back under the original threshold.bit statusguard now counts unique logical modules, not raw physical reads — paths are normalized past the lastnode_modules/segment, so duplicate copies of the same module (the entire layout-drift noise class) count once. Measured on the incident itself: 2.0.33 → 2.0.35 physical files went 1836 → 1857 while logical modules stayed exactly 1625 → 1625 — the three-week red was 100% duplication, 0% new code. The metric converges for both install flavors, so one snapshot (files-snapshot-status.txt, logical ids from the released linux-x64 bundle in a clean container) serves repo and bundle runs alike. No drift headroom needed: threshold 1700 vs measured baselines 1625–1645, to be tightened to measured+~30 from the report line below.total reads / physical files / logical modules / duplicate copiesreport line, accumulating true per-environment baselines in CI logs and keeping duplication trends visible without failing anyone. Verified against captured outputs of 2.0.33/2.0.35/2.0.74 (mac + clean linux container): all pass, an injected synthetic regression is pinpointed by name.Verification
npm run lintgreen (oxlint + tsc).bit compile teambit.compilation/compiler— dist verified lazy:await Promise.resolve().then(() => require('@teambit/toolbox.fs.hard-link-directory')).🤖 Generated with Claude Code