Versioning standard now states services must read their VERSION (e.g. a build arg) rather than hardcoding it; the compliance prompt repeats it. build_bundle also bundles src/wiki/** as wiki_-prefixed modules (e.g. docs://modules/wiki_development_releasing), so the release runbook is reachable from the MCP. Bundle grows to 22 modules.
8 lines
3.8 KiB
JSON
8 lines
3.8 KiB
JSON
{
|
||
"module": "wiki_overview",
|
||
"content": {
|
||
"path": "wiki_overview",
|
||
"docstring": "# Overview\n\nThe blueprint is a **hexagonal (ports & adapters) application** with a\n**spec-first** web edge and a **single composition root**. It favors explicit\nwiring over implicit magic and existing internal libraries over hand-written\ninfrastructure. Start here to build the mental model; the enforceable details\nlive in the reference pages.\n\n---\n\n## 🏗️ Architecture\n\n```mermaid\nflowchart LR\n subgraph EDGE[\"interfaces/ — HTTP edge\"]\n OAS[\"openapi.yaml<br/>operationId contract\"]\n RT[\"<resource>/routes.py<br/>thin handlers\"]\n end\n\n subgraph CORE[\"domain/ — business core\"]\n MD[\"models\"]\n PT[\"ports (adapter binding seam)\"]\n SV[\"services\"]\n end\n\n subgraph INFRA[\"infra/ — adapters\"]\n RP[\"mongo repos (mongo-ops)\"]\n AD[\"cache · stores · llm · mail\"]\n DB[(\"MongoDB\")]\n end\n\n CR[\"init.py<br/>composition root\"]\n\n OAS --> RT\n RT --> SV\n SV --> PT\n SV --> RP\n PT -. depends on .- RP\n CR --- RT\n CR --- SV\n CR --- RP\n RP --> DB\n AD --- CR\n```\n\nThe rule holds at every edge: code in an outer ring may depend on a ring closer\nto the core, never the reverse. `domain/` never imports a web framework;\nonly its `ports/` seam reaches into `infra/` to bind adapters.\n\n> **Legend** — solid arrows are compile-time calls; dotted arrows are the\n> port/adapter binding, performed by the composition root at startup.\n\n---\n\n## 🔄 The one-way dependency rule\n\n| Ring | May import | Never imports |\n|-------------|------------------------------------|----------------------------------|\n| `interfaces/` | `domain`, framework glue (glue only) | business logic, `infra` directly |\n| `domain/` | its own models + its `ports/` seam (which binds `infra`/libraries) | web frameworks, `interfaces/` |\n| `infra/` | `domain` ports, drivers, libraries | — |\n| `init.py` | everything (the wiring point) | — |\n\n---\n\n## 🧭 Core principles\n\n1. **One-way dependencies.** `interfaces -> domain -> infra` is allowed; the\n reverse is forbidden.\n2. **Ports in the domain, adapters in infra.** A service depends on a port; the\n port's factory binds the concrete adapter, and the composition root calls\n those factories.\n3. **One composition root.** Nothing constructs its own dependencies. All\n wiring lives in one module (`init.py`) exposed as a flat resource registry.\n4. **Spec-first.** The HTTP contract is declared in `openapi.yaml`; route\n handlers are looked up by `operationId`. There are no decorator routers.\n5. **Reuse the libraries.** Orchestration, DI, Mongo repositories, ingestion,\n auth, and docs come from internal libraries — see the [Library\n Registry](../lib/13_library_registry/).\n6. **Explicit state machines.** Long-running work moves through explicit,\n durable statuses and can pause for human input.\n\n---\n\n## ⚙️ Runtime processes\n\nA standard app may run as up to three processes that share the same composition\nroot:\n\n| Process | Entry point | Responsibility |\n|---------|------------------------|-------------------------------------------|\n| API | `main.py` | serve HTTP; start/stop resources via lifespan |\n| Worker | `worker.py` | poll durable jobs, run pipelines, publish progress |\n| Scripts | `python -m scripts.<name>` | one-shot operator tasks |\n\n---\n\n## ➡️ Read Next\n\n- [02 – App Components](02_components.md) · [03 – Start an App](03_start_an_app.md)\n",
|
||
"objects": {}
|
||
}
|
||
} |