Retention windows + legal holds (#63) #68
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/legal-hold"
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?
Closes #63 — completes the public-sector batch (#59 derived).
Legal holds (
internal/storage/hold): admins mark a path or subtree held viaGET/POST/DELETE /api/v1/admin/holds; while held, NOTHING may delete, overwrite, or rename it — admins included — until the hold is lifted. Containment is bidirectional (deleting an ancestor of held content is blocked too); reads and copy-out are never blocked. Holds persist as one atomic JSON file (holdsPath, default/data/.cairn/holds.json); the enforcing decorator sits under audit (refusals logged as failed attempts, set/lift logged ashold-set/hold-lift). Always active — an empty store costs nothing.Retention (settings-store policy
retentionPeriods, e.g.{"/spaces/records": "8760h"}, longest prefix wins): deletes still go to trash as usual — it's permanent destruction that waits. Purge and admin raw-deletes inside/.trash(single entries or whole "empty trash" trees) are refused withstorage.ErrRetentionuntildeletedAt + windowpasses. Window counted from deletion (the recoverability guarantee), evaluated per purge so policy edits apply without a restart. Restore is always allowed.Both surface as 403 with self-explanatory messages on REST. Explicitly out of scope (as the issue records): WORM guarantees against a hostile root operator — that layer belongs to backend snapshots/object-lock, same delegation decision as versioning (#23).
Tests: full hold matrix (overwrite/write-inside/delete/ancestor/rename-out/rename-onto/copy-onto blocked; read/copy-out allowed; lift restores; persistence; nil-safety) and retention (purge blocked in window, restore allowed, admin raw/empty-trash blocked, unretained purges immediately, nil policy = old behavior). Green on the runner.