# StopWatch 0.8.0 development

Branch `0.8.0` starts at repaired 0.7.0 commit `ef4b944`. Main and the installed
0.7.0 Wi-Fi profiles are preserved. This document records implementation scope;
the 2026-10-07 physical acceptance results are recorded below.

## View

Settings has a dedicated View menu with Current, History, Back. Agent contains
Session, Model, Effort, Permissions, Voice Send and Speech as capabilities allow.
View uses A for previous/newer and B for next/older, including every screen of a
long message. Hold A returns to View; Hold B closes to the Shell.

Current reads the full native latest exchange; Codex includes the latest active
turn and its user/assistant messages. History reads recent completed exchanges
within the existing native scan budget (up to 64 messages / 32 Codex turns).
Reasoning, tool output and credentials remain excluded. UTF-8 text is fragmented
at 1000 bytes without truncating messages. Each response is below 4096 wire bytes.
`view-pagination` selects opaque bidirectional h2 cursors; older firmware keeps h1.

Gateway snapshots are connection/target/generation/scope bound, live in memory
for five minutes, and are bounded to eight snapshots of at most 2 MiB each.
Incoming updates cannot replace an open reader. Reopening refreshes its snapshot.
The watch retains three fragments and refetches evicted ones in either direction.
An eight-second request timeout offers retry instead of indefinite Loading.

## Volume

Device menu order is Brightness, Volume, Vibration, Touch, Back. Volume cycles
0–100% in 10% steps; B applies and saves it, Hold A discards the draft. Zero mutes.
Default and physical test baseline are 80%. The existing NVS byte is reused,
without changing the preference schema or Wi-Fi store. Codec changes occur on
the audio owner task so a Settings click cannot wait on a microphone read.

## Speech

Speech Mode retains OFF / MANUAL / AUTO_REPLY / AUTO_SUMMARY and Double A.
Read Screen pins the visible content on entering Settings. Playback is restored
through `speech_playback`, with the buffered transport described in protocol.md.
Quiet TTS is raised toward RMS 5000 with at most 6x gain and a 26000 peak
ceiling; loud audio and silence are unchanged. Source and codec byte counts/hashes
must agree. Physical loudness at 80% was confirmed after increasing this gain. Approval, recording, selection and disconnect preempt it.

The 2026-10-06 diagnosis proved an RX64 → RX32 → RX64 pass/fail/pass and traced
OOSEQ packet eviction / L2 buffer retention. It did not prove which network hop
caused the first missing packet. The candidate enables SACK, RX64, Wi-Fi/lwIP
PSRAM allocation, OOSEQ cap 0 and the existing 65535-byte receive window,
matching the diagnostic pass profile. Retention is bounded by that window and
the global RX64 pool. The physical test validates short and 11-second playback;
continuous multi-hour playback has not been tested.

## Codex quota

The inspected deployed Gateway had no periodic quota query: a two-second push
could repeat an old startup/event cache. 0.8.0 actively queries the existing
native account API every 15 seconds, with one concurrent call and a five-second
RPC deadline. A background connection task starts account reads independently of the selected
Agent, and retries every 15 seconds after a native disconnect. Reconnect and
native notifications refresh it as well. Late RPC
responses cannot overwrite a newer notification. Values older than 45 seconds
are unavailable. Bucket/window selection and remaining-percent semantics remain
unchanged. The user's exact 31% observation was not instrumented end to end.

## Validation status

Mac firmware host gate and production network/History dispatch gate pass.
Complete Linux Gateway tests pass: 261 pytest and 22 Node tests. ESP-IDF 5.5.4
build passes with zero warnings, CJK link coverage and vendor ABI checks.

Physical acceptance on 2026-10-07, ESP32-S3 28:84:85:43:a2:00, PangTiao WAN:

- App-only flash verified; partition table unchanged and both saved Wi-Fi
  profiles preserved. Installed version is 0.8.0-dev, 3,333,232 bytes,
  SHA256 `9c94ba272305ea08f1497d033b5de0d7888f18bdbe0022033cb9d3a9b67b8ca8`.
- User confirms Current/History load, A/B browse and Hold A return. Serial
  records 0.6–0.9-second fetches and continued paging beyond the three-page cache.
- Volume appears after Brightness. Saved 80% survives reset: slot 1, generation
  12; codec volume is applied after initialization.
- Short WAN Speech at 80%: 24 chunks, 166,202 bytes received/written, integrity
  1, 1.859-second playback. User confirms complete, continuous speech.
- After the quiet-source gain adjustment, a candidate-only provider wrapper
  repeats one actual TTS result six times to exercise the 64-frame credit window.
  137 chunks, 966,492 bytes received/written, integrity 1, 10.932-second playback;
  codec SHA256 `c0343a3ec988e373a3b3d18471580d563492b6dd3aa0dcbf810e9abe032fcde5`.
  User confirms all six repetitions complete, no stutter, suitable loudness at
  80%. Wrapper removed; every runtime source hash matches the verified export.
- Native quota cadence test makes three real account reads at 15.818 and
  15.000-second intervals. Physical testing exposed a missing startup connection
  when Pi was selected; the new background task fixes it and has a reconnect
  regression test. User confirms the Pi-target watch displays 20%, replacing --.

Gateway acceptance uses a reversible temporary systemd runtime override and an
independent private source directory. PrivateTmp is preserved; existing device
credentials are referenced in place. Persistent activation was explicitly approved and completed at 10:00 CST on
2026-10-07. Fixed release: `/home/lighthouse/.local/share/esp32-device-gateway/releases/0.8.0-451b4c5`.
Persistent override: `~/.config/systemd/user/device-gateway.service.d/zzzzz-stopwatch080.conf`.
The runtime-only test override is removed. Existing production target, project,
Speech and credential configuration is reused in place; no credentials copied.
Source is committed locally on 0.8.0; no push or main merge.

Rollback removes only that persistent override, then runs
`systemctl --user daemon-reload` and `systemctl --user restart device-gateway.service`.
Existing baseline overrides, source and Python runtime are retained. The installed
0.8.0-dev firmware remains on the watch.
