# SPEC — Dumpling Play (DPPlay) **Status:** Draft v0.8 (PoC scope) — v0.4 base **as supplied by Ace**, plus a **PROPOSALS layer (§9–§13)**. §10 questions answered → **§11 decisions (D15–D33)**. PoC runs on a **single machine (Docker-emulated split, hosted locally)**; AWS is the post-Phase-3 target (D27/D28). **Phase 0 is lobby-first** (D31); product/UX lives here (**§13**, D32), implementation in **`PHASE0.md`**. Pending approval to build. **Owner:** Kiri Zynk (architecture/build) · Ace (approver) — *base doc owner: TBD* **Created:** 2026-07-06 **Last updated:** 2026-07-06 > **Governance (per workspace TOOLS.md):** plan before build; approval before code > changes/deploys. The v0.4 base spec below is preserved **verbatim** as supplied. > Everything I add is confined to **§9 Proposals**, **§10 Open questions**, and the > **Changelog** — clearly marked `[PROPOSED 2026-07-06]` and **not yet decided**. > Nothing in the Decisions log (§7) has been altered. Any future spec-vs-build drift > is filed as a **BUG** with a proposed fix, never silently patched. ### Companion plan documents This spec is the **canonical index**. Child plan docs (kept linked here so none orphan): | Doc | Purpose | Link | |---|---|---| | **`PHASE0.md`** | Phase 0 (Foundations) staged build plan — *implementation only* | [PHASE0.md](./PHASE0.md) · | | **§13 (in this doc)** | Lobby UX & wireframes — *product/UX home* (D32) | [§13 Lobby UX](#13-lobby-ux--wireframes-product--proposed-2026-07-06-iterating) | | **`wireframes/lobby.html`** | Interactive lobby wireframe (visual, for iteration) | | *(New plan docs must be added to this table and back-reference this SPEC — workspace TOOLS.md rule 4, no orphan documents.)* --- # Dumpling Play (DPPlay) — Product Specification | | | |---|---| | **Product** | Dumpling Play (DPPlay) — casino game aggregator service | | **Status** | Draft v0.4 (PoC scope) | | **Last updated** | 2026-07-03 | | **Owner** | TBD | | **Initial merchant** | KZ Whitelabel (company's main product) | | **Related assets** | `mascotcharactersheet.png` (brand/style reference) | > Abbreviation note: this product is abbreviated **DPPlay** to avoid confusion with Dumpling Pay (**DPP**), a separate product. --- ## 1. Overview Dumpling Play (DPPlay) is a game aggregation service that sits between online casino operators (merchants) and game providers. To the merchant, DPPlay presents itself as a single game: one icon in their existing lobby. When a player clicks that icon, instead of loading a single game, it opens the **DPPlay lobby** — a curated, Dumpling-branded selection of games sourced from multiple upstream providers. What DPPlay means to each audience: - **Player** — a destination: a warm, fortune-themed game hub with a recognizable mascot. - **Merchant** — a low-friction integration: one game entry using the integration pattern they already support. - **DPPlay** — a pass-through layer that owns the lobby experience, meters every transaction for records and statistics, and abstracts provider accounts away from merchants. ### 1.1 Goals 1. Integrate with **KZ Whitelabel** (the company's main product) as the initial merchant, appearing as a single game entry alongside its existing game catalogue. 2. Deliver a curated, branded game lobby experience hosted by DPPlay. 3. Pass game sessions and wallet transactions through to upstream game providers transparently, with minimal merchant integration effort. 4. Record all transactions independently for reconciliation and statistics. 5. Abstract provider accounts so the merchant's commercial and technical relationship is with DPPlay. ### 1.2 Out of scope (PoC) - Regulatory / licensing considerations. - Billing and commercial model — reconciliation covers **statistics only**. - Currency bridging / FX — currency between merchant and provider **must match** (THB only, see §5). - Promotions and free rounds pass-through. - Provider discovery — the provider shortlist is already fixed; no new providers in this scope. - Building or hosting our own game engines/content (aggregation only). - Player account management, KYC, or funds custody — the merchant remains the wallet of record. - Direct-to-player distribution (players are always the merchant's players). ### 1.3 Precedent The "icon opens a lobby" pattern already exists in market (e.g., provider-branded lobbies, crash/instant-game hubs, and fishing-game halls launched from a single tile). Merchants and players are familiar with this behaviour, which lowers education cost on both sides. --- ## 2. Actors & definitions | Term | Definition | |---|---| | **Merchant** | An online casino / gaming site that integrates DPPlay as a game. Owns the player relationship and the player wallet. PoC merchant: **KZ Whitelabel**. | | **Player** | An end user of a merchant site. Never has a direct account with DPPlay. | | **Game provider** | An upstream studio/aggregator supplying games that DPPlay curates into its lobby. Fixed shortlist for the PoC: **Zenith, AMB, Super Swan** (see Appendix A). | | **DPPlay** | The pass-through service: lobby frontend + transaction gateway + accounting/statistics layer. | | **Session token** | Short-lived credential issued at launch that binds a player, merchant, currency, and locale to a DPPlay lobby session. | | **Pass-through transaction** | A bet/win/rollback that DPPlay relays between a provider and the merchant wallet, recording it along the way. | --- ## 3. Frontend ### 3.1 Entry point: the game icon **FE-1.** DPPlay appears in the merchant's lobby as a game tile, launched exactly like any other game: the merchant platform calls a launch endpoint with player/session parameters and receives a URL to open in an iframe, new tab, or webview. **How the game appears — tile design, placement, sizing — is entirely the merchant's decision.** DPPlay provides a reference/recommended image, but the merchant has ultimate say over presentation. **FE-2.** DPPlay supplies catalogue metadata the same way game providers commonly do: **game code, game type, category, and image (tile icon)**. Merchants are expected to **query a DPPlay catalogue endpoint** (pull/poll) to retrieve current metadata and updated images. Push notifications (webhooks) for metadata/image updates are an **optional merchant integration and not required for the PoC**. For the PoC, DPPlay itself is a single catalogue entry; the same endpoint pattern leaves room for future entries (e.g., seasonal variants or direct-launch shortcuts). ### 3.2 The lobby **FE-3.** Clicking the icon opens the DPPlay lobby, a web page hosted by DPPlay (stack: see §7, decision #1). It must run inside an iframe or webview and standalone in a browser tab, and be responsive from small mobile (360px) up to desktop, since traffic is mobile-dominant. **FE-4.** The lobby displays games **curated by DPPlay**. Curation is centrally managed by DPPlay (ordering, categories, featured slots, availability per merchant). **DPPlay defines its own category taxonomy**: provider-supplied game types/categories are treated as ingest metadata only and are re-organised into DPPlay's taxonomy during curation. Merchants do not manage lobby content. **FE-5.** Core lobby capabilities for the PoC: - Game grid with category rows (e.g., Featured, Slots, Fishing, Instant/Crash, New). - Search and category filtering. - Game launch: tapping a game opens the provider game inside the lobby context, with a persistent way back to the lobby. - Session continuity: returning from a game lands the player back in the lobby, not back at the merchant site. - Localization: language inherited from launch parameters (Thai, English for PoC — see §5). - Graceful states: loading, provider unavailable, game unavailable, session expired (with a re-entry path back to the merchant). **FE-6.** Deferred/post-PoC: recently played, favourites, jackpot tickers, promotions rail, mascot-driven onboarding moments. ### 3.3 Visual & brand direction Reference: `mascotcharactersheet.png`. - **Mascot**: "Dumpling," a cheerful dumpling character — bringer of wealth and good fortune. Poses in the sheet (brings wealth, attracts fortune, good luck aura, supports your journey, treasure chest hero pose) map naturally to lobby states: hero banner, empty states, loading, celebration moments. - **Palette**: deep charcoal/near-black backgrounds; rich gold as the primary accent; auspicious red as the secondary accent; warm cream for highlights. Gold-on-dark is the default surface treatment. - **Motifs**: gold ingots (元宝), round coins with square holes, sparkles/star glints, the 福 (fortune) seal, subtle cloud line-work on dark backgrounds. - **Tone**: cheerful, lucky, generous — "good games, like good dumplings, bring people together." Prosperity-themed but cute rather than aggressive; culturally resonant in the Thai market. - **Typography**: bold display face with a brushstroke feel for headings (per the wordmark), paired with a clean geometric sans for UI text; must support Latin and Thai scripts (CJK optional for PoC). ### 3.4 Frontend requirements summary | ID | Requirement | Priority | |---|---|---| | FE-1 | Launchable as a standard game tile; tile presentation is merchant's decision; DPPlay supplies a recommended image | P0 | | FE-2 | Catalogue endpoint exposing game code, type, category, image; merchants query for updated images | P0 | | FE-3 | Responsive lobby, iframe/webview-safe, mobile-first | P0 | | FE-4 | Centrally curated content with per-merchant configuration | P0 | | FE-5 | Grid, categories, search, in-context game launch & return, Thai/English localization, error states | P0 | | FE-6 | Favourites, recents, promos, jackpot tickers | P2 | --- ## 4. Backend ### 4.1 Architecture summary DPPlay is a **pass-through game service** with three responsibilities: 1. **Lobby hosting** — serving the lobby web app and its content/config APIs. 2. **Transaction pass-through** — relaying game/wallet calls between providers and merchants in real time. 3. **Accounting & abstraction** — recording every transaction for reconciliation and statistics, and shielding merchants from provider account ownership. ``` ┌──────────┐ launch ┌──────────────────────────────┐ launch ┌───────────┐ │ Merchant │ ──────────▶ │ DPPlay │ ──────────▶ │ Game │ │ (KZ WL) │ │ │ │ Providers │ │ │ ◀────────── │ Lobby ▪ Gateway ▪ Ledger │ ◀────────── │ │ └──────────┘ wallet └──────────────────────────────┘ bet/win └───────────┘ ▲ player's wallet of record │ └── players never hold a DPPlay account ──┘ ``` ### 4.2 Launch & session flow 1. Merchant platform requests a DPPlay game launch (player ref, currency, language, return URL, merchant credentials). 2. DPPlay validates the merchant, creates a **DPPlay session**, and returns the lobby URL with a session token. **KZ Whitelabel opens this URL in an iframe**, as it does for other games. 3. Player browses the lobby; content is filtered by merchant configuration. 4. Player launches a game. DPPlay calls the corresponding provider's launch API **using DPPlay's provider account**, presenting the DPPlay-wrapped player reference (see §4.5), and embeds the provider game. 5. Gameplay begins; wallet traffic flows per §4.3. **Providers never communicate with the merchant directly** — all traffic for DPPlay-routed sessions flows through DPPlay. 6. On exit, the player returns to the DPPlay lobby; on lobby exit, DPPlay **redirects to the merchant's return URL** (KZ Whitelabel's iframe handles the redirect back into its own flow). ### 4.3 Transaction pass-through (per-provider mirrored APIs) The merchant remains the wallet of record. To keep pass-through **low-effort and low-risk**, DPPlay does **not** translate provider wallet APIs into a unified spec. Instead: - **Merchants integrate one set of wallet APIs per game provider they want to enable**, mirroring that provider's native wallet callback spec (balance, debit/bet, credit/win, rollback). - If the merchant has **already integrated that provider directly**, the work is minimal: they stand up a **separate endpoint for DPPlay** reusing their existing implementation of the provider's spec. The separate endpoint (and separate credentials) is what distinguishes DPPlay-routed traffic from the merchant's own direct integration. - **Upstream**, providers call DPPlay as the operator (traffic rides **DPPlay's provider account**); **providers never call the merchant directly** for DPPlay-routed sessions. DPPlay relays each call to the merchant's DPPlay-specific endpoint for that provider with minimal transformation (identity re-mapping, signing, logging), then relays the merchant's response back. Every operation is written to the DPPlay ledger on the way through, with idempotency keys preserved end-to-end so provider retries and merchant retries reconcile to a single logical transaction. Key behaviours: - **Idempotency:** all debit/credit/rollback calls carry provider transaction IDs; DPPlay maps them to DPPlay transaction IDs and enforces exactly-once ledger effects even under retries. - **Rollbacks & unfinished rounds:** DPPlay relays provider rollbacks and runs a sweeper for rounds left open beyond a TTL, per each provider's round-settlement rules. - **Timeout policy:** if the merchant wallet is unreachable, DPPlay responds to the provider per that provider's required failure semantics and records the discrepancy for reconciliation. - **Currency:** merchant and provider currency **must match**; PoC is THB end-to-end. Launch requests in unsupported currencies are rejected. ### 4.4 Accounting, reporting & statistics DPPlay maintains an **independent double-entry ledger** of all pass-through activity. Scope for the PoC is **statistics and reconciliation only — no billing**. - Per-transaction records: merchant, player ref, provider, game, round, bet, win, rollback, timestamps, currency, status. - Aggregations: GGR and volume per merchant/provider/game/period. - **Reconciliation:** daily jobs compare DPPlay ledger vs. provider reports vs. merchant confirmations; discrepancies enter an exceptions queue. - **Reporting surfaces (MVP):** read-only reports with transaction search — merchant-facing portal (their own traffic only) and internal ops portal (global view). ### 4.5 Provider account abstraction DPPlay holds the commercial and technical accounts with each game provider. Merchants never see provider credentials, contracts, or player-registration requirements. - **Identity wrapping (DPPlay-owned reference):** merchant player refs are assumed **reliably unique** and are used to determine returning players. However, merchant refs are **never sent upstream**: DPPlay wraps each (merchant, merchant player ref) pair in a stable, DPPlay-issued player reference, and this wrapped identity is the only identifier ever presented to providers. This is a deliberate design choice so that DPPlay operations always work with a **consistent, DPPlay-controlled player reference** across providers, independent of any merchant's ref format or future changes. Mapping records (merchant ref ↔ DPPlay ref ↔ per-provider identifiers) are persisted so per-player history and statistics stay consistent across sessions. - **Provider adapters:** each shortlisted provider is integrated as an adapter module implementing a common internal interface (launch, wallet relay, round lifecycle, catalogue sync). Adding a provider requires the merchant only to stand up that provider's mirrored wallet endpoint (§4.3). - **Catalogue sync:** provider game lists, thumbnails, and metadata are ingested into DPPlay's catalogue service, which feeds lobby curation and the merchant-facing catalogue endpoint (FE-2). ### 4.6 Non-functional requirements - **Latency:** wallet callback round-trips (provider → DPPlay → merchant → DPPlay → provider) are on the hot path of every spin. Target added latency from DPPlay ≤ 50 ms p95 per hop; deploy in-region (e.g., Singapore) for Thai traffic. - **Availability:** 99.9%+ for gateway and lobby; wallet gateway degrades independently of lobby. - **Security:** merchant/provider auth via signed requests (HMAC or mTLS per counterparty convention), IP allowlisting where required, full audit logging, encrypted PII at rest (player refs are pseudonymous but treated as PII). - **Observability:** per-merchant and per-provider dashboards for error rates, latency, and stuck rounds; alerting on reconciliation drift. --- ## 5. Market - **PoC market:** Thailand, **THB only**. Currency must match end-to-end (merchant wallet, DPPlay ledger, provider sessions). - **Languages:** Thai and English. - **Device profile:** overwhelmingly mobile web and in-app webviews on mid-range Android; the lobby must be lightweight (target < 1.5 MB initial load) and tolerant of high-latency networks. - **Cultural fit:** the fortune/prosperity brand direction (gold, red, 福, ingots) resonates in the Thai market and supports seasonal lobby refreshes (Lunar New Year, Songkran). - **Content curation:** Thai-popular verticals — slots, fishing/arcade games, instant/crash games — anchor the initial curated catalogue from the shortlisted providers. - **Regulatory:** out of scope for this PoC. --- ## 6. Success metrics (PoC) - **At least 10 games live** in the DPPlay lobby, playable end-to-end through KZ Whitelabel. - KZ Whitelabel integration time from credentials to live: < 5 business days per enabled provider. - Lobby open → first game launch conversion rate. - DPPlay-added wallet latency p95 ≤ 50 ms. - Reconciliation match rate ≥ 99.99% of transactions auto-matched. - Zero wallet-integrity incidents (double-debit / lost credit) during PoC. --- ## 7. Decisions log | # | Topic | Decision | Status | |---|---|---|---| | 1 | Lobby frontend stack | **Recommended: SvelteKit** (or Preact + Vite as alternative). Rationale from constraints: smallest runtime footprint of mainstream frameworks (fits < 1.5 MB budget on mid-range Android), SSR/streaming for fast first paint on high-latency networks, straightforward i18n (Thai/English), no iframe/webview constraints, and simple static/edge deployment for in-region hosting. Avoid heavy SPA frameworks unless team familiarity outweighs bundle cost. | Proposed | | 2 | Merchant integration surface | Merchants integrate **one mirrored wallet API set per enabled provider**; if already integrated directly with that provider, they add a **separate DPPlay endpoint** reusing existing code. No unified wallet spec. | Decided | | 3 | Commercial model / billing | Out of scope. Reconciliation provides **statistics only**. | Decided | | 4 | Currency bridging / FX | None. Currency must match; PoC is THB only. | Decided | | 5 | Promotions / free rounds | Out of scope. | Decided | | 6 | Licensing / regulatory | Out of scope for PoC. | Decided | | 7 | Provider shortlist | Fixed: **Zenith, AMB, Super Swan** (Appendix A). No provider discovery in this scope. | Decided | | 8 | Merchant reporting portal | MVP: read-only reports with transaction search. | Decided | | 9 | KZWL launch convention | Return-URL redirect; KZ Whitelabel opens the lobby URL in an **iframe**. | Decided | | 10 | Wallet routing | Providers **never** call the merchant directly; all DPPlay-routed traffic relays through DPPlay (fully ledgered). | Decided | | 11 | Player identity | Merchant refs are **reliably unique** and identify returning players. DPPlay **wraps** the merchant ref in its own player reference before sending to providers, so DPPlay operations use a consistent, DPPlay-controlled identity across all providers. | Decided | | 12 | Catalogue updates | Pull/poll endpoint for PoC; webhooks are an optional merchant integration, post-PoC. | Decided | | 13 | Category taxonomy | DPPlay-owned taxonomy; provider categories are ingested as metadata and re-organised during curation. | Decided | | 14 | UAT environments | Zenith and AMB UAT are good; **Super Swan UAT is poor** — sequence Super Swan last and budget extra integration/QA time. | Decided | --- ## 8. Roadmap sketch (PoC) - **Phase 0 — Foundations:** ledger, launch/session API, catalogue endpoint, first provider adapter (**Zenith** — good UAT), lobby prototype. - **Phase 1 — KZ Whitelabel pilot:** end-to-end launch → play → settle with Zenith in THB; reconciliation jobs; read-only reporting with transaction search. - **Phase 2 — Fill out shortlist:** **AMB** adapter (good UAT), then **Super Swan** last (poor UAT — budget extra integration/QA time, and consider validating against production-like sandbox behaviour early); curated catalogue expansion to ≥ 10 live games; branded lobby polish (Thai/English). - **Post-PoC candidates:** additional merchants, favourites/recents, promotions, additional markets/currencies, billing, catalogue webhooks. --- ## Appendix A — Provider shortlist (PoC) | Provider | UAT environment | Sequencing | Notes | |---|---|---|---| | **Zenith** | Good | 1st | First adapter; anchors Phase 0/1. | | **AMB** | Good | 2nd | Phase 2. | | **Super Swan** | Poor | 3rd (last) | Extra integration/QA buffer; plan for limited UAT reliability. | --- *Style/brand reference: `mascotcharactersheet.png` — Dumpling, mascot & bringer of wealth and good fortune.* --- # 9. PROPOSALS `[PROPOSED 2026-07-06 — pending approval]` > These sections respond to Ace's two requests (2026-07-06): **(A)** add an > **Admin portal** component, and **(B)** design a **decentralised architecture** > split into a **central worker** (monolithic, admin APIs) and a **gateway** > (horizontally scalable, player auth + provider proxy). Nothing here is decided; > it is a proposal for review. Open questions that gate these choices are in §10. ## 9.A New component — Admin portal The base spec (§4.4) already names an **internal ops portal (global view)** and a **merchant-facing portal (own traffic only)**, both scoped read-only. This proposal **promotes the internal ops portal into a first-class Admin portal** and defines its surface. It does **not** change the merchant-facing portal (stays as Decision #8). **AD-1 — Purpose.** A DPPlay-internal web console for operations, finance, and curation staff to review and (optionally) act on live and historical data. **AD-2 — Read surfaces (P0, aligns with §4.4 "read-only"):** - **Transactions:** search/filter by merchant, provider, game, round, player ref, status, time; drill into a single logical transaction and its idempotency chain (provider txn ↔ DPPlay txn ↔ merchant call/response). - **Players:** look up a DPPlay player reference, view the identity mapping (merchant ref ↔ DPPlay ref ↔ per-provider ids, §4.5) and that player's session/round history. **PII treated per §4.6** (pseudonymous, encrypted at rest). - **Reconciliation:** view the daily exceptions queue and per-transaction match state. - **Statistics:** GGR/volume aggregations per merchant/provider/game/period (§4.4). - **Health:** per-merchant/per-provider error, latency, and stuck-round dashboards (surfaces §4.6 observability); reconciliation-drift alerts. **AD-3 — Write/action surfaces `[RESOLVED 2026-07-06 — Ace (Q2): READ-ONLY for initial scope; actions added iteratively later]`:** The PoC admin portal is **read-only** (AD-2 surfaces only). The action surfaces below are **deferred / out of PoC scope**, documented so we design the read model without foreclosing them. Candidate actions for a later version: curation management (ordering, featured slots, categories, per-merchant availability — see FE-4), catalogue overrides, manual resolution of reconciliation exceptions, manual round settlement / rollback replay for stuck rounds, merchant/provider config & credential rotation, session kill-switch, and provider/game enable-disable toggles. **Every write must be RBAC-gated and fully audit-logged** (§4.6). *Whether any writes are in PoC scope is an open question (Q2)* — v0.4 §4.4 implied read-only. **AD-4 — Access & security `[RESOLVED 2026-07-06 — Ace (Q1): user base & roles below]`:** internal-only (VPN / IP allowlist), SSO + RBAC. Confirmed user base and role sizing: - **Ops** (5–10) — operational monitoring, transaction/round lookups, health. - **Finance / Recon** (1–3) — reconciliation exceptions, GGR/stats, ledger drill-down. - **Game managers** (1–5) — catalogue/curation *views* in PoC (edits deferred, AD-3/Q2). - **UX & Data analysts** (10–20) — read/query access to stats & player-journey data; this is the **largest cohort**, so the read/query surface (AD-2) and any analytics export must be built for ~20+ concurrent read users, not an afterthought. All access audit-logged. The admin portal is **not on the player hot path** and must not share a failure domain with the wallet gateway. **AD-5 — Placement:** the Admin portal **frontend** is served by / talks only to the **central worker** (§9.B), never the gateway. This keeps admin traffic off the latency-critical data plane. ## 9.B Decentralised architecture — control plane vs data plane The core idea: split DPPlay's three responsibilities (§4.1) along a **hot-path / not-hot-path** seam. The wallet relay and player auth are latency-critical and bursty → **gateway (data plane), stateless, horizontally scaled**. Admin, curation, reconciliation, aggregation and config are batch/interactive and low-QPS → **central worker (control plane), monolithic**. ``` PLAYERS MERCHANT (KZ WL) PROVIDERS │ │ │ ▼ ▼ launch bet/win ▼ (providers→DPPlay) ┌───────────────────────────────────────────────────────────────────────────┐ │ DATA PLANE · GATEWAY (stateless · horizontally scalable · in-region) │ │ • player auth / session-token issue & verify • lobby launch endpoint │ │ • wallet pass-through relay (§4.3, hot path, ≤50ms p95/hop) │ │ • provider proxy APIs (adapters: launch, wallet relay, round lifecycle) │ │ • serves lobby SSR/static assets (or via CDN/edge) │ └───────────────┬───────────────────────────────────────────┬─────────────────┘ │ shared stores │ event/ledger stream ▼ ▼ ┌───────────────────────────────┐ ┌──────────────────────────────────┐ │ SHARED STATE │ │ CONTROL PLANE · CENTRAL WORKER │ │ • Postgres (ledger, mappings, │◀────────▶│ (monolithic · admin APIs) │ │ config, catalogue) │ │ • Admin portal backend (§9.A) │ │ • Redis (sessions, tokens, │ │ • curation & catalogue sync │ │ idempotency, rate limits) │ │ • reconciliation & sweeper jobs │ │ • optional queue/bus │ │ • statistics/GGR aggregation │ └───────────────────────────────┘ │ • merchant/provider config mgmt │ └──────────────────────────────────┘ ``` **AR-1 — Gateway (data plane).** Stateless request handlers behind a load balancer; scale horizontally on QPS/latency. `[RESOLVED 2026-07-06 — Ace (Q4): Node/TS for maintainability (team stack is TypeScript). Note: the hot-path work is now I/O-bound relay + a Redis check + a stream publish (AR-1/Q5), which suits Node's event loop; the heavy CPU-bound accounting moved off this path to the worker.]` Responsibilities: - **Player auth:** issue and verify **session tokens** (§2). Tokens should be **self-contained/signed** (or backed by shared Redis) so **no node affinity / sticky sessions** are required — any gateway node can serve any request. - **Launch endpoint** (merchant → DPPlay) and **provider proxy** (provider adapters, §4.5): launch, wallet relay, round lifecycle. - **Wallet pass-through** (§4.3): the hot path. `[RESOLVED 2026-07-06 — Ace (Q5): ASYNC ledger via queue — real volume expected]` The gateway does **not** do the heavy double-entry Postgres write inline. On the hot path it: (1) enforces **exactly-once relay** via a **synchronous Redis idempotency check** on the end-to-end idempotency key (cheap, sub-ms — a provider/merchant retry never double-hits the merchant wallet); (2) **durably captures** the transaction event by publishing to the ledger stream (§9.D); then (3) relays to the merchant and responds to the provider. The **worker** consumes the stream and performs the authoritative double-entry ledger write (write-behind). See §9.D for how this preserves the **zero-wallet-integrity-incident** goal. - Terminates counterparty auth (HMAC/mTLS, IP allowlist — §4.6) at the edge. `[RESOLVED 2026-07-06 — Ace (Q9): provider IP gating is handled at the LB.]` So the **AWS LB/edge** enforces the provider IP allowlist (ELB security groups / WAF) *before* traffic reaches the gateway; the gateway then verifies HMAC/mTLS and applies each provider's required failure semantics (§4.3 timeout policy) **per adapter**. - **Fails independently of the lobby and of the control plane** (§4.6 availability). **AR-2 — Central worker (control plane).** A single deployable **monolith** (per Ace's "can be monolithic"), low-QPS, not on the player hot path. `[RESOLVED 2026-07-06 — Ace (Q4): Node/TS, matching the gateway and team stack for a single maintainable codebase; Q6: single instance is fine for PoC, SPOF flagged for v-next.]` Responsibilities: - **Ledger consumer** — consumes the ledger stream (§9.D) and performs the authoritative double-entry Postgres write (the async half of AR-1/Q5). - Admin portal backend & APIs (§9.A). - **Curation** (FE-4) and **catalogue sync/ingest** (§4.5) → writes catalogue/config consumed by the gateway and the FE-2 catalogue endpoint. - **Reconciliation** daily jobs + **stuck-round sweeper** (§4.3) + exceptions queue. - **Statistics/GGR aggregation** (§4.4). - **Config & secrets management** for merchants/providers (source of truth the gateway reads). **AR-3 — Shared state (the seam).** Both planes are stateless-compute over shared stores so the gateway can scale freely: - **Postgres** — the double-entry ledger, identity mappings (§4.5), catalogue, and merchant/provider config. - **Redis** — session tokens, idempotency keys, rate limits, hot config cache. - **Queue/bus `[RESOLVED 2026-07-06 — Ace (Q7): bus in the PoC now; stack proposed in §9.D]`** — carries the ledger-event stream (hot-path capture → worker write), the reconciliation feed, and decoupled work/command queues. Stack proposal: §9.D. **AR-4 — Deployment & availability `[RESOLVED 2026-07-06 — Ace (Q8): AWS, `ap-southeast-1` (Singapore); SLA covers the player experience only — the worker is out of SLA scope as back-office]`.** - Cloud/region: **AWS `ap-southeast-1`** (Singapore) for Thai latency (§4.6); both planes co-located, data stores multi-AZ within the region. - **SLA scope = player experience only.** The 99.9% target (§4.6) applies to the **gateway + lobby + wallet relay** (the player/wallet hot path). The **worker is explicitly excluded** from the SLA. This makes the split's failure-isolation the literal SLA boundary: worker downtime is, by definition, not an SLA breach. - Gateway: **N≥2** stateless replicas across AZs behind an LB (no SPOF; meets 99.9%). - Worker: `[RESOLVED — Ace (Q6): single instance sufficient for PoC]` monolith, **single instance for PoC**. ⚠️ **SPOF — flagged for v-next:** acceptable now only because (a) it is out of SLA scope, (b) jobs are idempotent/restartable, and (c) the ledger stream (§9.D) is **durable and replayable**, so a worker outage delays ledger writes/recon but loses nothing — on restart it drains the backlog. Warm standby / multi-instance consumer group is the first v-next hardening item. - **Failure isolation:** a gateway outage must not take down admin/recon, and a worker outage must not stop gameplay/wallet relay (the gateway keeps serving from cached config and keeps publishing to the durable stream). This is the main payoff of the split — and now the SLA boundary. **AR-5 — Latency guard.** The split must not add hops on the wallet path: the gateway calls providers/merchant directly, does a **sync Redis idempotency check** and a **single async stream publish** (§9.D) — it does **not** write the double-entry ledger inline and does **not** round-trip through the worker for any player-facing request. Net hot-path adds vs a bare relay: ~1 Redis RTT + 1 stream publish, both well inside the ≤50ms p95/hop budget (§4.6). ## 9.C Impact on existing sections (no decisions changed) - **§4.1** three responsibilities now map onto two planes (lobby+relay+auth → gateway; accounting/abstraction control + admin → worker). Diagram in §9.B supersedes the §4.1 sketch **only if approved**. - **§4.4** internal ops portal → promoted to **Admin portal (§9.A)**; merchant portal unchanged (Decision #8). - **Roadmap (§8):** suggest adding a control-plane/data-plane split to **Phase 0 Foundations**, and the Admin portal read surfaces to **Phase 1** (writes, if any, to Phase 2). `[PROPOSED]` ## 9.D Queue/bus stack proposal `[PROPOSED 2026-07-06 — Ace asked me to propose (Q7)]` Ace chose an **async, queue-backed ledger** (Q5) and wants the **bus in the PoC now** (Q7), citing **real volume**. Constraints that drive the choice: AWS `ap-southeast-1` (Q8); **per-entity ordering** (a round's bet must be written before its win/rollback); **durable + replayable** (so a single-instance worker outage loses nothing — AR-4 — and so the ledger can be rebuilt/re-reconciled); **high sustained throughput**; and **low ops** for a PoC with one worker consumer. **How async stays wallet-integrity-safe (reconciles the Q5 tension I raised).** The **merchant wallet is the source of truth**, not DPPlay's ledger — DPPlay's ledger is an independent *mirror* for reconciliation/stats (§4.4). So integrity is protected on the hot path by the **synchronous Redis idempotency check** (exactly-once *relay* to the merchant), while the *accounting write* is what goes async. We never trust the transport for exactly-once: the worker's ledger write is **idempotent** (idempotency key + Postgres unique constraint), so **at-least-once** delivery + idempotent consumer = effectively exactly-once. This is the standard shape for a financial ledger and directly serves the **zero-wallet-integrity-incident** success metric (§6). **Recommended stack (all AWS-native, `ap-southeast-1`):** 1. **Ledger event stream → Amazon Kinesis Data Streams (on-demand capacity).** *Primary backbone.* The hot-path capture target and the recon feed. - **Ordering:** partition key = DPPlay round (or wrapped player ref) → per-entity order preserved. - **Replayable:** retention up to 365 days → ledger rebuild + re-reconciliation, and the worker drains from the last checkpoint after any outage (backs AR-4's "loses nothing" claim). - **On-demand mode:** auto-scales to real volume with **no shard babysitting** — low ops for the PoC. - **At-least-once** delivery; safe because the consumer is idempotent (above). 2. **Work / command queues → Amazon SQS (standard) + DLQ.** For discrete jobs, not the ordered ledger log: stuck-round sweeper tasks (§4.3), reconciliation job dispatch, provider-callback retries. DLQ isolates poison messages for the admin portal (§9.A). 3. **Operational fan-out → Amazon EventBridge.** Routing of operational events (reconciliation-drift alerts, health signals → §4.6 observability). Not a financial log; keep money events on Kinesis. **Explicitly deferred — Amazon MSK / Kafka.** More powerful (multi-consumer-group replay, higher ceilings) but **heavy ops** (cluster to run) and overkill for a single-worker PoC. Documented as the **scale path**: adopt when the worker splits into multiple consumer groups or throughput outgrows Kinesis on-demand. `[PROPOSED]` > **One integrity caveat to accept with async (flagged, not hidden):** if the gateway > successfully relays to the merchant but the process dies *before* the stream publish > lands, DPPlay's ledger would miss a transaction the merchant did apply. Mitigation: > publish-before-respond ordering + the **daily reconciliation** (§4.4) against the > merchant/provider reports catches any such gap and files it to the exceptions queue. > The merchant wallet is never wrong; only DPPlay's mirror can lag, and recon closes it. --- # 10. Open questions → **ANSWERED 2026-07-06** `[was PROPOSED 2026-07-06]` > Ace answered all nine on 2026-07-06 (Slack #dplay-general). Each is marked > **✅ ANSWERED** below with the decision; the durable decisions are logged in **§11**. **Admin portal** - **Q1 — Users & auth.** ✅ **ANSWERED — Ace:** Ops **5–10**, Finance **1–3**, Game managers **1–5**, UX & Data analysts **10–20** (largest cohort). Roles → AD-4; decision **D15**. - **Q2 — Read-only vs actions in PoC.** ✅ **ANSWERED — Ace:** **read-only for initial scope; add actions iteratively later.** → AD-3; decision **D16**. - **Q3 — Merchant portal relationship.** ✅ **ANSWERED — Ace:** merchant portal is a **separate webapp** (distinct from the internal admin portal). → decision **D17**. **Decentralised architecture** - **Q4 — Stack for the two services.** ✅ **ANSWERED — Ace:** **gateway = Node/TS** for maintainability (team stack is TypeScript). Worker follows the same stack for one maintainable codebase (AR-2). → decision **D18**. - **Q5 — Ledger write on the hot path.** ✅ **ANSWERED — Ace:** **async, via a queue — real volume expected.** (Overrides my synchronous lean.) Integrity preserved via sync Redis idempotency on the relay + idempotent worker write; see AR-1 & §9.D. → decision **D19**. - **Q6 — Worker SPOF tolerance.** ✅ **ANSWERED — Ace:** **single worker is sufficient for PoC**; SPOF risk noted for next versions. → AR-4; decision **D20**. - **Q7 — Queue/bus now or later.** ✅ **ANSWERED — Ace:** **bus now**, and asked me to propose the stack → **§9.D** (Kinesis ledger stream + SQS work queues + EventBridge fan-out; MSK deferred). → decision **D21**. - **Q8 — Availability / region.** ✅ **ANSWERED — Ace:** **AWS, `ap-southeast-1`**; **worker out of SLA scope — SLA covers player experience only.** → AR-4; decision **D22**. - **Q9 — Provider callback ingress.** ✅ **ANSWERED — Ace:** **provider IP gating at the LB.** Per-adapter failure semantics still captured at the gateway. → AR-1; decision **D23**. --- # 11. Decisions log — PROPOSALS layer `[Ace-approved 2026-07-06]` Extends the v0.4 Decisions log (§7, untouched). These capture Ace's answers to the §10 questions. **D19 overrides my earlier synchronous-ledger lean** — recorded openly per governance (no silent overwrite). | # | Topic | Decision | Status | |---|---|---|---| | 15 | Admin-portal users & roles | Ops 5–10, Finance 1–3, Game managers 1–5, UX & Data analysts 10–20 (largest cohort). RBAC roles per AD-4. | Decided | | 16 | Admin-portal scope | **Read-only** for initial PoC; actions added iteratively later (AD-3). | Decided | | 17 | Merchant portal | **Separate webapp**, distinct from the internal admin portal (different trust boundary). | Decided | | 18 | Service stack | **Gateway = Node/TS**; **worker = Node/TS** (team stack is TypeScript; one maintainable codebase). Lobby stays SvelteKit (§7 #1). | Decided | | 19 | Ledger write on hot path | **Async via queue** (real volume). Hot-path integrity via sync Redis idempotency + idempotent worker write (AR-1, §9.D). *Overrides Kiri's prior synchronous lean.* | Decided | | 20 | Worker instances | **Single instance for PoC**; SPOF explicitly accepted (out of SLA), flagged as first v-next hardening item (AR-4). | Decided | | 21 | Queue/bus | **Adopt in PoC now.** Proposed stack (§9.D): Kinesis Data Streams (ledger), SQS+DLQ (work queues), EventBridge (ops fan-out); MSK/Kafka deferred as scale path. | Decided (stack proposed, pending approval) | | 22 | Cloud / region / SLA | **AWS `ap-southeast-1`** (Singapore). **SLA covers player experience only** (gateway + lobby + wallet relay); **worker excluded** as back-office (AR-4). | Decided | | 23 | Provider ingress | Provider **IP gating at the LB**; gateway still verifies HMAC/mTLS and applies per-adapter failure semantics (AR-1, §4.3). | Decided | | 24 | §9.D queue stack | Kinesis (ledger) + SQS+DLQ (work) + EventBridge (fan-out); MSK deferred. **Approved by Ace 2026-07-06** ("looks good"). | Decided | | 25 | §12 AWS inventory | PoC AWS footprint (§12) accepted as the Phase-0 target. **Approved by Ace 2026-07-06.** | Decided | | 26 | Phase 0 kickoff | Ace authorised drafting **Phase 0** (2026-07-06) → plan in `PHASE0.md`. Build begins only after the Phase-0 plan is approved. | Plan drafted — needs approval | | 27 | **PoC runtime = single machine** | Everything runs on **one machine**, with **Docker to emulate the decentralised split** (gateway/worker/stores as separate containers). **This holds until Phase 3** (after all shortlisted providers are integrated); traffic is mild until then. **Approved by Ace 2026-07-06.** | Decided | | 28 | **AWS deploy deferred** | We provision the managed AWS footprint (§12) **only after we've tested and are satisfied locally** — i.e. **post-Phase 3**. §12 remains the eventual target; CDK is authored/kept in sync but **not deployed** during PoC. | Decided | | 29 | **Phase 0 delivery shape** | Phase 0 runs as **sequential stages with implement → review → revise loops** (not parallel workstreams), to avoid big-bang integration. See `PHASE0.md`. **Approved by Ace 2026-07-06.** | Decided | | 30 | Phase-0 tooling (P0-D1…D5) | **D1 IaC = AWS CDK (TS)** · **D2 CI = GitHub Actions** · **D3 migrations/ORM = Drizzle** · **D4 merchant wallet = real KZWL UAT** (env available) · **D5 session token = signed JWT**. **Approved by Ace 2026-07-06.** | Decided | | 31 | **Phase 0 = lobby-first** | Start Phase 0 with the **lobby frontend** — wireframe the UI and document the UX **before** backend wiring. **Approved by Ace 2026-07-06.** See `PHASE0.md`. | Decided | | 32 | **Doc separation of concerns** | **Product details (UX, flows, wireframes) live in the product spec (this `SPEC.md`, §3 + §13).** `PHASE0.md` (and future phase docs) hold **only phase-specific implementation details** and reference the SPEC for product intent. **Set by Ace 2026-07-06.** | Decided | | 33 | Local hosting | The Docker setup is **hosted locally on this machine** for now (Docker installed 2026-07-06). Same as D27 (single machine) — no remote host in PoC. | Decided | --- # 12. AWS resource inventory — **eventual target** `[Approved as target 2026-07-06]` > **⚠️ Deployment timing (D27/D28):** this managed AWS footprint is the **eventual > target**, provisioned **only after we're satisfied with the local setup — post-Phase 3**. > **During PoC everything runs on ONE machine**, with **Docker Compose emulating the > decentralised split** and **LocalStack** standing in for Kinesis/SQS/EventBridge (and > local Postgres/Redis containers). The CDK app (D30) is authored and kept in sync > against this inventory but **not deployed** until then. Each row below maps to its > **local PoC equivalent** so the CDK and the Docker setup stay 1:1. Region **`ap-southeast-1`** (Singapore, D22), multi-AZ within region. Derived from the architecture (§9.B), the queue stack (§9.D), and the NFRs (§4.6). "PoC" = the local Docker equivalent now; "AWS" = the managed target for post-Phase 3. **AWS resource → local PoC equivalent (single machine, Docker):** | AWS (target) | Local PoC equivalent | |---|---| | ECS Fargate gateway ×2 / worker ×1 | separate `gateway` / `worker` **containers** (gateway can run 2 replicas + a local LB to emulate scale-out) | | ALB + WAF (IP allowlist) | **Traefik/Nginx** container as LB; IP allowlist via config | | RDS/Aurora PostgreSQL | **Postgres container** | | ElastiCache Redis | **Redis container** | | Kinesis / SQS / EventBridge | **LocalStack** container (kinesis, sqs, events) | | S3 + CloudFront | LocalStack **S3** + local static serve | | Secrets Manager / KMS | `.env` + local secrets file (dev only) → real services at AWS | | CloudWatch / SNS / X-Ray | local logs + a lightweight metrics stack (optional) | | ECR | local Docker image builds | **Compute** - **ECS Fargate — gateway service** (data plane, Node/TS): service with **≥2 tasks across AZs**, target-tracking autoscaling on CPU/latency. Stateless (D18, AR-1/AR-4). - **ECS Fargate — worker service** (control plane, Node/TS): **1 task for PoC** (D20 SPOF, out of SLA D22). Runs ledger consumer, recon/sweeper, aggregation, admin API. - **ECS Fargate — lobby SSR** (SvelteKit) *or* static export to S3+CloudFront. For PoC I lean **static build → S3+CloudFront** (cheapest, fits <1.5MB budget §5); a small Fargate SSR service only if we need server-side rendering. - **ECR** — container image registry for the three services. **Networking & edge** - **VPC** — public + private subnets across ≥2 AZs; **NAT Gateway** for private egress. - **Application Load Balancer (ALB)** — TLS termination, routes to gateway; supports the HMAC/mTLS + failure-semantics handling at the gateway (§4.3, AR-1). - **AWS WAF** — **provider IP allowlist at the LB edge** (D23/Q9) + basic rate rules. - **CloudFront** — CDN for lobby assets, catalogue thumbnails; low-latency delivery. - **Route 53** — DNS. **ACM** — TLS certificates. **Data stores** - **RDS for PostgreSQL, Multi-AZ** (or **Aurora PostgreSQL** for the scale path) — the double-entry ledger, identity mappings (§4.5), catalogue, merchant/provider config. - **ElastiCache for Redis, Multi-AZ** — session tokens, **hot-path idempotency keys** (AR-1/Q5), rate limits, hot config cache. **Messaging (§9.D)** - **Kinesis Data Streams (on-demand)** — the ledger event stream (hot-path capture → worker write; replayable for rebuild/recon). - **SQS (standard) + DLQ** — work/command queues: sweeper, recon dispatch, callback retries. - **EventBridge** — operational event fan-out (alerts, health signals). **Security & secrets** - **Secrets Manager** — provider/merchant credentials, DB creds (§4.5 abstraction). - **KMS** — encryption at rest for PII/ledger (§4.6), key management. - **IAM** — least-privilege task roles per service. **Observability (§4.6)** - **CloudWatch** — metrics, logs, dashboards (per-merchant/provider error, latency, stuck rounds), **alarms on reconciliation drift**. - **SNS** — alarm notifications (paging/Slack). - **X-Ray** *(optional)* — hot-path tracing. **Storage** - **S3** — lobby static assets, catalogue images, ingested provider report files for reconciliation, backups. > **Not yet needed (deferred):** Amazon MSK/Kafka (scale path beyond Kinesis, D21); > worker warm-standby / multi-AZ (SPOF hardening, D20); cross-region anything (single > region confirmed, D22). CI/CD (CodePipeline/CodeBuild vs GitHub Actions) is a team > tooling choice, not fixed here. --- # 13. Lobby UX & wireframes `[PRODUCT — PROPOSED 2026-07-06, iterating]` > **Home of product/UX detail** (SPEC D32). This section expands the base §3 Frontend > product intent into concrete screens, flows, and wireframes for the PoC lobby. > Implementation lives in `PHASE0.md`, which references this section — it does **not** > restate product detail. Brand direction: §3.3 (charcoal/near-black, gold primary, red > secondary, cream highlights; Dumpling mascot; 福/ingot/coin motifs). > > **Visual wireframe (interactive, for iteration):** > ## 13.1 Design constraints (from §3, §5) - **Mobile-first** 360px → up; iframe/webview-safe **and** standalone tab (§3.1/FE-3). - **Lightweight:** < 1.5 MB initial load (§5); high-latency tolerant. - **Thai + English** (locale from launch params); Thai script support (§3.3). - **In-context game launch & return** — the player returns to the *lobby*, not the merchant site (FE-5); lobby exit → merchant return URL (§4.2). ## 13.2 Screen inventory (PoC) 1. **Splash / loading** — mascot hero, brand load state (session validate). 2. **Lobby home** — top bar, featured hero, category rows, game grid. 3. **Search & filter** — query + category chips over the grid. 4. **Game view** — provider game in-context with a persistent **← Lobby** affordance. 5. **States** — provider unavailable · game unavailable · session expired (→ re-entry to merchant) · empty search (mascot empty state) · offline/slow. ## 13.3 Core flow ``` merchant tile → launch (token) → [Splash] → [Lobby home] → tap game → [Game view] ── back ──▶ [Lobby home] → exit lobby → redirect to merchant return URL (token expiry anywhere → [Session expired] → back to merchant) ``` ## 13.4 Wireframes (mobile, 360px) **Lobby home** ``` ┌────────────────────────────┐ │ 🥟 DumplingPlay 🔍 TH ▾│ ← top bar: logo · search · locale ├────────────────────────────┤ │ ╭──────────────────────╮ │ │ │ ✨ 福 featured hero │ │ ← rotating featured / mascot banner │ │ "Fortune awaits" │ │ │ ╰──────────────────────╯ │ │ Featured see all ▸ │ ← category row (horizontal scroll) │ ┌────┐┌────┐┌────┐┌────┐ │ │ │game││game││game││game│ │ │ └────┘└────┘└────┘└────┘ │ │ Slots see all ▸ │ │ ┌────┐┌────┐┌────┐┌────┐ │ │ │ ││ ││ ││ │ │ │ └────┘└────┘└────┘└────┘ │ │ Fishing see all ▸ │ │ ┌────┐┌────┐┌────┐┌────┐ │ │ │ ││ ││ ││ │ │ │ └────┘└────┘└────┘└────┘ │ │ Instant / Crash see all ▸│ │ ┌────┐┌────┐┌────┐┌────┐ │ │ └────┘└────┘└────┘└────┘ │ └────────────────────────────┘ ``` **Search & filter** ``` ┌────────────────────────────┐ │ ← 🔍 [ search games… ] │ │ [All][Slots][Fishing][Crash]│ ← category chips (scroll) ├────────────────────────────┤ │ ┌────┐┌────┐┌────┐ │ ← results grid (2–4 cols responsive) │ │ ││ ││ │ │ │ └────┘└────┘└────┘ │ │ ┌────┐┌────┐┌────┐ │ │ └────┘└────┘└────┘ │ └────────────────────────────┘ ``` **Game view (in-context)** ``` ┌────────────────────────────┐ │ ← Lobby Zenith · game│ ← persistent return; provider label ├────────────────────────────┤ │ │ │ provider game │ ← iframe, fills viewport │ (full area) │ │ │ └────────────────────────────┘ ``` **States (provider/game unavailable · session expired · empty)** ``` ┌────────────────────────────┐ ┌────────────────────────────┐ │ ← Lobby │ │ │ │ │ │ 🥟 (sad pose) │ │ 🥟 (support pose) │ │ "Your session has ended" │ │ "This game is taking a │ │ [ Return to site ] │ ← re-entry to merchant │ short break" │ │ │ │ [ Back to lobby ] │ └────────────────────────────┘ └────────────────────────────┘ provider/game unavailable session expired ``` ## 13.5 Interaction & responsive rules - **Grid:** 2 cols @360px → 3 @tablet → 4–6 @desktop; lazy-load images (FE-2 tiles). - **Category rows:** horizontal scroll on mobile; "see all" → filtered grid. - **Return affordance:** always visible in Game view; hardware/browser back = ← Lobby. - **Loading:** skeleton tiles; mascot only on full-screen loads, not per-tile. - **Locale:** switch in top bar; persists for the session (from launch param default). - **Deferred (P2, §3.2 FE-6):** favourites, recents, promos, jackpot tickers. --- ## Changelog - **2026-07-06 — v0.8 (Kiri Zynk).** Ace: **lobby-first** replan (D31) + **doc separation** (D32 — product/UX in SPEC, implementation in phase docs) + **local Docker hosting** (D33, Docker installed on this machine). Added **§13 Lobby UX & wireframes** (product home: screens, flow, mobile wireframes, interaction rules) with an interactive visual wireframe. `PHASE0.md` rewritten **lobby-first and implementation-only**, referencing §3/§13 for product intent. - **2026-07-06 — v0.7 (Kiri Zynk).** Ace review of the Phase-0 draft. (1) Added the **Companion plan documents** index (top) so `PHASE0.md` is no longer an orphan — and added workspace TOOLS.md **rule 4 (no orphan documents)** so this never recurs. (2) Recorded **D27–D30**: PoC runs on **one machine with Docker emulating the split** until **Phase 3**; **AWS deploy deferred** to post-Phase 3 (§12 reframed as *eventual target* with a local-equivalent mapping); Phase 0 restructured into **staged implement→review→revise loops**; and P0 tooling fixed (**CDK, GitHub Actions, Drizzle, real KZWL UAT, signed JWT**). `PHASE0.md` rewritten to match. - **2026-07-06 — v0.6.1 (Kiri Zynk).** Added **§12 AWS resource inventory** (Ace request): itemised the PoC AWS footprint across compute (ECS Fargate ×3, ECR), edge (ALB, WAF, CloudFront, Route 53, ACM), data (RDS/Aurora Postgres, ElastiCache Redis), messaging (Kinesis, SQS+DLQ, EventBridge), security (Secrets Manager, KMS, IAM), observability (CloudWatch, SNS, X-Ray), and S3. Marked `[PROPOSED]`. - **2026-07-06 — v0.6 (Kiri Zynk).** Ace answered all nine §10 questions. Folded the answers in: marked Q1–Q9 **✅ ANSWERED**; annotated the affected AR-*/AD-* points `[RESOLVED 2026-07-06]`; added **§9.D queue/bus stack proposal** (Kinesis + SQS + EventBridge; MSK deferred) per Ace's request in Q7; reworked AR-1/AR-2/AR-5 for the **async, queue-backed ledger** (Q5) with the wallet-integrity reconciliation; and added **§11 decisions log (D15–D24)**. **D19 overrides my earlier synchronous-ledger lean — logged openly, not silently overwritten.** §7 (v0.4 decisions) still untouched. - **2026-07-06 — v0.5 (Kiri Zynk).** Stored the v0.4 base spec supplied by Ace, verbatim. Added **§9 Proposals** (9.A Admin portal, 9.B decentralised control/data-plane architecture with central worker + horizontally-scalable gateway, 9.C impact notes) and **§10 Open questions (Q1–Q9)**, all marked `[PROPOSED]` and pending approval. No entry in the Decisions log (§7) was altered.