Golden Ticket Issuance
choco advanced 5 min read
ELI5
Only five Golden Tickets exist in the whole factory, ever. To stop two clerks stamping ticket #6 at the same time, the database hands one writer a key (an advisory lock); whoever holds the key gets to mint, then hands it back. Each ticket is signed with the factory’s private pen so anyone can verify it later.
Technical Deep Dive
Service: services/golden-press/. Singleton issuer enforcing the five-ticket system-wide cap. Events: GoldenTicketIssued, GoldenTicketRedeemed (proto/events/monetization/v1/golden.proto:55-78).
Issuance Sequence
sequenceDiagram participant Caller as Caller (gRPC) participant GP as golden-press participant PG as PostgreSQL participant LD as choco-ledger participant N as NATS Caller->>GP: IssueTicket(user_id) GP->>PG: SELECT pg_advisory_xact_lock(GOLDEN_KEY) GP->>PG: COUNT(*) FROM golden_tickets WHERE NOT redeemed alt count >= 5 GP-->>Caller: error: cap reached else count < 5 GP->>GP: ed25519.Sign(payload) GP->>PG: INSERT golden_ticket(...) GP->>LD: append ledger entry GP->>N: choco.events.monetization.golden_ticket.issued GP-->>Caller: ticket_id, ed25519_signature endFive-Ticket Cap
README.md:13 states the cap is “enforced by PostgreSQL advisory lock”. The lock serialises issuance across all golden-press replicas — without it two replicas could each pass the count check before either insert commits and overshoot the cap. Ordering: globally_ordered on the issued event (golden.proto:51) reflects this single-writer constraint at the wire layer.
Cryptographic Constraints
golden.proto:53-54 enumerates issuance constraints:
- “Maximum 5 Golden Tickets may exist system-wide”
- “Ticket must carry a valid Ed25519 signature”
Redemption (golden.proto:67-71) adds:
- “Ticket must pass Ed25519 signature verification”
- “TimeChain Merkle proof must validate against public ledger”
- “Ticket is non-transferable — user_id must match original issuee”
Anti-Gaming
README.md:14 references REQ-002-008 (“anti-gaming rules”); the implementation lives in the internal/antigaming package within golden-press. Specific rule contents are not in this repo (referenced by requirement ID only).
Endpoints
| RPC | Description |
|---|---|
IssueTicket | mint under advisory lock |
VerifyTicket | Ed25519 signature check |
GetTicket / ListTickets | read APIs |
RedeemTicket | redeem with TimeChain proof |
Retention
Both monetization events carry Retention: infinite (golden.proto:52, 66) — they are the canonical ledger of the five tickets’ history.
Key Terms
- advisory lock → application-defined Postgres lock on a key (
pg_advisory_xact_lock); not tied to a row, scoped to the transaction. - Ed25519 → elliptic-curve signature scheme (RFC 8032); deterministic, fast verification, 64-byte signatures.
- TimeChain → choco’s audit ledger (Rust, vest-node fork —
README.md:48); Merkle-proof-bound entries.
Q&A
Q: What happens if two callers race to issue the fifth ticket? A: First to acquire the advisory lock wins; the second blocks, re-reads the count after the first commits, sees 5, and errors. Without the lock the count check would race the insert.
Q: Why infinite retention? A: Five tickets system-wide; the entire history is small enough that retention pruning would save nothing and forfeit auditability.
Q: Where does the redemption-time Merkle proof come from?
A: timechain_proof field on GoldenTicketRedeemed (golden.proto:75); generated by choco-ledger against the public ledger and validated server-side before redemption is accepted.
Examples
A user redeems ticket #3. golden-press receives RedeemTicket(ticket_id, signature, timechain_proof), runs (1) Ed25519 verify against the issuer key, (2) TimeChain Merkle verify against the ledger root, (3) user_id match against the row, then UPDATEs redeemed=true under advisory lock and emits GoldenTicketRedeemed to choco.events.monetization.>.
neighbors on the map
- EventEnvelope Wire Wrapper publishing a new domain event proto
- Airlock JWT Handoff & Session Cookies debugging login loops or session expiry
- Multi-Strategy Authentication debugging 401 errors across different clients
- LORE RBAC & Airlock Auth Flow implementing authentication in a new LORE page