Record the loose end the taskNote outage exposed, and the last of its checks

A session whose transcript will not parse is skipped with only a log line, so
from the phone it is indistinguishable from an idle unresponsive one. That is
why the outage needed a report from Bryan rather than showing itself. The
cause is fixed; the class is not, and it is the "design the unknown state
first" rule rather than a bug in one code path.

Also rustfmt on the parse path, which the fix landed unformatted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-06 22:43:01 -04:00
1 parent fd71d876e1
commit 0862b47f76
2 files changed
+20 -3

No files matched your search

+18
View File
@@ -33,3 +33,21 @@ one in place when it turns out to need a decision.
that would work today, for Claude sessions, and it is the option that was
not chosen.
## A session the server could not load
- [ ] **A session whose transcript will not parse is skipped with nothing but a
log line, and from the phone it looks exactly like an idle unresponsive
one.** `SessionManager::new` catches a failing `launch` and logs
"couldn't relaunch session <id>", so the session has no pump and no
driver: no status, no history, nothing sendable. That is what the
`taskNote` incident (fd71d87) looked like from Bryan's phone, and why it
needed a report from him rather than being visible in the app.
`Event::Unreadable` removes the cause that time, but not the class — an
unreadable `process.json`, a provider edited away and an unreachable host
all reach the same place.
This is the "design the unknown state first" rule: a session the server
could not load is not a session with nothing to say, and only the phone
can show the difference. It needs a status the wire can carry for it —
the failure with its reason, reported on the session itself — rather than
the reader having to tell it apart from silence.
+2 -3
View File
@@ -353,9 +353,8 @@ impl<'a> Indexed<'a> {
#[serde(rename = "type")]
kind: Option<String>,
}
let place: JustPlace = serde_json::from_str(line).with_context(|| {
format!("bad transcript line in {}", self.path.display())
})?;
let place: JustPlace = serde_json::from_str(line)
.with_context(|| format!("bad transcript line in {}", self.path.display()))?;
// Debug rather than a warning: a transcript written against a
// newer build has one of these per line it wrote, and the row
// on the phone is where this is actually reported.