Space deletion: Deactivate → Delete, contents to trash, name tombstone (#268 decisions) #286
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Cordy/Cairn#286
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Dogfood finding (2026-08-19, v0.6.51): the owner of a space (e.g.
Fall 3) tries to delete it from the Spaces file listing and gets "Spaces are managed containers and cannot be deleted from the file listing." That guard is correct — but there is currently no way to delete a space at all:spacestore.Deleteexists but is metadata-only and nothing exposes it. This issue implements the lifecycle decided in #268.Decided model (#268, 2026-08-18):
Implementation sketch:
spacestore:Deactivate(name)/Reactivate(name)flags +Delete(name)grows the content move (space tree → trash entries) and writes the tombstone{name, deletedAt, keepUntil};Createrefuses tombstoned names with a clear error.POST /api/v1/spaces/{name}/deactivate,POST /api/v1/spaces/{name}/reactivate,DELETE /api/v1/spaces/{name}— allownerOrAdmin, all audited (space-deactivate,space-delete).recvSpacesmust tolerate a deactivated/deleted space (listed pitfall).Out of scope: key rotation on reactivation; bulk space archival.
Shipped as v0.6.54 (PR #289), live on both dogfoods. Built exactly on the #268 decisions; lifecycle tests (deactivate/reactivate roles + visibility, tombstone blocking + expiry) green in CI.
How it works:
/spaceslisting, owner or admin): Details, then Deactivate space — reversible; the space vanishes for members while the owner keeps read-only sight (admins see everything via the unscoped view). A deactivated space's menu offers Reactivate and the red Delete space…./spaces/<name>into the deleting user's trash as one recoverable entry (visible in Admin → Deleted files → Manual purge) and tombstones the record.space-deactivate,space-reactivate,space-delete.Known edges (accepted v1): restoring the trashed space folder restores files only, not membership — the tombstone still blocks recreating the space until expiry; an early manual purge doesn't shorten the name reservation; IdP-managed (route A) spaces answer 501 on lifecycle routes. Deviation from the mockup: no "deactivated" pill on the listing row yet — the state shows in the menu; pill is a candidate for a follow-up polish once row decoration is scouted.
Dogfood checklist (fresh login):
UI polish round decided (2026-09-03, operator review of the shipped lifecycle; mockups in
space-lifecycle-ui-mockup.html):Backend note: the
/spaceslisting rows and the in-space listing response need adeactivatedflag stamped from the spacestore (fillLocks-style enrichment, no N+1); everything else is frontend + i18n ×4.UI polish round shipped — v0.6.114 (PR #407), live on both dogfoods.
neverPurgefield onGET /api/v1/spaces/{name}/state.deactivatedstamped on/spacesrows (fillSpaceStates, in-memory, owner/admin-only by construction); deactivated spaces sink below an amber "Deactivated" divider, dimmed, amber chip, "Hidden from members · you keep view-only access" sub-line; footer counts them.spaceDeactivated; amber "Deactivated" chip beside "View only" in the crumb, plus a banner with inline Reactivate.Dogfood checklist (fresh login — in-memory sessions):
Operator visual pass complete on the live dogfood (2026-09-03, v0.6.114) — all checklist items passed. With that, the full #286 arc is done: lifecycle shipped v0.6.54, admin inventory wired in the #311 sweep, and the UI polish round (A2 dialog with honest retention copy + name confirm, B2 deactivated group, C in-space banner) verified in use. Closing.