Foundation
L1. Generic infrastructure with no business logic in it. The test is that another product could run on it unchanged.
Foundation
L1. The base every layer stands on.
The foundation is generic. It holds no agent logic, no workflow logic and no company rule. The test is simple: another product could run on it unchanged.
Components
| Component | Job | Consumed by |
|---|---|---|
| Application API | Serve the control API and the internal service routes. | L6, L2 |
| PostgreSQL | Hold every definition, every run and all company state. | Every layer |
| Vector index | Serve similarity search over knowledge. An extension of the same database. | L3 |
| Redis | Cache, lock and hold short-lived state. | L4, L2 |
| Queue | Hand work to a worker. | L4 |
| Event bus | Carry a fact from a producer to any number of consumers. | L4 |
| Scheduler | Start work at a time, or on a repeat. | L4 |
| Durable execution engine | Keep a run alive across a crash, a retry and a wait. | L4 |
| Object storage | Hold a file an agent read or produced. | L4, L2 |
| Authentication | Identify a person, and issue a session. | L6, plane |
| Secrets vault | Hold every credential value. | L2 |
| Observability | Logs, traces, metrics and errors, correlated by run id. | Every layer |
Rules
- No business logic here. No agent rule, no workflow rule, no company rule. If a change to a business rule requires a change in this layer, the boundary is wrong.
- The database is the tenancy boundary. Row-level security is enforced in PostgreSQL, not in a handler. A handler can forget. The database cannot.
- One durable execution engine. Not one for agents and a second for workflows.
- A secret value never leaves the vault as data. A row holds a reference. A log holds neither.
- Every log line and every trace carries the run id. A run is the unit of work, so it is the unit of debugging.
- The foundation does not know a run's meaning. It knows a run has an id, a state and a deadline. What the run does is L4's business.
- Storage is boring on purpose. One database, one cache, one bus. A new store needs a reason that the existing ones cannot meet.
What the database holds
One database, and four groups of tables.
Definitions agents · skills · workflows · triggers · tools · policies · limits
Execution runs · run_events · artifacts · approvals · policy_decisions
Company state companies · people · opportunities · projects · tasks ·
goals · metrics · activities · decisions
Knowledge documents · document_chunks · memories
Definitions are read constantly and written rarely. Execution is written constantly and read by one screen. Company state is the product. Knowledge is the index. The four have different access patterns and one connection pool, and that is fine at this scale.
Observability
Three signals, one correlation key.
| Signal | Answers | Key |
|---|---|---|
| Logs | What happened in this step? | run id, step id |
| Traces | Where did the time go? | run id |
| Metrics | Is the fleet healthy? | agent, workflow, domain |
A run that fails must be explainable from Mission Control alone. A person should not need a log search to answer "why did it stop". That is why the run row carries the error, and the event log carries the sequence.
Data model
| Table | Holds |
|---|---|
users | One employee, and the roles that set what they may do. |
secrets | One credential reference, its owner and its rotation date. The value is in the vault. |
Every other table belongs to a layer above, and is listed on that layer's page.
Risks
| Risk | Mitigation |
|---|---|
| Business logic leaks into the foundation, one convenience at a time | The test is stated above, and it is applied in review |
| A second store is added for one feature, and it becomes a source of truth | A new store needs a written reason. The default answer is the database we run |
| A secret reaches a log or an event payload | Redaction at the logger, and a rule that a tool result carries no secret |
| Run volume outgrows one database | Retention and rollup first, partitioning second. Both are cheaper than a second store |
| The vector index competes with the transactional load | It is a separate index in the same database, and it can move to a replica |
Open questions
- Is the durable execution engine self-hosted, or a managed service? The answer sets the failure mode, not the feature set.
- What is the retention for
run_events, and what is rolled up? - Does Mission Control share an identity provider with the customer product, or keep its own? A shared provider is convenient, and it is a coupling.
- Does the vector index stay in PostgreSQL at the volume knowledge will reach?
Diagram source. ac-docs/diagrams/mission-control-layers.drawio, page mission-control-foundation.
Edit that page, then run ./scripts/export-diagrams.sh mission-control-layers.
Update this page and the diagram together.