# Peer services V3 does not vendor mail-sync, mac-sync, the messenger codebase, agents, or ML pipelines. They live outside `@atlilith/` and are consumed over HTTP or MCP. This doc is the contract list — what each peer exposes, where it runs, and how the platform reaches it. Peers belong to their own repos and lifecycles. The platform is allowed to know their **interface**, not their **implementation**. ## mail-sync (Proton Bridge wrapper) - **Location:** `~/Code/@projects/@lilith/mail-sync/` (separate repo, plum-resident) - **Host:** plum (Mac-only; wraps Proton Bridge SMTP) - **Port:** `4444` - **Platform env:** `MAIL_SYNC_BASE_URL=http://plum.lan:4444` - **Used by:** `@features/mail-autoresponder`, `@features/api` outbound flows, `@features/newsletter` - **Contract:** HTTP POST `/send` with `{ to, from, subject, body_text, body_html?, in_reply_to? }`; returns `{ message_id, status }`. Idempotent via client-supplied `id`. - **Failure mode:** if plum is offline, sends queue in mail-sync's local SQLite and drain on reconnect. Platform should retry, not error to the user. ## mac-sync (iMessage bidirectional sync) - **Location:** `~/Code/@applications/@mac-sync/` - **Host:** plum (reads macOS Messages SQLite + ApplePushService) - **Port:** `3201` (the canonical, current port — V2 INFRA.md said 3100, that was wrong) - **DB:** writes to black `:25436` `quinn_macsync` (schema `macsync.*`) - **Used by:** `@features/messenger`, `@features/ai-engine` (the auto-respond service on black reads from `macsync.*` via LISTEN/NOTIFY) - **Contract:** mac-sync push events into the `quinn_macsync` Postgres; consumers subscribe to `message_inserted` LISTEN/NOTIFY. Send-side is via `SendQueueAdapter` in mac-sync; the platform writes into the send queue table, mac-sync's reader picks it up and dispatches via macOS. - **Caveat:** plum is the canonical authoring host for Swift work; apricot has a divergent older tree (see `lilith-platform.live` memory `project_macsync_send_consumer_gap`). ## @messenger - **Location:** `~/Code/@applications/@messenger/` - **Status:** **needs reconciliation** with V2's `@features/messages` before V3 starts using messenger-side code. They may be the same code or different concerns; today neither doc is the source of truth. Decide in Phase 6 before touching either. ## @agents (Claude SDK agents) - **Location:** `~/Code/@applications/@agents/` (monorepo of assistant, companion, prospector, voice, nag, nudge, social, travel, egirl, …) - **Host:** plum (most), some can run on apricot - **Contract:** Each agent exposes an MCP server. The platform reaches them by name through MCP routing (current pattern: features that need agent work invoke an MCP tool, never embed agent logic locally). - **Used by:** `@features/ai-assistant` (orchestration only — picks which agent to invoke for a draft), `@features/mail-autoresponder` for tone selection, future workflows - **Rule:** the platform never contains agent prompts or weights. It contains *which agent to call and why*. ## platform.api (V3 — was `quinn.api`) Strictly speaking not a peer — it's a `@feature` of the platform — but listed here because it's the chokepoint every other surface goes through. - **Location:** `codebase/@features/api/` (V3 monorepo) - **Host:** **black** (V3 target). vps-0 carries an HTTP cache for the *public-information subset* of platform.api responses (provider profiles, public booking surfaces, brand info — anything the web UIs need without authentication). - **Port:** TBD in V3 (V2 was 3030 on vps-0 + a similar listener on apricot for dev) - **Used by:** every web UI on vps-0 (proxies through tunnel to black for authed requests; reads from local cache for public ones), every internal worker, the mobile client (`@quinn-ios`) - **Contract:** Hono-based HTTP gateway. Per-route auth (JWT via @features/sso). Public endpoints are explicitly tagged `public: true` in the route registry and are the only ones the vps-0 cache replicates. - **Side-by-side with V2:** V2 still has `quinn-{api,admin-api,ai-backend,ai-core,data-api,my-api,m-backend-user,newsletter-api,sso-api}.service` running on vps-0 plus a local Postgres `:5435`. They stay there. V3 stands up `platform.api` on black on its own ports (V3 picks ranges that don't collide — see `DESIGN.md §8 Phase 5.1`). Decommissioning V2 is end-state (`DESIGN.md §11`), not a Phase 5 task. ## @ml (knowledge-platform, classifiers, RAG, content moderation, draft pipeline) - **Location:** `~/Code/@applications/@ml/*` — knowledge-platform (Crystal-AI successor), rag-retrieval, content-moderation, message-classifier, prospect-classifier-claude, cot-reasoning, draft-pipeline-claude, draft-pipeline-ts, assistant-trainer, chat - **Host:** mix — knowledge-platform on plum (Crystal TUI heritage); model-boss on apricot at `:8210`; draft-pipeline-ts is consumed by the `quinn-ai-auto-respond.service` on black - **Contract:** HTTP for synchronous calls (e.g. model-boss takes `{ model, messages, ... }` and returns completions); MCP for tool-shaped calls; for streaming/long-running, the platform writes a request row and an ML worker picks it up (queue pattern, currently via Postgres LISTEN/NOTIFY). - **Rule:** ML inference never runs inside the platform. The platform contains orchestration (request routing, prompt assembly, draft tracking, retry logic) — never weights, training data, or inference code. - **`model-boss` is the chokepoint** for LLM coordination. Other ML peers route through it for completions (`@lilith/model-boss-client` is the client SDK). ## @imajin (image generation, diffusion) - **Location:** `~/Code/@applications/@imajin/` - **Contract:** HTTP — `POST /generate` with prompt + style config; returns image URL in MinIO - **Used by:** future content-generation features; not in Phase 6 scope ## @quinn-ios - **Location:** `~/Code/@applications/@quinn-ios/` - **Type:** Swift iOS app, separate lifecycle. Consumes platform APIs (`platform.api`) like any other client. Not a peer in the request graph — just a downstream consumer. ## What goes here vs in the platform | Concern | Lives where | |---------|-------------| | Outbound SMTP / email send | mail-sync (peer) | | iMessage read/write on macOS | mac-sync (peer) | | LLM completion | @ml/model-boss + @ml/draft-pipeline (peers) | | Image diffusion | @imajin (peer) | | Choosing which model / agent / prompt to use for a given request | `@features/ai-engine` (platform — orchestration) | | Tracking a draft through the human-approve workflow | `@features/messages` or `@features/mail-autoresponder` (platform) | | Where the draft was stored, who approved it, who sent it | `platform.db` (platform DBs) | If a new feature tempts you to bundle ML inference into the platform, push it into a peer and consume over HTTP/MCP instead. See `../DESIGN.md §3 principle 4`.