- The composer read the setup session with a bare readCloudSetupSession() call in render. The React
Compiler memoizes that on the session id, so the panel kept its first (empty) read: rows never
moved past 'In browser', the finished session never auto-started the workspace, and the GitHub
row stayed 'Needed' after the browser said 'You're all set'. Read it through
useCloudSetupSession (useSyncExternalStore with a per-poll cached snapshot) instead.
- Billing asked the control plane for the GitHub install URL with a plain fetch to its workers.dev
origin. Same-account Workers can't do that (Cloudflare error 1042), so every setup GitHub step
showed 'Orca Cloud setup is unavailable'. Bind the control plane as a service (SANDBOX_CONTROL)
in the dev config and send the request through it when bound.
Found by the NP-4 end-to-end run (np4-e2e) on m4air against staging.
Setup session API on the billing Worker: the desktop creates a session after
sign-in and polls its steps (account, team, plan/trial, github); the setup pages
on Orca Cloud auth redeem a one-time browser ticket, bind the team (granting the
trial through a port np4-trial's module plugs into), open Checkout that returns
to the setup pages, and ask the control plane for the GitHub install URL. The
control plane flips the GitHub step via POST /v1/internal/cloud-setup/github.
Checkout now refuses personal accounts with 409 team_required: a user: plan
could never move to a team later.
- Overage stays $1.00 per sandbox hour (ORCA_CLOUD_OVERAGE_CENTS_PER_HOUR) and is now billed by
the minute: a per-minute metered TEST price (unit_amount_decimal = rate / 60 to 12 decimals,
transform_quantity divide_by 60, round up), created the same way by stripe-test-setup.ts.
capSeconds rounds the cap down to whole minutes and spentCents mirrors the invoice, so the
cap math matches Stripe. The meter still counts seconds.
- Opting in re-prices an overage item still on an older price (e.g. $0.75 / h) instead of adding
a second item on the same meter, and removes any extra stale one.
- Alerts at 75%, 90% and 100% of included hours (warnAtPercent).
- New top-level entitlement.suspendRunning: payment grace expired, or at the limit (out of hours
with overage off, or at the spend cap). The start check and usage answers carry it, so the
control plane puts running sandboxes to sleep (snapshot kept, never deleted). Payment fields and
/v1/internal/suspensions stay payment-only, so no data-retention clock starts at a cap.
- Copy (desktop billing panel, plan card, build sheet, phone, CLI): "billed by the minute" after
the rate; at the limit "Running sandboxes go to sleep and new ones can't start. Nothing is
deleted, and your files are safe."
* feat(billing): Team-only pricing, opt-in overage with spend cap, live Stripe test-mode e2e
- Catalog: Team $50/seat/mo or $480/seat/yr, 60 Standard h/seat/month pooled
(monthly windows on annual plans), Large 2x, 3 running/seat, 15-min idle sleep;
Enterprise is contact-only. All numbers/labels in BILLING_PLANS defaults.
- Overage is opt-in (adds the metered item), $0.75/h, monthly spend cap (default
$25, admin-raisable) enforced in the meter outbox; 80%/100% usage warnings.
- Checkout: plan/interval/seats with adjustable quantity; portal configuration var.
- Workers reject fetch redirect 'error': use 'manual'. Log route errors.
- scripts/stripe-test-setup.ts creates the test catalog + portal configuration;
scripts/e2e-test-mode.ts drives Checkout (headless, test card), overage, meter,
cap, annual, test-clock renewal, payment failure and cancel.
- Desktop: Team/Enterprise cards with interval + seats, usage warnings, overage
toggle + cap; split into copy/offers/usage modules.
* feat(billing): dev deployment config, dev operator keys, return page
- wrangler.dev.jsonc for orca-billing-dev (workers.dev, dev D1, test-mode prices).
- BILLING_DEV_JWKS (issuer orca-billing-dev-test) accepted only when BILLING_ENV
is not prod, for e2e runs until auth mints billing tokens.
- GET /return: static 'return to Orca' page for Checkout/Portal redirects.
- Design doc: final pricing, dev URL and resources for the control plane.