From e15864f82f143137d4e7376a069a701ced9f9054 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Mon, 12 Oct 2026 21:31:38 +0530 Subject: [PATCH] build(standards): rebuild bundle and collect docs (build_recipe module, start-an-app page) --- standards/lib/01_build_recipe/index.html | 999 ++++++++++++++++++ standards/lib/02_layering_rules/index.html | 24 +- standards/lib/03_composition_root/index.html | 22 + .../lib/04_spec_first_routing/index.html | 22 + standards/lib/05_crud_template/index.html | 22 + standards/lib/06_pipeline_scaffold/index.html | 22 + .../lib/07_worker_and_progress/index.html | 22 + standards/lib/08_human_in_loop/index.html | 22 + standards/lib/09_infra_adaptors/index.html | 22 + standards/lib/12_genericity_matrix/index.html | 22 + standards/lib/13_library_registry/index.html | 22 + standards/lib/404.html | 22 + standards/lib/index.html | 25 +- standards/lib/search/search_index.json | 2 +- standards/mcp/index.json | 2 +- standards/mcp/modules/build_recipe.json | 8 + standards/mcp/modules/index.json | 2 +- standards/mcp/nav.json | 5 + standards/wiki/01_overview/index.html | 10 +- standards/wiki/02_components/index.html | 12 +- standards/wiki/03_build_recipe/index.html | 831 --------------- standards/wiki/03_start_an_app/index.html | 649 ++++++++++++ .../wiki/04_development/01_testing/index.html | 12 +- standards/wiki/404.html | 8 +- standards/wiki/index.html | 18 +- standards/wiki/search/search_index.json | 2 +- 26 files changed, 1962 insertions(+), 867 deletions(-) create mode 100644 standards/lib/01_build_recipe/index.html create mode 100644 standards/mcp/modules/build_recipe.json delete mode 100644 standards/wiki/03_build_recipe/index.html create mode 100644 standards/wiki/03_start_an_app/index.html diff --git a/standards/lib/01_build_recipe/index.html b/standards/lib/01_build_recipe/index.html new file mode 100644 index 0000000..b86b6d7 --- /dev/null +++ b/standards/lib/01_build_recipe/index.html @@ -0,0 +1,999 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Build Recipe - Aetos Standards — Reference + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + +

Build Recipe

+

Summary

+

The ordered, deterministic checklist for generating a new application of the +standard shape. Every step is fixed; only the resource model (step 2) and the +pipeline family (step 7) need app-specific authoring.

+

This page is served by the standards MCP as doc://modules/build_recipe. The +start_app prompt on that server collects the two axes and hands off here; pull +exact files with get_app_component.

+
+

🚀 Bootstrap

+

From the standards docs checkout:

+
1
+2
cp -r <docs>/standards/src/templates/app apps/<your-app>
+cd apps/<your-app>
+
+

Install the internal libraries — editable local checkouts (preferred in +development) or the private index (CI / fresh machines). Credentials are +environment-only; never commit them.

+
1
+2
+3
+4
+5
+6
# local checkouts
+pip install -e ../aetos/openapi-first -e ../aetos/mongo-ops -e ../aetos/hexa \
+            -e ../aetos/dagpipe -e ../aetos/doc-forge
+# private index
+pip install --extra-index-url \
+  "https://$PIP_REGISTRY_USERNAME:$PIP_REGISTRY_PASSWORD@pip.aetoskia.com/simple" .
+
+
+

📋 Agent prompt (copyable)

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
# Build a new application from the Aetos Standards blueprint
+
+You are coding a complete new backend application conforming to the Aetos
+standard app blueprint. Execute every step in order. Only steps 2 and 3 use the
+app-specific details provided by the user; everything else is deterministic.
+
+## Before writing any code
+
+Connect to the `standards` MCP server and read:
+- `doc://nav` (the module list)
+- `doc://modules/genericity_matrix` (Tier A library / Tier B template / Tier C authored)
+- `doc://modules/layering_rules` (the dependency rules)
+
+Then:
+- call `find_library` with `db`, `di`, `routing`, `ingestion`, `pipeline`, `docs`
+  and note the Tier A libraries that already exist — never reimplement one;
+- call `list_app_components()` and pull each file you need with
+  `get_app_component(kind, resource=..., family=...)` instead of writing it from
+  scratch.
+
+## Steps
+
+1. **Scaffold** — copy `standards/src/templates/app/` into `apps/<your-app>/`.
+   Keep the tree: `domain/`, `infra/`, `interfaces/`, `pipelines/`, `tests/`,
+   `scripts/`, plus `pyproject.toml`, `openapi.yaml`, `config.py`, `init.py`,
+   `main.py`, `worker.py`, `Dockerfile`, `docker-compose.yaml`, `.env.example`.
+
+2. **Author the spec (app-specific)** — write `openapi.yaml`: resources,
+   schemas, `operationId`s, security, and extension metadata. This is the
+   contract and drives all routing.
+
+3. **Write each CRUD slice (app-specific)** — per resource create the four-file
+   slice: `models.py`, `ports/db.py`, `ports/service.py`, and optional
+   `converters.py`. Follow the CRUD template.
+
+4. **Wire the composition root** — in `init.py`, build leaf repositories, then
+   dependent repositories, then services; add infra adapters (db, cache, stores,
+   progress bus, fetchers). Expose `get_svc` overloads.
+
+5. **Add routes** — create `interfaces/<resource>/routes.py` thin handlers bound
+   to `operationId`s and re-export them in `interfaces/openapi.py`. Add the cache
+   decorator to read endpoints.
+
+6. **Bootstrap app and worker** — confirm `main.py` runs the OpenAPI-first app
+   with its lifespan. If the app has long-running jobs, adapt `worker.py` to poll
+   the job collection, run the pipeline, and publish progress.
+
+7. **Add pipeline families (only if data-driven)** — copy `pipelines/example/`
+   to `pipelines/<family>/` with `abc.py`, `impl.py`, `pipeline.yaml`,
+   `resources/`, and reuse `pipelines/shared/` (loader + registry). Register the
+   root. Add fixtures and a parity test.
+
+8. **Add infrastructure only where needed** — Tier A capability: use the
+   library. Tier B capability: copy the template. Never hand-write a Tier A
+   library.
+
+9. **Tests** — integration tests with fakes at the HTTP edge; unit tests for
+   domain and pipeline logic; a config-consistency test for rule-driven
+   pipelines.
+
+10. **Scripts and seeds** — operator scripts under `scripts/` using
+    `init()` / `get_svc()` / `shutdown()`; run as `python -m scripts.<name>`.
+
+11. **Docs** — author GSDFC docstrings, generate `.pyi` stubs, mark the package
+    `py.typed`, and build the docs.
+
+**Definition of done:**
+- `python -c "import main"` succeeds.
+- `pytest` passes.
+- The app serves every operation in the spec; the worker drains its queue.
+- No domain module imports a web framework.
+- No Tier A library was reimplemented.
+
+
+

🧭 Where the steps land

+

The steps map onto the layers as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StepPackage / fileDepends on
1 · Scaffoldwhole templates/app/—
2 · Specopenapi.yaml—
3 · CRUD slicesdomain/<resource>/spec, CRUD template
4 · Wiringinit.pyevery slice
5 · Routesinterfaces/<resource>/services, openapi route registry
6 · Bootstrapmain.py, worker.pycomposition root
7 · Pipelinespipelines/<family>/, shared/library pipeline engine
8 · Infrainfra/domain ports
9 · Teststests/app + fixtures
10 · Scriptsscripts/composition root
11 · Docsdocstrings + docs buildcode, Doc Forge
+
+

⚠️ Definition of done

+
    +
  • python -c "import main" succeeds.
  • +
  • pytest passes.
  • +
  • The app serves the spec's operations; the worker drains its queue.
  • +
  • No domain module imports a web framework.
  • +
  • No Tier A library was reimplemented.
  • +
+
+ + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/standards/lib/02_layering_rules/index.html b/standards/lib/02_layering_rules/index.html index fac1c8d..a761543 100644 --- a/standards/lib/02_layering_rules/index.html +++ b/standards/lib/02_layering_rules/index.html @@ -11,7 +11,7 @@ - + @@ -244,6 +244,28 @@ + + +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + diff --git a/standards/lib/03_composition_root/index.html b/standards/lib/03_composition_root/index.html index 5c67d48..c4ed3af 100644 --- a/standards/lib/03_composition_root/index.html +++ b/standards/lib/03_composition_root/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/04_spec_first_routing/index.html b/standards/lib/04_spec_first_routing/index.html index 9770476..6fb32ec 100644 --- a/standards/lib/04_spec_first_routing/index.html +++ b/standards/lib/04_spec_first_routing/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/05_crud_template/index.html b/standards/lib/05_crud_template/index.html index d535a1e..49c09c2 100644 --- a/standards/lib/05_crud_template/index.html +++ b/standards/lib/05_crud_template/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/06_pipeline_scaffold/index.html b/standards/lib/06_pipeline_scaffold/index.html index 8dff635..fcb6c29 100644 --- a/standards/lib/06_pipeline_scaffold/index.html +++ b/standards/lib/06_pipeline_scaffold/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/07_worker_and_progress/index.html b/standards/lib/07_worker_and_progress/index.html index dabe4b1..965826c 100644 --- a/standards/lib/07_worker_and_progress/index.html +++ b/standards/lib/07_worker_and_progress/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/08_human_in_loop/index.html b/standards/lib/08_human_in_loop/index.html index 9279a51..6eaedab 100644 --- a/standards/lib/08_human_in_loop/index.html +++ b/standards/lib/08_human_in_loop/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/09_infra_adaptors/index.html b/standards/lib/09_infra_adaptors/index.html index e6309eb..d2a91d7 100644 --- a/standards/lib/09_infra_adaptors/index.html +++ b/standards/lib/09_infra_adaptors/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/12_genericity_matrix/index.html b/standards/lib/12_genericity_matrix/index.html index 26b7d2e..b443fe0 100644 --- a/standards/lib/12_genericity_matrix/index.html +++ b/standards/lib/12_genericity_matrix/index.html @@ -246,6 +246,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/13_library_registry/index.html b/standards/lib/13_library_registry/index.html index bb820b4..08316ee 100644 --- a/standards/lib/13_library_registry/index.html +++ b/standards/lib/13_library_registry/index.html @@ -244,6 +244,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/404.html b/standards/lib/404.html index 847dfff..4da309b 100644 --- a/standards/lib/404.html +++ b/standards/lib/404.html @@ -237,6 +237,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • diff --git a/standards/lib/index.html b/standards/lib/index.html index 8780c27..5b7ed12 100644 --- a/standards/lib/index.html +++ b/standards/lib/index.html @@ -12,7 +12,7 @@ - + @@ -254,6 +254,28 @@ +
  • + + + + + + Build Recipe + + + + + +
  • + + + + + + + + +
  • @@ -506,6 +528,7 @@

    The reference half of the Standards description: the enforceable rules, patterns, and the internal library catalog that agents consult while coding.


    © Aetoskia Internal — standards

    diff --git a/standards/wiki/search/search_index.json b/standards/wiki/search/search_index.json index b8ab9db..3d999d6 100644 --- a/standards/wiki/search/search_index.json +++ b/standards/wiki/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde9 Standards \u2014 the Aetos App Blueprint","text":"

    One reusable architecture for every backend application in the Aetos ecosystem: a spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure layer, and a single composition root.

    Fill in two axes only and a new app is done: your resource model, and (if needed) your pipeline family. The blueprint itself never names a business domain \u2014 expenses, health metrics, inventory, and analytics are all the same shape underneath.

    Doc model: this wiki is written for humans \u2014 how-to guides, the build recipe, and quality gates. The enforceable rules (layering, composition root, CRUD template, pipeline scaffold) and the library registry live in the reference pages, mirrored by the machine-readable standards MCP bundle. Query find_library before writing any infrastructure.

    "},{"location":"#key-features","title":"\ud83d\ude80 Key Features","text":""},{"location":"#documentation-structure","title":"\ud83d\udcc1 Documentation Structure","text":"Section Description Overview Philosophy, the one-way dependency rule, architecture App Components The component model and how the pieces wire together Build Recipe The ordered, agentic checklist for a new app Testing & Quality Test layout and acceptance gates

    Reference (separate site, mirrors the MCP bundle): the enforceable rules \u2014 Layering, Composition Root, Spec-First Routing, CRUD Template, Pipeline Scaffold, Worker & Progress, Human-in-the-Loop, Infra Adapters, Genericity Matrix, Library Registry.

    "},{"location":"#related-resources","title":"\ud83d\udd17 Related Resources","text":"

    \u00a9 Aetoskia Internal \u2014 standards

    "},{"location":"01_overview/","title":"Overview","text":"

    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.

    "},{"location":"01_overview/#architecture","title":"\ud83c\udfd7\ufe0f Architecture","text":"
    flowchart LR\n    subgraph EDGE[\"interfaces/ \u2014 HTTP edge\"]\n        OAS[\"openapi.yaml<br/>operationId contract\"]\n        RT[\"<resource>/routes.py<br/>thin handlers\"]\n    end\n\n    subgraph CORE[\"domain/ \u2014 business core\"]\n        MD[\"models\"]\n        PT[\"ports (adapter binding seam)\"]\n        SV[\"services\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        RP[\"mongo repos (mongo-ops)\"]\n        AD[\"cache \u00b7 stores \u00b7 llm \u00b7 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

    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 \u2014 solid arrows are compile-time calls; dotted arrows are the port/adapter binding, performed by the composition root at startup.

    "},{"location":"01_overview/#the-one-way-dependency-rule","title":"\ud83d\udd04 The one-way dependency rule","text":"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 \u2014 init.py everything (the wiring point) \u2014"},{"location":"01_overview/#core-principles","title":"\ud83e\udded Core principles","text":"
    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 \u2014 see the Library Registry.
    6. Explicit state machines. Long-running work moves through explicit, durable statuses and can pause for human input.
    "},{"location":"01_overview/#runtime-processes","title":"\u2699\ufe0f Runtime processes","text":"

    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.<name> one-shot operator tasks"},{"location":"01_overview/#read-next","title":"\u27a1\ufe0f Read Next","text":""},{"location":"02_components/","title":"App Components","text":"

    What ships in every standard app, and how the pieces relate. This is the blueprint's component model \u2014 templates/app/ is a runnable instance of it.

    "},{"location":"02_components/#component-model","title":"\ud83d\uddc2\ufe0f Component model","text":"

    The blueprint has two orthogonal views: runtime flow (who calls whom) and composition-root wiring (who constructs whom). Keeping them separate makes the layering visible instead of hiding it behind a hub.

    "},{"location":"02_components/#runtime-flow","title":"\ud83d\udd00 Runtime flow","text":"

    Who calls whom at request and job time:

    %%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    subgraph REQ[\"Request path \u2014 API process\"]\n        direction LR\n        CL([\"Client<br/>operationId\"]) --> RT[\"interfaces/&lt;resource&gt;/routes.py\"]\n        RT --> SVC[\"&lt;resource&gt;_svc\"]\n        SVC --> REPO[\"&lt;resource&gt;_repo\"]\n    end\n\n    subgraph WRK[\"Background path \u2014 worker process\"]\n        direction LR\n        W[\"worker.py\"] --> JSVC[\"job_svc\"]\n        W --> PIPE[\"pipelines/&lt;family&gt;\"]\n        PIPE --> ISVC[\"item_svc\"]\n        JSVC --> JREPO[\"job_repo\"]\n        ISVC --> IREPO[\"item_repo\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        MONGO[(\"MongoDB / mongo_ops\")]\n    end\n\n    REPO --> MONGO\n    JREPO --> MONGO\n    IREPO --> MONGO

    Legend \u2014 solid arrows are runtime calls. Nothing is self-constructed.

    "},{"location":"02_components/#composition-root-wiring","title":"\ud83e\uddf5 Composition-root wiring","text":"

    Who constructs what at startup:

    %%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    INIT[\"init.py \u2014 composition root\"]\n    SETUP[\"infra/db/setup.py\"]\n    FACT[\"domain/*/ports/*<br/>factory seams\"]\n    REPOS[\"repos<br/>infra/db/repos/mongo.py\"]\n    SVCES[\"services<br/>CrudsServiceAdaptor\"]\n    STATE[\"app.state.db_resources\"]\n    HEXA[\"hexa.build\"]\n    RT[\"routes.py\"]\n    WK[\"worker.py\"]\n\n    INIT --> SETUP\n    INIT --> FACT\n    FACT --> REPOS\n    FACT --> SVCES\n    REPOS --> SVCES\n    HEXA -.-> SVCES\n    INIT --> STATE\n    STATE --> RT\n    INIT --> WK

    Legend \u2014 init.py is the only place that imports concrete adapters. The ports/ factory seams bind infra; the API reads resources from app.state.db_resources, the worker calls init() directly.

    "},{"location":"02_components/#component-roles","title":"\ud83d\udce6 Component roles","text":""},{"location":"02_components/#1-interfaces-the-edge","title":"1. interfaces/ \u2014 the edge","text":"

    Thin handlers bound to openapi.yaml operationIds. They parse the request, call a service, and shape the response. No business rules, no I/O.

    "},{"location":"02_components/#2-domain-the-core","title":"2. domain/ \u2014 the core","text":"

    Models, ports, and services (use cases). No framework imports. The ports/ package is the one seam allowed to reach into infra/: each port module declares the document shape and a factory that binds the adapter.

    "},{"location":"02_components/#3-infra-the-adapters","title":"3. infra/ \u2014 the adapters","text":"

    Concrete implementations of the domain ports plus cross-cutting infrastructure:

    "},{"location":"02_components/#4-pipelines-data-driven-families-optional","title":"4. pipelines/ \u2014 data-driven families (optional)","text":"

    Extraction and enrichment families, each a deterministic step chain (abc.py / impl.py / pipeline.yaml / resources/). Roots are registered in the pattern registry and driven either by a worker job or a CLI.

    "},{"location":"02_components/#5-workerpy-the-job-worker-optional","title":"5. worker.py \u2014 the job worker (optional)","text":"

    A separate process that polls durable job collections, runs pipeline roots, and publishes progress to the progress bus. It shares the same composition root as the API.

    "},{"location":"02_components/#6-initpy-the-composition-root","title":"6. init.py \u2014 the composition root","text":"

    The only place anything is constructed: leaf repositories \u2192 dependent repositories \u2192 services \u2192 adapters. Exposes get_svc overloads and starts / stops resources on the app lifespan.

    "},{"location":"02_components/#how-the-request-flows","title":"\ud83d\udd17 How the request flows","text":"
    sequenceDiagram\n    participant C as Client\n    participant R as route (interfaces)\n    participant S as service (port factory / adapter)\n    participant P as repo (infra)\n    participant DB as MongoDB\n\n    C->>R: POST /items (operationId)\n    R->>S: svc.create(payload)\n    S->>P: repo.insert(doc)\n    P->>DB: insert\n    DB-->>P: ack\n    P-->>S: doc\n    S-->>R: result\n    R-->>C: 200 JSON
    "},{"location":"02_components/#related","title":"Related","text":""},{"location":"03_build_recipe/","title":"Build Recipe","text":"

    The ordered, deterministic checklist for generating a new application of the standard shape. Every step is fixed; only steps 2 and 3 need app-specific authoring. Give an AI agent the copyable prompt below (or read it from the standards MCP bundle as doc://modules/build_recipe) and it can produce a complete app in one pass.

    "},{"location":"03_build_recipe/#quick-start","title":"\ud83d\ude80 Quick start","text":"
    # Copy the runnable skeleton (from the standards docs checkout)\ncp -r <docs>/standards/src/templates/app apps/<your-app>\ncd apps/<your-app>\n

    Then follow the numbered steps in the prompt.

    "},{"location":"03_build_recipe/#agent-prompt-copyable","title":"\ud83d\udccb Agent prompt (copyable)","text":"
    # Build a new application from the Aetos Standards blueprint\n\nYou are coding a complete new backend application conforming to the Aetos\nstandard app blueprint. Execute every step in order. Only steps 2 and 3 use the\napp-specific details provided by the user; everything else is deterministic.\n\nBefore writing any code, connect to the `standards` MCP server and read:\n- `doc://nav` (the module list)\n- `doc://modules/layering_rules` (the dependency rules)\n- `doc://modules/genericity_matrix` (what is generic vs app-specific)\nThen call `find_library` with capabilities like `db`, `di`, `routing`,\n`ingestion`, `auth`, `docs`, `pipeline`, and note the libraries that already\nexist. Never reimplement one.\n\n1. **Scaffold** \u2014 copy `src/templates/app/` into `apps/<your-app>/`. Keep the\n   package tree: `domain/`, `infra/`, `interfaces/`, `pipelines/`, `tests/`,\n   `scripts/`, plus `pyproject.toml`, `openapi.yaml`, `config.py`, `init.py`,\n   `main.py`, `worker.py`, `Dockerfile`, `docker-compose.yaml`, `.env.example`.\n\n2. **Author the spec (app-specific)** \u2014 write `openapi.yaml`: resources,\n   schemas, `operationId`s, security, and extension metadata. This is the\n   contract and drives all routing.\n\n3. **Write each CRUD slice (app-specific)** \u2014 per resource create the\n   four-file slice: `models.py`, `ports/db.py`, `ports/service.py`, and\n   optional `converters.py`. Follow the CRUD template.\n\n4. **Wire the composition root** \u2014 in `init.py`, build leaf repositories, then\n   dependent repositories, then services; add infra adapters (db, cache,\n   stores, progress bus, fetchers). Expose `get_svc` overloads.\n\n5. **Add routes** \u2014 create `interfaces/<resource>/routes.py` thin handlers\n   bound to `operationId`s and re-export them in `interfaces/openapi.py`. Add\n   the cache decorator to read endpoints.\n\n6. **Bootstrap app and worker** \u2014 confirm `main.py` runs the OpenAPI-first app\n   with its lifespan. If the app has long-running jobs, adapt `worker.py` to\n   poll the job collection, run the pipeline, and publish progress.\n\n7. **Add pipeline families (only if data-driven)** \u2014 create\n   `pipelines/<family>/` with `abc.py`, `impl.py`, `pipeline.yaml`,\n   `resources/`, and register the root. Add fixtures and a parity test.\n\n8. **Add infrastructure only where needed** \u2014 prefer a library-backed adapter.\n   Never hand-write what an internal library already provides.\n\n9. **Tests** \u2014 integration tests with fakes at the HTTP edge; unit tests for\n   domain and pipeline logic; a config-consistency test for rule-driven\n   pipelines.\n\n10. **Scripts and seeds** \u2014 operator scripts under `scripts/` using\n    `init()` / `get_svc()` / `shutdown()`.\n\n11. **Docs** \u2014 author GSDFC docstrings, generate `.pyi` stubs, mark the package\n    `py.typed`, and build the docs.\n\n**Definition of done:**\n- `python -c \"import main\"` succeeds.\n- `pytest` passes.\n- The app serves every operation in the spec; the worker drains its queue.\n- No domain module imports a web framework.\n- No infrastructure was reimplemented that a library already provides.\n
    "},{"location":"03_build_recipe/#where-the-steps-land","title":"\ud83e\udded Where the steps land","text":"

    The steps map onto the layers as follows:

    Step Package / file Depends on 1 \u00b7 Scaffold whole templates/app/ \u2014 2 \u00b7 Spec openapi.yaml \u2014 3 \u00b7 CRUD slices domain/<resource>/ spec, CRUD template 4 \u00b7 Wiring init.py every slice 5 \u00b7 Routes interfaces/<resource>/ services, openapi route registry 6 \u00b7 Bootstrap main.py, worker.py composition root 7 \u00b7 Pipelines pipelines/<family>/ library pipeline engine 8 \u00b7 Infra infra/ domain ports 9 \u00b7 Tests tests/ app + fixtures 10 \u00b7 Scripts scripts/ composition root 11 \u00b7 Docs docstrings + docs build code, Doc Forge"},{"location":"03_build_recipe/#definition-of-done","title":"\u26a0\ufe0f Definition of done","text":""},{"location":"03_build_recipe/#related","title":"Related","text":""},{"location":"04_development/01_testing/","title":"Testing & Quality Gates","text":"

    Two suites run under pytest with asyncio auto mode: integration (the HTTP edge against fakes) and unit (pure domain and pipeline logic). Finish a blueprint app only when every gate below passes.

    "},{"location":"04_development/01_testing/#layout","title":"\ud83d\uddc2\ufe0f Layout","text":"
    tests/\n    integration/     # TestClient(app) + mocked resources\n    unit/            # models, converters, pipeline stages/roots\n    conftest.py      # fixtures\n
    "},{"location":"04_development/01_testing/#integration-tests","title":"\ud83d\ude80 Integration tests","text":"
    client = TestClient(app)\napp.state.db_resources = {\"item_svc\": FakeItemService(), ...}\n\ndef test_create_item():\n    r = client.post(\"/items\", json={\"name\": \"x\"})\n    assert r.status_code == 200\n
    "},{"location":"04_development/01_testing/#unit-tests","title":"\ud83e\uddea Unit tests","text":""},{"location":"04_development/01_testing/#config-consistency-tests","title":"\ud83d\udd10 Config-consistency tests","text":"

    For rule-driven pipelines, add a test that cross-references rules against the declared pattern registry: every flag emitted must be defined; every defined flag must be reachable. This catches drift without running the pipeline.

    "},{"location":"04_development/01_testing/#quality-gates","title":"\u2705 Quality gates","text":"

    A definition of done for any standard app:

    "},{"location":"04_development/01_testing/#conventions","title":"\ud83d\udca1 Conventions","text":""},{"location":"04_development/01_testing/#related","title":"Related","text":""}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde9 Standards \u2014 the Aetos App Blueprint","text":"

    One reusable architecture for every backend application in the Aetos ecosystem: a spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure layer, and a single composition root.

    Fill in two axes only and a new app is done: your resource model, and (if needed) your pipeline family. The blueprint itself never names a business domain \u2014 expenses, health metrics, inventory, and analytics are all the same shape underneath.

    Doc model: this wiki is written for humans \u2014 how-to guides, the build recipe, and quality gates. The enforceable rules (layering, composition root, CRUD template, pipeline scaffold) and the library registry live in the reference pages, mirrored by the machine-readable standards MCP bundle. Query find_library before writing any infrastructure.

    "},{"location":"#key-features","title":"\ud83d\ude80 Key Features","text":""},{"location":"#documentation-structure","title":"\ud83d\udcc1 Documentation Structure","text":"Section Description Overview Philosophy, the one-way dependency rule, architecture App Components The component model and how the pieces wire together Start an App The entry point: gather the two axes, then build Testing & Quality Test layout and acceptance gates

    Reference (separate site, mirrors the MCP bundle): the enforceable rules \u2014 Build Recipe, Layering, Composition Root, Spec-First Routing, CRUD Template, Pipeline Scaffold, Worker & Progress, Human-in-the-Loop, Infra Adapters, Genericity Matrix, Library Registry.

    "},{"location":"#related-resources","title":"\ud83d\udd17 Related Resources","text":"

    \u00a9 Aetoskia Internal \u2014 standards

    "},{"location":"01_overview/","title":"Overview","text":"

    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.

    "},{"location":"01_overview/#architecture","title":"\ud83c\udfd7\ufe0f Architecture","text":"
    flowchart LR\n    subgraph EDGE[\"interfaces/ \u2014 HTTP edge\"]\n        OAS[\"openapi.yaml<br/>operationId contract\"]\n        RT[\"<resource>/routes.py<br/>thin handlers\"]\n    end\n\n    subgraph CORE[\"domain/ \u2014 business core\"]\n        MD[\"models\"]\n        PT[\"ports (adapter binding seam)\"]\n        SV[\"services\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        RP[\"mongo repos (mongo-ops)\"]\n        AD[\"cache \u00b7 stores \u00b7 llm \u00b7 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

    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 \u2014 solid arrows are compile-time calls; dotted arrows are the port/adapter binding, performed by the composition root at startup.

    "},{"location":"01_overview/#the-one-way-dependency-rule","title":"\ud83d\udd04 The one-way dependency rule","text":"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 \u2014 init.py everything (the wiring point) \u2014"},{"location":"01_overview/#core-principles","title":"\ud83e\udded Core principles","text":"
    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 \u2014 see the Library Registry.
    6. Explicit state machines. Long-running work moves through explicit, durable statuses and can pause for human input.
    "},{"location":"01_overview/#runtime-processes","title":"\u2699\ufe0f Runtime processes","text":"

    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.<name> one-shot operator tasks"},{"location":"01_overview/#read-next","title":"\u27a1\ufe0f Read Next","text":""},{"location":"02_components/","title":"App Components","text":"

    What ships in every standard app, and how the pieces relate. This is the blueprint's component model \u2014 templates/app/ is a runnable instance of it.

    "},{"location":"02_components/#component-model","title":"\ud83d\uddc2\ufe0f Component model","text":"

    The blueprint has two orthogonal views: runtime flow (who calls whom) and composition-root wiring (who constructs whom). Keeping them separate makes the layering visible instead of hiding it behind a hub.

    "},{"location":"02_components/#runtime-flow","title":"\ud83d\udd00 Runtime flow","text":"

    Who calls whom at request and job time:

    %%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    subgraph REQ[\"Request path \u2014 API process\"]\n        direction LR\n        CL([\"Client<br/>operationId\"]) --> RT[\"interfaces/&lt;resource&gt;/routes.py\"]\n        RT --> SVC[\"&lt;resource&gt;_svc\"]\n        SVC --> REPO[\"&lt;resource&gt;_repo\"]\n    end\n\n    subgraph WRK[\"Background path \u2014 worker process\"]\n        direction LR\n        W[\"worker.py\"] --> JSVC[\"job_svc\"]\n        W --> PIPE[\"pipelines/&lt;family&gt;\"]\n        PIPE --> ISVC[\"item_svc\"]\n        JSVC --> JREPO[\"job_repo\"]\n        ISVC --> IREPO[\"item_repo\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        MONGO[(\"MongoDB / mongo_ops\")]\n    end\n\n    REPO --> MONGO\n    JREPO --> MONGO\n    IREPO --> MONGO

    Legend \u2014 solid arrows are runtime calls. Nothing is self-constructed.

    "},{"location":"02_components/#composition-root-wiring","title":"\ud83e\uddf5 Composition-root wiring","text":"

    Who constructs what at startup:

    %%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    INIT[\"init.py \u2014 composition root\"]\n    SETUP[\"infra/db/setup.py\"]\n    FACT[\"domain/*/ports/*<br/>factory seams\"]\n    REPOS[\"repos<br/>infra/db/repos/mongo.py\"]\n    SVCES[\"services<br/>CrudsServiceAdaptor\"]\n    STATE[\"app.state.db_resources\"]\n    HEXA[\"hexa.build\"]\n    RT[\"routes.py\"]\n    WK[\"worker.py\"]\n\n    INIT --> SETUP\n    INIT --> FACT\n    FACT --> REPOS\n    FACT --> SVCES\n    REPOS --> SVCES\n    HEXA -.-> SVCES\n    INIT --> STATE\n    STATE --> RT\n    INIT --> WK

    Legend \u2014 init.py is the only place that imports concrete adapters. The ports/ factory seams bind infra; the API reads resources from app.state.db_resources, the worker calls init() directly.

    "},{"location":"02_components/#component-roles","title":"\ud83d\udce6 Component roles","text":""},{"location":"02_components/#1-interfaces-the-edge","title":"1. interfaces/ \u2014 the edge","text":"

    Thin handlers bound to openapi.yaml operationIds. They parse the request, call a service, and shape the response. No business rules, no I/O.

    "},{"location":"02_components/#2-domain-the-core","title":"2. domain/ \u2014 the core","text":"

    Models, ports, and services (use cases). No framework imports. The ports/ package is the one seam allowed to reach into infra/: each port module declares the document shape and a factory that binds the adapter.

    "},{"location":"02_components/#3-infra-the-adapters","title":"3. infra/ \u2014 the adapters","text":"

    Concrete implementations of the domain ports plus cross-cutting infrastructure:

    "},{"location":"02_components/#4-pipelines-data-driven-families-optional","title":"4. pipelines/ \u2014 data-driven families (optional)","text":"

    Extraction and enrichment families, each a deterministic step chain (abc.py / impl.py / pipeline.yaml / resources/). Roots are registered in the pattern registry and driven either by a worker job or a CLI.

    "},{"location":"02_components/#5-workerpy-the-job-worker-optional","title":"5. worker.py \u2014 the job worker (optional)","text":"

    A separate process that polls durable job collections, runs pipeline roots, and publishes progress to the progress bus. It shares the same composition root as the API.

    "},{"location":"02_components/#6-initpy-the-composition-root","title":"6. init.py \u2014 the composition root","text":"

    The only place anything is constructed: leaf repositories \u2192 dependent repositories \u2192 services \u2192 adapters. Exposes get_svc overloads and starts / stops resources on the app lifespan.

    "},{"location":"02_components/#how-the-request-flows","title":"\ud83d\udd17 How the request flows","text":"
    sequenceDiagram\n    participant C as Client\n    participant R as route (interfaces)\n    participant S as service (port factory / adapter)\n    participant P as repo (infra)\n    participant DB as MongoDB\n\n    C->>R: POST /items (operationId)\n    R->>S: svc.create(payload)\n    S->>P: repo.insert(doc)\n    P->>DB: insert\n    DB-->>P: ack\n    P-->>S: doc\n    S-->>R: result\n    R-->>C: 200 JSON
    "},{"location":"02_components/#related","title":"Related","text":""},{"location":"03_start_an_app/","title":"\ud83d\ude80 Start an App","text":"

    This is the entry point for building a new application from the blueprint. The goal is one deterministic pass: you supply only the two axes, and the agent does the rest by reading the standards MCP, importing Tier A libraries, and copying Tier B template components.

    Doc model: this page is the human entry point. The deterministic, machine-facing checklist lives in the reference page Build Recipe, served as doc://modules/build_recipe.

    "},{"location":"03_start_an_app/#what-the-agent-needs-from-you","title":"\ud83e\uddfe What the agent needs from you","text":"

    Gather these before starting \u2014 the start_app MCP prompt asks for them:

    1. App name + one-line purpose.
    2. Axis 1 \u2014 resources. Each resource, its fields, and relationships. Paste openapi.yaml if you already have it.
    3. Axis 2 \u2014 pipelines. Only if an input needs a multi-step transformation: the families and their input formats (or \"none\").
    4. Auth needed now? Default no; auth is deferred (py-jwt only).
    5. Integrations. Mongo, ingestion formats, email, LLM provider.

    If you can state axes 1 and 2, the rest is mechanical.

    "},{"location":"03_start_an_app/#how-to-start","title":"\u25b6\ufe0f How to start","text":"

    From an MCP client connected to the standards server:

    1. Invoke the start_app prompt with no arguments to get the intake questions.
    2. Answer them, then invoke start_app(app_name=..., resources=..., pipelines=..., auth=...).
    3. The prompt hands off to doc://modules/build_recipe; the agent pulls exact files with get_app_component(kind, resource=..., family=...) and authors only the app-specific parts.

    Manual alternative \u2014 copy the skeleton and follow the reference recipe:

    cp -r <docs>/standards/src/templates/app apps/<your-app>\n
    "},{"location":"03_start_an_app/#reference","title":"\ud83d\udcda Reference","text":""},{"location":"03_start_an_app/#related","title":"Related","text":""},{"location":"04_development/01_testing/","title":"Testing & Quality Gates","text":"

    Two suites run under pytest with asyncio auto mode: integration (the HTTP edge against fakes) and unit (pure domain and pipeline logic). Finish a blueprint app only when every gate below passes.

    "},{"location":"04_development/01_testing/#layout","title":"\ud83d\uddc2\ufe0f Layout","text":"
    tests/\n    integration/     # TestClient(app) + mocked resources\n    unit/            # models, converters, pipeline stages/roots\n    conftest.py      # fixtures\n
    "},{"location":"04_development/01_testing/#integration-tests","title":"\ud83d\ude80 Integration tests","text":"
    client = TestClient(app)\napp.state.db_resources = {\"item_svc\": FakeItemService(), ...}\n\ndef test_create_item():\n    r = client.post(\"/items\", json={\"name\": \"x\"})\n    assert r.status_code == 200\n
    "},{"location":"04_development/01_testing/#unit-tests","title":"\ud83e\uddea Unit tests","text":""},{"location":"04_development/01_testing/#config-consistency-tests","title":"\ud83d\udd10 Config-consistency tests","text":"

    For rule-driven pipelines, add a test that cross-references rules against the declared pattern registry: every flag emitted must be defined; every defined flag must be reachable. This catches drift without running the pipeline.

    "},{"location":"04_development/01_testing/#quality-gates","title":"\u2705 Quality gates","text":"

    A definition of done for any standard app:

    "},{"location":"04_development/01_testing/#conventions","title":"\ud83d\udca1 Conventions","text":""},{"location":"04_development/01_testing/#related","title":"Related","text":""}]} \ No newline at end of file