Rename VaultStateHandler to HomeStateHandler (home_state, AppState::Home)
The FSM state handler was misnamed — "vault" belongs to the storage/crypto layer
(src/vault/, VaultStore, VaultCrypto), whereas this handler is the post-unlock home
orchestrator (menu + settings + admin + device config + BLE hosts + cred-detail). Rename
it throughout: class VaultStateHandler -> HomeStateHandler; files
src/states/vault_state.{h,cpp} -> home_state.{h,cpp} (+ the mirror test test_vault_state ->
test_home_state); enum AppState::VaultMenu -> AppState::Home; the debug screen-name strings
"VAULT_MENU/..." -> "HOME/..."; the appStateName() label "VAULT_MENU" -> "HOME"; the
"requires VAULT_MENU" debug messages; and the FSM references in the docs, .github
skills/agents, and QA scripts. The GOTO debug command keeps "VAULT_MENU" as a back-compat
alias alongside the new "HOME".
The src/vault/ storage/crypto layer keeps "vault" (correct usage); the VaultMenuView /
vault_row_widgets / cred_row_cache helpers keep their names (they name the vault-contents
menu, still accurate). Pure rename, no logic change.
Verified: native 1168/1168, pio check clean, guards, full fleet -Werror (9 variants +
debug), and on-device QA on Stick S3 + M5Stack Gray (boot, PIN dial via PinEntryRenderer,
home menu nav, HOME/... state strings). Completes the vault-state god-object split:
HomeStateHandler is device-agnostic and ~30 methods / ~16 fields, under the Sonar
S1448/S1820 thresholds.
Claude-Session: https://claude.ai/code/session_01Y7Cy1HetRp6TZAUAeekN8X
Add "GPS time sync" settings action and progress overlay (HAS_GPS boards)
Settings -> Device gains a one-shot "GPS time sync" row on HAS_GPS boards
(DEVICE reaches exactly kSettingsMaxItems there; GPS-less boards keep the
4-item layout with RESTART last). Selecting it opens GpsSyncController, a
thin overlay over the gps:: sync engine: it polls syncPoll, refreshes the
elapsed/timeout countdown once per second, and closes on fix (success
toast), timeout acknowledgement, or cancel (B-long on button boards, Esc
on keyboard boards). Every UI exit path — including overlay idle-sleep and
the parent reset — funnels through reset(), whose syncCancel powers the
receiver down. The trailing settings value surfaces the last clock-set
provenance (ClockSource).
Long-press edges are polled before short-click polls on the same button,
matching the documented ButtonInput call order.
Carried polish: the UART facade begin() now releases the TX/RX pads on its
partial-failure branch, syncCancel documents the Core-1 owning-task
contract, and the stale SyncPhase::Idle doc phrase is reworded.
Claude-Session: https://claude.ai/code/session_01SV58JXhfxhhc9DC6vdjBo4