name: ee-billing
description: >
Surface workflow for billing in Grida — Stripe (subscriptions) +
Metronome (AI credit ledger). The stable contracts: grida_billing.*
is not REST-exposed (views/RPCs only), fn_billing_apply_* are the
single mutation points, webhook receivers are GRIDA-SEC-001, BYOK
is the GRIDA-SEC-003 carve-out. Use when touching
editor/lib/billing/, editor/scripts/billing/, the
grida_billing schema, the webhook receivers, or the entitlement
gate. Companion to ee.
ee-billing
This is the surface skill for billing — the workflow once the
ee anchor has placed billing on the EE side and
the contributor setup is done. Setup itself is documented; cite it,
don't restate it:
- docs/contributing/billing — local Stripe + Metronome sandbox, cloudflared tunnel, env vars, troubleshooting.
- docs/wg/platform/billing/ — design notes: AI credits master plan, Metronome integration, known issues.
- docs/platform/billing — user-facing copy.
Stable surface (the contract)
These shapes are locked. A change that breaks any of them must be intentional and called out in the PR description.
grida_billing.*schema — not REST-exposed. Public reads go throughv_billing_*views; writes only throughfn_billing_*RPCs. Don't add a new direct-access surface; add a view or an RPC. Schema discipline lives indatabase/supabase/AGENTS.md.public.fn_billing_apply_stripe_event— the only place Stripe-driven subscription state mutates. Mutating from a new direction (UI form, ad-hoc RPC, hand-written migration) corrupts the projector model.public.fn_billing_apply_metronome_event— same role for Metronome credit / alert /payment_gateevents.- Webhook receivers —
/webhooks/stripeand/webhooks/metronomeare the only billing ingress; both are signature-verified perGRIDA-SEC-001. editor/lib/billing/metronome.ts— the service module surface:provisionOrg,addStripeChargedCommit,setAutoReload,getEntitlement,ingestUsageEvent. New billing actions go through this module, not adjacent to it.
Substrates
Two external clouds; both use per-contributor sandbox accounts. Credentials are never shared. Live keys are refused at boot.
- Stripe — subscriptions + payment processing. Provision via
pnpm tsx editor/scripts/billing/cli.ts setup:stripe. Idempotent; re-run after everysupabase db reset(writes price IDs into the catalog). - Metronome — AI credit ledger. Provision via
pnpm tsx editor/scripts/billing/cli.ts setup:metronome. Same idempotency / re-run rule.
editor/scripts/billing/cli.ts is the single entry point for every
billing script; run without arguments for the full subcommand list.
See editor/scripts/billing/README.md.
The seam: how OSS reads entitlement
OSS code that needs to gate on a paid plan, AI credit balance, or
org entitlement does not import billing internals. The seam is
getEntitlement (from editor/lib/billing/metronome.ts) and its
typed wrappers. New gates go through this function so fail-closed
and BYOK behavior stay centralized.
BYOK carve-out — GRIDA-SEC-003
If BYOK_OPENROUTER_API_KEY or BYOK_AI_GATEWAY_API_KEY is set in
editor/.env.local, the AI-SDK text path routes through the
contributor's provider and bypasses billing.
- Auth is never bypassed. A resolvable org is still required.
- Text/chat only. Image and audio still go through Replicate and still bill, even under BYOK.
- Never set
BYOK_*on a hosted or preview deploy. It disables billing and the org-id sanity gate for every org. SeeSECURITY.md(GRIDA-SEC-003).
Working on billing
- Read docs/contributing/billing for setup before the first change. Don't skip cloudflared if you need Metronome — webhook delivery requires public HTTPS.
- Tag every billing file with
GRIDA-EE: billingper theeeskill. - Webhook receivers also carry
GRIDA-SEC-001— thesecurityreview runs first. - Don't mutate
grida_billing.*outsidefn_billing_apply_*or the migration that creates it. - Run the E2E suite before opening the PR (refuses to start unless
every channel is demonstrably test-mode):
pnpm --filter editor vitest run lib/billing/__tests__/e2e. - For schema changes, the
databaseskill governs —grida_billingis a regulargrida_*schema under that discipline.
Known issues
docs/wg/platform/billing/known-issues
is the living register (KI-BILL-NNN). Add to it when you mitigate
or accept an issue; don't quietly bake the mitigation into a PR
without registering it.
See also: ee (the EE anchor),
security (GRIDA-SEC-001,
GRIDA-SEC-003), database (schema
discipline for grida_billing).