fix(commitments): serialize load-modify-save with in-process queue + cross-process file lock#86326
Conversation
|
Codex review: passed. Reviewed May 25, 2026, 1:14 AM ET / 05:14 UTC. Summary PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, and the linked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Review metrics: 3 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land this focused writer queue/file-lock fix after exact-head gates pass, then close #81145 as implemented. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main shows the unqueued load-modify-save mutation path, and the linked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Is this the best way to solve the issue? Yes. The PR applies the existing in-process queue plus AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 908b894432c4. Label changesLabel justifications:
Evidence reviewedPR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg ✨ Hatched: 🥚 common Clockwork Branchling Hatch commandComment Hatchability rules:
Rarity: 🥚 common. What is this egg doing here?
|
|
🦞✅ Source: What merged:
Automerge notes:
The automerge loop is complete. Automerge progress:
|
…cross-process file lock markCommitmentsAttempted, markCommitmentsStatus, upsertInferredCommitments, and the auto-expire pass in loadCommitmentStoreWithExpiredMarked each did an independent load-modify-save against ~/.openclaw/commitments/commitments.json with no lock. Two callers that overlapped in one event-loop tick — or in two different processes (gateway daemon heartbeat + standalone `openclaw commitments dismiss` CLI) — silently lost whichever save committed first. Verified 20/20 in a Promise.all repro on v2026.5.10-beta.1 (qa-reports/13-commitments-race-no-lock/programmatic-repro.log). User-visible symptoms: openclaw commitments dismiss silently reverts; a sent commitment can lose its sent stamp and get re-delivered; attempts counters can roll back past maxPerDay. Add src/commitments/store-writer.ts wrapping every mutator in runExclusiveCommitmentsStoreWrite, which layers a per-store-path in-process FIFO queue on top of withFileLock (advisory lockfile). The queue serializes same-process writers (CLI + heartbeat Promise.all + the now-queued loadCommitmentStoreWithExpiredMarked); the file lock serializes cross-process writers (gateway daemon vs. CLI), mirroring the same pattern used by src/plugin-sdk/persistent-dedupe.ts. Split the expire pass into an unchecked helper so upsertInferredCommitments can reuse it without re-entering the queue. Three regression tests in store.test.ts assert concurrent dismisses on disjoint ids, repeated attempted bumps, and a dismiss racing an attempted bump all converge — each fails on current main.
…cross-process file lock
2d84450 to
a349f41
Compare
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: #86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com> (cherry picked from commit d3c293d)
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
…cross-process file lock (openclaw#86326) Summary: - The PR adds a commitments-store writer helper, wraps load-modify-save mutators and expiry cleanup with a per-path queue plus `withFileLock`, adds three concurrency regressions, and updates the changelog. - PR surface: Source +153, Tests +61, Docs +1. Total +215 across 4 files. - Reproducibility: yes. Source inspection on current main shows the unqueued load-modify-save mutation path, a ... inked proof log shows the Promise.all repro changing from 20/20 lost writes before the patch to 0/20 after. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(commitments): serialize load-modify-save with in-process queue + … Validation: - ClawSweeper review passed for head a349f41. - Required merge gates passed before the squash merge. Prepared head SHA: a349f41 Review: openclaw#86326 (comment) Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
Makes #81153 merge-ready for the ClawSweeper automerge loop.
The edit pass should inspect the live PR diff, review comments, and failing checks; rebase if needed; keep the contributor branch credited; and stop only when validation is green or an external blocker is proven.
ClawSweeper 🐠 replacement reef notes:
Inherited issue-closing references from the source PR:
Closes #81145
Co-author credit kept:
fish notes: model gpt-5.5, reasoning high; reviewed against 2d84450.