Files
wristivo/docs/ARCHITECTURE.md
T

4.3 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 Local demo UI
Apps/Watch Session controls, touch remote, calibration UI Local demo UI
Apps/Shared Command presentation Implemented
Packages/WristivoKit/RemoteCore Commands, envelopes, admission and receipts Foundation implementation
Packages/WristivoKit/SamsungProtocol Key mapping and frame/URL encoding Pure encoding, no socket
Packages/WristivoKit/GestureCore Normalized directional excursion state machine Algorithm seam, no raw sensor classifier
Adapters/TVTransport iPhone URLSession WebSocket state machine Planned
Adapters/WatchBridge WCSession lifecycle and live delivery Source/test package and injection seams ready; live WCSession implementation pending
Adapters/MotionCapture Core Motion, coordinate calibration, normalization Planned
Adapters/SecureStorage Keychain token and trust persistence Planned

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.