feat(file-safety): atomic text publish primitive (S3 v2-1, epic #1375) - #43
Open
easonLiangWorldedtech wants to merge 1 commit into
Open
feat(file-safety): atomic text publish primitive (S3 v2-1, epic #1375)#43easonLiangWorldedtech wants to merge 1 commit into
easonLiangWorldedtech wants to merge 1 commit into
Conversation
…ode-Org#1375) Recreates upstream PR Zoo-Code-Org#1395 (A4) on current main as the first unit of the v2 split. Adds src/services/file-safety/safeWriteText.ts: temp-file write + atomic commit rename with optional backup, win32 DACL preservation/restore, and pre-commit verification hook wiring (A4a guarded-write surface). Includes the unit spec (safeWriteText.spec.ts). Content is byte-identical to the reviewed Zoo-Code-Org#1395 tip (tree 0a6f4ac772, commit a37dd24).
Review statusThanks for contributing. This comment tracks the review sequence and the next action. Current step: Required CI passed. Waiting for automated review of the latest commit. If automated review does not start, a maintainer must restart it. Review-state labels are managed by this workflow; do not edit them manually. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First unit of the v2 split of the file-write-safety stack (epic Zoo-Code-Org#1375, A4). Recreates the reviewed content of upstream PR Zoo-Code-Org#1395 (S3: atomic text publish) on current main as a standalone unit, replacing the stacked PR chain that will be closed as superseded.
Changes
src/services/file-safety/safeWriteText.ts(new, 304 lines): atomic text publish primitiveresolvePublishTarget: realpath resolution for the target; ENOENT falls back to the given path, any other error propagatessafeWriteText(filePath, content, options):backup: true: renames the previous target to a backup before the commit and deletes it on success; on commit failure the backup is renamed back (rollback) and the temp file is discardedtempPath: caller-supplied pre-written temp file (used by safeWriteJson in a later unit); the staging dir is not created and the temp file is not unlinked (caller's concern)platform/execFileRunner: test seams for the win32 DACL pathsrc/services/file-safety/__tests__/safeWriteText.spec.ts(new, 672 lines): 31 unit tests — happy path/cleanup, fsync ordering, symlink resolution, backup/rollback semantics (ENOENT swallowing, error propagation), win32 DACL handling (save/restore args, fallback on failure, dump cleanup, default-platform path), pre-written tempPath behaviour (fchmod to target mode, 0o444 open ordering, no POSIX directory fsync), and durability regressions (short writes, POSIX directory fsync, realpath/access error propagation)Tests
src/workspace): 31/31 passed--prune-suppressions --max-warnings=0on both files: clean, suppression counts unchangedpnpm check-types: passed (11/11 tasks)scripts/stryker-diff.mjs ci, changed lines only): 115 mutants — 109 killed + 6 timeouts; 0 surviving, 0 NoCoverageorigin/main(measured viagit merge-tree --write-tree); within the 1000 hard cap. A single self-contained new module plus its spec — splitting further would fragment the primitive from its tests.Provenance
7fd49bcea, S3 heada37dd24f1. Functionally identical, with the following documented micro-refactors made to satisfy the 100% mutation gate:Buffer.from(content)— the explicit"utf8"encoding literal was an equivalent mutant (default encoding is utf8)codeextraction in the ENOENT checks totypeof x === "object" && x !== null— property access on a non-null object returnsundefinedwhen absent, so dropping the"code" in xhalf is behaviour-identical while removing an equivalent-mutant siteconst opts: SafeWriteTextOptions = options ?? {}instead of repeatedoptions?.lookupsplatform === "win32" &&guard in the post-commit DACL restore (daclDumpPathis non-null only on the win32 save path)origin/main0dbd5846f(v3.82.0)