You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
question-preference-hook looks up preferences under basename(cwd) while gstack-question-preference writes them under the owner-repo slug — never-ask silently never fires #2901
never-ask preferences written by bin/gstack-question-preference --write are never honored by the PreToolUse hook. The writer files them under the canonical owner-repo slug (~/.gstack/projects/<owner-repo>/question-preferences.json), but hosts/claude/hooks/question-preference-hook.ts looks them up under path.basename(cwd). For any repo with an origin remote those two never match, so every marked, two-way, never-ask question still falls through to defer / ask-normally. The feature silently does nothing.
Still present on main (a6b3a57, VERSION 1.87.4.0). Observed on 1.60.1.0.
Repro
cd<any repo with an origin remote># here: git@github.com:kvzn/LovedVoice.git~/.claude/skills/gstack/bin/gstack-slug # SLUG=kvzn-LovedVoice
bin/gstack-question-preference --write '{"question_id":"review-finding-fix","preference":"never-ask","source":"plan-tune"}'
bin/gstack-question-preference --check review-finding-fix # AUTO_DECIDE (skill-side path works)
ls ~/.gstack/projects/kvzn-LovedVoice/question-preferences.json # written here# What the hook actually does, with the cwd Claude Code passes it:printf'%s''{"session_id":"t","hook_event_name":"PreToolUse","tool_name":"AskUserQuestion","cwd":"/Users/me/Workspaces/LovedVoice","tool_input":{"questions":[{"question":"D1 fix? <gstack-qid:review-finding-fix>","options":[{"label":"Fix now (recommended)"},{"label":"Ship as-is"}]}]}}' \
| hosts/claude/hooks/question-preference-hook
# → {"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"defer"}}# expected: deny + "[plan-tune auto-decide] review-finding-fix → Fix now"
Same result from a git worktree (cwd=.../.claude/worktrees/<branch>), where basename is the worktree directory name.
Root cause
bin/gstack-question-preference L36-38: eval "$(gstack-slug)" → PREF_FILE="$GSTACK_HOME/projects/$SLUG/question-preferences.json". gstack-slug resolves to owner-repo from the git remote (step 2 in its header comment); basename is only the no-remote fallback.
functionslugFromCwd(cwd: string|undefined): string{// Mirror gstack-slug's basename fallback. ... the basename is close// enough for preference lookup ...if(!cwd)return'unknown';returnpath.basename(cwd);}
and L149-152 lookupPreference(slug, id) reads projects/<slug>/question-preferences.json, then global-question-preferences.json.
The comment's premise ("mirror gstack-slug's basename fallback") only holds for repos with no remote. For everyone else the hook reads a bucket nothing ever writes to. Because the hook fails closed to defer, there is no error, no log line, and --check/--stats both report the preference as configured, so the user has no signal that the hook path is dead.
Workaround
Copy the project file to the global fallback the hook does read:
After that the same payload returns deny with the auto-decide reason; one-way ids and unmarked questions still defer as designed.
Suggested fix
lib/bin-context.ts already has slugFromEnvironment(gstackHome, cwd) (L150), the native port that reads the same slug-cachegstack-slug writes, without spawning git. Replacing slugFromCwd with it keeps the hook off the git hot path and makes writer and reader agree. Falling back to path.basename only when the cache has no entry would preserve today's behavior for no-remote folders.
A regression test that writes a preference through gstack-question-preference --write in a temp repo with an origin remote and then pipes a marked PreToolUse payload through the hook would have caught this; the two halves are currently only tested in isolation.
Fixed in v1.91.13.0 (#3013, merged as f30b7b7): the preference hook now resolves the same owner-repo slug as the writer (via the versioned slug cache), so never-ask fires; unknown identity asks instead of auto-deciding. Run /gstack-upgrade, then start a new Claude Code session. Thanks for the report. Reopen if you still see it after upgrading.
Activity
test: seed the versioned slug cache in the memory-injection deny case (…
v1.91.13.0 fix: severe bug wave (autoplan guard, land-and-deploy CI g…
capy-ai commentedon Oct 2, 2026
Fixed in v1.91.13.0 (#3013, merged as f30b7b7): the preference hook now resolves the same owner-repo slug as the writer (via the versioned slug cache), so never-ask fires; unknown identity asks instead of auto-deciding. Run
/gstack-upgrade, then start a new Claude Code session. Thanks for the report. Reopen if you still see it after upgrading.