Design Rationale

Why No Database

The documentation system already has a data model. It has been refined over 15 months across 3,486 files. The directory structure IS the schema:

pages/
├── standards/       → 21 governance documents (STD-001 through STD-020 + template)
├── case-studies/    → 80 operational records (5 types)
├── patterns/        → 95 experiential knowledge entries (18 domains)
├── codex/           → 114 CLI reference cards (17 categories)
├── projects/        → 369 project documents (55 projects)
├── education/       → 808 learning materials (44% of the system)
├── sessions/        → 16 AI collaboration logs
├── 2026/            → 105 chronological worklogs
└── ...              → 20 top-level categories total

Adding a database would create a copy. Copies drift. The filesystem is the single source of truth — the API reads from it directly and writes to it directly. When you create an incident through the API, the file appears in case-studies/incidents/ immediately. When you search, the API reads the actual files. There is no sync, no migration, no cache invalidation problem.

The only concession is an in-memory metadata cache loaded at startup. Titles, attributes, and file paths for all files are parsed once and held in a Python dict. Content is loaded on demand. The cache makes list operations instant. The filesystem makes writes durable.

The Stack

Component Why This One

FastAPI

Auto-generates OpenAPI schema. Every endpoint self-documents. Pydantic validation rejects malformed requests before they reach your code. Async by default.

Pydantic v2

Type-safe models for every request and response. Enums enforce controlled vocabularies (P1-P4 severity, low-critical risk levels). Validation errors return structured JSON, not stack traces.

uvicorn

ASGI server. Starts in under 2 seconds. --reload watches for changes. Production-grade.

PyYAML

Parses antora.yml for the 127 attributes that define every mutable value in the system.

No ORM

There is no database. pathlib.Path.rglob("*.adoc") is the query engine. re.match is the metadata parser. The standard library does the work.

How It Connects

Terminal (curl/jq)          domus-api (FastAPI)          Filesystem (AsciiDoc)
      │                          │                              │
      │  GET /search?q=mandiant  │                              │
      ├─────────────────────────►│  grep across cached files     │
      │                          ├─────────────────────────────►│
      │                          │  13 results, ranked           │
      │◄─────────────────────────┤                              │
      │  JSON response            │                              │
      │                          │                              │
      │  POST /case-studies/     │                              │
      │       incidents          │  scaffold from template       │
      ├─────────────────────────►│  validate via Pydantic        │
      │                          │  write INC-2026-04-06.adoc    │
      │                          ├─────────────────────────────►│
      │◄─────────────────────────┤                              │
      │  {"id": "INC-...",       │                              │
      │   "file_path": "..."}   │                              │

The API is a bridge between the terminal and the filesystem. It does not replace either. It makes the filesystem programmable without requiring the human to remember file paths, naming conventions, or template structures. The standards are embedded in the scaffolder service — STD-011 for incidents, STD-005 for changes, STD-010 for RCAs, STD-001 for projects. Compliance is automatic.

What This Enables

Today: curl -s localhost:8080/search?q=mandiant | jq finds 13 documents in milliseconds.

Tomorrow: Your Z Fold 7 queries the API over Tailscale. An Ollama model reads your documentation and answers questions in natural language. A webhook watches for resolved incidents and auto-scaffolds RCAs. A CI pipeline queries /standards to verify that every standard is Active before deploying.

The system scales because the architecture is simple. Add a spoke repository to the config and the API indexes it. Add an endpoint to a route file and it appears in the OpenAPI schema. The filesystem grows, the cache grows, the API grows. Nothing breaks because nothing is coupled.

This is not a prototype. It loaded 3,486 files in under 2 seconds. It serves responses in single-digit milliseconds. It runs on localhost with zero infrastructure. It was built in one session because the documentation system it exposes was built correctly in the first place.

The API did not make the documentation system valuable. The documentation system was already valuable. The API made it accessible.