Finding
Non-interactive patching currently analyzes and writes files concurrently. A later analysis or write failure can therefore leave earlier files modified. Interactive patching preflights all selected files, but its sequential write phase can still partially apply a multi-file patch.
Portable filesystem APIs cannot provide a truly atomic project-wide commit, so the implementation must expose that limitation rather than overstate its guarantees.
Proposed approach
- Separate file analysis from filesystem mutation in
packages/spatch/src/phases/rewrite.ts.
- Stage replacement and rollback content for every changed file before modifying any target.
- Preflight all targets against their analyzed source content.
- Commit in deterministic absolute-path order with a final stale-content check before each rename.
- On commit failure, roll back committed files in reverse order without overwriting concurrent external edits.
- Throw an explicit
PartialCommitError listing affected files if rollback cannot fully restore the original state.
- Route interactive and non-interactive writes through the same transaction implementation in
packages/spatch/src/file-write.ts.
Acceptance criteria
- Analysis, staging, or global preflight failure modifies no target files.
- Commit order is deterministic regardless of analysis concurrency.
- A later commit failure restores earlier writes when rollback succeeds.
- Incomplete rollback produces a stable typed error with deterministic affected-file paths.
- Concurrent edits are preserved rather than overwritten during commit or rollback.
- Dry-run, check mode, result shape, and CLI output remain compatible.
- Tests cover staging failure, stale preflight, commit failure with successful rollback, rollback failure, and concurrent edits.
Finding
Non-interactive patching currently analyzes and writes files concurrently. A later analysis or write failure can therefore leave earlier files modified. Interactive patching preflights all selected files, but its sequential write phase can still partially apply a multi-file patch.
Portable filesystem APIs cannot provide a truly atomic project-wide commit, so the implementation must expose that limitation rather than overstate its guarantees.
Proposed approach
packages/spatch/src/phases/rewrite.ts.PartialCommitErrorlisting affected files if rollback cannot fully restore the original state.packages/spatch/src/file-write.ts.Acceptance criteria