56 lines
3.5 KiB
Markdown
56 lines
3.5 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.
|
|
- [ADR 0047](0047-editor-authored-asset-documents.md) applies these guards at explicit asset Save
|
|
boundaries; interactive parameter edits never enter the authored-file publication path.
|