The comment at the top of our diagram generator says why it exists: "AI-generated diagrams get text wrong and draw differently every call, so there's no guarantee the pt, en and zh versions are the same drawing." We swapped AI for code exactly to solve that. Except code has bugs too, and ours sat there, never fixed for good, for at least 6 days: four diagrams published this week shipped with a text note cut off past the card border, fixed by hand, the same way every time.
Why aren't the blog's diagrams generated by AI?
Because generative AI draws differently every call. Each article ships in three languages (pt, en, zh), and every version needs the exact same geometry, only the text changes. An AI image generator doesn't guarantee that: sometimes it swaps a color, sometimes it gets a word wrong, sometimes it draws an extra box on one side. The fix was to take the drawing out of AI's hands and put it in code: a Python script (render.py, using Pillow) reads a JSON spec file and draws the same structure in all three languages, changing only the strings.
How does the generator actually work?
Each diagram is a specs/<name>.json file, with a layout (fluxo, comparativo or capa_vs) and a locales key holding pt, en and zh inside. Text that never translates (a command, a flag, a variable name) lives at the root of the spec; whatever gets translated lives inside locales. Running it looks like this:
python3 render.py specs/diagram-name.json pt en zh
One PNG per language comes out in out/, same geometry, same colors, only the string changes.
What bug showed up at least 4 times in 6 days?
Every piece of text in the diagram was drawn with a direct call to d.text(), at a fixed position, with zero width checking. Each step's card has a width computed by dividing the available space by the number of steps; if that step's note was longer than that width, it just kept drawing past the card's edge. Nobody had noticed until the text got long enough, and it happened again, and again:
| Date | Post | What overflowed |
|---|---|---|
| 2026-09-12 | Codex burns tokens while it waits for you | notes for steps 1 and 2 |
| 2026-09-16 | Verboo Code's free tokens ran out | notes for steps 1 and 2 |
| 2026-09-16 | Why Claude Code usage reset on its own | branch label, cut off at the right edge |
| 2026-09-17 | Response language in Verboo Code | step notes |
In two of those rounds the log itself already said "same bug seen in earlier posts": the real number of times this happened is higher than these 4 rows, these are just the ones that got a date and a post tied to them in our execution log. The fix was always the same: open the note, eyeball the character count, shorten it, regenerate, and hope the English and Chinese versions also fit, because each language needs a different amount of text to say the same thing.
How did we fix it, so there isn't a fifth time?
Instead of trusting the eye, the generator now measures before it draws. A new function, ajusta(), uses d.textlength(), the same Pillow function that already centered the "vs" on the comparison-track covers, to know, in pixels, whether the text fits the available width. If it doesn't, a binary search finds the longest chunk of text that still fits and appends an ellipsis:
def ajusta(s_, fo, maxw):
if maxw <= 0 or d.textlength(s_, font=fo) <= maxw * S:
return s_
lo, hi = 0, len(s_)
while lo < hi:
mid = (lo + hi + 1) // 2
if d.textlength(s_[:mid].rstrip() + "…", font=fo) <= maxw * S:
lo = mid
else:
hi = mid - 1
return (s_[:lo].rstrip() + "…") if lo > 0 else "…"
Applied to the four spots that had overflowed at some point: each step's title and note, the error branch's label, and every line of the branch's notes. There's no more guessing how many characters fit per language: the code measures pt, en and zh, each with its own font, and each one decides on its own whether it needs to truncate.
What this doesn't fix: the text still sits on a single line and gets cut, it never wraps to a second line. A note that's too long loses information instead of taking up more vertical space on the card. It solves the real problem (text spilling past the card), it isn't the final version of a text-fitting system.
The same priority guides Verboo Code: measure instead of guess. Open-weight models running on dedicated GPUs, with unlimited tokens, so you can retry as many times as it takes until the result is right, instead of finding out mid-test that your quota ran out.



