Blacksite/docs/adr/0037-collaborative-authored-file-safety.md

54 lines
3.3 KiB
Markdown

# 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 `FileSnapshot` containing 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.