Symptom. The Conformity workflow is green and the Deploy to Pages job succeeded, but a page on the live site is wrong or broken.
If the gate failed instead, there is nothing to roll back: the deploy did not run and the previous build is still live. Follow Gate blocked a deploy.
How a rollback works here
The only path to the live site is a push to main that passes the gate (Deploy pipeline), and changes reach main through pull requests (ADR-0029). A rollback is therefore a revert pull request that undoes the bad commit, and it goes through the same check, gate and deploy as any other change.
Re-running an earlier workflow run does not roll back. Both jobs in .github/workflows/conformity.yml check out main on every run except a pull request run, so a re-run, or a run started by hand, deploys the current main. There is no way in the workflow to redeploy an earlier build.
Steps
- Record it, if readers saw it. Open
incidents/YYYY-MM-DD-short-name.ymlwith aninvestigatingupdate, as in Status page. It can go out in the same push as the revert. - Find the commits to undo. The run on GitHub Actions, the Website deploys dashboard and
git logname the commit each deploy came from. Skip theconformity-botcommits marked[skip ci]: they only touchconformity/latest.jsonandconformity/index.html, which every run rewrites. - Revert on a branch from the current main, newest commit first:
git fetch origin && git switch -c revert-<sha> origin/main
git revert --no-edit <sha>
If the revert conflicts with later commits, fix forward instead: change the page and send the fix through the same steps.
- Leave hashed predictions alone. If a bad commit added or changed a file in
predictions/orpredictions/HASHES.txt, do not revert those files; predictions are never edited after hashing. Ask the operator how to withdraw it. - Run the dry run until it prints
overall=pass:
python3 .github/actions/conformity/run.py --root . --config conformity/site-tier.json \
--requirements conformity/requirements.json --out conformity --dry-run
A revert can fail the gate when a rule or a check changed since the bad commit. Fix the failing check as in Gate blocked a deploy; until the gate passes, the bad build stays live.
- Open the revert pull request and merge it.
git push -u origin HEAD,gh pr create --fill, wait for the Conformity checks on the pull request (gh pr checks --watch), then merge (gh pr merge --squash). The merge starts the run onmain. A run already in progress onmainfinishes first; the workflow does not cancel it (cancel-in-progress: false). - Check the result. The Conformity checks job and the Deploy to Pages job are green, the status page shows the site as operational, and the page itself is right. Then move the incident record through
monitoringtoresolved.
What a rollback does not restore
The deploy job rebuilds four files from live sources on every deploy and never commits them, so a rollback deploy carries their state at the time of the rollback, not the state of the bad deploy or of the one before it:
| File | Rebuilt from | If the step fails |
|---|---|---|
map/graph.json | scripts/crawl_map.py against the live sites | The committed snapshot is deployed; it is also kept when the crawl returns fewer nodes or links |
inside/search.json | scripts/build_search.py, from the docs, the services and the map | The committed index is deployed |
inside/deploys.json | The last 15 Actions runs of machinebehavior.io and tychat.io | The step fails without failing the job |
inside/board/issues.json | scripts/board_snapshot.py, from GitHub Issues | The step fails without failing the job |
Each of these steps may fail without failing the job, so a green deploy does not prove they ran; read the step log.
When this does not help
- GitHub Pages or Actions is down. Nothing in this repository can deploy or roll back. Escalate to GitHub (On-call and escalation).
- The fault is in the gate's rule table or tiers. Changes to the gate go to the gate owner; tier changes are the operator's decision (Conformity gate).
Time
No rollback has been timed. The one recorded fix-forward, the blocked deploy of 2026-10-08, took 81 seconds from the failed run to the passing run.