[GH-ISSUE #4900] [Bug] Setup rollback can overwrite or delete a replacement configuration #3042

Closed
opened 2026-10-31 00:35:22 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4900

Before submitting

  • Searched open and closed configuration/rollback/replacement reports.
  • Removed credentials and sensitive target data.

Area

Setup, packaging, or upgrade

Observed behavior

Three controlled production-boundary regressions fail at main 19329e43b: after atomic setup publication, replace the config path before a forced readback failure. Existing-file rollback follows a replacement symlink and overwrites its unrelated target, overwrites a replacement regular file, or first-run rollback deletes a replacement symlink. The six existing recovery controls pass.

Reproduction

npm run test:focused -- tests/process-global/setupConfigurationRollback.test.ts: 3 failed, 6 passed. Added controls use the existing atomic-writer/readback fault seam. The real writer publishes real bytes, then owned fixture operations replace the pathname before the injected readback failure. All fixtures are temporary; no real agent config or external target was touched. Each case executed once.

Expected behavior

Per AGENTS.md ownership rules, rollback may act only on the transaction's exact published file. Pathnames and original-content backups do not prove current mutation/removal authority. Preserve a replacement, retain the verified original backup, and report unresolved recovery.

Impact and scope

Observed data replacement/deletion at the controlled filesystem application boundary. Public CLI/MCP or real concurrent editor reproduction and user frequency: NOT_ENOUGH_INFO; not measured. Source also reopens a transaction path through write-file-atomic rather than carrying publication identity into rollback.

REA version

6.5.0 source 19329e43bb.

Runtime and platform

Node24.18.0, macOS arm64; real temporary files, injected sequencing/readback failure.

Target and artifact context

Owned inert JSON files only; no investigated application or provider execution.

Interface / Earliest failure stage

Other: shared setup filesystem boundary / readback and rollback.

Relevant output or evidence

Expected replacement bytes, received original bytes in both existing-file controls. First-run replacement-symlink lstat failed ENOENT. Source: SetupClientConfiguration.ts restoreConfig reopens with writeFile(path, original), or rm(path) when there was no original.

Analysis

Source-derived root cause: transaction ownership is represented only by a string path after publication. Retain the exact staged/published descriptor through verification and recovery, compare current name identity, and route restoration through the owned descriptor. Cleanup failures must retain that descriptor owner. Related broad lifecycle audit #4227; no matching concrete report found in search.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4900 ### Before submitting - [x] Searched open and closed configuration/rollback/replacement reports. - [x] Removed credentials and sensitive target data. ### Area Setup, packaging, or upgrade ### Observed behavior Three controlled production-boundary regressions fail at main 19329e43b: after atomic setup publication, replace the config path before a forced readback failure. Existing-file rollback follows a replacement symlink and overwrites its unrelated target, overwrites a replacement regular file, or first-run rollback deletes a replacement symlink. The six existing recovery controls pass. ### Reproduction `npm run test:focused -- tests/process-global/setupConfigurationRollback.test.ts`: 3 failed, 6 passed. Added controls use the existing atomic-writer/readback fault seam. The real writer publishes real bytes, then owned fixture operations replace the pathname before the injected readback failure. All fixtures are temporary; no real agent config or external target was touched. Each case executed once. ### Expected behavior Per AGENTS.md ownership rules, rollback may act only on the transaction's exact published file. Pathnames and original-content backups do not prove current mutation/removal authority. Preserve a replacement, retain the verified original backup, and report unresolved recovery. ### Impact and scope Observed data replacement/deletion at the controlled filesystem application boundary. Public CLI/MCP or real concurrent editor reproduction and user frequency: NOT_ENOUGH_INFO; not measured. Source also reopens a transaction path through write-file-atomic rather than carrying publication identity into rollback. ### REA version 6.5.0 source 19329e43bb38ca9d64512d801b25abcb188d2512. ### Runtime and platform Node24.18.0, macOS arm64; real temporary files, injected sequencing/readback failure. ### Target and artifact context Owned inert JSON files only; no investigated application or provider execution. ### Interface / Earliest failure stage Other: shared setup filesystem boundary / readback and rollback. ### Relevant output or evidence Expected replacement bytes, received original bytes in both existing-file controls. First-run replacement-symlink lstat failed ENOENT. Source: SetupClientConfiguration.ts restoreConfig reopens with writeFile(path, original), or rm(path) when there was no original. ### Analysis Source-derived root cause: transaction ownership is represented only by a string path after publication. Retain the exact staged/published descriptor through verification and recovery, compare current name identity, and route restoration through the owned descriptor. Cleanup failures must retain that descriptor owner. Related broad lifecycle audit #4227; no matching concrete report found in search.
bsakaguchi 2026-10-31 00:35:22 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Fixed in 7e4eed9dd on main.

Setup now retains the exact staged descriptor through publication, readback and recovery. A replaced pathname cannot redirect restoration to a different file; detected replacements/edits retain their bytes and the original backup. First-run readback failure reports manual recovery and retains the file, since pathname deletion cannot prove exact ownership. Nested readback/publication close failures retain both exact owners; a typed error used as an opaque close rejection cannot authorize closing an unrelated descriptor.

Executed: 192 focused tests in 9 files, check:fast, formatting, docs:check (including5 consistency tests), pre-push gate. Three replacement controls fail on baseline19329e43b while six existing recovery controls pass. Additional controls cover mixed close/retry, opaque close causes, a valid but replaced readback, and in-place edits already visible to recovery. Six completed isolated public setup tasks preserve equivalent configuration/backup semantics and filtered status replies; no performance improvement claim. Two source reviews completed after their findings were addressed.

Scope: macOS arm64 / Node24.18.0, owned temporary files and fault seams. No real agent configurations, nativeWindows/Linux, GUI app or provider/target execution. State checks do not exclude an in-place writer acting after the last check; quit clients before setup. The separate pre-publication writer path authority remains an audit candidate. The installation guide documents the recovery behavior and concurrency limitation.

<!-- gh-comment-id:6242353547 --> @morluto commented on GitHub (Oct 17, 2026): Fixed in 7e4eed9dd on main. Setup now retains the exact staged descriptor through publication, readback and recovery. A replaced pathname cannot redirect restoration to a different file; detected replacements/edits retain their bytes and the original backup. First-run readback failure reports manual recovery and retains the file, since pathname deletion cannot prove exact ownership. Nested readback/publication close failures retain both exact owners; a typed error used as an opaque close rejection cannot authorize closing an unrelated descriptor. Executed: 192 focused tests in 9 files, check:fast, formatting, docs:check (including5 consistency tests), pre-push gate. Three replacement controls fail on baseline19329e43b while six existing recovery controls pass. Additional controls cover mixed close/retry, opaque close causes, a valid but replaced readback, and in-place edits already visible to recovery. Six completed isolated public setup tasks preserve equivalent configuration/backup semantics and filtered status replies; no performance improvement claim. Two source reviews completed after their findings were addressed. Scope: macOS arm64 / Node24.18.0, owned temporary files and fault seams. No real agent configurations, nativeWindows/Linux, GUI app or provider/target execution. State checks do not exclude an in-place writer acting after the last check; quit clients before setup. The separate pre-publication writer path authority remains an audit candidate. The installation guide documents the recovery behavior and concurrency limitation.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3042
No description provided.