# Fallback — forking NextGraph to expose the inbox (path not taken) **Status:** not taken — short-circuited by this lib's emulated inbox (`inbox.ts`, see [`simulation.md`](./simulation.md)). Kept as the fallback plan if a native broker inbox ever becomes necessary — chiefly for the crypto anonymity the emulation does not provide (native `from = None` sealed deposit). Current NextGraph does not expose the inbox to the JS SDK: the verifier has no `InboxPost` arm and no wasm helper seals a deposit (see [`nextgraph-current-state.md`](./nextgraph-current-state.md) § Inbox). Two ways to get a real inbox: emulate it (what this lib does) or fork the engine (this document). The emulation was chosen; this is the archived alternative. ## Strategic posture The fork would be **explicitly temporary, not for upstream**. Hypothesis: NextGraph will eventually expose its **own** JS-SDK inbox solution, possibly different. When it lands, drop the fork and adapt. No PR is targeted. This posture is the reason the emulation was preferred: it avoids maintaining a fork + hosting a full stack for a feature the upstream will likely ship differently. ## Layer 1 — the Rust patch: 4 files (vanilla broker) 1. **`engine/net/src/types.rs`** — `InboxMsgContent::Link` is a **unit** variant (stub); give it a payload (or a `Notification` variant) carrying the target NURI + link to the deposited reference. Add an `InboxPost::new_link(...)` builder modeled on `new_contact_details`. `from = None` → anonymity. 2. **`engine/verifier/src/request_processor.rs`** — add the missing command arm (there is no `InboxPost` arm). Ideally a high-level command (`NotifyInbox`) that builds the post on the Rust side (keeps crypto sealing in Rust). Model on `SocialQueryStart`. 3. **`sdk/js/lib-wasm/src/lib.rs`** — expose `pub async fn inbox_post_link( session_id, to_inbox_nuri, to_profile_nuri, link, anonymous)`, modeled on `social_query_start`. 4. **`engine/verifier/src/inbox_processor.rs`** (`process_inbox`) — a receive arm where the owner's own verifier unseals the queued message and applies it inline into the owner's store (model on the `ContactDetails` handler). The app then reads via ORM/SPARQL — no new inbox-read API. Identity resolution (known/anonymous): free via app-side SPARQL (JOIN the sender inbox NURI against `social:contact` docs). Discovering the owner's inbox: embed the owner's `public_store` inbox NURI in the entity document or public profile (the QR profile-share flow already carries it). ## Layer 2 — deployment (from the fork) The patched verifier runs **in the iframe ng-app** (see integration model in [`nextgraph-current-state.md`](./nextgraph-current-state.md)) → **build and self-host `ngd` + the ng-app** from the fork, then rebuild Festipod's `@ng-org/web` with `NG_REDIR_SERVER`/`NG_DEV*` pointing at that ng-app. **No rewrite of the third-party integration** (stays iframe). The broker's inbox routing is already native, but since the patched ng-app is self-hosted, the **whole stack ships from the fork** (one source tree). ### Coolify hosting — 3 web pieces 1. **`ngd`** — stateful WebSocket daemon: container with a **persistent volume** for `--base-path` (RocksDB + keys + PeerId, never wiped), `--domain` mode behind Coolify's Traefik. Build: official Dockerfiles are broken → write a **custom multi-stage Rust Dockerfile** (RocksDB needs llvm/clang). First boot is **interactive** (admin-wallet invitation link) → script via `ngcli` or do it once by hand then persist in the volume. 2. **ng-app** (iframe frontend, patched wasm) — **static build** (`pnpm webfilebuild`). Served statically. 3. **Routing**: one domain serves the ng-app static AND proxies the WebSocket to `ngd`. ### Layer 1 (JS libs) — patched client npm packages Maintain patched client packages, not just the wasm. The generic forwarding *technically* reaches a wasm method without touching the JS, but that's an untyped **hack** — quick test only. To modify for real: - **`@ng-org/web`** — modified anyway (broker URL) → add `inbox_post_link` to the typed API surface + `.d.ts`. - **Streamed methods** (if inbox *reads* ever stream) — need an entry on both sides. For write-only (request/response) — unneeded. - **`@ng-org/orm`** — only if inbox writes join the ORM flow. Otherwise unneeded. ## Layer 3 — consumer application integration Exposing the method is not enough; the consumer application must model the entity + its inbox NURI, write the registration, deposit into the host inbox, and read/resolve notifications. Several of these are already done in the shared-wallet emulation (registration wired on the emulated `inbox.post`), which is precisely why this fork was not needed. ## Why this fallback still matters The emulated inbox stores `from = null` as *absence of a triple*; it does not seal deposits, so it does not provide the target's crypto anonymity. If a consumer application needs true anonymous-but-verifiable deposits to a non-connected host, only a native inbox (`from = None` sealed) delivers it — and this fork is the route. Until then, the emulation is sufficient.