fix(teardown): prevent descriptor exhaustion during Treehouse return - #26
Open
ruby-dlee wants to merge 2 commits into
Open
fix(teardown): prevent descriptor exhaustion during Treehouse return#26ruby-dlee wants to merge 2 commits into
ruby-dlee wants to merge 2 commits into
Conversation
ruby-dlee
force-pushed
the
fm/fm-reap-fdcap-r7
branch
2 times, most recently
from
July 25, 2026 18:22
a04ae44 to
df082bc
Compare
ruby-dlee
force-pushed
the
fm/fm-reap-fdcap-r7
branch
from
July 25, 2026 19:01
df082bc to
eb24f90
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Prevent production teardown failures on realistically sized repositories by capping the directory descriptors inherited by
treehouse return --force.Relvino worktrees contain about 41,884 directories.
The previous walk retained one descriptor per directory and made every descriptor inheritable across
exec, which caused Treehouse and its Git child to fail withToo many open files.What changed
os.fchdircontinues to bind Treehouse to the intended worktree.O_NOFOLLOWchecks.Security boundary
The retained root descriptor still binds Treehouse to the validated worktree if the root pathname is replaced with a symlink before Treehouse acts.
Descendant validation is now explicitly point-in-time.
Descendant descriptors are not retained across
exec, so the previous test's stronger claim that every descendant identity remained bound during a mid-return swap no longer holds.The test now pins the surviving root-binding guarantee instead of silently claiming otherwise.
Deliberate non-goal
The pre-existing failed-spawn rollback failure on
origin/mainis not addressed here and is tracked separately asfm-rollback-lock-assertion-red.That rollback path currently fails before Treehouse is involved.
The pre-existing full-repository Lint and Behavior reds are also not addressed here and are tracked separately as
fm-main-green-g7.This capacity-only PR does not change
tests/fm-account-routing.test.sh, the rollback implementation, or any of the files reported by the baseline lint failure.It must not be read as fixing the separately tracked lock-owner assertion or main's unrelated lint and behavior failures.
Verification
bash tests/fm-checkout-return-boundary.test.shFM_TEST_FOCUSED=treehouse-return-root-swap bash tests/fm-teardown.test.shFM_TEST_FOCUSED=treehouse-return-directory-capacity bash tests/fm-teardown.test.shbash -n bin/fm-checkout-lock-lib.sh tests/fm-checkout-return-boundary.test.sh tests/fm-teardown.test.shgit diff --checkThe local machine does not currently have the repository's pinned ShellCheck 0.11.0 binary, so the local lint command reported only that missing-tool condition.
CI installs the pinned binary before running
bin/fm-lint.sh -xand is the authoritative lint result.Pipeline provenance
Updates from git push no-mistakes
No-mistakes run
01KYDAETNSKB9ADWAG322ZFKY4completed intent, rebase, and push for this exact capacity-only head with outcomepassed.Review, test, document, lint, PR, and CI were deliberately skipped in that provenance-only run because the capacity checks are recorded above and the separately assigned
fm-main-green-g7owns the pre-existing full-repository reds.