October 3, 2026

The Stop Button Promised an Undo

A subagent stop button that showed the undo arrow, attachments that could silently miss search, and a type check that changed verdict on unchanged code.

Quiet day. Four fixes, no features, and the worst one failed without saying anything.

Yesterday’s entry ended with the subagent stop button shipping. Today it turned out to be wrong in two ways. It used the chat’s stop-and-undo arrow, but stopping a subagent undoes nothing, so the icon promised something the code does not do. It is a square stop icon now. Second, a stopped run’s transcript showed only the task it was given, which read like an empty answer. The panel now ends with a line saying the run was stopped.

The worst one was attachments. When several came in on one message, their search indexing ran in parallel and raced to create the index file. One of them could fail with “database is locked” and quietly miss the index, so that file does not show up when you search for it. Silent is worse than broken. A user finds this kind of bug by searching for something that is not there.

The cause was SQLite. When two connections try to switch a new database to write-ahead logging at the same moment, the switch fails immediately instead of waiting. The fix switches the new file one connection at a time, so the race is gone rather than retried around.

The rest of the day was cleanup, and most of it deleted code. One pull request consolidates a JSON query that had been written out across the backend models, and adds guards on row creation and path validation. It touches sixteen files and removes more lines than it adds. That is the dedupe I want.

The last one is a small embarrassment. The type check was not reproducible. The dev dependencies allowed any newer mypy, so a new release could turn the check red on code nobody had touched. The version is pinned now. The subclass walkers also type their receiver as any class, so newer typing stubs can still infer the subclass list.

All four commits sit on the 1.4.0 line. None of them is the per-call row change from yesterday’s entry, which is still the next thing to land there.

  • The subagent stop button uses a stop icon, and a stopped run’s transcript says it was stopped

  • Attachments sent together are all indexed for search

  • New database files are switched to write-ahead logging one connection at a time

  • A JSON query copied across the backend lives in one place

  • The type checker is pinned to an exact mypy version