harness: Busy ■ Stop stays on-canvas at ~390px via full button-footprint reserve (plan #782, issue #779) - #784
Conversation
…int reserve (plan #782, issue #779) Root cause (rect-proven): the trailing-icon reserve counted only TOUCH_H (40) per button, but each ButtonWidget's real tag-rect footprint includes dvui default padding (6) + margin (4) per side = TOUCH_H + 2*10 = 60. The reserve under-counted by 20px/button so the two Busy buttons overran the row and dvui's compactor crushed the trailing ■ flush into the right edge at ~390px (Stop un-hittable). Fix: define ICON_PAD(6)/ICON_MARGIN(4)/ICON_EDGE_W(10); iconCellW() = TOUCH_H + 2*ICON_EDGE_W = 60; iconPackW/iconReserveW/fieldW rebuilt on iconCellW(); pin every trailing ▶/■ button's padding/margin to those same constants so the arithmetic and the widget options can never drift. Tests: parameterize the layout helper to arbitrary width and add ~390px locks — busy empty-queue, idle narrow, busy unbreakable-line — asserting ■/▶ full tag rects stay on-canvas with real slack (never flush) and the field stays left of the icons. 600px rows: composer_layout now 11 pass. Docs: harness-limits.md Layout/Wrap-grow/Icon-button rows + iconCellW inlined (cap raise approved by operator 2026-08-22). Cloud ops: N/A (no Production mutate).
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
btipling
left a comment
There was a problem hiding this comment.
Adversarial review — PR #784
Verdict: PASS WITH NOTES
Repo: btipling/invincible
Scope: main ← plan/stop-on-canvas · 3 files · Busy ■ Stop on-canvas at ~390px (full button-footprint reserve)
Lenses run: L1, L3, L6, L8, L9 (skip: L2 no trust-boundary/API/secret files; L4 no GHA/artifact path change — zig → harness.wasm already green on the PR; L5 no poll/history/body-size; L7 no host pin; L6 DI/cost N/A — existing dvui_testing layout backend, not PGlite)
AGENTS.md read: yes (docs/feature-divide.md — Stop stays Wasm; no dual-chat)
Findings
| Sev | Lens | Finding | Break scenario | Refutation attempt | Confidence |
|---|---|---|---|---|---|
| Minor | L6 | Plan #782 tests 2 and 3 (Busy ~390 with queue Pause/Clear header; paused + · full) are not implemented. composer_layout.test.zig only paints paintComposerChrome at 390 (empty-queue, idle, unbreakable-line). docs/harness-limits.md Layout / Icon-button rows claim ▶/■ stay on-canvas “including with the queue-band Pause/Clear header visible.” |
A later queue-band header min-width growth is what tests 2/3 were written to catch. This PR’s 390 locks would stay green while the docs sentence is false. | Defender: queue band is a separate vertical band at the same avail.w (ui.zig); max_size_content.w = max_float_safe; host sizes the canvas, dvui min-size cannot widen it. Production leak path is bounded. Still an untested DoD row plus a living-doc overclaim. |
high |
| Minor | L8 | Living docs and new comments cite “plan #779”. Source bug is #779; the plan is #782. docs/harness-limits.md (Layout / Composer / wrap-grow / Icon-button) plus composer_chrome.zig / composer_layout.test.zig. Plan living-docs rule was timeless / no process artifacts. |
Next reader looks up issue #779 expecting the plan body (caps, test table) and finds the bug ticket instead. | Defender: operators say “#779” for the crush. The plan-issue number is still wrong in a file whose job is to be the timeless cap source. | high |
| Nit | L8 | composer_layout.test.zig module comment still documents field_w = avail_w − (TOUCH_H×n + 8) — the pre-fix formula. composer_chrome.zig still says icons “land post-reserve at TOUCH_H.” Arithmetic is iconCellW() (60). |
An agent “aligns” fieldW back to the test header and re-ships the #779 crush. |
Tests below the header call iconReserveW()/iconCellW(), so CI would catch a silent revert of the functions — unless someone “fixes” the tests to match the stale comment. |
high |
| Nit | L6 | assertBusyOnCanvasW accepts stop.w >= 0.8 * iconCellW (48 logical vs 60). The original crush was ~28 logical, so this still fails the reported bug, but it allows a 20% shrink before CI notices. |
A future pad/margin drift that cuts the cell to 50px stays green. | 0.8 is a subpixel/font fudge; gap >= 2*EPS is the real “not flush” lock. Soft, not a current miss. |
medium |
Residual risk
Did not execute zig build test-rich here (no Zig 0.16 on PATH). GHA zig → harness.wasm is green. ButtonWidget defaults on pin 4f810ef match ICON_PAD=6 / ICON_MARGIN=4; borderGet() is empty unless set, so tag-rect width = TOUCH_H + 2·10 is the right cell. Vertical pad+margin (button ~60 tall in a 44px idle chrome, gravity_y = 1.0) is pre-existing default chrome, not introduced. Operator tap-cancel on a real ~390 device was not driven. ui.zig:710 and native/harness/build.zig still describe TOUCH_H×n + 8 (out of diff).
Merge guidance
- PASS WITH NOTES: safe to merge from this attack. Fix the #782 vs #779 citations and the stale
TOUCH_H×n+8/ “lands at TOUCH_H” comments in the same file set when cheap; tests 2/3 are optional given band isolation. Do not treat the Goal 1 ~390 busy lock as missing — it is there and would fail the original crush.
What was not attacked
Live phone /harness tap on ■, zig build test-rich / test-rich-invariants in this session, queue_band layout at 390, dvui versions other than the harness pin, host chrome padding that could make the canvas slightly narrower than 390.
… formulas and tighten the ~390px cell lock
btipling
left a comment
There was a problem hiding this comment.
Adversarial review — PR #784 (round 2)
Verdict: PASS WITH NOTES
Repo: btipling/invincible
Scope: main ← plan/stop-on-canvas · 3 files · 2 commits (1e122ef + a16cd2f feedback follow-up)
Lenses run: L1, L3, L6, L8, L9 (skip: L2 no trust-boundary/API/secret files; L4 no GHA/artifact path change — zig → harness.wasm green on HEAD; L5 no poll/history/body-size; L7 no host pin; L6 DI/cost N/A — existing dvui_testing layout backend, not PGlite)
AGENTS.md read: yes (docs/feature-divide.md — Stop stays Wasm; no dual-chat)
Round 1 was PASS WITH NOTES (Minor L6: plan tests 2/3 unpainted; Minor L8: docs/comments cited plan #779; Nit L8: stale TOUCH_H×n+8 / “lands at TOUCH_H”; Nit L6: stop.w >= 0.8·cell). a16cd2f addresses the cheap notes. This pass re-attacks HEAD.
Round-1 items
| Round-1 | Status on a16cd2f |
|---|---|
| Minor L8 plan #779 vs plan #782 | Closed in the three PR files (docs, composer_chrome.zig, composer_layout.test.zig now say #782). Source bug #779 is still named only as the crush, which is correct. |
Nit L8 stale field_w = avail_w − (TOUCH_H×n + 8) and “land post-reserve at TOUCH_H” |
Closed in the PR files. Arithmetic comments now use iconCellW(). |
Nit L6 stop.w >= 0.8·cell |
Tightened to 0.9·cell (108 physical vs 120). Still catches the ~28-logical crush (~47% cell) without a rounding false-fail. |
Minor L6 plan tests 2/3 (Busy ~390 with queue Pause/Clear header; paused + · full) |
Unchanged. composer_layout.test.zig still only paints paintComposerChrome. |
Findings (HEAD)
| Sev | Lens | Finding | Break scenario | Refutation attempt | Confidence |
|---|---|---|---|---|---|
| Nit | L8 | docs/harness-limits.md Layout / Icon-button rows still claim ▶/■ stay on-canvas “including with the queue-band Pause/Clear header visible.” No test mounts queue_band. Living docs also still embed “plan #782” process artifacts (the follow-up corrected the number, did not drop the theater). |
A later header min-width growth is what tests 2/3 were written to catch; the sentence stays green. Next reader treats plan numbers as the cap source. | Defender (same as round 1): queue band is a separate vertical band at avail.w; max_size_content.w = max_float_safe; host sizes the canvas. Production leak path is bounded. Caps themselves (iconCellW = 60, pin ICON_PAD/ICON_MARGIN) are correct. |
high |
No new L1: follow-up is comments + citation + 0.8 → 0.9. iconCellW / fieldW / the three button padding/margin pins are unchanged. Vendored ButtonWidget defaults remain padding=6 / margin=4 / empty borderGet(), so the 60 px cell still matches tag-rect width.
Residual risk
Did not run zig build test-rich here. GHA zig → harness.wasm is green on a16cd2f. Out of diff (not this PR’s files): ui.zig:710 and native/harness/build.zig still describe TOUCH_H×n + 8 — a later agent could “align” those comments backward; the layout tests would still catch a silent fieldW revert. Operator tap-cancel on a real ~390 device was not driven. Vertical pad+margin (button ~60 tall in 44 px idle chrome) remains pre-existing default chrome.
Merge guidance
- PASS WITH NOTES: safe to merge from this attack. Round-1 Goal 1 ~390 busy lock is intact and tighter. Tests 2/3 remain optional given band isolation; dropping “plan #782” from living docs is cosmetic.
- Do not treat the missing queue-header paint as a Goal 1 miss — empty-queue + unbreakable-line at 390 still fail the original crush.
What was not attacked
Live phone /harness tap on ■, test-rich / test-rich-invariants in this session, queue_band layout at 390, dvui versions other than the harness pin.
…m + plan-#782 theater from living docs (L8 Nit, round 2)
|
Round-2 L8 Nit resolved in
Docs-only so no Zig/TS gates apply. |
btipling
left a comment
There was a problem hiding this comment.
Adversarial review — PR #784 (round 3)
Verdict: PASS WITH NOTES
Repo: btipling/invincible
Scope: main ← plan/stop-on-canvas · 3 files · 3 commits (HEAD 59f80ce — docs-only follow-up)
Lenses run: L1, L3, L6, L8, L9 (skip: L2 no trust-boundary/API/secret files; L4 no GHA/artifact path change — zig → harness.wasm green on HEAD; L5 no poll/history/body-size; L7 no host pin; L6 DI/cost N/A — existing dvui_testing layout backend, not PGlite)
AGENTS.md read: yes (docs/feature-divide.md — Stop stays Wasm; no dual-chat)
Round 1/2 were PASS WITH NOTES. 59f80ce is docs-only. Production iconCellW / fieldW / the three button padding/margin pins are unchanged from a16cd2f.
Round-2 items
| Round-2 | Status on 59f80ce |
|---|---|
| Nit L8 docs claimed on-canvas “with the queue-band Pause/Clear header visible”; living docs embedded “plan #782” | Closed. Layout / Composer / wrap-grow / Icon-button rows dropped the untested header clause and the plan-number theater. Caps remain inline (iconCellW = TOUCH_H + 2·(pad 6 + margin 4)). |
Plan tests 2/3 (queue header / paused+· full) unpainted |
Unchanged, accepted residual. Composer is a separate vertical band at avail.w; host sizes the canvas. Docs no longer claim that lock. |
Findings (HEAD)
None that survive refutation. Docs-only delta does not reintroduce the #779 crush, the TOUCH_H-only reserve, or a dual-chat path.
Residual risk
Did not run zig build test-rich here. GHA zig → harness.wasm is green on 59f80ce. Out of this PR’s files: ui.zig:710 and native/harness/build.zig still describe TOUCH_H×n + 8 — a later agent could “align” those comments; the composer_layout ~390 locks would still fail a silent fieldW revert. stop.w >= 0.9·cell still allows a 10% shrink (the gap >= 2*EPS lock is the “not flush” assertion). Operator tap-cancel on a real ~390 device was not driven. Zig comments in composer_chrome.zig still cite plan #782 — fine for implementation notes, not living docs.
Merge guidance
- PASS WITH NOTES: safe to merge from this attack. Goal 1 ~390 busy lock is intact (
assertBusyOnCanvasW+ unbreakable-line). Round-2 living-doc overclaim is gone. - Do not treat missing queue-band paint as a Goal 1 miss.
What was not attacked
Live phone /harness tap on ■, test-rich / test-rich-invariants in this session, queue_band layout at 390, dvui versions other than the harness pin.
Closes #779 (via plan #782). Human cap-approval recorded 2026-08-22.
What
While a turn is Busy the composer's trailing icon pack is ▶ enqueue + ■ Stop. On a ~390px phone-width canvas the ■ was crushed flush into the right edge (tag rect slid past
win.w) — un-hittable, so the operator can't tap-cancel the in-flight turn on the width they actually use.Root cause (rect-proven, not assumed): the trailing-icon reserve counted only
TOUCH_H(40) per button, but each ButtonWidget's real tag-rect footprint includes dvui's default padding (6) + margin (4) per side →TOUCH_H + 2·10 = 60. Reserve under-counted by 20px/button, so the two Busy buttons overran the row and dvui's horizontal compactor crushed the rightmost ■ off-canvas.Fix: reserve the FULL button footprint —
ICON_PAD(6)/ICON_MARGIN(4)/ICON_EDGE_W(10),iconCellW() = TOUCH_H + 2·ICON_EDGE_W = 60,fieldW = avail_w − (n·iconCellW + 8)— and pin every trailing ▶/■ button's padding/margin to those same constants so arithmetic and widget options can never drift.Cap raise (human-approved)
The trailing-icon reserve raises
TOUCH_H×n + 8(88 busy / 48 idle) →iconCellW×n + 8(128 busy / 68 idle), +20px/icon, narrowing the message field at all widths (idle 552→532, busy 512→472 @ 600px). Approved by operator 2026-08-22.TOUCH_H/SUBMIT_CAP/MAX_ITEMSare NOT raised.Tests
composer_layout11 pass — new ~390px locks: busy empty-queue, idle narrow, busy unbreakable-line — asserting ■/▶ full tag rects stay on-canvas with real slack (never flush) and field stays left of icons.Gates (all green locally)
zig fmt --check·zig build test-rich(exit 0) ·zig build test-rich-invariants·zig build harness -Doptimize=Debug.Ops
Cloud ops N/A — no Production mutate. Docs:
docs/harness-limits.mdupdated in the same PR.