[GH-ISSUE #4311] [Feature] Report macOS permission and Xcode tool readiness before native operations fail #1715

Open
opened 2026-10-16 21:09:21 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 16, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4311

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Provider or capability discovery

Current limitation

On macOS, make rea doctor and the native-macos capability readiness report the host prerequisites that REA's native operations depend on: Accessibility trust, Screen Recording access, Developer Tools debugging authorization, and availability of the Xcode command-line tools REA invokes. Today each of these surfaces only when an operation fails partway, and the capability list reports every native operation as available on any Mac.

An agent preparing to observe a native UI or trace calls on macOS cannot learn in advance whether the host will allow it. Measured with REA 6.5.0 (npx -y rea-agents@6.5.0, tag rea-agents-6.5.0, commit 3b79af28e80785afce9f5998d8f03289402a1847) on macOS 27.0.1 (26A434) arm64 with Xcode 27.0 (27A266a) and Node.js v26.10.0:

  • rea doctor --json returned checks named node, host, hopper, ghidra, ida-registration, jadx, skill:identity and per-client registration:*, and none about Accessibility, Screen Recording, Developer Tools or Xcode tools. The system doctor host adds provider inspections for Ghidra, IDA and JADX and a Linux display check, and nothing for macOS host permissions (doctorRuntime.ts).
  • On the same host DevToolsSecurity -status printed "Developer mode is currently disabled.", while rea capabilities --json listed observe_native_calls, capture_native_ui_scenario and observe_native_ui with available: true and reason: null. Native capability availability depends only on platform === "darwin" (NativeMacOSProviderMetadata.ts).
  • Accessibility and Screen Recording are checked inside the compiled UI helper, at call time: CGPreflightScreenCaptureAccess() produces screen-recording-denied and AXIsProcessTrusted() produces accessibility-denied (ReaNativeUI.swift). Compiling that helper first requires xcrun swiftc (NativeUiHelperRuntime.ts).
  • Debugging authorization appears only as remediation text after LLDB is refused: "Allow debugging for this user (Developer Tools access: DevToolsSecurity -enable, or membership in the _developer group)." (LldbCallTracer.ts).
  • Static native tools resolve codesign, dyld_info, dwarfdump, file, lipo, nm, otool, plutil, strings, swift-demangle and vtool through xcrun --find at call time (CommandRunner.ts), and asset catalogs need /usr/bin/assetutil (AppleAssetCatalogAnalysis.ts).
  • The MCP contract states the design: "macOS may deny Accessibility, Screen Recording, or native mounting ... These failures are reported at the operation that needs them." (docs/mcp-contracts.md).

For an unattended agent, discovering these one failed call at a time costs turns. Some of them also need a person to act in System Settings, and DevToolsSecurity(8) says that without the policy "the user is queried for an administator password" (spelling as in the manual page) the first time a debugger examines one of the user's processes in a login session. Main at d52a488 adds Kuna and request-budget handling to doctor but no macOS host checks.

Use cases

No response

Desired outcome and success criteria

  • On macOS, rea doctor reports these named checks, each with ok, classification, detail and remediation in the existing doctor format:
    • Accessibility: whether the process running the check is a trusted accessibility client.
    • Screen Recording: whether that process has screen-capture access.
    • Developer Tools: the DevToolsSecurity -status result and whether the current user is in the _developer or admin group, worded as authorization that may still prompt, not as a definite debugger failure.
    • Xcode tools: the active developer directory, and for each tool REA's native operations call, whether xcrun --find resolves it, plus /usr/bin/assetutil and swiftc.
  • The checks are informational by default, so existing healthy results do not change. They become required when the caller scopes doctor to native macOS readiness. The exact flag is left to the maintainers.
  • The checks never prompt and never change state. They must not call AXIsProcessTrustedWithOptions with the prompt option or CGRequestScreenCaptureAccess(), must not run DevToolsSecurity -enable, and must not trigger the Command Line Tools installation dialog.
  • Each privacy check names the process it evaluated and states its limitation: macOS grants apply to the process that asks, so a result from a terminal can differ from the result for an MCP server started by a client app. Results the check cannot establish are reported as unknown, never as granted.
  • The native-macos capability entries carry a readiness reason, or an unknown state, for operations whose prerequisite check failed. For example, observe_native_ui names Accessibility when it is not granted, instead of available: true, reason: null.
  • Off macOS the checks are absent or not applicable, as other platform-specific checks are today.

Acceptance criteria

  • With Accessibility not granted to the terminal running rea doctor --json, the Accessibility check is not ok and its remediation names System Settings > Privacy & Security > Accessibility. After granting it and starting a new process, the check is ok. No prompt appears in either run.
  • The Screen Recording check behaves the same way, with remediation that names Screen Recording under System Settings > Privacy & Security, and does not open the system request dialog.
  • On a host where DevToolsSecurity -status prints "Developer mode is currently disabled.", the Developer Tools check reports that status and the group membership it observed. After sudo DevToolsSecurity -enable, run by the person, it reports enabled.
  • Running DEVELOPER_DIR=/tmp/rea-empty-developer-dir rea doctor --json with an empty directory reports each tool in REA's xcrun list as unresolved. On a normal Xcode or Command Line Tools install, each resolves. assetutil and swiftc are reported separately.
  • With Accessibility not granted, rea capabilities --json gives observe_native_ui a reason or readiness state that names Accessibility, and inspect_macho stays available.
  • When the caller scopes doctor to native macOS readiness and Accessibility is not granted, the Accessibility check is a required failed check and healthy is false.
  • Existing doctor checks and the healthy result are unchanged when no native scope is requested. Doctor output on Linux and Windows is unchanged.

Expected interaction with targets

No target interaction (documentation or usability only)

Target and scope details (optional)

Affected area

The rea doctor command and the native-macos capability readiness, the doctor sections of docs/installation.md or docs/cli.md, and the host-requirement paragraph of docs/mcp-contracts.md.

Non-goals

  • Requesting, granting or resetting permissions, editing the TCC database, installing configuration profiles, or running DevToolsSecurity -enable or xcode-select --install.
  • Checking per-target conditions such as a target's hardened runtime or get-task-allow; inspect_signature already reports those.
  • Removing the operation-time checks. They stay authoritative, because grants can change between doctor and the call.

Verification available so far

I can suggest a sample or manual check

Verification details (optional)

No response

Alternatives considered

  • Documenting the prerequisites only: this does not tell an agent the state of this host, and the capability list would still report every operation as available.
  • Probing by running a real native operation against a disposable target: this has side effects (process launch, UI) and can itself trigger prompts.

Possible direction

No response

References

  • AXIsProcessTrusted(): "Returns whether the current process is a trusted accessibility client." AXIsProcessTrustedWithOptions(_:) documents kAXTrustedCheckOptionPrompt, "indicating whether the user will be informed if the current process is untrusted", which a doctor check must not set.
  • CGPreflightScreenCaptureAccess() (macOS 10.15+) is the call REA's helper already uses. Apple also documents a separate CGRequestScreenCaptureAccess(). Neither page has a description in the corpus, so the no-prompt behavior of the preflight call should be confirmed by the implementer.
  • Apple Platform Security, Controlling app access to files: "accessibility and automation capabilities require user permission to help ensure that they don't circumvent other protections. Depending on the access policy, users may be asked, or required, to change the setting in" System Settings > Privacy & Security > Privacy. Protecting app access to user data lists "Screen recording (for example, static screen shots and video)" among the macOS permissions users grant or revoke.
  • PrivacyPreferencesPolicyControl.Services, ScreenCapture: "A profile can't grant access to the contents; it can only deny it." Even managed Macs therefore need a person to grant Screen Recording, which makes an early report more valuable.
  • Installing the command-line tools: "Commands such as xcodebuild and xctrace only ship with Xcode, and aren't in the Command Line Tools for Xcode package", and "On a fresh install of macOS, invoking any command in Xcode or the command-line tools package (such as git) from the command line prompts you to download and install the Command Line Tools for Xcode package." The tool check must detect absence without causing that prompt.
  • DevToolsSecurity(8) (macOS 27.0 manual page): "a user who is a member of either the admin group or the _developer group does not need to enter an additional password to use the Apple-code-signed debugger or performance analysis tools."
  • GitHub searches for "doctor accessibility", "Screen Recording permission", "DevToolsSecurity", "doctor permissions", "TCC" and "Xcode command line tools" found no request for these checks. Related but different: #381 (resettable macOS VM with TCC reset), #3376 and #3385 (accessibility inventory reporting bugs at call time), and closed #497 (the original native UI observation feature).
Originally created by @coygeek on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4311 ### Before submitting - [X] I searched the open and closed issues and pull requests for a related proposal. - [X] I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here. - [X] This request does not include credentials, private samples, or sensitive target data. ### Area Provider or capability discovery ### Current limitation On macOS, make `rea doctor` and the native-macos capability readiness report the host prerequisites that REA's native operations depend on: Accessibility trust, Screen Recording access, Developer Tools debugging authorization, and availability of the Xcode command-line tools REA invokes. Today each of these surfaces only when an operation fails partway, and the capability list reports every native operation as available on any Mac. An agent preparing to observe a native UI or trace calls on macOS cannot learn in advance whether the host will allow it. Measured with REA 6.5.0 (`npx -y rea-agents@6.5.0`, tag `rea-agents-6.5.0`, commit `3b79af28e80785afce9f5998d8f03289402a1847`) on macOS 27.0.1 (26A434) arm64 with Xcode 27.0 (27A266a) and Node.js v26.10.0: - `rea doctor --json` returned checks named `node`, `host`, `hopper`, `ghidra`, `ida-registration`, `jadx`, `skill:identity` and per-client `registration:*`, and none about Accessibility, Screen Recording, Developer Tools or Xcode tools. The system doctor host adds provider inspections for Ghidra, IDA and JADX and a Linux display check, and nothing for macOS host permissions ([doctorRuntime.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/doctorRuntime.ts#L24-L31)). - On the same host `DevToolsSecurity -status` printed "Developer mode is currently disabled.", while `rea capabilities --json` listed `observe_native_calls`, `capture_native_ui_scenario` and `observe_native_ui` with `available: true` and `reason: null`. Native capability availability depends only on `platform === "darwin"` ([NativeMacOSProviderMetadata.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/NativeMacOSProviderMetadata.ts#L20-L35)). - Accessibility and Screen Recording are checked inside the compiled UI helper, at call time: `CGPreflightScreenCaptureAccess()` produces `screen-recording-denied` and `AXIsProcessTrusted()` produces `accessibility-denied` ([ReaNativeUI.swift](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/bridge/native/ReaNativeUI.swift#L73-L78)). Compiling that helper first requires `xcrun swiftc` ([NativeUiHelperRuntime.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/NativeUiHelperRuntime.ts#L40-L42)). - Debugging authorization appears only as remediation text after LLDB is refused: "Allow debugging for this user (Developer Tools access: `DevToolsSecurity -enable`, or membership in the _developer group)." ([LldbCallTracer.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/LldbCallTracer.ts#L166-L167)). - Static native tools resolve `codesign`, `dyld_info`, `dwarfdump`, `file`, `lipo`, `nm`, `otool`, `plutil`, `strings`, `swift-demangle` and `vtool` through `xcrun --find` at call time ([CommandRunner.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/CommandRunner.ts#L279-L303)), and asset catalogs need `/usr/bin/assetutil` ([AppleAssetCatalogAnalysis.ts](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/artifacts/apple/AppleAssetCatalogAnalysis.ts#L17)). - The MCP contract states the design: "macOS may deny Accessibility, Screen Recording, or native mounting ... These failures are reported at the operation that needs them." ([docs/mcp-contracts.md](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/docs/mcp-contracts.md#L492-L496)). For an unattended agent, discovering these one failed call at a time costs turns. Some of them also need a person to act in System Settings, and `DevToolsSecurity(8)` says that without the policy "the user is queried for an administator password" (spelling as in the manual page) the first time a debugger examines one of the user's processes in a login session. Main at `d52a488` adds Kuna and request-budget handling to doctor but no macOS host checks. ### Use cases _No response_ ### Desired outcome and success criteria - On macOS, `rea doctor` reports these named checks, each with `ok`, classification, detail and remediation in the existing doctor format: - Accessibility: whether the process running the check is a trusted accessibility client. - Screen Recording: whether that process has screen-capture access. - Developer Tools: the `DevToolsSecurity -status` result and whether the current user is in the `_developer` or `admin` group, worded as authorization that may still prompt, not as a definite debugger failure. - Xcode tools: the active developer directory, and for each tool REA's native operations call, whether `xcrun --find` resolves it, plus `/usr/bin/assetutil` and `swiftc`. - The checks are informational by default, so existing `healthy` results do not change. They become required when the caller scopes doctor to native macOS readiness. The exact flag is left to the maintainers. - The checks never prompt and never change state. They must not call `AXIsProcessTrustedWithOptions` with the prompt option or `CGRequestScreenCaptureAccess()`, must not run `DevToolsSecurity -enable`, and must not trigger the Command Line Tools installation dialog. - Each privacy check names the process it evaluated and states its limitation: macOS grants apply to the process that asks, so a result from a terminal can differ from the result for an MCP server started by a client app. Results the check cannot establish are reported as unknown, never as granted. - The native-macos capability entries carry a readiness reason, or an `unknown` state, for operations whose prerequisite check failed. For example, `observe_native_ui` names Accessibility when it is not granted, instead of `available: true, reason: null`. - Off macOS the checks are absent or not applicable, as other platform-specific checks are today. **Acceptance criteria** - With Accessibility not granted to the terminal running `rea doctor --json`, the Accessibility check is not ok and its remediation names System Settings > Privacy & Security > Accessibility. After granting it and starting a new process, the check is ok. No prompt appears in either run. - The Screen Recording check behaves the same way, with remediation that names Screen Recording under System Settings > Privacy & Security, and does not open the system request dialog. - On a host where `DevToolsSecurity -status` prints "Developer mode is currently disabled.", the Developer Tools check reports that status and the group membership it observed. After `sudo DevToolsSecurity -enable`, run by the person, it reports enabled. - Running `DEVELOPER_DIR=/tmp/rea-empty-developer-dir rea doctor --json` with an empty directory reports each tool in REA's `xcrun` list as unresolved. On a normal Xcode or Command Line Tools install, each resolves. `assetutil` and `swiftc` are reported separately. - With Accessibility not granted, `rea capabilities --json` gives `observe_native_ui` a reason or readiness state that names Accessibility, and `inspect_macho` stays available. - When the caller scopes doctor to native macOS readiness and Accessibility is not granted, the Accessibility check is a required failed check and `healthy` is false. - Existing doctor checks and the `healthy` result are unchanged when no native scope is requested. Doctor output on Linux and Windows is unchanged. ### Expected interaction with targets No target interaction (documentation or usability only) ### Target and scope details (optional) **Affected area** The `rea doctor` command and the native-macos capability readiness, the doctor sections of `docs/installation.md` or `docs/cli.md`, and the host-requirement paragraph of `docs/mcp-contracts.md`. **Non-goals** - Requesting, granting or resetting permissions, editing the TCC database, installing configuration profiles, or running `DevToolsSecurity -enable` or `xcode-select --install`. - Checking per-target conditions such as a target's hardened runtime or `get-task-allow`; `inspect_signature` already reports those. - Removing the operation-time checks. They stay authoritative, because grants can change between doctor and the call. ### Verification available so far I can suggest a sample or manual check ### Verification details (optional) _No response_ ### Alternatives considered - Documenting the prerequisites only: this does not tell an agent the state of this host, and the capability list would still report every operation as available. - Probing by running a real native operation against a disposable target: this has side effects (process launch, UI) and can itself trigger prompts. ### Possible direction _No response_ ### References - [AXIsProcessTrusted()](https://developer.apple.com/documentation/applicationservices/1460720-axisprocesstrusted): "Returns whether the current process is a trusted accessibility client." [AXIsProcessTrustedWithOptions(_:)](https://developer.apple.com/documentation/applicationservices/1459186-axisprocesstrustedwithoptions) documents `kAXTrustedCheckOptionPrompt`, "indicating whether the user will be informed if the current process is untrusted", which a doctor check must not set. - [CGPreflightScreenCaptureAccess()](https://developer.apple.com/documentation/coregraphics/cgpreflightscreencaptureaccess()) (macOS 10.15+) is the call REA's helper already uses. Apple also documents a separate [CGRequestScreenCaptureAccess()](https://developer.apple.com/documentation/coregraphics/cgrequestscreencaptureaccess()). Neither page has a description in the corpus, so the no-prompt behavior of the preflight call should be confirmed by the implementer. - Apple Platform Security, [Controlling app access to files](https://support.apple.com/guide/security/controlling-app-access-to-files-secddd1d86a6/1/web/1): "accessibility and automation capabilities require user permission to help ensure that they don't circumvent other protections. Depending on the access policy, users may be asked, or required, to change the setting in" System Settings > Privacy & Security > Privacy. [Protecting app access to user data](https://support.apple.com/guide/security/protecting-app-access-to-user-data-secc01781f46/1/web/1) lists "Screen recording (for example, static screen shots and video)" among the macOS permissions users grant or revoke. - [PrivacyPreferencesPolicyControl.Services](https://developer.apple.com/documentation/devicemanagement/privacypreferencespolicycontrol/services-data.dictionary), `ScreenCapture`: "A profile can't grant access to the contents; it can only deny it." Even managed Macs therefore need a person to grant Screen Recording, which makes an early report more valuable. - [Installing the command-line tools](https://developer.apple.com/documentation/xcode/installing-the-command-line-tools): "Commands such as `xcodebuild` and `xctrace` only ship with Xcode, and aren't in the Command Line Tools for Xcode package", and "On a fresh install of macOS, invoking any command in Xcode or the command-line tools package (such as `git`) from the command line prompts you to download and install the Command Line Tools for Xcode package." The tool check must detect absence without causing that prompt. - `DevToolsSecurity(8)` (macOS 27.0 manual page): "a user who is a member of either the admin group or the _developer group does not need to enter an additional password to use the Apple-code-signed debugger or performance analysis tools." - GitHub searches for "doctor accessibility", "Screen Recording permission", "DevToolsSecurity", "doctor permissions", "TCC" and "Xcode command line tools" found no request for these checks. Related but different: #381 (resettable macOS VM with TCC reset), #3376 and #3385 (accessibility inventory reporting bugs at call time), and closed #497 (the original native UI observation feature).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1715
No description provided.