From a341bfbea9cafe53510ff7d732ea5aacb40b7190 Mon Sep 17 00:00:00 2001 From: Lahfir Date: Sat, 25 Jul 2026 22:17:01 -0700 Subject: [PATCH] fix: report PLATFORM_NOT_SUPPORTED instead of PERM_DENIED on stub adapters The default SystemOps::permission_report returned accessibility Denied, so the CLI preflight short-circuited before dispatch and told Windows and Linux users they had a permissions problem. They do not; those adapters are unimplemented, and the suggested fix does not exist. An adapter that never overrides the probe has not measured permissions at all, which is a different fact from a user denying one. Reporting Unknown lets preflight pass so the call reaches the adapter and surfaces the honest PLATFORM_NOT_SUPPORTED. The skills reference assertion is gated to macOS because the macOS reference document is itself cfg-gated into the binary. --- crates/core/src/adapter/system.rs | 8 +++++--- crates/core/src/adapter/system_tests.rs | 11 +++++++++++ crates/core/src/commands/skills_tests.rs | 4 +++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/core/src/adapter/system.rs b/crates/core/src/adapter/system.rs index 5bbc96c..86e035d 100644 --- a/crates/core/src/adapter/system.rs +++ b/crates/core/src/adapter/system.rs @@ -15,11 +15,13 @@ pub trait SystemOps: Send + Sync { Err(AdapterError::not_supported("acquire_interaction_lease")) } + /// An adapter that never overrides this has not probed permissions at all, + /// which is not the same fact as a user denying one. `Unknown` routes through + /// `unknown_accessibility_means_unsupported` to `PLATFORM_NOT_SUPPORTED` + /// rather than the misleading `PERM_DENIED`. fn permission_report(&self, _deadline: Deadline) -> Result { Ok(PermissionReport { - accessibility: PermissionState::Denied { - suggestion: "Platform adapter not available".into(), - }, + accessibility: PermissionState::Unknown, screen_recording: PermissionState::Unknown, automation: PermissionState::NotRequired, }) diff --git a/crates/core/src/adapter/system_tests.rs b/crates/core/src/adapter/system_tests.rs index c48899b..f2840b1 100644 --- a/crates/core/src/adapter/system_tests.rs +++ b/crates/core/src/adapter/system_tests.rs @@ -18,6 +18,17 @@ fn default_surfaces_fail_closed() { assert!(DefaultOnly.supported_surfaces().is_empty()); } +#[test] +fn default_permission_report_is_unknown_not_denied() { + let report = DefaultOnly + .permission_report(crate::Deadline::standard().unwrap()) + .expect("default permission report must not error"); + + assert_eq!(report.accessibility, crate::PermissionState::Unknown); + assert!(!report.accessibility_denied()); + assert!(DefaultOnly.unknown_accessibility_means_unsupported()); +} + #[test] fn default_open_session_is_explicitly_unsupported() { let affinity = crate::SessionAffinity { diff --git a/crates/core/src/commands/skills_tests.rs b/crates/core/src/commands/skills_tests.rs index 0892da5..4943af5 100644 --- a/crates/core/src/commands/skills_tests.rs +++ b/crates/core/src/commands/skills_tests.rs @@ -30,7 +30,9 @@ fn get_full_inlines_references() { .expect("get full"); let content = v["content"].as_str().expect("string"); assert!(content.contains("--- references/workflows.md ---")); - assert!(content.contains("--- references/macos.md ---")); + if cfg!(target_os = "macos") { + assert!(content.contains("--- references/macos.md ---")); + } assert!(content.contains("@s8f3k2p9:e1")); assert!(content.contains("session start` does not activate later processes")); assert!(content.contains("session-owned ref still requires the same `--session`"));