**The language rule gets a test, a gate, and an apology.** One question decides every naming
question here: *would a visitor read this string on the site?* Yes means European Portuguese; no
means English. `CLAUDE.md` has said "code and comments are in English" since the first commit,
and **seventeen Python files ignored it** — including most of the ones written this week —
because the code already there was Portuguese. An existing convention is not the rule. Roughly
880 comment lines across 22 files are now English, and **gate 34** fails the build on the next
one.

**The gate was wrong twice before it was right, and both bugs are worth knowing.** Its first
version matched triple-quoted blocks with a regular expression and flagged eleven *page
templates* in `build/build.py` — blocks of HTML holding the Portuguese a reader sees. It was
telling the site to stop being Portuguese. Its second read `##` markdown headings *inside* the
llms.txt string as comments. Both are the same mistake: guessing at syntax a parser already
knows. It now uses `ast` and `tokenize`, and skips «guillemets», because an English sentence
naming a Portuguese section is still an English sentence.

**Three files are exempt, by name, and the exemption is the editor's to clear.**
`build/gates.py`, `build/entregas.py` and `build/pdf.py` are in the deny list of
`.claude/settings.json`, so no agent here can edit them — and a gate that fails the build over a
file the agent is forbidden to touch is not a gate, it is a deadlock. They are named in the
gate, counted in its summary, and listed here rather than quietly skipped.

**Every agent gets a `ROLE.md` and a `MANDATE.md` — rendered, not written.** And the story of
how is the useful part: **two sessions answered this same ask on the same afternoon.** One wrote
five mandate files by hand; the other built `dados/agentes.json`, which already held every field
those files would state. Two answers to one ask is two copies, and two copies diverge the day
somebody edits one. The register won — it shipped first and is wired into the API, the console
and the mail — and the hand-written files were deleted. `build/mandatos.py` now renders
`agents/<id>/ROLE.md` and `MANDATE.md` from it, marked `DERIVED FILE`, with English scaffolding
and the register's values quoted verbatim in Portuguese. **Gate 35** fails a run naming an
unregistered agent, a registered agent with no mandate file, a mandate not marked as derived,
and — the one worth having — **a mandate whose domain, mission or central claim has drifted from
the register**. A mandate that no longer matches reads as authoritative while being wrong.

**Guidance, at `docs/guidance/` and in the back office.** Four pages, in the order they should
be read: the language rule, the nine principles each naming the gate that enforces it, the
before-you-change checklist, and what not to build. Modelled on
[sgit.ai/docs/guidance](https://sgit.ai/docs/guidance/index.html), and on the lesson from
[coding.sgit.ai](https://coding.sgit.ai) that measured its own estate and found a guard that had
never matched anything: **a rule without a gate is decoration**, so each principle names its
gate or says it has none.

**Evidence from a sibling publication, kept as its evidence.** Fourteen frozen files from
newsroom.sgit.ai — two Startup Summit captures from 8 and 13 September, and three press pages —
verified against their manifest and stored under `fontes/transferidas/`, **never in our own
register**. They were frozen by another publication's fetcher, at its times; entering them as
our captures would make this site's method quietly untrue, which is the one failure mode that
does not look broken. They turn a story explicitly waiting for a second capture into three
captures in six days: **60 → 64 → 70** speakers.
