My Local LLM Writer Failed Its Own Word-Count Gate
Gemma 4 26B wrote a 535-word draft against a 550-word floor. The gate blocked it, both rescue engines were down, and no bad post shipped.
Every morning a local model writes my blog draft. Gemma 4 26B runs through Ollama on an RTX 5090 and hands its output to a deterministic gate before anything reaches the publish queue. On 2026-08-17 the gate said no, twice, and the pipeline shipped nothing. That is the system working. It still cost me a publish day, so here is the full failure chain and what I changed.
Summary: On 2026-08-17 a local blog writer (Gemma 4 26B via Ollama on an RTX 5090) produced a 535-word draft against a 550-word floor, so a deterministic output gate rejected it. Both frontier rescue engines were down at the same time, one on quota and one on expired auth. The result was 0 posts shipped and 0 bad posts shipped.

What failed in the local writer run?
Two separate things, in order.
The 07:45 run never loaded the model. The host RAM guard wants 16 GiB free before a Gemma cold load, and the box had less. The run exited with a skip reason instead of grinding the machine into swap. If you run big models next to real workloads, you want this guard. I covered the memory side of this in unload local LLMs after tests.
The 10:00 run loaded fine and generated. Then the output gate counted the body: 535 words against a 550 to 1100 window. The draft also failed a literal-string check for the closing prompt section my blog contract requires. The writer exited nonzero and wrote nothing to the queue.
The word count check is one line of Python: len(body.split()). It catches a real failure mode. A 26B model will write a confident, complete-looking draft and stop early. Nothing about the text looks broken. Only the count says so. I saw the same shape in my 4B vs 26B task quality tests: small and mid-size local models fail quietly, not loudly.
Why did the rescue path also fail?
The pipeline has a frontier fallback for days the local writer cannot deliver. It tries one hosted CLI engine first, then a second. On this day both were dead.
The first engine had hit its usage quota and was locked out for two more days. The second had an expired OAuth session that could not refresh. Neither failure had anything to do with the blog. Both had been true for hours before the pipeline needed them, and nothing checked. That left 2 rescue engines down at the exact moment the local model came up short.
So the day's arithmetic: one blocked cold load, one rejected draft, 2 dead rescue engines, 0 posts shipped, 0 bad posts shipped. The alert fired to my phone, and one login fixed the auth half.
What should a local writer gate check?
Deterministic things only. Do not ask a model whether a model's output is fine. My gate checks four things:
- Word count inside a configured window (550 to 1100 for blog drafts)
- Every required heading present as an exact string
- The image path matches the post slug
- No words from a parsed forbidden-word list
Each check is a string or integer comparison. Each failure names itself: the log line for this incident read "body word count 535 outside 550-1100". No detective work, no judgment call. This is the same principle as the speed and quality gate I put on benchmark runs: the model produces, the script decides.
How do you keep the rescue path alive?
The gate did its job. The gap was upstream. Engine health is pipeline health, and I only measured it at publish time.
Quota exhaustion and auth expiry are ordinary states, not incidents. Treat them like disk space. Probe every engine once a day with a one-token call and alert the moment one dies, hours before you need it. A dead fallback discovered at publish time is not a fallback.
This is also half the case for owning the hardware. The 5090 never expires a session and never hits a vendor quota. But the local box has its own guards, like the 16 GiB RAM floor, so the frontier fallback still earns its place. Watch both sides, and make the watcher deterministic.
Accompanying prompt
What the prompt does: It adds a deterministic output gate to any local LLM writer pipeline.
Copy/paste this prompt:
Copy-ready prompt
Paste the exact block into your coding agent.
No article chrome, no footnotes, no formatting drift.
This prompt and every other one we publish live in the free prompt library.
Copy the block above.
Get the artifact-backed local AI lab notes by email: https://bmdpat.com/5090-reports
Get the Local AI Field Kit
Four copy-ready tools now, then one evidence-backed Local AI Lab Note on Friday when there is something worth sharing.
Get the requested artifact now, then at most one evidence-backed Local AI Lab Note on Friday when there is something worth sharing. One-click unsubscribe. No sponsored placements. Privacy.
Patrick Hughes
Building BMD HODL — a one-person AI-operated holding company. Nashville, Tennessee. Twenty-Two agents.
More writing
- 5 min
Unload Local LLMs After Every Test
A local model test is not over when text appears. I unload the model, read idle VRAM, and record the result before I start another run.
- 5 min
How I Benchmark Local LLMs Before I Trust Them
A local LLM benchmark should end with a decision. I record task quality, tokens per second, VRAM, power, and failure state before I add a model.
- 5 min
How I Test a 30B Local Model Before I Load It
A 30B local model can fit on paper and still fail the job. This test plan checks memory, tool use, speed, and repeatability first.
- 5 min
When a 4B Local LLM Beats 26B on One Task
On one RTX 5090 workshop, a 4B model beat a 26B model on speed while both passed four code checks. Here is the model-selection rule I kept.
- 5 min
My Local LLM Got Faster After It Passed the Tests
A three-run RTX 5090 test showed why local LLM tuning must pair speed with fixed-task checks. One faster setting also repaired every test.