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,68 @@
|
||||
# Task 02 — The hardware contract: what the gate cannot see
|
||||
|
||||
**Phase:** `01_verification_gate` · **Source:** `TODO.md` — (foundation; `AGENTS.md`
|
||||
"Verification standard": *"A feature that lives on the device is not done when the source
|
||||
builds — it is done when the device is running it and something observed it."*)
|
||||
**Story:** `n/a`
|
||||
|
||||
## Objective
|
||||
|
||||
Make the device-only half of this roadmap explicit, runnable and non-blocking: a probe that
|
||||
reports what hardware is reachable right now, and a file that pairs every device-only claim
|
||||
with the exact command that would confirm it — so a unit running unattended never hangs on
|
||||
a board and never claims a device result it did not observe.
|
||||
|
||||
## Work
|
||||
|
||||
1. `.agents/HW_VERIFICATION.md` — three sections:
|
||||
- **Baseline** (measured, from task 01's gate run): `bridge RAM 26.7% (87 592 B) /
|
||||
Flash 36.1% (1 135 293 B)`, `console RAM 16.8% (55 200 B) / Flash 33.6% (1 056 081 B)`,
|
||||
`3406 host checks`. Later phases quote a delta against these numbers.
|
||||
- **Claims that need hardware**, each with its command and its expected observation, at
|
||||
least: keystroke/chord delivery and *which* keys a chord really was
|
||||
(`python3 tools/watch_target.py` on the target); served-page byte agreement
|
||||
(`curl -sk https://keyrelay.local/ | wc -c` vs the gate's page count — `http` until
|
||||
phase 02 lands, `https -k` after); TLS handshake + the SHA-256 fingerprint printed once
|
||||
on the serial console; takeover actually releasing the incumbent's held keys
|
||||
(`watch_target.py` must show key-up *before* the new session's first key); the mobile
|
||||
soft keyboard and touch pad (a phone on the board's AP, `watch_target.py` for both the
|
||||
characters and the pointer deltas).
|
||||
- **The blocking rule**: a unit attempts a device step **at most once**, wrapped in
|
||||
`timeout`, and writes the outcome — `ok`, `skipped (no device)`, or `failed: …` — with
|
||||
the command it ran into the section's table. It never loops on a port, never re-flashes
|
||||
to "see if it works", and never leaves the board in ROM download mode without saying so
|
||||
in the report (`tools/to_bootloader.py` drops it there deliberately; a power cycle is
|
||||
the only way back and nobody may be there to do it).
|
||||
2. `tools/hw_probe.sh` (executable, `set -uo pipefail`, no side effects) — prints one line
|
||||
per fact and **always exits 0** (it informs, it does not gate):
|
||||
`/dev/ttyACM*`/`/dev/ttyUSB*` present?; `keyrelay.local` resolves?; `https` reachable
|
||||
(`curl -sk -m 2 -o /dev/null -w '%{http_code}'`)?; `http` reachable and does it redirect?;
|
||||
`uv` on PATH?; `node` on PATH?; is a `watch_target.py`-capable evdev device visible
|
||||
(informational only). Nothing is opened on a serial port except a `test -e`/`test -r`
|
||||
check — opening it toggles DTR/RTS and resets the board, so the probe must not.
|
||||
3. `.agents/validate.sh` — append `bash tools/hw_probe.sh` as the **last, non-affecting**
|
||||
line (its exit status is deliberately not folded into `rc`), with a comment saying why:
|
||||
it is context for whoever reads the gate output, not a check.
|
||||
4. `README.md` — no behaviour change yet; only if the "End-to-end verification" section
|
||||
contradicts what the probe just printed, fix the stale line. Do not restructure it here.
|
||||
|
||||
- ASSUMPTION: at execution time a board *may* be attached and reachable but nobody is
|
||||
watching it, so "board available" is treated as best-effort. Any phase that needs an
|
||||
on-target second machine (`watch_target.py`) records `skipped (no device)` rather than
|
||||
inventing a result. This is the user-facing cost of running the roadmap unattended; the
|
||||
file is where they pick those checks up.
|
||||
|
||||
## Testing & Quality
|
||||
|
||||
- `bash tools/hw_probe.sh` exits 0 with and without a board, with and without `uv`, from any
|
||||
cwd; it never blocks (every probe has a `-m`/`timeout`).
|
||||
- The gate still passes with the probe line added, and its output cannot flip `rc`.
|
||||
- `shellcheck`-clean if `shellcheck` is installed; otherwise `-n` syntax check in the report.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
- [ ] `bash tools/hw_probe.sh` prints the six facts and exits 0 (paste its output).
|
||||
- [ ] `.agents/HW_VERIFICATION.md` covers every phase 02–05 device claim listed above, each
|
||||
with command + expected observation + the rule about one attempt.
|
||||
- [ ] `bash .agents/validate.sh` still exits 0.
|
||||
- [ ] Full test suite green; no firmware source touched.
|
||||
Reference in New Issue
Block a user