cadrumo.adapters.persistence.storage.custody._inventory module¶
Bounded no-follow inventory of current profile-custody capsules.
- DATABASE_SIDECAR_RELATIVE_PATHS: Final[frozenset[str]]¶
Members the digest ignores ENTIRELY, path and bytes alike.
The engine opens the capsule database in
journal_mode=WAL, so an open connection parks committed pages in a-walsidecar with a-shmindex beside it, and closing that connection removes both. Their very presence is a statement about whether a connection is open, so neither their bytes nor their existence can be held constant across a transaction that closes one.
- HOLDER_LOCK_RELATIVE_PATHS: Final[frozenset[str]]¶
Members the digest ignores ENTIRELY, path and bytes alike.
The lockfile’s whole payload is the holder’s process id, and its presence is a statement about WHO HOLDS the bucket rather than about custody. A transaction whose own precondition is to acquire that lock cannot hold it constant: the process that resumes after a crash is a different process, so it writes a different pid, and a digest covering it can never reproduce across the boundary it exists to span. That is the same self-invalidation the sidecar exclusion above answers, one file over.
Excluded entirely rather than by path alone, because presence is volatile too (absent unheld, present held, removed when a stale holder is reclaimed) and because a staged capsule never carries one while a published capsule can – so a presence member would diverge a stage-versus-committed comparison that is otherwise identical. Nothing about lock SAFETY rests here: acquisition is enforced by exclusive creation and stale reclaim, never by this digest.
- DATABASE_PRESENCE_ONLY_RELATIVE_PATHS: Final[frozenset[str]]¶
Members the digest covers by PATH but not by content.
This is the capsule’s own encrypted database, and it is the concession this module has to argue for rather than assume. Excluding only the two sidecars above looks sufficient and is not: closing the connection CHECKPOINTS the sidecar’s pages into the main file, which was measured growing from 12288 to 94208 bytes across one ordinary session close with no logical write between the two observations. Holding its bytes constant across a transaction whose first act closes that connection is therefore not merely strict, it is unsatisfiable – it would refuse every deletion of a profile the operator is signed into, which is the same self-invalidation excluding the sidecars exists to fix, one file over.
So its bytes are out. Its PATH is not: a database that vanished, or became a directory, between preflight and execution moves the digest and refuses. That is a real guard and it costs nothing, but it must not be oversold – content between those two points is genuinely unwatched, and that limitation is stated on
ProfileCustodyInventorywhere a reader of the digest will meet it.Both collections are exact paths read off the storage taxonomy, never a suffix or directory rule. A foreign file dropped anywhere under the database directory is in neither and stays fully content-covered.
- class ProfileCustodyInventoryEntry(relative_path, size_bytes, sha256)[source]¶
Bases:
objectOne regular file observed under a current committed capsule.
- class ProfileCustodyInventory(profile_id, entries, digest_entries, total_bytes, digest)[source]¶
Bases:
objectBounded, no-follow exact inventory used by local custody transactions.
The capsule holds four kinds of member, and the digest treats each differently:
Custody records – the password envelope, the DEK sentinel, the label projection, the commit record, the recovery envelope, and anything else not named below. Covered by path AND content. These are write-once canonical JSON, so one byte different is a different capsule.
The capsule database,
DATABASE_PRESENCE_ONLY_RELATIVE_PATHS. Covered by path only.Its write-ahead sidecars,
DATABASE_SIDECAR_RELATIVE_PATHS. Not covered at all.The bucket holder lockfile,
HOLDER_LOCK_RELATIVE_PATHS. Not covered at all, because its payload is the holding process’s id and a transaction that acquires the lock cannot hold that constant across the process boundary a crash-resume spans.
entriesis the honest observation: every regular file the walk saw, whatever its treatment.digest_entriesis the subset whose CONTENT the digest covers, and it is the one a caller should measure or count when it needs a figure that survives a connection closing.The split exists because a local deletion compares an inventory taken at preflight against the same capsule at execution, and its own first destructive act – revoking the live profile secret – closes the capsule’s database connection. That close removes the sidecars and checkpoints their pages into the database file, so a digest over raw bytes could never match itself and a profile the operator was signed into could not be deleted at all.
THE LIMITATION, stated here rather than left to be discovered: rows written into the capsule DATABASE between preflight and execution do not move the digest. Nothing else catches them either – the deletion is the only reader of this inventory in that window. It is not recoverable at this layer, because the database’s logical content is readable only through the DEK, which a deletion deliberately never holds, and its raw bytes are a function of connection state. What survives is that the database must still BE there, and that every other member is byte-exact.
- Parameters:
profile_id (UUID)
entries (tuple[ProfileCustodyInventoryEntry, ...])
digest_entries (tuple[ProfileCustodyInventoryEntry, ...])
total_bytes (int)
digest (str)
-
entries:
tuple[ProfileCustodyInventoryEntry,...]¶
-
digest_entries:
tuple[ProfileCustodyInventoryEntry,...]¶