Problem
`hooks/devkit-stop-guard.sh` (and by extension `devkit-engine guard --stop`) nags on every turn of every Claude Code conversation whenever any workflow session is active — regardless of which repo the user is currently working in. Once you start a `pr-ready` (or any other workflow) in repo A and the session isn't driven to completion, opening an unrelated conversation in repo B still fires:
```
Workflow pr-ready incomplete — 1 steps remaining. Call devkit_advance to continue.
```
The workflow session ID and state live in `~/.claude/` (plugin state dir), not in the repo that started it. So the hook has no way to tell "this nag applies here" vs "this nag belongs to a different project's stuck workflow."
Repro
- Start any devkit workflow in repo A (`/devkit:pr-ready`, `/devkit:feature`, etc.).
- Advance partway but don't reach the final step (e.g., close the terminal during CI monitoring).
- Open a fresh Claude Code session in an unrelated repo B (or even no repo).
- Every Stop event in repo B is blocked with the nag from repo A's workflow.
Why it's wrong
- Workflows are repo-scoped in intent: they operate on a branch, a PR, a diff.
- The nag is useful when you're still in the repo/branch that started the workflow — it keeps you from forgetting to finish.
- The nag is pure noise when you've cd'd out or context-switched — it blocks unrelated work.
- There's also no stale-session timeout, so a forgotten workflow from last week still fires today.
Proposed fix
Make the guard repo-aware. On session start, the workflow state should record:
- `cwd` (or resolved git repo root) at start time
- branch name at start time
- start timestamp
Then `devkit-engine guard --stop` should:
- Read the current `CLAUDE_PROJECT_DIR` (or resolve the active repo root from `pwd`).
- Read the active session's recorded repo root.
- Approve silently if they don't match — the workflow is not relevant to this session.
- Block (current behavior) only when the repo roots match.
- Optionally: approve silently for sessions older than a configurable TTL (`DEVKIT_WORKFLOW_STALE_HOURS`, default 24h), logging a stderr warning about the stale session.
Same thinking for branch: if the current branch differs from the one recorded at workflow start, either warn-approve or block — TBD. Repo-scoping alone fixes 95% of the pain.
Behavior to preserve
- Same nag firing when you ARE in the right repo on the right branch with an active workflow — that's useful.
- No regression when `CLAUDE_PROJECT_DIR` is unset or the session state is missing — continue to approve (as the hook already does on missing binary).
Touch points
- `src/mcp/server.go` — record cwd + branch when `devkit_start` is called (likely already tracks cwd somewhere in `src/lib/state.go`).
- `src/cmd/guard.go` — extend the stop-guard decision with repo match check.
- `src/lib/state.go` / `src/lib/state_json.go` — add fields if not already present.
- `hooks/devkit-stop-guard.sh` — no change needed; wrapper stays the same.
- Tests: `src/cmd/guard_test.go` table — add cases for mismatched cwd → approve.
Context
Surfaced while running `/devkit:pr-ready` for PR #90 (local runner + stealth scraping). The CI monitor step held the session open; the Stop hook fired on every conversational turn of unrelated work in other directories for the duration.
Problem
`hooks/devkit-stop-guard.sh` (and by extension `devkit-engine guard --stop`) nags on every turn of every Claude Code conversation whenever any workflow session is active — regardless of which repo the user is currently working in. Once you start a `pr-ready` (or any other workflow) in repo A and the session isn't driven to completion, opening an unrelated conversation in repo B still fires:
```
Workflow pr-ready incomplete — 1 steps remaining. Call devkit_advance to continue.
```
The workflow session ID and state live in `~/.claude/` (plugin state dir), not in the repo that started it. So the hook has no way to tell "this nag applies here" vs "this nag belongs to a different project's stuck workflow."
Repro
Why it's wrong
Proposed fix
Make the guard repo-aware. On session start, the workflow state should record:
Then `devkit-engine guard --stop` should:
Same thinking for branch: if the current branch differs from the one recorded at workflow start, either warn-approve or block — TBD. Repo-scoping alone fixes 95% of the pain.
Behavior to preserve
Touch points
Context
Surfaced while running `/devkit:pr-ready` for PR #90 (local runner + stealth scraping). The CI monitor step held the session open; the Stop hook fired on every conversational turn of unrelated work in other directories for the duration.