Create Wristivo iPhone and Apple Watch foundation
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user