fix(coding-agent): write settings and credentials atomically and migrate auth safely - #989
Closed
Adolanium wants to merge 1 commit into
Closed
Conversation
…ate auth safely - FileSettingsStorage.withLock re-reads the settings file under the lock before a first-time write, so concurrent creators no longer lose each other's updates, and writes go through a temp file and rename instead of truncating settings.json in place. - FileAuthStorageBackend writes auth.json via a 0600 temp file and atomic rename on both the sync and async lock paths, so a crash mid-write can no longer corrupt all stored credentials. - migrateAuthToAuthJson writes auth.json first and only then rewrites settings.json and renames oauth.json to .migrated, so a crash during migration cannot destroy credentials. fixes PrimeIntellect-ai#983
Contributor
|
Thank you for the report and proposed work. This root cause is now covered by maintainer-owned stacked PR #1160, authored independently from We did not inspect or reuse this PR's diff, branch, commits, implementation code, or tests; its public description/comments were used only as a bug report. To keep one review surface, this PR is superseded by #1160 and is being closed. The complete review stack is #1158–#1165. It is being left unmerged for human review after CI and review-bot findings are cleared. |
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.
Fixes #983.
What was broken
Three ways to silently lose settings or credentials:
FileSettingsStorage.withLockcomputed the next state before taking the lock when the file did not exist yet, so two concurrent first-time creators both merged from empty state and the later write won. It also wrote directly to the target, so a crash mid-write left a truncatedsettings.jsonthat the loader silently replaced with defaults.FileAuthStorageBackendwroteauth.jsonin place on both the sync and async paths. A crash mid-write corrupted every stored OAuth refresh token and API key at once.migrateAuthToAuthJsonrenamedoauth.jsonto.migratedand deletedapiKeysfromsettings.jsonbeforeauth.jsonwas written. A crash in that window left nothing to migrate on the next run.The fix
0o600at creation) + chmod + rename, mirroring the existingwritePrimeCliConfigDatapattern.auth.jsonfirst and only then rewritessettings.jsonand renamesoauth.json.Locking structure, the sync retry API, and the OAuth refresh flow are unchanged.
Testing
test/suite/regressions/983-credential-file-durability.test.ts(5 tests): migration ordering asserted via recorded fs events, re-read under lock on first creation, temp+rename with no leftovers on the settings and auth paths.npx tsx ../../node_modules/vitest/dist/cli.js --runon the new file plus the existing auth-storage, settings-manager, and migrations suites: all green. (Three failures inauth-storage.test.ts/auth-flows.test.ts/4620-fast-mode-settingsreproduce on pristine main and are unrelated, verified in a clean worktree.)npm run checkclean.Note
Write auth.json and settings.json atomically and harden credential migration
FileAuthStorageBackendnow go through a newwriteAtomicallyhelper: content is written to a uniquely-named0600temp file in the same directory, then renamed over the target, avoiding truncation on crash.FileSettingsStorageuse a newwriteSettingsFileAtomicallyhelper with the same temp-file-and-rename approach; first-time creation re-reads under the lock to avoid losing concurrent writes.migrateAuthToAuthJsonnow writesauth.jsondurably (via atomic helper,0600) before removingapiKeysfromsettings.jsonor renamingoauth.json, reducing credential loss risk on crash mid-migration.983-credential-file-durability.test.tsverifies atomic rename behavior, lock re-read semantics, and restrictive file permissions.Macroscope summarized 99a136c.