fix(hooks): resolve guard paths as the kernel does #175
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/guard-resolve"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
After #169, the main-checkout guard still let an agent write into a main
checkout on its main branch in several ways, by mistake or following
injected text:
.., such asout/lnk/../README.mdwithout/lnk -> repo/docs, since the guardentered directories with a logical
cdthat drops the..beforefollowing the link, while the kernel follows it first;
cdended the guard with status 1, which Claude Code lets through;
checkout, since the guard never resolved a path's last name, including
a link reached past a missing directory or named with a trailing
newline, which command substitution cut.
Checking only as the kernel resolves (
cd -P) was set aside: a symlinkinside the checkout pointing out, followed by
.., would then pass,though a client that normalizes the path as text writes into the
checkout, and the guard refuses that case today.
What changed
The guard checks each edited path both as the kernel resolves it and as
text, refusing when either lands in a guarded checkout, and follows the
last name link by link, up to 40 as the kernel does, checking each
target. A path it cannot resolve is refused, with a message naming it.
Paths keep their trailing newlines throughout. Every path the guard
passed before that lands in no guarded checkout either way still passes.
How to verify
In a scratch directory, make a repository on
mainand run the guardwith an edit through a symlink to its README:
The branch prints the refusal and
exit 2; main printsexit 0. Withmkdir repo/docs; ln -s "$PWD/repo/docs" out/intoand the path$PWD/out/into/../README.md, the same pair shows for the..case.The source's Maintenance checks pass on the tip:
bash tests/verify-agent-config.sh(328 passed),bash tests/check-work-folder.sh,.agents/hooks/shellcheck.sh repo,prettier --check '**/*.md',scripts/verify-agent-config.sh, andgit diff --check main. Intests/agent-config/main-checkout-guard.shthe six new cases fail on main, and the pin for the text case passes on
both. How OpenCode resolves a written path was not checked, as no
install was at hand; Claude Code trims the path before hooks see it.
Considerations
The case for a directory the guard cannot enter prints a skip line
where the user can enter a mode 0600 directory, as root does.