fix(cli): fail closed when the duplicate-purchase check errors - #2099
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: LeanerCloud/cloud-commitments-cli/.coderabbit.yaml Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (6)
Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. 📝 WalkthroughWalkthroughA failed existing-commitments check now prevents purchases for the affected service and region. Dry runs continue with a warning. CSV processing follows the same mode-specific behavior, with tests and documentation updated. ChangesDuplicate-check failure handling
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant runToolFromCSV
participant checkDuplicatesForCSVRegion
participant checkDuplicates
runToolFromCSV->>checkDuplicatesForCSVRegion: check recommendations for region
checkDuplicatesForCSVRegion->>checkDuplicates: check existing commitments
checkDuplicates-->>checkDuplicatesForCSVRegion: return no recommendations on purchase-run failure
checkDuplicatesForCSVRegion-->>runToolFromCSV: skip region
Merge Risk: ⚪ Minimal · up to No confirmed merge-blocking issue remains. The CSV regression test’s ability to catch the purchase-path regression is still unverified. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Out of Scope Changes checkExplanation The duplicate-check implementation, tests, and related documentation are in scope for [ Full details: Docstring CoverageExplanation Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 4 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
A failed duplicate-RI check (throttling, a describe-call AccessDenied, a transient 5xx) was logged as a warning and the run proceeded with the pre-dedup counts, so an error on this check caused a purchase run to buy reserved capacity the account already owns. This was the only guard between a re-run and a double purchase, and it failed open. Three call sites shared the bug: checkDuplicates (the main non-CSV pipeline, used by both fetchAndFilterRegionRecs and the legacy processRegionRecommendations), and the --input-csv path in runToolFromCSV. All three now fail closed on a real purchase run: a failed check drops that (service, region)'s recommendations entirely rather than falling back to the un-deduplicated counts, mirroring the existing "refuse to spend rather than purchase uncapped" stance for --max-instances. A dry run keeps the previous behavior (a warning, continuing with the un-deduplicated counts) since nothing is bought and reporting fidelity wins. Extracted checkDuplicatesForCSVRegion out of runToolFromCSV to keep its cyclomatic complexity under the project's gocyclo gate after adding the new branch. Regression tests: - TestCheckDuplicates_ErrorOnPurchaseRun_DropsRecsRatherThanFallingBack and TestCheckDuplicates_ErrorOnDryRun_ContinuesUnadjusted exercise checkDuplicates directly. - TestRunToolFromCSV_DuplicateCheckFailureRefusesToPurchase runs runToolFromCSV with ActualPurchase=true and invalid AWS credentials (so GetExistingCommitments fails the same way a real AWS error would) and asserts no purchase report is produced. Verified this test fails on the pre-fix code (it proceeds into the purchase loop with the un-deduplicated count) by running it against a worktree of the parent commit with only the test file applied. Verification: go build ./cmd, go vet ./cmd/..., golangci-lint v2.10.1 (the exact CI pin) run --timeout=10m clean, gocyclo -over 10 clean, go mod tidy -diff empty, go test -race -short ./... all green (493s). Closes #1941 Co-Authored-By: claude-flow <ruv@ruv.net>
…ount Rebased onto origin/main, which merged #2098's README/docs rewrite after this branch's base: three passages in README.md and docs/cli/purchase-safety.md still described the pre-#1941 fail-open behavior ("the run continues un-deduplicated with a warning"). Rewrote them to say what #1941 actually does: a dry run continues with a warning (nothing is bought); a --purchase run refuses that (service, region) with a "Refusing to purchase" line and buys nothing there. Also fixes two review findings on this PR: - checkDuplicates's failed-check branch counted its drops under common.DropDuplicateDedup, which means "an actual duplicate was found and subtracted" -- reusing it for a check that never ran reported the failure as a successful dedup in the end-of-run summary. Added a cmd-local dropDuplicateCheckFailed reason instead (no library change; DropSummary.Add takes a plain string). - Replaced two U+2014 em-dashes introduced by this PR's own new comments/strings with plain punctuation. And, since #1942 (--target-coverage abort-on-fetch-failure) merged onto main after this branch's base, folds in its two outstanding review minors from the same docs area: - docs/cli/purchase-safety.md: documented the CE-coverage-fetch failure behavior near the --target-coverage discussion. - Replaced the remaining U+2014 em-dash in the coverageFetchFailure warning string. Verification: go build ./cmd, go vet ./cmd/..., golangci-lint v2.10.1 (exact CI pin) run --timeout=10m clean, gocyclo -over 10 clean, go mod tidy -diff empty, go test -race -short ./... all green. Co-Authored-By: claude-flow <ruv@ruv.net>
7910dc0 to
afcc2af
Compare
|
Independent adversarial review (two rounds) + local verification: MERGE at afcc2af. A failed existing-commitments check now fails closed on purchase runs on both paths (--services: checkDuplicates drops the region's recs and records duplicate-check-failed; --input-csv: the region is skipped before the purchase loop); dry runs warn and continue. Docs rewritten to match; #2100's behavior intact after rebase. Regression tests fail on the pre-fix parent and pass on head under -race; 7/7 checks. |
Summary
A failed duplicate-purchase check (throttling, a
DescribeReservedDBInstancesAccessDenied, a transient 5xx) was logged as a warning and the run proceeded
with the pre-dedup counts, so an error on this check caused a real-purchase
run to buy reserved capacity the account already owns. This was the only
guard between a re-run and a double purchase, and it failed open.
Root cause
Three call sites shared the fail-open shape:
checkDuplicates(cmd/multi_service_helpers.go), used by the mainnon-CSV pipeline (
fetchAndFilterRegionRecs) and the legacyprocessRegionRecommendations.--input-csvpath inrunToolFromCSV(cmd/multi_service.go), whichcalled
adjustRecsForDuplicatesand resetadjustedRecs = recson error.All three logged a warning on error and continued with the original,
un-deduplicated recommendation counts, regardless of whether the run was a
dry run or a real purchase.
Fix
All three now fail closed on a real purchase run (
!isDryRun): a failedduplicate check drops that (service, region)'s recommendations entirely
rather than falling back to the un-deduplicated counts, mirroring the
existing "refuse to spend rather than purchase uncapped" stance already
taken for
--max-instancesinprocessRegionRecommendations. A dry runkeeps the previous behavior (a loud warning, continuing with the
un-deduplicated counts) since nothing is bought and reporting fidelity wins.
checkDuplicatesForCSVRegionwas extracted out ofrunToolFromCSVto keepits cyclomatic complexity at 10 (the project's gocyclo gate) after adding the
new branch.
Regression test
TestCheckDuplicates_ErrorOnPurchaseRun_DropsRecsRatherThanFallingBackandTestCheckDuplicates_ErrorOnDryRun_ContinuesUnadjustedexercisecheckDuplicatesdirectly with a mockedGetExistingCommitmentserror.TestRunToolFromCSV_DuplicateCheckFailureRefusesToPurchaserunsrunToolFromCSVwithActualPurchase=trueand invalid AWS credentials (soGetExistingCommitmentsfails the same way a real AWS error would) andasserts no purchase report is produced (the region is skipped before
processPurchaseLoopruns).Proved the new CSV-level test fails on the pre-fix code: built a detached
worktree of
origin/main(parent commitde556ad1), applied only the newtest, and ran it. Pre-fix it proceeds into the purchase loop with the
un-deduplicated recommendation (1 rec, 2 instances) and writes a purchase
report row; post-fix the region is skipped and no report file is written.
Verification
go build ./cmd- cleango vet ./cmd/...- cleangolangci-lint v2.10.1(the exact CI pin, not the newer local default) run--timeout=10mfrom the repo root -0 issuesgocyclo -over 10 -ignore "_test.go" cmd/- cleango mod tidy -diff- emptygo test -race -short ./...- all green (493s)Closes #1941
Summary by CodeRabbit