Skip to main content

SerenTheatre

Watch a model being made. A read-only viewer over training logs and artifacts.

Named for the anatomical theatre — a room built with tiered seats so people can watch a dissection. That's the whole design brief. Not a control panel, not a console. Seating. You glance at it, you learn where the run is, you look away.

Everything else in the constellation gets an accent colour. The theatre gets the house lights down.


The two rules everything else falls out of

1. Stagehand does the work; the theatre shows the data.

Theatre never builds anything. The [stagehand] extra owns the build and forks a subprocess rather than importing torch into the viewer — a stagehand is not on stage. It invokes the same CLI a human would type, on purpose: if the automated path and the hand-run path ever diverge, the hand-run path is the one that rots, because it's the one with no users.

2. A stage is a directory.

Not a process, not a client library, not an agent you have to install. Nothing has to be instrumented to be watched. Redirect a run's log into a folder and that folder is on stage. This is why Theatre requires nothing and can be the first thing installed on a box.

The run directory is also the only interface between the pipeline and the viewer, which is what lets ms-moe-maker and seren-theatre be separate packages that don't know the other exists. Install either one alone; both work.


Quick start

The fastest possible version — no config file at all:

pip install seren-theatre
SEREN_THEATRE_STAGE=/mnt/nvme/fraunkensteinLab python -m seren_theatre

Then open http://127.0.0.1:7427/viewer.

That's the case you'll actually be in nine times out of ten: you've got a run going in some directory and you want to see it. For anything longer-lived, copy seren-theatre.yaml.sample to ~/seren-theatre/seren-theatre.yaml and list your stages there.

Install with the installer (optional)

There's a seren-theatre-setup.sh in the SerenStarwright repo that does the venv, config, launcher and optional autostart for you:

bash seren-theatre-setup.sh              # build from the repo checkout
bash seren-theatre-setup.sh --service    # + autostart
bash seren-theatre-setup.sh --stage /mnt/nvme/fraunkensteinLab

It answers --describe, so Theatre appears in Starwright's grid with no edit to Starwright. None of that is required — pip install seren-theatre is the whole story if you'd rather not.


Routes

Route What it is
/viewer The room itself. Read-only, auto-refreshing.
/api/state The same thing as JSON, if you'd rather script it.
/health Liveness.
/ Service info + the version, family-standard.

Three deliberate constraints

Read-only, with no knob to turn it off. A theatre cannot perturb the thing on the table. That's precisely what makes it safe to point at a live 14B run that's been going for nine hours. There's no config option for a write path because there's no write path.

Binds 127.0.0.1 by default — like Margin, unlike Memory. A training log carries absolute paths, hostnames and the occasional snippet of a corpus. That isn't something to put on the LAN by accident. Widen it yourself, deliberately, if you mean to.

Reads the tail, never the whole file. Training logs are megabytes of carriage-returned progress bars and only the end is ever interesting. Tunable via tail_bytes, default 256 KiB. The dashboard must never be the reason the box is busy — that would be an unusually stupid way to perturb a measurement.


Config

Resolves in this order, first hit wins: --config → $SEREN_THEATRE_CONFIG → ~/seren-theatre/seren-theatre.yaml → built-in defaults.

Precedence, highest first: env vars (deploy-time escape hatch, for Environment= lines in a unit file) → YAML file → defaults.

Parsing is lenient, same as the rest of the family. Missing file falls back to defaults; malformed YAML logs and falls back; one bad value falls back alone. Postel's law as a kindness — train strict, infer lenient.

Env var Overrides
SEREN_THEATRE_CONFIG Config file path
SEREN_THEATRE_HOST server.host
SEREN_THEATRE_PORT server.port
SEREN_THEATRE_STAGE Appends a one-off stage

A note on the port

Theatre binds 7427. It was 7426 for about a day, chosen as the next free seat in the seren/port-map fact — which lists the eight network services and therefore doesn't list SerenSymposium, which binds 7426 on loopback for its UI shim. Localhost-only is exactly why it wasn't in the map and exactly why it collided. Symposium keeps the seat because Symposium is the one already installed and running; the unshipped service moves.

Worth knowing if you're adding a service of your own: a single-source-of-truth check inside one package can't catch this, because nothing drifted. Two constants in two packages were both correct and identical, and identical is the bug. Check the map, and make sure the map lists everything that binds, not everything that's reachable.


Stagehand — the half that does the work

pip install 'seren-theatre[stagehand]'
seren-theatre-stagehand recipe.yaml

"Stagehand does the work, cause they do fuckin everything, and the theatre shows the data."

Note that it's a command, not a button. That's the whole design, and it was decided by the read-only rule rather than by taste.

Starting a build is a write. Theatre exposes no write surface — there's a test, test_no_route_can_write, that fails if a POST/PUT/PATCH/DELETE ever appears — and that's exactly what makes it safe to point this at a live 14B run that's been going nine hours. So POST /build is out. If the theatre could start the build, the theatre would be doing the work. A stagehand is not on stage.

What stagehand runs is the literal command from ms-moe-maker's README:

stagehand → /usr/local/bin/ms-moe-maker build /path/recipe.yaml --json

Not an import of ms_moe_maker.runner, not a Python API with its own defaults. The same string a person types — so every automated run is also a test of the documented one. If those ever diverged, the hand-run path is the one that would rot, because it's the one with no users.

Forking is also what keeps torch out of the viewer's process. Theatre stays installable and runnable on a box with no CUDA, because watching a run costs nothing and that's the bargain.

seren-theatre-stagehand --check          # is it usable? which command will run?
seren-theatre-stagehand r.yaml -- --dryrun --offline

--check reports is_documented_command. If ms-moe-maker isn't on PATH, stagehand falls back to python -m ms_moe_maker — that works, but it quietly voids the "every run tests the hand-run path" guarantee, so it's reported rather than hidden.

The service can say whether stagehand is installed (stagehand on /) and can never use it. That asymmetry is the point.


Development

pip install -e ".[test]"
pytest

Theatre knows nothing about SerenStarwright, on purpose. The installer lives in that repo and this one doesn't reach into it — a viewer that needs a sibling checkout to run its own tests isn't standalone, and requires: [] should mean something.

--describe is still tested here, thoroughly: the payload's keys, its types, that it stays one line of JSON, that it imports nothing heavier than the standard library, and that it creates nothing on disk. What's not tested here is agreement with the shell installer's --describe. That comparison is real and worth having; it just belongs on the side that owns the installer. Something now does.


Licence

GPL-3.0-only. Same as the rest of the family.

Rip it and win. 🌭🔧

Release files for seren-theatre 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for seren-theatre 0.4.4
File Size Uploaded
seren_theatre-0.4.4.tar.gz 375.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for seren-theatre 0.4.4
File Interpreter ABI Platform
seren_theatre-0.4.4-py3-none-any.whl Python 3 none any Details

Total release size: 590.3 kB

Release files / seren_theatre-0.4.4.tar.gz

Download URL seren_theatre-0.4.4.tar.gz
Size 375.9 kB
Tags Source
SHA-256 checksum
How to use checksums
eee8ee1e89f2f63e349e7c3f7a2d3d31d795efb50cd41c800f6a59e398cb112c
BLAKE2b-256 checksum
How to use checksums
faf70788b3dbd59e2975005c67e68de4247472779cbe4831982d65fd6c666b4a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / seren_theatre-0.4.4-py3-none-any.whl

Download URL seren_theatre-0.4.4-py3-none-any.whl
Size 214.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19cc1e88ff30ed899455120306e8e23efddbf043c6c1b4eebd325a7fbc55af8e
BLAKE2b-256 checksum
How to use checksums
a98b0bb8f61cc7b26c0b11aa69a25d0e50a4b2fcaeceb8917938c8cf638efac7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

2 release files

This release

0.4.4 This release

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page