Skip to content

fix(automations): re-check subscription entitlement before claiming a run - #69

Open
polylane[bot] wants to merge 1 commit into
mainfrom
polylane/autofix/9nh8di7xh307
Open

polylane[bot] wants to merge 1 commit into
mainfrom
polylane/autofix/9nh8di7xh307

Conversation

@polylane

@polylane polylane Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Fixes: cache-app: paid automations keep running after a subscription lapses (no entitlement check on the scheduled run path)

Automations are sold as a paid capability, but the subscription was only checked when a user created, edited, or resumed one. A subscriber who canceled or whose payment failed kept having scheduled runs executed, consuming the metered Gen AI budget and sending email indefinitely. The scheduled path now re-checks the subscription before claiming a run and pauses the automation when the subscription is no longer active.

flowchart TD
    A["External cron GET /api/cron/automations"] --> B["claimDueAutomationRuns"]
    B --> C["claimAutomationRun transaction"]
    C --> D{"Owner subscription active?"}
    D -- yes --> E["Claim run and start durable workflow"]
    D -- no --> F["Pause automation, cancel run, delete pending runs, WARN"]
    E --> G["executeReadOnlyAutomationRun: Gen AI spend and email"]
    H["Before: gate only in create, update, resume"] -.-> C
Loading

What caused this

Affected: int_0b563423d00164u048hh0syk

Why this fix

The entitlement gate requireCanUseAutomations is reachable only from createAutomation, updateAutomation, and resumeAutomation; nothing on the scheduled path (/api/cron/automations -> claimDueAutomationRuns -> automationRunWorkflow) consulted the subscription. claimDueAutomationRuns selected due runs on scheduledForUtc and status: pending alone, so a lapsed user's runs kept being claimed and executed. The change evaluates getUserActiveSubscriptionStatus(run.userId, tx) inside the existing claim transaction, so a run is claimed only when the owner's subscription is active or trialing, and a lapsed owner's automation is paused with its pending runs removed in the same transaction. Pausing ends the recurring obligation rather than skipping one occurrence; the user restores it through the resume action, which already checks entitlement. A read error on the subscription lookup aborts the transaction, so a paying user's automation is never wrongly paused and no run is claimed. past_due is treated as not entitled, matching the capability model already used at creation and resume; a grace period would be a separate product decision. The WARN line makes every pause visible, though the workspace has no log drain to collect it.

Out of scope
  • No Stripe lifecycle hook to pause at cancellation time: the claim-time check stops the obligation on the next tick and does not depend on webhook delivery.
  • No past_due grace period: it stays not-entitled, consistent with the existing capability model.
  • No log drain or metric added: the WARN line is emitted but this workspace collects no production logs.
2 files changed (+291/-1)
  • lib/intelligence/automations/service.test.ts: added, +224/-0
  • lib/intelligence/automations/service.ts: modified, +67/-1

View thread View autofix


Generated by Polylane. You can ask follow-ups by mentioning @polylane in a comment.

… run

Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com>
@polylane polylane Bot added polylane severity:medium Polylane autofix severity: medium labels Sep 21, 2026
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: f6790f44-b39f-45a0-b3f6-778c15bfe5bd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

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

@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cache-app Ready Ready Preview Sep 21, 2026 7:35am UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

polylane severity:medium Polylane autofix severity: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant