A Remote That Reads Before It Takes

Written later and filed to this date, as part of filling in every day of the year.

Every path that can publish this site runs the same four gates: the type check, the draft lint, the redaction and site tests, the build. For the fleet there is one script allowed to push, in a directory no agent may edit. The daily writer has its own sanctioned job. For me, by hand, there was the script too, and in August I decided I wanted the ordinary verb back: git push, with the gates in the way.

The answer was a second remote, named gated: a bare repository on the box. Its pre-receive hook accepts exactly one ref per push, main only, no deletes, no rewritten history (a non-fast-forward is refused before any gate runs, so force is structurally impossible rather than merely forbidden). Then it extracts the pushed commit into a disposable workspace, never anyone’s working tree, and runs the four gates there, under a lock so two pushes cannot validate at once. On green the ref advances and a post-receive hook forwards it to the hosting remote, where CI re-runs the redaction guard as the backstop and deploys. On red the push is rejected whole, and the runbook’s advice is one line: fix the content, never the gate.

The hook lives inside the fleet directory, where the guards deny every agent an edit, because a gate an agent can modify is not one it must pass. The only environment variable it reads steers the one direction a gate should be steerable: a dry-run flag runs everything and then refuses regardless, so a rehearsal can never publish.

I verified it the afternoon it was built. The wrong ref, a delete, two refs at once, a rewritten history: four refusals, each with its message. Then a full dry run: extract, install, four gates, the refusal at the end, the lock released. The runbook records that the first real push was the remaining step.

It still is. The gate’s own copy of main sits at the commit of the day it was bootstrapped. Seventy-seven commits have reached the site since, and not one came through it. The fleet’s script and the daily job carried them all. The ergonomic verb I wanted was for a hand that, it turned out, had already stopped pushing on its own.

The pre-receive gate, then: a local bare repository whose hook runs every guard against a clean extract of the pushed commit, before the operator’s own push goes through, and refuses it whole when any guard fails. The runbook still ends on the sentence it ended on in August: the first real push is the remaining step.


← all writing