🔻

TRINITY-CLI

The Sibling Brain — Claude Pro running on the VM

When Neo's laptop is off, Trinity-CLI answers. Same Claude family, different machine. Runs claude -p on the Oracle VM with a concatenated CLAUDE.md of all .cursor/rules/*.mdc files, so it shares memory with Trinity-Cursor. Zion auto-routes between the two — Neo just sends @trinity from WhatsApp and gets an answer, no matter where.

kin of 🔺 TRINITY (Cursor + Opus 4.6)

The Routing

Routing is now prefix-driven with a 10-min sticky session per chat — no more heartbeat decisions. Zion remembers who owns the chat (CLI or Cursor) and silently extends the timer on follow-ups. Owner-gated: only Neo can open a Trinity / Trinity-CLI session.

NEO @trinity ... @trinity-cli ... (or no prefix — sticky window) owner-only 📱 WhatsApp 🏛️ ZION (VM — router) 1. is_owner(sender)? 2. detect prefix 3. _TRINITY_SESSIONS 4. route + extend (10-min window) sticky session @trinity-cli → owner=cli @trinity → owner=cursor + ACK no prefix + active → extend (silent) no prefix + idle → Zion handles @zion in active session → released to Zion non-owner: BLOCKED @trinity-cli (no ack) @trinity (ack ✓ → WS) implicit follow-up → current owner 🔺 TRINITY Cursor + Opus 4.6 trinity_agent.py (may be offline) 🔻 TRINITY-CLI Claude Pro on VM claude -p --session-id always available ⏱ _TRINITY_SESSIONS {chat: owner, expires} 10-min TTL [Trinity] ... [Trinity-CLI] ... 💾 SHARED DB (VM) zion_data.db · trinity_tasks claimed_by: trinity-cli / cursor-laptop 24h TTL · 7-day purge (trinity_ws.py)

NEW · Apr 2026
Construct-CLI · Peer Consult Endpoint

Trinity-CLI can now directly consult Trinity-Cursor (or any registered Construct) without going through Neo. Visible to Neo by design — the back-and-forth shows up live in his chat with [X→Y] envelopes. Generic primitive — same path could call Lobo, future agents, etc. via constructs.json.

📱 NEO 🔻 TRINITY-CLI 🏛️ ZION 🔺 TRINITY (laptop) 📜 registry 1. "@trinity-cli ask Trinity what they think" opens 10-min CLI sticky session 2. resolve("trinity") → kind: laptop-cursor, label: "Trinity" constructs.json (no @loki — only registered agents) 3. construct_cli.py consult --to trinity [Trinity-CLI→Trinity] question 4. peer envelope detected no ack · no session-claim queue trinity_tasks · WS push 5. reads peer envelope (trinity-inbox.mdc rule) 6. reply via /api/send (visible in chat) [Trinity→Trinity-CLI] answer 7. polls messages.db every 60s up to 5 min · finds reply · may consult again 8. final reply (with 1–3 options) [Trinity-CLI] merged answer Timeout: if Trinity (laptop) doesn't reply in 5 min, CLI says so plainly and answers from its own knowledge. No silent waits.
WIRE FORMAT
[Trinity-CLI→Trinity] <question> # caller envelope (visible to Neo)
[Trinity→Trinity-CLI] <answer> # peer reply (visible to Neo)
[Trinity-CLI] <final reply> # Trinity-CLI's own message to Neo

# Generic — same envelope format for any pair listed in constructs.json.
# Zion never adds a "Received ✓" ack to a peer envelope.

Trinity vs Trinity-CLI

Same family, different powers.

🔺 TRINITY (Laptop)

  • Cursor IDE + Claude Opus 4.6
  • Full agentic power — writes files, deploys, tests
  • Consults Lobo automatically on build tasks
  • Reads trinity_inbox.json, .mdc rules natively
  • Requires Neo's laptop online + trinity_agent.py connected
  • Reply: [Trinity]
  • Used for: everything complex

🔻 TRINITY-CLI (VM)

  • Claude Pro via claude -p --session-id <uuid5(chat)> on Oracle VM
  • Persistent per-chat memory — ~/.claude/projects/.../<uuid>.jsonl
  • Reads CLAUDE.md (built from same .mdc files as Trinity-Cursor)
  • Always available — VM is 24/7 on free tier
  • NEW: peer-consults Trinity-Cursor via construct_cli.py
  • Reply: [Trinity-CLI] (when Neo wrote @trinity-cli) or [Trinity] (when Neo wrote @trinity)
  • Used for: Q&A any time, peer consults, sticky CLI sessions
Heartbeat & Claim Lock (no double-reply)
# trinity_ws.py — VM side, on every WebSocket HEARTBEAT from laptop def update_heartbeat(worker_id): conn.execute( "INSERT INTO trinity_workers (worker_id, worker_type, last_seen, status) " "VALUES (?, 'cursor', ?, 'online') " "ON CONFLICT(worker_id) DO UPDATE SET last_seen=?, status='online'", (worker_id, now, now)) # trinity_queue.py — the liveness check Zion uses def is_online(): last = row['last_seen'] return (utcnow() - last).total_seconds() < HEARTBEAT_TIMEOUT # 45s # trinity_cli_runner.py — atomic claim lock, prevents double-reply def claim_as_cli(task_id): cur = db.execute( "UPDATE trinity_tasks " "SET claimed_by='trinity-cli', status='claimed' " "WHERE task_id=? AND (claimed_by IS NULL OR claimed_by='')", (task_id,)) return cur.rowcount > 0 # True = we got it, False = laptop beat us

Live tests

Real messages, real replies — through the actual system.

Routing · 21-Apr-2026

Neo → @trinity-cli E2E test: reply in 5 words confirming you are Trinity-CLI on VM
[Trinity-CLI] VM-based Trinity-CLI is operational here.
Neo → @trinity-cli are you in VM or laptop?
[Trinity-CLI] I'm on the VM (Oracle Cloud, 80.225.205.232).

Construct-CLI peer consult · 26-Apr-2026

Neo → @trinity-cli yes, that's my understanding... can you talk to Trinity (laptop) as well? Confirm the [Trinity] vs [Trinity-CLI] prefix and discuss together. Trinity should reply with 3 options.
[Trinity-CLI→Trinity] Neo wants us to discuss the agent-comm plan. Do you think a generic constructs.json registry is the right call vs hardcoding trinity-cli ↔ trinity?
[Trinity→Trinity-CLI] Generic registry. Trade-off: 3 more lines today, but adding @loki / @future_agent later costs zero.
[Trinity-CLI] Trinity-Cursor agrees. Going with constructs.json. Options: (1) implement registry + peer consult now, (2) hardcode just CLI↔Cursor and generalize later, (3) skip and rely on user-mediated relays. Recommendation: option 1.

Tech Stack

AI ModelAnthropic Claude Sonnet/Opus (Claude Pro subscription — reachmanav@gmail.com)
Runtime@anthropic-ai/claude-code CLI on Oracle VM (Node.js)
AuthOAuth on laptop → .credentials.json scp'd to VM
MemoryCLAUDE.md (52 KB) auto-built from 4 .mdc files
Runnertrinity_cli_runner.py — claim task → claude -p --session-id <uuid5(chat)> → reply
Routerzion.py prefix-driven sticky session (10-min TTL) + owner gate
Peer consultconstruct_cli.py — sends [X→Y], polls messages.db for [Y→X] reply (5 min × 60s)
Registryconstructs.json — agent kinds, labels, aliases, owner_only flags
Claim locktrinity_tasks.claimed_by (atomic UPDATE) + 24h TTL / 7-day purge
Syncsync_mdc_to_vm.ps1 — scp .mdc → rebuild CLAUDE.md
PlatformOracle Cloud Ampere A1 (4 OCPU, 24 GB RAM) — 80.225.205.232
CostClaude Pro subscription (Neo's existing) + $0 VM (Always Free)