PROTEUS docs
v0.1.0 Jeremy Hall

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 --> MODEL

Every 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.

Proteus is MIT-licensed. Built by Jeremy Hall.

Synthetic telemetry for CloudWatch Omni. Everything it emits is fabricated; nothing in it describes a real system.