# Overview
The blueprint is a **hexagonal (ports & adapters) application** with a
**spec-first** web edge and a **single composition root**. It favors explicit
wiring over implicit magic and existing internal libraries over hand-written
infrastructure. Start here to build the mental model; the enforceable details
live in the reference pages.
---
## ๐๏ธ Architecture
```mermaid
flowchart LR
subgraph EDGE["interfaces/ โ HTTP edge"]
OAS["openapi.yaml
operationId contract"]
RT["/routes.py
thin handlers"]
end
subgraph CORE["domain/ โ business core"]
MD["models"]
PT["ports (adapter binding seam)"]
SV["services"]
end
subgraph INFRA["infra/ โ adapters"]
RP["mongo repos (mongo-ops)"]
AD["cache ยท stores ยท llm ยท mail"]
DB[("MongoDB")]
end
CR["init.py
composition root"]
OAS --> RT
RT --> SV
SV --> PT
SV --> RP
PT -. depends on .- RP
CR --- RT
CR --- SV
CR --- RP
RP --> DB
AD --- CR
```
The rule holds at every edge: code in an outer ring may depend on a ring closer
to the core, never the reverse. `domain/` never imports a web framework;
only its `ports/` seam reaches into `infra/` to bind adapters.
> **Legend** โ solid arrows are compile-time calls; dotted arrows are the
> port/adapter binding, performed by the composition root at startup.
---
## ๐ The one-way dependency rule
| Ring | May import | Never imports |
|-------------|------------------------------------|----------------------------------|
| `interfaces/` | `domain`, framework glue (glue only) | business logic, `infra` directly |
| `domain/` | its own models + its `ports/` seam (which binds `infra`/libraries) | web frameworks, `interfaces/` |
| `infra/` | `domain` ports, drivers, libraries | โ |
| `init.py` | everything (the wiring point) | โ |
---
## ๐งญ Core principles
1. **One-way dependencies.** `interfaces -> domain -> infra` is allowed; the
reverse is forbidden.
2. **Ports in the domain, adapters in infra.** A service depends on a port; the
port's factory binds the concrete adapter, and the composition root calls
those factories.
3. **One composition root.** Nothing constructs its own dependencies. All
wiring lives in one module (`init.py`) exposed as a flat resource registry.
4. **Spec-first.** The HTTP contract is declared in `openapi.yaml`; route
handlers are looked up by `operationId`. There are no decorator routers.
5. **Reuse the libraries.** Orchestration, DI, Mongo repositories, ingestion,
auth, and docs come from internal libraries โ see the [Library
Registry](../lib/13_library_registry/).
6. **Explicit state machines.** Long-running work moves through explicit,
durable statuses and can pause for human input.
---
## โ๏ธ Runtime processes
A standard app may run as up to three processes that share the same composition
root:
| Process | Entry point | Responsibility |
|---------|------------------------|-------------------------------------------|
| API | `main.py` | serve HTTP; start/stop resources via lifespan |
| Worker | `worker.py` | poll durable jobs, run pipelines, publish progress |
| Scripts | `python -m scripts.` | one-shot operator tasks |
---
## โก๏ธ Read Next
- [02 โ App Components](02_components.md) ยท [03 โ Build Recipe](03_build_recipe.md)