<!--
Purpose: Host system architecture and launch ecosystem — MMRY Cloud + SensAffect
Last modified: 2026-09-09
By: Cursor Grok 4.6
Completeness: 96
-->

# Architecture — what we are launching

This repository is **one host**: Node.js Express + PostgreSQL. It serves every MMRY door, the workspace, Learn, and the memory API. SensAffect is a **separate service**. They share the Memory Atom contract. They do not share a runtime.

| Layer | Choice | Role |
|-------|--------|------|
| Runtime | Node.js 20+ | Single Express process (`server.js`) |
| Data | PostgreSQL 15+ (local 17 in Compose) | System of record; schema `db/schema.sql` at boot |
| Sessions | `connect-pg-simple` · cookie `mmry.sid` | Auth; CSRF on writes |
| UI | Static `dist/` | Landings, workspace, Learn |
| Recall | PostgreSQL full-text (`search_document`) | Cite or `insufficient_evidence`. No LLM, no vectors |
| Deploy | Render Blueprint `render.yaml` | Web `mmry-cloud` + DB `mmry-postgres` |
| Local | Docker Compose or native `PORT=3001` | Health `GET /api/health` |

Out of scope for this launch: vector/LLM recall as SSOT, clinical certification, Pro tenancy provisioning, `mmry.help` as a live product.

---

## 1. Ecosystem (two services)

```mermaid
flowchart TB
  subgraph contract["Memory Atom contract — Memory + Feeling + Context"]
    M[Memory]
    F[Feeling]
    C[Context — user authorised]
  end

  subgraph mmry["MMRY service — this host"]
    Cloud["mmry.cloud /"]
    Digital["mmry.digital /digital"]
    Chat["mmry.chat /chat"]
    Pro["mmry.pro /pro"]
    Learn["/learn"]
    WS["/workspace"]
    API["/api/*"]
  end

  subgraph sa["SensAffect service — independent"]
    SAHome["sensaffect.com"]
    SALearn["Learn"]
    SAStd["Memory Atom Standard"]
    Omni["Omni-CNN kit"]
    Audio["SensAudio"]
  end

  Cloud --> API
  Chat --> API
  WS --> API
  Digital -.-> SAStd
  Learn -.-> SALearn
  Omni -.-> API
  M --> Cloud
  F --> SAHome
  C --> Cloud
  C --> SAHome
```

| Service | Stands alone as | Does not require |
|---------|-----------------|------------------|
| **MMRY** | Capture, cite or abstain, authority, receipts, export | SensAffect. Feeling may stay empty. |
| **SensAffect** | Sensors, VAD, validation, proximity lab, Omni-CNN | This PostgreSQL. A record can live elsewhere. |

**Optional bundle:** citeable memory + labelled interpretation that cannot overwrite it + context under **current** authority. Cross-links only — no shared session, no shared database.

Public map: http://localhost:3001/architecture

---

## 2. Host system (this package)

One process. One database. Many product URLs that are **paths** today and **custom domains** when DNS is attached.

```mermaid
flowchart LR
  Browser --> Express
  Express --> Static["dist/ static doors"]
  Express --> APIs["JSON APIs"]
  APIs --> PG[(PostgreSQL)]
  Express --> PG
  Express --> Zip["Omni-CNN zip from vendor/"]
```

### Process

1. Load `.env` (`DATABASE_URL`, `SESSION_SECRET` ≥32 chars, `PORT`, `APP_ORIGIN`).
2. Connect `pg` pool. Apply `db/schema.sql` (idempotent).
3. Package Omni-CNN zip if missing (`scripts/ensure-omni-zip.mjs`).
4. Helmet CSP (`scriptSrc 'self'`), compression, JSON 256kb, rate limits, sessions in `user_sessions`.
5. Listen. Health: `SELECT 1`.

### Persistence (account-scoped)

| Table | Job |
|-------|-----|
| `users` | Email, bcrypt, display name |
| `memories` | Title, content, SHA-256 `source_hash`, tier, FTS on title+content only |
| `feeling_interpretations` | Optional VAD / word. Must not rewrite content |
| `context_items` | Situation. Origin confirmed / inferred / recorded |
| `evidence_files` | ≤10 MB, hashed |
| `authority_events` | Append-only allow/deny |
| `intent_records` | What was asked |
| `recall_traces` | Cite or abstain proof |
| `receipts` | Execution of a turn |
| `audit_events` | IP hashed with session secret |

### Security (host)

- CSRF header `x-csrf-token` on writes
- Parameterised SQL + `user_id` on every owned query
- Authority never updated in place
- Feeling is not an FTS index
- Omni-CNN `embedding` may sit on `metadata.imprint`; **not used for recall**

### Deploy topologies

| Environment | Shape |
|-------------|--------|
| This machine | Native Node `PORT=3001`, local `mmry` database |
| Docker | Compose `web` + `db` on 3000 |
| Render | `mmry-cloud` web + `mmry-postgres`; set `APP_ORIGIN` |

---

## 3. Each site’s architecture

Product domains are **doors**. Until custom DNS is live they are routes on this host. Architecture of each door is the job, the surfaces, and the APIs it actually uses.

### mmry.cloud — Store

| | |
|--|--|
| Path | `/` landing · `/workspace` product · `/login` identity |
| Job | Hosted system of record |
| UI | Cluster figure, VIVID→FORGOTTEN, capture dialog |
| Writes | `POST /api/memories`, evidence, authority, export |
| Reads | `GET /api/memories`, recall, session |
| Does not | Publish the spec, run chat turns as the homepage, provision Pro |

```mermaid
flowchart LR
  Landing["/"] --> WS["/workspace"]
  WS --> Mem["memories + sides"]
  WS --> Auth["authority_events"]
  WS --> Exp["GET /api/export"]
```

### mmry.digital — Standard

| | |
|--|--|
| Path | `/digital` |
| Job | Public contract. Nothing typed here is stored as your past |
| UI | Three sides, nine chapters (bodies on SensAffect), twin Learn links |
| Runtime | Static. No memory writes |
| Cross | Canonical chapters: `sensaffect.com/pages/memory-atom-standard/` |

### mmry.chat — Talk

| | |
|--|--|
| Path | `/chat` |
| Job | Conversation that cites or abstains. A reply is never the record |
| UI | Example turn when signed out; thread + tools when signed in |
| Writes | `POST /api/chat/turn` → intents, recall, receipts (`detail.surface = chat`) |
| Host | `lib/chat-host.js` greets; `lib/chat-turn.js` routes; `llm: false` |
| Does not | Invent memory. Generation, if added later, only phrases after a cite |

```mermaid
flowchart LR
  Utterance --> Classify["classifyUtterance"]
  Classify --> Greet["host reply"]
  Classify --> Remember["POST /api/memories"]
  Classify --> Recall["POST /api/recall"]
  Recall --> Cite["supported"]
  Recall --> Abstain["insufficient_evidence"]
```

### mmry.pro — Deploy

| | |
|--|--|
| Path | `/pro` |
| Job | Estate desk: tenancy, region, keys, ledger |
| UI | Static offer table |
| Runtime | **Landing only.** Does not provision a dedicated database from this page |
| Launch | Partner conversation (`mailto:`). Same contract as Cloud when an estate exists |

### MMRY Learn — Guides

| | |
|--|--|
| Path | `/learn` · `/learn/recall-lab/` · `/learn/omni-cnn` · `/learn/realseries` · `/learn/realflow` · `/learn/operate` · `/learn/library` · `/learn/emc2` |
| Job | Twin of SensAffect Learn, from the store |
| Samples | Cite-or-abstain lab (content hit / feeling miss / denied authority) |
| Kits | `GET /api/kits` · JS client `/sdks/mmry-js/` · kitchen example `/examples/` |
| Omni-CNN | Zip `/downloads/SensAffect-OmniCNN-v1.zip` — SensAffect model, MMRY attach path |
| RealSeries | Catalog `GET /api/realseries` — Detection, Triggers, Actions. This host is Remember; it does not run RealFuel |
| Library | `GET /api/library` · files under `/library/` — original RealFlow packets, THRPY PDF, EMC² math |
| Operate | `GET /api/operate` — APIs, MCPs, plugins, skills, CLIs. Product MCPs marked needed |
| EMC² | Research page `/learn/emc2`. Cosine undercurrent on THRPY edge. **Not** this host’s recall SSOT |
| RealFlow / Flo | `/learn/realflow` — ancestor lab vs named spine. Not executed here |

### RealSeries (SensAffect reference runtime)

SensAffect Standard names the functions. RealSeries is the already-built reference implementation. MMRY is the Remember beat.

```mermaid
flowchart LR
  D[Detection<br/>RealSense RealFeel] --> T[Triggers<br/>RealTrigger RealFuel]
  T --> A[Actions<br/>RealAction Ambient]
  A --> M[MMRY receipt]
```

RealFeel Ambient may ease UI colour, animation and transition speed from how the user feels that day. Accommodations are reversible, honour reduced-motion, and must not rewrite memory. Public map: http://localhost:3001/learn/realseries

**EMC²** (Emotional Memory Cloud Squared) is THRPY’s silhouette cosine layer. It must not replace PostgreSQL full-text on this host. Live math: `detectUndercurrent` in THRPY core-engine / SensAffect eKG. Some Python `rflow_emc2.py` files are stubs.

### Identity

| | |
|--|--|
| Path | `/login` |
| Job | One account on this origin for Cloud, Chat, Pro, workspace |
| Not | SensAffect SSO. Sister products join as relying parties later — no second password in doctrine |

### mmry.help — planned

Named in product architecture. **Not in this package.** Support stays `mailto:hello@mmry.cloud` until a help host ships.

---

## 4. SensAffect sites (independent)

Not deployed from this repo. Linked for reinforced learning and the optional bundle.

| Site | Job | How this host relates |
|------|-----|------------------------|
| [sensaffect.com](https://sensaffect.com/) | Feeling product (including SensAudio on the home) | Cross-link only |
| [Learn](https://sensaffect.com/pages/learn/index.html) | Build atoms from feeling and context; proximity lab | Twin of `/learn` |
| [Memory Atom Standard](https://sensaffect.com/pages/memory-atom-standard/index.html) | Canonical nine chapters | Twin reading on `/digital` |
| Omni-CNN | Five-modality imprint | Vendor in this repo; zip + `/learn/omni-cnn` attach docs |

Omni-CNN runs **on the developer’s machine** (PyTorch). This host stores `imprint` JSON as a derived feeling. It does not execute the network.

```mermaid
flowchart LR
  Sensors --> Infer["infer.py local"]
  Infer --> JSON["Imprint JSON"]
  JSON --> POST["POST /api/memories capture_surface=omni_cnn"]
  POST --> Feel["feeling_interpretations"]
  POST --> Meta["metadata.imprint"]
  Feel -.->|must not rewrite| Content["memories.content"]
```

---

## 5. Launch matrix

| Surface | In this host | Live at launch | Notes |
|---------|--------------|----------------|-------|
| Cloud landing + workspace | Yes | Yes | Store |
| Digital | Yes | Yes | Spec door; chapter HTML on SensAffect |
| Chat | Yes | Yes | Cite/abstain; no LLM memory |
| Pro landing | Yes | Yes | Desk copy only |
| Pro tenancy | No | No | Design partner |
| Learn + recall lab | Yes | Yes | |
| RealSeries catalog | Yes | Yes | Docs + API; inference not on this process |
| Documents library | Yes | Yes | `/learn/library` · `/library/` files |
| RealFlow / Flo pages | Yes | Yes | Docs only; Flo WS not on this process |
| Operate catalog | Yes | Yes | `/learn/operate` · `/api/operate`; product MCPs needed |
| EMC² research | Yes | Yes | Docs only; cosine not executed here |
| Omni-CNN zip + docs | Yes | Yes | Model is SensAffect |
| mmry.help | No | No | Planned |
| SensAffect.com | No | Independent | Already public |
| Clinical device claim | — | Never this launch | Out of charter |

---

## 6. Cross-links (no runtime coupling)

| From | To |
|------|----|
| Every MMRY footer | SensAffect home, Learn, Standard |
| `/digital` | Nine SA chapters + both Learn paths |
| `/learn` | SA Learn section-for-section |
| `/learn/omni-cnn` | Kit download + SA feeling chapter |
| `/learn/realseries` | RealSeries catalog; SA owns the runtimes |
| `/learn/realflow` | Flo ancestor vs RealFlow spine |
| `/learn/operate` | APIs, MCPs, plugins, skills; product MCPs needed |
| `/learn/library` | RealFlow packets + THRPY PDF |
| `/learn/emc2` | EMC² research; cosine is THRPY, not this FTS |
| Workspace | Standard + Omni-CNN zip |
| SensAffect Learn | (their site) — we cannot edit it from here |

API catalog: `GET /api/kits`, `GET /api/capture-surfaces`, `GET /api/authority/catalog`, `GET /api/realseries`, `GET /api/library`, `GET /api/operate`.
