fix(herdr): B5 — replace invented pane.kill/release/rotation_signal with real methods

Verified against a live herdr instance (192.168.1.105:9245) that pane.kill,
pane.release, and pane.rotation_signal never existed in the protocol, as
AUDIT.md's B5 suspected. Real method list captured in deploy/herdr-schema.json.

- Kill now calls the real pane.close({pane_id}).
- RotationSignal interface/method/call-site deleted; no real equivalent exists.
- Release now refuses loudly instead of calling a nonexistent method — the
  real pane.release_agent can't return a handoff_ref either way (herdr
  doesn't write handoffs, the agent does), so a real fix needs Phase 4
  handoff production first.

Also documents Phase 0 findings in AUDIT.md/progress.md, and adds
CLAUDE.md/AGENTS.md with project-specific knowledge (herdr protocol facts,
deployment topology, a currently-stuck live task, the federation fork) for
future sessions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
This commit is contained in:
kami
2026-07-27 21:05:53 +04:00
parent 02d93fb63d
commit 63cda5557e
7 changed files with 352 additions and 28 deletions
+64
View File
@@ -473,3 +473,67 @@ If you want one thing to do today: **Phase 0**, then **B2** (a ~20-line fix
that makes three subsystems reachable), then **B1**. Those three turn a system
that cannot rotate into one that can, and everything else in the plan is
building on top rather than repairing underneath.
---
## Phase 0 — done, 2026-07-27
B1, B2, B4, B8, S1, S5, S6 were already fixed and landed as of this session
(confirmed by reading the current code, not just trusting progress.md — see
`adapterFor` in `internal/orchestrator/orchestrator.go:190` and
`CLIAdapter.Occupancy` in `internal/herdr/adapter.go:197`).
This box (homesrv) turned out to have live TCP reachability to the real herdr
instance at `192.168.1.105:9245` (workpc) the whole time — the `unavailable:
connection refused` lines in `journalctl -u orchestra.service` are for
`homesrv-*` herdrs dialing `192.168.1.104:9245`, which has no local herdr
running; `workpc-*` herdrs were connecting fine but main.go never logs a
success, only a failure, so there was no positive signal either way. Also
found: **a real task is stuck live right now** — workspace `wA`, task
`06FT6CKD9Y98AZRX6X8K3QXFZG`, opencode agent, pane `wA:p1`, `agent_status:
"blocked"` — almost certainly stuck because `Release`/rotation could never
reach it (see below).
Ran the actual Phase 0 steps against this live instance (raw JSON-RPC probes
over TCP, params-omitted/empty-object tricks to read Rust serde's
missing-field errors — no `herdr` CLI available locally, so `herdr api schema
--json` itself wasn't run, but the equivalent info was extracted this way).
Full method list and findings committed to `deploy/herdr-schema.json`.
**Confirmed, with a real server response, not just static reading of
adapter.go:**
- `pane.release`, `pane.kill`, `pane.rotation_signal` — **none of these exist**
in the real protocol. Confirms B5's suspicion exactly.
- Real replacement for `pane.kill` is `pane.close({pane_id})` — same shape,
drop-in. **Fixed** in `internal/herdr/adapter.go`.
- Real replacement for `pane.release` is `pane.release_agent({pane_id,
source, agent})` — structurally different, and per B5's own analysis it
cannot return a `handoff_ref` regardless (herdr doesn't write handoffs, the
agent does, §6.1). Wiring this for real needs Phase 4's handoff-production
path first. `CLIAdapter.Release` now returns a loud error naming exactly
that instead of calling a method that doesn't exist. **Not a full fix** —
Phase 4 still owns making Release do something real.
- `pane.rotation_signal` doesn't exist and never will (herdr has no rotation
concept) — deleted `RotationSignal` interface, its `CLIAdapter` method, and
the call site in `Coordinator.rotate`, per this doc's own instruction
("Delete ... unless the schema proves it exists").
- `agent.get`, `pane.read`, `agent.prompt`, `worktree.create`, `worktree.open`,
`agent.start` — all confirmed real, no changes needed there.
- Protocol version confirmed live: `17`, matching `config.jsonc`'s
`"protocol": "17"` (returned as a bare JSON number by the server; the
existing string-fallback parse in `CheckProtocol` happens to handle that
correctly already).
`go build ./...`, `go vet ./...`, `go test ./...` all pass after these
changes.
**Still open from B5** (not attempted this pass — larger, needs design, not
just a method-name swap):
- `agent.prompt` inline `wait` on `CLIAdapter.Lease` (still `wait=0`, per B5's
note that only `Bootstrap` passes a real wait).
- `Release`'s real implementation, which depends on Phase 4 (§6) handoff
production existing at all.
- The stuck live task (`06FT6CKD9Y98AZRX6X8K3QXFZG`) was deliberately **not**
manipulated directly (no `pane.close`/`pane.release_agent` call against it)
— killing or releasing a real running agent from an audit session without
the user present is exactly the kind of action that warrants asking first.