Files

WristivoKit

Original Swift 6 foundation for the Wristivo prototype. No external dependencies. Minimum declared platforms: iOS 17, watchOS 10, macOS 14.

  • RemoteCore: command vocabulary, versioned envelope, receipts, transport contract, and a stateful admission gate with one-second command lifetime, 250 ms maximum future clock skew, monotonic sequence numbers, and a bounded 128-ID dedup window.
  • SamsungProtocol: candidate local-TV WebSocket endpoint and click-frame encoding. This module opens no sockets, pairs no devices, and supplies no TLS trust exceptions.
  • GestureCore: deterministic gate for already-normalized directional input. This is not a motion classifier. Raw Core Motion processing, calibration, wrist orientation, and physical-device validation remain work for the gesture agent.

Run swift test from this directory. The tests use Swift Testing.

Integration contract

Treat CommandEnvelope decoding as untrusted structure. A single transport actor must call CommandAdmission.admit(_:now:) immediately before each send, and send only .accepted commands. Do not enqueue commands for reconnection or automatically retry a failed send. A consumed sequence stays consumed even when sending fails. Use startNewSession(televisionID:) after reconnect, TV change, or a new control session and convey the returned UUID to the watch before enabling gesture input. The gate rejects old sessions; keep the actor alive for the entire session.

The caller supplies increasing sequence numbers starting at zero or one. At UInt64 exhaustion begin a fresh session, never wrap. The fixed defaults are prototype safety policy, not measured latency claims. Both devices require approximately aligned wall clocks. Use the sender's issue time and expiration; never refresh age upon reception. Use the same JSON date strategy on both devices; the standard Foundation Codable strategy is used by this package's round-trip test.

sentToTransport means submission to the transport only. It does not mean that the TV accepted a command or that the on-screen state changed. The transport implementer must map admission rejection to an appropriate receipt and expose a separate, truthful pairing/connection state.

DirectionalGestureGate.arm(sessionID:at:) requires deliberate user action in the foreground, followed by neutral input. Inputs use monotonic local seconds and the normalized range [-1, 1], where positive x means right and positive y means up. One event is allowed per neutral-to-direction excursion. Defaults propose 0.7 activation, 0.25 neutral, 0.3 seconds between emissions, and ten seconds armed. Ambiguous diagonals, invalid input, and debounce suppression consume the excursion. Return to neutral before another attempt. Call disarm() when app activity, connectivity, selected television, or control session changes. Stop actual sensor delivery in the adapter as well; this pure gate owns no sensor or background task.

Hostnames passed to SamsungRemoteEncoder.endpoint(host:token:) are bare hostnames or IPv4 addresses; bracket IPv6 literals. The client display name is Wristivo. The optional token is a secret and appears in the returned URL: do not log that URL. The wire format and individual keys, particularly KEY_PLAYPAUSE, require physical TV validation. Implement explicit supported-model capabilities before shipping.