Repository navigation
Description
Summary
The S4a/S4b guarded-write core (epic Zoo-Code-Org#1375, org) publishes via a check-then-publish sequence: compute the on-disk version token (stat-based), then rename the temp file into place. This is atomic with respect to in-process writers (all agent writes serialize on the per-path FIFO chain, and the CAS is evaluated inside that chain), but the check and the rename are not atomic with respect to other processes that can write the same file.
This issue tracks hardening the publish to be atomic (or provably safe) against inter-process writers — the design-level gap flagged by the CodeRabbit pre-merge "Persistence Integrity" check on PR Zoo-Code-Org#1833 (review card comment 5868626789, 2026-09-28).
Threat model (current series design)
- The extension host process is the sole agent writer in the series trust model: the model/agent writes files only through the guarded write path.
- VS Code's own file service writes originate from explicit user actions (the user is the operator, not an adversary — dirty/save-prompt state is surfaced in the UI), and external editors fall into the same operator-initiated category.
- The guard's job is to prevent the agent from silently clobbering content it has not seen or that has changed since it was seen — the re-read-then-retry contract does that.
What inter-process hardening would need (options, undecided)
- Per-file inter-process lockfile shared by every participating writer, held across the check + rename. Open questions: which writers participate (the VS Code file service cannot be modified — non-participating writers remain outside the lock), stale-lock handling, lock granularity.
- Platform-supported atomic CAS publish (e.g. a replace-if-unmodified syscall/API). Open questions: cross-platform availability (Windows/POSIX), whether the "unmodified" predicate can be the version token, symlink handling.
- Post-publish verification + compensating retry: publish, then re-stat; on mismatch, re-read and retry (weaker — the window remains, but the window's consequences become self-healing).
Any solution must carry its own threat-model decisions (which writers are in the trust boundary, what non-participating writers are allowed to do) and be budgeted as its own unit (planned before issued, per the series split discipline).
References
- Epic: ZooCode-Org/Zoo-Code#1375 (file-write-safety series), split record comment 5868117610
- PR: feat(tools): track read completeness and guard the diff-view save path (S4b, #1375) Zoo-Code-Org/Zoo-Code#1833 (S4b follow-ups) — pre-merge card comment 5868626789 (Persistence Integrity ❌, 2026-09-28)
- Core code: src/core/tools/guardedWrite.ts (replaceIfVersion / createIfAbsent), src/services/file-safety/safeWriteText.ts (atomic temp-file rename commit)
Activity