Conversation
`swarm list` and `swarm status` use `try_lock()` to avoid blocking on an agent that is in the middle of a turn. That makes a worker invoking a swarm tool unable to see its own model, even though SubagentStatus has already retained the model on its SwarmMember runtime snapshot. Use the retained in-memory runtime identity only when the live agent is unavailable. Keep live identity authoritative when the lock is available. This avoids synchronous session-file reads and stale persisted metadata. Add a roster regression that holds the peer agent lock, reproducing the worker-self query path, plus focused precedence tests.
|
The busy-member status workflow never ran. Both raw debug clients are
independent root sessions, and `swarm_id_for_session` gives each root
session its own `session:{id}` swarm, so `ensure_same_swarm_access`
refused the cross-session `comm_list`/`comm_status` calls. The wait for
the peer to enter `running` timed out and the test never reached its
assertions, on master and on this branch alike.
Opt both clients into one shared swarm so the workflow runs again, and
add a deterministic status-path regression that seeds the member's
retained runtime and holds its agent lock, covering the retained
identity fallback on the status surface.
Evidence:
- restored workflow passes in 1.4s (was a 5s timeout).
- new status regression fails without the fallback (None vs OpenCode Go).
- roster regression and identity precedence tests still pass.
|
P2 is valid, and it is pre-existing rather than introduced here. Reproduction
Failure: Root causeBoth raw debug clients are independent root sessions. Consequently
The test therefore never reached its assertions. Fixes in this PR
Note on asserting identity in the restored workflowThe restored end-to-end test cannot assert the retained provider/model: in that harness the member's runtime snapshot is never populated during the turn. Instrumenting the busy window shows |
Fixes #1266.
Problem
swarm listandswarm statusread provider identity from a member's live agent handle undertry_lock(). That is deliberate: the roster must never block on an agent that is mid-turn. The consequence is that the lock is exactly the state a busy member is in, so its ownModel:line was dropped.Observed symptom: a worker calling
swarm listfrom inside its own turn sees the coordinator's entry with a model and its own entry with none.Change
try_lock()behavior unchanged.SwarmMember.runtimebySubagentStatus.swarm listenrichment path and apply the same fallback toswarm status.Design notes:
JCODE_MODEL(that name is a config override for nested runs, so reusing it would change behavior elsewhere).Tests
New/updated coverage in this PR:
comm_list_includes_member_status_and_detail: roster entry for a member whose agent lock is held reports the retained provider/model/effort.comm_status_reports_retained_identity_while_member_is_busy: the status surface reports retained identity while the member is busy.member_identity_tests: retained identity is used when live identity is unavailable, and live identity wins when it is available.communicate_status_returns_busy_snapshot_for_running_member(existing workflow, restored): it previously timed out before its assertions. Root cause: both raw debug clients are independent root sessions, andswarm_id_for_sessiongives each root session its ownsession:{id}swarm, soensure_same_swarm_accessrefused the cross-sessioncomm_list/comm_statuscalls. Opting both clients into one shared swarm makes the workflow run again (passes in 1.4s instead of timing out at 5s).Observed locally:
NonevsOpenCode Go, so the test guards the changeReal-daemon acceptance check (no stubs, the shipped path): daemon started with a shared swarm id, worker spawned through the public
swarmtool, worker then callsswarm listfrom inside its own turn.Status: running,Activity: thinking,Model: Gemini/gemini-2.5-pro.a195ceecc), the identical probe shows its own entry withStatus,ActivityandWorkbut noModel:line, while the coordinator entry below does have one.Edge cases and known limits
SubagentStatusupdate, which is the same data the inline swarm strip already uses.CI status
Workflow runs for this fork PR require maintainer approval, so the CI jobs have not executed. I ran the non-compiling guardrail scripts locally on this branch: module declarations, dependency boundaries, and wildcard re-export pass. The code-size, test-size, panic, and swallowed-error ratchets report failures identical to untouched
upstream/master(src/cli/login.rs,src/cli/provider_init.rs,src/cli/commands_tests.rs,tests/e2e/test_support/mod.rs,src/cli/ssh*.rs,src/cli/tui_launch.rs); none involve files in this PR.