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, Communications, Agent runtimes, and infrastructure communicate
- Why the Agent domain orchestrates execution while Communications owns delivery
- How Organization and Agent authorization differ
- Where persistence and transaction boundaries live
- Why communication, 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 Agents that run through Hermes or OpenClaw. An Agent may be headless, or it may own zero or many Communication Connections to Slack, Microsoft Teams, Telegram, or Discord, which are delivered through the Communications Gateway and its Platform Plugins.
At a high level:
:8000 - PostgreSQL
- Kubernetes API → Agent Deployments
- LiteLLM → OpenRouter
- Firecrawl
- Email and OAuth providers
- Redis → Event Delivery worker
:8002Hermes or OpenClaw Agent runtime :8001 → PostgreSQL The system separates:
- Human product requests
- Communication delivery
- Runtime Tool Call 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. For the non-implementation summary of the same boundaries, see How Agent Barn fits together.
Four operational areas
Agent Barn is a monorepo with four major operational areas.
API
Three composed applications: product contracts, Runtime Tool Call telemetry, and Communications ingress, delivery, and Runtime protocol
Primary source: api/
Web app
Authenticated Organization and Platform experiences
Primary source: ui/
Agent runtimes
Execute rendered Agent configuration, claim Communication Deliveries, and call 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, .github/workflows/
These are operational boundaries, not four independently owned domain services. API domains are modules inside one codebase, they share the Agent Barn application database, and they are composed into three separate HTTP applications.
API
The API provides:
- Product HTTP routes
- Runtime Tool Call telemetry ingestion
- Provider ingress and communication delivery
- Authentication and token management
- Organization and Agent authorization
- Database persistence
- Template and Skill management
- Agent lifecycle orchestration
- Kubernetes resource creation
- LiteLLM key management
- Tool Integration credentials
- Domain Event delivery workers
- Monitoring metrics
Web app
The web app provides:
- Public authentication routes
- Organization View
- Platform View
- Agent configuration and lifecycle controls
- Communication Connection configuration
- 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
- Claim durable Communication Deliveries through the runtime-neutral protocol
- Call models through LiteLLM
- Use mounted Skills and tool Integrations
- Maintain Agent workspace state
- Push Tool Call telemetry to Ingest
- Expose health and metrics
Deployment
The deployment system owns:
- PostgreSQL, Redis, LiteLLM, Firecrawl, Product API, Ingest, Communications, 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 works from a claimed delivery:
Claimed Communication Delivery
↓
Hermes or OpenClaw
├── generated Template and policy
├── mounted Skills
├── decrypted Agent Secrets for tool Integrations
├── Agent workspace PVC
└── model request → LiteLLM → OpenRouterThe Agent runtime is a dynamically created Kubernetes workload, not code executing inside the Product API process.
Inbound communication flow
Platform provider
↓
Platform Plugin admission and normalization
↓
Communications Gateway
↓
Durable inbound Communication Delivery
├── canonical Conversation Message
└── Runtime protocol claim
↓
Hermes or OpenClawProvider message identity is idempotent within a Connection, and conversation location identity is (connection_id, channel_id).
Outbound communication flow
Hermes or OpenClaw
↓
Reply submitted against source Delivery
↓
Durable outbound Communication Delivery
↓
Source Communication Connection
↓
Platform Plugin
↓
Platform providerThe reply returns through the Connection and Platform Plugin that produced the source delivery.
Delivery guarantees
- Delivery processing is durable and at least once.
- Outbound ordering is preserved per conversation.
- Provider retries reuse stable delivery identity.
- Replies remain bound to the source Connection.
- Connection health is separate from Agent lifecycle.
See Communication Connections for the Connection lifecycle.
Internal 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.
- Memberships → User and authentication
- Organization Agent Settings
- Templates and Template Versions
- Organization Skills and Skill Versions
- Shared Credentials
- Domain Events
- Outbox Messages
- Event Deliveries
- Agent
- Runtime and lifecycle
- pinned Template or Override Version
- assigned Skill Version pins
- Agent-private Skills
- Agent Secrets and Integrations
- Communication Connections
- Platform Plugin
- Communication Deliveries
- Connection Journal
- Runtime Kubernetes resources
- Conversation Messages
- Tool Calls
- LiteLLM cost identity
Communication Connections are Agent subordinate resources for authorization, but they are not fields within the Agent aggregate. An Agent may have zero or many Connections, including several Connections for the same Platform.
Platform-owned resources
Some resources belong to Agent Barn itself rather than an Organization:
- Platform Privileges
- Predefined Platform Templates
- Platform Skills
- The Platform Plugin registry
- 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
- Bundled Platform Skills
- The predefined Platform Template catalogue
Platform Templates live in their own global table. Platform 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.
Platform Administrators do not receive implicit Organization Membership, an implicit Organization Role, or Agent access through their platform authority.
Authentication seams
Several distinct trust boundaries write to or read from the system:
| Seam | Required identity and scope |
|---|---|
| Product API user request | Authenticated user context; persisted Organization Membership for Organization routes; Organization Permissions; Agent Access for Agent and subordinate resources |
| Platform API request | Platform Administrator authority; no implicit active Organization |
| Ingest write | Agent identity; per-start Ingest key; Tool Call telemetry only |
| Runtime Communications protocol | Separate per-start protocol identity; claims and completes durable Communication Deliveries |
| Provider webhook | Platform Plugin verification; Connection-scoped provider identity |
| Driver callback | Separate non-user trust boundary |
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 (Communication Connections, conversations, Tool Calls, activity, costs, logs, Secrets, Skills, and configuration) must be accessed through the same accessible-Agent boundary.
API architecture
The API has three separately composed FastAPI applications.
| Application | Composition root | Mounted path | Responsibility |
|---|---|---|---|
| Product API | api/api_app.py | /api/v1 | User-facing product and administration operations |
| Ingest API | api/ingest_app.py | /ingest/v1 | Authenticated Runtime Tool Call telemetry |
| Communications | api/communications_app.py | /communications/v1 | Provider ingress, durable communication delivery, supervised provider sessions, and Runtime protocol |
Product runs on port 8000, Ingest on 8001, and Communications on 8002. They use separate Prometheus registries and expose separate /metrics endpoints.
Provider webhooks belong to the Communications application and are Connection-scoped. There is no provider-specific webhook route on the Product API. For route registration and request contracts, see API architecture and request boundaries and Develop against the API.
Layering
The normal dependency direction is:
routes.py
↓
service.py
↓
repository.py
↓
PostgresRepositoryDelegateServices may also call:
Kubernetes
LiteLLM
OpenRouter
Platform Plugin provider clients
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, LiteLLM, Kubernetes, Ingest, and the Communications protocol.
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
- Platform Plugin provider clients
- 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
- Organization Agent Settings
- Roles and Agent Access
- Agents and lifecycle state
- Templates and versions
- Skills and Skill Versions
- Encrypted credentials
- Communication Connections and Communication Deliveries
- Conversation Messages
- Tool Calls
- Connection Journal entries
- Domain Events, Outbox Messages, and Event Deliveries
- Security Audit Records
- Persisted model-call cost 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 |
| Conversation Message | Platform provider through the Communications Gateway | Connection-scoped provider identity | Conversation Message tables | Record canonical inbound and outbound communication |
| Tool Call telemetry | Hermes or OpenClaw | Agent ID and per-start Ingest key | Tool Call tables | Report Runtime tool execution |
| Communication Delivery | Communications Gateway | Internal Communications boundary | Durable PostgreSQL delivery rows | Track one inbound or outbound delivery attempt chain |
| 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 spend logs and OpenRouter recovery | Authorized report access | cost_record | Synchronize and attribute stored model-call costs to Agents and Organizations |
Activity has two writers
The Communications Gateway writes canonical inbound and outbound Conversation Messages. Ingest writes Tool Call telemetry. Ingest does not write Conversation Messages.
Platform Provider
↓
Communications Gateway
↓
Conversation Message repository
↓
Product read API
↓
Activity UI
Agent Runtime
↓
Ingest API
↓
Tool Call repository
↓
Product read API
↓
Activity UI- Product API provides authorized read routes for both.
- Conversation read paths preserve Connection identity.
- Tool Call correlation uses Runtime invocation identity.
- Neither Activity path writes Domain Events.
- Costs are not derived from Conversation or Tool Call rows.
Tool Call telemetry is authenticated with a per-start Ingest key rather than a human Membership, and it is not copied into the Domain Event outbox. See Activity, conversations, and runtime telemetry.
Domain Events
Domain Events are immutable typed 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. Current events include Organization Agent Settings changes and Communications operational facts; this guide does not reproduce the complete event catalogue.
Event delivery
The business mutation, its Outbox Message, and its intended Event Deliveries commit in one domain-owned transaction. 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, and reconciliation republishes eligible Event Deliveries.
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
See Domain Events, outbox, and delivery.
Costs
Cost reports query persisted model-call records populated by synchronization and recovery. Organization cost reporting requires Organization membership authority; Platform Administrator privilege does not bypass that requirement. Separate Platform cost routes provide explicitly authorized cross-Organization oversight without granting Organization content access.
Costs are not calculated from:
- Conversation Messages
- Tool Calls
- Domain Events
- Kubernetes resource usage
Agent runtime architecture
The Agent domain orchestrates execution. It does not own communication delivery.
The Agent domain owns
- Agent lifecycle
- Runtime selection
- Pinned Template or Agent Template Override Version
- Assigned Skill Version pins
- Agent Secrets and Shared Credential references for tool Integrations
- Runtime configuration assembly
- Kubernetes resources
- LiteLLM key identity
The Communications domain owns
- Platform Plugin registry
- Communication Connections
- Connection settings
- Encrypted provider credentials
- Provider sessions
- Provider admission and normalization
- Durable Communication Deliveries
- Canonical Conversation Message writes
- Connection health
- Connection diagnostics and recovery operations
Runtime and Platform are separate
Hermes and OpenClaw consume one versioned, runtime-neutral Communications protocol, and Runtimes receive protocol credentials rather than provider credentials. Platform support is supplied by trusted, release-shipped Platform Plugins.
Generic Connection persistence, CRUD, schema-driven UI, durable delivery, and Runtime adapters do not branch by Platform. A new shipped Platform normally adds one Platform Plugin, its provider client, and focused tests rather than changes to every Runtime. For current per-Platform behavior, see Compare platform compatibility; for Runtime selection, see Choose an Agent runtime.
The Platform Plugin seam
Each plugin under api/domains/communications/plugins/ owns:
- Typed settings schema
- Typed credential schema
- Credential validation
- Credential identity and uniqueness rules
- Provider admission
- Payload normalization
- Optional inbound enrichment
- Supervised ingress or webhook verification
- Outbound sending
- Optional processing feedback
- Platform capabilities and setup guidance
The registry is code-owned and currently ships Slack, Microsoft Teams, Telegram, and Discord. Platform Plugins are not dynamically installed packages.
Ingress differs by Platform: Slack uses supervised Socket Mode, Telegram supervised polling, Discord a supervised Gateway session, and Microsoft Teams an authenticated provider webhook.
Agent start flow
Starting an Agent performs:
- 1
Load the Organization-owned Agent.
- 2
Authorize the lifecycle operation.
- 3
Resolve the pinned Template or Agent Template Override Version.
- 4
Render Template Markdown with Agent identity.
- 5
Resolve assigned Skill Version pins and eligible Platform Skills.
- 6
Decrypt Agent Secrets used by tool Integrations.
- 7
Select the Hermes or OpenClaw Runtime builder.
- 8
Materialize supported tool Integration configuration.
- 9
Append tool pointers and unconditional runtime behavior policies.
- 10
Generate fresh Ingest and Communications protocol credentials.
- 11
Build and apply the Kubernetes resources, including the runtime-neutral Communications adapter.
- 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, and a successful start clears the previous error. A provider-session or Connection failure changes Connection health instead of Agent lifecycle.
Desired and realized runtime state
| State | Source of truth |
|---|---|
| Agent identity, Runtime, model, and lifecycle status | Agent Barn PostgreSQL |
| Selected Template and Skill Versions | Agent Barn PostgreSQL |
| Agent Secrets for tool Integrations | Agent Barn PostgreSQL |
| Communication Connections, settings, and provider credentials | Agent Barn PostgreSQL, owned by Communications |
| Generated runtime configuration | Kubernetes ConfigMap and Secret |
| Running process | Kubernetes Deployment and pod |
| Workspace files | Agent PVC |
| Conversation Message history | Agent Barn PostgreSQL through the Communications Gateway |
| Tool Call history | Agent Barn PostgreSQL through Ingest |
| Provider spend | Stored cost_record rows synchronized from LiteLLM, with OpenRouter missing-cost recovery |
Runtime configuration is generated at start. A running Agent does not automatically receive a new runtime image, Template selection, Skill assignment, tool Integration policy, or builder change.
Applying a runtime-relevant change requires a deliberate stop and start or Apply & Restart workflow. Connection settings and credentials are different: updating a Connection increments its revision and the Communications Gateway reconciles the provider session without restarting the Agent. See Runtime assembly and deployment.
Configuration and versioning
Templates
Templates are versioned Markdown configuration lineages.
An active Agent selects exactly one immutable Template source: a Platform Template Version, an Organization Template Version, or an Agent Template Override Version. The persistence constraint includes all three pin fields. Soft-deleted Agents can retain historical pins or be detached when an old shared lineage is purged; do not describe the active constraint as an unconditional two-foreign-key model.
- 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. They exist at three ownership levels with additive visibility:
- Platform Skills
- Organization Skills
- Agent-private Skills
Published Skill Versions are immutable, each custom lineage keeps at most one mutable draft, and Agents and Template versions pin exact versions. Bundled Platform Skills are mounted under isolated aai-<integration>/SKILL.md roots.
Agent startup combines explicitly assigned Skill Version pins, Template-required Skill Versions, and eligible Platform Skills. Provider requirements are validated when configuring the Agent; changing a Skill’s provider metadata later does not retroactively revalidate every existing Agent. See Templates, versions, overrides, and Skills.
Organization Agent Settings
Model configuration resolves across two layers:
- Organization
allowed_modelsbounds what the Organization may use. - The Organization Agent Settings default model is nullable: when it is unset, Agents follow the platform default; when it is set, it becomes the Organization-owned default.
- An Agent inherits that default unless it carries an explicit override.
The effective model is resolved at start, so it can differ from the model a currently running Agent was started with.
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, tool Integration 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 under ui/src/app/ 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
Feature hooks use the shared API transport and centralized query-key infrastructure.
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 |
| Connection credential | One Communication Connection | Authenticate one provider endpoint inside Communications |
| Agent Secret | One Agent | Give one Runtime access to a tool Integration |
| Shared Credential | Organization | Reuse one tool Integration credential across Agents |
| LiteLLM virtual key | Agent or API service | Attribute and authorize model access |
| Ingest key | One Agent start | Authenticate Runtime Tool Call telemetry |
| Communications protocol credential | One Agent start | Claim and complete durable Communication Deliveries |
Encryption boundary
Provider payloads are:
- Validated against typed schemas.
- Encrypted before persistence.
- Validated again after decryption.
- Returned through read APIs only as safe metadata.
- Decrypted by the domain that owns them.
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 - Tool Integration environment variables
- Eligible Platform Skills
- Tool Integration policy appended to Agent configuration
- Firecrawl platform defaults or per-Agent overrides
- Ingest and Communications protocol credentials
Storage validation is only half of a tool Integration: Runtime support must also exist in the 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, Communications, and worker workloads
↓
Agent Barn UI
↓
MonitoringService workloads
| Workload | Responsibility |
|---|---|
| Product API | Product HTTP contracts, orchestration, and metrics on port 8000 |
| Ingest API | Runtime Tool Call telemetry and metrics on port 8001 |
| Communications | Provider ingress, durable delivery, provider sessions, Runtime protocol, and metrics on port 8002 |
| 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, Ingest, and Communications processes
- Worker deployment
- Reconciliation CronJob
- Alembic migration Job
These workloads run different commands but share application code and configuration contracts.
Provider webhook ingress reaches the Communications service, not the Product API. Runtime protocol traffic stays internal. Operational procedures belong to the deployment guides; see Runtime assembly and deployment.
Data and infrastructure responsibilities divide as follows.
PostgreSQL
- Product state
- Communication Connections and Deliveries
- Conversation Messages
- Tool Calls
- Domain Event outbox and deliveries
- Connection Journal
Redis
- Domain Event delivery transport
- Not the source of durable Domain Event truth
LiteLLM
- Model routing
- Agent cost identity and reporting
Kubernetes
- Runtime ConfigMaps
- Runtime Secrets
- PVCs
- Services
- Deployments
Communications service
- Provider-session leases
- Provider ingress
- Outbound processing
- Connection health and metrics
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
The k3s testing deployments use:
agent-farmand:
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 Product API, Ingest, Communications, LiteLLM, and Agent runtimes expose Prometheus metrics.
The namespace-scoped monitoring stack contains:
- Prometheus
- Grafana
- Alertmanager
- kube-state-metrics
It observes:
- Product, Ingest, and Communications availability
- HTTP requests and errors
- Application database connectivity
- Connection status and delivery outcomes
- 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, Communications, workers, Event Deliveries, provider Connections, LiteLLM, Firecrawl, email, or external providers are healthy.
Application logs, Agent logs, the Connection Journal, Event Delivery state, Activity, Tool Calls, costs, and Prometheus metrics are complementary operational sources.
Where changes belong
Code map
| Concern | Source path |
|---|---|
| Product application composition | api/api_app.py |
| Ingest application composition | api/ingest_app.py |
| Communications application composition | api/communications_app.py |
| Agent lifecycle and runtime assembly | api/domains/agents/ |
| Organization Agent Settings | api/domains/agent_settings/ |
| Connections, plugins, and delivery | api/domains/communications/ |
| Conversation Message persistence | api/domains/conversations/ |
| Tool Call telemetry | api/domains/ingest/ |
| Domain Events, outbox, and delivery | api/domains/events/ |
| Skills and Skill Versions | api/domains/skills/ |
| Templates and versions | api/domains/templates/ |
| Dashboard Web Chat and authenticated SSE | api/domains/web_chat/ |
| External system adapters | api/infrastructure/ |
| App Router pages | ui/src/app/ |
| UI feature modules | ui/src/features/ |
| Shared UI transport and query keys | ui/src/shared/ |
| Hermes runtime image | hermes-base/ |
| OpenClaw runtime image | openclaw-base/ |
| Charts | helm/ |
| Release composition | helmfile.yaml.gotmpl |
| Build and deployment workflows | .github/workflows/ |
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 |
| Tool Integration 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 belong in a Platform Plugin rather than a Runtime?
- Does it change the Communications protocol version?
- 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 Tool Call 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, including subordinate Communication Connections.
- Routes remain thin.
- Services own orchestration.
- Repositories own persistence and tenant visibility.
- Infrastructure adapters own external systems.
- Runtime and Platform remain separate.
- Runtimes receive protocol credentials, not provider credentials.
- Communication Connections are Agent subordinate resources, not fields inside the Agent aggregate.
- The Communications Gateway owns canonical Conversation Message writes.
- Generated Runtime configuration changes only through deliberate lifecycle action, while Connection settings and credentials reconcile without restarting the Agent.
- Runtime telemetry remains separate from Domain Events.
- PostgreSQL remains authoritative for Domain Event delivery state.
- Event Handlers remain idempotent under at-least-once delivery.
- Cost reports read persisted model calls populated by synchronization and recovery.
- 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 APIWeb Chat ownership
The api/domains/web_chat/ domain owns dashboard chat requests, user-scoped thread history, and the authenticated SSE surface. It uses the Communications delivery pipeline and built-in Web Chat Connection. Reads require Agent activity permission; mutations require Agent update permission. This is distinct from external provider webhook authentication and runtime protocol credentials.
Dashboard Chat → Product API Web Chat domain → Communications delivery pipeline → built-in Web Chat Connection. See Dashboard Web Chat for the user workflow.