Fence managed file object effects

This commit is contained in:
2026-08-03 04:21:52 +02:00
parent b993d8e31a
commit 6baf2a421b
10 changed files with 1162 additions and 25 deletions
+52 -3
View File
@@ -517,6 +517,50 @@ dry-run by default, rechecks that no database reference exists, remains scoped
to the scanned tenant prefix, and is idempotent. Both applied and dry-run
actions emit audit evidence.
### Recovery ledger for object effects
Every managed blob creation or integrity repair starts a Core recovery
operation in an independent committed transaction before Files protects or
writes bytes. The operation records tenant/blob identifiers, an opaque object
locator or locator digest, semantic SHA-256/size evidence, the recovery mode,
and a distributed lease fence. It never records file contents, ZIP passwords,
connector credentials, or a newly uploaded filename. New object keys are opaque;
legacy filename-bearing keys remain readable but repair operations record only
their digest and recover through the blob ID.
The Files business transaction then creates or updates the blob, version, and
asset rows. Its actual SQLAlchemy commit or rollback settles every pending
operation:
- commit reloads the blob through an independent session and streams the object
to verify its stored-byte SHA-256 and size before recording success;
- rollback deletes only a newly reserved object after independently proving
that no `FileBlob` references it, then records verified compensation;
- a repaired existing object is forward-completed only when its identity,
envelope, semantic evidence, and stored bytes all match;
- missing or mismatched bytes quarantine a committed blob and leave the
operation `recovery_required`; an unavailable probe remains
`outcome_unknown` rather than becoming an ordinary upload failure.
Applied orphan cleanup has its own forward-recovery operation. The database
reference check and tenant-prefix check happen before deletion; object absence
and the durable finding state are verified afterward. If the caller transaction
rolls back after deletion, Files may forward-complete only that existing
finding after rechecking that the key is still unreferenced.
Archive preview and confirmation use bounded process-local temporary staging.
Staging is not authoritative and is removed on every handled exit; extracted
members enter the same per-blob recovery boundary as direct uploads. A hard
process loss may leave a temporary OS file for normal host temporary-file
cleanup, but cannot make that staging path a managed Files object.
Use the Ops recovery-operation view to inspect `files` operations. Do not retry
a busy or unresolved blob blindly: first verify the FileBlob row, object hash,
integrity state, and any Encryption envelope named by the blob. Hard purge,
legal hold, and two-way remote connector mutation are not implemented yet, so
they cannot claim recovery-ledger adoption; their owning work remains tracked
separately.
After restore:
1. Verify the active tenant and module migration state.
@@ -644,6 +688,9 @@ Files baseline indiscriminately.
every protected blob; they are identical for unprotected blobs.
- Upload and archive-confirm APIs can select an Encryption vault. Protected
writes and reads fail closed if the optional Encryption capability is absent.
- Managed-object writes and applied orphan cleanup start lease-fenced Core
recovery operations before their physical effects; terminal success and
compensation require independent database and object checks.
The module does **not** currently provide malware scanning, content disarm and
reconstruction, a file-type allowlist, per-user quota, automatic encryption
@@ -794,8 +841,8 @@ returning different content or credentials.
| Area | Implemented now | Planned or explicitly outside the current boundary |
| --- | --- | --- |
| Managed storage | Core local/S3 backend, exact managed-Garage or explicitly trusted HTTPS external S3, state-profile validation, fallback local read roots, tenant blob deduplication, checksums, bounded resumable integrity scans, quarantine, and dry-run-first orphan cleanup | Scheduled scan execution and deployment-specific S3 HA/backup automation |
| Upload | Bounded direct upload, drag-and-drop UI, archive preview/selective extraction, password-protected ZIP support, explicit conflicts | Malware scanning, quotas, type policy, resumable/chunked upload |
| Managed storage | Core local/S3 backend, exact managed-Garage or explicitly trusted HTTPS external S3, state-profile validation, fallback local read roots, tenant blob deduplication, checksums, bounded resumable integrity scans, quarantine, dry-run-first orphan cleanup, and Core-ledger verification/forward recovery | Scheduled scan execution and deployment-specific S3 HA/backup automation |
| Upload | Bounded direct upload, drag-and-drop UI, archive preview/selective extraction, password-protected ZIP support, explicit conflicts, opaque new object keys, and rollback compensation | Malware scanning, quotas, type policy, resumable/chunked upload |
| Organization | Folders, bulk rename preview/apply, move/copy, drag-and-drop, ZIP download, pattern resolution | General file-history UI and user-driven append-version/restore |
| Sharing | User/group/tenant/campaign grants, expiry, idempotent revocation, searchable share-management UI, and campaign linkage display | Richer policy-driven share lifecycles |
| Deletion/retention | Soft-delete assets/folders/spaces; immediate audited connector-secret scrubbing | File restore API, hard purge, retention policy, legal hold, and blob GC ([#38](https://git.add-ideas.de/GovOPlaN/govoplan-files/issues/38)) |
@@ -829,7 +876,9 @@ Before releasing Files:
8. Verify credential deletion scrubs dependents and produces audit evidence.
9. Verify a campaign attachment snapshot still identifies its exact version and
checksum after the current file changes.
10. Update the implemented/planned table whenever a boundary changes.
10. Exercise a committed upload, a rolled-back upload, object tamper detection,
and applied orphan cleanup; inspect their `files` operations in Ops.
11. Update the implemented/planned table whenever a boundary changes.
## Related documents