Fix race conditions in state persistence by reading fresh session before writing

Batch-clearing stale flags in list and blindly writing back the session
in review could clobbер concurrent changes. Use per-session get/set
instead of whole-state load/save, and re-read before clearing in_review.
This commit is contained in:
Chris Wanstrath 2026-03-19 11:24:18 -07:00
parent d10adac712
commit e8e5b850a0
2 changed files with 13 additions and 9 deletions

View File

@ -61,13 +61,13 @@ export async function action(opts: { json?: boolean }) {
) )
const statuses = Object.fromEntries(statusEntries) const statuses = Object.fromEntries(statusEntries)
// Batch-clear stale in_review flags in a single write // Clear stale in_review flags via setSession to avoid clobbering concurrent writes
if (staleReviewBranches.length > 0) { for (const branch of staleReviewBranches) {
const freshState = await state.load(root) const fresh = await state.getSession(root, branch)
for (const branch of staleReviewBranches) { if (fresh) {
if (freshState.sessions[branch]) freshState.sessions[branch].in_review = false fresh.in_review = false
await state.setSession(root, fresh).catch(() => {})
} }
await state.save(root, freshState).catch(() => {})
} }
if (opts.json) { if (opts.json) {

View File

@ -69,7 +69,7 @@ Your thoughts, in brief.
if (extra) prompt += "\n\n" + extra if (extra) prompt += "\n\n" + extra
session.in_review = true session.in_review = true
await state.setSession(root, session).catch(() => {}) await state.setSession(root, session)
try { try {
if (opts.print) { if (opts.print) {
@ -82,8 +82,12 @@ Your thoughts, in brief.
} }
} finally { } finally {
spin.stop() spin.stop()
session.in_review = false // Load fresh session to avoid clobbering changes made during the review
await state.setSession(root, session).catch(() => {}) const fresh = await state.getSession(root, session.branch)
if (fresh) {
fresh.in_review = false
await state.setSession(root, fresh).catch(() => {})
}
if (!opts.print) await saveChanges(session.worktree, session.branch).catch(() => {}) if (!opts.print) await saveChanges(session.worktree, session.branch).catch(() => {})
} }
} }