feat: Owner column via per-folder owner manifests (#315, D1–D7) #388

Merged
Cordy merged 13 commits from owner-column into main 2026-09-01 19:18:00 +00:00
Owner

Implements the ratified #315 owner design.

Backend: new internal/storage/ownermeta decorator between trash and quota — records the creator on Write/Mkdir/Copy in a per-directory .cairn-meta.json ({owner, at} per child), moves records on Rename, drops them on Delete/rename-into-trash, and stamps FileInfo.Owner on List with exactly ONE extra read per listing (test-guarded). Manifests pass through encrypt (ciphertext at rest) and are invisible/unwritable on every user surface. Trash sidecars gain owner; user and admin restores put the original owner back. GET /api/v1/files fills blanks by structural inference only — homes → their user, app-owned spaces → the space owner (60s-cached), IdP-managed spaces stay honestly ownerless. Manifest writes are best-effort: a failed update never fails the user's operation.

UI: Owner column live in space contexts (avatar initial + name, muted em dash when unknown); data-space now set per navigation in load(), retiring the #311-era personal default.

Tests: full ownermeta lifecycle suite incl. concurrent-upload serialisation, manifest unreachability, and the single-read-per-listing guard (mutation-checked); pure inference table test; go vet ./... + full Go/web suites green.

Implements the ratified #315 owner design. Backend: new `internal/storage/ownermeta` decorator between trash and quota — records the creator on Write/Mkdir/Copy in a per-directory `.cairn-meta.json` (`{owner, at}` per child), moves records on Rename, drops them on Delete/rename-into-trash, and stamps `FileInfo.Owner` on List with exactly ONE extra read per listing (test-guarded). Manifests pass through encrypt (ciphertext at rest) and are invisible/unwritable on every user surface. Trash sidecars gain `owner`; user and admin restores put the original owner back. `GET /api/v1/files` fills blanks by structural inference only — homes → their user, app-owned spaces → the space owner (60s-cached), IdP-managed spaces stay honestly ownerless. Manifest writes are best-effort: a failed update never fails the user's operation. UI: Owner column live in space contexts (avatar initial + name, muted em dash when unknown); `data-space` now set per navigation in `load()`, retiring the #311-era `personal` default. Tests: full ownermeta lifecycle suite incl. concurrent-upload serialisation, manifest unreachability, and the single-read-per-listing guard (mutation-checked); pure inference table test; `go vet ./...` + full Go/web suites green.
Cordy merged commit 9fa03d58b5 into main 2026-09-01 19:18:00 +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#388
No description provided.