Retire obsolete sessions when a paired server is reinstalled

Merged
TE
16d ago
+506-51

Reinstalling a paired server now replaces its client session even when the Unix, SSH or overlay path stays the same. Removing or replacing a session retires captured reconnect callbacks. Offline reconnect, temporary policy disconnect and the person’s launch preference remain supported.

Validation: four fleet suites pass, including app/provider catalog and inventory-watch journeys. Regressions fail before the fix on all three route kinds. Swift parsing, concurrency and coordination checks pass. GUI and live paired-network dogfood remain pending.

Stacked on #21480.

Changelog

Fixed: Reinstalled or removed servers no longer retain obsolete client sessions.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Reinstalling a paired server now retires its stale session, and Settings/palette agent CLI updates run as durable, owner-captured jobs instead of commands typed into a terminal tab.

  • A host with a changed install ID is treated as a replacement owner even when its Unix, SSH, or overlay path is unchanged; retired sessions fence their connect and wake callbacks.
  • Update jobs record intent durably, replay across lost replies, and recover after app restarts without reselecting or executing an owner. Every retained update has a way out: a closed terminal settles its job, rows from sessions no route can reach block until the ledger's seven-day bound retires them, failed records clear the batch, and a creation pending ten minutes becomes dismissible.
  • Explicit inventory refresh rechecks registry versions only, never probing CLIs, reading sign-ins, or starting updates.
  • npm update commands bind to the detected installation prefix, and already-current updates require evidence of the newest known version.
  • App mutation keys and caller attribution survive provider-to-action routing through the shared registry.
  • Settings update runs scope their mutation key with withValueInTask, avoiding the crash-class gate on TaskLocal.withValue.
  • The update intent argument is localized into all supported locales.