Architecture outcome
What you will understand
By the end of this guide, you will understand:
- The four major operational areas of the monorepo
- How the UI, Product API, Ingest API, Agent runtimes, and infrastructure communicate
- Why the Agent is the central orchestration boundary
- How Organization and Agent authorization differ
- Where persistence and transaction boundaries live
- Why telemetry, Domain Events, Event Deliveries, audit records, and costs are separate
- How versioned configuration becomes a running Kubernetes workload
- Where a new feature or system change belongs
Overview
Understand where Agent Barn responsibilities live, how data crosses system boundaries, and which contracts must move together when you make a change.
Agent Barn manages Organization-owned AI Agents that run through Hermes or OpenClaw and communicate through Slack, Microsoft Teams, Telegram, or Discord.
At a high level:
:8000 - PostgreSQL
- Kubernetes API → Agent Deployments
- LiteLLM → OpenRouter
- Firecrawl
- Email and OAuth providers
- Redis → Event Delivery worker
:8001 → PostgreSQL The system separates:
- Human product requests
- Runtime telemetry
- Internal business events
- Background delivery
- Provider cost reporting
- Dynamic Agent execution
- Platform deployment
These paths interact, but they do not share one event model, authentication mechanism, or source of truth.
Four operational areas
Agent Barn is a monorepo with four major operational areas.
API
Product contracts, authentication, authorization, orchestration, persistence, Ingest, and runtime control
Primary source: api/
Web app
Authenticated Organization and Platform experiences
Primary source: ui/
Agent runtimes
Execute rendered Agent configuration and communicate with platforms and tools
Primary source: hermes-base/, openclaw-base/, Agent builders
Deployment
Build and deploy databases, services, runtime images, monitoring, and Agent infrastructure
Primary source: helm/, helmfile.yaml.gotmpl, workflows
These are operational boundaries, not four independently owned domain services. API domains are modules inside one application and commonly share the Agent Barn application database.
API
The API provides:
- Product HTTP routes
- Runtime telemetry ingestion
- Authentication and token management
- Organization and Agent authorization
- Database persistence
- Template and Skill management
- Agent lifecycle orchestration
- Kubernetes resource creation
- LiteLLM key management
- Provider integrations
- Domain Event delivery workers
- Monitoring metrics
Web app
The web app provides:
- Public authentication routes
- Organization View
- Platform View
- Agent configuration and lifecycle controls
- Template and Skill management
- Activity, Tool Call, cost, and log views
- Platform administration
- Permission-aware actions
Agent runtimes
Hermes and OpenClaw:
- Load generated Agent configuration
- Connect to a supported communication Platform
- Call models through LiteLLM
- Use mounted Skills and provider integrations
- Maintain Agent workspace state
- Push messages and Tool Call telemetry to Ingest
- Expose health and metrics
Deployment
The deployment system owns:
- PostgreSQL, Redis, LiteLLM, Firecrawl, API, UI, and monitoring releases
- Runtime image builds
- Alembic migration hooks
- LiteLLM virtual-key hooks
- Kubernetes Secrets and ingress
- Production and staging namespaces
- Image and chart version inputs
System topology
Product request path
A normal browser request follows:
Browser
↓
Next.js route or feature component
↓
Shared UI API client
↓
Product API /api/v1
↓
Route
↓
Service
↓
Repository
↓
Agent Barn PostgreSQLServices can branch to infrastructure adapters when the workflow needs Kubernetes, LiteLLM, email, OAuth, encryption, or another provider.
Runtime execution path
A running Agent follows a different path:
Platform message
↓
Hermes or OpenClaw
├── generated Template and policy
├── mounted Skills
├── decrypted integration material
├── Agent workspace PVC
└── model request → LiteLLM → OpenRouterThe Agent runtime is a dynamically created Kubernetes workload, not code executing inside the Product API process.
Runtime telemetry path
Hermes or OpenClaw
↓ Agent ID + per-start ingest key
Ingest API /ingest/v1
├── Conversation Message persistence
└── Tool Call persistence
↓
Product read APIs
↓
Activity UIInternal event path
Business mutation
↓ one PostgreSQL transaction
Business state + Outbox Message + Event Deliveries
↓ post-commit enqueue
Redis / Dramatiq
↓
Worker
↓
Event Handler
├── Security Audit projection
└── Agent lifecycle emailIf immediate enqueue fails, committed delivery state remains in PostgreSQL and reconciliation can republish it later.
Domain model
Organization is the ownership and tenancy root for user-facing resources.
- Membership → User and authentication
- Organization Role
- Agent Access Roles
- Shared Credentials
- Organization Templates and versions
- Organization Skills and versions
- Domain Events
- Outbox Messages
- Event Deliveries
- Agent
- Agent Creator provenance
- explicit and General Agent Access
- Runtime and Platform
- configured model
- pinned Template or Override version
- assigned Skill versions
- Agent Secrets and Shared Credential references
- Kubernetes runtime resources
- Conversation Messages
- Tool Calls
- LiteLLM key identity
Platform-owned resources
Some resources belong to Agent Barn itself rather than an Organization:
- Platform Privileges
- Predefined Platform Templates
- Built-in Skills
- Platform-level Domain Events
- Platform oversight views
- Platform configuration and catalogue data
A new installation has no default Organization.
Application startup ensures:
- The bootstrap Platform Administrator
- RBAC seed data
- Built-in aai-cli Skills
- The predefined Platform Template catalogue
Platform Templates live in their own global table. Built-in Skills use global ownership rather than being copied into every Organization.
Tenancy and authorization
Organization is the tenancy axis
Organization-owned routes normally include:
/api/v1/organizations/{organization_id}/...Authentication produces a current user context. Organization-scoped services resolve a real persisted Membership for the requested Organization.
A Platform Administrator does not receive a synthetic Membership or implicit Organization Role.
Organization View and Platform View
| View | Route shape | Authority |
|---|---|---|
| Organization View | /dashboard/[orgId] | Membership and Agent Access |
| Platform View | /dashboard/platform | Platform Privilege |
Platform View has no Active Organization.
Platform oversight is explicitly allowlisted. It does not mean unrestricted access to Organization-owned credentials, configuration payloads, conversations, or raw telemetry.
Two role families
Organization Roles govern Organization-level capabilities:
- Organization Owner
- Organization Admin
- Organization Member
Agent Access Roles govern one Agent aggregate:
- Agent Viewer
- Agent Editor
- Agent Owner
- Organization-defined custom Agent Access Roles
Organization Owner and Admin receive implicit Agent Owner authority over Agents in their Organization. Members can receive Agent authority through:
- Explicit Agent Access
- Agent General Access
- Both, with additive Permissions
Creator fields are provenance. They are not permanent authorization exceptions.
Authorization placement
The architecture divides authorization responsibility:
- Repositories constrain visibility before count, pagination, and return.
- Services enforce action Permissions and lifecycle rules.
- Routes authenticate, parse, delegate, and return.
- The UI uses server-reported permitted actions to render controls.
- Every backend mutation independently reauthorizes the request.
Subordinate resources—conversations, Tool Calls, activity, costs, logs, Secrets, Skills, and configuration—must be accessed through the same accessible-Agent boundary.
API architecture
The API has two FastAPI composition roots.
| Application | Route prefix | Port | Authentication boundary |
|---|---|---|---|
| Product API | /api/v1 | 8000 | Human authentication, Platform authority, Membership, and Agent Access |
| Ingest API | /ingest/v1 | 8001 | Agent identity and per-start ingest key |
The deployed API container starts both processes. They use separate Prometheus registries and expose separate /metrics endpoints.
Layering
The normal dependency direction is:
routes.py
↓
service.py
↓
repository.py
↓
PostgresRepositoryDelegateServices may also call:
Kubernetes
LiteLLM
OpenRouter
Slack
Telegram
Google OAuth
Cloudflare email
Cryptography
Other provider adaptersRoutes
Routes should:
- Authenticate
- Parse path, query, and body data
- Resolve dependencies
- Delegate to a service
- Return the response
Routes should not own business workflows, SQL, or database transactions.
Services
Services own:
- Business rules
- Permission-sensitive behavior
- Lifecycle validation
- Error translation
- Cross-domain orchestration
- Calls to infrastructure adapters
- Post-commit Event Delivery enqueue
The Agent Service is intentionally broader than a CRUD service because starting an Agent crosses Templates, Skills, credentials, providers, LiteLLM, Kubernetes, and telemetry.
Repositories
Repositories own:
- SQLModel and SQLAlchemy queries
- Tenant and visibility predicates
- Persistence
- Ordering and pagination
- Explicit transaction boundaries where required
- Atomic business mutation plus event staging
Infrastructure adapters
Infrastructure code isolates external concerns such as:
- PostgreSQL
- Kubernetes
- Redis transport
- LiteLLM
- OpenRouter
- Messaging-platform APIs
- OAuth
- Encryption
- Time
Dependency injection is assembled through the API’s Injector modules.
Persistence and transactions
Application database
Agent Barn’s PostgreSQL database stores:
- Users and authentication state
- Organizations and Memberships
- Roles and Agent Access
- Agents and lifecycle state
- Templates and versions
- Skills and versions
- Encrypted credentials
- Conversation Messages
- Tool Calls
- Domain Events, Outbox Messages, and Event Deliveries
- Security Audit Records
Schema changes use Alembic migrations under:
api/migrations/versions/Integration tests migrate a real PostgreSQL test database.
Separate databases
The deployment includes distinct databases:
| Database | Owner |
|---|---|
| Agent Barn application PostgreSQL | Agent Barn API and Alembic |
| LiteLLM PostgreSQL | LiteLLM |
| Firecrawl PostgreSQL | Firecrawl |
Agent Barn Alembic migrations do not manage the LiteLLM or Firecrawl schemas.
Ordinary repository operations
Most repositories use a shared delegate that opens and commits a session per operation.
Therefore:
service call
├── repository operation A → commit
└── repository operation B → commitis not automatically one transaction.
If operation B fails, operation A may already be committed.
Explicit transactions
A workflow requiring all-or-nothing persistence needs a domain-specific repository transaction:
one SQLModel session
├── business mutation
├── Outbox Message
├── intended Event Deliveries
└── one commitThe outbox stages rows inside the repository-owned session. It does not open or commit its own session.
Event and data flows
Several similarly named records have deliberately different roles.
| Concept | Origin | Authentication | Persistence | Purpose |
|---|---|---|---|---|
| Product request | Browser or API consumer | Human token and scoped authority | Domain tables | Read or mutate product state |
| Telemetry Event | Hermes or OpenClaw | Agent ID and ingest key | Conversation or Tool Call tables | Report runtime activity |
| Domain Event | Business mutation | Internal application boundary | Immutable event envelope in PostgreSQL | Record a typed business fact |
| Outbox Message | Domain Event transaction | Internal | Immutable PostgreSQL row | Record durable publication intent |
| Event Delivery | One intended handler | Internal worker boundary | Mutable PostgreSQL lifecycle row | Track handler-specific delivery |
| Security Audit Record | Selected Domain Event handler | Internal | Immutable PostgreSQL projection | Preserve compliance evidence |
| Cost report | LiteLLM | API-to-LiteLLM credentials | Not persisted by Costs domain | Attribute provider spend to Agents |
Runtime telemetry
Telemetry originates in the Agent runtime.
It becomes:
- Conversation Messages
- Tool Calls
Telemetry is authenticated with a per-start ingest key rather than a human Membership.
It is not automatically copied into the Domain Event outbox.
Domain Events
Domain Events are typed internal business facts.
They include:
- Event ID
- Event name and schema version
- Event Scope
- Optional Organization ID
- Actor and Subject identities
- Correlation and optional causation identity
- Bounded, secret-safe payload
Domain Event payloads must reject credentials, secrets, unsupported values, sensitive key names, and unbounded content.
Event delivery
PostgreSQL is authoritative for:
- The event
- Publication intent
- Intended handlers
- Delivery status
- Attempts
- Current bounded error
- Dead-letter reason
Redis and Dramatiq provide low-latency transport.
The delivery guarantee is at least once. A worker can fail after a handler commits its side effect but before the delivery becomes SUCCEEDED, so handlers must be idempotent.
The system does not promise:
- Exactly-once side effects
- Strict global ordering
- A distributed transaction with external providers
- Automatic replay of dead-lettered deliveries
Costs
Costs are queried from LiteLLM and joined to Agents through their LiteLLM key identity.
Costs are not calculated from:
- Conversation Messages
- Tool Calls
- Domain Events
- Kubernetes resource usage
Agent runtime architecture
An Agent is the central cross-domain orchestration boundary.
It combines:
- One Organization
- One Runtime
- One Platform
- One configured model
- One pinned shared Template or Agent Override version
- Explicit Skill assignments
- Eligible provider-derived built-in Skills
- Agent Secrets and Shared Credential references
- Platform routing and access policy
- Kubernetes runtime resources
- Ingest identity
- LiteLLM key identity
Runtime and Platform are separate
| Runtime | Slack | Teams | Telegram | Discord |
|---|---|---|---|---|
| Hermes | Yes | No | Yes | Yes |
| OpenClaw | Yes | Yes | Yes | Yes |
Runtime is the implementation executing the Agent. Platform is the communication system through which it interacts with people.
Agent start flow
Starting an Agent performs:
- 1
Load the Organization-owned Agent.
- 2
Authorize the lifecycle operation.
- 3
Resolve the pinned Template or Override version.
- 4
Render Template Markdown with Agent identity.
- 5
Resolve assigned and required Skills.
- 6
Decrypt Agent and Shared Credential payloads.
- 7
Generate runtime-specific provider configuration.
- 8
Append integration, chat-command, and role-scope policies.
- 9
Generate a fresh ingest key and runtime environment.
- 10
Build Kubernetes resources.
- 11
Apply the resources.
- 12
Mark the Agent
RUNNING.
The generated resources include:
- ConfigMap
- Secret
- PVC
- Service
- Deployment
A failed credential check or Kubernetes start can place the Agent in ERROR. A successful start clears the previous error.
Desired and realized runtime state
| State | Source of truth |
|---|---|
| Agent identity, Runtime, Platform, model, and lifecycle status | Agent Barn PostgreSQL |
| Selected Template and Skill versions | Agent Barn PostgreSQL |
| Encrypted credentials | Agent Barn PostgreSQL |
| Generated runtime configuration | Kubernetes ConfigMap and Secret |
| Running process | Kubernetes Deployment and pod |
| Workspace files | Agent PVC |
| Conversation and Tool Call history | Agent Barn PostgreSQL through Ingest |
| Provider spend | LiteLLM |
Runtime configuration is generated at start. A running Agent does not automatically receive a new runtime image, Template selection, Skill assignment, integration policy, or builder change.
Applying a runtime-relevant change requires a deliberate stop and start or Apply & Restart workflow.
Configuration and versioning
Templates
Templates are versioned Markdown configuration lineages.
- Predefined Templates are Platform Resources.
- Custom Templates belong to one Organization.
- Organization forks preserve source lineage.
- Published versions are immutable snapshots.
- Agents pin a specific version.
- Existing Agent pins do not automatically move to the latest version.
Agent Template Overrides
An Agent can have its own private Override lineage:
- One mutable draft
- Immutable published versions
- Explicit version selection
- Source-version provenance
- Apply & Restart for a running Agent
Publishing an Override does not automatically activate it.
Skills
Skills are packaged instructions or references that can be assigned to Agents and required by Templates.
Agent startup combines:
- Explicitly assigned Skills
- Template-required Skills
- Eligible built-in provider Skills
Provider requirements are validated when configuring the Agent. Changing a Skill’s provider metadata later does not retroactively revalidate every existing Agent.
Runtime snapshots
Agent startup materializes a snapshot of current configuration into Kubernetes.
This creates an intentional boundary:
Versioned source configuration
↓ explicit selection
Agent persisted configuration
↓ start or restart
Generated runtime resourcesIt prevents a new Template, Skill, provider policy, or runtime-image release from silently changing a running Agent.
Web app architecture
The web app uses Next.js App Router with feature-oriented organization.
Provider hierarchy
The root application composes shared providers including:
- URL query-state adapter
- TanStack Query provider
- Tooltip provider
- Application provider
- User context
- Organization context
Public authentication routes bypass the protected user and Organization context.
Route ownership
App Router pages are composition points.
Feature behavior belongs under:
ui/src/features/Authentication behavior belongs under:
ui/src/auth/Shared transport and query infrastructure belongs under:
ui/src/shared/API client
Normal UI calls use the shared API client.
It owns:
- Authentication token attachment and refresh
- Cookie-bearing requests
- Request keys converted to
snake_case - Response keys converted to
camelCase - Structured
ApiError - Optional feature-local Zod response validation
UI components should not create unrelated transport clients for ordinary product requests.
Organization switching
The Active Organization comes from:
/dashboard/[orgId]Platform View uses:
/dashboard/platformThe Organization provider removes known Organization-scoped query families during a genuine Organization switch so data from the previous Organization does not remain visible under the new URL.
Adding a new Organization-scoped query requires either:
- Including Organization identity in its query key, or
- Adding it to the Organization-switch eviction boundary
Agent log streaming
Agent logs are an exception to the ordinary API flow.
A dedicated Next.js route proxies backend server-sent events through a streaming response. The client log hook owns browser reconnection. This prevents ordinary proxy buffering and keeps the internal API hostname on the server.
Integrations and credentials
Agent Barn separates several credential classes.
| Credential class | Owner | Purpose |
|---|---|---|
| Deployment Secret | Platform operator | Configure databases, providers, signing, and infrastructure |
| User Slack configuration token | User | Automate Slack app creation |
| Agent Secret | One Agent | Give one runtime provider access |
| Shared Credential | Organization | Reuse one provider credential across Agents |
| LiteLLM virtual key | Agent or API service | Attribute and authorize model access |
| Ingest key | One Agent start | Authenticate runtime telemetry |
Encryption boundary
Provider payloads are:
- Validated against provider-specific schemas.
- Encrypted before persistence.
- Validated again after decryption.
- Returned through read APIs only as safe metadata.
- Decrypted during Agent start.
- Materialized into runtime-specific environment or configuration.
Credential plaintext is never returned by normal read APIs.
Runtime materialization
At start, Agent Barn can produce:
- aai-cli profiles and secret-store setup
- Google Workspace
gogconfiguration - Provider environment variables
- Built-in provider Skills
- Integration policy appended to Agent configuration
- Firecrawl platform defaults or per-Agent overrides
Storage validation is only half of an integration. Provider support must also be implemented for both runtime builders and their generated artifacts.
Deployment architecture
Helmfile deploys the platform into one Kubernetes namespace.
The general dependency order is:
PostgreSQL services and Redis
↓
LiteLLM and Firecrawl
↓
Agent Barn API hooks
↓
API and worker workloads
↓
Agent Barn UI
↓
MonitoringService workloads
| Workload | Responsibility |
|---|---|
| Product and Ingest API | HTTP contracts, orchestration, telemetry, metrics |
| API worker | Dramatiq Event Delivery processing |
| Reconciliation CronJob | Republish eligible pending or stale Event Deliveries |
| UI | Next.js application and API proxy |
| LiteLLM | Model proxy, Agent virtual keys, spend records |
| Firecrawl | Web search and scraping |
| Redis | Event Delivery and Firecrawl transport |
| Monitoring | Prometheus, Grafana, Alertmanager, kube-state-metrics |
The API image is reused for:
- Product and Ingest processes
- Worker deployment
- Reconciliation CronJob
- Alembic migration Job
These workloads run different commands but share application code and configuration contracts.
Dynamic Agent workloads
Agent Deployments are not static entries in Helmfile. The API dynamically creates and removes them through the Kubernetes client.
Each running Agent owns its runtime resources while remaining part of the same agent-farm or agent-farm-staging namespace.
Environment isolation
Production uses:
agent-farmStaging uses:
agent-farm-stagingEvery release and Helmfile dependency uses the selected namespace. The API also receives that namespace so it creates Agent resources in the correct environment.
Observability
The API, Ingest, LiteLLM, and Agent runtimes expose Prometheus metrics.
The namespace-scoped monitoring stack contains:
- Prometheus
- Grafana
- Alertmanager
- kube-state-metrics
It observes:
- API and Ingest availability
- HTTP requests and errors
- Application database connectivity
- Agent health and ERROR state
- Agent restarts
- Tool Call outcomes
- LiteLLM availability and usage
- OpenRouter credit state
The Product API health endpoint proves application PostgreSQL connectivity. It does not prove Redis, workers, Event Deliveries, Agent platforms, LiteLLM, Firecrawl, email, or external providers are healthy.
Application logs, Agent logs, Event Delivery state, Activity, Tool Calls, costs, and Prometheus metrics are complementary operational sources.
Where changes belong
Source map
| Concern | Start with |
|---|---|
| Domain terminology | CONTEXT.md |
| Context routing | docs/INDEX.md |
| Cross-system relationships | docs/architecture/system-map.md |
| API layering and tenancy | docs/architecture/api.md |
| UI providers and data flow | docs/architecture/ui.md |
| Runtime and deployment | docs/architecture/runtime-and-deployment.md |
| Identity and Organizations | docs/features/identity-and-organizations.md |
| Roles and Agent Access | docs/features/rbac/IMPLEMENTATION-BRIEF.md |
| Agent lifecycle and configuration | docs/features/agents.md |
| Templates and Skills | docs/features/templates-and-skills.md |
| Runtime activity and Ingest | docs/features/activity-and-ingest.md |
| Internal events and delivery | docs/features/domain-events.md |
| Cost attribution | docs/features/costs.md |
| Provider credentials | docs/features/integrations.md |
| Hard-to-reverse rationale | docs/adr/ |
| Repeatable implementation rules | docs/guidelines/ |
Choose the authoritative document
| Information | Authoritative location |
|---|---|
| Current behavior and invariants | Feature or architecture document |
| Canonical product language | CONTEXT.md |
| Repeatable engineering convention | Matching guideline |
| Consequential architectural rationale | ADR |
| Active multi-ticket delivery state | Feature changelog |
| Proposed work | Issue tracker or plan |
Do not treat an implementation plan as proof that a feature is delivered.
Change-impact questions
Before changing a boundary, ask:
- Does it affect Organization tenancy?
- Does it expose an Agent or subordinate resource?
- Does it require a new Permission?
- Does it change the Agent start snapshot?
- Does it affect both Hermes and OpenClaw?
- Does it affect every supported Platform?
- Does it change encrypted credential compatibility?
- Does it change a persisted schema?
- Does it require an Alembic migration?
- Does it produce a Domain Event?
- Does the business mutation need one explicit transaction?
- Does it change runtime telemetry?
- Does it affect cost attribution?
- Does the UI need a Zod schema or query-cache update?
- Does the deployment or monitoring contract change?
- Do authoritative docs need to move with the code?
Architecture invariants
Keep these invariants intact unless the change deliberately revises the documented contract:
- Organization is the user-visible tenant boundary.
- Platform authority and Organization authority remain separate.
- Agent authorization covers the complete Agent aggregate.
- Routes remain thin.
- Services own orchestration.
- Repositories own persistence and tenant visibility.
- Infrastructure adapters own external systems.
- Runtime and Platform remain separate.
- Running Agent configuration changes only through deliberate lifecycle action.
- Telemetry Events remain separate from Domain Events.
- PostgreSQL remains authoritative for Domain Event delivery state.
- Event Handlers remain idempotent under at-least-once delivery.
- Costs remain sourced from LiteLLM.
- Secret plaintext is never returned through read APIs.
- Schema changes include Alembic migrations.
- API, UI, runtime, tests, deployment, and documentation move together when a contract crosses those boundaries.
Next steps
Continue with the API guide to understand route registration, request contracts, service orchestration, repository visibility, dependency injection, and integration patterns.
Develop against the API