54 lines
3.3 KiB
Markdown
54 lines
3.3 KiB
Markdown
# 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.
|