The operator console has a pipeline tab: the latest run of each workflow, gate results at job level, test counts. All of that lives at GitHub.
There are two ways to get it onto a page served from a box in Falkenstein.
Pull
The box holds a GitHub token and asks.
It is the obvious design and it costs two things. A standing credential on the
server, for the sake of a dashboard — the box currently holds provider keys, a
Stripe key and a Postmark token, and each addition is another thing that leaks
if the box does. And a page that breaks when github.com is slow, which is a
dependency on somebody else's availability for a page that shows your own state.
Push
The workflow already holds a token. It already knows the answer — it is the answer. So it posts, when it changes:
on:
workflow_run:
workflows: [product-validate, security-gate, images, deploy]
types: [completed]
The box needs no GitHub credential at all. The console has no outbound dependency while somebody is reading it. And nothing that crosses is more than is already visible to anyone who can read the repository.
One row, replaced
CREATE TABLE pipeline_status (
id INTEGER PRIMARY KEY DEFAULT 1,
payload JSONB NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
CONSTRAINT pipeline_status_singleton_ck CHECK (id = 1)
);
Deliberately not a history. This answers what is the state of the pipeline, and GitHub keeps the history considerably better than a copy of it would. A table that accumulated would be a second archive to keep, trim, and reconcile against the first — and the first is authoritative.
The CHECK (id = 1) makes the singleton a schema property rather than a
convention, which is the same move as the ledger's sign constraints.
The numbers are derived, not typed
Test counts come from the JUnit report the suite writes, uploaded as an artifact and read back:
- name: Publish the test summary
if: always()
if: always() matters. A summary that only exists when everything passed tells
you nothing you did not already know — the interesting run is the failing one,
and that is precisely the run where an on: success upload would produce
nothing.
Product graph counts come from the same generated bundle the public /product
page renders. One source, two readers, so the console cannot claim a feature
count that the public page disagrees with.
Authentication reuses what exists
The same OPS_TOKEN the watchdog presents to read the health digest. One
credential for "a scheduled job of ours is talking to us", rather than one per
job.
An unauthenticated post gets a 404, like every other endpoint here with no
reason to be discoverable. The comparison is constant-time and the payload is
size-bounded, because a public endpoint that writes to a JSONB column is a
place for something to be parked otherwise.
Still read-only
There is no re-run button and no approve-deploy. Every one of those is a write, and the console asserts read-only by walking its own route table:
for route in app.routes:
if route.path.startswith("/api/admin"):
assert set(route.methods) <= {"GET", "HEAD"}
So adding a write endpoint fails the build rather than quietly changing what this page is. Which is the point of the property: it is not that nobody would add a re-run button, it is that adding one has to be a decision somebody makes on purpose.