PROTEUS docs
v0.1.0 Jeremy Hall

Operations

Worked walkthroughs for the CLI and the Web GUI, each with a goal, the steps, and how to confirm it worked.

Two ways to drive Proteus, and they share one engine. The CLI is scriptable and shows you exactly what it sent. The Web GUI lets you compose an estate by hand and watch the cost projection move as you do it. Neither can bypass the cost guard — both go through the same proteus.cli.inject path.

Pick by what you are trying to do.

Goal Go to
First run: get telemetry into CloudWatch at all CLI walkthrough, journey 1
Choose which of the seven built-in estates to start from The seven presets
Understand what the estate currently contains Reading the estate
Present a live incident while narrating A live demo
Watch data land in the console within seconds firehose
Add a specific incident in plain language Injecting an incident with chat
Run a fault-finding exercise for a team Fault hunting with hunt
Find out what a run will cost before paying for it Cost control
Build an estate visually, service by service Web GUI walkthrough
Find the workload that emits a metric you care about Filtering the palette
Drag a fault onto a node and see it on a timeline Placing a fault
Read the projection before spending anything The cost meter
Rehearse a run without sending it Preview with a dry run
Rename services or infra nodes without breaking the dependency graph rename
Remove everything Proteus created Teardown
Test whether an alarm threshold actually catches a fault Field notes, alarm coverage
Find the fault class your alarms structurally cannot see Field notes, noisy-neighbor
Check a CloudFormation template for monitoring coverage gaps Field notes, coverage

Which interface#

The GUI is the better tool when the estate is the thing you are designing: it shows dependencies as edges, tenants as colors, and the cost meter updates on every edit. The CLI is the better tool when you already know what you want and need it reproducible — same world model plus same seed gives byte-identical telemetry, so a run you script today replays next month.

The GUI holds your AWS credentials and can spend money, so it binds 127.0.0.1 only. See Web GUI for the reasoning and the walkthrough for how to use it.

Before either#

Run proteus doctor. It is read-only, it takes seconds, and every failing check prints the command that fixes it. Most of Troubleshooting is a symptom doctor would have named first.

Cost Injection costs real money. seed, live and firehose all send data to CloudWatch and are billed at CloudWatch list rates. Every example on these two pages that touches money says so, and every example that does not is either read-only or uses --dry-run. Read the cost guard once before your first real run.

New to the tool entirely? Start at the Quick Start — it is four commands and no options. These pages assume you have already done that once.

Somebody else's account of using it#

Field notes from an SRE is the odd page in this chapter: not a walkthrough but a report, in its author's own words —

Which fault kinds your alarm thresholds actually catch, why noisy-neighbor is not one of them, and which resources in your own CloudFormation template a replica leaves untested — worked out offline, before spending anything.

Read it when you have alarm thresholds nobody has ever tested. Read the walkthroughs above for how to drive the tool. It is also the page that found the alarm metric-name mismatch from the outside, which is now fixed by resolving metric names per archetype.

Keeping these pages honest#

The two walkthroughs show what the tool really prints, and both have a script that proves it still does. Run them after any change that touches the CLI's output or the GUI's layout.

scripts/check-docs-cli.py         # re-runs the documented commands, checks the text
scripts/check-docs-deps.py        # checks credits.md, README.md and the homepage
scripts/capture-docs-shots.py     # rebuilds every image in docs/images/

The split between them is deliberate. Terminal output is text here, not screenshots — it is searchable, it can be copied into a shell, a screen reader can read it, and a transcript costs about two kilobytes where a PNG of the same thing costs three hundred. The price of text is that nothing notices when it rots, which is what check-docs-cli.py is for: each figure and flag the pages assert is an anchor it re-derives from a live run.

Both checkers run in scripts/deploy.sh and in CI before the site is built, so a stale claim fails a deploy rather than reaching a page. That is deliberate: they each caught a published falsehood only because somebody happened to run them by hand, and a check whose value depends on being remembered eventually has none. They also reach past this directory — check-docs-deps.py covers README.md and web/index.html, the two published pages nothing watched. The README had drifted four ways while every page here stayed correct. A page no checker covers is not passing; it is unmeasured, and silence from the checkers that do run reads exactly like coverage.

The homepage was added to it for a reason worth stating, because it is the same mistake three times. The sentence "N runtime dependencies" appears on the credits page, in README.md and on the marketing homepage, and it has now gone stale on all three — every time because someone edited pyproject.toml, and nothing about editing pyproject.toml suggests that a landing page mentions it. The homepage was claiming six when there are eight. Pointing the existing check at one more file caught it immediately.

So the rule that follows is about where a number lives, not how careful its author was. A figure derived from the source tree needs a check wherever it is repeated, and repeating it in a third place without one is how the third place goes wrong.

By that standard, Field notes is currently unmeasured: no checker reads it, so the transcripts and figures on it are only as current as the last person to look. Treat its numbers as of its writing rather than as re-derived on every build, which is what the two walkthroughs above can claim and it cannot.

The GUI is images, because a layout, a drag target and a color are the content there and prose describing them is a poor substitute. Those rot too, so capture-docs-shots.py rebuilds all fifteen from one command against a preset estate anyone can reproduce. Regenerate rather than replace a single image by hand, or the set stops agreeing with itself.

A changed screenshot and a wrong screenshot are different facts here, and conflating them wastes real time. Capture all fifteen repeatedly against one pinned commit and at least five are byte-stable; the rest move — the inspector, three of the palette shots and the timeline hold, and the remainder do not. Recapturing the movers produces different files and no new information, so a byte diff cannot tell you whether they are stale, and a gate built on one would fire every morning and be switched off within a week.

That is deliberately phrased as a floor with a method rather than as a split. The count was measured at three, then six, then five as more samples were taken — each reading honest for the samples behind it, and each shrinking. A floor survives the next measurement; a split does not. One shot, the workloads palette, is stable in some measurements and not others, and the footer explanation below does not account for it — most likely a pixel of scroll variance.

The reason is not what it looks like. The obvious suspect is the clock — the fault timeline's axis runs now − 14 d → now + 2 h and advances daily — but the browser clock is pinned to a fixed instant, and the timeline is one of the stable ones. What actually moves the rest is the cost projection in the footer, which is derived server-side and wobbles with the diurnal traffic curve. The stable shots share one structural property: each is clipped to a region that excludes the footer. Every full-page capture inherits the wobble whatever the clock is doing.

So the rule is about framing, not time. A shot cropped away from the footer can be diff-checked; a full-page shot cannot.

What is checked instead is the text behind the shots. check-docs-cli.py reads the template-size figures out of proteus doctor at run time and requires this chapter to agree with them, so the doctor screenshot is verified through the command rather than through its pixels.

The doctor shot is the clearest case of that split. Its pixels are nondeterministic, because the blurred cost meter shows through behind the modal — but every figure it displays is fixed text that the checker re-derives from the command. A pixel diff on it tells you nothing; the check that matters never looks at the image.

Measure stability more than twice before you claim it. Comparing two captures would have promoted three of these shots as deterministic: the cost meter, the doctor dialog and the light theme each matched on a first comparison and moved on later ones. Four back-to-back captures against one unchanged tree is what produced the figure above, and comparing across different tree states produces nonsense — drift and run-to-run variance become indistinguishable, which is how the count was first miscounted.

One shot deserves suspicion rather than credit. The light-theme capture matched on an early comparison, but it is a full-page shot including the footer, so there is no mechanism by which it could be stable — and on three clean comparisons it moved every time, as its dark-theme twin did. Treat it as unverified. Stability without a mechanism is evidence of nothing, which is the same shape as a cost figure that looks steady only because $152.54 rounds away the movement underneath it.

When an image and the prose beside it disagree, fix the image first. A page whose transcript contradicts its own screenshot is worse than one that is uniformly out of date, because a reader cannot tell which half to believe; when both are stale together, the only cost is the delay. Update the alt text and any paired transcript in the same pass as the regeneration, never ahead of it.

Neither script touches AWS. Both run against a scratch PROTEUS_HOME, the capture script's only run is a dry run, and it refuses to keep an image whose page text contains an account id, an ARN, a home-directory path or your username.

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.