feat: renumber lib reference into 4-pillar anatomy
Renumber the 15 reference docs into pillar groups (recipe -> anatomy): - 01 Build Recipe (entry), 02 Composition Root - domains: 10 Layering Rules - contract: 20 Spec-First Routing, 21 CRUD Template, 22 Auth Integration - interfaces/infra: 30 Infra Adapters - UI: 40 UI: Auto-Rendered Admin & Custom Pages (new; @aetoskia packages, client template, x- catalog via react-openapi MCP module) - pipelines: 50 Pipeline Scaffold, 51 Worker & Progress, 52 Human-in-the-Loop - delivery/meta: 90 Drone Pipelines, 91 Versioning & Changelog, 92 Genericity Matrix, 93 Library Registry, 94 Repository Inventory MCP module names are unchanged (NN_ prefix stripped); all cross-references (wiki, templates, hooks, registry) updated; lib index rewritten pillar-first; build recipe bootstraps the client template. Bundle + HTML sites regenerated.
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
"module": "index",
|
||||
"content": {
|
||||
"path": "index",
|
||||
"docstring": "# Standards Reference\n\nThe reference half of the Standards description: the enforceable rules,\npatterns, and the internal library catalog that agents consult while coding.\n\n- **Build Recipe** — the ordered, agentic checklist for a new app.\n- **Layering Rules** — the strict request → domain → repository layering and\n the rules that enforce it.\n- **Composition Root** — a single composition point wiring the whole app.\n- **Spec-First Routing** — the OpenAPI contract as the routing source of truth.\n- **CRUD Template** — the standardized generic resource endpoint scaffold.\n- **Pipeline Scaffold** — the deterministic pipeline skeleton for multi-stage\n jobs.\n- **Worker & Progress** — queued work, progress reporting, and visibility.\n- **Human-in-the-Loop** — guardrails and approvals inside automations.\n- **Infra Adapters** — how infrastructure connects without leaking into domain.\n- **Drone Pipelines** — the two CI shapes: a PyPI package or a Docker deployment.\n- **Versioning & Changelog** — SemVer, the tag↔version contract, and the release\n changelog.\n- **Repository Inventory** — every covered repo, its type, version source, and\n Drone shape.\n- **Genericity Matrix** — what is library-backed, template-provided, or authored.\n- **Auth Integration** — consuming the shared auth-server service (spec-driven,\n no auth code).\n- **Library Registry** — the catalog of internal libraries behind all of it.\n\nRead the **Wiki** for the philosophy and rationale; these pages are the\nreference that mirrors the `standards` MCP bundle.\n",
|
||||
"docstring": "# Standards Reference\n\nThe reference half of the Standards description: the enforceable rules,\npatterns, and the internal library catalog that agents consult while coding.\n\nThe reference is organized as an **anatomy** — one entry checklist and four\npillars describing what an application is made of, plus delivery/meta pages\nand an optional pipelines layer.\n\n## Anatomy\n\n- **Build Recipe** — the ordered, agentic checklist for a new app; the entry\n point that walks the whole anatomy.\n\n## Pillar 1 — Domains\n\n- **Layering Rules** — the strict request → domain → repository layering and\n the rules that enforce it.\n\n## Pillar 2 — OpenAPI Spec (the contract)\n\n- **Composition Root** — a single composition point wiring the whole app.\n- **Spec-First Routing** — the OpenAPI contract as the routing source of truth.\n- **CRUD Template** — the standardized generic resource endpoint scaffold.\n- **Auth Integration** — consuming the shared auth-server service (spec-driven,\n no auth code).\n\n## Pillar 3 — Interfaces & Infra\n\n- **Infra Adapters** — how infrastructure connects without leaking into domain.\n\n## Pillar 4 — UI\n\n- **UI: Auto-Rendered Admin & Custom Pages** — the `@aetoskia/react-openapi`\n admin rendered from the spec's x- extensions, and `@aetoskia/react-auth`\n for auth pages; the client template scaffold.\n\n## Pipelines (optional layer)\n\n- **Pipeline Scaffold** — the deterministic pipeline skeleton for multi-stage\n jobs.\n- **Worker & Progress** — queued work, progress reporting, and visibility.\n- **Human-in-the-Loop** — guardrails and approvals inside automations.\n\n## Delivery & Meta\n\n- **Drone Pipelines** — the two CI shapes: a PyPI/npm package or a Docker\n deployment.\n- **Versioning & Changelog** — SemVer, the tag↔version contract, and the\n release changelog.\n- **Repository Inventory** — every covered repo, its type, version source, and\n Drone shape.\n- **Genericity Matrix** — what is library-backed, template-provided, or\n authored.\n- **Library Registry** — the catalog of internal libraries behind all of it.\n\nRead the **Wiki** for the philosophy and rationale; these pages are the\nreference that mirrors the `standards` MCP bundle.\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "repository_inventory",
|
||||
"content": {
|
||||
"path": "repository_inventory",
|
||||
"docstring": "# Repository Inventory\n\n## Summary\n\nThe canonical list of Aetos repositories covered by the CI and versioning\nstandards, with the artifact each one produces, its version source, and its\nDrone shape. Every entry maps to the contract in\n[11 – Versioning & Changelog](11_versioning_and_changelog.md) and the two CI\nfiles in [10 – Drone Pipelines](10_drone_pipelines.md).\n\nThe same data is published machine-readably as the `registry://repos` MCP\nresource (and the `list_repos` tool), sourced from `standards/src/repos.json`.\nPaths are relative to the `aetos/` workspace root.\n\n---\n\n## Packages (Type A)\n\nA wheel + sdist published to the private index. Version source is\n`pyproject.toml`; Drone file is `python-lib.yaml` (tag-triggered).\n\n| Repo | Path | Docs | MCP server |\n|------|------|------|------------|\n| `dagpipe` | `dagpipe` | lib, wiki | `dagpipe:8006` |\n| `doc-forge` | `doc-forge` | lib, wiki | `docforge:8001` |\n| `hexa` | `hexa` | lib, wiki | `hexa:8008` |\n| `mail-intake` | `mail-intake` | lib, wiki | `mail_intake:8002` |\n| `mongo-ops` | `mongo-ops` | lib, wiki | `mongo_ops:8007` |\n| `omniread` | `omniread` | lib, wiki | `omniread:8003` |\n| `openapi-first` | `openapi-first` | lib, wiki | `openapi_first:8004` |\n| `py-jwt` | `py-jwt` | lib, wiki | `jwtlib:8005` |\n\n---\n\n## Services (Type B)\n\nA container image pushed to the registry and run on the Docker host. Version\nsource is the `VERSION` file; Drone file is `service-docker.yaml`.\n\n| Repo | Path | Trigger | Docs |\n|------|------|---------|------|\n| `auth-server` | `auth-server` | tag | api, lib, wiki |\n\nTag-triggered and enforces `tag == VERSION`.\n\n---\n\n## Required files per repo\n\n| Type | Version source | Changelog | Drone |\n|------|----------------|-----------|-------|\n| package | `pyproject.toml` | `CHANGELOG.md` | `python-lib.yaml` |\n| service | `VERSION` | `CHANGELOG.md` | `service-docker.yaml` |\n\nEvery covered repository must be able to satisfy `tag == version`:\nthe version file (never a commit id) is bumped in the release MR, the MR is\nmerged, and the tag is created on the merged commit.\n\n---\n\n## Reading this at runtime\n\n- Resource: `registry://repos`\n- Tool: `list_repos()`\n- Humans: this page (mirror of `standards/src/repos.json`).\n\n---\n\n## Related\n\n- [10 – Drone Pipelines](10_drone_pipelines.md) · [11 – Versioning & Changelog](11_versioning_and_changelog.md) · [13 – Library Registry](13_library_registry.md)\n",
|
||||
"docstring": "# Repository Inventory\n\n## Summary\n\nThe canonical list of Aetos repositories covered by the CI and versioning\nstandards, with the artifact each one produces, its version source, and its\nDrone shape. Every entry maps to the contract in\n[91 – Versioning & Changelog](91_versioning_and_changelog.md) and the two CI\nfiles in [90 – Drone Pipelines](90_drone_pipelines.md).\n\nThe same data is published machine-readably as the `registry://repos` MCP\nresource (and the `list_repos` tool), sourced from `standards/src/repos.json`.\nPaths are relative to the `aetos/` workspace root.\n\n---\n\n## Packages (Type A)\n\nA wheel + sdist published to the private index. Version source is\n`pyproject.toml`; Drone file is `python-lib.yaml` (tag-triggered).\n\n| Repo | Path | Docs | MCP server |\n|------|------|------|------------|\n| `dagpipe` | `dagpipe` | lib, wiki | `dagpipe:8006` |\n| `doc-forge` | `doc-forge` | lib, wiki | `docforge:8001` |\n| `hexa` | `hexa` | lib, wiki | `hexa:8008` |\n| `mail-intake` | `mail-intake` | lib, wiki | `mail_intake:8002` |\n| `mongo-ops` | `mongo-ops` | lib, wiki | `mongo_ops:8007` |\n| `omniread` | `omniread` | lib, wiki | `omniread:8003` |\n| `openapi-first` | `openapi-first` | lib, wiki | `openapi_first:8004` |\n| `py-jwt` | `py-jwt` | lib, wiki | `jwtlib:8005` |\n\n---\n\n## Services (Type B)\n\nA container image pushed to the registry and run on the Docker host. Version\nsource is the `VERSION` file; Drone file is `service-docker.yaml`.\n\n| Repo | Path | Trigger | Docs |\n|------|------|---------|------|\n| `auth-server` | `auth-server` | tag | api, lib, wiki |\n\nTag-triggered and enforces `tag == VERSION`.\n\n---\n\n## Required files per repo\n\n| Type | Version source | Changelog | Drone |\n|------|----------------|-----------|-------|\n| package | `pyproject.toml` | `CHANGELOG.md` | `python-lib.yaml` |\n| service | `VERSION` | `CHANGELOG.md` | `service-docker.yaml` |\n\nEvery covered repository must be able to satisfy `tag == version`:\nthe version file (never a commit id) is bumped in the release MR, the MR is\nmerged, and the tag is created on the merged commit.\n\n---\n\n## Reading this at runtime\n\n- Resource: `registry://repos`\n- Tool: `list_repos()`\n- Humans: this page (mirror of `standards/src/repos.json`).\n\n---\n\n## Related\n\n- [90 – Drone Pipelines](90_drone_pipelines.md) · [91 – Versioning & Changelog](91_versioning_and_changelog.md) · [93 – Library Registry](93_library_registry.md)\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
8
standards/mcp/modules/ui_admin.json
Normal file
8
standards/mcp/modules/ui_admin.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"module": "ui_admin",
|
||||
"content": {
|
||||
"path": "ui_admin",
|
||||
"docstring": "# UI: Auto-Rendered Admin & Custom Pages\n\n## Summary\n\nThe UI axis of an Aetos app is a **published React client**, not code written\nper application. Two npm packages carry the whole surface:\n\n| Package | Role |\n|---|---|\n| `@aetoskia/react-openapi` | Renders a complete admin panel (CRUD tables, forms, filters, sorting, pagination, uploads) **from the app's `openapi.yaml`** — zero UI code. |\n| `@aetoskia/react-auth` | Auth contexts and pages (login/register/me) wired to the auth-server, plus the axios client with token handling. |\n\nBoth publish to the private registry `https://npm.aetoskia.com`. The server\nspec is the single source of truth: the same `openapi.yaml` that drives\n`openapi-first` routing drives the admin UI, through **x- extension fields**\n(see below).\n\n---\n\n## Scaffold\n\n```bash\ncp -r <docs>/standards/src/templates/client apps/<your-app>-client\ncd apps/<your-app>-client\nnpm install # deps come from npm.aetoskia.com via .npmrc\nnpm run dev\n```\n\nThe client template is a Vite + MUI app with:\n\n- `src/openapi-config.ts` — points the renderer at the app's spec and the\n auth-server's spec;\n- `.env.example` — `VITE_API_BASE_URL` (app API) and `VITE_AUTH_BASE_URL`\n (auth-server);\n- a `Home` page that auto-lists every resource the spec declares, and a\n `Header`/`Footer`/theme scaffold.\n\nCustom pages are ordinary React routes layered on top; the auto-rendered admin\nis available per resource at `#/resource/<name>`.\n\n---\n\n## x- extensions: how the spec steers the UI\n\nThe admin renderer reads a catalog of OpenAPI extension fields (`x-resource`,\n`x-list-columns`, `x-display-format`, `x-label`, `x-order`, `x-hidden`,\n`x-sortable`, `x-filterable`, `x-autocomplete`, `x-fk`, `x-ui-type`,\n`x-upload`, `x-sse`, `x-profile`, and the auth wiring `x-server-url` /\n`x-login-path` / `x-me-path` / …) declared on schemas and properties.\n\n**The catalog is canonical in the react-openapi source, not in this doc.**\nRead it from the MCP bundle:\n\n```\ndocs://modules/react-openapi # module: specExtensions — the full catalog\n```\n\nThe app's own spec carries the per-resource values; the catalog explains what\neach field does. The template's `openapi.yaml` shows the convention on the\nexample `Item` and `Job` schemas.\n\n---\n\n## Golden rules\n\n1. **The spec owns the UI.** Add a resource or rename a column in\n `openapi.yaml`; the admin follows. Never fork the renderer per app.\n2. **Custom pages for workflows, auto-render for CRUD.** Anything that is\n \"list / create / edit / delete an entity\" is a spec concern; anything that\n is a bespoke workflow is a React page.\n3. **Auth is consumed, never re-implemented.** `@aetoskia/react-auth` holds\n tokens and calls the auth-server endpoints declared by the x- wiring; pages\n read the context.\n4. **Publish, don't vendor.** UI shared across apps belongs in\n `@aetoskia/react-openapi` or `@aetoskia/react-auth` (SemVer, tag-triggered\n npm release), not copy-pasted into app trees.\n\n---\n\n## Notes\n\n- The server template ships authless by default (see\n [22 – Auth Integration](22_auth_integration.md)); the client template pairs\n with it and degrades to \"no login\" until a security scheme is declared.\n- `react/vet` is the full-stack reference implementation: spec with x-\n extensions, server, and the consuming client in one tree.\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
"module": "wiki_development_releasing",
|
||||
"content": {
|
||||
"path": "wiki_development_releasing",
|
||||
"docstring": "# Releasing & Versioning\n\nHow to cut a release of any Aetos repository. The rule lives in the reference\npage [Versioning & Changelog](../lib/11_versioning_and_changelog/); this is the\nrunbook you follow.\n\nEvery repository is one of two Drone shapes — a **PyPI package** or a **Docker\ndeployment** ([Drone Pipelines](../lib/10_drone_pipelines/)). Both release the\nsame way: the version bump and changelog promotion go **in the merge request**,\nand the tag is created on the merged commit.\n\n---\n\n## 🧾 Before you start\n\n- You have an open **merge request** holding the change, and `main` is green\n (the Drone quality gate passed on the last run).\n- You know whether this is a **breaking**, **feature**, or **fix** release.\n- The version file exists:\n - package → `version` in `pyproject.toml`\n - service → `VERSION` at the repo root\n\n---\n\n## 🚦 Pick the next version\n\nThe version file and the tag must be identical. For `0.y.z`, `0.y` is the major\nline (see the reference page); once at `1.0.0`, normal SemVer applies.\n\n| Change | `0.y.z` → | `1.0.0+` → |\n|--------|-----------|------------|\n| Breaking | `0.(y+1).0` | `(x+1).0.0` |\n| Feature | `0.y.(z+1)` | `x.(y+1).0` |\n| Fix | `0.y.(z+1)` | `x.y.(z+1)` |\n\n---\n\n## 🌿 Release in the MR\n\nThe version is known while the change is still a merge request, so the bump\nrides along with it. Do all edits **in the MR**:\n\n- **Reconcile the changelog first.** `[Unreleased]` is a **draft, not the source\n of truth**: diff the change against the last tag\n (`git log <last-tag>..HEAD`, `git diff --stat <last-tag>..HEAD`) and add an\n entry for every user-facing change that is missing. **Always show the proposed\n additions to the user and wait for approval** before promoting — ask rather\n than guess when an entry is ambiguous.\n\n- **Promote the changelog** in `CHANGELOG.md`: move the (now reconciled)\n `[Unreleased]` content under a new `## [x.y.z] - YYYY-MM-DD` heading, leave a\n fresh empty `[Unreleased]` on top, and add the compare links — naming the\n **version/tag**, never a commit id:\n\n ```markdown\n [Unreleased]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.z...HEAD\n [x.y.z]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.(z-1)...x.y.z\n ```\n\n- **Bump the version file** to the intended release version: `version = \"x.y.z\"`\n in `pyproject.toml` (packages) or the `VERSION` file (services).\n\n---\n\n## 🏷️ Tag the merged commit\n\n1. **Merge or squash** the MR into `main`.\n2. **Create the tag** on the resulting commit: `git tag x.y.z` (lightweight).\n3. **Push the tag** (`git push origin x.y.z`) — Drone builds the release.\n\n### 🤖 Agent-assisted tagging\n\nThe agent does not author or merge the MR and never tags before the merge. After\nyou confirm the MR is merged/squashed and tell it to proceed, the agent:\n\n1. Waits for that explicit go-ahead.\n2. Finds the commit that introduced the bump:\n - package:\n `git log -S 'version = \"x.y.z\"' -n 1 --format='%H %s' -- pyproject.toml`\n - service:\n `git log -S 'x.y.z' -n 1 --format='%H %s' -- VERSION`\n3. Verifies that commit's version file equals `x.y.z`, then tags **only** that\n commit: `git tag x.y.z <sha>`.\n4. Does **not** push — it asks you to run `git push origin x.y.z`.\n\n---\n\n## 🤖 What Drone does\n\n- **Type A (package):** asserts `tag == pyproject version`, then skips if that\n version already exists on the index, runs the quality gate, builds, and\n uploads the wheel + sdist.\n- **Type B (service):** asserts `tag == VERSION`, resolves the tag, skips if the\n image already exists, runs the quality gate, builds, pushes, and restarts the\n container.\n\nIf the guard fails, nothing is published — fix the version file, amend the\ncommit, and move the tag **only** if it was never pushed.\n\n---\n\n## 🛟 Backfill / recovery\n\nIf an older tag never published (a past version-file mismatch, an index\noutage):\n\n- **Package:** run the `backfill-pypi-from-tags` pipeline (custom event). It\n checks out every tag, verifies `tag == pyproject version` at that commit,\n and uploads the ones missing from the index. Already-fixed history is never\n rewritten.\n- **Service:** rebuild the image for the missing tag with a fresh commit and a\n new patch version; do not move a published tag.\n\n---\n\n## 🔁 If a release is wrong\n\n- Never reuse or force-move a pushed tag.\n- Fix forward: bump to the next patch, promote the changelog, tag again.\n\n---\n\n## Related\n\n- [Testing & Quality Gates](01_testing.md) · [Versioning & Changelog](../lib/11_versioning_and_changelog/) · [Drone Pipelines](../lib/10_drone_pipelines/)\n",
|
||||
"docstring": "# Releasing & Versioning\n\nHow to cut a release of any Aetos repository. The rule lives in the reference\npage [Versioning & Changelog](../lib/91_versioning_and_changelog/); this is the\nrunbook you follow.\n\nEvery repository is one of two Drone shapes — a **PyPI package** or a **Docker\ndeployment** ([Drone Pipelines](../lib/90_drone_pipelines/)). Both release the\nsame way: the version bump and changelog promotion go **in the merge request**,\nand the tag is created on the merged commit.\n\n---\n\n## 🧾 Before you start\n\n- You have an open **merge request** holding the change, and `main` is green\n (the Drone quality gate passed on the last run).\n- You know whether this is a **breaking**, **feature**, or **fix** release.\n- The version file exists:\n - package → `version` in `pyproject.toml`\n - service → `VERSION` at the repo root\n\n---\n\n## 🚦 Pick the next version\n\nThe version file and the tag must be identical. For `0.y.z`, `0.y` is the major\nline (see the reference page); once at `1.0.0`, normal SemVer applies.\n\n| Change | `0.y.z` → | `1.0.0+` → |\n|--------|-----------|------------|\n| Breaking | `0.(y+1).0` | `(x+1).0.0` |\n| Feature | `0.y.(z+1)` | `x.(y+1).0` |\n| Fix | `0.y.(z+1)` | `x.y.(z+1)` |\n\n---\n\n## 🌿 Release in the MR\n\nThe version is known while the change is still a merge request, so the bump\nrides along with it. Do all edits **in the MR**:\n\n- **Reconcile the changelog first.** `[Unreleased]` is a **draft, not the source\n of truth**: diff the change against the last tag\n (`git log <last-tag>..HEAD`, `git diff --stat <last-tag>..HEAD`) and add an\n entry for every user-facing change that is missing. **Always show the proposed\n additions to the user and wait for approval** before promoting — ask rather\n than guess when an entry is ambiguous.\n\n- **Promote the changelog** in `CHANGELOG.md`: move the (now reconciled)\n `[Unreleased]` content under a new `## [x.y.z] - YYYY-MM-DD` heading, leave a\n fresh empty `[Unreleased]` on top, and add the compare links — naming the\n **version/tag**, never a commit id:\n\n ```markdown\n [Unreleased]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.z...HEAD\n [x.y.z]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.(z-1)...x.y.z\n ```\n\n- **Bump the version file** to the intended release version: `version = \"x.y.z\"`\n in `pyproject.toml` (packages) or the `VERSION` file (services).\n\n---\n\n## 🏷️ Tag the merged commit\n\n1. **Merge or squash** the MR into `main`.\n2. **Create the tag** on the resulting commit: `git tag x.y.z` (lightweight).\n3. **Push the tag** (`git push origin x.y.z`) — Drone builds the release.\n\n### 🤖 Agent-assisted tagging\n\nThe agent does not author or merge the MR and never tags before the merge. After\nyou confirm the MR is merged/squashed and tell it to proceed, the agent:\n\n1. Waits for that explicit go-ahead.\n2. Finds the commit that introduced the bump:\n - package:\n `git log -S 'version = \"x.y.z\"' -n 1 --format='%H %s' -- pyproject.toml`\n - service:\n `git log -S 'x.y.z' -n 1 --format='%H %s' -- VERSION`\n3. Verifies that commit's version file equals `x.y.z`, then tags **only** that\n commit: `git tag x.y.z <sha>`.\n4. Does **not** push — it asks you to run `git push origin x.y.z`.\n\n---\n\n## 🤖 What Drone does\n\n- **Type A (package):** asserts `tag == pyproject version`, then skips if that\n version already exists on the index, runs the quality gate, builds, and\n uploads the wheel + sdist.\n- **Type B (service):** asserts `tag == VERSION`, resolves the tag, skips if the\n image already exists, runs the quality gate, builds, pushes, and restarts the\n container.\n\nIf the guard fails, nothing is published — fix the version file, amend the\ncommit, and move the tag **only** if it was never pushed.\n\n---\n\n## 🛟 Backfill / recovery\n\nIf an older tag never published (a past version-file mismatch, an index\noutage):\n\n- **Package:** run the `backfill-pypi-from-tags` pipeline (custom event). It\n checks out every tag, verifies `tag == pyproject version` at that commit,\n and uploads the ones missing from the index. Already-fixed history is never\n rewritten.\n- **Service:** rebuild the image for the missing tag with a fresh commit and a\n new patch version; do not move a published tag.\n\n---\n\n## 🔁 If a release is wrong\n\n- Never reuse or force-move a pushed tag.\n- Fix forward: bump to the next patch, promote the changelog, tag again.\n\n---\n\n## Related\n\n- [Testing & Quality Gates](01_testing.md) · [Versioning & Changelog](../lib/91_versioning_and_changelog/) · [Drone Pipelines](../lib/90_drone_pipelines/)\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "wiki_index",
|
||||
"content": {
|
||||
"path": "wiki_index",
|
||||
"docstring": "# 🧩 Standards — the Aetos App Blueprint\n\nOne reusable architecture for every backend application in the Aetos ecosystem:\na spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure\nlayer, and a single composition root.\n\nFill in **two axes only** and a new app is done: your **resource model**, and\n(if needed) your **pipeline family**. The blueprint itself never names a\nbusiness domain — expenses, health metrics, inventory, and analytics are all\nthe same shape underneath.\n\n> **Doc model:** this wiki is written for humans — how-to guides, the build\n> recipe, and quality gates. The enforceable rules (layering, composition root,\n> CRUD template, pipeline scaffold) and the library registry live in the\n> **reference** pages, mirrored by the machine-readable `standards` MCP bundle.\n> Query `find_library` before writing any infrastructure.\n\n---\n\n## 🚀 Key Features\n\n- 🧭 **Spec-first routing** — the OpenAPI document, not decorator routers, is\n the source of truth (operationId lookup)\n- 🏗️ **One-way layering** — `interfaces → domain → infra`, enforced\n- 🔌 **Single composition root** — every dependency is wired in exactly one place\n- 🧩 **Generic, not app-specific** — reusable rules versus two authoring axes\n- 📚 **Library-backed** — DB, DI, pipelines, ingestion, auth, and docs come from\n internal libraries, never hand-written\n- 🚦 **Explicit state machines** — durable job statuses, progress, and\n human-in-the-loop pauses\n\n---\n\n## 📁 Documentation Structure\n\n| Section | Description |\n|-----------------------------------------------------|--------------------------------------------------------|\n| [Overview](01_overview.md) | Philosophy, the one-way dependency rule, architecture |\n| [App Components](02_components.md) | The component model and how the pieces wire together |\n| [Start an App](03_start_an_app.md) | The entry point: gather the two axes, then build |\n| [Testing & Quality](04_development/01_testing.md) | Test layout and acceptance gates |\n\n**Reference** (separate site, mirrors the MCP bundle): the enforceable\nrules — [Build Recipe](../lib/01_build_recipe/), [Layering](../lib/02_layering_rules/), [Composition\nRoot](../lib/03_composition_root/), [Spec-First\nRouting](../lib/04_spec_first_routing/), [CRUD\nTemplate](../lib/05_crud_template/), [Pipeline\nScaffold](../lib/06_pipeline_scaffold/), [Worker &\nProgress](../lib/07_worker_and_progress/), [Human-in-the-Loop](../lib/08_human_in_loop/),\n[Infra Adapters](../lib/09_infra_adaptors/), [Genericity\nMatrix](../lib/12_genericity_matrix/), [Library\nRegistry](../lib/13_library_registry/).\n\n---\n\n## 🔗 Related Resources\n\n- **MCP bundle** — `standards` server on `:8009`: read `docs://index`,\n `docs://nav`, `docs://modules/{module}`; call `find_library(capability)`\n- **Library registry** — the catalog of internal libraries behind every app\n (`libraries.json`, served as `registry://libraries`)\n- **Template** — the runnable skeleton at `standards/src/templates/app/`\n- **Start a build** — invoke the `start_app` prompt on the `standards` server,\n or read the [Start an App](03_start_an_app.md) guide\n\n---\n\n© Aetoskia Internal — `standards`\n",
|
||||
"docstring": "# 🧩 Standards — the Aetos App Blueprint\n\nOne reusable architecture for every backend application in the Aetos ecosystem:\na spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure\nlayer, and a single composition root.\n\nFill in **two axes only** and a new app is done: your **resource model**, and\n(if needed) your **pipeline family**. The blueprint itself never names a\nbusiness domain — expenses, health metrics, inventory, and analytics are all\nthe same shape underneath.\n\n> **Doc model:** this wiki is written for humans — how-to guides, the build\n> recipe, and quality gates. The enforceable rules (layering, composition root,\n> CRUD template, pipeline scaffold) and the library registry live in the\n> **reference** pages, mirrored by the machine-readable `standards` MCP bundle.\n> Query `find_library` before writing any infrastructure.\n\n---\n\n## 🚀 Key Features\n\n- 🧭 **Spec-first routing** — the OpenAPI document, not decorator routers, is\n the source of truth (operationId lookup)\n- 🏗️ **One-way layering** — `interfaces → domain → infra`, enforced\n- 🔌 **Single composition root** — every dependency is wired in exactly one place\n- 🧩 **Generic, not app-specific** — reusable rules versus two authoring axes\n- 📚 **Library-backed** — DB, DI, pipelines, ingestion, auth, and docs come from\n internal libraries, never hand-written\n- 🚦 **Explicit state machines** — durable job statuses, progress, and\n human-in-the-loop pauses\n\n---\n\n## 📁 Documentation Structure\n\n| Section | Description |\n|-----------------------------------------------------|--------------------------------------------------------|\n| [Overview](01_overview.md) | Philosophy, the one-way dependency rule, architecture |\n| [App Components](02_components.md) | The component model and how the pieces wire together |\n| [Start an App](03_start_an_app.md) | The entry point: gather the two axes, then build |\n| [Testing & Quality](04_development/01_testing.md) | Test layout and acceptance gates |\n\n**Reference** (separate site, mirrors the MCP bundle): the enforceable\nanatomy — start at the [Build Recipe](../lib/01_build_recipe/), then the\npillars: domains ([Layering](../lib/10_layering_rules/)), the OpenAPI\ncontract ([Composition Root](../lib/02_composition_root/),\n[Spec-First Routing](../lib/20_spec_first_routing/), [CRUD\nTemplate](../lib/21_crud_template/), [Auth\nIntegration](../lib/22_auth_integration/)), interfaces & infra ([Infra\nAdapters](../lib/30_infra_adaptors/)), UI ([Auto-Rendered\nAdmin](../lib/40_ui_admin/)), the optional pipelines layer ([Pipeline\nScaffold](../lib/50_pipeline_scaffold/), [Worker &\nProgress](../lib/51_worker_and_progress/), [Human-in-the-Loop](../lib/52_human_in_loop/)),\nand delivery/meta ([Genericity\nMatrix](../lib/92_genericity_matrix/), [Library\nRegistry](../lib/93_library_registry/)).\n\n---\n\n## 🔗 Related Resources\n\n- **MCP bundle** — `standards` server on `:8009`: read `docs://index`,\n `docs://nav`, `docs://modules/{module}`; call `find_library(capability)`\n- **Library registry** — the catalog of internal libraries behind every app\n (`libraries.json`, served as `registry://libraries`)\n- **Template** — the runnable skeleton at `standards/src/templates/app/`\n- **Start a build** — invoke the `start_app` prompt on the `standards` server,\n or read the [Start an App](03_start_an_app.md) guide\n\n---\n\n© Aetoskia Internal — `standards`\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
"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",
|
||||
"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/93_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": {}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "wiki_start_an_app",
|
||||
"content": {
|
||||
"path": "wiki_start_an_app",
|
||||
"docstring": "# 🚀 Start an App\n\nThis is the entry point for building a new application from the blueprint. The\ngoal is one deterministic pass: you supply only the **two axes**, and the agent\ndoes the rest by reading the `standards` MCP, importing Tier A libraries, and\ncopying Tier B template components.\n\n> **Doc model:** this page is the human entry point. The deterministic,\n> machine-facing checklist lives in the reference page\n> [Build Recipe](../lib/01_build_recipe/), served as `docs://modules/build_recipe`.\n\n---\n\n## 🧾 What the agent needs from you\n\nGather these before starting — the `start_app` MCP prompt asks for them:\n\n1. **App name + one-line purpose.**\n2. **Axis 1 — resources.** Each resource, its fields, and relationships. Paste\n `openapi.yaml` if you already have it.\n3. **Axis 2 — pipelines.** Only if an input needs a multi-step transformation:\n the families and their input formats (or \"none\").\n4. **Auth needed now?** Default **no**. Auth is deferred (`py-jwt` primitives\n only), and an authless app is just a spec with no `security` keys — see\n [Spec-First Routing → Authless apps](../lib/04_spec_first_routing/#authless-apps).\n5. **Integrations.** Mongo, ingestion formats, email, LLM provider.\n\nIf you can state axes 1 and 2, the rest is mechanical.\n\n---\n\n## ▶️ How to start\n\nFrom an MCP client connected to the `standards` server:\n\n1. Invoke the **`intake`** prompt (or `start_app` with no arguments) to get the\n intake questions.\n2. Answer them, then invoke **`build`**\n (`build(app_name=..., resources=..., pipelines=..., auth=...)`), or use\n **`start_app`** to intake-and-build in one call.\n3. The prompt hands off to `docs://modules/build_recipe`; the agent scaffolds\n with `get_app_template()` and pulls exact files with\n `get_app_component(kind, resource=..., family=...)`, authoring only the\n app-specific parts.\n4. To validate the standard without touching a real app, invoke **`trial`**\n (`trial(app_name=..., build_path=...)`) to build into a scratch directory,\n prove it builds, and report findings.\n\nManual alternative — copy the skeleton and follow the reference recipe:\n\n```bash\ncp -r <docs>/standards/src/templates/app apps/<your-app>\n```\n\n---\n\n## 📚 Reference\n\n- [Build Recipe](../lib/01_build_recipe/) — the deterministic checklist\n- [Genericity Matrix](../lib/12_genericity_matrix/) — Tier A / B / C\n- [Library Registry](../lib/13_library_registry/) — the Tier A catalog\n- [App Components](02_components.md) — the component model\n\n---\n\n## Related\n\n- [01 – Overview](01_overview.md) · [02 – App Components](02_components.md) · [04 – Testing & Quality](04_development/01_testing.md)\n",
|
||||
"docstring": "# 🚀 Start an App\n\nThis is the entry point for building a new application from the blueprint. The\ngoal is one deterministic pass: you supply only the **two axes**, and the agent\ndoes the rest by reading the `standards` MCP, importing Tier A libraries, and\ncopying Tier B template components.\n\n> **Doc model:** this page is the human entry point. The deterministic,\n> machine-facing checklist lives in the reference page\n> [Build Recipe](../lib/01_build_recipe/), served as `docs://modules/build_recipe`.\n\n---\n\n## 🧾 What the agent needs from you\n\nGather these before starting — the `start_app` MCP prompt asks for them:\n\n1. **App name + one-line purpose.**\n2. **Axis 1 — resources.** Each resource, its fields, and relationships. Paste\n `openapi.yaml` if you already have it.\n3. **Axis 2 — pipelines.** Only if an input needs a multi-step transformation:\n the families and their input formats (or \"none\").\n4. **Auth needed now?** Default **no**. Auth is deferred (`py-jwt` primitives\n only), and an authless app is just a spec with no `security` keys — see\n [Spec-First Routing → Authless apps](../lib/20_spec_first_routing/#authless-apps).\n5. **Integrations.** Mongo, ingestion formats, email, LLM provider.\n\nIf you can state axes 1 and 2, the rest is mechanical.\n\n---\n\n## ▶️ How to start\n\nFrom an MCP client connected to the `standards` server:\n\n1. Invoke the **`intake`** prompt (or `start_app` with no arguments) to get the\n intake questions.\n2. Answer them, then invoke **`build`**\n (`build(app_name=..., resources=..., pipelines=..., auth=...)`), or use\n **`start_app`** to intake-and-build in one call.\n3. The prompt hands off to `docs://modules/build_recipe`; the agent scaffolds\n with `get_app_template()` and pulls exact files with\n `get_app_component(kind, resource=..., family=...)`, authoring only the\n app-specific parts.\n4. To validate the standard without touching a real app, invoke **`trial`**\n (`trial(app_name=..., build_path=...)`) to build into a scratch directory,\n prove it builds, and report findings.\n\nManual alternative — copy the skeleton and follow the reference recipe:\n\n```bash\ncp -r <docs>/standards/src/templates/app apps/<your-app>\n```\n\n---\n\n## 📚 Reference\n\n- [Build Recipe](../lib/01_build_recipe/) — the deterministic checklist\n- [Genericity Matrix](../lib/92_genericity_matrix/) — Tier A / B / C\n- [Library Registry](../lib/93_library_registry/) — the Tier A catalog\n- [App Components](02_components.md) — the component model\n\n---\n\n## Related\n\n- [01 – Overview](01_overview.md) · [02 – App Components](02_components.md) · [04 – Testing & Quality](04_development/01_testing.md)\n",
|
||||
"objects": {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user