Skip to content

fix(spawn): capture worktree lease by repo-identity, not treehouse root#218

Open
maximebrmd wants to merge 4 commits into
kunchenguid:mainfrom
maximebrmd:fm/harden-worktree-path-capture
Open

fix(spawn): capture worktree lease by repo-identity, not treehouse root#218
maximebrmd wants to merge 4 commits into
kunchenguid:mainfrom
maximebrmd:fm/harden-worktree-path-capture

Conversation

@maximebrmd

Copy link
Copy Markdown

What Changed

  • Replaced the spawn worktree-capture check in bin/fm-spawn.sh: instead of accepting the first pane cwd that merely differs from the project dir (which could latch onto shell-init noise like a transient ~/.oh-my-zsh cwd), it now accepts a path only when it is a genuine worktree of the same repository, comparing canonical git common dirs and resolving every path with pwd -P so a symlinked $HOME or a non-default treehouse pool root no longer breaks the match.
  • Made the worktree wait window configurable via FM_SPAWN_WORKTREE_WAIT (default 60s), threaded through the loop and the timeout error message, and documented it in docs/configuration.md.
  • Guarded the bash 3.2 empty-array expansion in bin/fm-pr-merge.sh and updated tests/fm-tangle-guard.test.sh for the new repo-identity worktree check.

Risk Assessment

✅ Low: A well-bounded 46-line change to a single spawn helper that faithfully replaces a brittle treehouse-root containment check with a symlink-safe repository-identity check, keeps the existing isolation guard as a backstop, and leaves no orphaned code.

Testing

Completed 1 recorded test check.

  • Outcome: 🔧 1 issue found → auto-fixed ✅ across 2 runs (25m25s)

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 2 issues found → auto-fixed ✅
  • ⚠️ bin/fm-spawn.sh:655 - is_treehouse_worktree gates lease capture on containment under TH_ROOT=${FM_TREEHOUSE_ROOT:-$HOME/.treehouse}, but treehouse's pool root is configurable via treehouse.toml (root key: worktrees are placed under {root}/.treehouse/, e.g. root = &#34;./&#34; puts them under <repo>/.treehouse/). For any repo with a non-default treehouse root, the captured pane cwd will never be under $HOME/.treehouse, so the loop never selects, and spawn fails with the confusing 'treehouse get did not enter a worktree within 60s' timeout unless the operator knows to set the undocumented FM_TREEHOUSE_ROOT env var. Since this repo is a shared template for every user, consider deriving the root from treehouse.toml (or relaxing to 'is a git worktree distinct from PROJ_ABS' and relying on the existing isolation guard) rather than assuming $HOME/.treehouse.
  • ℹ️ bin/fm-spawn.sh:429 - The containment check uses raw string-prefix matching (path_is_ancestor_of) between the tmux pane_current_path (a resolved physical path on macOS/Linux) and the unresolved TH_ROOT ($HOME/.treehouse). If $HOME contains a symlinked component (common on some Linux hosts where /home is symlinked), the physical pane path won't be prefixed by the logical $HOME and the match silently fails, causing the same 60s timeout. The later isolation guard resolves both sides with pwd -P; this new pre-check does not.

🔧 Fix: replace treehouse-root check with repo-identity worktree check
✅ Re-checked - no issues remain.

🔧 **Test** - 1 issue found → auto-fixed ✅
  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: guard bash 3.2 empty array in pr-merge; fix stale spawn worktree test
✅ Re-checked - no issues remain.

  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

The worktree wait loop accepted the first pane cwd that differed from the
project dir, so shell-init noise (e.g. a transient ~/.oh-my-zsh cwd during zsh
startup - itself a git repo, so the post-loop isolation guard would fail the
spawn rather than wait) could be captured. Require the captured path to be an
existing git worktree under the treehouse root, so the loop keeps polling for
the genuine lease; the isolation guard remains the backstop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant