Adds README.md to each of the 13 SPM packages (AgentCore, Bus, Config,
DevOverlay, Harness, Keychain, Logging, MCP, Memory, Replay, Shell, Vision,
Voice). Each covers purpose, key public types, deps, consumers, invariants
(pulled from CLAUDE.md + grep-gates + audit findings), test stack, and
notable files. Memory README explicitly marks the package functionally OFF
until vec0.dylib + Ollama models land.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`HIDAccessProbe` gained `isListenEventAccessGranted() -> Bool` (the
query-only relaunch path that doesn't re-prompt) but `MockProbe` in
`InputMonitoringDenialTests.swift` was never updated to conform — the
test target failed to compile entirely. Existence on develop indicates
the Shell package isn't covered by pre-merge CI.
Add the conformance with the same `granted` value as
`requestListenEventAccess()` since the tests don't differentiate the
two surfaces.
Verified: `swift test --package-path packages/Shell` compiles + runs
19 tests (1 skipped) green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per `.planning/audit-2026-05-03/tests-audit.md` section 5, five
`XCTAssertTrue(true)` placeholder tests were identified across the tree
that are mathematically incapable of failing. This commit fixes or
removes each, conservatively. Files touched and disposition:
- App/Tests/AppTests/MCPRuntimeWiringTests.swift:260
fixed: replaced trailing `XCTAssertTrue(true)` rubber-stamp at end of
CR-02 channel-drain test with a load-bearing assertion that the drain
task completed via `finish()`, not cancellation. The implicit `await
drainTask.value` is the real gate; the new assertion ensures regressions
that cancel-instead-of-finish surface.
- App/Tests/AppTests/WebviewBundleLoadTests.swift:60
deleted: `test_assetsDirectoryGitignored_documentedInSmokeScript`. Body
was `XCTAssertTrue(true)` with comment "intentionally has no assertion
— it exists to document the split of responsibility". Documentation,
not a test. Replaced with a top-level comment block documenting the
same split (smoke-test-hud.sh is the runtime gate).
- packages/AgentCore/Tests/AgentCoreTests/ToolChoiceTests.swift:38
fixed: removed trailing `XCTAssertTrue(true) // Test compiles → contract
holds.` from `testLLMProviderStreamRequiresToolChoice`. The closure
body itself is the contract — if the test compiles, the contract holds.
Comment updated to make the compile-time semantics explicit.
- packages/Shell/Tests/ShellTests/InputMonitoringDenialTests.swift:36
deleted: `test_localMonitorOnlyFallback`. Body was `XCTAssertTrue(true)`
documenting that the real fallback test lives in HotkeyBindingTests.
Replaced with a top-level comment pointing readers there.
- packages/Vision/Tests/VisionTests/PackageBoundaryTests.swift:14
deleted: `testVisionModuleCompilesStandalone`. Body was
`XCTAssertTrue(true)` with comment "compile is the assertion." VISION-03
isolation is enforced by `scripts/check-vision-isolation.sh` and the
Package.swift dependency graph, both of which are real gates. Folded
the documentation into the `testPublicAPISurface` doc-comment so the
explanation isn't lost.
HudStateEnumTests rubber-stamps (audit items #4–6 in section 5) were
left as-is. The voiceOverLabel literals are user-facing accessibility
text that VoiceOver actually speaks; they are load-bearing in the sense
the audit calls out as worth preserving ("replace with behavioral
assertions if the literal under test is load-bearing"). A regression
that breaks an a11y label IS a real regression. Conservative read; not
worth the blast radius of guessing wrong.
Pre-existing baseline issues unrelated to this batch:
- `packages/Shell/Tests/ShellTests/InputMonitoringDenialTests.swift`
fails to COMPILE on a clean tree (MockProbe missing
`isListenEventAccessGranted()`). Verified via `git stash` that the
failure is independent of this commit. Not addressed here per the
scope rules — flagged for follow-up.
Net test count: -3 tests (3 deleted, 0 added — the
MCPRuntimeWiringTests assertion replaces the tautology in-place).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The wizard had two persistence holes that made the user's quit-and-reopen
workflow surface the same stage(s) again:
1. Hotkey was in-memory only. WizardState.hotkey was @Published but
never written to disk. Quit and reopen → state defaults to nil →
firstUnresolvedStage returns .hotkey → wizard re-asks even though
the user already bound one a moment ago.
2. Input Monitoring grant detection used the in-memory
inputMonitoringProbed flag (also session-scoped), not the actual
system grant state. Quit and reopen after granting → flag resets to
false → wizard returns to TCC stage even though TCC remembers the
grant.
Fixes:
- WizardState.refresh() now reads from system sources of truth on every
invocation:
apiKeyStored ← Keychain (already correct)
inputMonitoringGranted ← IOHIDCheckAccess (new — query-only, no prompt)
hotkey ← UserDefaults 'Jarvis.hotkey' (JSON-encoded)
- firstUnresolvedStage gates TCC on !inputMonitoringGranted (the actual
grant) instead of !inputMonitoringProbed (the session UI flag).
- WizardState.hotkey has a didSet that persists to UserDefaults; the
Stage 3 'Save Hotkey' button assigning to state.hotkey now hits disk
too. Set to nil → key removed.
- HIDAccessProbe protocol gains isListenEventAccessGranted(), backed by
IOHIDCheckAccess in production. Tests can inject deterministic grant
state without TCC side effects.
Verified: check-app-builds clean. After scripts/dev-reset.sh --yes,
launching → wizard at apiKey. Entering key + granting Input Monitoring
+ binding hotkey + Quit + relaunch (fresh process) should land past
all three stages because each is recomputed from system state.
Three fixes for the 'pick your hotkey' screen the user reported as
unusable:
1. ShortcutRecorderHostView (Shell): the NSView had no draw(_:) override
and no mouseDown(_:) override, so it was both invisible AND uncllickable
for focus purposes. The user had nothing to click on, and even if they
guessed where the 40-px tall frame was, clicking didn't make it first
responder, so the keyDown monitor never registered.
- Add wantsLayer + cornerRadius for a visible rounded field.
- Add mouseDown(with:) → window.makeFirstResponder(self).
- Add draw(_:) that renders a placeholder ('Click to record shortcut…'),
a focused-state hint ('Press a shortcut…'), and the recorded value
once captured. Border + background change color when focused so the
focus state is obvious.
- Add setRecordedDisplay(_:) public setter so the SwiftUI parent can
push the captured shortcut text in for rendering.
2. WizardStageHotkeyView (App): tells the user, in plain language, what to
do — three numbered steps explaining click-to-record, modifier+key, and
Esc-to-cancel. Adds a 'Selected: [⌘⇧J]' confirmation row with a Clear
button so the user can see and reset the chosen shortcut before saving.
Wraps text properly via .fixedSize(horizontal: false, vertical: true).
3. KeyboardShortcut.displayString (Shell): renders shortcut as Apple's
menu-style glyph string ('⌘⇧J', '⌃⌥Space', etc.). Carbon import is
required for kVK_* constants — added directly to KeyboardShortcut.swift
per user direction. Modifier glyph order matches Apple convention
(⌃ ⌥ ⇧ ⌘); unmapped key codes fall back to 'Key{n}' for debuggability.
Verified: check-app-builds.sh PASS; relaunched (PID 68314).
Phase 1 REVIEW.md CR-03 (SHELL-06): `HotkeyBinder.bind` never checked
whether `store.installGlobalMonitor` returned nil — yet
`NSEvent.addGlobalMonitorForEvents` silently returns nil when Input
Monitoring was revoked between launches (common after a codesign
identity change). The result was the exact silent-no-op SHELL-06
exists to prevent: hotkey appears bound, global monitor is dead, no
banner surfaces. Related WR-06: `BannerContent.hotkeyBindFailed`
existed but was never enqueued from production code.
packages/Shell/Sources/Shell/HotkeyBinder.swift
- Add `HotkeyBinder.BannerSink` protocol (mirrors
`InputMonitoringProbe.BannerSink` pattern).
- `bind(_:inputMonitoringGranted:bindFailedSink:onPress:)` now checks
the returned token: if nil, sets `isDegraded = true` AND invokes
`sink.enqueueHotkeyBindFailed()`. Local monitor install is still
unconditional so the hotkey works while Jarvis is frontmost.
packages/Shell/Tests/ShellTests/HotkeyBindingTests.swift
- Add `DeniedGlobalMonitorStore` fake (returns nil for global install).
- Add `RecordingBindFailedSink` that counts enqueue calls.
- New tests:
- `test_nilGlobalTokenMarksDegradedAndNotifiesSink` — SHELL-06
regression guard for the silent-revoke path.
- `test_deniedInputMonitoringDoesNotEnqueueBindFailed` — asserts the
priority-2 inputMonitoringDenied banner is not mixed with the
priority-3 hotkeyBindFailed banner.
- `test_successfulBindDoesNotEnqueueBindFailed` — no spurious banner
on the happy path.
App/AppDelegate.swift:233-260
- Add `HotkeyBindFailedSink` adapter (mirrors `AdHocBannerSink`
pattern) so Shell can enqueue `BannerContent.hotkeyBindFailed` onto
the `HUDBannerCoordinator` without importing App types.
- `bindHotkeyFromWizard()` now passes the sink into `hotkeyBinder.bind`
— fixes WR-06 (hotkeyBindFailed preset no longer orphaned).
- packages/Keychain — zero SPM deps (Security.framework at link time only)
- packages/Logging — depends on apple/swift-log 1.5.3+; library product is
named JarvisLogging to avoid collision with swift-log's own Logging module
- packages/Config — depends on Keychain + Logging (product JarvisLogging)
- packages/Shell — depends on Config + Logging; links AppKit,
ServiceManagement, IOKit, Carbon for hotkey/launch-at-login surfaces
Every target (main + test) opts into .swiftLanguageMode(.v6) per D-04 so
data-race errors are compile-time failures, not warnings.
Placeholder sources (one per package) plus one trivial XCTest per package
per D-03 so each package builds standalone and has a passing test. Real
sources land in Plan 02 (Keychain/Config/Logging) and Plan 04 (Shell).
Bus/LLM/MCP/Voice/Memory packages NOT pre-created per D-01 — they arrive
in their owning phases (P2/P4/P5/P6/P7) to keep rebuild scope tight.