Locks: space-owner folder locking behind an instance setting (#395) #398

Merged
Cordy merged 2 commits from lock-folders into main 2026-09-02 20:13:10 +00:00
Owner

Implements #395 (deferred L2 extension from #315).

  • spaceFolderLocks setting (bool, off by default) + admin checkbox in Basic settings, i18n ×4.
  • filelock.Record gains Dir; Store.Covering(p) resolves the governing lock: exact match first, then a parent-segment walk for live Dir records — one in-memory walk, no I/O. The guard's deny now uses Covering, and Mkdir is guarded too (creating entries inside a frozen subtree is a write).
  • Plain file locks are untouched: a non-Dir record never covers children (regression-tested).
  • API: folders are accepted by POST /api/v1/lock only when the setting is on AND the requester owns the containing space (spaceOwnerCached); otherwise the existing 400/new 403 stand. Unlock keeps the holder/admin matrix.
  • UI: folder rows get Lock/Unlock when locked or when the setting is on under /spaces/; the chip stays exact-path (only the locked folder shows it, children inherit enforcement silently). Server enforces regardless of what the client shows.
  • Tests: subtree freeze matrix (overwrite/create/mkdir/delete/rename vs reads and outside paths, holder vs other), non-Dir no-coverage, Covering walk incl. name-prefix bleed; mutation check on the r.Dir condition.

Closes #395.

Implements #395 (deferred L2 extension from #315). - `spaceFolderLocks` setting (bool, off by default) + admin checkbox in Basic settings, i18n ×4. - `filelock.Record` gains `Dir`; `Store.Covering(p)` resolves the governing lock: exact match first, then a parent-segment walk for live `Dir` records — one in-memory walk, no I/O. The guard's `deny` now uses `Covering`, and `Mkdir` is guarded too (creating entries inside a frozen subtree is a write). - Plain file locks are untouched: a non-`Dir` record never covers children (regression-tested). - API: folders are accepted by `POST /api/v1/lock` only when the setting is on AND the requester owns the containing space (`spaceOwnerCached`); otherwise the existing 400/new 403 stand. Unlock keeps the holder/admin matrix. - UI: folder rows get Lock/Unlock when locked or when the setting is on under `/spaces/`; the chip stays exact-path (only the locked folder shows it, children inherit enforcement silently). Server enforces regardless of what the client shows. - Tests: subtree freeze matrix (overwrite/create/mkdir/delete/rename vs reads and outside paths, holder vs other), non-Dir no-coverage, `Covering` walk incl. name-prefix bleed; mutation check on the `r.Dir` condition. Closes #395.
Cordy merged commit 888ea0b855 into main 2026-09-02 20:13:10 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#398
No description provided.