Skip to content

fix(exchange): fail closed on unparseable PaymentDue in daily-cap check - #1229

Merged
cristim merged 1 commit into
mainfrom
fix/cor-04-fix
Jul 17, 2026
Merged

fix(exchange): fail closed on unparseable PaymentDue in daily-cap check#1229
cristim merged 1 commit into
mainfrom
fix/cor-04-fix

Conversation

@cristim

@cristim cristim commented Jun 11, 2026

Copy link
Copy Markdown
Member

Problem

COR-04 (docs/reviews/codebase-review-2026-06-10.md): in processAutoExchange (pkg/exchange/auto.go), a PaymentDue parse failure only logged a warning and coerced the value to $0 before adding it to the MaxPaymentDailyUSD daily-cap check. This is a silent fallback on a money path and is inconsistent with the dailySpent parse failure five lines above, which aborts the exchange and persists a failed record. Latent today (current callers always produce a parseable decimal), but any future path producing a non-decimal paymentDueStr would silently undercount the daily guardrail.

Fix

  • The PaymentDue parse failure now mirrors the dailySpent branch: log at error level, set outcome.Error, persist a failed record via saveFailedRecord, and return without executing the exchange.
  • The documented nil-means-zero-cost quote case stays explicit and separate: processRecommendation maps a nil quote.PaymentDueUSD to the literal "0" string before the parse, now with a comment distinguishing it from parse errors.

Test evidence

New regression test TestProcessAutoExchange_UnparseablePaymentDue_FailsClosed exercises processAutoExchange directly with "not-a-number" and "" (the public RunAutoExchange path always builds a parseable string, which is why the bug was latent). It asserts the outcome errors, Execute is never called (new mock call counter), and a failed record is persisted.

  • Pre-fix (fix stashed): both subtests FAIL - outcome.Error empty, exchange executed with $0 counted toward the cap.
  • Post-fix: go test ./exchange/ from pkg/ - 97 passed.
  • go build ./... succeeds in both the root module and the pkg/ module.

Closes #1166

@cristim cristim added triaged Item has been triaged priority/p3 Polish / idea / may never ship severity/medium Moderate harm urgency/eventually No deadline impact/few Limited audience effort/xs Trivial / one-liner type/bug Defect labels Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5516afc0-179a-478c-8ba7-aa4da77e2092

📥 Commits

Reviewing files that changed from the base of the PR and between 89658a3 and 0099c1a.

📒 Files selected for processing (2)
  • pkg/exchange/auto.go
  • pkg/exchange/auto_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cor-04-fix

Comment @coderabbitai help to get the list of available commands.

@cristim

cristim commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim

cristim commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

Rebased onto main (includes #1437 tflint cache + #1438 trivy skip). The previous Security Scanning CI failure was on the pre-rebase commit; gosec v2.27.1 now passes on all 6 modules (root, pkg, providers/{aws,azure,gcp}, tests/e2e) with 0 issues. Gate results: go build/vet exit 0 (root + pkg), gocyclo on pkg/exchange exit 0, go test ./exchange/... 103 passed, gosec all modules exit 0.

The auto-exchange daily-cap check warned and counted $0 toward the
MaxPaymentDailyUSD guardrail when paymentDueStr failed to parse, in
contrast to the dailySpent parse failure five lines above which aborts
with a failed record. A silent $0 coercion on a money path undercounts
the daily spend cap if any future caller produces a non-decimal value.

Make the parse failure abort the exchange and persist a failed record,
mirroring the dailySpent branch. The documented nil-means-zero-cost
quote case stays separate: processRecommendation still maps a nil
PaymentDueUSD to the explicit "0" string before the parse.

Regression test exercises processAutoExchange with unparseable and
empty PaymentDue values; confirmed failing pre-fix (exchange executed
with $0 counted) and passing post-fix (aborted, failed record saved,
Execute never called).

Closes #1166
@cristim
cristim merged commit a7318d1 into main Jul 17, 2026
18 checks passed
@cristim
cristim deleted the fix/cor-04-fix branch July 27, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/xs Trivial / one-liner impact/few Limited audience priority/p3 Polish / idea / may never ship severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/eventually No deadline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

COR-04: RI auto-exchange daily-cap check coerces unparseable/absent PaymentDue to $0 instead of failing loud

1 participant