Problem
All 43 hook wrappers in .claude/settings.json use a walk-up loop to locate the ops-fork root:
```bash
bash -c 'r=$PWD;while [ ! -f "$r/.apexyard-fork" ] && [ ! -f "$r/onboarding.yaml" ] && [ -n "$r" ] && [ "$r" != / ];do r=${r%/*};done;exec "$r/.claude/hooks/hook-name.sh"'
```
When Claude Code is launched from a directory that has no apexyard ancestry (e.g. /tmp, a bare project clone, or any directory outside the ops fork), the loop exits with $r = /. The wrapper then tries to exec /.claude/hooks/hook-name.sh which doesn't exist, producing:
Failed with non-blocking status code: bash: /.claude/hooks/detect-role-trigger.sh: No such file or directory
Failed with non-blocking status code: bash: /.claude/hooks/require-skill-for-issue-create.sh: No such file or directory
Failed with non-blocking status code: bash: /.claude/hooks/require-migration-ticket.sh: No such file or directory
Failed with non-blocking status code: bash: /.claude/hooks/require-active-ticket.sh: No such file or directory
Every hook fires this error on every tool call, flooding the UI with noise.
Root cause
The walk-up loop correctly stops at / but the wrapper has no guard — it unconditionally execs $r/.claude/hooks/... even when $r ended up as / (anchor not found).
Fix
Add an anchor-found guard before the exec:
```bash
done;[ -f "$r/.apexyard-fork" ]||[ -f "$r/onboarding.yaml" ]||exit 0;exec "$r/.claude/hooks/hook-name.sh"
```
This makes the hook a silent no-op when invoked outside an apexyard fork, which is the correct behaviour — hooks should only fire when running inside a managed ops fork.
Affected scope
All 43 exec "$r/.claude/hooks/..." wrappers in .claude/settings.json.
Reproduction
cd /tmp
- Launch Claude Code
- Issue any prompt — all
PreToolUse and SessionStart hooks produce the error above
Problem
All 43 hook wrappers in
.claude/settings.jsonuse a walk-up loop to locate the ops-fork root:```bash
bash -c 'r=$PWD;while [ ! -f "$r/.apexyard-fork" ] && [ ! -f "$r/onboarding.yaml" ] && [ -n "$r" ] && [ "$r" != / ];do r=${r%/*};done;exec "$r/.claude/hooks/hook-name.sh"'
```
When Claude Code is launched from a directory that has no apexyard ancestry (e.g.
/tmp, a bare project clone, or any directory outside the ops fork), the loop exits with$r = /. The wrapper then tries to exec/.claude/hooks/hook-name.shwhich doesn't exist, producing:Every hook fires this error on every tool call, flooding the UI with noise.
Root cause
The walk-up loop correctly stops at
/but the wrapper has no guard — it unconditionally execs$r/.claude/hooks/...even when$rended up as/(anchor not found).Fix
Add an anchor-found guard before the
exec:```bash
done;[ -f "$r/.apexyard-fork" ]||[ -f "$r/onboarding.yaml" ]||exit 0;exec "$r/.claude/hooks/hook-name.sh"
```
This makes the hook a silent no-op when invoked outside an apexyard fork, which is the correct behaviour — hooks should only fire when running inside a managed ops fork.
Affected scope
All 43
exec "$r/.claude/hooks/..."wrappers in.claude/settings.json.Reproduction
cd /tmpPreToolUseandSessionStarthooks produce the error above