chore(agent): phase roadmap from TODO.md, 5 phases
The four open items in TODO.md become an executable pipeline: 01 the verification gate (host suites + sanitiser + both firmware envs, and the hardware contract so no unit blocks on a board nobody is holding), 02 HTTPS and wss:// with an identity the board generates itself into NVS, 03 session takeover that always lands disarmed, 04 a responsive page whose safety statements are pinned before they are trimmed, 05 the phone as a controller (press-and-hold pad, soft keyboard, modifier latches over a new Q= frame). TODO.md is cleared to its empty title; the items live in .agents/phases/ now. AGENTS.md gains the five protocol rules and nothing else. LLM-Generated: true
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Task 01 — Touch pad: the capture is the finger
|
||||
|
||||
**Phase:** `05_mobile_controller` · **Source:** `TODO.md:5` — "Needs to be mobile compatible
|
||||
— … **Mobile trackpad for touch trackpad.**"
|
||||
**Story:** `n/a`
|
||||
|
||||
## Objective
|
||||
|
||||
`#mPad` becomes a touch pad: press and hold it and the target's pointer moves with your
|
||||
finger, drag two fingers to scroll, and the moment the touch ends the movement stops and every
|
||||
button lets go. Pointer Lock does not exist for touch, so the capture is the touch itself.
|
||||
|
||||
## Work
|
||||
|
||||
1. `src/web_page.h`, the mouse block:
|
||||
- `touchstart` on `#mPad`: requires `armed` and `mouseAvailable()` (`s.mouse === 1`) — the
|
||||
same two gates as `takeMouse()`, and the same `E10`/`E11` refusal path if the board
|
||||
disagrees. Sets `mTouchActive`, records the anchor point, and takes **no** button.
|
||||
- `touchmove`: compute the delta from the previous sample, feed the existing movement
|
||||
pipeline (the code behind `flushMouse()`) so the ±127 cap and the multi-frame split are
|
||||
the ones already tested — do not write a second splitter. Coalesce per report the way
|
||||
`mousemove` does, and drop movement when there is no link rather than queueing it
|
||||
(the page's existing rule: a queue of pointer motion delivered after you stopped moving
|
||||
is the pointer version of a stuck key).
|
||||
- Two-touch drag → wheel/pan through the same quantiser the desktop `wheel` handler uses
|
||||
(notches with the remainder carried), not movement. `touchmove` with two fingers must not
|
||||
also emit dx/dy.
|
||||
- `touchend`/`touchcancel`, and `blur`/`visibilitychange`/disarm/link loss: end the capture,
|
||||
`dropMouse()` (which releases every button through the funnel), reset the anchor. `touchcancel`
|
||||
is the browser taking the gesture away — incoming call, notification shade, a palm — and it
|
||||
must land exactly like lifting the finger.
|
||||
- A visible button row beside the pad: **Left / Right / Middle**, held while pressed
|
||||
(`touchstart` down, `touchend` up), carrying the existing `MOUSE_BTN` bits. Tap on the pad
|
||||
itself never clicks. The row is 44 px and shows which bits are down, so "left is held" is
|
||||
a thing you can see before you ask what is stuck.
|
||||
- The pad's label changes with state (`not captured` / `captured — move to move, lift to
|
||||
release`) since a phone has no cursor to indicate either.
|
||||
2. `refreshMouseUi()` / `paintMouse()` / `mouseAvailable()` — teach them the touch state so
|
||||
the pills say what is true. `mCaptured` (Pointer Lock) and `mTouchActive` are different
|
||||
states that must render distinctly and never both claim the pointer.
|
||||
3. Keep the desktop path byte-for-byte identical: `mousemove`, the Pointer Lock request,
|
||||
`Esc`, `wheel` on a mouse — phase 04's assertions and today's `test_page.js` mouse checks
|
||||
must stay green without edit.
|
||||
4. `tests/test_page.js` — extend the shim for multi-point touch and add: capture requires
|
||||
armed + `mouse:1`; a drag produces one `M=` per flush with no idle frames; a large drag
|
||||
splits with the net displacement exact; two fingers produce wheel/pan and no dx/dy;
|
||||
`touchend` and `touchcancel` each release every button and stop movement; button-row bits
|
||||
equal `MOUSE_BTN`; every emitted frame parses with the firmware's own parser.
|
||||
5. `README.md` — Controller page: the pad row of the element table describes the touch
|
||||
behaviour; "What capture does and does not do" gains the touch sentence (this is
|
||||
elaborated properly in task 04 — here, only what this task changes).
|
||||
|
||||
- ASSUMPTION: one finger moves, two fingers scroll, and clicking is an explicit held button
|
||||
rather than a tap. Tap-to-click on a pad whose whole job is movement produces clicks the
|
||||
operator did not ask for, and on a remote keyboard a click the target did not expect is the
|
||||
worst class of surprise.
|
||||
- ASSUMPTION: no "tap-and-hold to drag" (holding a button while moving). It needs a second
|
||||
simultaneous gesture and any mis-timing strands a button on the target; the button row gives
|
||||
the same capability with visible state.
|
||||
- ASSUMPTION: scale of finger-delta to HID delta is 1:1 (one CSS pixel → one report unit) at
|
||||
first. If it feels slow on hardware, the tuning knob goes in `config.h`-style naming on the
|
||||
page side with the measured value in the comment — the board must not invent a pointer speed
|
||||
of its own.
|
||||
|
||||
## Testing & Quality
|
||||
|
||||
- `node tests/test_page.js`: the new touch checks pass and the existing mouse checks are
|
||||
unmodified (prove it: the diff of that test file adds, it does not change, mouse assertions).
|
||||
- `bash .agents/validate.sh` green; `test_proto.cpp`, `test_mouse.cpp`, `test_output.cpp`
|
||||
untouched.
|
||||
- Device (best effort, one attempt): a phone on the board's AP — movement lands, lift stops
|
||||
it, and `watch_target.py` shows no stuck button across 20 press/release cycles.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- [ ] Press-and-hold on the pad moves the target's pointer; lifting stops it and releases
|
||||
every button (observed, or recorded `skipped (no device)` with the commands).
|
||||
- [ ] Two-finger drag scrolls and never moves the pointer.
|
||||
- [ ] Left/Right/Middle are held-while-pressed and visible; tap on the pad clicks nothing.
|
||||
- [ ] Desktop Pointer Lock path unchanged and still covered by the pre-existing checks.
|
||||
- [ ] Full test suite green.
|
||||
Reference in New Issue
Block a user