fix(hooks): resolve pre-push workspace root from the main clone, not the worktree - #490
Open
ProtocolWarden wants to merge 2 commits into
Open
fix(hooks): resolve pre-push workspace root from the main clone, not the worktree#490ProtocolWarden wants to merge 2 commits into
ProtocolWarden wants to merge 2 commits into
Conversation
`git rev-parse --show-toplevel` returns the WORKTREE root. In a `git
worktree` checkout that is <clone>/.claude/worktrees/<name>, so
<repo_root>/.. was the worktrees dir — not the workspace holding the
sibling repos. Two things broke as a result, both only from a worktree:
* Boundary-artifact discovery globbed a directory containing nothing but
other worktrees, so every worktree push failed closed on
"missing REPOGRAPH_BOUNDARY_ARTIFACT_FILE" before the audit ever ran.
* The custodian-multi fallbacks all missed: a worktree has no .venv of
its own, and $workspace_root/Custodian/.venv/ pointed inside
.claude/worktrees/. With no PATH entry the hook died on
"custodian-multi not found" — the state of the WSL fleet box, where
<clone>/.venv/bin/custodian-multi is the only custodian present.
--git-common-dir always resolves to the ORIGINAL clone's .git: relative
to cwd for a plain checkout (".git" at the top level, "../.git" from a
subdirectory), absolute from a worktree. dirname + cd normalizes all
three, since cd interprets a relative path against cwd — which is
exactly what git means by it. Avoids --path-format=absolute so the hook
keeps working below git 2.31.
Added $main_repo_root/{.venv,.warehouse-venv}/bin/custodian-multi to the
binary candidates; for a plain checkout main_repo_root == repo_root and
they are harmless duplicates. Left the `command -v` PATH-first ordering
alone — it changes nothing in either environment today (Windows has no
repo venv, so PATH is the only candidate; WSL has no PATH entry, so the
venv already wins).
The audit target stays "$repo_root": we audit the content being pushed,
which is the worktree.
Verified from all three repo shapes — worktree, plain clone at top level
(how git invokes hooks), and plain clone from a subdirectory — each
resolving to the same main_repo_root/workspace_root and finding the
artifact. workspace_root for a plain clone is byte-identical to before,
so non-worktree pushes are unaffected. End-to-end run of the hook from a
worktree with REPOGRAPH_BOUNDARY_ARTIFACT_FILE unset now reaches the
audit instead of failing closed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
main already carries an equivalent workspace_root fix via #491, which bundled the same worktree discovery bug. Resolved in favour of main's version (git_common_dir/main_clone_root) — no reason to prefer my phrasing of an identical fix. What survives from this branch is the part main does NOT have: the custodian-multi candidate list still omits the main clone's venv, so a worktree push on a box whose only custodian-multi lives at <clone>/.venv/bin — no PATH entry, no sibling Custodian checkout, which is the fleet's layout — still fails "custodian-multi not found". Added main_clone_root/{.venv,.warehouse-venv} using main's variable name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The bug
.hooks/pre-pushderived the workspace root fromgit rev-parse --show-toplevel:--show-toplevelreturns the worktree root. In agit worktreecheckout that is<clone>/.claude/worktrees/<name>, so$repo_root/..was the worktrees directory — not the workspace holding the sibling repos.Two things broke as a result, both only from a worktree:
missing REPOGRAPH_BOUNDARY_ARTIFACT_FILE; failing closed— before the audit ever ran.custodian-multiresolution missed every fallback: a worktree has no.venvof its own, and$workspace_root/Custodian/.venv/pointed inside.claude/worktrees/. With no PATH entry the hook died oncustodian-multi not found. That's the exact state of the WSL fleet box, where<clone>/.venv/bin/custodian-multiis the only custodian present.The fix
--git-common-diralways resolves to the original clone's.git:dirname+cdnormalizes all three forms git emits —.gitat a clone's top level,../.gitfrom a subdirectory, absolute from a worktree — becausecdinterprets a relative path against cwd, which is exactly what git means by it. This avoids--path-format=absolute(git 2.31+), so the hook keeps working on older git rather than introducing a needless version floor.Also added
$main_repo_root/{.venv,.warehouse-venv}/bin/custodian-multito the binary candidates. For a plain checkoutmain_repo_root == repo_root, so they're harmless duplicates of the existing entries.The audit target stays
"$repo_root"— we audit the content being pushed, which is the worktree.What I deliberately left alone
The
command -v custodian-multiPATH-first ordering. I checked whether reordering would help: it changes nothing in either environment today. Windows has no repo venv, so PATH is the only candidate; WSL has no PATH entry, so the venv candidate already wins.Verification
Resolution probed from all three repo shapes:
main_repo_root…/GitHub/OperationsCenter…/GitHub/OperationsCenter…/GitHub/OperationsCenterworkspace_rootfor a plain clone is byte-identical to before, so non-worktree pushes are unaffected.End-to-end run of the real hook from a worktree with
REPOGRAPH_BOUNDARY_ARTIFACT_FILEunset now printsboundary artifact: …/PrivateManifest/dist/boundary_disclosure_artifact.jsonand proceeds to the audit, instead of failing closed at discovery.bash -nclean. (shellcheck isn't installed in either environment, so it wasn't run.)custodian-multiagainst this branch: 0 findings, clean.No log.md entry
.hooks/is in the pre-commit guard'sTRIVIALexemption, so a hook-only commit doesn't require one. Skipping it also avoids a guaranteed top-of-file conflict with #487, which is open concurrently — the same conflict problem theoc-watchdog/*exemption comment in.hooks/pre-commitdescribes. The root cause is documented inline at the point of use instead.🤖 Generated with Claude Code