Status: implemented
Version: latest
Review: source-backed
Last scanned: 2026-06-25T00:00:00Z
Review required: false
Architecture
Layered system architecture for Phoenix, Hermes, Jido, NVIDIA, ToolRouter, Stripe, Postgres, and Oban.
Layered overview
| Layer | Primary modules | Production role | Fail-closed rule |
|---|---|---|---|
| Phoenix control plane |
Router, controllers, LiveViews, layout components
| Auth, public docs, account controls, project UI, approvals, CRM, inbox, proof | Protected routes require login and scoped account access |
| Domain contexts |
Revenue, CRM, Agency, Approvals, Hermes, Integrations, Audit
| Own business rules and Ecto changesets | UI events call contexts instead of writing raw state |
| Postgres source of truth | Ecto schemas, migrations, constraints, UUID keys | Orders, CRM, approvals, tool calls, model decisions, audit, ledger, skills | Runtime reads and writes durable state, not browser-local state |
| Oban orchestration | Workers and queues | Durable retries for Hermes, Gmail, fulfillment, provider checks, sync work | Failed jobs remain visible and retryable |
| PubSub and LiveView | Phoenix PubSub and LiveView processes | Live run updates, approval cards, status panels, CRM/inbox changes | Browser observes state; it does not own authority |
| Hosted Hermes runtime |
HermesRuntime, HermesRunWorker, Tools.Hermes, profiles, skills
| Agent planning, drafting, task execution, skill use | Runtime submissions pass content firewall and ToolRouter boundaries |
| Jido policy/firewall layer |
ContentFirewall, ContentFirewallPolicy, JidoRuntime
| Typed payload checks for data poisoning and provenance | Missing Jido or malformed provenance blocks handoff |
| NVIDIA model layer |
ModelRouter, Tools.Nemotron, ModelDecision, safety review
| Scoring, copy safety, final QA, structured decisions | Invalid or unsafe model output blocks action |
| ToolRouter |
AutonomousAgency.Tools.ToolRouter
| Single audited side-effect gateway | No external side effect bypasses policy and idempotency |
| Stripe revenue rails |
Revenue, Tools.Stripe, webhook controller
| Checkout, webhooks, orders, revenue proof, future spend | Webhooks are idempotent and signed outside test bypass |
| Gmail outreach rails | Google OAuth, token vault refs, mailbox, alias, project Gmail setting, GmailClient, GmailAdapter | Drafts, sends, inbox ingestion, replies, thread labels | No live send without account mailbox, project alias, suppression, policy, idempotency, approval |
| Artifact storage | Project document and artifact contexts, S3/Tigris-compatible storage | Uploaded docs, generated docs, downloadable outputs, private attachments | Raw external content is quarantined until release |
Core design choices
- Phoenix/LiveView gives the operator a real-time control plane while keeping secrets server-side.
- Postgres is the durable system of record for proof, not a transient cache.
- Oban is used for retries and background work instead of relying on browser sessions or local CLI state.
- Hosted Hermes is used as the agent runtime, but it does not own live side effects.
- Jido is intentionally narrow: it executes policy/firewall decisions where typed action boundaries help.
- NVIDIA model decisions are stored as structured evidence, not opaque text blobs.
- Stripe and Gmail live operations remain policy-gated and idempotent.
System boundary map
| Boundary | Allowed input | Blocked input | Output |
|---|---|---|---|
| Public request forms | Basic lead/contact data, business website, honeypot-empty submissions | Filled honeypot fields and invalid sponsor access domains | CRM lead, owner notification, or safe rejection |
| Hermes runtime package | Project summary, released source refs, approval state, scoped skills | Raw secrets, unreleased inbound content, direct credentials | Plan, draft, artifact request, action intent |
| ModelRouter | Structured scoring/safety/QA request | Unsupported provider, missing route, malformed schema | ModelDecision or fail-closed error |
| ToolRouter | Approved provider operation with idempotency key | Missing readiness, missing approval, disabled live mode, unsafe payload | ToolCall, provider result, audit event |
| Gmail adapter | Approved draft/send/reply payload, account mailbox, project alias | Unapproved live send, missing project Gmail setting, missing alias, suppression conflict | Draft/send result and thread/message proof |
| Stripe webhook | Signed event and checkout metadata | Duplicate event, unsigned event outside test bypass | Order, RevenueEvent, Deal, ledger entry |
Durable proof graph
| Proof object | Links to | Why it exists |
|---|---|---|
Order
| Customer, offer, checkout session, project/order intake | Converts payment into business state |
RevenueEvent
| Order, Stripe event, deal, ledger | Shows money movement as durable proof |
AcquisitionRun
| Project, order intake, run events, approvals | Holds operational work generated from the goal |
ToolCall
| Provider, operation, idempotency key, approval, audit | Proves external side effects were routed safely |
ModelDecision
| Route, provider, schema, source ref, run/draft | Proves model work and safety review without hidden reasoning |
ApprovalRequest
| Actor, action, amount/risk, payload summary | Separates agent intent from human authority |
AuditEvent
| Context record, action, metadata, hashes | Provides explainable system history |
Why BEAM matters here
This architecture benefits from Elixir because agent operations are concurrent, stateful, interruptible, and failure-prone. LiveViews can represent operator sessions, workers can retry runtime/provider jobs, supervisors can restart processes, and PubSub can broadcast state changes while Postgres remains the authority. The design avoids treating a model session as the application state.
Primary source links
Official references
| System | Use in Trinity | Official docs |
|---|---|---|
| Phoenix LiveView | Server-owned real-time UI | Phoenix LiveView |
| Oban | Durable jobs and retries | Oban Worker |
| PostgreSQL | Durable source of truth | PostgreSQL docs |
| Stripe | Signed revenue webhooks | Stripe event types |
| Gmail | OAuth scopes and mail operations | Gmail API scopes |
Source paths
docs/ARCHITECTURE.mdlib/autonomous_agency_web/router.exlib/autonomous_agency/tools/tool_router.exlib/autonomous_agency/ai/model_router.exlib/autonomous_agency/revenue.ex