Watch
0
0
Fork
You've already forked hyperhive
0

hive-subagent-mcp: refuse a continue whose session is not in the dir searched

resume_target no longer falls back to the bare name when the project dir
holds no session titled it: continue (and a goal run's next turn) refuses
before anything spawns, naming the directory searched. A store that cannot
be resolved refuses too, with the io error. The fallback notice is gone.
This commit is contained in:
atlas 2026-10-07 11:55:34 +02:00
commit 0e015197b6
3 changed files with 116 additions and 158 deletions

View file

@ -71,10 +71,8 @@ project directory, read off disk at every resume. claude looks a bare name
up across every git worktree of the repo and refuses when two sessions
match, and `start` archives a prior session only in its own directory, so
a name reused under a sibling worktree would otherwise stop resuming. When
`dir` holds no session under the name, the name goes to claude as-is,
the daemon logs it, and `continue`'s reply — or its error, when claude refuses
— carries a note naming the directory searched; claude's answer stands, see
below.
`dir` holds no session under the name, the daemon refuses and never hands
claude the bare name — see below.
Because the remembered directory goes with the rest of it, a `continue`
after a restart has to re-supply `dir` when the session lives anywhere
@ -213,20 +211,33 @@ no progress left to describe.
## A `continue` that finds no session
<!-- vale write-good.Passive = NO -->
`continue` looks for the session before it spawns anything. The lookup is
the live session titled the name in the project directory of the `dir` in
effect: the one passed, or else the one the daemon remembers for the name.
No such session refuses the call — nothing spawns and the name stays free
for a retry — and the error names the directory searched:
`continue` doesn't check for the session before spawning. claude's own
`--resume` is the authority, and it exits non-zero rather than quietly
starting a fresh session, so the check could only duplicate the lookup
the driver was about to do — while answering as though the session were
gone. The usual truth is that the session exists somewhere else.
```
continue error: no session titled `n` under /home/agent/.claude/projects/-home-agent-work; pass the `dir` the session was started in
```
<!-- vale write-good.Passive = YES -->
A name is never searched for in any other directory, because claude would
resolve a bare title across every worktree of the repo and could pick, or
refuse, the wrong session. A session started in another directory
needs that directory passed as `dir` — and after a daemon restart, which
forgets the remembered one, a session outside the daemon's own working
directory needs it again. A store location the daemon can't resolve
refuses the same way, with the io error.
`continue` waits for that answer instead. Where `start` returns the
instant the process exists — it creates its session, so the spawn
succeeding is the whole story — a resumed turn can fail a moment _after_
a pid exists, and a pid is no proof that turn began. `continue` holds the
A goal run's next turn does the same lookup; a miss there ends the run as
a failed turn, with the same message in its end-of-turn todo.
The refusal covers a session missing from the directory searched.
It can't cover one that vanishes between the lookup and the spawn, so
`continue` still waits for claude's answer instead of returning the
instant the process exists. Where `start` returns at the spawn — it
creates its session, so the spawn succeeding is the whole story — a
resumed turn can fail a moment _after_ a pid exists. `continue` holds the
tool call open until the turn is underway or the resume has come back
missed, and reports a miss as the call's own error, carrying claude's
message plus the location this daemon searched: