When the Pipeline Publishes Its Own Autopsy
The March 12 blog post opened with this sentence:
There is no March 11 blog post yet, and the pipeline didnât produce actual content â it produced a meta-description instead of a blog post.
That was the blog post. The pipeline explaining, with perfect accuracy, why it couldnât write the dayâs blog post â published to the live site for anyone to read.
If youâve followed this blog since early March, the shape is familiar. Between March 3 and 6, the pipeline published Claudeâs editorial notes instead of finished posts. The review, revision, and polish passes each diagnosed the missing content correctly, but their diagnoses became the published output. Four days running, until a reader noticed.
That bug was fixed. Logging, draft-mode routing, front matter deduplication, meta-commentary detection. The March 7 and 8 posts document the investigation. The pipeline ran clean for a week. Then March 12 happened, and the same failure came back wearing different clothes.
Same Root Cause, Different Surface
The March 3â6 failures had a specific signature. The polish pass tried to write directly to _posts/, the sandbox denied the write, and Claude returned what it would tell a human operator: âHereâs what I changed and why. Could you grant write permission?â The detection heuristics were built to catch exactly that:
meta_patterns = [
r'^(Here\'s|I need|Would you like|Could you)',
r'^Changes made:',
r'write permission'
]
The March 12 failure matched none of those patterns. No editorial notes. No permission requests. Instead, a procedural summary: âThere is no March 11 blog post yet,â followed by numbered instructions for how to fix it.
To a regex checking for ^(Here's|I need|Would you like|Could you), a declarative sentence about pipeline status looks like the opening of a blog post. The heuristics were calibrated against the failure mode theyâd already seen. This was a new one that shared the same root cause but slipped past every check.
The Engineering Work That Got Lost
The actual sessions from the day before involved creating three matplotlib SVG schematics for the PAR Mobile Robot Platformâs structural analysis report: push-out load limits on the anchor assembly, base sliding under lateral force, and a free body diagram combining both analyses.
The push-out and base-sliding schematics were essentially labeled arrows on rectangles. Each showed an individual load path â lateral capacity at the anchor point, friction resistance at the base â but neither connected them. Useful numbers (a 1.3 safety factor, 6-inch anchor bolt spacing), but the reader had to hold all three load paths in their head simultaneously to understand why the assembly worked.
The free body diagram did what the other two couldnât. It showed all forces acting on the assembly at once: lateral push-out at the anchor, sliding friction at the base, the reaction moment at the bolted connection, gravity through the center of mass. The 1.3 safety factor stopped being an abstract number and became a visible relationship between arrows â the margin between applied forces and the reactions resisting them.
The design decisions outweighed the code complexity. Where to place force arrows so they didnât overlap. Whether to show the bolt pattern as individual fasteners or a single reaction point. Each choice was about what the reader needs to see first versus what they can infer. The push-out and base-sliding drawings became appendix material. The FBD carried the main body of the report.
Three drawings planned, one that mattered, two that supported it. That hierarchy only became clear during the work, not before it.
Why the Pipeline Missed Its Own Subject
The dayâs engineering sessions produced visual artifacts designed to make structural analysis legible to readers who hadnât done the analysis. The FBD exists because numbers in a sentence arenât enough â you need spatial orientation, a way into the force balance that doesnât require already understanding it. And the pipeline, tasked with turning those sessions into a readable post, produced a meta-description instead.
It didnât fail at understanding the content. It failed at producing it. The draft pass returned a summary of the transcripts rather than a narrative built from them. The review pass correctly identified that the draft was a summary, not a post. The revision pass acknowledged the problem and described what a proper post would contain. The polish pass, receiving a stack of diagnoses rather than prose, concluded that there was nothing to polish and published that conclusion.
Each pass did its job. The cascade produced garbage anyway.
What the Validation Actually Needs
The existing heuristics catch conversational responses â a model talking to an operator. A summary is a model talking about a situation. Different phrasing, same uselessness as a blog post.
Three additions would close the gap:
A minimum word count. A 121-word post should trigger review. Every legitimate post in the archive exceeds 600 words. A hard floor at 300 catches summaries without rejecting short but real posts.
A structural check for narrative elements. Blog posts contain section headings, multiple paragraphs, and prose that develops an argument. Summaries contain numbered lists, suggested commands, and procedural language like âto move forwardâ or âyou have two options.â Checking for ## headings and the absence of instruction-like phrasing separates posts from troubleshooting guides.
A classification gate. A second Claude pass that asks: âIs this a blog post or a description of what a blog post should contain?â The model is good at this distinction â every pass in the March 12 cascade correctly diagnosed the problem. The pipeline just never asked the question in a way that could stop the output.
The Lesson the Schematics Already Taught
The push-out and base-sliding drawings each answered their own narrow question correctly. The FBD was necessary because narrow answers donât compose into understanding without a drawing that shows the whole system.
The pipelineâs regex patterns work the same way. Each catches a specific meta-commentary phrase. None of them compose into a general answer to the question âis this actually a blog post?â The pipeline needs its own free body diagram â a validation check that looks at the whole output, not individual strings.
This post was written manually, outside the pipeline, because the pipeline produced a summary instead of prose. Thatâs the most concrete proof the validation gap is real. The pipeline caught its own failure. Every pass diagnosed the problem correctly. It just couldnât do anything about it except publish the diagnosis.