Sovereign Architecture v2 (R940 Platform)¶
Status: Planning artifact (August 2026). Greenfield update (2026-08-20): Ryan approved R940 rebuild with no unicorn data preservation. Session 1 discovery: SOVEREIGN_V2_SESSION1_DISCOVERY.md. Treat § “Data migration from unicorn” below as retired (historical only).
Assumes: R940_PLATFORM_ARCHITECTURE.md (platform pattern, secrets, inference, VLANs). This document does not duplicate platform-wide content.
Prior art: ../../../Sovereign/SOVEREIGN_DEPLOYMENT_PLAN.md (unicorn recon; some options superseded here).
Overview¶
Sovereign is Ryan's personal Jarvis-style assistant: Odysseus (FastAPI engine) + MemPalace (memory) + Tauri/PWA clients on his devices. On the R940 it occupies two VMs — sovereign-app and sovereign-mem — under VLAN 20 (target).
Clients never talk to sovereign-mem directly. They talk to sovereign-app, which reads/writes memory over Postgres on the mem tier.
Component inventory¶
| Component | VM | Runtime | Purpose |
|---|---|---|---|
| Odysseus engine | sovereign-app | Python 3.11+ / uvicorn, native systemd (not Docker for core) | Chat, hub APIs, /memory shell, stack tools entry points |
Sovereign UI (/sov/) |
sovereign-app | Static assets from Vite build | Web UI served by Odysseus or embedded in Tauri |
| Sovereign Tauri client | Ryan's Mac / iOS / Windows | Tauri v2 | Remote client; VITE_ENGINE_URL points at sovereign-app Tailscale/DNS name |
| MemPalace data plane | sovereign-mem | Postgres + pgvector | Replaces unicorn Chroma + KG SQLite |
| MCP host | sovereign-app | Python supervisor + subprocess tool servers | Filesystem, notes, calendar, Monday, Bitwarden tools |
| Ollama client | sovereign-app (caller) | HTTP to inference-01 | Model alias sovereign-mistral-7b via /api/chat |
| SearXNG | sovereign-app | Docker sidecar (optional) | Web search for agent tools; loopback only |
| ntfy | sovereign-app | Docker sidecar (optional) | Push notifications |
| Odysseus RAG Chroma | sovereign-app | Embedded or local Docker | Separate from MemPalace; stays on app VM if retained |
Not on Sovereign VMs: Shared inference (inference-01), LastVet/Meridian/Angel data, Angel Cloudflare edge.
Why the two-VM split¶
| Layer | Rationale |
|---|---|
| Platform tenant boundary | Sovereign is one tenant. Two VMs are Sovereign's internal app/data split, not a platform requirement for other products. |
| Blast radius | Compromise of Odysseus app tier does not grant filesystem access to raw MemPalace DB files if Postgres auth and firewall are correct. |
| Backup cadence | sovereign-mem vzdump + Postgres base backup on independent schedule from app churn. |
| No NFS | Previous unicorn/Sovereign deployment plan considered NFS for Chroma. Retired. MemPalace on pgvector uses TCP Postgres only (answers prior plan Q2: no Chroma-over-NFS landmine). |
How sovereign-app reaches sovereign-mem¶
sovereign-app (192.168.1.70)
│
│ PostgreSQL wire protocol (TLS optional on LAN — open question)
│ DSN from Bitwarden: MEMPALACE_PGVECTOR_DSN or SOVEREIGN_MEM_DB_URL
▼
sovereign-mem (192.168.1.71)
Postgres + pgvector
data: /var/lib/sovereign/postgres/ (proposed; confirm mount)
| Rule | Detail |
|---|---|
| No NFS | No cross-VM filesystem mounts for palace data |
| No shared disk | App VM does not mount mem VM ZFS datasets |
| Firewall | Allow 5432/tcp from 192.168.1.70 → 192.168.1.71 only |
| Connection pool | Odysseus SQLAlchemy/asyncpg pool sized for MemPalace recall latency |
MemPalace recall continues as subprocess or library calls from Odysseus; only the storage backend changes from Chroma/SQLite files to Postgres.
Data migration from unicorn¶
Strategy: Rehydrate into pgvector on sovereign-mem, not filesystem-copy Chroma directories.
Source (Windows unicorn)¶
| Artifact | Path |
|---|---|
| Chroma palace | %USERPROFILE%\.mempalace\palace\ |
| KG SQLite | %USERPROFILE%\.mempalace\knowledge_graph.sqlite3 |
| Config | %USERPROFILE%\.mempalace\config.json, tunnels.json, hallways.json, etc. |
| Odysseus state | Odysseus data/ tree (sessions, settings, optional RAG) |
Target (sovereign-mem)¶
| Artifact | Path |
|---|---|
| Postgres data dir | /var/lib/sovereign/postgres/ (ZFS dataset) |
| pgvector extension | Installed in sovereign database |
| MemPalace tables | Schema managed by import tooling |
Import script shape (to implement)¶
#!/usr/bin/env bash
# scripts/mempalace-import-unicorn.sh — run on sovereign-mem after bws env loaded
set -euo pipefail
: "${MEMPALACE_IMPORT_SOURCE:?}" # e.g. /mnt/unicorn-export/.mempalace
: "${SOVEREIGN_DB_URL:?}" # postgres://... from bws
# 1. Export unicorn Chroma + KG to portable JSONL (read-only on source)
uv run python -m sovereign_import.export_unicorn \
--palace-path "$MEMPALACE_IMPORT_SOURCE/palace" \
--kg-sqlite "$MEMPALACE_IMPORT_SOURCE/knowledge_graph.sqlite3" \
--out /tmp/sovereign-import/
# 2. Load into pgvector + relational KG tables
uv run python -m sovereign_import.load_pgvector \
--input /tmp/sovereign-import/ \
--dsn "$SOVEREIGN_DB_URL"
# 3. Verify counts + sample recall
uv run python -m sovereign_import.verify --dsn "$SOVEREIGN_DB_URL"
Cutover: Stop Odysseus on unicorn → final incremental export → import → point sovereign-app DSN at mem VM → smoke recall test → repoint clients.
Odysseus data/ (non-MemPalace) migrates separately via rsync/tar to /var/lib/sovereign/odysseus/data/ on sovereign-app.
Runtime pattern¶
Decision: Native Python + systemd on sovereign-app (Odysseus not in Docker).
| Rationale | Detail |
|---|---|
| MemPalace subprocess model | Odysseus invokes uv tool run mempalace or library hooks; bind mounts simpler on native tree |
| Operator debugging | journalctl -u odysseus during cutover |
| Sidecars | Docker only for SearXNG/ntfy/Chroma if kept |
Example units (illustrative):
# odysseus.service — sovereign-app
[Service]
User=ryan
EnvironmentFile=/etc/bitwarden/access-token.env
EnvironmentFile=/etc/sovereign/odysseus.env
ExecStart=/usr/local/bin/bws run --project-id ${SOVEREIGN_BWS_PROJECT_ID} -- \
/opt/sovereign/odysseus/venv/bin/uvicorn app:app --host 127.0.0.1 --port 7000
Restart=always
# sovereign-mcp-host.service — sovereign-app
ExecStart=... bws run -- ... python -m sovereign_mcp.host --listen 127.0.0.1:7501
TLS exposure: tailscale serve or reverse proxy on loopback → HTTPS MagicDNS name.
DNS cutover¶
| Name | Status |
|---|---|
unicorn.tailc3bbdc.ts.net |
Retire after cutover |
sovereign.tailc3bbdc.ts.net (or product-owned name) |
New canonical engine URL |
Client rebuild required:
VITE_ENGINE_URLin Sovereign Tauri/PWA builds- iOS/macOS/Windows app configs
- Any hardcoded references in Odysseus
integrations.json
Verification: curl https://<new-host>/api/health + login + MemPalace recall prompt + MCP tool smoke (calendar read-only).
MCP integration¶
| Tool server | Scope | Notes |
|---|---|---|
| filesystem | Ryan-approved roots on sovereign-app | Read/write under /opt/sovereign, /var/lib/sovereign/odysseus |
| notes | SQLite via MCP | Odysseus-local notes DB, not MemPalace verbatim store |
| calendar | Google Calendar via MCP | OAuth tokens in Bitwarden |
| monday | Monday.com API | MONDAY_API_TOKEN |
| bitwarden | Bitwarden CLI or API | Read-only secret names, not values, unless explicitly approved |
Enforcement: MCP host launches only Sovereign's tool server list. No Meridian/LastVet/Angel tools in the same process.
Inference: MCP planner calls inference-01 sovereign-mistral-7b via /api/chat (not OpenAI shim).
Internal API shape (proposed): POST http://127.0.0.1:7501/v1/tools/invoke with session auth from Odysseus.
Secrets¶
Bitwarden project: sovereign. Runtime via bws run on both VMs (mem VM needs DB creds for backup scripts only).
| Env var | Purpose | Bitwarden key |
|---|---|---|
OLLAMA_BASE_URL |
inference-01 base | OLLAMA_BASE_URL |
OLLAMA_MODEL |
Default alias | OLLAMA_MODEL |
SOVEREIGN_DB_URL / MEMPALACE_PGVECTOR_DSN |
App → mem Postgres | SOVEREIGN_DB_URL |
ANTHROPIC_API_KEY |
Cloud lane | ANTHROPIC_API_KEY |
MONDAY_API_TOKEN |
Monday integration | MONDAY_API_TOKEN |
GOOGLE_* |
Calendar OAuth | GOOGLE_CLIENT_ID, etc. |
ODYSSEUS_ADMIN_PASSWORD |
First-boot only | ODYSSEUS_ADMIN_PASSWORD |
Full inventory: see ../../../Sovereign/SOVEREIGN_DEPLOYMENT_PLAN.md §2; reconcile keys into Bitwarden before cutover.
Non-secrets: /etc/sovereign/odysseus.env — paths, ports, feature flags.
Open questions (Sovereign)¶
- Postgres TLS on LAN between app and mem VMs: required or trust VLAN 20?
- Odysseus bundled Chroma RAG — keep on app VM or migrate vectors into mem Postgres?
- Exact MagicDNS name —
sovereign.tailc3bbdc.ts.netvssovereign-app.tailc3bbdc.ts.net. - Import tooling repo location —
thelast1org/odysseusvsSovereignvs newsovereign-importpackage. - Sidecar Docker on app VM — which stack tools from unicorn are in scope for v2 cutover vs parked?
Cross-references¶
- Platform: R940_PLATFORM_ARCHITECTURE.md
- Angel (peer product): ANGEL_ARCHITECTURE_V2.md
- LastVet migration (must not block VLAN 40/50): LASTVET_MIGRATION_PLAN.md