Skip to content

harness: Busy ■ Stop is pushed off the right edge of the canvas #779

Description

@btipling

Summary

Operator report: the composer Stop (■) is pushed off the right edge of the screen. It sits in the trailing icon pack next to the composer field (Busy: ▶ enqueue + ■ Stop). The button is still in the widget tree — it is not hittable because it is past the viewport’s right edge.

That is a product break: while a turn is Busy the only in-canvas cancel is that ■ (and Esc). Off-canvas Stop means the operator cannot tap-cancel on the width they are actually using.

Current baseline (live code)

Claim Path / symbol Notes
Stop is the Busy trailing ■ native/harness/src/ui/composer_chrome.zig ~197–210 Idle = one ▶; Busy = ▶ then ■. gravity_y = 1.0, min_size_content TOUCH_H×TOUCH_H (40).
Icons must stay on-canvas plan #737 / source #734 Field lives on a reserved sub-rect fieldW(avail_w, busy) = avail_w − (TOUCH_H×n + 8) so a long unbreakable line cannot steal the icon columns.
Layout tests native/harness/src/composer_layout.test.zig Lock wrap / ▶ / ■ placement and stop.x + stop.w ≤ win.w. Window is WIN_LW = 600 only — no ~390 px row.
Docs docs/harness-limits.md Touch / mobile “Full-bleed canvas … no horizontal overflow expected.” Composer chrome: trailing icon-only buttons.
Queue band sits above the composer ui.zig queue_band.paint(…, avail.w) then paintComposerChrome Header is a horizontal box: {n} queued + optional · full / · paused + Pause (min 64) + Clear (min 56). max_size_content.w = max_float_safe (queue_band.zig ~102). Pause landed in #778 (plan #777), now on main.

Two seams are in play (do not assume one without a layout-rect proof):

  1. Composer chrome (harness: composer textEntry grows horizontally and squeezes ▶/■ off-canvas before wrapping #734 class) — Busy 2-slot reserve is 2×TOUCH_H + 8. Button tag rects include default margin. Tests never run at ~390 px. A too-small reserve or a field min-width floor (min_size_content.w = 120 on the textEntry) can slide ■ past win.w on a phone-width canvas.
  2. Queue-band header (feat(harness): in-canvas Pause for the submit queue (plan #777) #778) — new Pause column on the row immediately above the composer. If that header’s min-size grows the window/canvas wider than the visible viewport, composer is laid out at the wide avail.w and ■ sits at the right of that width — off-screen.

Goals

# Goal Success signal
1 Busy ■ Stop is fully inside the visible canvas stop.x ≥ 0 and stop.x + stop.w ≤ viewport.w at ~390 px and at 600+ px (left rail open or closed)
2 Busy ▶ enqueue stays on-canvas too Same inequality for the send tag; ▶ left of ■, no overlap with the field
3 Idle ▶ Send stays on-canvas No regression of the #737 idle lock
4 Queue non-empty (Pause + Clear visible) does not push Stop off-screen Same as (1) with n>0, paused and unpaused, including · full
5 Stop still cancels only the in-flight turn Hit target works; #757 / #760 queue semantics unchanged

Non-goals / out of scope

Testing

# Case Layer Expected
1 Busy, canvas ~390 px, empty queue composer_layout (or equivalent testing-backend rects) ■ fully on-canvas
2 Busy, ~390 px, queue non-empty (Pause + Clear on the header) harness layout ■ still on-canvas; queue header does not widen the window past the viewport
3 Busy, ~390 px, paused + · full harness layout worst-case header; Stop still visible
4 Idle ▶ at ~390 and 600 (left rail 40 / 220) existing #737 tests + a narrow row ▶ on-canvas
5 Operator: Busy turn on a phone-width /harness browser ■ tappable, cancels the turn

Gates: zig build test-rich (layout tests) + zig build harness -Doptimize=Debug. The interaction itself is also operator-gated at ~390 px.

Cloud ops

N/A — no Production mutate. Layout-only harness chrome.

Living docs

Surface Change
docs/harness-limits.md Layout / composer chrome + Touch / mobile Restate: trailing ▶ / ■ stay fully on-canvas; no horizontal overflow at ~390 px (including when the queue-band Pause/Clear header is visible)
README / SECURITY / .env.example N/A

Refs plan #737 / source #734 (icons must not leave the viewport) · PR #778 (Pause/Clear on the queue-band header) · plan #777

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingharnessHarness / agent UIui

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions