mirror of
https://github.com/euzu/tuliprox.git
synced 2026-09-24 10:02:29 +02:00
First step of the shared-recording model. A recording is now stored as two records: a PersistedMaterialization, which is the file on disk and the work that produces it, and a PersistedLibraryEntry, which is one principal's link to it. The materialization carries no owner and no visibility, because a file that several users have asked for cannot belong to any one of them. The mapping is still one entry per file, so no behaviour changes yet. What changes is where the truth lives: reference_count is now a stored field with one owner, and read_records() refuses any state where it disagrees with the links pointing at the file, or where a link names a file that is not there. A file deleted while still reachable, or kept forever after its last reference went away, is not something a later pass can work out by guessing. The DVR still works in whole tasks; split() and join() are the repository's job precisely so the count has a single place to be maintained. join() is lossless, and the link is authoritative for owner, visibility and quota while the file is authoritative for everything physical. Entry ids and materialization ids are separate namespaces from the start (mat-<uuid>), so they cannot be used interchangeably in the interval before one file legitimately serves several entries. The schema name and database file change to recording_library, because the previous shape stored the owner inside the task and cannot be expressed as a one-to-one value migration into two records. The queue does not migrate — as already documented — so the old database and history are left untouched beside the new pair rather than failing the open. The startup tests now discover the repository's artefacts instead of naming them; hardcoding the filenames would have silently stopped testing the fail-closed path the moment they changed, which is exactly what happened here.