Skip to content

fix(purchase): approve and scheduled-fire paths execute approved rows without claiming them as running #829

Closed

Description

@cristim

Problem

approvals.go:392 (approve CAS to approved) followed by approvals.go:421 (transitionApproveAndExecute -> executeAndFinalize) and scheduled_fire.go:100 run the provider call on an approved row WITHOUT first claiming it as running. claimAndExecute (manager.go:180) also claims approved rows. Two executors can therefore act on one row, and a stale save from the approve path can overwrite a pre-submission failure (or the reverse).

Impact

Found by the gate on PR #828 (ladder #118 PR-C1). The no_submission proof (the "nothing was sent" fact the ladder reconciler uses to release a tranche) cannot be trusted while this race exists: the guard added in #828 covers the ordering where the stale approved save lands after the pre-submission failure, not the other ordering. Possible double submission is also a general purchase-safety question.

Proposed fix

Make every executor claim approved -> running by CAS before any provider call (single claim primitive), and make stale saves CAS-guarded on the expected status.

Blocking

Blocks ladder #118 C2 trusting no_submission and the B2 executor.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions