[bmdpat]
All writing
5 min read

I Raised the QA Bar on Blog Infographics

Blog charts need correct labels. I tightened layout geometry, char budgets, claims checks, and vision logs so a bad PNG cannot ship quietly.

Share LinkedIn

I ship measured local-model posts with charts. Generative image tools garble numbers. So the fleet uses one matplotlib renderer under config/visuals/. Exact text. Fixed brand colors.

That still was not enough. A chart could pass "it rendered" and still look sloppy: numbers in corners, tiny labels, digits that never appear in the post. I raised the bar.

What failed before

The first defect class was layout. Step numbers sat in the top-left of a card while the label sat in the center. Peer cards did not share baselines. Long labels shrank below a readable floor.

The second class was honesty. A graphic could invent a comparison that no metrics file contained. Vision QA only checked whether the image looked clean, not whether the numbers were true.

The third class was publish mechanics. Committing a PNG from a feature branch worktree was easy to get wrong. Agents need a path that always targets main for the one asset file.

The gates

Every blog infographic now hits the same chain before an embed line is printed.

  1. Char budget. Budgets scale with step count. A short chain (n≤3) gets wider cards and longer labels. A four-step row stays tight (18/22). Five or more steps use a two-row grid so cards do not crush.
  2. Layout then claims. Numbers, labels, and subs share peer baselines. Step indexes sit in orange pills with clearance so they never paint over the words. Digits in the graphic require --claims <post or metrics> or publish exits 8.
  3. Vision log. The vision gate still fail-closes. Full stdout and stderr land under Reports/Visuals/ so a timeout is not a mystery.

Footer text stays at the same readable floor as body labels (7pt minimum). Titles sit on a dark header scrim so ambient textures cannot wash them out.

Three gates before a blog PNG ships: char budget, layout and claims, vision log

What I measure

The unit suite under config/visuals/ is at 29 tests as of 2026-07-13. Selftest renders every file in examples/ and specs/ (13 specs after this post). Geometry QA checks containment, min size, peer baselines, and peer line counts. Char lint runs before draw.

I also re-rendered the live vector-migration post asset earlier the same day after the first stack fix. New posts get the full gate set automatically when they use publish_blog_asset.py.

What I will not do

I will not put labels inside a diffusion model. Charts need crisp, correct English. Ambient textures stay under the diagram. Text stays on the matplotlib layer.

I will not ship a PNG that fails any gate. Fail closed means ship text-only or fix the spec. That is intentional.

When a graphic is worth it

Use a chart when the post has a process, a comparison, or a set of numbers. Write the short labels first. Point --claims at the draft. If the story needs long phrases, use fewer steps or a stats/flow template. Do not fight the 4-up width with paragraphs inside cards.

The contract lives in Prompts/Includes/blog-publish.md and config/visuals/README.md. Agents read it before inventing a one-off plot.

Accompanying prompt

What the prompt does: This prompt turns a draft post into a fail-closed infographic publish checklist with char budgets and claims.

Copy/paste this prompt:

Copy-ready prompt

Paste the exact block into your coding agent.

No article chrome, no footnotes, no formatting drift.

Role: You are a blog infographic publisher for exact-text charts. Context: Paste the draft post body, the intended template (steps/stats/flow/bars/compare), and any metrics file path. Task: 1. Write a JSON spec that fits char budgets (4-up steps: label <=18, sub <=22). 2. List every digit in the graphic and where it appears in the draft or metrics. 3. Run publish with --claims and report geometry/vision outcomes. Output: - The JSON spec - A digit provenance table - PASS/FAIL for each gate with one-line reasons Constraints: - No generative text-in-image for labels - Fail closed on missing claims when digits exist - Keep labels short; do not invent metrics
20 lines666 chars
Ready

This prompt and every other one we publish live in the free prompt library.

Copy the block above.

I publish measured local-model work and the systems around it in The 5090 Reports. Join the list for the next artifact.

For related layout and local-model posts, see I rebuilt 5,383 embeddings after a dimension change and the num_ctx reload tax.

Get the local AI lab notes

Benchmark rows, VRAM fit checks, quant choices, and what actually runs on consumer GPUs. M-F, only when there is something worth sending.

PH

Patrick Hughes

Building BMD HODL — a one-person AI-operated holding company. Nashville, Tennessee. Twenty-Two agents.

More writing