Authority and selection#
The phone is the only composer of watch Rail state. buildWatchRailTile accepts
one explicitly selected ChannelManifest, re-parses it, requires
surfaces.watch, and rejects the adult ring before producing a
v10.watch-rail.1 payload. WatchCompanionBridge.pushRailTile atomically
replaces or clears that one selection over the existing versioned companion
transport.
Neither native companion accepts a manifest or invents channel state. Both cache
only the last validated rail_tile, so the chosen channel remains glanceable
while the phone is unreachable.
Content and behavior#
- Rich tiles render the canonical header, state line, and optional glance metric.
- Cold/text-only tiles render
faces.spectator.textOnlyDegradationbyte-for-byte; the TS, Swift, and Kotlin codecs reject a text-only payload whose state line differs from that field. - The Wear OS provider is the single Rail tile and the first screen in each native app is the same restrained, single-channel presence. Existing Today, Breath, Streak, and Settings screens remain.
- A live-moment alert can enter the wire shape only when a real decision is granted at effective loudness 3 and names a live moment declared by the chosen manifest.
- Native clients deduplicate alert ids and emit one gentle click/28 ms low-amplitude pulse. They remain silent when haptics are disabled or the phone-synced quiet-hours window is active.
Structural exclusions#
WatchRailRing is wellness | games in TypeScript, Swift, and Kotlin. There is
no adult enum case. The canonical Zod schema also fixes alerts to
granted: true and effectiveLoudness: 3; both native decoders repeat those
checks at the trust boundary.
Verification notes#
- Contract and bridge suites cover verbatim degradation, adult rejection, real grant-3 projection, malformed alert rejection, one-tile replacement/clear, and sync replay.
- Swift and Kotlin parity suites cover codec round trips, non-grant rejection, haptic deduplication, and quiet-hours silence.
- On the July 22 Linux host, the TypeScript contract/mobile checks run normally. Native suite setup remains host-constrained: Swift is not installed, and Gradle cannot install Android 36.1 until the Android SDK license is accepted. These are environment limitations, not suppressed test failures.
- The full contracts suite also reports its existing common-manifest drift for
portfolio-release-gates.ts; the focused V10 watch contract suite passes independently.