uphold 1.14.1: the shim cannot spawn itself - #135
Conversation
Point the documented pins at 1.14.1 and bump the crate version. Patch, not minor. No name a policy can write changes. The one change since 1.14.0 is #134, which closes the loop reported in #133: on 2026-09-02 a git push inside this repository's own checkout, under the released v1.13.0 binary, spawned roughly 250 processes a second and drove the load average past 3000, because the shim's own public-target probe resolved gh through PATH to itself and the tree's policy had grown a match entry that probe's argv hit. 1.14.0 removed one trigger by exempting the bodyless GET. This removes the mechanism: every internal spawn of git, gh or glab from the decision path carries UPHOLD_SHIM_INNER, and the entry point seeing that marker resolves the real tool and hands over without judging. The value counts, so a regression in that passthrough is bounded by a refusal at depth rather than by the machine. Landed in this release: #134. A policy written against 1.14.0 loads unchanged, and a consumer who bumps a rev or a ref gets no new refusal. The marker is documented beside UPHOLD_ALLOW because exported by hand it is that variable under another name, and it prints the same unchecked notice on stderr. Claude-Session: https://claude.ai/code/session_01HEudouCNhFHK6UPEWcWqXd
|
Warning Review limit reachedNext included review available in 45 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #135 +/- ##
=======================================
Coverage 93.41% 93.41%
=======================================
Files 38 38
Lines 14443 14443
=======================================
Hits 13492 13492
Misses 951 951 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Point the documented pins at 1.14.1 and bump the crate version: Cargo.toml,
Cargo.lock, README.md, hooks/lefthook.yml.
Why a patch
No name a policy can write changes, and no seam starts refusing anything it
allowed at 1.14.0. A consumer who bumps a
revor arefgets a binary thatanswers its own questions without asking itself.
The single change since 1.14.0 is #134, which closes #133. On 2026-09-02 a
git pushinside this repository's own checkout, under the released v1.13.0binary, spawned roughly 250 processes a second and drove the load average past
3000; nothing short of
kill -9 -<pgid>stopped it. The shim answers apublic-targetscope by runninggh api repos/<owner>/<repo>, PATH resolvesthat
ghto the shim, and the tree's policy had grown anapi:*match entrythat the probe's own argv hits. So v1.13.0 fork-bombs a workstation whenever
its policy gains a match entry a probe's argv hits.
v1.14.0 removed one trigger, by exempting a bodyless GET. It did not remove the
mechanism: any other new
matchentry, or a binary and a policy that disagreeabout which entries exist, reopens it, and
Target::GitRemotehad the sameexposure through
git remote get-url originwith no exemption in front of itat all.
#134 removes the mechanism. Every internal spawn of
git,ghorglabfromthe decision path goes through
shim::inner_tool, which marks the child withUPHOLD_SHIM_INNER=<depth>; the entry point, seeing the marker, resolves thereal tool through the PATH walk that already skips its own file and hands over
without judging, before the working directory and before the policy. The value
counts rather than flags, so past depth 2 the seam refuses with exit 2 and
names the loop: a regression in the passthrough is bounded by a refusal rather
than by the machine.
Verification
cargo build,cargo test(762 pass, 0 fail),cargo clippy --all-targets,cargo fmt --checkandprek run --all-files --hook-stage manualare allclean on this branch.
https://claude.ai/code/session_01HEudouCNhFHK6UPEWcWqXd