July 18, 2026
One XSS Hole, Three Stuck-Turn Bugs
A stored-XSS sanitization gap and three separate ways a conversation turn could get stuck or crash-loop all got fixed today, alongside a calendar timezone bug and a mail integration that failed every search.
Yesterday was cleanup under a strict no-behavior-change rule. Today broke that rule on purpose — eighteen commits, and most of them changed what Chalie actually does, because most of them were fixing something that was actually broken. Different kind of day. Less sweeping, more triage.
The sharpest one first. Assistant replies get turned into HTML and rendered straight into the page — on the live send, and again on every later reopen. That HTML was never sanitized. If a model response happened to carry a script tag or an event handler, it got stored as-is and replayed every time, not just once. Fixed it at the single point both paths run through: sanitize once, at save time, so there’s no second copy of the message floating around that skipped the check. Exactly the kind of bug that costs nothing until someone goes looking for it on purpose.
Three separate fixes converge on the same failure mode: a turn that should end cleanly instead spins. If the model called the same tool with the same arguments over and over, it used to get zero feedback until the fifth call triggered a hard kill — now it gets nudged after the second. If a completion came back completely empty — no tool calls, no text, nothing — it used to just settle as “done” with a blank answer, pretending it had responded; now it retries a couple of times and crashes loudly if that keeps happening, instead of faking success. And if a background task finished after the turn that spawned it had already crashed, it used to respawn that exact doomed work all over again; now it checks the parent’s state first and doesn’t. None of these are features anyone will notice. They’re the difference between a system that says something went wrong and one that wastes a few minutes hoping nobody asks.
Two “how did this ship” bugs got squashed alongside them. Ask Chalie what’s on tomorrow, and if you weren’t on UTC, you’d sometimes get back nothing — a whole-day date range was computing midnight in UTC instead of your own timezone, so the window collapsed to zero width before the calendar ever looked for events. Separately, every single mail search had been crashing outright, because a broken import meant the code was reaching for a settings object that never actually loaded. Both small, targeted fixes. Neither should have shipped in the first place, but that’s what a hardening pass is for — find it, fix it, don’t dwell on it.
On the memory side: a corrected fact — a name, a relationship, anything Chalie stores under one canonical key — used to just pile up next to the old, wrong version instead of replacing it. Say you correct a detail Chalie has stored; the old value stayed live right alongside the new one, forever. Now a correction actually supersedes what came before it, deterministically, with no fuzzy-matching guesswork involved. And the code-execution ability finished its rename and picked up a real security guard along the way — scripts can no longer escape their sandboxed workspace through a symlink.
Two days of hardening back to back now — one pass for the code that only offended a linter, one for the code that was actually hurting someone. Whatever ships next isn’t dragging either kind of debt behind it.
-
Sanitized assistant HTML at the point it’s saved, closing a stored-XSS gap shared by the live-send and page-refresh render paths
-
Fixed three separate ways a conversation turn could get stuck: no feedback on a repeated tool call until a hard kill, a completely empty completion silently settling as answered, and a finished background task respawning work its parent turn had already crashed on
-
Fixed a timezone bug collapsing whole-day calendar windows to zero width for anyone outside UTC, and a broken import that crashed every mail search
-
Corrected facts in memory now actually replace the stale value under the same key instead of piling up next to it
-
Closed out the code-execution ability’s redesign with a guard against sandbox-escaping symlinks