Why our CI can reject an essay
Every post on this blog has to pass a blocking CI check before it can ship, exactly like code. Five gates run over every artifact: sensitivity, anti-slop, faceless-voice, no-overclaim, and conversion mechanics. A post with a bloated title, an uncited number, or a missing call-to-action fails the build, and no amount of "it reads fine to me" overrides the exit code. This is the first episode of Governance Engineering 101, and it starts here because everything else in the series depends on this move: turning editorial judgment into law that machines enforce and humans can only consciously change, never quietly skip.
Where this sits in the pipeline
The gates are the last step of a longer machine, and it is worth saying plainly what the machine is: all of this is infrastructure as code, content included. Nothing on this blog is written from scratch for the blog. Posts are distilled from work already happening: commits, killed hypotheses, decision records, flowing out of a knowledge base and through the same review-and-approve pipeline as our software. This episode deliberately starts at the end, where quality is enforced, because everything upstream depends on this floor existing. The series works backwards from here toward the intake, one step per episode.
The concept: quality as an exit code
A rule that lives in a style guide is advice. A rule that lives in CI is law. The difference is not the rule's content but its failure mode: advice fails silently, on a bad day, when the reviewer is tired; law fails loudly, every time, with a line number. Governance engineering is largely the craft of moving rules from the first category to the second.
Subscribe free
The anchor: this is how serious software already works
Nothing here is novel, and that is the point. Google's engineering practice gates every change behind mandatory code review and pre-submit checks that run before a human ever looks: linters, tests, style verifiers. The reviewer's attention is spent on judgment because machines already enforced the floor. Publishing has the same shape: a magazine's fact-checker and sub-editor were pre-submit checks made of people. We just put the people-shaped checks back into machines, where they run on every artifact instead of every artifact a tired human remembers to check.
The application: five gates, one command
Our checks live in a small library, one file per gate, walked by one command over every content file:
src/gates/
anti-slop.ts craft bar: banned phrasing, slop patterns
artifact.ts loader: frontmatter, publish-path classification
conversion.ts funnel mechanics: rules C1-C8 (SEO, CTA, citations, taxonomy)
faceless-voice.ts no operator identity leaks, synthetic voice only
index.ts registry + config loading
no-overclaim.ts no invented numbers, no stage-inflation
sensitivity.ts the firebreak: public|fleet|operator, asserted per artifact
types.tsThe conversion gate alone enforces eight rules: SEO title and description length, new-tab link safety, an in-body call-to-action, descriptive link text, primary-source citations for named tools, a self-contained opening block, and a concept taxonomy that powers the "Read next" links below this post. Errors block; warnings surface honestly and let the build pass.
The artifact: a real rejection
We planted a deliberately bad draft, long title, ten-character description, "click here" link, and ran the real command. This is the actual output:
✗ content/drafts/s1e1-demo-bad-post.md
[conversion/C1] title is 89 chars (max 60): trim it for the SEO title
[conversion/C2] description is 10 chars: must be 120–156 for a
well-formed meta_description
[warn conversion/C5] generic link text "here": use descriptive anchor
text that says where the link goes
[warn conversion/C4] no in-body CTA ([cta] marker) in the first 75%
[warn conversion/C8] no `concepts:` frontmatter: declare at least one
vocabulary concept so the related-posts footer can cross-link this post
content gates FAILED: exit code 1One transparency note: the tool's own messages use em dashes, which the anti-slop gate bans in post bodies, so they are rendered as colons above. The gate refused to publish its own error messages verbatim. We consider that a feature.
Exit code 1. The post cannot merge, cannot publish, cannot quietly slip through because someone was busy. The two errors block; the three warnings print with line numbers and wait for the next edit. This very post passed the same command with zero warnings before you saw it.
The oldest gate in the archive closes for one hour a year, on a schedule no calendar carries.
Send-off
If you run agents that produce anything outward-facing, try the one-week version of this: pick your three most-violated editorial rules, encode them as a script that exits non-zero, and put it in front of your publish step. You will learn more from what it catches than from any style guide. Next in the series: how one governed agent per repository keeps thirty repositories from eating each other, and eventually the intake itself, where working code becomes teachable record without anyone sitting down to write. The whole practice is built on Loa, and every post here, including this one, carries its own audit trail in the footer below.
Get the next post
Free membership: new posts on how the fleet is built, delivered by email. Subscribe free
Read next
- The repo remembers: how agents build hosaka
- The Forged Approval
- A Rule Without an Enforcer Is a Costume
Post history
- 2026-07-21: densify why-our-ci-can-reject-an-essay: 1 internal link(s), pass cl-20260721 (standing admin preapproval (pending-laws 2026-07-19))
- 2026-07-21: crosslinker + enrich phase + OQ-1 spike + caption-uniqueness law
- 2026-07-21: BLOG SURFACE ENRICHMENT: four corners + engine images + backfill (sprint-25)
- 2026-07-13: THE LOAD-BEARING TRIO: fixpoint, fate, colophon, shadow gate + backfill
- 2026-07-12: charter addendum (self-eating spiral, mibera stats, priced departures, fingerprint carve-out) + THE JESTER LEDGER + shadow-sentence backfill in all 9 essay sources
- 2026-07-12: THE DOOR: deliver/verdict mechanized, queue law wired blocking with its bootstrap staged
- 2026-07-10: pipeline-framing section: content is infra-as-code distilled from real work; series works backwards from the gates (operator editorial direction); S1E0 map-episode beaded
№ 2926