CB-584: sync the portable block, and catalogue the resume hint

The bridge_spawn and bridge_list rows in the intent table changed on
main, so the wiki template had drifted from CLAUDE.md. Re-synced; the
check now prints 'in sync: True'.

Features entry for the failed-ticket session id: what it is, that it
needs no knob, why it exists (stage C saves the files, this saves the
thread), and that its absence is the normal case rather than a fault.
Dai Ha
2026-08-16 18:29:53 +02:00
parent 113859d1c2
commit 9fe66176b0
2 changed files with 27 additions and 2 deletions
+25
@@ -1470,6 +1470,31 @@ callers were ever affected.
---
## A failed ticket names the conversation, not just the files
**What.** When a member dies, the failed ticket's detail now carries the member's `agentSessionId`
alongside the worktree, branch and snapshot ref it already reported:
```
… worktree=/wt/x branch=worker/x snapshot=refs/wip/x agentSessionId=abc-123
```
A lead can pass that id back as `bridge_spawn{resumeSessionId: "abc-123"}` on the same profile.
**On.** Automatic, no knob. It appears whenever the released member's backend produced a session id.
**Why.** CB-578 stage C already lets a lead re-dispatch a fresh member onto the same worktree after a
failure, and it states its own limit plainly: the files survive, the **reasoning** does not. A
re-dispatch was a cold start re-reading a brief. Pairing the session id with the worktree is the other
half — it turns *"the work survives"* into *"the work and the thread both survive"*.
**Gotcha.** It is absent whenever the adapter never resolved an id: the member was spawned without
`sessionName` or `resumeSessionId` (the ordinary path), or its backend does not declare
`Capability.SESSION_RESUME`. Silence here is the expected case, not a fault — do not read a missing
`agentSessionId=` as a bug.
---
## `weighted` placement is not "cheapest first"
**What.** `placement: weighted` is smooth weighted round-robin. It spreads unqualified spawns across
+2 -2
@@ -393,8 +393,8 @@ the merge — and merging on a reviewer's word is delegating it by proxy.
|---|---|
| Confirm your own role | `bridge_whoami` |
| See backends available | `bridge_profiles` |
| Start a member | `bridge_spawn{role?, profile?, cwd?, worktree?, ticket?}` → `sessionId` + `paneId` |
| See the fleet | `bridge_list` → `leads` (your peers) + `members` · one peer's state: `bridge_status{sessionId}` |
| Start a member | `bridge_spawn{role?, profile?, cwd?, worktree?, ticket?, sessionName?, resumeSessionId?}` → `sessionId` + `paneId` |
| See the fleet | `bridge_list` → `leads` (your peers) + `members` (each carries `agentSessionId` when its backend knows one) · one peer's state: `bridge_status{sessionId}` |
| Delegate (blocking) | `bridge_send{sessionId, content}` |
| Delegate (long task) | `bridge_send{sessionId, content, wait:false}` → ticket → `bridge_poll{ticket}` |
| Answer a member's `bridge_ask` | `bridge_send{turnId, content}` — **not** `sessionId` |