LeTissierCreative Studios
Cue 02The log04 Sept 2026

Fifty-six things that were wrong

Crewbox v0.19.0 is one release made entirely of fixes from a review of the last one. Not tidier code — a box that could be killed from the network, an updater that could not be used, and a disaster plan nobody had ever run.

Patched to

v0.18.0 was "a box that can update itself". v0.19.0 is the review of v0.18.0, acted on in full. Fifty-six commits, and the rule for each one was that it had to be a thing that was wrong rather than a thing that could be tidier.

Releasecrewboxv0.19.0v0.19.004 Sept 2026

What a box on 0.18.0 gains by taking it

Written as plainly as it deserves, because this is the bit an operator needs:

  • It stops being killable from the network by one unauthenticated packet.
  • It stops losing comms once a minute when its disk fills.
  • Its updater becomes usable — the port is released while phones are still connected, the supervisor's way back survives the install, a rollback restores the database that goes with the binary it puts back, and the panel stops reporting a failed install as a success.
  • Session tokens stop travelling in plain text on every USB stick that holds a backup.
  • A three-day festival's running order names the right band on the right night.
  • backup.sh and restore.sh — which nothing had ever executed — stop being able to hand you half a database and call it the newest backup.

That last one is the one that keeps me up. A backup regime that quietly stopped three events ago looked identical to one that ran last night, right up until the night it mattered.

The bug that only exists off-site

The module list grew to seven, and one of them found a defect worth naming. Crew phones read the running order against their own local time. Without a timezone set, the box reads it against its process timezone — so a box imaged with UTC and driven to a field in July tells the production desk the headliner is on an hour from when every phone on site says. During the show, with nothing saying why.

CREWBOX_TZ now exists and the documentation says to set it on any box that was not set up on site. It is a one-line fix for a failure that would have taken an hour to diagnose at the worst possible time.

Building the running-order module also turned up something structural: opening a shared document announced this device in it, so a module reading other people's documents appeared as a person in every one of them. A patch operator saw company in a sheet nobody else had open. Syncing a document and being present in it are now separate things.

Seven modules, all on by default

The shell is identity, chat, offline storage and routing; everything else is a department module, and a box chooses which to run. Chat is always on and cannot be turned off. The other six — running order, patch sheets, lighting, show log, video and network — now all ship enabled unless a box says otherwise, because there are no tiers and no "full" edition to sell.

The patch sheets are Live Patch, ported whole. Its domain model was framework-free and fully unit-tested, which is why it lifted almost verbatim, and both git histories were merged in so git blame still works on every line.

RepositoryTypeScriptlegofsalmon/livepatch

The video module watches NovaStar LED processors and cannot drive them. That is not a review convention — there is no encoder anywhere in the codebase that can produce a NovaStar write. The read-only type is a literal 'GET', redirects are refused before a socket opens, and the SNMP encoder's PDU type has exactly two members, neither of them SetRequest. The protocol facts come from the sister project, which has now read two real controllers.

RepositoryPythonlegofsalmon/novasun

The upstream break that was coming either way

The v0.19.0 release failed on the macOS job and only there. go install of the LiveKit server refused to run at all, because LiveKit's go.mod carries three replace directives from v1.13 — its own forks of pion's webrtc, dtls and ice. v1.11 and v1.12 have none, which is why this worked when v0.18.0 was cut. Nothing in the repo changed; upstream did.

Those replaces are how the SFU is meant to be built rather than a mistake to route around, so the build moved inside the module: clone at the tag, build ./cmd/server. The cost is worth saying out loud rather than leaving for somebody to find — go install resolved LiveKit through the Go checksum database, and a clone does not. Every dependency is still verified against sum.golang.org, and the commit the tag resolved to is printed into the build log so a release can be traced to one.

What is still not true

The updater's Windows and macOS paths are reasoned about and tested against real filesystems. Linux is exercised for real. No Windows box and no Mac has yet updated itself. The four native shells compile in CI and have no automated test at any layer.

docs/UPDATING.md says so, and says to do the first update on each platform with a spare box rather than ten minutes before doors. A release note that only lists what works is not a release note.

Verified for this one: lint, format, both typechecks, 1,226 server and 771 web unit tests, 67 end-to-end, and green across every CI job including the Android APK and the unsigned iOS compile.