Skip to content

Architecture and module boundaries

Last updated:

Understand the modular monolith, data ownership, and client package responsibilities.

Prerequisite: a working source setup. Identify the business owner of a use case before tracing cross-module capabilities through Contracts.

Backend organization

AGW is a modular monolith. Agw.Host supplies shared hosting; Control Plane, Data Plane, and Standalone compose the modules they need. Business modules follow Api → Application → Domain ← Infrastructure, creating only necessary layers.

LayerResponsibilityWhat to inspect
ApiReceive requests and return responsesRoutes, inputs, and outputs
ApplicationComplete a business operationAuthorization, queries, transactions, and call order
DomainHold business data and express rulesEntities, Behaviors, and DomainServices
InfrastructureConnect databases and external systemsPersistence and concrete adapters

Domain entities hold state. A Behavior handles rules within one Aggregate, while a DomainService handles rules that need facts beyond it. Application loads data, coordinates these calls, and persists changes. Ordinary CRUD stays in Application without creating a Behavior for every entity.

Data ownership

Each table has one owning module. Sharing entity types and a database does not permit direct access to another module’s tables; use that module’s published interfaces.

Each module that owns tables declares its persistence interface I<Module>DbContext in Application/Persistence. There are nine: Agents, Auth, Integrations, Jobs, Projects, Providers, Settings, Skills, and Tools. Files, Setup, and A2A own no tables and have no such interface. Within a request, one AgwDbContext instance implements these interfaces. Modules share database resources while limiting the data each can access. Cross-module calls use Contracts; approved Infrastructure adapters handle cross-module transactions.

Agw.Agents.Execution → Agw.Agents is one-way; both assemblies belong to the Agents module. Selective DDD for Agentflows does not extend to ordinary CRUD modules.

Example: updating an Agentflow

Api receives the request. Application checks access and loads the flow with all nodes and edges. Policy validates the proposed graph and returns a Decision. Behavior applies valid changes to the loaded objects, then Application saves them.

For edge rules, inspect the Agentflow Policy and Topology. For authorization or loading and saving order, inspect Application. For database implementation, inspect Infrastructure. This separates business rules from network and storage details and makes them easier to test independently.

Clients

Web and Desktop own independent route shells and builds. Business packages live in src/clients/packages. chat-core owns message semantics, chat-runtime owns execution connections and state, and chat owns DOM rendering. Mobile uses chat-native and RN-safe packages rather than DOM packages.

Identify the owning module and public entry point before adding a feature. Run pnpm test:boundaries and the backend architecture tests, dotnet test tests/Agw.Architecture.Tests, after boundary changes.

Implementation and references