You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(ri-exchange): direct execute bypasses the source-in-flight guard #1829
Found in the cold review of #1826 (the #1050 backend). The #1050 plan scoped this out; this issue tracks it.
Gap. The direct RI exchange execute path (internal/api/handler_ri_exchange.go:2013-2091) never calls the source-in-flight guard (refuseRIExchangeSourceInFlight, internal/config/store_postgres.go:3440-3461) that #1826 adds to the approve and AUTO reservations. A lost accept from a direct execute is recorded only in the direct-execution audit table, not as a processing ri_exchange_history row. So the guard doesn't work in either direction:
Direct after unknown: a direct execute can exchange a source RI that an approve or AUTO exchange holds in an unknown (processing) state.
Unknown after direct: a direct execute whose outcome is unknown never blocks a later approve or AUTO exchange of the same RI.
Repro. Leave an ri_exchange_history row processing on ri-1, then POST the direct execute endpoint with ri_ids: ["ri-1"]. The request goes to AWS with no refusal.
Suggested direction.
Run the direct path through the same guard, under the same advisory lock as the ceiling.
Make its unknown outcomes visible to the guard: either insert a processing history row, or have the guard also consult the direct-execution audit table.
Add tests for both directions.
Related low items from the same review. Rows whose source_ri_ids is NULL or empty skip the guard (store_postgres.go:3441), which only matters for legacy rows without source IDs. Two approvals of rows sharing an RI that both transition before either reserves can refuse each other: both fail, which is safe, and a retry works.
Claimed by claude-darling: planning. Test-first: direct execute must refuse while a source RI is in flight, and the reverse direction too. Stacked on #1826's guard; local commits until #1826 merges and a platform slot frees.
Activity
cristim commentedon Nov 6, 2026
Claimed by claude-darling: planning. Test-first: direct execute must refuse while a source RI is in flight, and the reverse direction too. Stacked on #1826's guard; local commits until #1826 merges and a platform slot frees.
cristim commentedon Nov 7, 2026
Claimed by claude-darling: PR #1838 is open (6 commits; plan, per-task and full-change reviews done). Follow-up for the resolve API: #1836.
style(config): spell serializes the US way in the spend-lock comment
docs(ri-exchange): quote the runbook psql placeholders
fix(ri-exchange): guard direct execute against an RI held by an in-fl…