SIGN IN SIGN UP

A task keeps taking messages after a turn settles off the stream (#120)

* fix(console): a task keeps taking messages after a turn settles off the stream

A task took three turns and then silently took no more: the composer looked
enabled, Enter and Send did nothing, and no request left the tab until the page
was reloaded. The send latch collapses clicks landing in the same tick and is
released in send()'s finally, but that finally only runs when the POST stream
ends. A turn can settle without it, from the broadcast bus or the reconciliation
poll, while the stream stays open; the latch then outlives its turn and every
later message is dropped at the guard.

The conversation going idle is proof the turn is over, so the latch is released
there too. The double-click guard is unaffected: the clicks it collapses land
before any render, so no effect runs between them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* ci: start the checks on the bot-opened PR

* fix(console): a produced file is shown once, not once per delivery

A file the task produced rendered as two identical cards during the session,
and the "Download all" count said two; a reload showed one, because the turn
record holds one. The same citation reaches a tab twice: its own POST stream
renders it as it arrives, and the broadcast bus delivers that same event a
moment after the stream ended and its suppression was lifted. Both appended
blindly.

A file is identified by its container and id, so adding the one already shown
is now a no-op, on both paths.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(matrix): the artifact row judges the rendered cards against the record

The artifact scenario asked only whether SOME rendered card carried the
expected filename, so a file rendered twice passed as a produced artifact. The
console showed two cards for one produced file until a reload, and the matrix
could not see it in any column of any harness.

The cards a reader sees must BE what the turn stored: same names, same count.
A harness that produces files is now measured on both halves, and the row fails
with the two lists side by side when they disagree.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: richard-epsilla <richard@epsilla.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
G
github-actions[bot] committed
7a58b8a9e1c10aa3da16aaa3ff3796a6bcfd943c
Parent: 528c37e
Committed by GitHub <noreply@github.com> on 9/7/2026, 9:17:54 PM