# Architecture

Layered system architecture for Phoenix, Hermes, Jido, NVIDIA, ToolRouter, Stripe, Postgres, and Oban.

Status: implemented
Version: latest
Review: source-backed

## 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

- [Technology stack reference](/docs/reference/tech-stack)
- [Vendor and integration reference](/docs/reference/vendor-map)
- [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html)
- [Oban workers and retries](https://hexdocs.pm/oban/Oban.Worker.html)
- [PostgreSQL documentation](https://www.postgresql.org/docs/)
- [Stripe event types](https://docs.stripe.com/api/events/types)
- [Gmail API scopes](https://developers.google.com/workspace/gmail/api/auth/scopes)


Source paths:
- `docs/ARCHITECTURE.md`
- `lib/autonomous_agency_web/router.ex`
- `lib/autonomous_agency/tools/tool_router.ex`
- `lib/autonomous_agency/ai/model_router.ex`
- `lib/autonomous_agency/revenue.ex`
