App-side adapters bridge JarvisMCP's self-knowledge dispatcher protocols
to concrete runtime sources, mirroring the InProcessMemoryAdapters.swift
Track D-2 pattern (commit 707c45b). JarvisMCP stays unaware of
Voice/AVFoundation/CoreAudio.
- App/MCP/InProcessSelfStateAdapters.swift (NEW):
- CoreAudioIntrospection.snapshotDevices() — full
AudioObjectGetPropertyData enumeration, one entry per
(device, direction) pair with name/uid/sampleRate/channels and
isDefault/isActive flags resolved from
kAudioHardwarePropertyDefaultInput/OutputDevice.
- CoreAudioIntrospection.defaultDeviceUID(isInput:) — used by
AudioGraphRouteAdapter to fill the route's input/output UID + name.
- CoreAudioDeviceListAdapter — wraps snapshotDevices() (SELF-01).
- AudioGraphRouteAdapter (actor) — hops into AudioGraphOwner for the
probed sample rate + channels, combines with the CoreAudio default
device UIDs for the active route (SELF-02).
- SelfStateAdapter — closure-injected probes for provider, voice loop
state, TTS tier, STT backend, wake-word mute. Uses captured launch
Date for app uptime (NOT ProcessInfo.systemUptime which is host
uptime per D-11). buildMode reads #if DEBUG. (SELF-03).
- AVCaptureDeviceListAdapter — DiscoverySession enumeration; metadata-
only, does NOT trigger camera TCC prompt (SELF-04).
- packages/Voice/Sources/Voice/AudioGraph/AudioGraph.swift: store the
probedFormat on AudioGraph so AudioGraphOwner can expose it. Additive
public let; no behavior change.
- packages/Voice/Sources/Voice/AudioGraph/AudioGraphOwner.swift:
- new public ActiveRouteSnapshot Sendable struct (sampleRate, channels)
- new public actor accessor activeRouteSnapshot() returns the probed
input format. Hardware-identity (UID/name) intentionally lives in
the App-side adapter so Voice doesn't take on CoreAudio-introspection
concerns.
- App/AppDelegate.swift:
- launchInstant: Date captured at AppDelegate construction time for
SELF-03 app-uptime reporting (D-11).
- selfKnowledgeInstallTask + installSelfKnowledgeTools() registers the
four tools into the existing inProcessToolRegistry built by
installMemory. Runs after voiceInstallTask so audioGraphOwner is
available; degrades gracefully when audioGraphOwner is nil
(registers the three tools that don't depend on it). All four tools
declare requiresConfirmation:false (D-10 / AP-12); no caching
(D-09 / AP-11). Provider identity reads from configStore.perTurn();
voice loop state hops VoiceController.state; wake-word mute reads
UserDefaults `features.voice.wakeWordMuted` (mirrors MuteWakeWord's
persistence key).
Verification:
- swift test --package-path packages/MCP — all suites GREEN incl.
registersFourSelfKnowledgeTools.
- swift test --package-path packages/Voice — 26 tests in 7 suites GREEN
(AudioGraph probedFormat additive change, no regressions).
- bash scripts/check-app-builds.sh — PASS.
- All 18 boundary gates exit 0 (incl. check-applescript-confirmation,
check-no-leftover-stubs, check-install-order, check-no-null-voice-
adapters, check-no-evaluate-javascript).