Take subagent reports out of the main transcript, and separate turns with a rule
A row per finished background task is a screenful of dividers about work the reader was not asking after, and one of them turned out to be a whole shell command drawn as centred prose, because its words came from somewhere with no reason to keep them short. `Event::TaskNote` is gone entirely, along with the row that drew it. A subagent's closing report is recorded as that subagent's own transcript's closing text and is read in the subcard, which is where it was already going; what the parent gets a row for is a message a subagent genuinely sends it, which arrives by the peer path and has had one all along. What remains is the actual defect and the smallest thing that fixes it. The fold still refuses to grow a settled reply, so a turn boundary is always a message boundary, and where two replies then abut it puts a `TurnBreak` between them: a hairline, no words, no colour. Made by the fold rather than sent by the server, because it is not something that happened -- it is the boundary between two things that did. `joinPages` puts one in at a page seam, which the fold never gets to see. The task notification is still what closes a task in `Status::Waiting`'s bookkeeping, and the registry lookup that recognises one this translator never saw start is what makes that work for a session adopted across a restart. Verified on the emulator: three replies, three rules, and nothing about the helpers anywhere in the parent. 170 server tests, 85 JVM tests, ktfmt, clippy, rustfmt and Android lint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ef1aad8776
commit
1bbb642973
13 files changed
+171
-407
No files matched your search
@@ -241,17 +241,17 @@ sent while a subagent runs is not held until the subagent finishes; and
|
||||
`sessionWorking("waiting")` is deliberately **false** — nothing is being
|
||||
written, and the fold uses that same predicate to decide a reply is settled.
|
||||
|
||||
- **A task reporting back is a divider** (`Event::TaskNote`, `TaskNoteRow`),
|
||||
and the reply that answers it is a **new** message. The fold refuses to grow
|
||||
a settled reply; without that, two turns with nothing recorded between them
|
||||
were folded into one and ran together mid-sentence. The divider is **closed**
|
||||
and does not say what the subagent said: that is recorded as the subagent's
|
||||
own transcript's closing text and belongs there, not repeated in its
|
||||
parent's. Opening it shows the report anyway, and a backgrounded *command*
|
||||
— which has no transcript of its own — names itself from its summary and has
|
||||
nothing left to open. `./ui-sandbox.sh` plus `/subagent 8` in an echo session
|
||||
is the whole rig; the helpers stagger a second apart so each report and the
|
||||
reply to it are legible.
|
||||
- **Nothing subagent-specific goes in the main agent's transcript** unless a
|
||||
subagent sends it a real message that wakes it — which is the peer path, and
|
||||
already has a row. A row per finished background task was tried and was a
|
||||
screenful of dividers about work nobody was asking after, one of them a whole
|
||||
shell command. A subagent's report is its own transcript's closing text and
|
||||
is read in the subcard.
|
||||
- **Two replies that meet are separated by a `TurnBreak`** — a hairline, no
|
||||
words. The reply that follows a turn boundary is a **new** message: the fold
|
||||
refuses to grow a settled reply, and without that the two ran together
|
||||
mid-sentence. `./ui-sandbox.sh` plus `/subagent 3` in an echo session is the
|
||||
whole rig; the helpers stagger a second apart so each reply is its own.
|
||||
- **Whether work is outstanding has two sources and needs both.** The
|
||||
translator's `open_tasks` is what it watched start — the only thing that
|
||||
knows about a backgrounded command — and `Subagents::any_open` reads the
|
||||
|
||||
Reference in new issue
Block a user