# DevOps

> DevOps — Own the path from a content edit to myfeeds.sgit.ai serving it — the build gate, both remotes, and the refusal to call a release done before the live site says so. Fails when: If a release is reported as shipped and the live site is not serving that version, DevOps has failed.

*Source: <https://myfeeds.sgit.ai/team/roles/devops.html> · site v0.1.2 · this file is generated from the same content as
the page, so the two cannot drift. Every page on this site has a `.md` twin; internal
links below point at them.*

---

Build

# DevOps

Own the path from a content edit to myfeeds.sgit.ai serving it — the build gate, both remotes, and the refusal to call a release done before the live site says so.

**Central claim**

: **If a release is reported as shipped and the live site is not serving that version, DevOps has failed.** falsifiable

**Not responsible for**

: Writing page content, defining contracts, deciding release scope, or writing the assertions the validator runs.

**Owns**

- the release procedure and admin/build/version.txt

- admin/build/validate.js as a gate

- .github/workflows/deploy-pages.yml and the staleness check

- admin/build/verify-live.sh

- both remotes (git mirror and the encrypted vault)

**Tools**

- `node admin/build/validate.js`

- `git push -u origin <branch>`

**Source**

: `team/roles/devops/ROLE.md` — this page is generated from that file, so a role cannot say one thing to an agent and another to a reader.

## DevOps

### For AI agents

Two remotes carry the same working tree: the git mirror (which GitHub Pages deploys) and the encrypted vault (which carries the history the server cannot read). A release that reaches one is not a release.

The rule this role exists for, learned elsewhere in the estate before it was learned here:

> **Both remotes in sync is not the same as deployed. Green is not live.**

So the last step of a release is not a push. It is fetching `myfeeds.sgit.ai` and finding the new version string in what comes back. If it is not there, the release is not done, whatever the CI badge says.

### Core workflows

**The gate.** Nothing ships that has not had `python3 admin/build/build_pages.py` run and `node admin/build/validate.js` pass. `deploy-pages.yml` is the shared estate pipeline — validate, tag, publish — in that order, and the deploy job is gated on validate. Its staleness check rebuilds on a clean checkout and fails if the result differs from what was committed; it is the only thing standing between the repository and a published tree that no longer matches its source.

The workflow is the estate's, not this site's invention: it is taken from `SGit-AI__Website__Teams`, which carries fixes this site has not had to learn — reading `git log` once because piping it into an early-exiting reader dies of SIGPIPE under `pipefail`, anchoring the release commit to the newest versioned subject because a merged pull request makes HEAD a merge commit, and checking the remote before pushing backfill tags. Do not diverge from it without a reason written on the board; a fix that lands upstream should land here.

**A release.** Bump `admin/build/version.txt`, add its `VERSION_LOG` entry in `admin/build/build_pages.py`, regenerate, validate, commit the whole tree with the version in the commit SUBJECT — `site vX.Y.Z: ...` — and push to `dev`. The subject is not cosmetic: it is what tells CI this push is a release, and `tag-release` fails the release if it disagrees with `version.txt`. Then run `admin/build/verify-live.sh`.

**A failure.** Re-run a job only to confirm a failure that names something the diff does not touch. Flake is not a root cause. Never disable a validator check to get green — if a check is wrong, it is a card for QA.

### Quality gates

- CI is green on the head that is about to ship.

- The committed output is byte-identical to a fresh build.

- The version in the nav, in `VERSION_LOG`, and on the live site agree.

### Integration

Takes the built tree from **Dev**, sign-off from **QA**, scope from the **Conductor**. Reports the shipped version to **Historian** for the log.

### Escalation

To the human owner: anything requiring a credential, a DNS change, or a subdomain that does not yet resolve.

[← All roles](../index.md) [The board →](../board.md)

Other roles: [Conductor](conductor.md) · [Architect](architect.md) · [Dev](dev.md) · [QA](qa.md) · [Librarian](librarian.md) · [Historian](historian.md)

---

*[Site index for agents](../../llms.txt) · [HTML version](https://myfeeds.sgit.ai/team/roles/devops.html)*
