fix: keep foreign discovery from throwing, and correct the adoption docs (release review)

candidatesFrom had moved outside the try when the transports moved to
runForeignProbe, so a classifier failure would have reached the route as a 500.
The module promises it never throws, so the guard is back for local and docker.

Docs:
- The api reference said `blocked` waits are always refused, and listed Ralph as
  refused while two of its file routes were not (they are now).
- The invariants doc and CLAUDE.md gain the rules this review turned up: target
  syntax in names, the ping before list-panes, nothing typed into an adopted pane,
  quoteAdoptLaunch.
- CLAUDE.md no longer says every claude session gets hooks or a stop wait.
- ForeignTmuxSession's mode and workingDir describe the first listed pane, not
  the active one.
- The wiki had no page on adoption: The Dashboard gains an Opened outside Codeman
  section, and the remote and docker pages point at it. docs/docker-cases.md now
  separates an adopted container from an adopted tmux session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-06 04:45:29 +01:00
1 parent 25214fcc5f
commit 2d7cd49449
11 files changed
+104 -30

No files matched your search

+7
View File
@@ -121,6 +121,13 @@ curl -X POST localhost:3000/api/quick-start -d '{"caseName":"sandbox","mode":"cl
## Attach to a container you already run
⚠️ Two different things are called "adopted". This section is about a CONTAINER
(`DockerCase.owned === false`). A tmux SESSION a human started inside a container is
listed by `GET /api/mux/foreign?docker=1` and wrapped by `POST /api/sessions/adopt`, for
which the container needs a Docker case but no adoption of its own. That one is
`Session.isAdopted`, with the connection on `Session.adopt.docker` and `session.docker`
undefined. See `docs/architecture-invariants.md#adopted-foreign-tmux-sessions`.
The tab's **Attach to an existing container** toggle points a case at a container **you**
built and run. Codeman only ever `docker exec`s into it: it never creates, starts, stops,
restarts or removes it, and it seeds no credentials into it, so the CLIs inside must already