Internal — not for client sharing

Internal · Operations

Automation architecture

Where every Mangrove automation lives and why — the routing logic for the ops upgrade (Hermes · n8n · Executor · Claude Code · Zapier retirement). This page is the canonical plan; the auto-generated census of what's actually running lives on the Hermes server at /opt/data/ops/AUTOMATIONS.md, rewritten every Monday by the ops-inventory cron.

Updated 2026-11-02

The routing rule is one question: does the job need judgment, or just reliability? The index-card test — if you can write the steps on an index card such that a very literal intern never has to ask a question, it's deterministic and belongs in n8n. If the job is "look at it and figure out what matters" (reading, interpreting, comparing, writing prose), it belongs on Hermes. If it needs Maiya in the loop, or access only her machine has, it stays in Claude Code. The systems compose: n8n does the mechanics and calls an agent only for the one step that needs words written or a judgment call.

System roles

SystemRoleCost per runFails how
n8n
mangrove.app.n8n.cloud
Deterministic plumbing: webhook or poll → fixed transforms → API writes. Same input, same steps, same output, every time. $0 — no tokens Retries identically; errors are mechanical.
Hermes
hermes.mangrove-web.com
(VPS MG.Ops)
Judgment on a schedule: reconciliations, health checks, reports, plus kanban cards Maiya promotes to Ready. Tokens per run Can be wrong — so report-only jobs and Executor approval gates on writes.
Executor
executor.mangrove-web.com
The sole credential and tool hub. All agent access to services goes through it; billable or destructive writes pause for approval. — —
Claude Code
local
Interactive work with Maiya, and routines that need judgment plus local-only access (the M365 connector, local repos, Keychain). Tokens Maiya is watching.
Zapier Legacy. Retiring in phases; keeper Zaps run until their n8n ports are verified. Subscription —

Current state (verified 2026-11-02)

SystemRunning today
n8n 3 active: website lead → Attio + Twenty (plus its Twenty sub-workflow); Twenty email attachments → deals. Off: Attio sub-workflow, Project Intake → Deal Creation, attachment backfill.
Hermes 3 crons: daily ops health check (weekdays 9:00a PT) · Harvest↔Teamwork reconciliation (weekdays 9:15a, report-only — replaced the local Claude time-report routine, now disabled as fallback) · ops inventory (Mon 8:30a).
Claude routines Daily briefing 10a · Firefly calendar refresh · billing dashboard update · Notion/Groove sync (Wed) · Twenty→Brevo (monthly) · PTO reminder (Mon).
Zapier 5 keeper Zaps + Deal Won fan-out, unchanged until Phase 1.

No system duplicates another's job today. Planned migrations exist only as Hermes kanban cards in Triage, and the old version stays on until its replacement is verified.

Rollout phases (tracked as Hermes kanban cards)

  1. Enable n8n instance-level MCP so Hermes can drive n8n (clears the n8n-official OAuth errors).
  2. Phase 1 Zapier port: 5 keeper Zaps → n8n. Check overlap with the live website-lead workflow first so nothing double-writes to Twenty.
  3. Deal Won fan-out rebuilt from Twenty in n8n — n8n mechanics, an agent step only if copy gets written.
  4. Calendar refresh (GCal→M365) → n8n when feasible (local-only today because of the M365 connector).
  5. Billing dashboard + Notion/Groove sync → Hermes (judgment-adjacent, needs report output).
  6. Phase 3: retire Zapier once the ports have run clean.

Hermes board semantics (this build — not standard kanban)

LaneWhat it really is
Triage The backlog. The only lane the dispatcher never touches — park everything here.
Todo A feeder queue — auto-promotes to Ready within 60 seconds. Never park cards here.
Ready Approved to run. Dispatches within a minute only if the card has an assignee; unassigned cards are inert.
Blocked Hermes stopped and needs something from Maiya — answer in the card's comments, drag back to Ready.
Review Hermes thinks it's done and wants sign-off.

Safety rules: nothing moves to Ready without Maiya · kanban.default_assignee stays empty (the unassigned-skip is the only brake) · a card's description is the worker's entire prompt, so write a real brief — a bare title gets improvisation.

Known gap: notifications

Hermes pushes nothing to Maiya; results sit in the Ops Home dashboard tab and Sessions. Interim habit: check Ops Home daily. Candidate fix: the local daily briefing pulls Hermes cron results and board state via the API.

Credentials

Agents get service access only through Executor connect links. Local scripts use the macOS Keychain (mg-* names); the n8n API key is mg-n8n. Never in chat, source, or files.