# Plan: GHA CI Executor — macOS Build + Peekaboo **Date**: 2026-05-14 **Status**: Planning ## Goal Migrate executor workers from Eagle's local Mac to GitHub Actions macOS runners: - Each task spawns a GHA job - Job installs Claude Code + Peekaboo + builds the app - Executor (Claude Code) runs the fix, opens PR, posts report to Asana - Eagle orchestrates: queues task → triggers GHA → monitors job → handles result ## Architecture ``` Eagle (orchestrator) → triggers GHA workflow via gh CLI ↓ GHA macOS runner (macos-15-xlarge or self-hosted) ↓ Install: Xcode, Claude Code, Peekaboo, Simulator ↓ claude -p executor-worker.md (non-interactive) ↓ Claude Code: fix → build → UI test via Peekaboo → PR ↓ Post result to Asana (gh pr comment + asana-bot) ``` ## Analysis Agent (Cloud-side) Separate from the executor worker: - Runs in Claude Cloud (or Eagle's Mac) - Picks task tagged "обработать" from Asana - Reads full task context (description, stories, user reports) - Generates detailed executor prompt (investigation plan + acceptance criteria) - Triggers GHA workflow with this prompt as input ## GHA Workflow Design ```yaml name: Executor Worker on: workflow_dispatch: inputs: task_gid: description: 'Asana task GID' executor_prompt: description: 'Base64-encoded executor prompt' branch_name: description: 'Git branch to create' jobs: executor: runs-on: macos-15 # or self-hosted M-series timeout-minutes: 120 steps: - uses: actions/checkout@v4 - name: Install Claude Code run: npm install -g @anthropic-ai/claude-code - name: Install Peekaboo run: # brew install or download binary - name: Bootstrap Xcode run: # select Xcode version, accept license - name: Run Executor env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_CI_KEY }} ASANA_TOKEN: ${{ secrets.ASANA_CI_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "${{ inputs.executor_prompt }}" | base64 -d > /tmp/prompt.md claude -p /tmp/prompt.md \ --branch "${{ inputs.branch_name }}" \ --no-interactive - name: Post Result if: always() run: # Post summary to Asana task + open PR if not already ``` ## Research Findings (2026-05-14) ### GHA macOS Runners — Current State - `macos-15` is current `macos-latest` (since Sep 2025) - Xcode max 3 simulator runtimes per image (since Aug 11, 2025) - **Simulators work fine on GHA** — iOS Simulator runs headless without display server - XCUITests run via `xcodebuild test` on Simulator → headless OK, no Screen Recording needed ### Peekaboo on GHA — The Problem Peekaboo requires: 1. **Screen Recording** permission (TCC) — for `ScreenCaptureKit` 2. **Accessibility** permission (TCC) — for AX tree traversal 3. Runs on **macOS 15+ (Sequoia)** On GHA macOS runners: - TCC permissions can be pre-granted via `tccutil reset` + `tccutil insert` — but requires SIP disabled or specific entitlements - GHA macOS runners run **with SIP enabled** — `tccutil insert` won't work without sudo tricks - **Peekaboo CLI needs the Mac App running as a bridge** (Unix socket IPC) for privileged operations **Conclusion: Peekaboo on GHA hosted runner = NOT viable out of the box.** Would need: - Self-hosted macOS runner (Eagle itself, or a dedicated Mac) - OR: use ddg-vm to spin a VM on Eagle, run Peekaboo inside VM (current CI pattern) ### XCUITest on GHA — Works Fine Our current CI already runs `macOS UI Tests CI` scheme on GHA via ddg-vm VMs. The issue isn't XCUITest — it's **visual/Peekaboo-based** reproduction that's GHA-incompatible. ### Two-Tier Approach (Recommended) ``` Analysis Agent (Claude Cloud / Eagle) ↓ reads Asana task, generates prompt ↓ triggers GHA workflow GHA macOS runner: ↓ checkout + build (cached DerivedData) ↓ claude -p executor-worker.md (non-interactive) ↓ fix code, run unit + UI tests via Simulator (NO Peekaboo) ↓ open draft PR For visual reproduction / Peekaboo validation: → spawn ddg-vm (existing infra) from Eagle or from GHA via SSH → VM has Peekaboo pre-installed + permissions granted ``` ### Claude Code Non-Interactive on GHA `claude -p prompt.md` works non-interactively. Needs: - `ANTHROPIC_API_KEY` in secrets - `--dangerously-skip-permissions` flag (all tools pre-approved) or tool allowlist GHA secret: `ANTHROPIC_CI_KEY` — separate from user key. ## Validation Steps Before full implementation: 1. Test prod build on `macos-15` runner: does it succeed without signing? 2. Test Peekaboo install + basic screenshot on GHA runner 3. Test `claude -p` with a simple prompt on GHA runner 4. Verify DerivedData caching works (build time < 10 min cached) ## Phased Implementation ### Phase 1: Validation (1-2 days) - Create a test GHA workflow that: checks out repo, builds, runs basic UI test - Verify Peekaboo accessibility permissions on headless runner - Document what works / what doesn't ### Phase 2: Claude Code Integration (2-3 days) - Add Claude Code step to workflow - Test with a trivial fix prompt - Verify PR creation from GHA bot context ### Phase 3: Analysis Agent (3-5 days) - Cloud-side agent that picks Asana tasks + generates prompts - Triggers GHA workflow via `gh workflow run` - Monitors job, posts result to Asana ### Phase 4: Eagle Integration (1 day) - Eagle can trigger Phase 3 analysis agent on demand - `#executor` topic shows GHA job status - Auto-approval for GHA-spawned actions ## Relation to Sentry Bot Sentry bot pattern (already working): - Cloud agent monitors Sentry errors - Generates structured report - Posts to Asana/Slack GHA executor follows same pattern: - Cloud agent picks Asana bug tasks - Generates fix prompt - GHA runner executes fix + validation ## Notes - GHA macos-15 runners do NOT have Xcode pre-cached — each run installs from scratch - Self-hosted runner on Eagle avoids this but ties up the main Mac - DuckDuckGo likely has existing GHA macOS setup — check existing workflows first - Peekaboo may need `tccutil` or System Preferences pre-grant on runner