August 4, 2026

One Registry Replaces Four Places to Remember

Adding an LLM provider used to mean touching four separate places by hand — today it collapsed into one self-describing class, and the same instinct killed a hardware fallback ladder, a duplicated file-copy path, and a broken glob.

Half of today’s commits were the same move: find a hand-rolled version of something the codebase already does correctly, and delete it.

The biggest one: adding an LLM provider used to mean remembering four separate places to touch — a factory branch, a catalog entry, a key-requirement rule, a frontend preset — and missing one failed silently, the kind of gap that only shows up when someone tries to actually use the provider you half-added. Collapsed all four into one: a provider class now states its own name, host, and whether it needs a key, and everything downstream — factory, setup catalog, credential rules, even the frontend — reads off that class instead of keeping its own copy. Seventeen platforms slot in now by extending one base class, most in under thirty lines. Registering the same platform twice raises immediately instead of silently picking whichever definition loaded last. The readme still said four providers; it now says the real number, twenty-one.

Same instinct, one layer down: local inference had an accelerator ladder — try the fast path, fall back, fall back again — for hardware the install never actually ships an accelerated build for. Ripped it out. Every session runs on the plain CPU path now, full stop, and a session that fails to start is a broken install, not a cue to try three more paths and hope one works. The install checker that verifies a machine can actually run Chalie had been printing every accelerator the runtime happened to report, on a Mac that’s three, only one of which the code ever touches. It now checks for, and only reports, the one that matters.

The feature work followed the same shape by accident. Built a tool that shows a picture — a local chart, something fetched off the web — directly in the conversation, split cleanly from the tool that searches for images, which now just describes what it found and hands off to the one that displays it, instead of half-rendering a thumbnail carousel nobody asked for. Going back through it the same day, found it was downloading and re-copying images through a private cap-and-cleanup path that duplicated a file primitive already used everywhere else in the app. Deleted the duplicate, pointed the tool at the real one, and dropped the referrer on every remote image so a picture card pointing off-machine doesn’t announce where it came from too.

The uglier bug: attachments were vanishing from your own message right after you sent it, reappearing only if something else happened to refresh the screen. The interface refetches the conversation the instant a reply starts working — but the record linking your file to that reply got written a beat later, and nothing told the interface a correction was coming. Whoever refetched first won, and the early refetch always lost the attachment. Fixed by writing that link before announcing the reply had started, not after.

Smallest fix undid the most damage per line: the filter matching stored memories against a pattern had been hand-translating that pattern into a match rule, and got it wrong three ways — bracket groups did nothing, punctuation wasn’t escaped, only two of the real wildcard characters worked at all. Swapped it for the equivalent already sitting in the standard library, which does this correctly. Every case anyone actually uses behaves identically; every pattern nobody had tried yet now works.

Next up is watching whether the registry holds the way the read/URL split has — the real test isn’t today, it’s the next platform someone adds without thinking about the four places it used to require.

  • Replaced provider onboarding’s four separate places to update with one self-describing class per platform and a single registry — seventeen platforms now join in under thirty lines each

  • Removed the local-inference accelerator fallback ladder in favor of one CPU provider; a failed session is now a broken install, not a retry

  • Fixed the install checker printing accelerators the runtime reports but never actually uses

  • Split image search from image display, then caught the display tool duplicating a file-copy and truncation primitive that already existed — deleted the duplicate

  • Fixed attachments disappearing from your own message on first send, caused by the interface refetching before the attachment record finished writing