Four things it owns, and nothing else
One Go binary, one SQLite file, agents on your machines. Everything a conductor needs to trust a head is one of these four.
-
1
The pipeline file
.swrails.ymlis Buildkite-shaped: command, wait, block, input, trigger and group steps;depends_on,if:, matrix, retry, soft-fail and concurrency groups. A step can upload more pipeline mid-build. -
2
Agents on your hostsA tagged agent claims the jobs its tags match, streams the log, and drains before it upgrades itself — only to a release whose SHA-256 the server pinned. A failed upgrade is declined for an hour, not retried blind.
-
3
One status per stepGitHub sees
rails/<pipeline>for the build andrails/<pipeline>/<step>for each job, through an outbox that dedupes and backs off. Fork pull requests never build. -
4
The conductor’s read
GET /api/v1/checksnames the SHA it is answering for and where that SHA came from, so the conductor falls back to GitHub unless the answer is about the exact head it asked for.
Nothing self-certifies
A conductor merges on CI plus a finished review. Rails is the CI half: it decides from evidence — the exit code, the status it posted, the SHA it built — and keeps the record where the conductor can read it back.
-
A job token dies with its jobEvery job gets its own bearer for meta-data, artifacts and annotations. When the job finishes, the token is gone; a leaked log line buys nothing.
-
Retry is a conductor verbThe conductor’s rework lane calls
POST /builds/{id}/retry-failed; only the failed steps run again, under the same build, and the statuses update in place. -
Secrets are referencesConfig holds
env:NAMEorfile:/path, never a value; the loader refuses an inline one. The log stream masks any secret-named variable before it is stored. -
One file, backed up onlineSQLite in WAL mode behind one writer. Backups are taken with
VACUUM INTOwhile serving, checked withintegrity_check, rotated, and reported on/metrics.
What you can go and check
Each claim below names the mechanism behind it. If the mechanism is not there, the claim is false.
-
Webhooks are verifiedEvery GitHub delivery is HMAC-checked against the server’s webhook secret before anything is scheduled. A bad signature is a 401 and no build.
-
Lost agents are reapedA job whose agent stops heartbeating is failed as lost, its status goes red, and it can be retried. Nothing waits on a machine that is gone.
-
Upgrades are pinnedThe server offers one version with one checksum per platform. The agent downloads, verifies, swaps the binary and re-executes — or declines and says why.
-
Paths stay in the treeCache keys and artifact paths refuse any
..segment, on the agent and on the server. A pipeline cannot write outside its checkout.
Two commands to a working agent
The installer fetches the current release for your platform from this site, verifies it against checksums.txt, and puts swrails on your path. Then point it at this server with the agent token.
curl -fsSL https://rails.switchyard.work/install.sh | sh swrails agent \ --endpoint https://rails.switchyard.work \ --token file:/etc/swrails/agent.token \ --tags os=linux,arch=arm64,role=conductor