Summary
Enqueueing a follow-up while Busy (▶ / Ctrl+Enter) does not bring the new queued row into view. The composer may clear, but the canvas stays where it was, so it looks like the send was a no-op.
Idle send already follows: a new user row lands in the transcript and stick-to-bottom runs. Queue appends have no equivalent follow.
Observed
- Start a turn so the harness is Busy.
- Scroll the transcript up (or already have 3+ items in the queue band).
- Type a follow-up and ▶ / Ctrl+Enter.
Actual: composer text disappears (or stays if the queue is full). No new transcript row. The queue band either appears off the operator’s focus at the bottom chrome, or the new FIFO row sits below the 3-row window. Nothing in the scrolled view changes.
Expected: the newly queued item is on-screen — same “I sent something” feedback as idle send.
Likely seam
Submit-queue band (native/harness/src/ui/queue_band.zig, plan #664):
- Rows paint FIFO
0..n-1 (newest last).
- Band height is header +
min(n, QUEUE_BAND_MAX_ROWS) (QUEUE_BAND_MAX_ROWS = 3). Extra rows live in state.queue_list_scroll.
- Nothing calls
scroll.scrollToBottom(&state.queue_list_scroll) on enqueue. Item 4+ is appended below the visible window.
Transcript stick-to-bottom (native/harness/src/ui.zig, plan #135 / #131 / #251) only follows user_sent / hydrate / near-bottom. Enqueue does not change msg_count, so a scrolled-up transcript never moves. The band is outside the transcript scroller (above the composer); if the operator’s eyes are on old messages, the only tell is a cleared composer.
Full-queue reject already paints · full in EMBER (#666). The empty “nothing happened” case is a successful enqueue with no follow.
Goal
- After a successful enqueue, the new queue row is visible without the operator hunting for it.
- At minimum:
queue_list_scroll follows the newest row when n > QUEUE_BAND_MAX_ROWS.
- Also worth doing: treat enqueue like send for transcript follow (scroll the transcript to bottom) so attention is at the live turn + queue chrome. Idle send already does this for
user_sent.
- Failed enqueue (blank / full) must stay a no-op on scroll — composer text stays,
· full is the signal.
Non-goals
- Putting queued text into the transcript ring (FIFO stays Wasm-ephemeral, above the composer).
- Changing
QUEUE_BAND_MAX_ROWS / MAX_ITEMS (16).
- Auto-promote / drain behavior.
Related
native/harness/src/ui/queue_band.zig — list + queue_list_scroll, no follow on append
native/harness/src/ui/state.zig — queue_list_scroll
native/harness/src/ui/scroll.zig — scrollToBottom (used for transcript only)
native/harness/src/ui.zig — stick-to-bottom; user_sent does not include enqueue
native/harness/src/ui/composer.zig — submitOrEnqueue → enqueueFromUi
docs/harness-limits.md — Submit queue: compact list, extra rows scroll
Suggested next: enqueue a 4th item with the list scrolled to the top; then enqueue the first item of a turn while the transcript is scrolled up. Both should leave the new row on-screen.
Summary
Enqueueing a follow-up while Busy (▶ / Ctrl+Enter) does not bring the new queued row into view. The composer may clear, but the canvas stays where it was, so it looks like the send was a no-op.
Idle send already follows: a new user row lands in the transcript and stick-to-bottom runs. Queue appends have no equivalent follow.
Observed
Actual: composer text disappears (or stays if the queue is full). No new transcript row. The queue band either appears off the operator’s focus at the bottom chrome, or the new FIFO row sits below the 3-row window. Nothing in the scrolled view changes.
Expected: the newly queued item is on-screen — same “I sent something” feedback as idle send.
Likely seam
Submit-queue band (
native/harness/src/ui/queue_band.zig, plan #664):0..n-1(newest last).min(n, QUEUE_BAND_MAX_ROWS)(QUEUE_BAND_MAX_ROWS= 3). Extra rows live instate.queue_list_scroll.scroll.scrollToBottom(&state.queue_list_scroll)on enqueue. Item 4+ is appended below the visible window.Transcript stick-to-bottom (
native/harness/src/ui.zig, plan #135 / #131 / #251) only followsuser_sent/ hydrate / near-bottom. Enqueue does not changemsg_count, so a scrolled-up transcript never moves. The band is outside the transcript scroller (above the composer); if the operator’s eyes are on old messages, the only tell is a cleared composer.Full-queue reject already paints
· fullin EMBER (#666). The empty “nothing happened” case is a successful enqueue with no follow.Goal
queue_list_scrollfollows the newest row whenn > QUEUE_BAND_MAX_ROWS.user_sent.· fullis the signal.Non-goals
QUEUE_BAND_MAX_ROWS/MAX_ITEMS(16).Related
native/harness/src/ui/queue_band.zig— list +queue_list_scroll, no follow on appendnative/harness/src/ui/state.zig—queue_list_scrollnative/harness/src/ui/scroll.zig—scrollToBottom(used for transcript only)native/harness/src/ui.zig— stick-to-bottom;user_sentdoes not include enqueuenative/harness/src/ui/composer.zig—submitOrEnqueue→enqueueFromUidocs/harness-limits.md— Submit queue: compact list, extra rows scrollSuggested next: enqueue a 4th item with the list scrolled to the top; then enqueue the first item of a turn while the transcript is scrolled up. Both should leave the new row on-screen.