4.9 KiB
Architecture
Decision
Use native SwiftUI applications and a local Swift package. The watch owns motion capture and recognition; the phone owns TV credentials and networking. No backend is required. Gitea stores development source, not user data.
flowchart LR
A[Watch Core Motion] --> B[GestureCore: calibrated discrete intent]
C[Watch buttons] --> D[WatchBridge: live message]
B --> D
D --> E[iPhone session / command admission]
F[iPhone buttons] --> E
E --> G[TVTransport actor]
G --> H[Samsung TV: paired local WebSocket]
I[Keychain token + TV trust record] --> G
G --> J[Send receipt / failure]
J --> D
Apple TN3135 restricts ordinary watch apps' low-level networking, including URLSessionWebSocketTask. A TV remote does not qualify for the audio, VoIP or tvOS discovery exceptions. See PLATFORM-FEASIBILITY. WatchConnectivity may wake the phone, but this does not grant unlimited phone background execution. Phone-lock/relaunch usability is a physical-hardware gate.
Boundaries
| Location | Responsibility | Current state |
|---|---|---|
| Apps/iPhone | Setup, manual remote, status and troubleshooting | Live composition with explicit demo mode |
| Apps/Watch | Session controls, touch remote, calibration UI | Live composition with explicit demo mode |
| Apps/Shared | Command presentation | Implemented |
| Packages/WristivoKit/RemoteCore | Commands, envelopes, admission and receipts | Implemented and tested |
| Packages/WristivoKit/SamsungProtocol | Key mapping and frame/URL encoding | Encoding and bounded event parser |
| Packages/WristivoKit/GestureCore | Normalized directional excursion state machine | Conservative calibrated classifier; hardware thresholds unvalidated |
| Adapters/TVTransport | iPhone URLSession WebSocket state machine | Integrated prototype; hardware pending |
| Adapters/WatchBridge | WCSession lifecycle and live delivery | Live delegates, bounded messages and session negotiation |
| Adapters/MotionCapture | Core Motion, coordinate calibration, normalization | Integrated prototype; hardware pending |
| Adapters/SecureStorage | Keychain token and trust persistence | Integrated prototype; hardware pending |
Adapters/PhoneControl owns testable iPhone setup orchestration and selected-TV metadata. Apps/iPhone/PhoneAppComposition constructs one TVConnectionActor, one authorization store and one phone WCSession delegate. It publishes only the selected opaque ID, display name and readiness to the watch. Phone and watch commands have separate session admission state in the same TV actor and share its serialized socket drain.
Package target source directories are under Sources. Imported modules use the module names, not the package name. OS adapters stay platform-specific. The integrator adds targets/dependencies or file memberships when implementations arrive.
States and ownership
TV connection: disconnected → connecting → awaitingApproval → ready; errors lead to denied, unauthorized, untrusted, timedOut or unavailable. Socket-open alone is never ready. Require the model's authorization event. Changing target destroys the old connection and control session. Tokens never travel to Watch.
Watch: idle → calibrating → ready → armed → paused. A scene phase other than active, sensor error, TV switch, phone unavailability or stop disarms and clears accumulated motion. Resuming requires explicit re-arm and fresh neutral baseline. No automatic gesture on launch.
One iPhone actor serializes commands, session authorization, admission and TV send operations. Avoid holding unbounded work across await: actor reentrancy still requires cancellation/generation checks when a TV or session changes. At most one in-flight TV send and a small bounded queue; drop expired items. No backlog in WatchConnectivity transferUserInfo or application context.
Prototype order
Build a phone-to-TV vertical slice first. Run a watch-button relay slice alongside raw motion capture/calibration work with a fake command sink. Only integrate gesture-to-TV output after each slice passes separately. UI agents work against fake services using shared contracts. The demo never silently becomes a live transport.
Alternatives and decisions
- ADR-001: phone relay required by watch network constraints.
- ADR-002: active sessions only; no background mode misuse.
- ADR-003: no TV app required for initial local controller pairing. Pairing identity is a network controller label, not Bluetooth certification or TV app store registration.
- ADR-004: manual address first; discovery deferred to avoid blocking the free-account prototype on multicast entitlement work.
- ADR-005: no runtime third-party libraries in foundation; compatibility protocol remains an isolated replaceable adapter.
Contract changes require an integration decision entry with date, reason, affected agents, migration and tests. Do not maintain different command models in each app.