Skip to content

macOS permission-free window-origin lookup: window-relative replay resolution goes live#94

Merged
mohabbis merged 1 commit into
masterfrom
claude/ghost-strategy-ratification-jqecf6
Jul 3, 2026
Merged

macOS permission-free window-origin lookup: window-relative replay resolution goes live#94
mohabbis merged 1 commit into
masterfrom
claude/ghost-strategy-ratification-jqecf6

Conversation

@mohabbis

@mohabbis mohabbis commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the platform gap left deliberately open in #91: the window-relative resolution strategy (find the recorded window by title, click at the recorded in-window offset, verify the descriptor) now works on macOS — with no new permission and no new crate. Everything runs under the Accessibility permission replay already requires.

Trust & safety

  • Touches files / filesystem mutation: none
  • Touches OS input: replay-time only — the same resolution chain gains a working strategy on macOS; every candidate point is still descriptor-verified before any click, and failures fall through exactly as before
  • Touches screenshots / screen contents: no — explicitly avoids CGWindowList, which would require the Screen Recording permission; window titles/positions are read via the AX API already covered by the Accessibility grant
  • Touches network: none
  • Touches authentication / secrets: none
  • Touches app / window state: reads process names (libproc) and the matched app's window titles/positions during approved replay, only when the recorded-point match already failed

Pipeline checklist:

  • Risky actions remain deny-by-default
  • No silent delete or silent overwrite
  • New Tauri commands: none
  • Experimental features stay gated

Changes

  • core/replay_support.rs: the window_origin closure now receives the full recorded ElementInfo (macOS needs app to find the owning process; Windows keeps title-only FindWindowA, behavior unchanged). Mechanical updates to the Windows wrapper, unit tests, and the benchmark harness — all 13 benchmark scenarios pass unchanged.
  • platform/macos.rs::find_window_origin: libproc pid enumeration (proc_listallpids/proc_name — part of libSystem) → process-name match against the recorded app (including the 32-byte proc_name truncation) → AXWindows walk of the matched app → AXTitle match → AXPosition origin (decode extracted into ax_element_origin, shared with capture). Best-effort at every step; strict CFRelease discipline; CFArray elements follow the get-rule and are never released.
  • Unit tests on the macOS CI leg: proc-name matching (exact, case-insensitive, truncation, no short-prefix false positives) and find_window_origin's pure pre-FFI gates.
  • Docs: docs/target-resolution.md platform section, CLAUDE.md accounting.

Validation

  • cargo fmt -- --check, cargo check --all-targets, cargo clippy --all-targets -- -D warnings
  • cargo test — 348 passed, 0 failed; --test resolution_benchmark 13/13
  • No experimental-gated code touched

CI must confirm the macOS leg (new libproc/CFArray FFI compiles; new unit tests run) and the Windows leg (closure change). The live AXWindows walk cannot run on a headless runner — it joins the manual macOS smoke list (move a window across the screen mid-replay; the trace should show WindowRelative).

Risks / follow-up

  • proc_name matches the process name, which normally equals the AX app title but can diverge (e.g. localized app names). Divergence degrades gracefully to today's behavior (spiral/fallback), never mis-clicks — the candidate is descriptor-verified.
  • Duplicate window titles within one app resolve to the first AXWindows match; descriptor verification guards the click, same trade-off as Windows' FindWindowA.

🤖 Generated with Claude Code

https://claude.ai/code/session_019gj5w7gNG2fJpNEE1buXc4


Generated by Claude Code

…eplay live on macOS

The window-relative resolution strategy (#91) was deliberately inert on
macOS pending a design that avoids new permissions. This wires it,
entirely under the Accessibility permission replay already requires:

- The resolution chain's window_origin closure now receives the full
  recorded ElementInfo instead of just the title — macOS needs the
  recorded app name to locate the owning process; Windows keeps using
  only the title (FindWindowA), behavior unchanged. Benchmark and unit
  tests updated mechanically; all 13 scenarios still pass.
- find_window_origin (platform/macos.rs): libproc pid enumeration
  (proc_listallpids/proc_name — libSystem, no new crate, no new
  permission), process-name match against the recorded app including
  the 32-byte proc_name truncation, then an AXWindows walk of the
  matched app for an AXTitle match whose AXPosition supplies the
  origin. Deliberately NOT CGWindowList, which would require the
  Screen Recording permission. Best-effort at every step: any failure
  returns None and the chain falls through to the spiral / recorded
  coordinates exactly as before.
- AXPosition decoding extracted into ax_element_origin (shared with
  capture's window_info_for). New CFArray FFI follows the existing
  extern-block style; array elements follow the CF get-rule and are
  never released.
- Unit tests (macOS CI leg): proc-name matching incl. truncation and
  the no-short-prefix case; find_window_origin's pure pre-FFI gates.
- docs/target-resolution.md platform section + CLAUDE.md accounting
  updated.

Validation: fmt, clippy -D warnings, 348 tests + 13/13 resolution
benchmark on Linux/headless. The macOS FFI compiles and its unit tests
run only on the macOS CI leg; the live AXWindows walk needs a real
macOS session — added to the manual smoke list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019gj5w7gNG2fJpNEE1buXc4
@netlify

netlify Bot commented Jul 3, 2026

Copy link
Copy Markdown

Deploy Preview for muhammadghost ready!

Name Link
🔨 Latest commit 6705a02
🔍 Latest deploy log https://app.netlify.com/projects/muhammadghost/deploys/6a47f7bdbb79d30008d51c2b
😎 Deploy Preview https://deploy-preview-94--muhammadghost.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ghost Ready Ready Preview, Comment Jul 3, 2026 5:56pm

@mohabbis mohabbis marked this pull request as ready for review July 3, 2026 17:57
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@mohabbis mohabbis merged commit fc8d332 into master Jul 3, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants