Files
tuliprox/backend
DarkBreakpoint 1f94d51c76 feat(dvr): recording sidecars, and a shared retention pool that exists
Task 16, steps 4 and 5. A finished recording now has a
`<file>.tuliprox-recording.json` beside it holding what the file is:
materialization id, media identity, kind, relative path, size,
completion time. Nothing else. It lives in the recording directory,
which is not a place for owners, quota, headers, URLs or resume
validators, and a test walks the encoded fields to keep it that way.

The plan names the sidecar `.tuliprox-recording.json`. Taken literally
that is one file per directory, and the organised layouts put many
recordings in one -- it would describe only whichever finished last. It
is suffixed onto the recording's own name instead.

Written staged-and-renamed before the repository is told the recording
completed, so an operator finding an orphan has the record even when the
commit is what failed. Rewriting is normal: finalization is idempotent
and the sidecar write has to be too. Failing to write one is logged, not
fatal -- refusing to complete a real recording because a descriptive
file could not be written trades the thing for the note about it.

Startup reports orphans by count. Deliberately not by path, and
deliberately without creating anything: a sidecar describes a file, it
is not evidence anyone was entitled to play it. The return type carries
no principal, so there is nothing to build an entry from.

Step 1 turned up a defect. `RetentionOwner::Shared` was a variant
nothing constructed: `from_recording_owner` read `meta.owner`, which is
always a user, so every shared recording was retained out of its
creator's personal budget -- and shared recordings by different creators
never shared a pool at all. The doc comment claimed the opposite.
Retention now keys on visibility, the same way quota already did.
2026-09-02 09:21:07 -05:00
..
2026-08-28 19:17:39 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-27 15:36:23 +02:00
2026-08-28 19:17:39 +02:00
2026-08-27 15:36:23 +02:00
2026-08-29 11:14:44 +02:00