7.1 KiB
Contract: Billing Plane v1 (billing-plane-v1)
Status: frozen baseline · Plane: commercial (Team/Cloud) · Source: rust/src/core/billing/
Note (2026-07-07): This document is the frozen v1 baseline. The current plan catalog has evolved: Pro now includes 1000 MB hosted index (not 0), and the Business plan ($149/mo flat, OIDC SSO) was added in
billing-plane-v3. For the authoritative tier ladder and entitlements, seebilling-plane-v1-catalog.json(golden fixture, test-pinned) anddocs/business/product-architecture.md. The six-plan ladder is:free ⊂ supporter ⊂ pro ⊂ team ⊂ business ⊂ enterprise.
The commercial-plane billing substrate (EPIC 13.6). It turns the existing plan-upgrade flow into real plans + entitlements and usage-based metering derived from the signed savings ledger — without ever touching the local experience.
Local-Free Invariant (RFC §4/§6): the Personal (local) plane is free, ungated, best-in-class — forever. Billing only describes/meters; it never gates local.
Plans & entitlements
Five plans, strictly additive: free ⊂ supporter ⊂ pro ⊂ team ⊂ enterprise.
| Entitlement | free | supporter | pro | team | enterprise |
|---|---|---|---|---|---|
| seats | 1 | 1 | 1 | 25 | unlimited |
| hosted_index_mb | 0 (none) | 0 (none) | 0 (none) | 5000 | unlimited |
| managed_connectors | 0 (none) | 0 (none) | 0 (none) | 5 | unlimited |
| private_registry | no | no | no | yes | yes |
| sso_scim | no | no | no | no | yes |
| audit_retention_days | 0 | 0 | 0 | 90 | 3650 |
| revenue_share | no | no | no | yes | yes |
| supporter | no | yes | yes | yes | yes |
| cloud_sync | no | no | yes | yes | yes |
supporter is the voluntary Supporter subscription (sponsor is an accepted
alias for its top tier): an individual funds development and gets account-level
recognition (a supporter badge) and convenience perks. It is commercially
identical to free for every Team/Cloud capability — it can never gate a local
feature and grants none of the coordination entitlements; it only sets the
account-level supporter flag (also true for pro/team/enterprise, since
every paid plan is at minimum a supporter). Self-serve checkout for it never
triggers team-server provisioning (only team does).
pro is the paid "Personal Cloud" subscription — its own plan (pro
parses to Plan::Pro; it is no longer an alias of supporter). It adds exactly
one capability over supporter — cloud_sync — and nothing else: the same single
seat, none of the Team/Cloud coordination entitlements, so the ladder stays
additive (supporter ⊂ pro ⊂ team). cloud_sync is the hosted Personal
Cloud: cross-device sync + backup of the user's own context (knowledge, learned
shell patterns, CEP scores, gotchas, savings history) via the /api/sync/*
endpoints. It is a hosted service, not a local capability — the local engine
is fully usable without it. Like team, pro is account-bound self-serve
checkout; unlike team it provisions no team server.
A quota of 0 means none; the UNBOUNDED sentinel (u32::MAX) means
unlimited / negotiated. The two are never conflated (so Free's "no hosted
index" is never shown as "unlimited"). Every entitlement describes a Team/Cloud
capability; none can restrict a local feature.
entitlement_allows(plan, feature)
- Any feature in
LOCAL_ALWAYS_ON_FEATURES(or the local compile-optional set) returnstrueon every plan — the local plane is never gated. - Commercial keys (
private_registry,sso_scim,revenue_share,supporter,cloud_sync,managed_connectors,hosted_index,audit_retention) resolve from the plan's entitlements. - Unknown features default to allowed (fail-open for the user — never fail-closed against the local experience).
- Self-hosting
team_server/cloud_serverstays free: those are compile-time capabilities, not entitlement keys. The commercial plane is the hosted version.
Metering
Usage is derived read-only from RoiReport (EPIC 12.20), which is itself
derived from the Ed25519-SignedSavingsBatchV1. It carries only counts, sums,
and provenance hashes — never paths, prompts, or content.
{
"schema_version": 1,
"period": "all",
"created_at": "…",
"agent_id": "…",
"metered_events": 1234,
"net_saved_tokens": 9876543,
"saved_usd": 19.75,
"last_entry_hash": "…",
"chain_valid": true,
"signed": true
}
is_billable()=signed && chain_valid. Unsigned or broken chains are observable locally but are not billable (fail-closed for billing only, never for the user).- Producing a usage record never mutates the ledger or the local experience.
CLI surface (informational, never gating)
lean-ctx billing plans [--json] # plan catalog + entitlements
lean-ctx billing entitlements <plan> [--json] # one plan's entitlements
lean-ctx billing usage [--json] # metered usage from the local ledger
All three are read-only reporting. There are no entitlement checks in the local binary; enforcement (checkout, plan gating) lives only on the hosted control plane, the single place an account/plan is consulted.
Production wiring (out of scope for the local engine)
Self-serve checkout and plan provisioning are a hosted control-plane
concern, built on the existing cloud_server backend (rust/src/cloud_server/)
and lean-ctx upgrade flow (rust/src/cli/cloud.rs):
- A payment processor (e.g. Stripe) handles checkout + subscription lifecycle;
its webhooks update the account's plan in the cloud Postgres
(
cloud_server/db.rs,models.rs). - The hosted
/v1endpoint maps an authenticated account →Plan, then usesentitlement_allowsto gate hosted capabilities only. - Usage is reported by clients submitting signed savings batches
(
lean-ctx savings push); the control plane aggregatesUsagefor usage-based billing.
The local engine never participates in (1)–(3); it only describes plans and reports its own usage.
Invariants (test-enforced)
entitlement_allowsreturnstruefor every local feature on every plan (core::billingunit tests +tests/local_free_invariant.rs).- Free grants no commercial entitlements; higher plans only add.
Usageis privacy-preserving (no path/prompt/content fields).- Only signed + intact chains are billable.
Versioning
Adding a plan or entitlement field is additive (stays v1). Removing/renaming a
field, or changing the local-free semantics of entitlement_allows, bumps to
billing-plane-v2. The pro plan and the cloud_sync entitlement were added
under this rule — purely additive, so still v1. (cloud_sync gates only a
hosted sync service, never a local feature, so the local-free semantics are
unchanged.)
The metered hosted-index storage-overage add-on is documented separately in
billing-plane-v2: a new metered surface layered on top
of these plans, additive and Local-Free-preserving.