A Blog AI Agents Can Write To — But Never Publish
This post was drafted with assistance from Hermes (my automation crew) and reviewed and approved by me before publishing.
This post is being written by an AI agent executing a Vikunja card. That sentence is not a gimmick — it is the infrastructure this post describes. Pull back the curtain and you will find a content pipeline designed around one constraint: the AI can draft, submit, revise, and re-revise, but it can never publish.
The Pipeline
Every piece of content on this site passes through a defined workflow. Ideas land in a content inbox as Vikunja cards. From there, an agent — one of several personas running as scheduled cron jobs — picks up the card, reads the brief, and produces a draft.
The draft is posted back to the card as a comment. A human reviews it. If it passes review, a Gitea pull request is opened. Then the human reviews the PR, and if everything holds, merges it to main. That merge triggers a deployment, and the post goes live.
The stages:
- Inbox — Ideas land as Vikunja cards, raw and unrefined.
- Drafts — An agent picks up the card and writes a full draft.
- Review — The draft goes up as a Gitea PR; a human reviews it there.
- Main — The PR is reviewed, merged, and deployed.
CI as Editorial Assistant
Before any draft reaches a human reviewer, it runs through automated checks. These run in CI on every PR and function as editorial assistants — fast, consistent, and tireless:
- Frontmatter schema validation — Does the post have valid title, description, excerpt, pubDate, and permitted tags? Malformed frontmatter is rejected before a human even sees it.
- Unique slug enforcement — No duplicate URLs. No accidental overwrites of published content.
- Duplicate topic detection — Has this subject already been covered? The CI knows the archive and will flag a re-tread.
- Unsupported claims linter — Are all factual claims sourced? This catches fabricated metrics, invented case studies, and phantom client logos — the kind of hallucinated content that undermines technical blogs.
- SEO thinness check — Is the post substantial enough to merit publishing? A 200-word post with a title and nothing more gets flagged.
These checks are not suggestions. They are gates. If a draft fails any of them, the PR is marked as failing CI and the human reviewer knows exactly what to look at before they invest their time.
Branch Protection as Editorial Policy
The Gitea account that Hermes authenticates with is deliberately scoped. The token is generated with the minimum permissions necessary to participate in the writing workflow — and explicitly denied the permissions required to publish.
The scoped account can:
- Create branches from issues and cards.
- Open pull requests against any branch.
- Push commits to feature branches.
- Respond to review feedback with additional commits.
- Rebase feature branches when main advances.
It cannot:
- Push directly to main.
- Merge any pull request.
- Bypass branch protection rules.
- Delete protected branches.
- Modify repository settings.
This is not an afterthought. Branch protection on main is editorial policy enforced at the infrastructure layer. No amount of prompt engineering, system prompt manipulation, or agent autonomy can override an HTTP 403 from the Gitea API. The merge button is a human privilege, enforced by Gitea branch protection on the server side.
The Feedback Loop
When a human reviewer requests changes — and they frequently do — the agent receives the feedback through the Vikunja card. A comment is posted specifying what needs to change: tighten a section, add a source, rephrase a claim. The agent picks up the card on its next cron cycle, reads the feedback, revises the draft, and pushes an updated commit to the PR branch. The CI pipeline re-runs. The reviewer re-reviews.
This loop can repeat as many times as needed. The agent has infinite patience for revisions because it has no ego about its prose. The human has final say because they hold editorial judgment the agent lacks.
Why This Matters
The web is filling with AI-generated content published without human oversight — entire blogs generated by prompt, posted by script, and indexed by search engines before anyone has read a single word. This pipeline rejects that model entirely.
The AI accelerates drafting, revision, and the mechanical parts of content production. The human owns the decision to publish. The cost is latency — review takes hours or days instead of seconds. The benefit is that every published post on this site has been read, edited, and approved by a person who stands behind it.
This is not about trust. It is about accountability. When a post publishes, the person who merged it owns it. That person chose to affiliate their name, their reputation, and their domain with those words. No amount of AI assistance changes that.
Merge is Publish
Merge to main is the only publication event in this pipeline. The AI agent cannot trigger it. The CI pipeline cannot trigger it. No automated process can trigger it. Only a human, sitting at a terminal or a browser, running git merge or clicking “Merge Pull Request,” can make content go live.
This pipeline is part of the larger Hermes agent infrastructure, where multiple AI personas collaborate on content, automation, and infrastructure tasks — each constrained by code, permissions, and human oversight at every boundary.
Hermes proposes. A human merges. Merge is publish.