Repository navigation
fix(purchase): refuse a Redshift dispatch inside the adoption window - #1810
Conversation
Part of #702. Before buying, cloud-commitments-go adopts any owned node with the same offering and count that started at or after RequestedAt minus 5 minutes. So a new purchase dispatched shortly after another lineage's completed buy of the same tuple adopted that node and bought nothing: an under-buy, with one commitment counted twice. - The dispatch gate also counts another lineage's completed, partially completed or revocation-requested buy of the tuple as a conflict while its last save (updated_at, database clock) is within 10 minutes of this dispatch's stamp: go's 5-minute skew plus a 5-minute clock margin. The refusal happens before any purchase call, with a fixed text that names no other execution. - The conflict query now matches a candidate on the execution's account first, as dispatch does, so a differing rec account cannot hide a conflict. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #702. Mark the cross-lineage adoption entry as mitigated for buys the platform records, and list what remains open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 21 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
APPROVED 2f0063b by claude-ui-fix-2 Cold review of #702 PR2b (money path, no migration). The code is approved. CI is red on lint, so a fix commit is needed before merge (see the end), and the new head needs a delta review. Window bounds: no upper-bound gapThe new branch ( The proxy can't miss an adoption. A finished row's Clock source: the database on both sides
It can't let an adoption through, within its stated scope
Tenant and account scope
Refusal text"…start a new purchase at least 10 minutes after the other one completed". It's fixed and matches the 10-minute window, per the owner's Q7 A. Runtime (scratch worktree at this SHA, heavy-review-2,
|
|
CHANGES REQUESTED 2f0063b by claude-qa-ui-4 Blocking:
Non-blocking:
Checked and holding:
Runs (GOMAXPROCS=4, -p 2): build and vet pass; unit purchase/config pass; integration purchase/config pass. Probes: 9 of 10 killed (Go refusal dropped, SQL finished branch dropped, partially_completed or revocation_requested dropped from SQL, revocation_requested dropped from Go, COALESCE reverted, app time in Go or SQL, an upper bound added). The 4-minute window survived (finding 1). |
…rgin Part of #702. A review probe set the window to 4 minutes, below go's 5-minute Redshift dedupe skew, and every test still passed, because the tests derived their expectations from the constant. Assert the window with literals: go's 5-minute skew plus a 5-minute clock margin. Also drop the finished-row helper's unused return (unparam). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #702. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
APPROVED 404ad8e by claude-ui-fix-2 Delta from my approval at
CI at this SHA was still running when I posted (4 pass, 32 pending). The merge gate needs it green, including Lint Code. |
|
APPROVED 404ad8e by claude-qa-ui-4 Delta from my CHANGES REQUESTED at 2f0063b; test and docs only, no production code changed.
|
Part of #702 (Redshift re-drive idempotency). This is PR2b, between PR2 (#1807, merged) and PR3. It does not close the issue.
Why
Before buying, the Redshift client in cloud-commitments-go adopts any owned reserved node with the same offering and node count that started at or after
RequestedAtminus 5 minutes. It applies no upper bound and doesn't check who bought the node. The platform always sends a token, so this runs on first dispatches too. As a result, a new purchase of a tuple dispatched within about 5 minutes of another lineage's completed buy adopted that node instead of buying its own: an under-buy, with one commitment counted twice. PR2's gate only counted running or still-open lineages, so it didn't close this.What
completed,partially_completedorrevocation_requestedand itsupdated_atis within 10 minutes of this dispatch's first-dispatch stamp. That is go's 5-minute skew plus a 5-minute clock margin. Both timestamps come from the database clock.known_issues/39marks the entry as mitigated for buys the platform records, and lists what remains:Trade-off
A legitimate repeat buy of the same tuple is refused for 10 minutes instead of being silently adopted. Plan steps are spaced in days and ladders fire daily or weekly, so a single plan or ladder never hits this. Two different plans that buy the same tuple on the same tick can.
Until PR3 lifts the Redshift Retry guard, a refused plan row can't be retried, and its ramp step stays held until the account is detached. A refused ladder tranche is resolved as failed and re-bought at its next fire. The owner accepted this trade-off.
Tests
updated_atused overcompleted_at, and a completion after an old stamp.No migration.
🤖 Generated with Claude Code