← Roadmap
🔧

Self-Hosted CI

✓ Shipped

With the forge hosting the code, the next piece is a runner that tests it. Celilo deploys its own CI worker — again as a module — so that every push and every pull request checks itself automatically, on hardware in the lab, with no outside CI vendor in the loop. The runner registers with the forge, waits for jobs, and runs the project’s real tests against them.

A runner wired through capabilities

The runner is a separate module from the forge, and the two connect through Celilo’s capability system: the forge provides a source_forge capability that mints a short-lived registration token, and the runner consumes it. The token never gets hand-copied through a UI — it crosses the boundary through Celilo’s own secrets machinery, which is exactly the cross-module wiring Celilo exists to demonstrate. Because the runner holds nothing precious, redeploying it is cheap and lossless.

Light work and heavy work

Not every check needs the same muscle. The runner comes in two profiles. A light runner handles the fast tier — unit tests, linting, type-checking, publish dry-runs — and runs on every push. A builder profile carries the heavy tier: the full end-to-end suite, which spins up a large multi-container topology and takes the better part of an hour. Gating every commit on that would bring back exactly the slow iteration CI was meant to remove, so the heavy suite runs on demand or on a schedule instead.

Contained by design

The runner needs no inbound access at all — it reaches out to the forge for work rather than being reached. That lets it sit in the lowest-trust zone that can still do its job, where its outbound traffic can eventually be locked down to just the destinations it legitimately needs. The box that runs code is treated like the box that runs code.