Skip to content

fix(purchase): gate scheduler/SQS on typed web source constant (follow-up to #1456) - #1458

Merged
cristim merged 1 commit into
mainfrom
fix/1456-followup-web-source-gate
Jul 19, 2026
Merged

fix(purchase): gate scheduler/SQS on typed web source constant (follow-up to #1456)#1458
cristim merged 1 commit into
mainfrom
fix/1456-followup-web-source-gate

Conversation

@cristim

@cristim cristim commented Jul 19, 2026

Copy link
Copy Markdown
Member

Follow-up to #1456 — unaddressed CodeRabbit CRITICAL

Part of the adversarial-sweep over PRs merged in the last 2 weeks. #1456 merged
with an unresolved CodeRabbit CRITICAL review thread; this implements the fix
and hardens the regression tests that could never have caught it.

Bug (money-path fail-open)

executableByScheduler gated on the bare literal exec.Source == "web", but
web-originated executions are persisted with Source = common.PurchaseSourceWeb
("cudly-web", set in handler_purchases.go). The literal never matched, so a
pending/notified web row on a plan with AutoPurchase=true could be
auto-executed by both the cron sweep (ProcessScheduledPurchases) and the
SQS execute_purchase path without the required token-link human approval.

Confirmed to reproduce on current main.

Fix

  • manager.go: compare against the typed common.PurchaseSourceWeb constant
    instead of a stringly-typed literal (repo enum convention).
  • manager_test.go / messages_test.go: the prior regression tests set
    Source: "web" (matching the buggy gate) and relied on
    AssertNotCalled("GetPurchasePlan"). The mock's default GetPurchasePlan
    stub does not record the call, so those tests could never detect the
    bypass. They now use the real persisted value and assert the invariant via a
    GetPurchasePlanFn sentinel: web rows must short-circuit before the
    AutoPurchase plan fetch. Verified the tests fail on the buggy literal and
    pass on the fix.

Verification

  • go build ./..., go vet, go test ./internal/purchase/... all green.
  • Adversarial check: injected the buggy "web" value → both regression tests fail.

…w-up to #1456)

executableByScheduler gated on the bare literal exec.Source == "web", but
web-originated executions are persisted with Source = common.PurchaseSourceWeb
("cudly-web"). The literal never matched, so a pending/notified web row on a
plan with AutoPurchase=true could be auto-executed by the cron sweep and the
SQS execute_purchase path WITHOUT the required token-link human approval -- a
fail-open on a money path (CodeRabbit CRITICAL thread on #1456, left unaddressed).

Fix:
- manager.go: compare against the typed common.PurchaseSourceWeb constant, not
  a stringly-typed literal (repo enum convention).
- manager_test.go / messages_test.go: the prior regression tests set
  Source: "web" (matching the buggy gate) and relied on
  AssertNotCalled("GetPurchasePlan"); the mock's default GetPurchasePlan stub
  does not record the call, so those tests could never detect the bypass. Use
  the real persisted value and assert the invariant via a GetPurchasePlanFn
  sentinel: web rows must short-circuit before the AutoPurchase plan fetch.
  Verified the tests FAIL on the buggy literal and PASS on the fix.
@cristim cristim added triaged Item has been triaged priority/p1 Next up; this sprint severity/critical Major harm when it happens urgency/now Drop other things impact/all-users Affects every user effort/xs Trivial / one-liner type/bug Defect type/security Security finding labels Jul 19, 2026
@coderabbitai

coderabbitai Bot commented Jul 19, 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: 2 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: a2866a82-5fcd-4e9e-b377-6023a9d72ded

📥 Commits

Reviewing files that changed from the base of the PR and between 5c267c5 and 18de8ea.

📒 Files selected for processing (3)
  • internal/purchase/manager.go
  • internal/purchase/manager_test.go
  • internal/purchase/messages_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1456-followup-web-source-gate

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

@cristim

cristim commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 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 merged commit a3dd1b1 into main Jul 19, 2026
19 checks passed
@cristim
cristim deleted the fix/1456-followup-web-source-gate branch July 27, 2026 11:09
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/all-users Affects every user priority/p1 Next up; this sprint severity/critical Major harm when it happens triaged Item has been triaged type/bug Defect type/security Security finding urgency/now Drop other things

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant