Files
hermes-agent/apps
Jack Lau 20ccf88acd fix(desktop): fail the agent switch closed when its descriptor lookup rejects
Review caught that the agent path fixed the pending-descriptor race but not
the failure path. `resolveConnectionForActiveAgent` caught a
`getConnectionFor` rejection and returned null, so `Promise.all` resolved as
`[null, activate]` and the switch published anyway: the activation thunk ran
and `$activeGatewayProfile` advanced, while only `setConnection` was skipped.

That is the same mixed state this PR exists to remove, except it does not
close on its own. The pending-descriptor window ends when the descriptor
arrives; a failed lookup never arrives, so `$gateway` named the new backend
while `$connection` described the old one until an unrelated reconnect or
switch happened to repair it. Anything branching on connection mode in
between (plugins, `MEDIA:`, `/api/fs/*`, `/api/media`, image attach) saw the
pair disagree.

Let the rejection propagate, matching `resolveConnectionForProfile`, whose
contract is already exactly this: null means "no desktop bridge" and nothing
else, and a bridge rejection aborts the whole switch before anything is
published. Both doors now fail closed identically, and the caller can retry.

The existing "leaves the prior connection intact when the descriptor fetch
fails" test asserted the old best-effort behaviour, so it pinned the defect
rather than a contract worth keeping. Replaced with a rejected-descriptor
test that asserts none of the three atoms moved and the activation thunk was
never called. The pending-descriptor case keeps its own separate test, so the
success and failure contracts are pinned independently.

Also reworded the publication comments: these are sequential atom writes with
no asynchronous gap between them, not a transaction, and describing them as
one "frame" overstated the guarantee.
2026-08-18 15:04:28 -07:00
..