althorlabs
All work
Independent project · Updated September 2026

Spire

The operator interface I build for my own infrastructure: service evidence, tasks, and reviewed actions in one place.

Why I built it

Running a collection of services creates two recurring problems: finding the evidence behind a failure, and knowing whether an attempted fix actually happened. Spire gives me an interface for that work, alongside tasks, reading, and selected home controls.

It is my own operating environment. This page describes its architecture, not a hosted product or a public download.

The current architecture

The first version bundled a browser UI into a Rust application. The current design separates the React and TypeScript browser application from the retained Rust runtime. Browser state uses Postgres; the Rust runtime retains the approval ledger and execution responsibilities.

Browser application

Authenticated views for tasks, service evidence, history, and assistant conversations. Browser APIs enforce access to the records each user can see.

Evidence collector

Reads operational sources and records their observations. Missing, stale, and partial coverage remain visible instead of being presented as a healthy system.

Rust runtime

Retains execution, credentials, compatibility APIs, and background jobs. Approval state and result evidence belong to the execution path.

A timeout is not an outcome

If a requested action times out, the system may have completed it without returning a response. Retrying immediately can repeat the side effect. Spire records an uncertain outcome and uses subsequent reads to determine what happened.

This matters more than making every status indicator green. The operator needs to distinguish a failed action from a missing response before deciding what to do next.

Changes are narrower than reads

The interface can show evidence from many sources while exposing only specific actions. Home controls, for example, use an explicit allowlist through the Rust execution bridge. Being able to inspect a service does not imply authority to modify it.

Approval decisions are recorded objects with state and result evidence. A conversation alone is not proof that a change was authorized or completed.

What changed from the first version

The single-binary design kept the initial deployment small. As the browser workflows and access rules grew, separating those responsibilities made their ownership clearer. That adds a release coordination cost: related runtimes and migrations must be tested together.

The useful lesson is specific to this project: keep the component that owns a decision responsible for its record, even when the user interface moves.

Stack

ReactTypeScriptPostgresRustSQLite approval ledgerMCPDocker
All work