@@ -0,0 +1,999 @@
<!doctype html>
< html lang = "en" class = "no-js" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width,initial-scale=1" >
< meta name = "description" content = "The rules and library registry of the standardized application blueprint." >
< link rel = "prev" href = ".." >
< link rel = "next" href = "../02_layering_rules/" >
< link rel = "icon" href = "../assets/images/favicon.png" >
< meta name = "generator" content = "mkdocs-1.6.1, mkdocs-material-9.6.23" >
< title > Build Recipe - Aetos Standards — Reference< / title >
< link rel = "stylesheet" href = "../assets/stylesheets/main.84d31ad4.min.css" >
< link rel = "stylesheet" href = "../assets/stylesheets/palette.06af60db.min.css" >
< link rel = "preconnect" href = "https://fonts.gstatic.com" crossorigin >
< link rel = "stylesheet" href = "https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback" >
< style > : root { --md-text-font : "Inter" ; --md-code-font : "JetBrains Mono" } < / style >
< script > _ _md _scope = new URL ( ".." , location ) , _ _md _hash = e => [ ... e ] . reduce ( ( ( e , _ ) => ( e << 5 ) - e + _ . charCodeAt ( 0 ) ) , 0 ) , _ _md _get = ( e , _ = localStorage , t = _ _md _scope ) => JSON . parse ( _ . getItem ( t . pathname + "." + e ) ) , _ _md _set = ( e , _ , t = localStorage , a = _ _md _scope ) => { try { t . setItem ( a . pathname + "." + e , JSON . stringify ( _ ) ) } catch ( e ) { } } < / script >
< / head >
< body dir = "ltr" data-md-color-scheme = "slate" data-md-color-primary = "deep-purple" data-md-color-accent = "cyan" >
< input class = "md-toggle" data-md-toggle = "drawer" type = "checkbox" id = "__drawer" autocomplete = "off" >
< input class = "md-toggle" data-md-toggle = "search" type = "checkbox" id = "__search" autocomplete = "off" >
< label class = "md-overlay" for = "__drawer" > < / label >
< div data-md-component = "skip" >
< a href = "#build-recipe" class = "md-skip" >
Skip to content
< / a >
< / div >
< div data-md-component = "announce" >
< / div >
< header class = "md-header md-header--shadow" data-md-component = "header" >
< nav class = "md-header__inner md-grid" aria-label = "Header" >
< a href = ".." title = "Aetos Standards — Reference" class = "md-header__button md-logo" aria-label = "Aetos Standards — Reference" data-md-component = "logo" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54" / > < / svg >
< / a >
< label class = "md-header__button md-icon" for = "__drawer" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z" / > < / svg >
< / label >
< div class = "md-header__title" data-md-component = "header-title" >
< div class = "md-header__ellipsis" >
< div class = "md-header__topic" >
< span class = "md-ellipsis" >
Aetos Standards — Reference
< / span >
< / div >
< div class = "md-header__topic" data-md-component = "header-topic" >
< span class = "md-ellipsis" >
Build Recipe
< / span >
< / div >
< / div >
< / div >
< form class = "md-header__option" data-md-component = "palette" >
< input class = "md-option" data-md-color-media = "" data-md-color-scheme = "slate" data-md-color-primary = "deep-purple" data-md-color-accent = "cyan" aria-hidden = "true" type = "radio" name = "__palette" id = "__palette_0" >
< / form >
< script > var palette = _ _md _get ( "__palette" ) ; if ( palette && palette . color ) { if ( "(prefers-color-scheme)" === palette . color . media ) { var media = matchMedia ( "(prefers-color-scheme: light)" ) , input = document . querySelector ( media . matches ? "[data-md-color-media='(prefers-color-scheme: light)']" : "[data-md-color-media='(prefers-color-scheme: dark)']" ) ; palette . color . media = input . getAttribute ( "data-md-color-media" ) , palette . color . scheme = input . getAttribute ( "data-md-color-scheme" ) , palette . color . primary = input . getAttribute ( "data-md-color-primary" ) , palette . color . accent = input . getAttribute ( "data-md-color-accent" ) } for ( var [ key , value ] of Object . entries ( palette . color ) ) document . body . setAttribute ( "data-md-color-" + key , value ) } < / script >
< label class = "md-header__button md-icon" for = "__search" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5" / > < / svg >
< / label >
< div class = "md-search" data-md-component = "search" role = "dialog" >
< label class = "md-search__overlay" for = "__search" > < / label >
< div class = "md-search__inner" role = "search" >
< form class = "md-search__form" name = "search" >
< input type = "text" class = "md-search__input" name = "query" aria-label = "Search" placeholder = "Search" autocapitalize = "off" autocorrect = "off" autocomplete = "off" spellcheck = "false" data-md-component = "search-query" required >
< label class = "md-search__icon md-icon" for = "__search" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5" / > < / svg >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z" / > < / svg >
< / label >
< nav class = "md-search__options" aria-label = "Search" >
< a href = "javascript:void(0)" class = "md-search__icon md-icon" title = "Share" aria-label = "Share" data-clipboard data-clipboard-text = "" data-md-component = "search-share" tabindex = "-1" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08" / > < / svg >
< / a >
< button type = "reset" class = "md-search__icon md-icon" title = "Clear" aria-label = "Clear" tabindex = "-1" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" / > < / svg >
< / button >
< / nav >
< div class = "md-search__suggest" data-md-component = "search-suggest" > < / div >
< / form >
< div class = "md-search__output" >
< div class = "md-search__scrollwrap" tabindex = "0" data-md-scrollfix >
< div class = "md-search-result" data-md-component = "search-result" >
< div class = "md-search-result__meta" >
Initializing search
< / div >
< ol class = "md-search-result__list" role = "presentation" > < / ol >
< / div >
< / div >
< / div >
< / div >
< / div >
< / nav >
< / header >
< div class = "md-container" data-md-component = "container" >
< main class = "md-main" data-md-component = "main" >
< div class = "md-main__inner md-grid" >
< div class = "md-sidebar md-sidebar--primary" data-md-component = "sidebar" data-md-type = "navigation" >
< div class = "md-sidebar__scrollwrap" >
< div class = "md-sidebar__inner" >
< nav class = "md-nav md-nav--primary" aria-label = "Navigation" data-md-level = "0" >
< label class = "md-nav__title" for = "__drawer" >
< a href = ".." title = "Aetos Standards — Reference" class = "md-nav__button md-logo" aria-label = "Aetos Standards — Reference" data-md-component = "logo" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54" / > < / svg >
< / a >
Aetos Standards — Reference
< / label >
< ul class = "md-nav__list" data-md-scrollfix >
< li class = "md-nav__item" >
< a href = ".." class = "md-nav__link" >
< span class = "md-ellipsis" >
Home
< / span >
< / a >
< / li >
< li class = "md-nav__item md-nav__item--active" >
< input class = "md-nav__toggle md-toggle" type = "checkbox" id = "__toc" >
< label class = "md-nav__link md-nav__link--active" for = "__toc" >
< span class = "md-ellipsis" >
Build Recipe
< / span >
< span class = "md-nav__icon md-icon" > < / span >
< / label >
< a href = "./" class = "md-nav__link md-nav__link--active" >
< span class = "md-ellipsis" >
Build Recipe
< / span >
< / a >
< nav class = "md-nav md-nav--secondary" aria-label = "Table of contents" >
< label class = "md-nav__title" for = "__toc" >
< span class = "md-nav__icon md-icon" > < / span >
Table of contents
< / label >
< ul class = "md-nav__list" data-md-component = "toc" data-md-scrollfix >
< li class = "md-nav__item" >
< a href = "#summary" class = "md-nav__link" >
< span class = "md-ellipsis" >
Summary
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#bootstrap" class = "md-nav__link" >
< span class = "md-ellipsis" >
🚀 Bootstrap
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#agent-prompt-copyable" class = "md-nav__link" >
< span class = "md-ellipsis" >
📋 Agent prompt (copyable)
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#where-the-steps-land" class = "md-nav__link" >
< span class = "md-ellipsis" >
🧭 Where the steps land
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#definition-of-done" class = "md-nav__link" >
< span class = "md-ellipsis" >
⚠️ Definition of done
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#related" class = "md-nav__link" >
< span class = "md-ellipsis" >
Related
< / span >
< / a >
< / li >
< / ul >
< / nav >
< / li >
< li class = "md-nav__item" >
< a href = "../02_layering_rules/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Layering Rules
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../03_composition_root/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Composition Root
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../04_spec_first_routing/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Spec-First Routing
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../05_crud_template/" class = "md-nav__link" >
< span class = "md-ellipsis" >
CRUD Template
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../06_pipeline_scaffold/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Pipeline Scaffold
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../07_worker_and_progress/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Worker & Progress
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../08_human_in_loop/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Human-in-the-Loop
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../09_infra_adaptors/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Infra Adapters
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../12_genericity_matrix/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Genericity Matrix
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "../13_library_registry/" class = "md-nav__link" >
< span class = "md-ellipsis" >
Library Registry
< / span >
< / a >
< / li >
< / ul >
< / nav >
< / div >
< / div >
< / div >
< div class = "md-sidebar md-sidebar--secondary" data-md-component = "sidebar" data-md-type = "toc" >
< div class = "md-sidebar__scrollwrap" >
< div class = "md-sidebar__inner" >
< nav class = "md-nav md-nav--secondary" aria-label = "Table of contents" >
< label class = "md-nav__title" for = "__toc" >
< span class = "md-nav__icon md-icon" > < / span >
Table of contents
< / label >
< ul class = "md-nav__list" data-md-component = "toc" data-md-scrollfix >
< li class = "md-nav__item" >
< a href = "#summary" class = "md-nav__link" >
< span class = "md-ellipsis" >
Summary
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#bootstrap" class = "md-nav__link" >
< span class = "md-ellipsis" >
🚀 Bootstrap
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#agent-prompt-copyable" class = "md-nav__link" >
< span class = "md-ellipsis" >
📋 Agent prompt (copyable)
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#where-the-steps-land" class = "md-nav__link" >
< span class = "md-ellipsis" >
🧭 Where the steps land
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#definition-of-done" class = "md-nav__link" >
< span class = "md-ellipsis" >
⚠️ Definition of done
< / span >
< / a >
< / li >
< li class = "md-nav__item" >
< a href = "#related" class = "md-nav__link" >
< span class = "md-ellipsis" >
Related
< / span >
< / a >
< / li >
< / ul >
< / nav >
< / div >
< / div >
< / div >
< div class = "md-content" data-md-component = "content" >
< article class = "md-content__inner md-typeset" >
< h1 id = "build-recipe" > Build Recipe< / h1 >
< h2 id = "summary" > Summary< / h2 >
< p > 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.< / p >
< p > This page is served by the < code > standards< / code > MCP as < code > doc://modules/build_recipe< / code > . The
< code > start_app< / code > prompt on that server collects the two axes and hands off here; pull
exact files with < code > get_app_component< / code > .< / p >
< hr / >
< h2 id = "bootstrap" > 🚀 Bootstrap< / h2 >
< p > From the standards docs checkout:< / p >
< div class = "language-bash highlight" > < table class = "highlighttable" > < tr > < td class = "linenos" > < div class = "linenodiv" > < pre > < span > < / span > < span class = "normal" > < a href = "#__codelineno-0-1" > 1< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-0-2" > 2< / a > < / span > < / pre > < / div > < / td > < td class = "code" > < div > < pre > < span > < / span > < code > < span id = "__span-0-1" > < a id = "__codelineno-0-1" name = "__codelineno-0-1" > < / a > cp< span class = "w" > < / span > -r< span class = "w" > < / span > < docs> /standards/src/templates/app< span class = "w" > < / span > apps/< your-app>
< / span > < span id = "__span-0-2" > < a id = "__codelineno-0-2" name = "__codelineno-0-2" > < / a > < span class = "nb" > cd< / span > < span class = "w" > < / span > apps/< your-app>
< / span > < / code > < / pre > < / div > < / td > < / tr > < / table > < / div >
< p > Install the internal libraries — editable local checkouts (preferred in
development) or the private index (CI / fresh machines). Credentials are
environment-only; never commit them.< / p >
< div class = "language-bash highlight" > < table class = "highlighttable" > < tr > < td class = "linenos" > < div class = "linenodiv" > < pre > < span > < / span > < span class = "normal" > < a href = "#__codelineno-1-1" > 1< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-1-2" > 2< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-1-3" > 3< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-1-4" > 4< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-1-5" > 5< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-1-6" > 6< / a > < / span > < / pre > < / div > < / td > < td class = "code" > < div > < pre > < span > < / span > < code > < span id = "__span-1-1" > < a id = "__codelineno-1-1" name = "__codelineno-1-1" > < / a > < span class = "c1" > # local checkouts< / span >
< / span > < span id = "__span-1-2" > < a id = "__codelineno-1-2" name = "__codelineno-1-2" > < / a > pip< span class = "w" > < / span > install< span class = "w" > < / span > -e< span class = "w" > < / span > ../aetos/openapi-first< span class = "w" > < / span > -e< span class = "w" > < / span > ../aetos/mongo-ops< span class = "w" > < / span > -e< span class = "w" > < / span > ../aetos/hexa< span class = "w" > < / span > < span class = "se" > \< / span >
< / span > < span id = "__span-1-3" > < a id = "__codelineno-1-3" name = "__codelineno-1-3" > < / a > < span class = "w" > < / span > -e< span class = "w" > < / span > ../aetos/dagpipe< span class = "w" > < / span > -e< span class = "w" > < / span > ../aetos/doc-forge
< / span > < span id = "__span-1-4" > < a id = "__codelineno-1-4" name = "__codelineno-1-4" > < / a > < span class = "c1" > # private index< / span >
< / span > < span id = "__span-1-5" > < a id = "__codelineno-1-5" name = "__codelineno-1-5" > < / a > pip< span class = "w" > < / span > install< span class = "w" > < / span > --extra-index-url< span class = "w" > < / span > < span class = "se" > \< / span >
< / span > < span id = "__span-1-6" > < a id = "__codelineno-1-6" name = "__codelineno-1-6" > < / a > < span class = "w" > < / span > < span class = "s2" > " https://< / span > < span class = "nv" > $PIP_REGISTRY_USERNAME< / span > < span class = "s2" > :< / span > < span class = "nv" > $PIP_REGISTRY_PASSWORD< / span > < span class = "s2" > @pip.aetoskia.com/simple" < / span > < span class = "w" > < / span > .
< / span > < / code > < / pre > < / div > < / td > < / tr > < / table > < / div >
< hr / >
< h2 id = "agent-prompt-copyable" > 📋 Agent prompt (copyable)< / h2 >
< div class = "language-markdown highlight" > < table class = "highlighttable" > < tr > < td class = "linenos" > < div class = "linenodiv" > < pre > < span > < / span > < span class = "normal" > < a href = "#__codelineno-2-1" > 1< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-2" > 2< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-3" > 3< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-4" > 4< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-5" > 5< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-6" > 6< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-7" > 7< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-8" > 8< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-9" > 9< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-10" > 10< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-11" > 11< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-12" > 12< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-13" > 13< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-14" > 14< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-15" > 15< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-16" > 16< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-17" > 17< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-18" > 18< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-19" > 19< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-20" > 20< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-21" > 21< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-22" > 22< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-23" > 23< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-24" > 24< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-25" > 25< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-26" > 26< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-27" > 27< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-28" > 28< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-29" > 29< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-30" > 30< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-31" > 31< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-32" > 32< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-33" > 33< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-34" > 34< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-35" > 35< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-36" > 36< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-37" > 37< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-38" > 38< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-39" > 39< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-40" > 40< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-41" > 41< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-42" > 42< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-43" > 43< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-44" > 44< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-45" > 45< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-46" > 46< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-47" > 47< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-48" > 48< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-49" > 49< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-50" > 50< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-51" > 51< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-52" > 52< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-53" > 53< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-54" > 54< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-55" > 55< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-56" > 56< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-57" > 57< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-58" > 58< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-59" > 59< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-60" > 60< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-61" > 61< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-62" > 62< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-63" > 63< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-64" > 64< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-65" > 65< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-66" > 66< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-67" > 67< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-68" > 68< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-69" > 69< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-70" > 70< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-71" > 71< / a > < / span >
< span class = "normal" > < a href = "#__codelineno-2-72" > 72< / a > < / span > < / pre > < / div > < / td > < td class = "code" > < div > < pre > < span > < / span > < code > < span id = "__span-2-1" > < a id = "__codelineno-2-1" name = "__codelineno-2-1" > < / a > < span class = "gh" > # Build a new application from the Aetos Standards blueprint< / span >
< / span > < span id = "__span-2-2" > < a id = "__codelineno-2-2" name = "__codelineno-2-2" > < / a >
< / span > < span id = "__span-2-3" > < a id = "__codelineno-2-3" name = "__codelineno-2-3" > < / a > You are coding a complete new backend application conforming to the Aetos
< / span > < span id = "__span-2-4" > < a id = "__codelineno-2-4" name = "__codelineno-2-4" > < / a > standard app blueprint. Execute every step in order. Only steps 2 and 3 use the
< / span > < span id = "__span-2-5" > < a id = "__codelineno-2-5" name = "__codelineno-2-5" > < / a > app-specific details provided by the user; everything else is deterministic.
< / span > < span id = "__span-2-6" > < a id = "__codelineno-2-6" name = "__codelineno-2-6" > < / a >
< / span > < span id = "__span-2-7" > < a id = "__codelineno-2-7" name = "__codelineno-2-7" > < / a > < span class = "gu" > ## Before writing any code< / span >
< / span > < span id = "__span-2-8" > < a id = "__codelineno-2-8" name = "__codelineno-2-8" > < / a >
< / span > < span id = "__span-2-9" > < a id = "__codelineno-2-9" name = "__codelineno-2-9" > < / a > Connect to the < span class = "sb" > `standards`< / span > MCP server and read:
< / span > < span id = "__span-2-10" > < a id = "__codelineno-2-10" name = "__codelineno-2-10" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > < span class = "sb" > `doc://nav`< / span > (the module list)
< / span > < span id = "__span-2-11" > < a id = "__codelineno-2-11" name = "__codelineno-2-11" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > < span class = "sb" > `doc://modules/genericity_matrix`< / span > (Tier A library / Tier B template / Tier C authored)
< / span > < span id = "__span-2-12" > < a id = "__codelineno-2-12" name = "__codelineno-2-12" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > < span class = "sb" > `doc://modules/layering_rules`< / span > (the dependency rules)
< / span > < span id = "__span-2-13" > < a id = "__codelineno-2-13" name = "__codelineno-2-13" > < / a >
< / span > < span id = "__span-2-14" > < a id = "__codelineno-2-14" name = "__codelineno-2-14" > < / a > Then:
< / span > < span id = "__span-2-15" > < a id = "__codelineno-2-15" name = "__codelineno-2-15" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > call < span class = "sb" > `find_library`< / span > with < span class = "sb" > `db`< / span > , < span class = "sb" > `di`< / span > , < span class = "sb" > `routing`< / span > , < span class = "sb" > `ingestion`< / span > , < span class = "sb" > `pipeline`< / span > , < span class = "sb" > `docs`< / span >
< / span > < span id = "__span-2-16" > < a id = "__codelineno-2-16" name = "__codelineno-2-16" > < / a > and note the Tier A libraries that already exist — never reimplement one;
< / span > < span id = "__span-2-17" > < a id = "__codelineno-2-17" name = "__codelineno-2-17" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > call < span class = "sb" > `list_app_components()`< / span > and pull each file you need with
< / span > < span id = "__span-2-18" > < a id = "__codelineno-2-18" name = "__codelineno-2-18" > < / a > < span class = "sb" > `get_app_component(kind, resource=..., family=...)`< / span > instead of writing it from
< / span > < span id = "__span-2-19" > < a id = "__codelineno-2-19" name = "__codelineno-2-19" > < / a > scratch.
< / span > < span id = "__span-2-20" > < a id = "__codelineno-2-20" name = "__codelineno-2-20" > < / a >
< / span > < span id = "__span-2-21" > < a id = "__codelineno-2-21" name = "__codelineno-2-21" > < / a > < span class = "gu" > ## Steps< / span >
< / span > < span id = "__span-2-22" > < a id = "__codelineno-2-22" name = "__codelineno-2-22" > < / a >
< / span > < span id = "__span-2-23" > < a id = "__codelineno-2-23" name = "__codelineno-2-23" > < / a > < span class = "k" > 1.< / span > < span class = "gs" > **Scaffold**< / span > — copy < span class = "sb" > `standards/src/templates/app/`< / span > into < span class = "sb" > `apps/< your-app> /`< / span > .
< / span > < span id = "__span-2-24" > < a id = "__codelineno-2-24" name = "__codelineno-2-24" > < / a > Keep the tree: < span class = "sb" > `domain/`< / span > , < span class = "sb" > `infra/`< / span > , < span class = "sb" > `interfaces/`< / span > , < span class = "sb" > `pipelines/`< / span > , < span class = "sb" > `tests/`< / span > ,
< / span > < span id = "__span-2-25" > < a id = "__codelineno-2-25" name = "__codelineno-2-25" > < / a > < span class = "sb" > `scripts/`< / span > , plus < span class = "sb" > `pyproject.toml`< / span > , < span class = "sb" > `openapi.yaml`< / span > , < span class = "sb" > `config.py`< / span > , < span class = "sb" > `init.py`< / span > ,
< / span > < span id = "__span-2-26" > < a id = "__codelineno-2-26" name = "__codelineno-2-26" > < / a > < span class = "sb" > `main.py`< / span > , < span class = "sb" > `worker.py`< / span > , < span class = "sb" > `Dockerfile`< / span > , < span class = "sb" > `docker-compose.yaml`< / span > , < span class = "sb" > `.env.example`< / span > .
< / span > < span id = "__span-2-27" > < a id = "__codelineno-2-27" name = "__codelineno-2-27" > < / a >
< / span > < span id = "__span-2-28" > < a id = "__codelineno-2-28" name = "__codelineno-2-28" > < / a > < span class = "k" > 2.< / span > < span class = "gs" > **Author the spec (app-specific)**< / span > — write < span class = "sb" > `openapi.yaml`< / span > : resources,
< / span > < span id = "__span-2-29" > < a id = "__codelineno-2-29" name = "__codelineno-2-29" > < / a > schemas, < span class = "sb" > `operationId`< / span > s, security, and extension metadata. This is the
< / span > < span id = "__span-2-30" > < a id = "__codelineno-2-30" name = "__codelineno-2-30" > < / a > contract and drives all routing.
< / span > < span id = "__span-2-31" > < a id = "__codelineno-2-31" name = "__codelineno-2-31" > < / a >
< / span > < span id = "__span-2-32" > < a id = "__codelineno-2-32" name = "__codelineno-2-32" > < / a > < span class = "k" > 3.< / span > < span class = "gs" > **Write each CRUD slice (app-specific)**< / span > — per resource create the four-file
< / span > < span id = "__span-2-33" > < a id = "__codelineno-2-33" name = "__codelineno-2-33" > < / a > slice: < span class = "sb" > `models.py`< / span > , < span class = "sb" > `ports/db.py`< / span > , < span class = "sb" > `ports/service.py`< / span > , and optional
< / span > < span id = "__span-2-34" > < a id = "__codelineno-2-34" name = "__codelineno-2-34" > < / a > < span class = "sb" > `converters.py`< / span > . Follow the CRUD template.
< / span > < span id = "__span-2-35" > < a id = "__codelineno-2-35" name = "__codelineno-2-35" > < / a >
< / span > < span id = "__span-2-36" > < a id = "__codelineno-2-36" name = "__codelineno-2-36" > < / a > < span class = "k" > 4.< / span > < span class = "gs" > **Wire the composition root**< / span > — in < span class = "sb" > `init.py`< / span > , build leaf repositories, then
< / span > < span id = "__span-2-37" > < a id = "__codelineno-2-37" name = "__codelineno-2-37" > < / a > dependent repositories, then services; add infra adapters (db, cache, stores,
< / span > < span id = "__span-2-38" > < a id = "__codelineno-2-38" name = "__codelineno-2-38" > < / a > progress bus, fetchers). Expose < span class = "sb" > `get_svc`< / span > overloads.
< / span > < span id = "__span-2-39" > < a id = "__codelineno-2-39" name = "__codelineno-2-39" > < / a >
< / span > < span id = "__span-2-40" > < a id = "__codelineno-2-40" name = "__codelineno-2-40" > < / a > < span class = "k" > 5.< / span > < span class = "gs" > **Add routes**< / span > — create < span class = "sb" > `interfaces/< resource> /routes.py`< / span > thin handlers bound
< / span > < span id = "__span-2-41" > < a id = "__codelineno-2-41" name = "__codelineno-2-41" > < / a > to < span class = "sb" > `operationId`< / span > s and re-export them in < span class = "sb" > `interfaces/openapi.py`< / span > . Add the cache
< / span > < span id = "__span-2-42" > < a id = "__codelineno-2-42" name = "__codelineno-2-42" > < / a > decorator to read endpoints.
< / span > < span id = "__span-2-43" > < a id = "__codelineno-2-43" name = "__codelineno-2-43" > < / a >
< / span > < span id = "__span-2-44" > < a id = "__codelineno-2-44" name = "__codelineno-2-44" > < / a > < span class = "k" > 6.< / span > < span class = "gs" > **Bootstrap app and worker**< / span > — confirm < span class = "sb" > `main.py`< / span > runs the OpenAPI-first app
< / span > < span id = "__span-2-45" > < a id = "__codelineno-2-45" name = "__codelineno-2-45" > < / a > with its lifespan. If the app has long-running jobs, adapt < span class = "sb" > `worker.py`< / span > to poll
< / span > < span id = "__span-2-46" > < a id = "__codelineno-2-46" name = "__codelineno-2-46" > < / a > the job collection, run the pipeline, and publish progress.
< / span > < span id = "__span-2-47" > < a id = "__codelineno-2-47" name = "__codelineno-2-47" > < / a >
< / span > < span id = "__span-2-48" > < a id = "__codelineno-2-48" name = "__codelineno-2-48" > < / a > < span class = "k" > 7.< / span > < span class = "gs" > **Add pipeline families (only if data-driven)**< / span > — copy < span class = "sb" > `pipelines/example/`< / span >
< / span > < span id = "__span-2-49" > < a id = "__codelineno-2-49" name = "__codelineno-2-49" > < / a > to < span class = "sb" > `pipelines/< family> /`< / span > with < span class = "sb" > `abc.py`< / span > , < span class = "sb" > `impl.py`< / span > , < span class = "sb" > `pipeline.yaml`< / span > ,
< / span > < span id = "__span-2-50" > < a id = "__codelineno-2-50" name = "__codelineno-2-50" > < / a > < span class = "sb" > `resources/`< / span > , and reuse < span class = "sb" > `pipelines/shared/`< / span > (loader + registry). Register the
< / span > < span id = "__span-2-51" > < a id = "__codelineno-2-51" name = "__codelineno-2-51" > < / a > root. Add fixtures and a parity test.
< / span > < span id = "__span-2-52" > < a id = "__codelineno-2-52" name = "__codelineno-2-52" > < / a >
< / span > < span id = "__span-2-53" > < a id = "__codelineno-2-53" name = "__codelineno-2-53" > < / a > < span class = "k" > 8.< / span > < span class = "gs" > **Add infrastructure only where needed**< / span > — Tier A capability: use the
< / span > < span id = "__span-2-54" > < a id = "__codelineno-2-54" name = "__codelineno-2-54" > < / a > library. Tier B capability: copy the template. Never hand-write a Tier A
< / span > < span id = "__span-2-55" > < a id = "__codelineno-2-55" name = "__codelineno-2-55" > < / a > library.
< / span > < span id = "__span-2-56" > < a id = "__codelineno-2-56" name = "__codelineno-2-56" > < / a >
< / span > < span id = "__span-2-57" > < a id = "__codelineno-2-57" name = "__codelineno-2-57" > < / a > < span class = "k" > 9.< / span > < span class = "gs" > **Tests**< / span > — integration tests with fakes at the HTTP edge; unit tests for
< / span > < span id = "__span-2-58" > < a id = "__codelineno-2-58" name = "__codelineno-2-58" > < / a > domain and pipeline logic; a config-consistency test for rule-driven
< / span > < span id = "__span-2-59" > < a id = "__codelineno-2-59" name = "__codelineno-2-59" > < / a > pipelines.
< / span > < span id = "__span-2-60" > < a id = "__codelineno-2-60" name = "__codelineno-2-60" > < / a >
< / span > < span id = "__span-2-61" > < a id = "__codelineno-2-61" name = "__codelineno-2-61" > < / a > < span class = "k" > 10.< / span > < span class = "gs" > **Scripts and seeds**< / span > — operator scripts under < span class = "sb" > `scripts/`< / span > using
< / span > < span id = "__span-2-62" > < a id = "__codelineno-2-62" name = "__codelineno-2-62" > < / a > < span class = "sb" > `init()`< / span > / < span class = "sb" > `get_svc()`< / span > / < span class = "sb" > `shutdown()`< / span > ; run as < span class = "sb" > `python -m scripts.< name> `< / span > .
< / span > < span id = "__span-2-63" > < a id = "__codelineno-2-63" name = "__codelineno-2-63" > < / a >
< / span > < span id = "__span-2-64" > < a id = "__codelineno-2-64" name = "__codelineno-2-64" > < / a > < span class = "k" > 11.< / span > < span class = "gs" > **Docs**< / span > — author GSDFC docstrings, generate < span class = "sb" > `.pyi`< / span > stubs, mark the package
< / span > < span id = "__span-2-65" > < a id = "__codelineno-2-65" name = "__codelineno-2-65" > < / a > < span class = "sb" > `py.typed`< / span > , and build the docs.
< / span > < span id = "__span-2-66" > < a id = "__codelineno-2-66" name = "__codelineno-2-66" > < / a >
< / span > < span id = "__span-2-67" > < a id = "__codelineno-2-67" name = "__codelineno-2-67" > < / a > < span class = "gs" > **Definition of done:**< / span >
< / span > < span id = "__span-2-68" > < a id = "__codelineno-2-68" name = "__codelineno-2-68" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > < span class = "sb" > `python -c " import main" `< / span > succeeds.
< / span > < span id = "__span-2-69" > < a id = "__codelineno-2-69" name = "__codelineno-2-69" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > < span class = "sb" > `pytest`< / span > passes.
< / span > < span id = "__span-2-70" > < a id = "__codelineno-2-70" name = "__codelineno-2-70" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > The app serves every operation in the spec; the worker drains its queue.
< / span > < span id = "__span-2-71" > < a id = "__codelineno-2-71" name = "__codelineno-2-71" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > No domain module imports a web framework.
< / span > < span id = "__span-2-72" > < a id = "__codelineno-2-72" name = "__codelineno-2-72" > < / a > < span class = "k" > -< / span > < span class = "w" > < / span > No Tier A library was reimplemented.
< / span > < / code > < / pre > < / div > < / td > < / tr > < / table > < / div >
< hr / >
< h2 id = "where-the-steps-land" > 🧭 Where the steps land< / h2 >
< p > The steps map onto the layers as follows:< / p >
< table >
< thead >
< tr >
< th > Step< / th >
< th > Package / file< / th >
< th > Depends on< / th >
< / tr >
< / thead >
< tbody >
< tr >
< td > 1 · Scaffold< / td >
< td > whole < code > templates/app/< / code > < / td >
< td > —< / td >
< / tr >
< tr >
< td > 2 · Spec< / td >
< td > < code > openapi.yaml< / code > < / td >
< td > —< / td >
< / tr >
< tr >
< td > 3 · CRUD slices< / td >
< td > < code > domain/< resource> /< / code > < / td >
< td > spec, CRUD template< / td >
< / tr >
< tr >
< td > 4 · Wiring< / td >
< td > < code > init.py< / code > < / td >
< td > every slice< / td >
< / tr >
< tr >
< td > 5 · Routes< / td >
< td > < code > interfaces/< resource> /< / code > < / td >
< td > services, openapi route registry< / td >
< / tr >
< tr >
< td > 6 · Bootstrap< / td >
< td > < code > main.py< / code > , < code > worker.py< / code > < / td >
< td > composition root< / td >
< / tr >
< tr >
< td > 7 · Pipelines< / td >
< td > < code > pipelines/< family> /< / code > , < code > shared/< / code > < / td >
< td > library pipeline engine< / td >
< / tr >
< tr >
< td > 8 · Infra< / td >
< td > < code > infra/< / code > < / td >
< td > domain ports< / td >
< / tr >
< tr >
< td > 9 · Tests< / td >
< td > < code > tests/< / code > < / td >
< td > app + fixtures< / td >
< / tr >
< tr >
< td > 10 · Scripts< / td >
< td > < code > scripts/< / code > < / td >
< td > composition root< / td >
< / tr >
< tr >
< td > 11 · Docs< / td >
< td > docstrings + docs build< / td >
< td > code, Doc Forge< / td >
< / tr >
< / tbody >
< / table >
< hr / >
< h2 id = "definition-of-done" > ⚠️ Definition of done< / h2 >
< ul >
< li > < code > python -c "import main"< / code > succeeds.< / li >
< li > < code > pytest< / code > passes.< / li >
< li > The app serves the spec's operations; the worker drains its queue.< / li >
< li > No domain module imports a web framework.< / li >
< li > No Tier A library was reimplemented.< / li >
< / ul >
< hr / >
< h2 id = "related" > Related< / h2 >
< ul >
< li > < a href = "../02_layering_rules/" > 02 – Layering Rules< / a > · < a href = "../05_crud_template/" > 05 – CRUD Template< / a > · < a href = "../06_pipeline_scaffold/" > 06 – Pipeline Scaffold< / a > · < a href = "../12_genericity_matrix/" > 12 – Genericity Matrix< / a > < / li >
< / ul >
< / article >
< / div >
< script > var tabs = _ _md _get ( "__tabs" ) ; if ( Array . isArray ( tabs ) ) e : for ( var set of document . querySelectorAll ( ".tabbed-set" ) ) { var labels = set . querySelector ( ".tabbed-labels" ) ; for ( var tab of tabs ) for ( var label of labels . getElementsByTagName ( "label" ) ) if ( label . innerText . trim ( ) === tab ) { var input = document . getElementById ( label . htmlFor ) ; input . checked = ! 0 ; continue e } } < / script >
< script > var target = document . getElementById ( location . hash . slice ( 1 ) ) ; target && target . name && ( target . checked = target . name . startsWith ( "__tabbed_" ) ) < / script >
< / div >
< button type = "button" class = "md-top md-icon" data-md-component = "top" hidden >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 24 24" > < path d = "M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z" / > < / svg >
Back to top
< / button >
< / main >
< footer class = "md-footer" >
< div class = "md-footer-meta md-typeset" >
< div class = "md-footer-meta__inner md-grid" >
< div class = "md-copyright" >
Made with
< a href = "https://squidfunk.github.io/mkdocs-material/" target = "_blank" rel = "noopener" >
Material for MkDocs
< / a >
< / div >
< / div >
< / div >
< / footer >
< / div >
< div class = "md-dialog" data-md-component = "dialog" >
< div class = "md-dialog__inner md-typeset" > < / div >
< / div >
< script id = "__config" type = "application/json" > { "base" : ".." , "features" : [ "navigation.sections" , "navigation.expand" , "navigation.top" , "navigation.instant" , "navigation.tracking" , "navigation.indexes" , "content.code.copy" , "content.code.annotate" , "content.tabs.link" , "content.action.edit" , "search.highlight" , "search.share" , "search.suggest" ] , "search" : "../assets/javascripts/workers/search.973d3a69.min.js" , "tags" : null , "translations" : { "clipboard.copied" : "Copied to clipboard" , "clipboard.copy" : "Copy to clipboard" , "search.result.more.one" : "1 more on this page" , "search.result.more.other" : "# more on this page" , "search.result.none" : "No matching documents" , "search.result.one" : "1 matching document" , "search.result.other" : "# matching documents" , "search.result.placeholder" : "Type to start searching" , "search.result.term.missing" : "Missing" , "select.version" : "Select version" } , "version" : null } < / script >
< script src = "../assets/javascripts/bundle.f55a23d4.min.js" > < / script >
< / body >
< / html >