ADR-0009 — a community is retired by a forced import with no members, and members arrive only through onboarding
Date: 2026-09-27 Status: accepted
Context
A community seeded from a bundle can carry members that are not real: placeholder names and accounts around a real meter. A deployment going live starts a new community instead — managers first, then everyone through onboarding — and the old one has to stop holding its meters, because a sensor has one active holder across the registry (ADR-0004) and the old placeholders would refuse every attach in the new community.
The registry has no community delete route and no "retired" status. REQ-0008 pins the action a
DELETE /admin/communities/{key} would derive, but no such route exists. Deactivating each
member one at a time would release the sensors but leave the rows, and nothing else would ever
read them.
Decision
- A community is retired by a forced import of a bundle naming the same community with no members. The import replaces the graph (REQ-0032), so every member and asset of the old community is deleted and its sensors are released; the community row stays, with whatever metadata the bundle carries.
- No new route and no new status. Retirement is an operation, performed by a platform operator holding the import grant, outside the product.
- On a deployed realm, members arrive only through onboarding. A bundle carries the
community's administrative data; loading members from a YAML file — the bundle's
membersor the policies tooling'ssync-users— is for local development only.
Consequences
The import grant is purge-equivalent, and always was: a forced import deletes every member
and asset of a community, which is more than members.purge can do to one member. REQ-0006's
separation of erasing from writing holds only for callers who do not hold rec-registry.import.
A retired community looks like an empty one. Nothing marks it retired, and a later import could fill it again. That is acceptable while retirement is rare and deliberate; a status is the follow-up if it stops being either.
History is erased with the rows. Readings keep their sensor ids and follow the sensors' next holders; which placeholder held a sensor before is not kept here.
The temptation is a DELETE /admin/communities/{key} "because the action already exists".
A community delete cascades through every member and meter; it deserves its own decision, not
an inherited action name.