Refreshing a chat lost the agent's answers: the turn folded to a seam and printed "Turn finished · no closing message" over a turn that had plainly answered. Reported against a commander, where it happened on most refreshes. The durable log was innocent. A refresh renders from Claude's .jsonl, and the harness delivers a finished background task as the agent's next user message — a <task-notification> envelope. The parser dropped it so it would not replay as a raw XML bubble you appear to have typed, and dropped a turn boundary with it, because turn-rows derives turns from the message list. The woken turn merged into the one before it, so that turn's closing prose became mid-turn work and folded, and the merged segment ended on a tool call, which earned the marker. Measured on the reported session: 30 messages, one user message, one fold hiding seven answers, the marker reproduced at 21 of 30 refresh points. The envelope now rebuilds into the same task row a live task:notification produces, carrying startsTurn. buildRows makes that a boundary and buildTurn exposes it as the turn's opener. Separately, the marker is withheld when a segment ends on a tool call we never saw come back — still running, or cut off holding it. A completed trailing tool call keeps its marker, so the test pinning that live behaviour is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: f7a62308-0977-4cf4-aa29-c020853fd420
todo/ — the format
One item per file. A file is a card. That is the whole idea, and everything below follows from it.
It replaced a single 1,050-line TODO.md on 2026-08-21, which had reached 72 open items across 28
sections and was read mostly on a phone. The split was mechanical — no prose was rewritten.
Layout
todo/
├── README.md # this file
├── <theme>/
│ ├── _index.md # the theme itself: display name, and any prose that belongs to the whole group
│ └── <item>.md # one item
The theme is the directory. _index.md carries the theme's display heading, so a theme is
self-describing and nothing has to hold a slug→name map. TODO.md at the repository root is the
generated index over all of it — bun run todo:index.
An item
---
id: fleet/an-orchestrator-that-acts-on-every-server-at
title: 'An orchestrator that acts on every server at once'
theme: fleet
status: open
created: 2026-08-21
date_source: stated
order: 1
---
**An orchestrator that acts on every server at once** — pull and update every platform, restart a
process everywhere, report which host is behind…
id—<theme>/<slug>, and it is the filename. Stable: rename the title freely, leave the id alone. Anything pointing at an item points at this.status—open,doing,blocked,backburnerordone. The board (/todos) renders one column per value; adding one is a new entry inTODO_STATUSES(api/todos/todo-tree.ts), not a new file or directory.backburneris parked-not-dead — still counted as open by the index.created— the date the item was raised.date_sourcesays how much to trust it:stated(the prose named a date — true),section(inherited from its old section heading — close),assumed(unknown, floored at 2026-08-20, the day before the split — a bounded "before today" rather than an invented day).order— position within the theme, preserved from the original list. What a board reorders.priority(optional) —urgentwhen the owner says so, absent otherwise. There is no scale of five: an item is either something he named as urgent or it is not, and a scale would only invite everything to drift upward. Urgent items are listed first in the generated index.due(optional) — a date the owner named. Only ever written because he said one; never inferred from tone or from how the item is worded.- The body is prose, and it is the point. These entries carry the reasoning, what was verified versus assumed, and what was already tried. An item stripped to a title loses the thing that made this list worth keeping.
Two-way sync — the contract for the Kanban board
A board that reads this tree and writes back to it is a wanted feature
(todo/prompt-library/… see todo/tooling/). What it may rely on:
- A card is a file. Creating a card creates a file; moving a card between columns rewrites one frontmatter field; deleting a card deletes a file. Every board action is a small, reviewable git diff.
idis the identity, not the title and not the line number. Renaming or rewording never orphans a card.- Frontmatter is the machine's half, the body is the human's half. A board may rewrite frontmatter freely. It must not reformat a body it did not change — the prose is hand-written and a normalising pass would produce a diff nobody can read.
TODO.mdis generated output. A board must never write to it; it regenerates from the tree.- Git is the sync log. No lock file and no sidecar state: the file on disk is the truth, and two writers are resolved the way every other conflict in this repository is.