Sanctum CRM

A partner sits down at the fund laptop and opens the deal timeline. In the same haus, on the same Mac, lives every text you have sent your spouse, every note from your kid’s school, the angel cheque you would rather nobody priced. The partner sees none of it. That gap — full archive for you, work graph for them — is the entire job of Sanctum CRM.
Jocasta keeps the archive. This page is about the wall she runs down the middle of it.
Every conversation that lands on the Mac — mail, iMessage, SMS, Signal, WhatsApp, Telegram, LinkedIn — is ingested into one local DuckDB store. Affinity deal flow and a personal angel ledger sit beside it. The Archives UI is a thin, read-only window on that store: if the UI burns down, zero bytes of intelligence burn with it.
What matters for a human operator is not the pipeline diagram. It is who can see what.
Two surfaces
Section titled “Two surfaces”| Surface | Who | What they see |
|---|---|---|
| Personal | You | Full timeline, family threads, Angel & LP |
| Work | Partners / fund session | Work-graph only — Affinity people, deal domains, firm addresses |
There is no LLM reading your texts to decide “sounds professional.” Classification is who the counterparty is, not what they said.
- Work = already on the work graph (Affinity contact, deal website domain,
@triptyq.vc). - Personal = household roster (instance family + Firewalla/screen-time devices) plus phones and emails that show up in family threads.
- Unknown = treated as personal for partners. Fail-closed.
Personal always wins when both match (spouse at a portfolio company stays personal).
ingest (hourly) ──▶ workspace.duckdb ──▶ v_timeline (you) │ ├── contact_silo + work_allowed_handles │ └──▶ v_timeline_work (partners) workspace-work.duckdb (export)Where you open it
Section titled “Where you open it”| Role | UI | Data |
|---|---|---|
| You | Archives :3346 | ~/.openclaw/workspace/workspace.duckdb |
| Partners | Archives :3347 (CRM_SESSION=work) | Prefer workspace-work.duckdb — personal rows never copied |
Both ports require a token. Each session mints its own 0600 file on first start — ~/.sanctum/secrets/jocasta-crm-personal.token for :3346, …-work.token for :3347 — and they are not interchangeable: the work token on the personal port is a 401, and so is the reverse. A request without one gets a 401 carrying WWW-Authenticate: Basic, so a browser prompts and you paste the token as the password with an empty username.
Both ports also bind the tailnet, which is deliberate — the archive is reachable from the MBP. It is only safe because of the paragraph above. It was not always: until 2026-08-11 :3346 answered /api/angel with the full Angel & LP ledger to anything that could reach the port, and :3347 had never started, so the only surface answering was the personal one. Auth landed first, then the partner port was turned on; the other order would have published a second open door.
The partner export is physical isolation, not a filter you hope nobody bypasses. Raw channel tables, the full timeline, and Angel & LP are simply not in that file — /api/angel on :3347 is a 403 even with a valid work token.
One correction worth carrying, because it is the more common shape of this mistake: the export’s row filter was never the leak. Its contacts table was built with SELECT * over a 30-column view, so business rows arrived carrying home addresses, birthdays and personal notes. Rows were right; columns were not. It now ships a six-column allowlist — name, email, company, title, type, Affinity ID — and sanctum-crm doctor fails critical if a future SELECT * widens it again.
CLI that matters
Section titled “CLI that matters”# Health of the dual surfacesanctum-crm statussanctum-crm silo-statussanctum-crm doctor # must be all-critical green before a partner session
# Your full archivesanctum-crm who "François Rioux"sanctum-crm timeline "demute"sanctum-crm needs-reply
# Partner-safe (same commands, work graph only)sanctum-crm timeline "demute" --workCRM_SESSION=work sanctum-crm needs-reply
# After Affinity sync or family roster changessanctum-crm silo-seedsanctum-crm work-export # → workspace-work.duckdbAffinity sync re-seeds the work graph automatically on success. Family identity is reloaded from instance.yaml and Firewalla-backed devices.yaml on every seed — you do not hand-maintain household members in a side file unless someone is missing.
What lands in the store
Section titled “What lands in the store”| Channel | How | Table |
|---|---|---|
| Mail.app / Graph | email_history | |
| iMessage / SMS | Signed FDA reader → dump | imessage_history |
| Signal | Desktop SQLCipher + Keychain | signal_history |
ChatStorage.sqlite (busy-timeout hardened) | whatsapp_history | |
| Telegram | MTProto session | telegram_history |
| Voyager / harvest | linkedin_history | |
| Deals | Affinity v2 → v_deal | dealflow |
| Angel & LP | Curated ledger | angel_investments (you only) |
Unified view: v_timeline. Partner view: v_timeline_work. Cross-channel “ball in your court”: v_needs_reply / v_needs_reply_work.
Partner session checklist
Section titled “Partner session checklist”sanctum-crm doctor— all critical checks greensanctum-crm work-export— fresh partner DBcurl -sf -u ":$(cat ~/.sanctum/secrets/jocasta-crm-work.token)" http://127.0.0.1:3347/— confirm the partner surface answers 200 before you seat anyone in front of it. It runs underKeepAlive, so it should already be up; if it is not,launchctl kickstart -k gui/$(id -u)/com.sanctum.jocasta-crm-work.- Hand partners the
:3347token, or onlyworkspace-work.duckdb - Never share
workspace.duckdb, the personal Archives on:3346, or the:3346token
Both ports listen on the tailnet as well as loopback, so “it is only on my machine” is not one of the guarantees. The token is.
Work access is audited at ~/.openclaw/logs/crm-work-access.log.
The wall is physical, not aspirational. A partner can read every deal in the room and never learn the family was ever in the building — which is how one Mac in a Quebec haus holds both a fund and a household without either one leaking into the other.
Related
Section titled “Related”- Jocasta — CRM Agent — who runs the archive
- Affinity filing — mail + Granola onto Affinity (the work CRM, different store)
- Dealflow Intelligence — Affinity → Mundi briefs
- Screen Time — Firewalla family roster that seeds personal silo
- Repo:
~/Projects/sanctum-crm/