15 KiB
Sanitized detailed source transcription S07, captured 2026-10-24. Original planning steps, acceptance criteria and historical evidence are retained rather than condensed. Read current context and precedence first: dated holds, approvals, test counts and “latest” labels below belong to their original checkpoint and do not grant current execution/publication authority. Privacy replacements preserve roles and test semantics. See section coverage.
Shared contracts and risk decisions (T01 working draft)
Status: DRAFT / BLOCKED BY T00 PROVENANCE. This document records contracts inferred from the trusted core baseline and the unaccepted IndeeHub audit input. It does not authorize implementation source, spending, publication, public exposure, or deployment. Items marked POLICY REQUIRED block only their dependent feature.
1. Identity namespaces
Do not overload identifiers.
| Identifier | Required binding and lifetime |
|---|---|
creator_pubkey |
32-byte Nostr public key that signed creator-visible metadata and discussion events. Never inferred from a profile name. |
producer_did / buyer_did / seller_did |
Authenticated node DID used by peer protocols. A syntactically valid DID is not proof of its presenter. |
project_id |
Private application project UUID/local key. Never a public film identity or media capability. |
film_key |
Stable creator-bound discussion/catalog key, independent of application origin and mutable media revision. Proposed preimage: protocol domain + creator pubkey + creator-selected stable slug/UUID. It must be signed before use. |
film_revision |
Monotonic signed revision for one film_key; updates cannot change creator or stable film key. |
media_revision |
Immutable content binding: registered content ID + byte SHA-256 + size + media receipt/terms hash. Asset replacement creates a new revision and leaves an active old revision usable until replacement readiness and explicit publication. |
operation_id |
Lowercase canonical UUID, generated once before any side effect and reused for every retry. Never reused across rail, recipient, film revision, amount, or purpose. |
entitlement_id |
Seller-authenticated result bound to operation, buyer, film/media revision, terms and settlement proof. It is not a URL. |
chunk_id |
Deterministic from metered session + film/media revision + ordinal/range + rate revision; retries use the same ID. |
tip_id |
Separate logical operation with purpose creator_tip; it must never create entitlement. |
Legacy origin-derived discussion IDs may be read only through an explicit signed mapping to film_key. New writes use only film_key. Mapping conflicts fail closed and remain visible as separate legacy threads rather than silently merging identities.
2. Authority and capability boundaries
- The browser may request an operation, display terms and retain non-secret recovery identifiers. It must not manufacture native approval or settlement.
- The native node owns wallet selection, secret material, signer consent, protected media authorization and durable financial journals.
- IndeeHub backend owns authenticated project/draft state and may verify node receipts; it must not act as a node-wallet authority.
- Public catalog metadata is untrusted input until creator signature, protocol revision, pagination completeness and withdrawal/revision ordering validate.
- A playback capability is buyer-, entitlement-, film/media-revision- and deadline-bound. It is private, unguessable, not logged, not placed in query strings, and checked on every manifest/key/segment/range path.
- Public guest mode is a separate principal/origin/route manifest. It never receives owner cookies, signer/wallet bridges, private app routes, Backstage, files or admin capabilities.
3. Purchase operation state machine
The existing core Cashu contract is the minimum invariant:
intent -> seller_accepted -> spend_prepared -> settlement_unknown|seller_settled -> receipt_saved -> entitlement_or_delivery
Cancellation is terminal only when both sides authoritatively seal an unspent intent. After a wallet side effect is dispatched, timeout, restart or lost reply means settlement_unknown, not failure. While unknown:
- preserve the original operation and exact immutable terms;
- prohibit another payment and prohibit rail switching;
- query/reconcile authoritative seller and local-wallet state;
- never trust “I paid” as settlement evidence;
- never grant access or increment tips/profits until correlated settlement is verified;
- expose only customer-safe recovery status.
Required immutable operation binding:
protocol_version, operation_id, purpose, buyer principal, seller principal, film_key, film_revision, media_revision, amount/net amount, fee ceiling, rail/network/mint, recipient commitment, offered_at, expires_at, terms_hash.
A retry with any changed binding is rejected. Seller acceptance has no implicit garbage-collection expiry; it remains recoverable until an explicit authenticated cancellation/refund protocol reaches a terminal state.
4. Rail-specific contracts
Native Cashu
The trusted core v1 contract already binds buyer/seller DID, content hash/size, terms hash, network, canonical mint, gross token amount, minimum seller net and offer lifetime. Preserve its journal-before-side-effect and exact-envelope replay rules. Mint support is an offered capability, not evidence of producer wallet type.
Native Lightning
A Lightning operation binds one invoice/payment hash, amount, recipient commitment and operation context before native payment dispatch. A held/pending/unknown payment blocks replacement. Only authenticated node settlement tied to the original payment hash is final. Do not call a non-NIP-57 native tip a NIP-57 receipt.
Native on-chain
The current engine is explicitly not connected to owner RPC/UI. Qualification requires operation-owned address allocation, leased inputs, fee budget, saved PSBT/raw transaction, same-byte rebroadcast, confirmation tracking and reorg reversal. External address exposure is itself durable state and prevents silent address replacement.
POLICY REQUIRED — confirmation/reorg: propose 1 confirmation for low-value test/regtest UX and a configurable producer policy for mainnet, with entitlement never becoming more permissive after a detected reorg. Product/security review must set supported mainnet thresholds before this rail can be offered.
External Lightning/on-chain
The customer may use a visitor-owned wallet and need not have a native sending wallet. Invoice/address exposure is journaled first. The application polls authoritative recipient state and must not accept user assertion. Expired unpaid instruments may be retired only by authoritative state; ambiguous instruments block replacement/method switching.
5. Capability privacy
Customer and guest APIs intentionally disclose only offered methods. For every producer-side unsupported, unconfigured, offline, unhealthy, empty, provider-mismatch or internal-error case, the customer-facing value is exactly “Not offered.”
Responses must be normalized against inference through body text, status class, headers, polling shape and avoidable timing differences. Producer/admin diagnostics remain authenticated and are redacted from customer logs. Customer-owned failures may describe only the customer’s own wallet, balance, network, fee or approval state.
6. Rental entitlement
- Payment/preparation does not start viewing time.
- Exactly one atomic
starttransition createsstarted_atand immutableexpires_at = started_at + viewing_seconds. - Concurrent starts return the same window.
- Lost start replies and restart return the same window; they never extend it.
- Every protected manifest, variant, key, segment, original, trailer/subtitle (when paid), range and cache hit rechecks entitlement and deadline.
- Expiry invalidates cached/key/media delivery. A definitive expired state may offer a distinct new-rental action requiring fresh consent and a fresh operation ID.
- Preparation/readiness never creates or extends a lease. Existing signed 64 KiB integrity indexes are transport-integrity support, not metered billing chunks.
POLICY REQUIRED — permitted sessions/devices: until reviewed, allow recovery by the same authenticated buyer/node and deny transfer to another principal. Concurrent first-start must collapse to one window; the maximum simultaneous playback streams must be selected before public qualification.
7. Metered ecash streaming
Metered streaming is a separate protocol from fixed rental and remains disabled by default.
Allowance record:
allowance_id, buyer, seller, film/media revision, mint/network, ceiling_sats, spent_sats, reserved_sats, rate_revision, state, created_at, updated_at.
Invariant: spent + reserved <= ceiling under one durable atomic lock across tabs/sessions. The zero default creates no purchases. Increasing the ceiling preserves history. Lowering to or below current spent + reserved stops new reservations but does not erase or misreport in-flight effects.
Each chunk binds ordinal/range, complete deliverable unit, seller, rate revision, gross fee-inclusive maximum, receipt and delivery state. Journal reservation before payment. A paid chunk retry/seek reuses access under the retained receipt; it is not repurchased. Pause, stop, background-disallowed playback, delivery uncertainty or unresolved settlement prohibits a new reservation.
POLICY REQUIRED — chunk/rate: duration/byte unit, complete-chunk pricing, seek/replay retention and allowance scope across simultaneous sessions are not inferred from the prototype. T25 cannot offer metered mode until those values are approved and represented in signed terms. Existing 64 KiB byte-index chunks must not silently become billing chunks.
8. Tips/zaps and social receipts
Tip capabilities are independent of rental capabilities. The original amount picker remains 21 / 100 / 1,000 / 5,000 sats, defaults to 100, and accepts positive whole-sat custom input. Method selection follows amount selection.
Every tip has a separate tip_id, creator/film key, amount, rail, payer attribution policy and settlement state. It grants no entitlement. Social totals and Networking Profits increment exactly once from a verified final receipt. Pending/unknown tips remain visibly pending and are not included in confirmed totals. Anonymous display must not remove the internal anti-duplication binding.
NIP-57 labels are reserved for protocol-valid NIP-57 request/receipt pairs. Native Cashu, native on-chain and non-NIP-57 Lightning tips use rail-correct generic tip receipts.
9. Catalog and discussion protocol
A catalog event binds protocol revision, creator, stable film key, monotonically ordered revision, immutable media/terms commitment, public presentation metadata, offered capability set and signed withdrawal semantics. It carries no management or byte-delivery authority. Pagination must prove boundary completeness or retain the previous verified snapshot.
Comments/replies/reactions bind stable film key, author pubkey, event ID, parent/root IDs and created time. Enforce event/body size, depth, cycle, signature and author consistency limits. Backfill and deduplicate by signed event ID. Moderation is additive signed policy/tombstone state; it does not rewrite another author’s event.
10. FIPS and media transport
All remote node-to-node media transport uses authenticated FIPS. No HTTP(S), direct object URL, redirect, Tor/CDN or storage fallback may bypass it. Browser HTTP from the owner node to its local presentation layer is distinct, but that layer may only serve bytes acquired and authorized through the FIPS path. Failure of FIPS while alternatives exist fails closed and preserves the entitlement for later recovery without repayment.
11. Networking Profits ledger
One durable receipt contributes to exactly one primary confirmed category:
fixed_film_salemetered_film_streamcreator_tipnetwork_service
Session subtotals are views, never additional revenue. Pending and unknown are excluded from confirmed total. Reorg/reversal creates a linked adjustment rather than deleting history. Every entry records unique receipt ID, operation ID, gross, fees where known, net where known, currency/rail, effective timestamp and source category. “Unavailable” is not zero; gross must not be displayed as net.
12. Versioning and migration
- Existing Cashu purchase protocol remains v1 and is not changed in place.
- New catalog/discussion/metered/tip envelopes use explicit versions,
deny_unknown_fieldsor equivalent strict validation, ordered commitment preimages and bounded encoded sizes. - Old receipts and entitlements remain readable through versioned adapters. Migration never fabricates missing signatures or settlement certainty.
- A migration writes new state only after validating the old record and remains retryable. Financial journals are never rolled back from a stale backup after a possible side effect; they stop for reconciliation.
13. Negative-test obligations before T01 acceptance
Production-path tests must fail safely for: identity/recipient/film/revision/amount substitution; malformed/oversized/unknown fields; stale signer; duplicate/concurrent intent; crash before and after each side effect; lost seller/native response; unknown settlement; method switch attempt; invoice/address expiry; fee or rate change; mint/network mismatch; reorg; entitlement concurrent start/expiry/cache/key/range bypass; allowance concurrency and exact ceiling; duplicate tip/profit receipt; catalog rollback/incomplete pagination; comment author/root/cycle/XSS; producer capability enumeration; and public guest access to owner bridges/routes.
14. Open decisions and feature-local blockers
| Decision | Blocks | Does not block |
|---|---|---|
| Metered billing unit/rate, seek retention and cross-session allowance scope | T25 metered offer | fixed rentals, UI preservation |
| Mainnet confirmation/reorg policy and fee ceilings | on-chain offering in T07/T12/T26 | Cashu and isolated regtest development |
| Permitted simultaneous playback/device policy | public rental qualification | atomic first-start implementation/tests |
| Approved replica retention/quota/hosting policy | T10 | direct publisher delivery |
| Accepted IndeeHub proposal/integration base | IndeeHub source acceptance and operator node deployment | trusted-core source work and local design/test analysis |
| Public guest threat-model/security review | T29/public exposure | authenticated owner-only local use |
No prototype value resolves these decisions automatically.