RUSSH WORK

Inside Content Bot: the questions that became the architecture

A client came to me tired of arguing with ChatGPT: re-pasting her rules every morning, watching the model ignore them, regenerating, losing the thread, fixing the same violations by hand. We replaced that loop with a system that carries her rules permanently and enforces them mechanically. This post is about the part that made it work, which was not the pipeline. It was the discovery interview. The questions I asked, the answers that became hard-coded rules, and the Forward Deployed engineering decisions that followed. The client is real and every number is from production.

By Russ. Production 2026.08, live behind an access-keyed operator page. The client is a working SEO strategist serving a Canadian addiction and mental-health treatment provider. Names withheld; everything else is real.


The use case, stated the way the operator stated it

The client writes SEO articles for a living. Her process before this system: research keywords by hand in SEMrush tab by tab, read the top ten results for each target by clicking every link, brief herself, then draft in ChatGPT. And then the part that made her want to throw the laptop: ChatGPT does not follow its own rules. She would paste her writing standards into the chat, get a draft that ignored half of them, correct it, regenerate, and watch the correction wash out two turns later as the context window silently forgot. Every article restarted the same argument with the same model about the same rules.

When we sat down to scope, she ranked her three problems. Keyword analysis takes the most time. Content analysis is second. The rules problem is the one that made her angriest, and it is the easiest of the three to solve mechanically, which is a useful mismatch to notice: the operator's emotional priority and the engineering difficulty ranking are different lists. We built the enforcement layer first because it earns trust fastest, and trust is what lets you build the rest.

Discovery: the questions are the product

The standard discovery failure is asking an expert to describe their process. You get the org-chart version: I research keywords, I analyze competitors, I write the article. That description is true and useless. It contains none of the judgment, and the judgment is the only thing worth automating. She had been doing this work so long that her real criteria were subconscious. The interview's job was to surface numbers she did not know she used.

So instead of what do you do, the interview ran on questions built to force specifics. These are the actual questions from the call transcripts, and what each one turned into.

Walk me through the last competitor you rejected. What killed it? Not how do you pick competitors. The last-real-example framing pulls the decision she actually made instead of the policy she thinks she has. Her answer surfaced the single most valuable signal in the system: she hunts for sites holding rankings with an authority score of zero, because a weak site ranking anyway means the keyword is winnable. That sentence became the primary selection filter in the research engine. A generic answer would have given us "I pick strong competitors," which is the exact opposite of what she actually does.

You said this article is good. It would NOT be good if what? She had a folder of articles she admired and could praise them fluently. Praise does not compile. Inverting the question forced the failure criteria out: paragraphs that restate themselves at the end, keyword stuffing, fewer than three internal and three external links, text blocks running past 300 words without a heading, information duplicated from the site's pillar pages. Her own notes had "low-quality blog definition" marked as to-be-determined. Twenty minutes of inversion questions produced the definition, and it now runs as eight deterministic checks on every draft.

What is the fix you make every single time, the one that annoys you most? This question finds the highest-value rule in any operator workflow, because a correction made every time is a constraint the model should never violate. Her answer: the primary keyword never lands in the first sentence, and she moves it by hand, every article. That is now a hard rule. A draft without the keyword in sentence one never reaches her.

Is fifteen the cap, or is twelve? When she said a 2,000-word article should not repeat the keyword more than "max, max, max 15 times... even that is stretching it," the follow-up mattered more than the first answer. Operators hedge upward when a number feels like a commitment. Pressed once, the cap settled at twelve, and twelve is what the linter enforces. The lesson generalizes: the first number an expert gives you is a negotiating position with themselves. Ask again.

When a draft fails three times and you fix it yourself, should your correction bind every future draft? This is the question that turned a complaint into a learning loop. Her condition was precise and became the design: she wants to see which rule the system thinks was violated, so she can either fix the draft or overrule the rule. Corrections become candidate rules; candidate rules bind only after she reviews them. The system gets stricter over time without drifting away from her judgment.

If you had fifty content gaps and could only write five, how do you actually choose? Still partially open, honestly. Her answer mixed volume, winnability, and client requests in proportions she could not fully articulate, so the queue scoring is labeled provisional in the registry and flagged for calibration against her picks. Discovery is allowed to return "not yet known." Encoding a guess as doctrine is how systems quietly diverge from their operators.

The pattern across all of these: never ask about the process, ask about the last decision. Never accept praise, invert it into failure criteria. Never accept the first number, press once. And when the operator cannot articulate a rule, record that as an open assumption instead of inventing one.

The architecture the answers forced

One registry, two faces. The root cause of her ChatGPT misery was that rules lived in prompts, and prompts are requests. Here, her rules live in one versioned registry file that renders two ways: a prose face injected into the writer's system prompt, and a machine face executed as code after every generation. The writer is asked to follow the rules and then checked anyway. Prompt and checker cannot drift apart because they compile from the same source.

Deterministic lint before model judgment. Every rule that can be code is code: keyword placement, mention counts against her floor and cap, section lengths, link anchors under four words, em-dash bans, meta lengths. A second model, never the writer, judges only what code cannot: voice, intent focus, fabricated claims, duplicated coverage. Splitting the two keeps the expensive judgment calls rare and the cheap checks absolute.

Three strikes, then a human, with the rule named. A failing draft gets precise revision instructions and two more chances. After the third failure it escalates to the client as a document plus a one-page summary where every rejection names the rule it broke. That naming is her sovereignty clause: she can fix the draft or overrule the rule, and either action improves the system.

Every link gets an HTTP request. Her review of the first article found five dead links the model had invented. The fix is not a better prompt, it is a verifier: every external link in every draft now gets hit with a live request before the draft can pass. Fabricated citations changed from an embarrassment she catches to a failure class the machine catches.

Research cached in SQLite, because keywords do not change weekly. The keyword engine pulls every keyword a competitor ranks for, filtered server-side to her thresholds, and lands everything in a local SQLite store with a thirty-day freshness window. First pull of a competitor: about three cents. Every re-run inside the window: zero. The research layer is built like a data pipeline, not like a chat session, because that is what it is.

Delivery meets the reviewer where she already works. A passing draft does not arrive as markdown in a repo she will never open. It lands in her Google Drive as one document with tabs: the formatted draft, a job-info tab carrying the business URL and exact spend, the full check report, and the escalation history when there is one. Passes route to a review folder, three-strike failures route to a needs-work folder. The system's output format is her existing workflow, not mine.

Cheap models where the loop protects you. The writer is a budget model at roughly $0.009 of spend across a full three-cycle draft, with a mid-tier fallback that engages automatically on provider failure. A reasoning-tier model judges. The enforcement loop is what makes cheap generation safe: when every draft is linted, link-checked, and judged before a human sees it, the writer's raw reliability matters less than the verifier's. Spend per article runs in the low cents, and every job reports its exact token spend to the operator when it finishes.

Receipts

Numbers from production, not projections. Writer spend for a full three-cycle draft: $0.0088 measured. Research: 129 qualifying keyword candidates from one competitor pull for $0.0275, re-runs free for thirty days. Calibration against the operator's labeled examples: the checks catch 100 percent of the articles she graded as weak, and her winners pass everything except one rule she herself flagged as a known gap in her old workflow. Her review notes arrive as voice memos; one round produced six specific criticisms, and all six were enforced rules within a day, which is the whole thesis of the escalation design: her criticism is not feedback, it is training data with sign-off.

Hours, labeled as the estimate it is. Her manual loop per article, from her own scoping ranking: keyword research measured in hours, content analysis in hours, drafting plus the regenerate-and-fix argument with ChatGPT in more hours. A conservative 4 to 6 hours per article end to end. The system's ask of her now is a one-line prompt and a review pass, well under an hour. Call it 3.5 to 5 hours returned per article; at a modest eight articles a month that is roughly 30 to 40 operator hours back, against low-cents marginal cost per article. The measured baseline is on the calibration backlog, and until it exists this paragraph stays labeled estimate. The number I will defend without a label is the count of times she re-explains her rules to a chat window: zero.

What this teaches about the FDE job

The deployment was never blocked on model capability. It was blocked on extraction: getting twenty years of taste out of an operator's head and into a form a machine can enforce, with her keeping veto power over every rule. The interview technique is the differentiator. The pipeline is competent plumbing.

And the healthiest number in this post is the feedback loop: one operator review becoming six new enforced rules inside a day. A system that metabolizes criticism at that speed is improving faster than an operator arguing with a chat window ever could. That compounding is what you are actually selling.


Registry version at time of writing: 2026-08-11b. 24 machine rules, 14 judgment rules, 3 open assumptions awaiting operator calibration. The open assumptions are listed in the source of record on purpose.