Repository navigation
fix(billing): hold free plans to their allowance mid-run - #9462
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
[Medium impact] The PR appears safe to merge; no new actionable issues were found. SummaryFree runs now read their latest spend after cost callbacks and stop when their allowance is spent or cannot be checked. Paid runs keep their existing behavior.
|
There was a problem hiding this comment.
All reported issues were addressed across 12 files
This PR changes payment, billing, or quota logic. Ultrareviews find 2.4x more serious bugs than standard reviews. Comment @cubic-dev-ai ultrareview to run one.
Turn on auto-fix | Re-trigger cubic
…free by the admitted plan
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 13 files
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
checkAttributedUsageLimits, the function the cache wraps; the direct-v1 path skips its verdict cache and shared in-flight read), so the callback that crosses the limit pauses the rununknownor the 1 s budget), the provider mid-run check, the copilot continuation re-check, and Mothership continuation admission all stop/refuse a free run with the usage card. Paid plans and orgs keep today's fail-open behaviour so a database blip never ends a paying runisFreeRunPayerdecides free from what the run was admitted with (attributedpayerSubscription; a direct-v1 decision withoutpayerSubscriptionId), so no new query; errors land on the paid (status-quo) sideType of Change
Testing
app/api/billing/update-cost/route.integration.ts(real Postgres): free direct-v1 and free attributed payers are paused when a second callback crosses the limit inside the cache window; a pro payer in the same scenario keeps the cached answer. Red with the fresh-read bypass disabled, green restoredupdate-cost/route.test.ts(fresh read, unreadable ledger, failed gate read, timeout → exceeded for free; blocked → not exceeded; paid unchanged),providers/run-usage-limit.test.ts,copilot/api-keys/validate/route.test.ts,mothership/request/lifecycle/admission.test.ts— each new free-payer guard shown red with the guard revertedlib/billing+ touched route/provider/lifecycle suites green; biome,check:test-patterns,check:comment-hygiene,check:unused-exports,check:file-names,check:boundariesChecklist
test-auditauthoring gate)