Skip to main content

Crate monetize_embed

Crate monetize_embed 

Source
Expand description

monetize-embed — what a product compiles in. One struct, one question: does this tenant get to do this, right now? Answered from verified facts held in memory, in nanoseconds, with monetize down or not.

  monetize-server ──signed Snapshot file──▶ EntitlementCache::refresh   (start, catch-up)
  monetize-server ──signed EntitlementFact─▶ EntitlementCache::push      (every change)
  product choke point ──────────────────▶ EntitlementCache::allows     (every request)

§The ladder table, as the product sees it

stateWrite (push, LFS upload)Read (owner clone/fetch)AnonymousReadAdmin (UI)
Free, Paidallowallowallow (product still applies Public)allow
Graceallow, EntitlementCache::notice has the warning lineallowallowallow
Suspendedrefuse, named reason + URLallowrefuserefuse: pay page only
Retentionrefuseallow (export)refuserefuse: pay page + export

Two rules, not negotiable: never hold data hostageRead is allowed in every state, a lapsed tenant can always clone their own repositories; and refuse before the bytes — the product asks at authorise_service, before a pack is read, and puts Verdict::Refuse::reason_line in report-status.

§What is, and is not, decided here

  • The state in a fact is monetize’s verdict at push time. The cache does not re-derive it as the clock moves — it does not know the policy’s day counts, and the product contract says a product keeps serving on its cached entitlement when monetize is unreachable. Ladder transitions arrive as new pushes.
  • An unknown tenant is Free: the product’s default, never a refusal.
  • Visibility (Public) and quotas (caps) are the product’s own checks; this crate only says whether the entitlement allows the kind of action.

§Cost of the read path

EntitlementCache::allows is one ArcSwap::load (an atomic increment on a debt-slot, ~2 ns, no lock, no allocation), one BTreeMap lookup on the tenant name, and a match. A refusal allocates its two strings; an allow allocates nothing. Writes (push, refresh) clone the map and swap the pointer — O(tenants), taken by the rare path on purpose so the hot path never contends.

Re-exports§

pub use signing::SignatureError;
pub use signing::Snapshot;
pub use ticket::verify_ticket;
pub use ticket::ActorTicket;
pub use ticket::SeenNonces;
pub use ticket::PURPOSE_ORDER;
pub use ticket::PURPOSE_READ;
pub use ticket::PURPOSE_RENEW;

Modules§

civil
Proleptic Gregorian civil dates from unix milliseconds, pure integer arithmetic (Howard Hinnant’s days_from_civil / civil_from_days). Here rather than in core because both sides need it: core to compute a period’s end and a reference’s date label, embed to print plan expired 2026-10-01 in a refusal line. No chrono: the product should not inherit a date library for one string.
signing
The one canonical form an entitlement is signed over, and the verify side.
ticket
The actor ticket: the appliance’s word that this human may renew this tenant — minted by the product’s appliance, verified here.

Structs§

EntitlementCache
EntitlementFact
The verdict monetize pushes back. Product-agnostic; the plugin maps it to the product’s own enum (gunnar: EntitlementState).
KeyError
TenantId
A tenant, as the product names it. gunnar: the Namespace name (team/sub).
VerifyingKey
Re-exported so a caller that must CHECK a signature — a product, or the operator console — links one crate and cannot end up on a different ed25519-dalek than the one the canonical form was verified against. An ed25519 public key.

Enums§

Action
What the product is about to do on behalf of (or to) a tenant.
RefreshError
State
The ladder. Numbers (grace/retention days) are the deployment’s policy (monetize::Policy), not the enum’s.
Verdict