Skip to content

Genericity Matrix

Summary

This page states precisely what is library-backed, what is template-provided, and what is app-specific and must be authored. Use it to scope a new build and to know, for any given capability, whether to call a library, copy template code, or write it yourself.


Tier A — Library-backed (use; never reimplement)

These capabilities already exist as internal libraries. Reach them through the library registry MCP (find_library(capability)) and read the library's own MCP for its API. Writing a private copy of any of these is a defect.

Capability Library MCP
Persistence: repositories, cache, populate, transactions Mongo Ops (mongo_ops) :8007
Dependency injection / composition Hexa (hexa) :8008
Deterministic multi-step transformation engine DAG Pipe (dagpipe) :8006
Spec-first HTTP edge, client, codegen OpenAPI First (openapi_first) :8004
Format-agnostic fetch + parse (HTML, PDF, CSV, XLSX) Omniread (omniread) :8003
Read-only email ingestion Mail Intake (mail_intake) :8002
JWT auth primitives (register, login, introspect) Py JWT (jwtlib) :8005
Documentation build (MkDocs + MCP) Doc Forge (docforge) :8001

Tier B — Template-provided (copy from templates/app, then adapt)

These are reusable internal components shipped inside the template — they are not independent libraries. Copy them as-is, then rename/populate only what is app-specific. They give every app the same wiring shape as the reference app. Fetch them by kind with get_app_component, or the whole tree with get_app_template.

Component Template location Action Shipped
Layering & dependency rule the package layout + import rules keep ✅
Composition root shape init.py (get_svc/get_db, idempotency) keep ✅
Spec-first web edge interfaces/openapi.py, thin handlers bound to operationId keep ✅
CRUD slice pattern domain/<resource>/{models.py, ports/db.py, ports/service.py, converters.py} rename + fill ✅
Generic CRUD service infra/adapters/service.py (CrudsServiceAdaptor) keep ✅
Repository factory infra/db/repos/mongo.py (_repo_factory) keep ✅
Worker poll + status loop worker.py keep ✅
Progress bus infra/adapters/sse.py (keyed in-memory bus) + an app SSE endpoint keep ✅
HTTP response cache infra/http_cache.py (cache_response + generation invalidation) keep ✅
Key-value store infra/adapters/kv.py (port + in-memory + Redis adaptor) keep ✅
Pipeline scaffold pipelines/shared/{ports,loader,registry}.py + pipelines/<family>/ rename + fill ✅
Operator scripts scripts/ (init() / get_svc() / shutdown()) rename ✅
Testing harness integration fakes + fixture-parity pattern keep ✅
Project scaffolding pyproject.toml, Dockerfile, docker-compose.yaml, .env.example, openapi.yaml rename + fill ✅

Tier B (patterns) — port from the reference app

A few Tier B capabilities are real and reusable, but are shaped by the app or the provider, so the template does not ship them verbatim — copying them blindly would carry app-specific names. Treat them as patterns: lift the shape from the reference app and rename per app.

Component Reference location Action Shipped
Human-in-the-loop durable pause + question document + resolve endpoint + resume map port + reshape ✗
LLM client pool provider-select + retry/rotation pool scaffold port + reshape ✗

Tier C — App-specific (must be authored)

Artifact Why
Resource models the business shape
Repository populate/cache rules the relationships
Service business logic domain behaviour
Pipeline families the transformation graph
Pattern/rule resources data-driven policy
Fixtures & golden outputs test data

The two axes

Everything app-specific reduces to two axes:

  1. Resource model — the set of resources, their fields, relationships, and the OpenAPI contract.
  2. Pipeline family — only if inputs require multi-step transformation.

If you can specify those two axes, the rest of the app follows mechanically: Tier A is imported, Tier B is copied, and Tier C is the only thing you author.