#8515·multica

[Feature]: Retire a stopped custom runtime instance without deleting its shared profile

Author: Bohan-JCreated Sep 17, 2026Updated Sep 17, 2026

What's missing

An admin cannot retire a stopped custom runtime instance on demand. Deleting one is refused while its profile exists, so the only ways to clear a dead row today are to wait out the 7-day retention window, or to delete the shared profile — which removes that runtime on every machine that registered it.

#8483 fixed the guidance around this (the refusals now explain the automatic cleanup, name the blockers and their real remedies, and stop recommending the profile delete). It deliberately did not change when a delete is allowed. This issue tracks the capability itself.

Why the guard exists

The 409 was added in #4456 to fix #4303, with a sound reason: "so clients cannot report success for a row that the daemon will recreate on restart." That holds for a machine that is coming back. It does not hold for a permanently retired daemon identity, and the guard cannot currently tell the two apart — it only checks whether the profile row still exists.

The shape that seems right

The server already decides this question elsewhere. Retention GC deletes exactly these rows, and its eligibility rule ignores profile_id entirely:

  • status = 'offline' and last_seen_at older than service.OfflineRuntimeTTLSeconds
  • no non-archived user agent bound to it
  • no undrained task on the runtime or on any user agent bound to it (gcRuntime's drain gate, archived agents included)

Letting an admin do on demand what the sweeper will do anyway needs no new policy, and the TTL condition is the only part that would be relaxed. Worth deciding explicitly: if that daemon ever comes back, should the row reappear? Matching GC's semantics — retire means "forget this machine", and a daemon that genuinely returns re-registers — seems right, and avoids the "my machine is connected, why is it missing" class of problem a tombstone would introduce.

Prior art

PR #7094 already implements per-instance deletion, but gates it on activation_mode == local. Both reports here are workspace-mode profiles, so it does not cover them as written. Worth reviewing alongside this rather than duplicating it — it has been open since 2026-08-17 with no review.

Reports this came from

  • #8456 — two daemons, one retired; five agents bound to the healthy instance blocked the profile delete
  • #6671 — twelve daemons, N−1 placeholder rows per profile