# V1 Backend & System Gap Analysis — 2026-05-30

**Scope.** This document broadens the V1 analysis **beyond the studio frontend**
(already covered by `V1_STUDIO_SURFACE_GAP_ANALYSIS_2026-05-30.md` and
`V1_SPEC_COVERAGE_MATRIX_2026-05-30.md`) to the dimensions those documents did
not systematically cover: **all product domains' backend services, the BFF route
surface, the messaging/notification chains, the governance/trust-&-safety
cascades, the LMS flows, the deployment tiers, and the external provider
integrations.**

**Method.** Six independent read-only sweeps of the repository (`libs/*`,
`apps/*`, `services/*`, `docker/`, `V1/`, BFF route registry) plus the
deployment requirements doc. Findings are file-path-anchored. This is an
**analysis + gap register** (Phases 1–2 of the V1 goal), not an implementation
turn.

---

## 0. Domain-name correction (Phase 1 finding)

The goal text names six domains: _"Isis, Hathor, Metis, Khemet, Thoth, Horus."_
Systematic inspection of `V1/features.md` + `libs/*` shows:

| Goal name  | In repo? | Note                                                         |
| ---------- | -------- | ------------------------------------------------------------ |
| Isis       | ✅       | Generation control plane (55 libs)                           |
| Hathor     | ✅       | Narrative / world authoring (17 libs)                        |
| Metis      | ✅       | Education / LMS substrate (24 libs)                          |
| **Khemet** | ❌       | **Not a V1 domain** — no `libs/khemet`, no features.md entry |
| **Thoth**  | ❌       | **Not a V1 domain**                                          |
| **Horus**  | ❌       | **Not a V1 domain**                                          |

The **actual** V1 domain model is ~17 domains, not 6. Treating the analysis as
"6 domains incl. Khemet/Thoth/Horus" would mis-scope it. Real set:

- **Customer-facing (6):** Tara (contemplative practice), Arete (goals/habits),
  Veritas (grounded stories/claims), Nyx (sky events), Nisaba (scholarly
  passages), Metis (education).
- **Platform substrates (5):** Sophia (grounding/citations), Iris (assistant
  memory/identity), Psyche (real-time voice/avatar runtime — largest, 135 libs),
  Lilith (tone/safety policy), Isis (governed generation).
- **Studio/support substrates (6):** Aja (embodied instruction), Yemaya
  (rendering), Themis (academic integrity), Bellona (engine bridges), Hathor
  (narrative), Neith (inverse modeling — 67 libs).

14 of 17 have runnable services under `apps/`; **Nisaba, Themis, Neith are
libs-only** (no service/app composition root yet).

---

## 1. BFF route surface (the integration spine)

The Fastify BFF (`apps/oshun/bff/src`) registers **~115 route modules** (~400
endpoints): roughly **156 admin-scoped** (`/v1/admin/*`) and **242
customer-facing** (`/v1/*`) plus ~10 infra/health.

**Real, domain-library-backed coverage:**

- **Admin is heavily invested and real** — 25+ `admin-isis-*` modules over real
  `@isis/*` libraries + durable/in-memory stores (the 31 real-algorithm studio
  pages wired this program live here), plus durable audit log, bulk ops,
  developer portal, integrations registry.
- **Customer domains with real routes (6):** Nisaba (`/v1/nisaba/*`, real state
  store), Nyx, Arete, Veritas (real adapters w/ circuit breakers), and
  Tara/Metis (real adapters but **aggregation-only** — see gap).

**Gaps:**

- **G-BFF-1 (P1):** Several documented customer journeys are served by
  `domain-stubs.ts` fixtures, not real adapters: **Sophia**
  (`/v1/sophia/answer`), **Psyche** (`/v1/psyche/session`), **Themis**
  (`/v1/themis/appeals`), **Safety** crisis resources, **Payments**,
  **Tenants/SCIM**. Real domain libs exist for most; they are not wired into the
  BFF request path.
- **G-BFF-2 (P2):** **Tara** and **Metis** have working domain adapters but **no
  dedicated `/v1/tara/*` or `/v1/metis/*` routes** — only `/v1/home` /
  `/v1/continue` aggregation. Customer deep-links into those domains have no
  surface.
- **G-BFF-3 (P2):** `v6.ts` and desktop/wearable/telegram delivery routes return
  hardcoded `v6BffStateStore` data.

---

## 2. Messaging / notification chains

`libs/oshun/messaging-channels` implements **8 channels with real transports**
(in-app, email/SendGrid, SMS/Twilio, push/FCM, WhatsApp/Meta, Slack, Discord,
Telegram). Delivery is **fully wired + idempotent** (`runReminderCycle` →
`deliverDispatchedMessage` → real provider HTTP) and **in-app delivery always
works without any provider creds** (44d59c05d5).

**Gaps:**

- **G-MSG-1 (P1):** The **4 reminder triggers** (V3 session, streak/habit,
  assignment/due-date, content-drop) exist as pure producers
  (`reminder-producers.ts` → `produceAllScheduledReminders`) but **no live
  producer/cron queries domain state and feeds them**. They're only invoked in
  tests. To go live: a scheduled worker must query upcoming sessions / at-risk
  streaks / due assignments / scheduled drops and POST to
  `/v1/reminders/schedule`.
- **G-MSG-2 (P1):** The **reminder worker is composed but not deployed as a
  process** — cycle logic exists, no long-running scheduler in the deploy
  topology.
- **G-MSG-3 (P3):** External channels require per-channel env creds
  (`OSHUN_SENDGRID_API_KEY`, `OSHUN_TWILIO_*`, `OSHUN_FCM_*`,
  `OSHUN_WHATSAPP_*`, `OSHUN_SLACK_BOT_TOKEN`, `OSHUN_DISCORD_BOT_TOKEN`).
  Documented; fail-closed.
- **G-MSG-4 (P3):** Metis sends notifications via a **separate Python Celery
  path** (`services/metis/.../notifications.py`) not connected to the TS
  messaging lib — two notification systems.

---

## 3. Governance / trust-&-safety cascades

Eleven cascades inspected. The pattern: **domain algorithms are real and
substantial; wiring into the BFF request→decision→action flow is uneven.**

| Cascade                                         | Real? | Wired end-to-end? | Note                                                                                                  |
| ----------------------------------------------- | ----- | ----------------- | ----------------------------------------------------------------------------------------------------- |
| Retraction (Veritas)                            | ✅    | ✅                | Event-bus worker + durable; full pipeline                                                             |
| Accountability / audit log                      | ✅    | ✅                | Append-only Postgres `admin_audit_event`                                                              |
| Crisis frame                                    | ✅    | ✅                | Runtime started at boot                                                                               |
| Abuse protection (rate-limit)                   | ✅    | ✅                | Redis-durable; ~68 routes; **no escalation**                                                          |
| Retention / deletion                            | ✅    | 🟡                | Admin route evaluates single artifacts; **no continuous scanner job**                                 |
| Content moderation                              | ✅    | 🟡                | Queues in-memory; safety route uses a _different_ path (dataset-curator), not the moderation workflow |
| Model governance (IP/license/commercial)        | ✅    | 🟡                | 70+ real modules; **not enforced** at upload/deploy — policy checks run in isolation                  |
| Takedown (DMCA/counter-notice/repeat-infringer) | ✅    | ❌ island         | `libs/aphrodite/content-takedown` — no BFF route                                                      |
| Account protection (ATO/credential-stuffing)    | ✅    | ❌ island         | `anomaly-detection-service` never instantiated by auth                                                |
| Chargeback / fraud                              | ✅    | ❌ island         | Detection rules configured; no payment-event trigger                                                  |
| Achievements / gamification                     | ✅    | ❌ island         | `libs/aglaea/gamification` full; no event listener awards them                                        |

**Gaps:**

- **G-GOV-1 (P1):** Five cascades are **real-but-islanded** (takedown, account
  protection, chargeback, achievements, and model-governance enforcement). The
  algorithms pass their own tests but nothing triggers them at runtime. (NB: the
  earlier "achievements 404 fixed" + "takedown cascade fixed" notes refer to
  _route-not-found_ fixes; the deeper **event-trigger wiring** is still absent.)
- **G-GOV-2 (P2):** Retention has no scheduled scanner; moderation route
  bypasses the moderation workflow.

---

## 4. LMS flows (Metis)

Strong here. **LTI 1.3 + LTI Advantage (NRPS/AGS) and SCORM 1.2/2004 are real
and wired end-to-end** (`@oshun/inbound-integrations`, BFF `/v1/tenant/lms/*`):
OIDC login→launch, JWS id_token verification against platform JWKS, AGS score
posting, full SCORM RTE state machines (24 tests). Per-tenant connectors come
from `OSHUN_LMS_CONNECTORS`.

**Gaps:**

- **G-LMS-1 (P1):** **OneRoster is dry-run only.** `dryRunOneRosterImport` +
  `diffOneRosterSnapshots` are real, but the **apply/commit path is not
  implemented** — `oneroster-route.ts` comments it as "a separate store-backed
  step a deployment provides." No commit route, no roster state machine wired.
- **G-LMS-2 (P2):** Course CRUD lives in the **out-of-repo Python backend**; the
  BFF/gateway proxies it. No course-publish trigger from the API in-repo.

---

## 5. Deployment tiers

`V1_DEPLOYMENT_REQUIREMENTS.md` + `docker/docker-compose*.yml` are explicit and
current. **Core infra is production-grade:** Postgres 16 (pgvector), Redis 7,
MinIO, Kafka+Zookeeper, Elasticsearch 8.11, Qdrant, Traefik; observability
(Prometheus/Grafana/Jaeger/Tempo/Loki). External services **fail closed** (no
fake sends) and are documented (messaging creds, `OSHUN_LMS_CONNECTORS`, C2PA
signing key `OSHUN_LIVING_SCENES_C2PA_*`, `JWT_SECRET` ≥64 chars in prod).

**Gaps (deployment-readiness):**

- **G-DEP-1 (P1):** No deployed **worker processes** for: messaging/reminder
  cycle, Veritas cascade, crisis-frame propagation. Composition exists; process
  management/scheduling does not.
- **G-DEP-2 (P2):** **Admin workspace state** is a large in-memory store; a
  durable snapshot exists but mutations don't survive restart without the
  migration wired at the composition root.
- **G-DEP-3 (P2):** Idempotency store has a real Redis impl but defaults to
  in-memory unless the durable binding is set in prod.

---

## 6. External provider integrations (generation)

**Verdict: the core generation pipeline is production-real for ComfyUI-based
image generation only.** `operation-orchestrator` + `job-envelope` +
`comfyui.service.ts` drive real RunComfy/RunPod ComfyUI execution with
retry/failover. Everything else is partial or stub:

| Provider                                | Real client?        | Wired into pipeline?                                                          |
| --------------------------------------- | ------------------- | ----------------------------------------------------------------------------- |
| ComfyUI / RunComfy / RunPod (image)     | ✅                  | ✅ (needs `RUNCOMFY_API_KEY`/`RUNPOD_API_KEY`)                                |
| Civitai (model intake)                  | ✅                  | 🟡 discovery only; on-site generation not wired                               |
| ElevenLabs (voice)                      | ✅                  | 🟡 client exists, no exposed route                                            |
| Suno / Udio (music)                     | 🟡 provider drivers | ❌ `/v1/isis/music/generate` → `notConfiguredMusicGenerationExecutor()` (503) |
| Meshy / Tripo / Stable-3D / 3D          | ❌ types only       | ❌ router exists, zero drivers registered                                     |
| Video (LTX/Hunyuan/Wan, RTX/RIFE/Topaz) | 🟡 partial          | ❌ not in main flow                                                           |

**Gaps:**

- **G-PROV-1 (P0 for music/3D/video launch):** Music, 3D, voice-cloning, and
  video generation are **demo/architecture-only** — routers exist, drivers are
  unregistered or type-stubs. If V1 launch scope includes these modalities, they
  are not production-real.
- **G-PROV-2 (P1):** No provider credentials in `.env.example`; image gen runs
  demo-mode without `RUNCOMFY_API_KEY`.

---

## 7. Consolidated gap register & production-readiness verdict

**Prioritized (P0 highest):**

- **P0** — Music/3D/video/voice generation pipelines are stub/architecture-only
  (G-PROV-1) — blocking _iff_ those modalities are in launch scope.
- **P1** — Reminder producers not wired to live data (G-MSG-1); no deployed
  messaging/cascade worker processes (G-MSG-2, G-DEP-1); five governance
  cascades islanded (G-GOV-1); OneRoster apply path missing (G-LMS-1); stub-only
  customer routes for Sophia/Psyche/Themis/Payments/Tenants (G-BFF-1); image-gen
  provider creds (G-PROV-2).
- **P2** — Tara/Metis customer routes are aggregation-only (G-BFF-2); retention
  scanner + moderation-path mismatch (G-GOV-2); admin durability + idempotency
  binding (G-DEP-2/3); course-publish trigger (G-LMS-2).
- **P3** — Channel creds (G-MSG-3), dual notification systems (G-MSG-4),
  v6/legacy hardcoded routes (G-BFF-3).

**Verdict.** The **platform spine is production-grade**: BFF + admin surface +
audit + abuse protection + LTI/SCORM + retraction cascade + image generation +
in-app messaging are real and wired, on production-grade infra that fails
closed. The **gaps are concentrated in (a) runtime _wiring_ of real-but-islanded
domain algorithms** (governance cascades, reminder producers, account/fraud
protection, achievements) and **(b) non-image generation modalities**
(music/3D/voice/video). Most P1/P2 items are **composition-root / worker-process
wiring**, not missing algorithms — consistent with the studio build-out pattern
(algorithms exist; surfaces/wiring are being connected one verified slice per
turn).

This analysis advances Phases 1–2 across all six previously-uncovered
dimensions. Phase 3 (full production readiness across every flow) remains the
multi-week build-out tracked in the studio surface program and this gap
register.
