Problem
`.claude/hooks/require-active-ticket.sh` computes `REL_PATH` by stripping `REPO_ROOT` from the absolute `FILE_PATH`. When the calling CWD is inside a nested git repository (e.g. an agent worktree created by the Agent tool at `workspace//.claude/worktrees/agent-xxx/`), `git rev-parse --show-toplevel` returns the worktree path — NOT the outer apexstack tree.
If an agent in that nested worktree tries to Write to a file in the outer apexstack tree (e.g. `/Users/ahmed/Projects/apexstack/.claude/session/current-ticket`), the strip no-ops (prefixes don't match), `REL_PATH` stays absolute, and the `.claude/*` case-match on line 36 never fires.
Incident
Agent dispatched from curios-dog CWD with worktree isolation. CWD ended up as `workspace/curios-dog/.claude/worktrees/agent-a6986b62/`. Agent tried to update `.claude/session/current-ticket` in the outer apexstack tree for apexstack#55 work. Hook computed absolute `REL_PATH` and rejected the write. Only `.md` Writes slipped through because the shell glob `` crosses `/`. Full session log on #55.
Proposed fix
One-line change to the case statement in `.claude/hooks/require-active-ticket.sh`:
```diff
- case "$REL_PATH" in
- .claude/|.claude|.md) exit 0 ;;
- case "$REL_PATH" in
- .claude/|.claude|.md|/.claude/|*/.claude) exit 0 ;;
```
This makes the `.claude/` exemption work whether `REL_PATH` is relative or absolute. `*.md` already crosses `/`, so the absolute-path case was a known-good pattern — just extend it.
Acceptance Criteria
Priority
P1 — unblocks agent-worktree workflows for apexstack-repo work. Without this, any agent spawned from one project's CWD cannot write session markers when its real work is in a different repo (as happened repeatedly during the 2026-04-14 session).
Related
- apexstack#55 (the task that exposed this bug)
- The handful of agent reports on 2026-04-14 that flagged "sandbox blocked session marker write"
Problem
`.claude/hooks/require-active-ticket.sh` computes `REL_PATH` by stripping `REPO_ROOT` from the absolute `FILE_PATH`. When the calling CWD is inside a nested git repository (e.g. an agent worktree created by the Agent tool at `workspace//.claude/worktrees/agent-xxx/`), `git rev-parse --show-toplevel` returns the worktree path — NOT the outer apexstack tree.
If an agent in that nested worktree tries to Write to a file in the outer apexstack tree (e.g. `/Users/ahmed/Projects/apexstack/.claude/session/current-ticket`), the strip no-ops (prefixes don't match), `REL_PATH` stays absolute, and the `.claude/*` case-match on line 36 never fires.
Incident
Agent dispatched from curios-dog CWD with worktree isolation. CWD ended up as `workspace/curios-dog/.claude/worktrees/agent-a6986b62/`. Agent tried to update `.claude/session/current-ticket` in the outer apexstack tree for apexstack#55 work. Hook computed absolute `REL_PATH` and rejected the write. Only `.md` Writes slipped through because the shell glob `` crosses `/`. Full session log on #55.
Proposed fix
One-line change to the case statement in `.claude/hooks/require-active-ticket.sh`:
```diff
```
This makes the `.claude/` exemption work whether `REL_PATH` is relative or absolute. `*.md` already crosses `/`, so the absolute-path case was a known-good pattern — just extend it.
Acceptance Criteria
Priority
P1 — unblocks agent-worktree workflows for apexstack-repo work. Without this, any agent spawned from one project's CWD cannot write session markers when its real work is in a different repo (as happened repeatedly during the 2026-04-14 session).
Related