mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-17 10:25:33 +02:00
fix(freeze): hook reads the same state root /freeze writes — fails closed under GSTACK_HOME (#1459, #1509)
check-freeze.sh resolved its state dir as ${CLAUDE_PLUGIN_DATA:-$HOME/.gstack}
while every writer (/freeze, /guard, /unfreeze, /investigate) resolves through
bin/gstack-paths, GSTACK_HOME first. With GSTACK_HOME set, /freeze wrote
freeze-dir.txt under GSTACK_HOME, the hook read $HOME/.gstack, found no file,
and allowed everything — a deny-tier boundary failing open.
One resolver now: gstack_hook_state_root() in careful/bin/hook-extract.sh
(already sourced by both check-freeze.sh and check-careful.sh) implements the
exact gstack-paths chain, including the CLAUDE_PLUGIN_ROOT guard that keeps a
CLAUDE_PLUGIN_DATA leaked from another plugin from redirecting our state.
check-freeze.sh and gstack_hook_log_fire both call it; nothing spawns
gstack-paths from a hook.
Tests: the GSTACK_HOME deny regression, GSTACK_HOME-over-CLAUDE_PLUGIN_DATA
precedence, plugin-root guard both ways, and a byte-parity check against
bin/gstack-paths across six env combinations. Existing freeze tests now pass
CLAUDE_PLUGIN_ROOT like a real plugin install would.
Idea from PR #1509 (@NikhileshNanduri); implemented natively against the shared
resolver rather than a second fallback chain.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
0d1bd5616c
commit
17733302cc
@@ -31,8 +31,12 @@ if [ ! -f "$_HOOK_HELPER" ] || ! . "$_HOOK_HELPER" 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Locate the freeze directory state file
|
||||
STATE_DIR="${CLAUDE_PLUGIN_DATA:-$HOME/.gstack}"
|
||||
# Locate the freeze directory state file. The writer (/freeze via
|
||||
# gstack-paths) and this reader MUST resolve the same root or the boundary
|
||||
# fails open: with GSTACK_HOME set, /freeze wrote freeze-dir.txt under
|
||||
# GSTACK_HOME while this hook read $HOME/.gstack, found nothing, and allowed
|
||||
# everything (#1459, #1509). gstack_hook_state_root mirrors gstack-paths.
|
||||
STATE_DIR="$(gstack_hook_state_root)"
|
||||
FREEZE_FILE="$STATE_DIR/freeze-dir.txt"
|
||||
|
||||
# If no freeze file exists, allow everything (not yet configured)
|
||||
|
||||
Reference in New Issue
Block a user