Diving Deep
Reference documentation for every Proteus subsystem, written for someone extending the code.
This chapter is the reference. Each page covers one subsystem: the real class and function names, the contract it presents to its neighbors, the invariants it holds, and why those invariants exist.
The audience is someone about to change the code. If you only want to run Proteus, Operations has the worked examples and Quick Start has the four commands.
The pages#
| Page | Covers |
|---|---|
| Architecture | The three-layer pipeline, the six frozen files, and why the seams are where they are |
| The world model | proteus/model/schema.py: WorldModel, Service, InfraNode, Tenant, Fault, the four enums, persistence and PROTEUS_HOME |
| The catalog | Hand-written archetypes versus declarative profiles; ArchetypeGenerator, WorkloadProfile, MetricSpec, Shape; how to add an AWS service |
| Faults | FaultEffect as the seam, the 14 kinds, ramping, propagation along depends_on, infra contention, noisy-neighbor asymmetry |
| The renderer | Determinism, Tick, tick_rng, Window, and the four record types |
| Emitters | OTLP over HTTP, SigV4, protobuf, the three endpoints, per-request limits, log streams, RUM |
| The cost guard | Projection, the 5 policies, the live AWS Pricing API, the spend ledger |
| Provisioning | CloudFormation synth, deploy and teardown; drift, fingerprints, S3 staging, ownership proofs |
| The web GUI | No-build ES modules, the state/render split, the canvas camera, theming tokens, the HTTP surface |
The layering rule#
Read this before changing anything, because almost every design decision in the chapter follows from it:
A layer may depend on the layer below it and on nothing above it.
flowchart TD
subgraph drivers["drivers: read input, call down"]
CLI["cli"]
WEB["web"]
AI["ai"]
end
subgraph effects["side effects live only here"]
GUARD["guard"]
CFN["cfn"]
EMIT["emit"]
end
subgraph pure["pure: no I/O, no clock, no random"]
ENGINE["render.engine"]
CATALOG["catalog"]
FAULTS["faults"]
end
subgraph data["data only"]
MODEL["model"]
RECORDS["render.records"]
end
drivers --> effects
drivers --> pure
EMIT --> RECORDS
GUARD --> MODEL
CFN --> MODEL
ENGINE --> CATALOG
CATALOG --> FAULTS
CATALOG --> RECORDS
FAULTS --> RECORDS
FAULTS --> MODEL
ENGINE --> MODELEvery edge there is a real top-level import, read out of the tree rather than drawn from memory. Two things that earlier hand-drawn versions of this graph got wrong are worth stating, because both look like rule violations and neither is.
render is two layers, not one. render/records.py imports nothing — not from
proteus, not from model — which makes it the true bottom of the tree. catalog imports
those record types; render/engine.py then imports catalog to call the generators. So
the chain is render.records → catalog → render.engine, and it is a DAG. Treating
render as a single box is what makes it look like a cycle with catalog.
model reaches up to catalog, in two places, deliberately.
model/cfnimport/build.py and model/liveclone/validate.py import catalog.profile to
check that a workload kind exists. Both imports are function-local, so nothing is
imported upward at module load and the data layer stays a leaf. That is the standard way
around a circular import, and the only upward reach in the package.
Three consequences worth stating explicitly.
The LLM never emits telemetry. proteus/ai/ edits a WorldModel and does
nothing else. It cannot write a metric, because writing a metric means being an
emitter, and an emitter is two layers away. A model that describes an incident is
a document you can read, diff and check into git; a stream of numbers an LLM
produced directly is neither.
render/ and catalog/ must stay importable and runnable with no network and
no credentials. Not "should" — this is what makes a fault testable by golden
file rather than by squinting at a console. CONTRACTS.md asks you to verify it
by stubbing sockets and deleting every AWS_* and PROTEUS_* variable, not by
reading the import list.
Network calls live in emit/, cfn/, ai/ and guard/. The fourth is a
known exception and is documented as one: guard/estimate.py reaches the AWS
Pricing API through proteus/pricing.py to price a projection. Pass region=""
to project() for a guaranteed offline projection. See
the cost guard for why the paranoid policy
does exactly that.
Conventions used throughout the chapter#
Units are stated on every number. Milliseconds for latency, percentage points for
utilisation addends, absolute counts for depths and connections, absolute
fractions for error rates and packet loss, dimensionless for anything named
*_mult.
Where a page says a value is verified, it was read out of this repository or produced by running the code, not recalled. Where something could not be verified, the page says so.
Exhaustive tables — all 68 workload types, all 14 fault kinds, every AWS limit, every environment variable — live in the Appendix. This chapter explains the mechanisms; the appendix lists the values.