← All updates

v0.1.1: a hardening pass, run by an adversarial audit program

v0.1.1 is a hardening release. An intensive multi-model audit swept the recorder, the API, every client, and the seams between them, finding each issue, trying to disprove it, then fixing it. Sixty-plus changes, almost none of which change what Crumb does, all of which change how much you can rely on it.

BackendDesktopAndroidiOSWeb releasesecurityreliabilityaudit

v0.1.0 was about building the seat you review footage from. v0.1.1 is about making that seat trustworthy. If you are running Crumb today, this release does not add a workflow you have to learn; it removes ways the system could drop footage, leak a credential, or show you something on screen that is no longer true.

The whole release came out of one thing: an audit program. Instead of a single review pass, this cycle ran repeated adversarial sweeps (several of them driven by Fable) over the entire system. Each sweep found an issue, then a separate pass tried to refute it, and only the findings that survived got fixed. That is where the sixty-plus changes below came from.

What got hardened

The recorder got the most scrutiny, because losing footage is the one unforgivable bug. The storage-migration copy now refuses to unlink the only copy of a segment. Quarantine pruning ages from the right clock and spares files that merely collided on a name. The retention ceiling is truly absolute now, even for cameras you have disabled. And a per-worker storage cache means a brief database hiccup no longer knocks a camera off its recording.

The API. Media tokens now carry the real capabilities of whoever minted them, instead of a blanket set. Log redaction, output escaping, and export and event authorization all got tightened. Export sizes and the filmstrip window are bounded so a single request cannot fill a disk or exhaust memory. The go2rtc reconcile loop no longer races a stream teardown.

The seams between server and client. One class of bug is the hardest to catch: a server change that is correct on its own but diverges from how a client actually calls it. That is the class that briefly turned license-plate crops into black tiles on some clients. A dedicated cross-boundary pass hunted the whole category and fixed the survivors: crops load again, capability checks match what each screen actually offers, and a motion-strip gap on long-keyframe cameras is gone.

Every client, audited on its own. iOS and macOS reached feature parity with 0.1.0 and then took a batch of correctness, security, and memory fixes. Android hardened its background and lifecycle handling, and stopped ever showing a stale Home Assistant reading as if it were live. The desktop client landed a long stability and polish pass, and picked up in-app Diagnostics: a bounded, scrubbed log export for when you need to send me something.

One rough edge on upgrade

Right after you upgrade the server, a client that is already open may show blank thumbnails or stalled video for up to about fifteen minutes, while the short-lived media tokens it cached expire. It clears on its own, or immediately if you restart the client. A permanent fix, where clients re-mint on the spot instead of waiting, is already queued for the next release.

Getting it

Backend, the usual:

docker compose pull && docker compose up -d

Back up your database first. It is a good habit even when a release adds no schema changes, and this one adds none. The desktop, Android, and macOS builds are attached to the v0.1.1 GitHub release, each with a checksum. The full change list is in the changelog.

Don't miss the next one.

Watch the repo on GitHub for releases, or grab the RSS.

Get it on GitHub