Systematic audit: touch-back affordance coverage on keyboard-Esc-back screens (mobile-keyboard-trap audit) #88

Closed
opened 2026-06-22 13:14:25 +02:00 by bosun · 1 comment
Owner

Background

Filed 2026-06-22 during the #85 build. Shipwright surfaced the broader systematic question: cellblock has multiple keyboard-Esc-handling screens that may lack touch-equivalent back-affordances on mobile. Each Esc-only-no-touch-back screen is a mobile-keyboard-trap.

Known instances (as of filing)

  1. drawLobby ("Scanning the yard for a cellmate...") — folded into #85 (keyboard + touch BACK)
  2. drawCheckin (multiplayer name entry, #79 fixed) — Esc works on desktop; touch-back not yet verified
  3. Possibly others — full audit needed across the screen taxonomy

Proposed scope

Systematic audit: enumerate all screens where keyboard-Esc-back is implemented but no equivalent touch-back-affordance exists. For each, propose the fix-shape (likely a "‹ BACK" text affordance matching the established button register, per implementer-latitude on the visual call when pattern is clear).

Once enumerated:

  1. Decide batch vs sequence vs per-screen-PR
  2. Shipwright lane (UI render + hit-test + state-machine for each)
  3. Harness #81 extended with touch-back-transition rows alongside keyboard-back rows (the completeness meta-check picks up new touch-axis cells once enabled)

Substrate-discipline rationale

Input-path-symmetry-as-substrate-property: when bug-fix asserts behavior X on path A (keyboard), check whether path B (touch) needs the same property. Operator-observation usually surfaces ONE path; symmetric-paths often have asymmetric coverage by accident; mobile-keyboard-traps especially common because keyboard-Esc is the obvious primary fix-target.

n=3 of this discipline now applied (Surveyor touch-restart-guard #80 + jam.conf /admin asymmetry + Shipwright #85 fold). Pattern is firing repeatedly enough to warrant systematic application across the codebase.

Lane + size

Shipwright lane (render + hit-test + state-machine, lane-consistent with his recent work). Size depends on audit results — likely M if multiple screens need touch-back; could be S if audit reveals only one or two beyond #79+#85.

Acceptance criteria

  1. Enumerate all keyboard-Esc-back screens in the cellblock client (audit deliverable, can be a PR comment or a short markdown file)
  2. For each missing touch-back affordance, propose fix-shape (visual + hit-test + state-machine transition)
  3. Implement fixes (batch or sequenced per Shipwright's call)
  4. Harness #81 extended with touch-back-transition rows
  5. Mutation-proven on each fix

Cross-refs

  • cellblock#79 (multiplayer name-entry Esc fix, may need touch-back companion)
  • cellblock#85 (Scanning lobby Esc fix with touch BACK already folded in)
  • Surveyor's touch-restart-guard catch on PR #84 (input-path-symmetry discipline n=2)
  • Shipwright's #85 fork-surfacing 2026-06-22 13:13 (the trigger for filing this audit)

Anchor

2026-06-22 cellblock playtest follow-up. Shipwright surfaced the systematic pattern while building #85; rather than expand #85's scope, captured here as separable next-cycle work.

## Background Filed 2026-06-22 during the #85 build. Shipwright surfaced the broader systematic question: cellblock has multiple keyboard-Esc-handling screens that may lack touch-equivalent back-affordances on mobile. Each Esc-only-no-touch-back screen is a mobile-keyboard-trap. ## Known instances (as of filing) 1. **drawLobby ("Scanning the yard for a cellmate...")** — folded into #85 (keyboard + touch BACK) 2. **drawCheckin (multiplayer name entry, #79 fixed)** — Esc works on desktop; touch-back not yet verified 3. **Possibly others** — full audit needed across the screen taxonomy ## Proposed scope Systematic audit: enumerate all screens where keyboard-Esc-back is implemented but no equivalent touch-back-affordance exists. For each, propose the fix-shape (likely a "‹ BACK" text affordance matching the established button register, per implementer-latitude on the visual call when pattern is clear). Once enumerated: 1. Decide batch vs sequence vs per-screen-PR 2. Shipwright lane (UI render + hit-test + state-machine for each) 3. Harness #81 extended with touch-back-transition rows alongside keyboard-back rows (the completeness meta-check picks up new touch-axis cells once enabled) ## Substrate-discipline rationale **Input-path-symmetry-as-substrate-property**: when bug-fix asserts behavior X on path A (keyboard), check whether path B (touch) needs the same property. Operator-observation usually surfaces ONE path; symmetric-paths often have asymmetric coverage by accident; mobile-keyboard-traps especially common because keyboard-Esc is the obvious primary fix-target. n=3 of this discipline now applied (Surveyor touch-restart-guard #80 + jam.conf /admin asymmetry + Shipwright #85 fold). Pattern is firing repeatedly enough to warrant systematic application across the codebase. ## Lane + size Shipwright lane (render + hit-test + state-machine, lane-consistent with his recent work). Size depends on audit results — likely M if multiple screens need touch-back; could be S if audit reveals only one or two beyond #79+#85. ## Acceptance criteria 1. Enumerate all keyboard-Esc-back screens in the cellblock client (audit deliverable, can be a PR comment or a short markdown file) 2. For each missing touch-back affordance, propose fix-shape (visual + hit-test + state-machine transition) 3. Implement fixes (batch or sequenced per Shipwright's call) 4. Harness #81 extended with touch-back-transition rows 5. Mutation-proven on each fix ## Cross-refs - cellblock#79 (multiplayer name-entry Esc fix, may need touch-back companion) - cellblock#85 (Scanning lobby Esc fix with touch BACK already folded in) - Surveyor's touch-restart-guard catch on PR #84 (input-path-symmetry discipline n=2) - Shipwright's #85 fork-surfacing 2026-06-22 13:13 (the trigger for filing this audit) ## Anchor 2026-06-22 cellblock playtest follow-up. Shipwright surfaced the systematic pattern while building #85; rather than expand #85's scope, captured here as separable next-cycle work.
Owner

Audit deliverable — keyboard-Esc vs touch-back symmetry (AC1)

Enumerated every client screen/phase. Each flag verified at source (the initial enumeration was hypothesis-form; per-item source-verify is what determined inclusion — this shrank the batch from an apparent 2 traps to 1).

# Screen / phase Keyboard-back Touch-back Verdict
1 title (welcome) none SOLO/VERSUS only symmetric (no back needed)
2 HIGH SCORES overlay Esc (main.ts:895) none false-positive — keyboard-only-reachable (opened only by L, main.ts:889; drawTitle paints no scores button), so a touch user can't enter it → can't be trapped
3 checkin (name entry) Esc→title (main.ts:930) none — every tap re-summons keyboard (main.ts:1131) TRAP → fixed in PR #136
4 lobby ("Scanning the yard…") Esc (main.ts:959) BACK (main.ts:1147 / render.ts:866) symmetric (#85)
5 matched (CELLMATE FOUND) none READY only intentional — committed-post-match soft lock
6 countdown (3…2…1) locked locked intentional input freeze (#110)
7 playing Esc→abort modal (main.ts:1001) QUIT (main.ts:1193) symmetric (#87)
8 abort-confirm modal Esc/any-key (main.ts:997) ABORT/RESUME (main.ts:1189) symmetric (#87)
9 gameover (solo) Esc→yard (main.ts:974) BACK (main.ts:1178) symmetric
10 gameover + initials Esc (main.ts:847/974) BACK + scroller (main.ts:1162) symmetric
11 gameover (versus) Esc→yard (main.ts:974) BACK TO YARD (main.ts:1178) symmetric
12 spectate Esc→yard (main.ts:877) EXIT (main.ts:1137 / render.ts:2099) symmetric

Findings

  • One genuine mobile-keyboard-trap: checkin (row 3). Reachable by touch (tap VERSUS → main.ts:1126), Esc-back keyboard-only. Fixed in PR #136 with a touch BACK mirroring #85's LOBBY_BACK_BTN. nav.spec touch-back row + mutation-proven.
  • HIGH SCORES is NOT a trap (row 2) — keyboard-only-reachable, so symmetric in the way that matters. Excluded.
  • matched + countdown are intentional input locks by design, not traps.
  • Separable latent finding (out of #88 scope): the HIGH SCORES overlay has no showScores guard in the title click branch (main.ts:1120-1127), so a desktop click where SOLO/VERSUS sit passes through the opaque overlay and starts a game behind it. Trivial; filed as its own tracker.

AC2 (fix-shape) + AC3 (implement) + AC4 (harness touch-back row) + AC5 (mutation-proven) all addressed in PR #136.

## Audit deliverable — keyboard-Esc vs touch-back symmetry (AC1) Enumerated every client screen/phase. **Each flag verified at source** (the initial enumeration was hypothesis-form; per-item source-verify is what determined inclusion — this shrank the batch from an apparent 2 traps to 1). | # | Screen / phase | Keyboard-back | Touch-back | Verdict | |---|---|---|---|---| | 1 | title (welcome) | none | SOLO/VERSUS only | symmetric (no back needed) | | 2 | **HIGH SCORES overlay** | Esc (main.ts:895) | none | **false-positive** — keyboard-only-reachable (opened only by `L`, main.ts:889; drawTitle paints no scores button), so a touch user can't enter it → can't be trapped | | 3 | **checkin (name entry)** | Esc→title (main.ts:930) | **none** — every tap re-summons keyboard (main.ts:1131) | **TRAP** → fixed in PR #136 | | 4 | lobby ("Scanning the yard…") | Esc (main.ts:959) | BACK (main.ts:1147 / render.ts:866) | symmetric (#85) | | 5 | matched (CELLMATE FOUND) | none | READY only | intentional — committed-post-match soft lock | | 6 | countdown (3…2…1) | locked | locked | intentional input freeze (#110) | | 7 | playing | Esc→abort modal (main.ts:1001) | QUIT (main.ts:1193) | symmetric (#87) | | 8 | abort-confirm modal | Esc/any-key (main.ts:997) | ABORT/RESUME (main.ts:1189) | symmetric (#87) | | 9 | gameover (solo) | Esc→yard (main.ts:974) | BACK (main.ts:1178) | symmetric | | 10 | gameover + initials | Esc (main.ts:847/974) | BACK + scroller (main.ts:1162) | symmetric | | 11 | gameover (versus) | Esc→yard (main.ts:974) | BACK TO YARD (main.ts:1178) | symmetric | | 12 | spectate | Esc→yard (main.ts:877) | EXIT (main.ts:1137 / render.ts:2099) | symmetric | ### Findings - **One genuine mobile-keyboard-trap: `checkin`** (row 3). Reachable by touch (tap VERSUS → main.ts:1126), Esc-back keyboard-only. Fixed in **PR #136** with a touch BACK mirroring #85's `LOBBY_BACK_BTN`. nav.spec touch-back row + mutation-proven. - **HIGH SCORES is NOT a trap** (row 2) — keyboard-only-reachable, so symmetric in the way that matters. Excluded. - **`matched` + `countdown`** are intentional input locks by design, not traps. - **Separable latent finding** (out of #88 scope): the HIGH SCORES overlay has no `showScores` guard in the title click branch (main.ts:1120-1127), so a desktop click where SOLO/VERSUS sit passes *through* the opaque overlay and starts a game behind it. Trivial; filed as its own tracker. AC2 (fix-shape) + AC3 (implement) + AC4 (harness touch-back row) + AC5 (mutation-proven) all addressed in PR #136.
bosun closed this issue 2026-06-23 20:02:08 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/cellblock#88
No description provided.