The stack is boring on purpose. Python 3.12, FastAPI, Postgres, Redis, React with Vite, one Dockerfile behind nginx. Nothing there is a decision anyone should be impressed by; those are the parts you pick so you can spend your attention elsewhere.
Here is the shape of what sits on it, counted this morning:
| files | lines | |
|---|---|---|
pantheon-core: the substrate |
146 | 14,002 |
apps/gateway, HTTP, routes, MCP |
87 | 24,814 |
apps/studio: the React SPA |
36 | 9,207 |
| core tests | 85 | 9,205 |
| gateway tests | 125 | 15,011 |
Two things in that table are worth more than the framework list.
Half as much test as application
24,216 lines of tests against 48,023 lines of application, and against the Python alone, 24,216 against 38,816. That ratio is not a boast about diligence. It is the only reason an AI-built system is safe to run at all.
I do not hand-write the implementation. That means I cannot rely on having felt every line into place: the usual, unspoken source of a developer's confidence is simply not available to me. What replaces it is an executable statement of what must remain true, and a machine that re-checks it on every commit.
If you direct AI to build, the test suite stops being a safety net and becomes the specification. It is the artefact you actually author.
The boundary is enforced by a machine, not a convention
pantheon-core may not import from residents or bundles. Not "should
not", cannot, because two independent checks fail CI when it does.
One is .importlinter, a declared contract:
[importlinter:contract:core-purity]
name = pantheon-core must not import residents or bundles
type = forbidden
source_modules =
pantheon
forbidden_modules =
residents
bundles
The other is an AST test that walks every file under the core and collects the root of every import, deliberately not requiring those packages to be installed. Its own docstring calls it "the structural twin" of the linter.
Belt and braces, because a boundary that is enforced by one mechanism is enforced until someone edits that mechanism.
There is a second contract underneath it, five layers deep, one-way:
layers =
architect | interop
runtime
guardrails
substrate
primitives
The comment above it earns its place by naming the exception rather than
hiding it: providers is deliberately not layered, because it sits below
both guardrails (which needs build_llm) and substrate (which needs
memory embeddings), and a strict linear stack cannot express that. A contract
that quietly bends to fit reality is worthless; one that documents where it
refuses to bend is a design.
What the boundary actually bought
It sounds like architectural hygiene. It paid out as something concrete.
Six components have been lifted out of this codebase and published, a constitution scorer, a tool sanitizer, an SSRF guard, the RLS helper, an iCal round-tripper, a credit ledger. All Apache-2.0, all on PyPI, all installable by strangers who will never see the product.
That was possible in an afternoon each because the boundary already existed. Extraction was not surgery; it was mostly moving files that had never been allowed to reach downward in the first place.
The first one I tried still needed real work: the scorer imported the application's settings object, which would have dragged Stripe keys, OAuth secrets and provider credentials into a public library. Replacing that with an injected judge protocol made the published version the better design, and that is the honest part of the story, because it means the boundary was good but not perfect, and the only way I found the gap was by trying to walk through it.
The gateway is bigger than the substrate
24,814 lines of HTTP against 14,002 lines of domain. I noticed that while writing this, and I do not have a satisfying account of it yet.
Some is legitimate: routes, auth, MCP in both directions, streaming, and the anonymous-pool ceiling all live there. Some is probably domain logic that drifted upward into route handlers because that was where the request already was, which is the exact gravity the purity contract exists to resist, applied one layer higher where nothing is currently checking.
I am recording it here rather than quietly fixing it before anyone notices. The measurement is a week old at most, and I would rather be seen finding it than be seen having always known.
The purity contracts are in .importlinter and tests/test_purity.py;
CI runs lint-imports and the suite on every commit.