[PR #4855] [MERGED] fix(setup): preserve concurrent client configuration edits #6443

Closed
opened 2026-10-31 01:14:30 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4855
Author: @abdulwasea89
Created: 10/17/2026
Status: ✅ Merged
Merged: 10/22/2026
Merged by: @morluto

Base: main ← Head: fix/setup-configuration-conflicts


📝 Commits (10+)

  • 564a930 fix(setup): preserve concurrent client configuration edits
  • 67ca0df fix(setup): normalize configuration transaction queue paths
  • 11fe0f4 fix(setup): report concurrent snapshot read conflicts
  • 2966037 test(setup): isolate Pi workflows from installed Hopper
  • 9fcaf8f fix(setup): reconcile conflict handling with current main
  • 39bcc4d chore: merge main into setup configuration conflict handling
  • 9cb6dd2 test: align inherited fixtures with current analysis contracts
  • eb732e6 test(ida): assert search recovery instead of diagnostic prose
  • 9960026 chore: merge main into setup configuration conflict handling
  • b87c796 fix(setup): share configuration queue keys across directory aliases

📊 Changes

11 files changed (+752 additions, -56 deletions)

View changed files

📝 docs/installation.md (+9 -0)
📝 src/application/ClientConfigPath.ts (+45 -5)
📝 src/application/ClientConfigurationPublication.ts (+86 -7)
➕ src/application/ClientConfigurationTransaction.ts (+27 -0)
📝 src/application/SetupClientConfiguration.ts (+85 -40)
📝 src/application/SetupClients.ts (+2 -0)
📝 src/application/SetupTypes.ts (+5 -0)
📝 tests/acceptance/setup/piClientSetup.test.ts (+3 -0)
📝 tests/boundary/filesystem/setupConfig.test.ts (+32 -0)
➕ tests/process-global/setupConfigurationConflicts.test.ts (+454 -0)
📝 tests/process-global/setupConfigurationRollback.test.ts (+4 -4)

📄 Description

Summary

When rea setup races with another edit to a client configuration, it reports a typed conflict and asks the user to review the current file and retry. Directory-symlink and real-directory spellings of the same file now share one in-process queue key.

Problem and approach

The original setup flow could take a snapshot, then publish from stale input or misclassify a replacement during readback and recovery. Current main already owns publication and cleanup through ClientConfigurationPublication. This PR uses that owner, carries the initial file identity and content into publication, verifies the selected destination before writing, and classifies confirmed changes as conflict. A path-keyed queue serializes setup operations within this process. The publication owner retains its descriptor, staging file, and failed cleanup for retry. Genuine I/O failures keep their distinct outcomes; first-run cleanup still follows the existing manual-recovery safety rule. Installation docs describe the guarantee and its external-writer limit.

resolveClientConfigTransactionPath now resolves parent-directory aliases for regular and missing files, including absent intermediate directories, before the queue chooses its key. A configuration file symlink still resolves only when the link and its target are owned by the current user. If a parent-directory alias is retargeted after that selection, publication keeps the already chosen canonical file. A configuration symlink that then names a different target still conflicts.

The user-visible message is: Agent configuration changed during setup. Review the current file and rerun setup. No provider, target execution, or network authority changes. The Pi acceptance fixtures select an unavailable Hopper launcher to prevent unrelated local-provider probes from creating cache files in their temporary homes.

Evidence and validation

Merged main at 7091be291 (#6375), which supplies the current browser storage fingerprint fixtures. Legacy hashed storage without fingerprint_version stays unknown. On Node 24.18.0 and npm 11.16.0:

  • npm run test:focused -- tests/process-global/setupConfigurationConflicts.test.ts tests/process-global/setupConfigurationRollback.test.ts tests/boundary/filesystem/setupConfig.test.ts tests/boundary/filesystem/clientConfigurationTransactions.test.ts tests/boundary/cli/browserCli.test.ts — 109 tests passed, including directory-alias queue serialization and compares reordered scenario storage through the public CLI.
  • npm run test:focused -- tests/boundary/filesystem/clientLifecycle.test.ts tests/boundary/filesystem/clientConfigurationBom.test.ts tests/boundary/filesystem/clientConfigurationDialects.test.ts tests/acceptance/setup/repeatedClientSetup.test.ts — 117 tests passed.
  • npm run check:fast — passed.

Directory-symlink coverage is skipped on Windows. There is no OS-level compare-and-swap or cross-process lock, so an external writer can still race after a filesystem check. Real-provider workflows were not run.

Scope and release

This is an ordinary setup correctness fix within existing configuration authority. The CLI setup result adds an explicit conflict outcome; the MCP catalog, dependencies, generated metadata, and provider contracts are unchanged. No migration is required. Only approved setup configuration writes are involved; no production client settings were edited during validation.

CI follow-up at 84ae10aa4: merged main bea6b98e8, which supplies the current structured integrity-error assertion for malformed mobile inventory Evidence, and formatted the new queue-alias regression. The five-file focused mobile/setup batch passed 102 tests; npm run check:ci:fast passed all five tasks, including formatting and built lint. Hosted validation of the updated head is pending.

Author readiness

Human owner: @abdulwasea89

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.
Open in Web Open in Cursor 

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4855 **Author:** [@abdulwasea89](https://github.com/abdulwasea89) **Created:** 10/17/2026 **Status:** ✅ Merged **Merged:** 10/22/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/setup-configuration-conflicts` --- ### 📝 Commits (10+) - [`564a930`](https://github.com/morluto/rea/commit/564a93081dc2875dbcfbfa9b2a8e1dd5af588eab) fix(setup): preserve concurrent client configuration edits - [`67ca0df`](https://github.com/morluto/rea/commit/67ca0dfde1cb27470c7c17943383a54d03ce0484) fix(setup): normalize configuration transaction queue paths - [`11fe0f4`](https://github.com/morluto/rea/commit/11fe0f40c441b8a1cf5b0de78ba3e06b77d589f2) fix(setup): report concurrent snapshot read conflicts - [`2966037`](https://github.com/morluto/rea/commit/2966037461980ef8e026302c0d5dfb92b852b418) test(setup): isolate Pi workflows from installed Hopper - [`9fcaf8f`](https://github.com/morluto/rea/commit/9fcaf8f17b3f510e40ba865adfb56e4853ab22d7) fix(setup): reconcile conflict handling with current main - [`39bcc4d`](https://github.com/morluto/rea/commit/39bcc4dbf3fa7497a504de002b7a2d82ead75415) chore: merge main into setup configuration conflict handling - [`9cb6dd2`](https://github.com/morluto/rea/commit/9cb6dd2e5c860601c18dcc0b87f985d2ec124a38) test: align inherited fixtures with current analysis contracts - [`eb732e6`](https://github.com/morluto/rea/commit/eb732e63c336540033cb881e92dcd8349502484e) test(ida): assert search recovery instead of diagnostic prose - [`9960026`](https://github.com/morluto/rea/commit/99600264a032f45c4341722ab40b552612983c4d) chore: merge main into setup configuration conflict handling - [`b87c796`](https://github.com/morluto/rea/commit/b87c796f73fec648c5c39a253d3ac875d3584a92) fix(setup): share configuration queue keys across directory aliases ### 📊 Changes **11 files changed** (+752 additions, -56 deletions) <details> <summary>View changed files</summary> 📝 `docs/installation.md` (+9 -0) 📝 `src/application/ClientConfigPath.ts` (+45 -5) 📝 `src/application/ClientConfigurationPublication.ts` (+86 -7) ➕ `src/application/ClientConfigurationTransaction.ts` (+27 -0) 📝 `src/application/SetupClientConfiguration.ts` (+85 -40) 📝 `src/application/SetupClients.ts` (+2 -0) 📝 `src/application/SetupTypes.ts` (+5 -0) 📝 `tests/acceptance/setup/piClientSetup.test.ts` (+3 -0) 📝 `tests/boundary/filesystem/setupConfig.test.ts` (+32 -0) ➕ `tests/process-global/setupConfigurationConflicts.test.ts` (+454 -0) 📝 `tests/process-global/setupConfigurationRollback.test.ts` (+4 -4) </details> ### 📄 Description ## Summary When `rea setup` races with another edit to a client configuration, it reports a typed conflict and asks the user to review the current file and retry. Directory-symlink and real-directory spellings of the same file now share one in-process queue key. ## Problem and approach The original setup flow could take a snapshot, then publish from stale input or misclassify a replacement during readback and recovery. Current `main` already owns publication and cleanup through `ClientConfigurationPublication`. This PR uses that owner, carries the initial file identity and content into publication, verifies the selected destination before writing, and classifies confirmed changes as `conflict`. A path-keyed queue serializes setup operations within this process. The publication owner retains its descriptor, staging file, and failed cleanup for retry. Genuine I/O failures keep their distinct outcomes; first-run cleanup still follows the existing manual-recovery safety rule. Installation docs describe the guarantee and its external-writer limit. `resolveClientConfigTransactionPath` now resolves parent-directory aliases for regular and missing files, including absent intermediate directories, before the queue chooses its key. A configuration file symlink still resolves only when the link and its target are owned by the current user. If a parent-directory alias is retargeted after that selection, publication keeps the already chosen canonical file. A configuration symlink that then names a different target still conflicts. The user-visible message is: `Agent configuration changed during setup. Review the current file and rerun setup.` No provider, target execution, or network authority changes. The Pi acceptance fixtures select an unavailable Hopper launcher to prevent unrelated local-provider probes from creating cache files in their temporary homes. ## Evidence and validation Merged `main` at `7091be291` (`#6375`), which supplies the current browser storage fingerprint fixtures. Legacy hashed storage without `fingerprint_version` stays `unknown`. On Node 24.18.0 and npm 11.16.0: - `npm run test:focused -- tests/process-global/setupConfigurationConflicts.test.ts tests/process-global/setupConfigurationRollback.test.ts tests/boundary/filesystem/setupConfig.test.ts tests/boundary/filesystem/clientConfigurationTransactions.test.ts tests/boundary/cli/browserCli.test.ts` — 109 tests passed, including directory-alias queue serialization and `compares reordered scenario storage through the public CLI`. - `npm run test:focused -- tests/boundary/filesystem/clientLifecycle.test.ts tests/boundary/filesystem/clientConfigurationBom.test.ts tests/boundary/filesystem/clientConfigurationDialects.test.ts tests/acceptance/setup/repeatedClientSetup.test.ts` — 117 tests passed. - `npm run check:fast` — passed. Directory-symlink coverage is skipped on Windows. There is no OS-level compare-and-swap or cross-process lock, so an external writer can still race after a filesystem check. Real-provider workflows were not run. ## Scope and release This is an ordinary setup correctness fix within existing configuration authority. The CLI setup result adds an explicit `conflict` outcome; the MCP catalog, dependencies, generated metadata, and provider contracts are unchanged. No migration is required. Only approved setup configuration writes are involved; no production client settings were edited during validation. CI follow-up at `84ae10aa4`: merged main `bea6b98e8`, which supplies the current structured integrity-error assertion for malformed mobile inventory Evidence, and formatted the new queue-alias regression. The five-file focused mobile/setup batch passed 102 tests; `npm run check:ci:fast` passed all five tasks, including formatting and built lint. Hosted validation of the updated head is pending. ## Author readiness Human owner: @abdulwasea89 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. <div><a href="https://cursor.com/agents/bc-8d7d89dd-f444-50ff-bca8-58370fac76b8?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-8d7d89dd-f444-50ff-bca8-58370fac76b8&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:14:30 +00:00
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#6443
No description provided.