0118: give a unit back the state it was found in — never-stop broke the converge rollback; process removal found and fixed

This commit is contained in:
jochen
2026-09-27 00:58:17 +02:00
parent ebd19c4c6c
commit 13208f0f48
3 changed files with 56 additions and 25 deletions
@@ -2,7 +2,7 @@
status: located
opened: 2026-09-27
located-in: [mesh-host internal/apply/apply.go (remove)]
amended-design: 02-DECISIONS/0118-undeclaring-leaves-the-machines-units-running.md
amended-design: 02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md
---
# 130 — undeclaring a service stops it, even one the mesh only reloads or only keeps running
@@ -45,10 +45,22 @@ reaches it by.
## Resolution
[ADR 0118](../../02-DECISIONS/0118-undeclaring-leaves-the-machines-units-running.md): undeclaring
removes what the mesh made, gives back what it changed, and leaves the machine's units as they
are. An undeclared `service` is forgotten, never stopped — the host did not create the unit.
That covers the runtime, sshd and the uplink modules at once, without each module opting out;
the private network and the sshd module need no change. A `process`'s unit, which the host does
write, is still stopped and removed. The unassign preview asked for above is left open for the
controller.
[ADR 0118](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md):
undeclaring removes what the mesh made and gives back what it changed. The host records the state
it first found a unit in, and undeclaring returns the unit to it — a unit found running (the
container runtime, sshd, a network manager) is left running; one the mesh started (the packet
filter a converge loaded) is stopped again; nothing is started on the way out; a record from
before the host kept what it found leaves the unit alone. That covers the runtime, sshd and the
uplink modules at once, without each module opting out; the private network and the sshd module
need no change.
A first draft — never stop a unit the mesh did not create — was rejected while implementing it:
returning a converged node to adopted unloads the mesh's filter by exactly this path.
Found on the way: an undeclared `process` failed every apply on its node (`remove` had no case
for it). Now removed with its unit, timer and bundle — the mesh's own code. `user` and `archive`
have the same gap and are left for their own decisions: removing a login or unpacked files is not
something to settle in passing.
The unassign preview is partly answered — the host's plan names each unit it will stop — and the
controller's side is left open.