diff --git a/CHANGELOG.md b/CHANGELOG.md index 3308152..058b547 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,37 @@ one of them changed. An entry says which artefact and which version, so `web 0.1 Every version published to a channel appears here. Nothing is written from memory afterwards: a build cannot be published without its entry. +## 2026-09-01 — One byte in a command's output could destroy the turn that read it `api 0.106.0` + +**If you have been seeing `Invalid prisma.message.update() invocation` in conversations, this is +it.** A single character in what a command printed made the assistant's turn impossible to store, +and the run died at the write — after the work had already been done on your machines. Reported this +morning, reproduced against a database within the hour. + +Two characters do it, and neither is exotic: + +- **A null byte.** PostgreSQL refuses it outright, in text and in JSON alike. It turns up in the + output of perfectly ordinary commands — reading a file with embedded nulls, `find -print0`, a + journal or LDAP dump, anything that touches something binary. +- **Half of an emoji.** This one was ours. Long output is shortened by cutting it, and the cut was + made without checking whether it landed in the middle of a character. An emoji in a log line, at + an unlucky offset, was enough to lose the turn that read it. + +Neither carries any information, so both are now removed before anything is stored — as close to the +source as possible, so what the assistant reads, what you see and what is written down are the same +text. Tabs, carriage returns, ANSI colour and whole emoji are untouched; a character that was cut in +half shows as `�`, which is the truth about it. + +**And a failed run no longer leaves a tool card spinning for ever.** The same report showed one that +had been turning for eighty-five minutes, above a turn that had already said it failed: closing a +run wrote its text but never its tool calls, so a call it never returned to kept the status it was +dispatched with. Those calls are now closed as cancelled, saying plainly that the command may have +reached the machine and its outcome is unknown — except one still waiting for an approval, which is +told it never ran, because it never did. That matters beyond the screen: the assistant reads those +rows back on the next turn, and "still running" makes it wait for an answer that cannot come. + +No schema change, no console change. Take the api image. + ## 2026-09-01 — Jarvis administers Kubernetes clusters `api 0.105.0` `web 0.128.0` **Register a cluster the way you register a server, and ask for the work in words.** A Kubernetes