Fix #64: pr.json CAS retry field-merge #67

Merged
crueber merged 1 commit from fix/issue-64 into main 2026-09-04 23:08:51 +00:00
Owner

Fixes #64 (follow-up from #59 audit): savePR CAS-retry wholesale *cur = *p could clobber a landed merge outcome, and refreshHead / merge-commit saved stale structs under fresh versions with no 412 at all.

Each pr.json writer now re-applies only its owned delta onto the fresh doc (UpdatePR: body; refreshHead: head sha/stamp; merge: outcome fields); the savePR retry field-merges with a monotonic write-once guard on merged/*. New prcas_test.go interleavings fail pre-fix, pass post-fix. Docs: features/03 §2.3 + Decisions entry.

Tests: go test ./internal/pulls/ -race green; new race tests -count=20 green; cover 97.7% (>=95%). No new imports; merge success path unchanged.

Fixes #64 (follow-up from #59 audit): savePR CAS-retry wholesale *cur = *p could clobber a landed merge outcome, and refreshHead / merge-commit saved stale structs under fresh versions with no 412 at all. Each pr.json writer now re-applies only its owned delta onto the fresh doc (UpdatePR: body; refreshHead: head sha/stamp; merge: outcome fields); the savePR retry field-merges with a monotonic write-once guard on merged/*. New prcas_test.go interleavings fail pre-fix, pass post-fix. Docs: features/03 §2.3 + Decisions entry. Tests: go test ./internal/pulls/ -race green; new race tests -count=20 green; cover 97.7% (>=95%). No new imports; merge success path unchanged.
savePR's 412 retry did wholesale *cur = *p from the writer's stale struct,
so an UpdatePR body write racing a landing merge overwrote merged/* back
to unmerged (unrecoverable). Worse, refreshHead and the merge commit step
saved a stale struct under a fresh version with no 412 at all.

Each writer now re-applies only its owned delta onto the fresh doc
(UpdatePR: body; refreshHead: head sha/force-push stamp; merge: outcome
fields), and the savePR retry field-merges with a monotonic guard: landed
merged:true is never unset, and a merge-completion retry keeps the fresh
editorial/head fields. Regression tests fail pre-fix, pass post-fix.

Docs: features/03 §2.3 + Decisions entry (law 12).
Sign in to join this conversation.
No description provided.