Keep temporary storage in each Home private directory #749

Closed
kayg wants to merge 6 commits from fix/storage-private-tmp-642 into dev
Owner

Superseded by #750, which preserves the current dev ADR updates with the same tested runtime code.

Temporary notes, uploads, import images and metadata snapshots now start in one private .calternal/tmp directory per Home on the target filesystem. Publication uses atomic rename. Temporary cleanup refuses public paths; explicit Trash, creation undo and backdrop deletion use separate user-action APIs.

Replaces #744 for #642.

Private recovery covers data and split state roots. Format owners authorize legacy migration; a creator receipt alone cannot make authoritative state disposable. Unknown legacy files retain their original names. Hard links and existing descriptors prevent disposal, including a read-only descriptor later reopened for writing. Case-only moves retain a durable restoration intent. Destination group and ACL inheritance are preserved before placement.

The production cards lint exemption is removed. Removal, rename and overwrite bans cover the standard and Tokio filesystem APIs. Tests verify direct production removal and async overwrite calls are rejected. Private content stays out of note scans, watchers, lists, search, sync and attachment serving; future WebDAV and File Provider bridges must keep that boundary.

Validation passed: formatting, workspace Clippy with warnings denied, workspace tests, all 74 fsio tests, the permanent reviewer regressions from #737/#740/#742/#744, ordinary-binary startup cases, upload memory bounds, watcher publication and tree confinement. The settled 1,000-stop run preserved every acknowledged Unicode marker exactly once, matched canonical bytes to notes.get, and left no staging entries in either root. Final Rust and Cargo inputs match that binary; only five static async overwrite bans were added afterward and independently checked.

Legacy replay cleared 211 proven file images from a local 511-entry old state tree. It retained 285 directories and 15 files without sufficient proof; retained file bytes were unchanged and new private staging was empty. This is the conservative choice required by the rule to leave unproven legacy entries alone. ADR 0062 and docs/storage.md document it and the separate Trash lifecycle.

The designated performance VM was unreachable through NetBird and its direct hostname could not resolve, so there is no latency measurement claim. Detailed gate output and earlier failed checks are recorded on #642. Evidence and run artifacts remain outside the commit.

Superseded by https://git.kayg.org/kayg/calternal/pulls/750, which preserves the current dev ADR updates with the same tested runtime code. Temporary notes, uploads, import images and metadata snapshots now start in one private `.calternal/tmp` directory per Home on the target filesystem. Publication uses atomic rename. Temporary cleanup refuses public paths; explicit Trash, creation undo and backdrop deletion use separate user-action APIs. Replaces #744 for #642. Private recovery covers data and split state roots. Format owners authorize legacy migration; a creator receipt alone cannot make authoritative state disposable. Unknown legacy files retain their original names. Hard links and existing descriptors prevent disposal, including a read-only descriptor later reopened for writing. Case-only moves retain a durable restoration intent. Destination group and ACL inheritance are preserved before placement. The production cards lint exemption is removed. Removal, rename and overwrite bans cover the standard and Tokio filesystem APIs. Tests verify direct production removal and async overwrite calls are rejected. Private content stays out of note scans, watchers, lists, search, sync and attachment serving; future WebDAV and File Provider bridges must keep that boundary. Validation passed: formatting, workspace Clippy with warnings denied, workspace tests, all 74 fsio tests, the permanent reviewer regressions from #737/#740/#742/#744, ordinary-binary startup cases, upload memory bounds, watcher publication and tree confinement. The settled 1,000-stop run preserved every acknowledged Unicode marker exactly once, matched canonical bytes to notes.get, and left no staging entries in either root. Final Rust and Cargo inputs match that binary; only five static async overwrite bans were added afterward and independently checked. Legacy replay cleared 211 proven file images from a local 511-entry old state tree. It retained 285 directories and 15 files without sufficient proof; retained file bytes were unchanged and new private staging was empty. This is the conservative choice required by the rule to leave unproven legacy entries alone. ADR 0062 and docs/storage.md document it and the separate Trash lifecycle. The designated performance VM was unreachable through NetBird and its direct hostname could not resolve, so there is no latency measurement claim. Detailed gate output and earlier failed checks are recorded on #642. Evidence and run artifacts remain outside the commit.
fix: recover interrupted note renames and staged saves
Some checks failed
CI / server (pull_request) Successful in 57s
CI / rust (pull_request) Successful in 20m26s
CI / web (pull_request) Failing after 2h59m10s
66f27ce3cd
Preserve unjournaled staging bytes across canonical file races
Some checks failed
CI / server (pull_request) Successful in 1m18s
CI / rust (pull_request) Successful in 15m56s
CI / web (pull_request) Has been cancelled
e46ce1c306
Saved by the coordinator after the job stopped early; gates not yet run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Cj2Q1hCskP8Frsk6X7EHw
test(storage): verify quarantine cleanup at concurrent replacement boundaries
Some checks failed
CI / server (pull_request) Successful in 1m18s
CI / rust (pull_request) Successful in 21m5s
CI / web (pull_request) Has been cancelled
ccc7a2b790
fix(storage): require durable creator receipts for all cleanup
Some checks failed
CI / server (pull_request) Successful in 1m26s
CI / rust (pull_request) Failing after 30m1s
CI / web (pull_request) Has been cancelled
c19aef3072
fix(storage): stage temporary writes in private Home directories
Some checks failed
CI / server (pull_request) Successful in 1m14s
CI / rust (pull_request) Failing after 17m53s
CI / web (pull_request) Has been cancelled
118ca22ce1
Author
Owner

Closing: superseded by #750 (named in the PR body or comments). Branch kept.

Closing: superseded by #750 (named in the PR body or comments). Branch kept.
kayg closed this pull request 2026-11-04 13:04:36 +00:00
Some checks failed
CI / server (pull_request) Successful in 1m14s
CI / rust (pull_request) Failing after 17m53s
CI / web (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
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
kayg/calternal!749
No description provided.