3.3 KiB
ADR 0037: Collaborative Authored-File Safety
Status
Accepted
Context
Transactional replacement protects an authored file from partial writes, but it does not prevent an editor session from replacing a newer revision written by another tool or collaborator. Git can explain common workspace states, while Perforce-style ownership or lock services may be present in some teams. Neither Git nor a provider may be assumed, and source-control integration must never stage, reset, discard, commit, or otherwise mutate repository state.
Blacksite needs one save boundary for user-authored scenes and assets. The boundary must detect changes using file content rather than timestamps alone, preserve atomic replacement, explain read-only and collaboration conflicts, and remain useful in projects with no repository or lock provider.
Decision
- Every loaded authored document records a
FileSnapshotcontaining a BLAKE3 content revision and comparison metadata. Missing files have an explicit revision so create/save-as races are guarded. - Authored writes compare the current revision with the caller's baseline before serialization is published and again immediately before the same-directory atomic rename. A mismatch, read-only target, or provider lock blocks publication and leaves the existing file untouched.
- The conflict workflow offers reload, metadata comparison, save-as, and cancel. There is no force-overwrite action. Reload semantics are owned by the document type so scene and asset state cannot be confused.
- Git status is collected asynchronously with read-only commands and parsed from NUL-delimited porcelain output. The editor reports clean, modified, untracked, and conflicted state for the active scene and selected asset without making Git a project requirement.
- Optional ownership integrations implement a thread-safe provider trait over the currently tracked project-relative paths. Provider absence performs no work and produces no warning. Provider errors are diagnostic status, not a reason to disable filesystem revision protection.
- Generated registries, import artifacts, caches, recovery snapshots, and package output do not open authored-file conflict UI. Their existing subsystem-specific transactional or regenerative rules remain authoritative.
- Source-control integration is observational. Blacksite never stages, commits, resets, checks out, discards, or changes locks through the Git status path.
Consequences
- External changes to loaded scenes, prefabs, materials, material instances, and project settings cannot be silently replaced by normal editor save/apply/history paths.
- Timestamp-only changes do not create false content conflicts, while metadata remains available for human comparison.
- A save conflict requires an explicit recovery choice and may interrupt a bulk save operation.
- Git is invoked periodically in a worker thread; the frame loop does not wait for repository I/O.
- Provider implementations must be deterministic, bounded, and safe to call off the main thread.
- Native filesystem replacement cannot coordinate with unrelated writers that ignore advisory conventions after Blacksite's final revision check; the narrow check-to-rename interval is the platform boundary, and deterministic race hooks cover the editor-controlled interval.