Build Daily

Tinley Park · August 2, 2026

Wednesday, July 15, 2026

mood: shipping-fast

A sixteen-second wait that turns out to be a coin flip is not a performance problem. It's a routing problem.

Long day across three products. The headline was chasing the agent's latency to its real cause — not the model, not a cold start, but which provider the request happened to land on — and closing it with a single routing preference. Around that: a shared kit for operator screens, a full rebuild of how Sage classifies what a video is actually about, and a search-terms report wired into the daily numbers email.

Shipped

  • Sixteen seconds became two — the agent's slow replies weren't the model and weren't a cold start; requests were being handed to whichever provider was available, and some of them were slow enough to hit the gateway's hard timeout and return an empty error. Asking for the fastest provider instead of any provider took generation from sixteen-plus seconds to roughly two
  • The empty error explained — those blank failures were the gateway giving up at its own ceiling; generation now runs against a bounded deadline so the agent always returns its own honest reply before anything upstream cuts the line
  • Answers stay closer to the source — lowered the agent's improvisation and added a check that flags claims the source material doesn't support
  • Retrieval moved onto the shared database — the content search layer now runs on the same database everything else uses, retiring an extra dependency without changing a single caller
  • One kit for the operator screens — a page written in a light palette had been dropped into a dark console and rendered dark-on-dark; the deeper cause was six drifting hand-rolled copies of the same controls, so the shared pieces became a real kit with a living reference page, and the offending screen is the worked example
  • Sage learned what a video is about — topics were surfacing videos that only mentioned them in passing. Each video now carries one primary subject drawn from real astrology — an aspect between two bodies, a movement into a sign, a forecast — with bare planet or sign names banned as too vague to mean anything
  • Recurring shows became their own topics — a daily card reading, a weekly update, a daily update; a short-form clip is recognised by its length, which meant teaching the pipeline to record how long a video actually is
  • Off-topic content stops at the door — a relevance check now runs at ingestion and auto-hides what clearly doesn't belong, queuing anything borderline for a human; the on-topic definition covers tarot and spiritual work, not astrology alone, after the first version over-corrected and started hiding good material
  • Search terms in the daily email — sagedaily.io was verified with the search engine's console and its query report now feeds the same summary email builddaily.io already gets, so the terms people actually search accrue from here on
  • The status badge tells the truth — the online indicator on builddaily.io was a hardcoded default; it now reads a real readiness check and shows online only when the agent can genuinely answer
  • Deploys refuse to ship stale code — two publishes went out with old content because the local copy hadn't caught up to what was merged; both deploy scripts now check and refuse, with an explicit override for the rare case that wants it
  • A book became a course — added a 1912 New Thought text to the elevatedaily.io shelf as a critical review plus a chapter-by-chapter breakdown, and rebuilt the local reading console that had been serving a stale copy
  • Search-friendly titles tried and reverted — reference pages were pulling impressions and no clicks, so their titles got reworked to chase long-tail queries; on reflection the pages should stay clean reference docs and the search work belongs in dedicated articles that link into them. Reverted, three articles queued instead

Notes

The latency fix is the one worth remembering, because everything about it pointed the wrong way. Sixteen seconds smells like a model too big for the job, or a function waking from sleep — both plausible, both wrong, and both would have taken days to "fix" without moving the number. The real answer was that identical requests were being routed to different providers with wildly different speeds, so the wait wasn't slow, it was random; the occasional total failure was just the unlucky tail crossing the gateway's timeout. One routing preference collapsed the whole distribution. The lesson isn't about that provider. It's that a symptom which varies wildly between identical runs is pointing at a variable outside the code, and averaging it hides the one signal worth having.