Previously, we moved our governance out of individual prompts and into the Context Control Center, so the chatbot answers in the right voice. Then we extended the same rules to field automators, so generated intros and descriptions match. Then we built a module to drive a field automator through an AI Agent, so a field could be filled by something that reasons rather than just completes.
Each of those made AI output comply with the standard. None of them helped with the far larger problem: the content humans write. An editor drafting an announcement has the same plain-language obligations, the same accessibility requirements and the same privacy line to hold, and nothing on the site was checking.
So we pointed the machinery at the humans. Or more precisely, at their drafts.
The goal
The user story: as a content editor, I want to know before I publish whether my draft meets the site's standards, and exactly what to change if it does not.
Concretely: when an article is saved, an AI agent evaluates it against the site-wide governance rules, assigns an adherence score from 1 to 10, and writes a prioritised improvement report. Editors see the score where they already are, on the edit form, and read the full report on a dedicated tab. The report is internal quality assurance, so it never appears in any public display.
How it works
The architecture is almost entirely made of parts from the earlier posts:
- The Context Control Center holds the three global governance items (voice and language, accessibility and formatting, privacy and safety) that the rest of the site already follows.
- An AI Agent does the evaluating, with no tools and a single pass.
- The agent-backed automator type from the last post connects the two to a field, so the agent's answer is stored as a real field value.
The important property follows from the first point. The Context Control Center automatically injects globally scoped items into the system prompt of every configured agent, with no per-agent wiring. That means the evaluator reads from the exact same rulebook as the generators, so there is no second copy of the standard to maintain and no risk of the reviewer enforcing rules the writers were never given. When an editor updates the voice item, the chatbot, the generate buttons, and the reviewer all change together.
Setting it up
The agent
The agent is a config entity with no tools, a single loop and structured output turned off. Its instructions do four jobs. First, a role that is explicit about the unusual calling convention:
Second, and this is the part we got wrong on the first attempt, it explains that the block of context appended after its instructions is the compliance standard. More on that below.
Third, it describes the input, including what to do with an empty field. Fourth, the task itself: what to weigh, in what order of severity, and what each band of the score means:
Two details in that task section matter more than they look. Naming the exact offending wording is what separates a useful report from horoscope advice. And the instruction to say so briefly where the article already complies stops the model from inventing problems to fill space.
The automator
On the report field, we add an automator, choose the agent-backed rule, and use token mode so the prompt can assemble the parts of the article we want reviewed:
The prompt is a small Markdown document built from explicit tokens:
# Article under review
## Title
[node:title]
## Introduction
[node:field_intro]
## Description
[node:field_description]
## Body
[node:body]We use explicit field tokens rather than a fully rendered node on purpose. A full render inside a save is both expensive and fragile, since a brand-new node has no URL yet, display components can throw, and it would fold in breadcrumbs, share buttons, and other chrome that isn't the content under review. The trade-off is a known limitation: prose that lives in paragraph components is not evaluated, only the fields named in the prompt.
The trigger behaviour comes from three settings. Edit mode on, with the body as the base field, means the review regenerates when the body changes but not when someone fixes a typo in the title or changes moderation state. A direct worker means the review is written during the save itself, so it is guaranteed to be present the moment the editor lands back on the node. The cost is that the model round trip sits inside the editor's save request.
Finally, the field is hidden from the node form and left out of every view display, and a field access hook restricts viewing it to users with the content overview permission. That single gate protects it on the tab, in JSON:API, and anywhere else it might surface.
The editor experience
On a node with no review yet, the Review tab offers a button:
On the edit form, a read-only indicator appears in the status panel, but only when it is worth attention. Before the first review, it sets expectations:
Once a review exists and the score is below the threshold, the indicator turns into a warning with a link straight to the report. A high score shows nothing at all, because a compliant article does not need to interrupt anyone:
And the report itself, on the Review tab: a score, a one-paragraph verdict, a prioritised list of improvements, and a short list of what already passes.
Look at what the improvements actually say. Not "improve your link text" but which specific links, why, and a suggested replacement. Not "be more neutral" but the two phrases that read as marketing and a neutral rewrite of one. Each item is tagged with the governance area it comes from, so an editor can trace any judgement back to a published rule rather than taking the model's word for it.
Tips and tricks
Tell the model that the injected block is the rules. Our first run produced a report claiming the governance rules were unavailable, even though injection had worked perfectly. The model simply did not connect a block of site-specific context with the phrase "the compliance standard". The fix was to describe that block explicitly in the instructions, by its heading, its item labels and examples of the specific rules it contains, and to delete the escape clause that let it off the hook when it thought rules were missing. If your agent reasons about injected context, say out loud what that context is.
Watch for tokens that pass through. In token mode, an unset field's token is not cleared, so an article with no description hands the agent the literal token text. The instructions tell it to treat an unfilled placeholder as an empty section rather than reviewing the placeholder.
Mind the context budget. Three governance items against a two-thousand-token budget leaves thin headroom. If an item grows, the selector truncates, and the agent quietly evaluates against less than the full standard. Naming the rule areas in the agent instructions is a useful backstop.
Improvements we have parked
The score currently lives inside the report text as a heading, which is enough for the indicator to parse but not enough for Views. A dedicated numeric field would enable dashboards and "everything below 7" filters, derived in a save step ordered after the automator writes the report.
Beyond that: an asynchronous variant if the synchronous latency starts to bother editors, per-area sub-scores instead of one number, evaluating prose held in paragraph components, a non-destructive regenerate that keeps the old report if a run fails, and showing the score in the tab label itself.
Conclusion
This feature is almost entirely made of things we had already built. The governance items existed, the injection was automatic, the agent-to-field bridge was a module we had just released. What was left was an agent with a carefully written brief and a field to put its answer in.
That is the argument for putting your rules in one place early. Once the standard is a first-class thing on your site rather than a paragraph pasted into a dozen prompts, new capabilities stop being integration projects. The reviewer and the writers read from the same page, literally, and the editor gets a second pair of eyes that never gets tired, never skips the accessibility checks, and always cites its reasoning.