Skip to main content

lean_ctx/core/billing/
mod.rs

1//! Commercial-plane billing substrate (`billing-plane-v1`, EPIC 13.6).
2//!
3//! Turns the existing plan-upgrade flow into **real plans + entitlements** plus
4//! **usage-based metering** derived from the signed savings ledger (EPIC 12.20)
5//! — without touching the local experience.
6//!
7//! ## Two halves, one invariant
8//!
9//! * [`plans`](crate::core::billing::plans) — the plan catalog and their
10//!   [`Entitlements`](crate::core::billing::Entitlements). Commercial, additive.
11//!   [`entitlement_allows`](crate::core::billing::entitlement_allows) expresses
12//!   the **Local-Free Invariant**: every local-always-on capability is allowed
13//!   on every plan, including [`Plan::Free`](crate::core::billing::Plan::Free).
14//!   No local feature is ever gated.
15//! * [`metering`](crate::core::billing::metering) —
16//!   [`Usage`](crate::core::billing::Usage) derived read-only from the
17//!   privacy-preserving, Ed25519-signed ledger aggregate. Its frozen v1
18//!   `is_billable` predicate means source integrity only; it is not settlement
19//!   authority.
20//! * [`settlement_evidence`](crate::core::billing::settlement_evidence) — bounded,
21//!   payload-free v2 evidence reconciliation.
22//!   It never calculates prices, approves customers, decides disputes, or
23//!   issues invoices.
24//!
25//! Crucially, this module computes and *describes* commercial state; it never
26//! enforces anything against the local plane. Enforcement (checkout, plan
27//! gating) lives on the hosted control plane, which is the only place an
28//! account/plan is consulted. The local engine has **no entitlement checks** —
29//! asserted by `tests/local_free_invariant.rs`.
30
31pub mod metering;
32pub mod plans;
33pub mod settlement_evidence;
34
35pub use metering::{Usage, metered_usage};
36pub use plans::{Entitlements, Plan, entitlement_allows, min_plan_for};
37pub use settlement_evidence::{
38    SettlementEligibilityV2, SettlementEvidenceManifestV2, reconcile_settlement_evidence_v2,
39};
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use crate::core::server_capabilities::{LOCAL_ALWAYS_ON_FEATURES, LOCAL_OPTIONAL_FEATURES};
45
46    #[test]
47    fn no_local_feature_is_gated_by_any_plan() {
48        // The whole point: local capabilities (always-on *and* compile-optional)
49        // are never restricted by a commercial plan.
50        for plan in Plan::all() {
51            for feature in LOCAL_ALWAYS_ON_FEATURES
52                .iter()
53                .chain(LOCAL_OPTIONAL_FEATURES.iter())
54            {
55                assert!(
56                    entitlement_allows(*plan, feature),
57                    "local feature '{feature}' gated on plan {plan:?}"
58                );
59            }
60        }
61    }
62
63    #[test]
64    fn commercial_entitlements_exist_only_above_free() {
65        // Self-hosting (team_server/cloud_server) stays free; the real commercial
66        // gates are the hosted/governance entitlement keys. Free grants none of
67        // them; higher plans add them. This keeps the plan ladder honest.
68        assert!(!entitlement_allows(Plan::Free, "sso_scim"));
69        assert!(entitlement_allows(Plan::Enterprise, "sso_scim"));
70        assert!(entitlement_allows(Plan::Team, "private_registry"));
71        assert!(!entitlement_allows(Plan::Free, "private_registry"));
72    }
73}