Lilith Metaverse · Features

Commerce, Rights & Takedown

A focused page within the Lilith Metaverse Features documentation. The full map and every sibling page live in the Features hub.

7sections12 minread1diagram

On this page
stateDiagram-v2 [*] --> Offered Offered --> Reserved: entitlement region and capacity admitted Reserved --> Paid: provider-authorized receipt Paid --> Active: ticket subscription or item delivered Reserved --> Expired: timeout or capacity release Paid --> Refunding: cancellation no-show dispute or policy Active --> Refunding: governed refund or takedown effect Refunding --> Refunded: provider and entitlement reconcile Active --> Withheld: rights consent safety or region restriction Withheld --> Active: restriction resolved on valid version Active --> Revoked: final takedown or entitlement termination Refunded --> [*] Revoked --> [*]

Payment, entitlement, attendance/delivery, rights, refund, and takedown states are reconciled but not conflated. Provider receipts and durable entitlement/ rights records govern what the member and creator see.

V3 ("Lilith") takes real money in three different rooms — a stadium ticket to a Saraswati concert, a tip dropped into a yoga instructor's jar mid-class, and a recurring pass that unlocks a club venue — and it sells one thing that has to unwind cleanly: a limited signed edition of an AI-generated track. The hard part was never charging the card. It is making the money land correctly afterward: a concert ticket has to be named-on-issue, capped per fan, and resalable only as a no-markup signed return so scalpers can't farm it; a cancellation has to know the difference between a user changing their mind an hour out and a Pixel-Streaming outage that wasn't the user's fault; and when a track is taken down for a rights violation, every ticket, replay, and signed edition that touches it has to flag itself within a day, with royalties paused. This page is the product-feature view of that discipline — the commerce primitives a fan touches, the cancellation and refund rules that govern them, and the rights/takedown machinery that can reverse a sale. It is the consumer-facing half of the architecture-side commerce & royalties companion; the deep settlement and split-math treatment lives there. For the full V3 feature map this slots into, start at the hub: ../V3_features.md.

What ships, honestly#

The commerce engine is real, tested Rust, not a checkout spec. apps/v3/lilith-commerce-service is a ~14.8 K-line crate — thirteen domain flow modules plus the Tara split engine in lib.rs — and it carries 151 #[test] cases (counted in-tree; the architecture companion records cargo test -p lilith-commerce-service151 passed; 0 failed, verified on box). The tests are not truthiness checks: they assert exact computed ledger amounts — a 10,000-cent paid class routes 2_000 to platform and 8_000 to the instructor, a 1,001-cent tip routes 100/901 with the rounding remainder deliberately handed to the recipient, a track waterfall that doesn't total exactly 10,000 bps is rejected. The crate's SERVICE_DESCRIPTOR (port 43105, lib.rs:206) advertises twelve capabilities — ticket-ledger, tip-route, saraswati-club-pass-billing, saraswati-signed-edition-drop, royalty-waterfall, and so on — each backed by a module.

Everything money-shaped settles on the shared Aje payment substrate, @oshun/payments-bridge (libs/oshun/payments-bridge): a substantive library with Ed25519 receipt signing (@noble/curves, src/receipt-signer/), a cold-spend co-signing queue, an admin/refund surface, and an entitlement bus (src/entitlement-bus/topics.ts) whose three topics — payment.invoice.confirmed, payment.invoice.settled, payment.refund.broadcast — carry structurally identical envelopes across four fiat processors and a long V1_PAYMENT_ASSETS list of crypto rails (BTC on-chain/Lightning, LTC, XMR, five EVM chains, SOL, TON, Cardano, Ergo, plus stablecoins). The entitlement service never learns whether a payment was fiat or crypto; it grants on invoice.settled.

Two honest qualifications. First, the commerce crate's job is the ledger, not the wire. Its flow functions validate the request, compute the routes, and emit a provider-shaped receipt with deterministic IDs and a Settled/Paid/Complete status — they do not call the live Stripe API or broadcast an Aje transaction from the pure-function path. That execution is the shared substrate's responsibility (Stripe Connect; the payments-bridge cold-spend queue and entitlement bus). Read a Settled status as "the ledger says settle here," with rail execution on the bridge. Second, the Year-1 catalog — which concerts, which drops, which passes — is a schedule the engine executes, not an artifact in the repo. The machinery is shipped; the merchandise is operations.

Selling access: tickets, tips, and subscriptions#

Three commerce primitives cover the ways a fan pays into Lilith, and each is its own module with its own anti-abuse posture.

Tickets — named, capped, signed-return-only resale#

lilith_ticket_issuance.rs (2.1 K lines, 15 tests) is the anti-scalp ticket ledger. A ticket is named on issue (bound to the buyer's V1 account) and capped at four per fan (LILITH_TICKET_PER_FAN_CAP = 4, :4). The only legal transfer is a LilithTicketResaleMode::SignedReturnOnly flow: the holder returns the ticket to the platform, which re-issues it to the next eligible buyer at the original price. Two checks make that anti-scalp, not advisory — the resale cannot exceed the original face value ("anti-scalp signed-return resale cannot exceed original face value", :493) and the buyer can't cross the per-fan cap (:481). The capacity bands map exactly onto the Stadium-tier seating plan: front-256 (LILITH_TICKET_FRONT_256_CAPACITY = 256), hall/mezzanine (768), crowd (3_072), and a 128-seat master class. A no-show seat is reclaimed by promote_lilith_waitlist_no_show_seat (:620) inside a 15-minute-pre / 10-minute-post-start window, and a canceled front-256 ticket promotes the next eligible mezzanine holder via the stadium band-reshuffle path.

Tips — three receipts, remainder to the creator#

lilith_tip_routing.rs (589 lines, 6 tests) routes a tip to an Instructor, Artist, or SessionHost at 10% platform / 90% recipient (LILITH_TIP_PLATFORM_BPS = 1_000 / LILITH_TIP_RECIPIENT_BPS = 9_000), over Stripe or Aje, and writes three receipts per tip — payer, recipient, and platform — so all three parties have a record. The rounding is a deliberate domain choice, not an accident: the test tip_routing_preserves_total_with_rounding_remainder_to_recipient (:502) feeds 1_001 cents and asserts the recipient gets 901 — the leftover cent favors the creator. saraswati_concert_tips.rs (413 lines, 5 tests) is the concert variant (SARASWATI_CONCERT_TIP_PLATFORM_BPS = 1_000 / ..._ARTIST_BPS = 9_000, settled inside a 60-minute window).

Subscriptions, passes, and the free tier#

lilith_subscription_billing.rs (832 lines, 10 tests) bills the recurring products — TaraPass, SaraswatiClubPass, CommonsMembership — on monthly cycles over Stripe or Aje, with month length bounded to 28–31 days and a post-GA 7-day proration window (LILITH_SUBSCRIPTION_PRORATION_WINDOW_MS). saraswati_club_pass.rs is the club admission path, and saraswati_free_tier.rs models the no-charge experience (catalog browse, follow, batched light-emoji, small-concert admission) so the free attendee is a first-class commerce state, not an absence of one — the same point the fan-economy page makes about where each tier ships.

Fan tokens — access, never yield#

lilith_fan_token_boundaries.rs (828 lines, 9 tests) keeps fan tokens an access primitive, not an investment. A valid access config must assert no_yield, no_transferable_security_claim, and access_only simultaneously (:72) — a token that grants queue priority or special-venue entry passes; a token that promises a return does not. Availability sits behind a per-region legal-review gate (LILITH_FAN_TOKEN_REQUIRED_REGION_PROFILE_COUNT = 5), and in a token-restricted region the same benefits are delivered through the V1 account primitive instead — a fan loses the token wrapper, never the benefit.

Store-billing bridges — compliance parity#

lilith_platform_billing_bridges.rs (514 lines, 6 tests) is the store-policy gate. Where Apple, Google, or Sony require their own billing flow, the bridge validates an Apple IAP / Google Play Billing / PSN Wallet receipt against the real policy references (LILITH_APPLE_IAP_POLICY_REF = "apple-app-review-guideline-3.1.1-iap", plus the Google Play and PSN refs): it forbids external payment links for in-app digital goods (:264"platform store policy gate forbids external payment links for in-app digital goods"), and requires a signed receipt, a passed certification case, and confirmed entitlement delivery. The point is reconciliation parity — a PSN-wallet purchase and a Stripe purchase grant an identical entitlement downstream.

Cancellation, refund, and no-show#

lilith_cancellation_refunds.rs (2.3 K lines, 22 tests) encodes the policy as a real classifier, not prose. classify_refund_tier resolves a user-initiated cancellation into three tiers: a full refund at ≥ 24 h before start, a half-refund / half-credit between 1 h and 24 h, and no refund inside the hour or on a no-show. The credit half lands in a 90-day Lilith credit ledger (LILITH_CREDIT_VALIDITY_MS = 90 * DAY_MS, :7).

The asymmetry between "the user changed their mind" and "we let the user down" is machine-enforced:

  • Platform / instructor cancellation adds a 50% goodwill credit (LILITH_PLATFORM_CANCELLATION_GOODWILL_CREDIT_BPS = 5_000) and must complete within a 24 h SLA (the report carries a completed_within_24h flag).
  • Provider-outage cancellation — a payment rail or Pixel-Streaming fault — issues a 100% credit (LILITH_PROVIDER_OUTAGE_CREDIT_BPS = 10_000), fires an operator alert, and pauses the affected concert's royalty waterfall pending review. Commerce and royalties are one ledger here, by construction.
  • Signed-edition drop cancellation. If editions were issued in advance, a holder chooses KeepAsHistoricalArtifact or BurnForFullRefund through a Lilith-Rights review queue (saraswati_signed_edition.rs) — a canceled concert never strips a holder of the artifact without consent.
  • Subscriptions cancel at any time with access through the end of the current period; post-GA, a renewal canceled inside the 7-day proration window is pro-rated.
  • Chargebacks and tax are first-class: the module owns refund tax reversal across jurisdiction profiles and a chargeback-handling path (LILITH_CHARGEBACK_HANDLING_POLICY_ID) with a confirmed-fraud route into the V1 anti-abuse list and an appeal window.

Waitlist promotion ties back to the ticket ledger: a no-show seat vacated inside the 15-min-pre / 10-min-post window is offered to the next active waitlist holder at the original price, never auctioned.

Rights and takedown#

A sale in Lilith is reversible because the underlying artifact's rights are. When a track's provenance is withdrawn, the money it touched has to unwind — and that is a coded cascade on a bounded clock, not a manual cleanup.

The 24-hour takedown cascade#

lilith_rights_takedown_cascade.rs (970 lines, 11 tests) is the unwind engine. execute_lilith_rights_track_takedown_cascade (:179) fans a track-level withdrawal across the surfaces the artifact touches, within a hard SLA: LILITH_RIGHTS_TAKEDOWN_CASCADE_SLA_MS = 24 * 60 * 60 * 1_000 (:5). The surface kinds and actions are typed, not freeform — InWorldReplay, OffPlatformReshare, and the archived-performance surface resolve to FlagHistorical, PauseReplay, and MarkSignedEditionHistorical, and the report records each outcome (PerformanceFlaggedHistorical, ReplayPaused, SignedEditionMarkedHistorical). The cascade is driven from V1: initiate_lilith_rights_v1_takedown_pipeline (:313) takes a v1_takedown_action_id and a target list, so a withdrawal initiated in the V1 takedown pipeline fans out into V3 automatically — V3 does not run a separate takedown machine.

The honest seam: what is coded and asserted here is the cascade report and the V1-pipeline contract — that a withdrawal produces flagged-historical performances, paused replays, marked editions, and disabled off-platform reshares, all inside 24 h. The actual replay-pausing and off-platform takedown notices ride the V1 event bus; this module is the deterministic V3-side contract that computes and bounds the fan-out. The persona-policy & provenance architecture makes the same honesty line: the Themis adjudication, the catalog-license pause, the royalty-waterfall pause, and the 24-hour deadline are the coded-and-gated core.

Signed editions and the historical flag#

saraswati_signed_edition.rs (2.2 K lines, 23 tests) mints limited editions of 250 (SARASWATI_SIGNED_EDITION_DROP_SUPPLY = 250) via the Aje primitive aje.signed-edition.mint.v1 inside a 6 h window, and enforces a 10% secondary-sale royalty (SARASWATI_SIGNED_EDITION_SECONDARY_ROYALTY_BPS = 1_000) that routes back to creators on every resale. When a track is taken down, its outstanding editions are marked Historical and resale-royalty routing pauses — but a holder is not stripped of the edition. This is the same royalty-protective logic the fan-economy page describes from the tenant-library side; here it is the commerce ledger's enforcement of it.

Where adjudication and provenance live#

The takedown the cascade executes is the output of a rights decision made elsewhere. Ownership and unlicensed-use disputes route through Themis in libs/v3/saraswati-stage/src/themis-rights-adjudication.ts, whose enforceSaraswatiThemisRightsDecision throws if enforcement lands outside SARASWATI_THEMIS_RIGHTS_MAX_ENFORCEMENT_MS = 86_400_000 (24 h) — the same bound the commerce cascade honors. The provenance bundle and forensic watermark that make an off-platform reshare traceable back to a session and recipient live in libs/shared/content-security (a plan/verify layer) and the V3 track bundle in libs/v3/isis-music. The detailed treatment of consent ledgers, the C2PA signature path, and crisis/persona policy is the governance, safety, recording & consent page and its architecture companion.

Settlement, audit, and DSAR#

Every ticket, tip, subscription, edition mint, and refund converges on the shared Aje plane so a purchase reconciles identically whether it arrived as fiat or crypto: the @oshun/payments-bridge entitlement bus grants on payment.invoice.settled, its state-mapper.ts maps a crypto confirmation depth to the V1 event types, and refunds flow back through payment.refund.broadcast and the admin-surface refund-initiation path. Receipts are Ed25519-signed against the V1 audit-platform key and canonicalized deterministically, so a receipt verifies off-box.

Every commerce action — issuance, route, cancellation, credit, takedown — is audit-logged into V1 @oshun/audit-platform, and the full ticket / refund / credit ledger is DSAR-covered. The same hash-chained, tamper-evident trail that the rights side produces is what an investigation or a data-subject request reads, so commerce, rights, and compliance share one evidentiary spine rather than three.

Edge cases and failure modes#

  • Resale can't scalp. A signed-return resale above original face value is refused, and a buyer already at the four-per-fan cap can't acquire a fifth through the resale path.
  • The remainder favors the creator. A 1_001-cent tip splits 100/901 — the rounding cent is assigned to the recipient by tested intent, not left to the platform.
  • Provider outage is a credit, not a loss. A payment-rail or Pixel-Streaming outage yields a 100% credit and an operator page, distinct from a user's own late cancellation — and it pauses the affected concert's royalty waterfall.
  • A store purchase can't dodge the rail. A platform-billing receipt carrying an external payment link for in-app digital goods is rejected at the gate.
  • Takedown is bounded, not eventual. The cascade and the Themis enforcement it follows both carry a 24-hour SLA as a coded invariant; "paused, eventually" is not a valid state.
  • A holder is never stripped silently. A taken-down edition is flagged historical with resale-royalty routing paused, and the holder chooses keep or burn-for-refund through a review queue.
  • The ledger seam is explicit. Stripe/Aje/store receipts are typed contracts emitted by pure functions; the live charge, on-chain broadcast, and cryptographic store-receipt validation happen in the shared substrate, not the split math.

Where this connects#