From 2e26eb1911f2ae11e5d13a83a4abb62d3a44bfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 20 Aug 2026 19:09:45 +0200 Subject: [PATCH 1/3] test: add tvOS platform command coverage manifest --- .../smoke-tvos-platform-coverage.test.ts | 120 ++++++++++ .../integration/tvos-e2e/coverage-manifest.ts | 211 ++++++++++++++++++ 2 files changed, 331 insertions(+) create mode 100644 test/integration/smoke-tvos-platform-coverage.test.ts create mode 100644 test/integration/tvos-e2e/coverage-manifest.ts diff --git a/test/integration/smoke-tvos-platform-coverage.test.ts b/test/integration/smoke-tvos-platform-coverage.test.ts new file mode 100644 index 000000000..87b706e74 --- /dev/null +++ b/test/integration/smoke-tvos-platform-coverage.test.ts @@ -0,0 +1,120 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import test from 'node:test'; + +import { TVOS_SIMULATOR } from '../../src/__tests__/test-utils/device-fixtures.ts'; +import { PUBLIC_COMMANDS } from '../../src/command-catalog.ts'; +import { + isCommandSupportedOnDevice, + requireGestureSupported, +} from '../../src/core/capabilities.ts'; +import { AppError } from '@agent-device/kernel/errors'; +import { + TVOS_COVERAGE_GAP_ISSUE, + TVOS_PLATFORM_COVERAGE, + TVOS_PLATFORM_COVERAGE_CLASSIFICATION_SUMMARY, + TVOS_REMOTE_EVIDENCE, + TVOS_REMOTE_SCENARIO_COMMANDS, + TVOS_REMOTE_TEST_NAME, +} from './tvos-e2e/coverage-manifest.ts'; + +const publicCommands = Object.values(PUBLIC_COMMANDS).sort(); + +test('tvOS coverage exhaustively classifies the public catalog', () => { + assert.deepEqual(Object.keys(TVOS_PLATFORM_COVERAGE).sort(), publicCommands); + + for (const command of publicCommands) { + const entry = TVOS_PLATFORM_COVERAGE[command]; + assert.ok(entry.assertion.trim().length > 0, `${command} needs an observable assertion`); + if (entry.level === 'live' || entry.level === 'command-contract') { + assert.ok(entry.owner.path.trim().length > 0, `${command} needs an evidence path`); + assert.ok(entry.owner.test.trim().length > 0, `${command} needs named evidence`); + } + if (entry.level === 'known-gap') { + assert.equal( + entry.trackingIssue, + TVOS_COVERAGE_GAP_ISSUE, + `${command} has the wrong gap issue`, + ); + } + } +}); + +test('tvOS coverage report has the expected classification counts', () => { + assert.deepEqual(TVOS_PLATFORM_COVERAGE_CLASSIFICATION_SUMMARY, { + capabilityDenial: 3, + contract: 12, + gap: 39, + live: 0, + total: 54, + }); +}); + +test('tvOS contract claims name existing executable evidence', () => { + for (const [command, entry] of Object.entries(TVOS_PLATFORM_COVERAGE)) { + if (entry.level !== 'command-contract') continue; + const evidencePath = path.resolve(entry.owner.path); + assert.equal(fs.existsSync(evidencePath), true, `${command} owner does not exist`); + assert.equal( + fs.readFileSync(evidencePath, 'utf8').includes(entry.owner.test), + true, + `${command} owner does not contain named evidence`, + ); + } +}); + +test('tvOS provider contract claims only commands executed by the existing scenario', () => { + const scenarioSource = fs.readFileSync(path.resolve(TVOS_REMOTE_EVIDENCE.path), 'utf8'); + assert.equal(scenarioSource.includes(TVOS_REMOTE_TEST_NAME), true); + + for (const command of TVOS_REMOTE_SCENARIO_COMMANDS) { + assert.equal( + scenarioSource.includes(`callCommand('${command}'`), + true, + `${command} is not invoked by ${TVOS_REMOTE_EVIDENCE.path}`, + ); + assert.equal(TVOS_PLATFORM_COVERAGE[command].level, 'command-contract'); + } +}); + +test('tvOS capability denials match the mechanical capability matrix', () => { + const deniedByCapabilities = publicCommands + .filter((command) => !isCommandSupportedOnDevice(command, TVOS_SIMULATOR)) + .sort(); + const deniedByManifest = Object.entries(TVOS_PLATFORM_COVERAGE) + .filter(([, entry]) => entry.level === 'capability-denial') + .map(([command]) => command) + .sort(); + + assert.deepEqual(deniedByManifest, deniedByCapabilities); +}); + +test('tvOS gesture contract preserves the typed multi-touch denial', () => { + assert.equal(TVOS_PLATFORM_COVERAGE[PUBLIC_COMMANDS.gesture].level, 'command-contract'); + assert.throws( + () => + requireGestureSupported( + { + intent: 'pan', + origin: { x: 100, y: 200 }, + delta: { x: 40, y: -20 }, + pointerCount: 2, + }, + TVOS_SIMULATOR, + ), + (error: unknown) => + error instanceof AppError && + error.code === 'UNSUPPORTED_OPERATION' && + /tvOS has no touch input/.test(String(error.details?.hint)), + ); +}); + +test('tvOS known gaps use one grouped tracking issue', () => { + const gapIssues = new Set( + Object.values(TVOS_PLATFORM_COVERAGE) + .filter((entry) => entry.level === 'known-gap') + .map((entry) => entry.trackingIssue), + ); + assert.deepEqual([...gapIssues], [TVOS_COVERAGE_GAP_ISSUE]); +}); diff --git a/test/integration/tvos-e2e/coverage-manifest.ts b/test/integration/tvos-e2e/coverage-manifest.ts new file mode 100644 index 000000000..c46ff048a --- /dev/null +++ b/test/integration/tvos-e2e/coverage-manifest.ts @@ -0,0 +1,211 @@ +import { PUBLIC_COMMANDS } from '../../../src/command-catalog.ts'; + +type PublicCommand = (typeof PUBLIC_COMMANDS)[keyof typeof PUBLIC_COMMANDS]; + +type RepositoryEvidence = { + path: string; + test: string; +}; + +export type TvOsPlatformCoverageEntry = + | { + assertion: string; + level: 'live' | 'command-contract'; + owner: RepositoryEvidence; + } + | { + assertion: string; + level: 'capability-denial'; + } + | { + assertion: string; + level: 'known-gap'; + trackingIssue: number; + }; + +export type TvOsPlatformCoverageClassificationSummary = { + capabilityDenial: number; + contract: number; + gap: number; + live: number; + total: number; +}; + +export const TVOS_COVERAGE_GAP_ISSUE = 1914; +export const TVOS_REMOTE_TEST_NAME = + 'Provider-backed integration tvOS remote flow maps navigation commands to runner remote presses'; +export const TVOS_REMOTE_EVIDENCE: RepositoryEvidence = { + path: 'test/integration/provider-scenarios/tvos-remote.test.ts', + test: TVOS_REMOTE_TEST_NAME, +}; +export const TVOS_REMOTE_SCENARIO_COMMANDS: readonly PublicCommand[] = [ + PUBLIC_COMMANDS.open, + PUBLIC_COMMANDS.scroll, + PUBLIC_COMMANDS.back, + PUBLIC_COMMANDS.home, + PUBLIC_COMMANDS.close, +]; + +const C = PUBLIC_COMMANDS; +const contract = (path: string, test: string, assertion: string): TvOsPlatformCoverageEntry => ({ + assertion, + level: 'command-contract', + owner: { path, test }, +}); +const denial = (assertion: string): TvOsPlatformCoverageEntry => ({ + assertion, + level: 'capability-denial', +}); +const gap = (assertion: string): TvOsPlatformCoverageEntry => ({ + assertion, + level: 'known-gap', + trackingIssue: TVOS_COVERAGE_GAP_ISSUE, +}); + +/** + * One primary, observable owner for every public command on the tvOS leaf. + * + * There is no tvOS CI or live-device lane at HEAD, so the existing provider + * scenario is contract evidence rather than a live claim. The remaining + * contract rows cite Apple deployment/inventory tests or the typed Apple + * interaction policy. Capability denials are limited to whole-command + * denials; tvOS's narrower multi-touch refusal stays with the gesture contract + * instead of denying the supported one-contact gesture path. + */ +export const TVOS_PLATFORM_COVERAGE = { + [C.artifacts]: gap('No tvOS-specific artifact inventory command evidence exists yet'), + [C.devices]: contract( + 'packages/platform-apple/src/simulator-inventory.test.ts', + 'simctl parser keeps available supported runtimes and their target semantics', + 'tvOS simulator inventory preserves the tv target and tvOS Apple-OS identity', + ), + [C.capabilities]: gap('No tvOS-specific capabilities command evidence exists yet'), + [C.doctor]: gap('No tvOS-specific doctor command evidence exists yet'), + [C.apps]: gap('No tvOS-specific app inventory command evidence exists yet'), + [C.boot]: gap('No tvOS-specific boot command evidence exists yet'), + [C.shutdown]: gap('No tvOS-specific shutdown command evidence exists yet'), + [C.appState]: gap('No tvOS-specific app-state command evidence exists yet'), + [C.perf]: gap('No tvOS-specific performance command evidence exists yet'), + [C.logs]: gap('No tvOS-specific app-log command evidence exists yet'), + [C.events]: gap('No tvOS-specific session-event command evidence exists yet'), + [C.network]: gap('No tvOS-specific network command evidence exists yet'), + [C.audio]: gap('No tvOS-specific audio command evidence exists yet'), + [C.replay]: gap('No tvOS-specific replay command evidence exists yet'), + [C.test]: gap('No tvOS-specific test-suite command evidence exists yet'), + [C.clipboard]: gap('No tvOS-specific clipboard command evidence exists yet'), + [C.keyboard]: denial('tvOS capability admission rejects keyboard input on the focus-only leaf'), + [C.install]: contract( + 'packages/platform-apple/src/deployment/runtime.test.ts', + 'classifies deployment facts for the %s denominator cell', + 'shared Apple deployment facts admit app installation on tvOS simulators', + ), + [C.reinstall]: contract( + 'packages/platform-apple/src/deployment/runtime.test.ts', + 'classifies deployment facts for the %s denominator cell', + 'shared Apple deployment facts admit the operation used by tvOS install and reinstall', + ), + [C.push]: contract( + 'packages/platform-apple/src/deployment/runtime.test.ts', + 'classifies deployment facts for the %s denominator cell', + 'shared Apple deployment facts admit simulator push notifications for tvOS', + ), + [C.triggerAppEvent]: gap('No tvOS-specific app-event command evidence exists yet'), + [C.open]: contract( + TVOS_REMOTE_EVIDENCE.path, + TVOS_REMOTE_EVIDENCE.test, + 'the existing provider scenario launches a tvOS app through the Apple tool provider', + ), + [C.prepare]: gap('No tvOS-specific runner preparation command evidence exists yet'), + [C.batch]: gap('No tvOS-specific batch command evidence exists yet'), + [C.close]: contract( + TVOS_REMOTE_EVIDENCE.path, + TVOS_REMOTE_EVIDENCE.test, + 'the existing provider scenario terminates the tvOS app and releases the session', + ), + [C.snapshot]: gap('No tvOS-specific snapshot command evidence exists yet'), + [C.diff]: gap('No tvOS-specific snapshot-diff command evidence exists yet'), + [C.wait]: gap('No tvOS-specific wait command evidence exists yet'), + [C.alert]: gap('No tvOS-specific alert command evidence exists yet'), + [C.settings]: gap('No tvOS-specific settings command evidence exists yet'), + [C.reactNative]: gap('No tvOS-specific React Native inspection command evidence exists yet'), + [C.record]: gap('No tvOS-specific recording command evidence exists yet'), + [C.trace]: gap('No tvOS-specific trace command evidence exists yet'), + [C.find]: gap('No tvOS-specific find command evidence exists yet'), + [C.click]: gap('No tvOS-specific click command evidence exists yet'), + [C.fill]: gap('No tvOS-specific fill command evidence exists yet'), + [C.longPress]: gap('No tvOS-specific long-press command evidence exists yet'), + [C.hover]: denial('tvOS capability admission rejects pointer-only hover input'), + [C.press]: gap('No tvOS-specific press command evidence exists yet'), + [C.type]: gap('No tvOS-specific type command evidence exists yet'), + [C.get]: gap('No tvOS-specific get command evidence exists yet'), + [C.is]: gap('No tvOS-specific predicate command evidence exists yet'), + [C.back]: contract( + TVOS_REMOTE_EVIDENCE.path, + TVOS_REMOTE_EVIDENCE.test, + 'the existing provider scenario maps Back to the tvOS Menu remote press', + ), + [C.gesture]: contract( + 'src/core/__tests__/gesture-capabilities.test.ts', + 'TV, spatial, watch, desktop, Linux, and web gesture policy stays explicit', + 'the typed Apple gesture policy refuses tvOS multi-touch while preserving the narrower gesture contract', + ), + [C.home]: contract( + TVOS_REMOTE_EVIDENCE.path, + TVOS_REMOTE_EVIDENCE.test, + 'the existing provider scenario maps Home to the tvOS Home remote press', + ), + [C.tvRemote]: contract( + 'src/core/__tests__/dispatch-tv-remote.test.ts', + 'dispatch tv-remote sends native tvOS remotePress command', + 'tvOS tv-remote dispatch emits the native remotePress runner command', + ), + [C.orientation]: denial('tvOS capability admission rejects device orientation changes'), + [C.scroll]: contract( + TVOS_REMOTE_EVIDENCE.path, + TVOS_REMOTE_EVIDENCE.test, + 'the existing provider scenario maps tvOS scroll direction to a remote press', + ), + [C.swipe]: gap('No tvOS-specific swipe command evidence exists yet'), + [C.focus]: gap('No tvOS-specific focus command evidence exists yet'), + [C.screenshot]: gap('No tvOS-specific screenshot command evidence exists yet'), + [C.viewport]: gap('No tvOS-specific viewport command evidence exists yet'), + [C.appSwitcher]: gap('No tvOS-specific app-switcher command evidence exists yet'), + [C.installFromSource]: contract( + 'packages/platform-apple/src/deployment/runtime.test.ts', + 'classifies deployment facts for the %s denominator cell', + 'shared Apple deployment operations expose source materialization for admitted tvOS deployment', + ), +} satisfies Record; + +export const TVOS_PLATFORM_COVERAGE_CLASSIFICATION_SUMMARY = buildCoverageClassificationSummary( + Object.values(TVOS_PLATFORM_COVERAGE), +); + +function buildCoverageClassificationSummary( + entries: readonly TvOsPlatformCoverageEntry[], +): TvOsPlatformCoverageClassificationSummary { + const summary: TvOsPlatformCoverageClassificationSummary = { + capabilityDenial: 0, + contract: 0, + gap: 0, + live: 0, + total: entries.length, + }; + for (const entry of entries) { + switch (entry.level) { + case 'live': + summary.live += 1; + break; + case 'command-contract': + summary.contract += 1; + break; + case 'capability-denial': + summary.capabilityDenial += 1; + break; + case 'known-gap': + summary.gap += 1; + break; + } + } + return summary; +} From 44e92a4f006d50202f9f8e0d08dea3abdcf7d29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 20 Aug 2026 20:19:45 +0200 Subject: [PATCH 2/3] fix: align tvOS audio coverage denial --- .../smoke-tvos-platform-coverage.test.ts | 19 +++++++++++++++---- .../integration/tvos-e2e/coverage-manifest.ts | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/test/integration/smoke-tvos-platform-coverage.test.ts b/test/integration/smoke-tvos-platform-coverage.test.ts index 87b706e74..5b0d62125 100644 --- a/test/integration/smoke-tvos-platform-coverage.test.ts +++ b/test/integration/smoke-tvos-platform-coverage.test.ts @@ -43,9 +43,9 @@ test('tvOS coverage exhaustively classifies the public catalog', () => { test('tvOS coverage report has the expected classification counts', () => { assert.deepEqual(TVOS_PLATFORM_COVERAGE_CLASSIFICATION_SUMMARY, { - capabilityDenial: 3, + capabilityDenial: 4, contract: 12, - gap: 39, + gap: 38, live: 0, total: 54, }); @@ -80,14 +80,25 @@ test('tvOS provider contract claims only commands executed by the existing scena test('tvOS capability denials match the mechanical capability matrix', () => { const deniedByCapabilities = publicCommands - .filter((command) => !isCommandSupportedOnDevice(command, TVOS_SIMULATOR)) + .filter( + (command) => + command !== PUBLIC_COMMANDS.audio && !isCommandSupportedOnDevice(command, TVOS_SIMULATOR), + ) .sort(); const deniedByManifest = Object.entries(TVOS_PLATFORM_COVERAGE) - .filter(([, entry]) => entry.level === 'capability-denial') + .filter( + ([command, entry]) => + command !== PUBLIC_COMMANDS.audio && entry.level === 'capability-denial', + ) .map(([command]) => command) .sort(); assert.deepEqual(deniedByManifest, deniedByCapabilities); + assert.equal( + isCommandSupportedOnDevice(PUBLIC_COMMANDS.audio, TVOS_SIMULATOR), + process.platform === 'darwin', + 'tvOS simulator audio admission follows host ScreenCaptureKit availability', + ); }); test('tvOS gesture contract preserves the typed multi-touch denial', () => { diff --git a/test/integration/tvos-e2e/coverage-manifest.ts b/test/integration/tvos-e2e/coverage-manifest.ts index c46ff048a..c97e744e0 100644 --- a/test/integration/tvos-e2e/coverage-manifest.ts +++ b/test/integration/tvos-e2e/coverage-manifest.ts @@ -89,7 +89,7 @@ export const TVOS_PLATFORM_COVERAGE = { [C.logs]: gap('No tvOS-specific app-log command evidence exists yet'), [C.events]: gap('No tvOS-specific session-event command evidence exists yet'), [C.network]: gap('No tvOS-specific network command evidence exists yet'), - [C.audio]: gap('No tvOS-specific audio command evidence exists yet'), + [C.audio]: denial('tvOS audio admission is host-dependent and denied on hosted CI'), [C.replay]: gap('No tvOS-specific replay command evidence exists yet'), [C.test]: gap('No tvOS-specific test-suite command evidence exists yet'), [C.clipboard]: gap('No tvOS-specific clipboard command evidence exists yet'), From 8611dcfdec2aa879a35f1ed5be5cd54afa23c098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Thu, 20 Aug 2026 21:20:21 +0200 Subject: [PATCH 3/3] fix: model tvOS audio as host-dependent contract --- .../smoke-tvos-platform-coverage.test.ts | 38 ++++++++-------- .../integration/tvos-e2e/coverage-manifest.ts | 45 ++++++++++++++++--- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/test/integration/smoke-tvos-platform-coverage.test.ts b/test/integration/smoke-tvos-platform-coverage.test.ts index 5b0d62125..af5066732 100644 --- a/test/integration/smoke-tvos-platform-coverage.test.ts +++ b/test/integration/smoke-tvos-platform-coverage.test.ts @@ -43,8 +43,8 @@ test('tvOS coverage exhaustively classifies the public catalog', () => { test('tvOS coverage report has the expected classification counts', () => { assert.deepEqual(TVOS_PLATFORM_COVERAGE_CLASSIFICATION_SUMMARY, { - capabilityDenial: 4, - contract: 12, + capabilityDenial: 3, + contract: 13, gap: 38, live: 0, total: 54, @@ -80,25 +80,27 @@ test('tvOS provider contract claims only commands executed by the existing scena test('tvOS capability denials match the mechanical capability matrix', () => { const deniedByCapabilities = publicCommands - .filter( - (command) => - command !== PUBLIC_COMMANDS.audio && !isCommandSupportedOnDevice(command, TVOS_SIMULATOR), - ) + .filter((command) => !isCommandSupportedOnDevice(command, TVOS_SIMULATOR)) .sort(); - const deniedByManifest = Object.entries(TVOS_PLATFORM_COVERAGE) - .filter( - ([command, entry]) => - command !== PUBLIC_COMMANDS.audio && entry.level === 'capability-denial', - ) - .map(([command]) => command) + const manifestCapabilityProjection = Object.entries(TVOS_PLATFORM_COVERAGE) + .flatMap(([command, entry]) => { + if (entry.level === 'capability-denial') return [command]; + if ( + entry.level === 'command-contract' && + 'admission' in entry && + entry.admission === 'host-dependent' && + !isCommandSupportedOnDevice(command, TVOS_SIMULATOR) + ) { + return [command]; + } + return []; + }) .sort(); - assert.deepEqual(deniedByManifest, deniedByCapabilities); - assert.equal( - isCommandSupportedOnDevice(PUBLIC_COMMANDS.audio, TVOS_SIMULATOR), - process.platform === 'darwin', - 'tvOS simulator audio admission follows host ScreenCaptureKit availability', - ); + assert.deepEqual(manifestCapabilityProjection, deniedByCapabilities); + const audio = TVOS_PLATFORM_COVERAGE[PUBLIC_COMMANDS.audio]; + assert.equal(audio.level, 'command-contract'); + assert.equal('admission' in audio ? audio.admission : undefined, 'host-dependent'); }); test('tvOS gesture contract preserves the typed multi-touch denial', () => { diff --git a/test/integration/tvos-e2e/coverage-manifest.ts b/test/integration/tvos-e2e/coverage-manifest.ts index c97e744e0..0b2d6cb46 100644 --- a/test/integration/tvos-e2e/coverage-manifest.ts +++ b/test/integration/tvos-e2e/coverage-manifest.ts @@ -7,12 +7,26 @@ type RepositoryEvidence = { test: string; }; +type TvOsCommandContractEntry = + | { + assertion: string; + level: 'command-contract'; + owner: RepositoryEvidence; + } + | { + assertion: string; + level: 'command-contract'; + owner: RepositoryEvidence; + admission: 'host-dependent'; + }; + export type TvOsPlatformCoverageEntry = | { assertion: string; - level: 'live' | 'command-contract'; + level: 'live'; owner: RepositoryEvidence; } + | TvOsCommandContractEntry | { assertion: string; level: 'capability-denial'; @@ -38,6 +52,10 @@ export const TVOS_REMOTE_EVIDENCE: RepositoryEvidence = { path: 'test/integration/provider-scenarios/tvos-remote.test.ts', test: TVOS_REMOTE_TEST_NAME, }; +const TVOS_AUDIO_EVIDENCE: RepositoryEvidence = { + path: 'src/core/__tests__/capability-plugin-routing-parity.test.ts', + test: '(b.1) isCommandSupportedOnDevice is unchanged across the command x device matrix', +}; export const TVOS_REMOTE_SCENARIO_COMMANDS: readonly PublicCommand[] = [ PUBLIC_COMMANDS.open, PUBLIC_COMMANDS.scroll, @@ -47,10 +65,16 @@ export const TVOS_REMOTE_SCENARIO_COMMANDS: readonly PublicCommand[] = [ ]; const C = PUBLIC_COMMANDS; -const contract = (path: string, test: string, assertion: string): TvOsPlatformCoverageEntry => ({ +const contract = ( + path: string, + test: string, + assertion: string, + admission?: 'host-dependent', +): TvOsPlatformCoverageEntry => ({ assertion, level: 'command-contract', owner: { path, test }, + ...(admission ? { admission } : {}), }); const denial = (assertion: string): TvOsPlatformCoverageEntry => ({ assertion, @@ -67,10 +91,12 @@ const gap = (assertion: string): TvOsPlatformCoverageEntry => ({ * * There is no tvOS CI or live-device lane at HEAD, so the existing provider * scenario is contract evidence rather than a live claim. The remaining - * contract rows cite Apple deployment/inventory tests or the typed Apple - * interaction policy. Capability denials are limited to whole-command - * denials; tvOS's narrower multi-touch refusal stays with the gesture contract - * instead of denying the supported one-contact gesture path. + * contract rows cite Apple deployment/inventory tests, the typed Apple + * interaction policy, or the executable capability oracle. Capability denials + * are limited to whole-command denials; tvOS's narrower multi-touch refusal + * stays with the gesture contract instead of denying the supported one-contact + * gesture path. Host-dependent contracts retain their oracle admission state + * without claiming a stable tvOS capability. */ export const TVOS_PLATFORM_COVERAGE = { [C.artifacts]: gap('No tvOS-specific artifact inventory command evidence exists yet'), @@ -89,7 +115,12 @@ export const TVOS_PLATFORM_COVERAGE = { [C.logs]: gap('No tvOS-specific app-log command evidence exists yet'), [C.events]: gap('No tvOS-specific session-event command evidence exists yet'), [C.network]: gap('No tvOS-specific network command evidence exists yet'), - [C.audio]: denial('tvOS audio admission is host-dependent and denied on hosted CI'), + [C.audio]: contract( + TVOS_AUDIO_EVIDENCE.path, + TVOS_AUDIO_EVIDENCE.test, + 'tvOS audio admission follows the host-dependent ScreenCaptureKit capability oracle', + 'host-dependent', + ), [C.replay]: gap('No tvOS-specific replay command evidence exists yet'), [C.test]: gap('No tvOS-specific test-suite command evidence exists yet'), [C.clipboard]: gap('No tvOS-specific clipboard command evidence exists yet'),