macOS-Trace: Autonomous Application Performance Optimization
macOS-Trace is a closed-loop performance optimization engine for native macOS applications (SwiftUI, AppKit, Metal, CoreAudio, WebKit, native binaries). Its core objective is to eliminate manual Instruments GUI interaction: an agent aligns on targets, captures headless traces, isolates hotspots, applies code fixes, re-tests with differential benchmarking, and iterates until performance targets are verified with empirical data.
Phase 1: User Goal Alignment (Pre-Flight Questionnaire)
Before modifying code or collecting traces, align with the user on optimization targets and success criteria. Use an interactive modal if available (ask_question, option lists); otherwise ask directly with structured options.
Primary Optimization Objective:
- A: Reduce CPU utilization, power consumption, and thermal throttling.
- B: Lower memory footprint / transient allocation spikes / eliminate leaks.
- C: Eliminate UI frame stuttering and dropped frames (Hitches).
- D: Accelerate cold launch time.
Specific Performance Targets (recommended defaults):
- CPU / Energy: idle < 20 M/s instructions, CPU Impact < 0.5; active < 100 M/s (or reduce 30–50%).
- Memory: resident RAM < 150 MB (utilities/audio) / < 300 MB (rich UI); allocation rate < 500 events/sec steady-state; 0 persistent leaks.
- UI Smoothness: hitch ratio < 5.0 ms/s (acceptable), < 1.0 ms/s (fluid/no dropped frames).
- Launch Time: time to first frame < 400 ms (excellent), < 800 ms (acceptable).
Benchmark User Scenario: ask which specific screen, interaction, or workload to benchmark.
Once targets are confirmed, proceed to Phase 2.
Scope and Prerequisites
- Target platform: macOS native desktop apps only (SwiftUI, AppKit, Metal, CoreAudio / AVAudioEngine, WebKit host views, native CLI executables). Does not support iOS simulators, remote mobile devices, or browser-only web apps.
- Xcode tooling: macOS 12+, full Xcode or Xcode Command Line Tools (
xcrun xctrace version).
- Hardware metrics:
Power Profiler and energy impact counters require Apple Silicon (M1/M2/M3/M4).
- Python: 3.8+ (standard library only, zero pip dependencies).
- Process permissions: debug builds or binaries with
get-task-allow entitlement are required for --attach <PID> under Hardened Runtime.
Rules for Agents
- Establish a baseline first: always capture an idle baseline (app open, workload paused) before the active workload. Compute
Delta = Active - Baseline.
- Verify target state before recording: confirm the process exists (
pgrep -x <name>) and the target feature is actively executing during the recording window.
- Keep the window in foreground: macOS throttles rendering/display links for occluded or minimized windows (
NSWindowOcclusionState) — an occluded window produces falsely low GPU/CPU readings.
- Use equal test parameters: identical durations (default 60s), display scales, window sizes, and input data. Never compare Debug vs Release builds.
- Zero third-party Python dependencies: bundled scripts use the standard library only (
compare_elements.py, parse_power.py, top_categories.py, top_time.py, activity_cpu.py, compare_cpu.py).
- Save outputs to
/tmp/macos-traces/: timestamped, scenario-tagged filenames.
- Protect context budget: never dump raw
.trace bundles, call-trees, or unparsed XML into the conversation — they can be hundreds of MB. Always stream/filter/rank via the bundled scripts before reading.
- Focus on primary bottlenecks: profile first to confirm the dominant contributor; don't scatter micro-optimizations across innocent utilities.
- Never silently alter UI, visual effects, or core behavior: if an optimization affects visual fidelity or essential behavior, formally ask the user first and articulate the exact before/after tradeoff with quantified expected gain.
- Clean up recording artifacts:
run_trace.sh auto-cleans the several-GB transient kernel traces (instruments*.ktrace in $TMPDIR). When running xctrace directly, clean them yourself before concluding:find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true
- Resolve
SKILL_DIR dynamically, never hardcode it: the skill's install path varies by host and agent (Claude Code: ~/.claude/skills/macos-trace; DSH: ~/.dsh/skills/macos-trace; project scope: <root>/.dsh/skills/macos-trace). Locate it before calling bundled scripts, and reference scripts only via "$SKILL_DIR/scripts/...".
- Never edit files inside the skill directory: if you need to adapt a bundled script, copy it to a temp directory first (e.g.
/tmp/my-trace-tools/), modify the copy, and run the copy. Keep the originals untouched so every run sees the same baseline.
- Check the hardware before choosing Power Profiler:
Power Profiler and energy counters require Apple Silicon (M1/M2/M3/M4). On Intel Macs use --template time (hot call-trees) + --template activity (per-process CPU ms/s) as the fallback pair, and never invent energy figures. See references/device-commands.md for exact process/launch commands.
The 4-Phase Optimization Protocol
Phase 2: Diagnostic Profiling & Attribution
APP_NAME="YourApp"
# Locate the skill install dir (path varies by host/agent; see Rule 11)
SKILL_DIR="$(ls -d "$HOME/.claude/skills/macos-trace" "$HOME/.dsh/skills/macos-trace" 2>/dev/null | head -1)"
[ -n "$SKILL_DIR" ] || SKILL_DIR="$(find "$HOME" -maxdepth 6 \( -type d -o -type l \) -name macos-trace 2>/dev/null | head -1)"
# Idle baseline (workload paused, window visible)
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "01-baseline"
# Active workload (user triggers the scenario in the app while this records)
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "02-pre-opt"
# Pre-optimization delta
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \
/tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt"
Non-Apple-Silicon fallback (Power Profiler requires Apple Silicon): use Time
Profiler for attribution and Activity Monitor for magnitude, then compare those
numbers:
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template time --duration 60s --label "01-baseline"
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template time --duration 60s --label "02-pre-opt"
python3 "$SKILL_DIR/scripts/top_time.py" /tmp/macos-traces/01-baseline-*-time.xml 15 --leaf
python3 "$SKILL_DIR/scripts/top_time.py" /tmp/macos-traces/02-pre-opt-*-time.xml 15 --leaf
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template activity --duration 30s --label "01-baseline"
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template activity --duration 30s --label "02-pre-opt"
python3 "$SKILL_DIR/scripts/compare_cpu.py" \
/tmp/macos-traces/01-baseline-*-actmon.xml:"Idle Baseline" \
/tmp/macos-traces/02-pre-opt-*-actmon.xml:"Active Pre-Opt" \
--process "$APP_NAME"
Compare avg CPU ms/s (compare_cpu.py) and top-function sample weights
(top_time.py) across runs; never report energy figures that Power Profiler
could not produce.
Attribute the bottleneck with specialized templates: --template time for hot call-trees, alloc with top_categories.py for allocation thrashing, hitches during UI interactions (scrolling, transitions, gestures) for render vs commit delays, sys for lock contention. See references/templates.md for the full template reference.
If the target workload requires interaction or reproduction (clicks, scrolling, gestures), read references/workload-reproduction.md before recording and decide which reproduction tier to use.
Phase 3: Targeted Code Modification
Apply minimal, surgical fixes based on findings:
- Real-time audio threads allocating heap memory? Replace with pre-allocated lock-free ring buffers.
- WebKit IPC saturated? Throttle state updates and switch to CSS transform animations.
- Metal fragment shader overdrawing on Retina? Add dynamic resolution scaling or pause offscreen render loops.
- Memory spikes from decoding large assets? Downsample images at decode time (
CGImageSourceCreateThumbnailAtIndex), decode video frames at playback size, or paginate PDF/large-document rendering instead of materializing full-resolution buffers.
Rebuild the application.
Phase 4: Re-Test, Quantitative Review & Decision Gate
# $SKILL_DIR = skill install dir, resolved as in Phase 2 (Rule 11)
# Post-optimization active workload
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "03-post-opt"
# Compare Pre-Opt vs Post-Opt against Baseline
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \
/tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt" \
/tmp/macos-traces/03-post-opt-power.xml:"Active Post-Opt"
Example Decision Output:
Scenario Sec CPU Avg CPU Max Display GPU Avg Total Instr Instr M/s
============================================================================================
Idle Baseline 60 0.15 0.80 0.05 0.00 1.02G 17.0
Active Pre-Opt 60 2.40 4.80 1.10 1.50 16.20G 270.0
Active Post-Opt 60 0.65 1.20 0.25 0.10 4.80G 80.0
----------------------------------------------------------------------------------------------
Optimization Delta (Post-Opt vs Pre-Opt):
Instruction throughput: -70.4% (80.0 vs 270.0 M/s)
CPU Average Impact: -72.9% (0.65 vs 2.40)
Decision Gate: target met → present the comparison table and conclude. Target not met → keep the current optimization, isolate the next hotspot, repeat Phases 3–4.
Post-Report Cleanup: after the user accepts the report, delete accumulated .trace bundles under /tmp/macos-traces/ (each can be tens of GB) unless the user asks to keep them.
Direct CLI
You may call xctrace directly instead of the bundled scripts. Run xcrun xctrace record --help and xcrun xctrace export --help for full options. You may also adapt the bundled scripts for a specific task — copy them to a temp directory first and modify the copies; never edit files inside the skill directory (Rule 12).
# Record an attached-process sample
xcrun xctrace record --template 'Time Profiler' --time-limit 60s \
--output /tmp/macos-traces/run.trace --attach $(pgrep -x YourApp)
# Export the Power Impact table
xcrun xctrace export --input /tmp/macos-traces/power.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \
> /tmp/macos-traces/power.xml
Reference Documents (load on demand)
references/templates.md — Instruments template picker (which template for which bottleneck).
references/subsystems.md — per-subsystem optimization patterns (audio, Metal, WebKit, UI/memory, media decoding).
references/workload-reproduction.md — how to reproduce the workload (Tier 0–2), including Accessibility-driven UI automation.
references/device-commands.md — exact process/launch/export commands, hardware template limits, Accessibility UI automation, and the script-copy rules.
1---2name: macos-trace3description: Autonomous closed-loop performance optimization engine for macOS applications using xctrace and Xcode Instruments. Handles the full lifecycle: aligning optimization targets with the user, headless diagnostic trace capture, isolating hotspots, implementing code fixes, re-testing with differential A/B verification, and iterating until performance goals are met without manual GUI intervention. Use when the user reports high CPU usage, memory growth or leaks, UI stutter or dropped frames, slow cold launch, audio dropouts, or thermal issues in a macOS application, and asks to profile, benchmark, or optimize it.4license: MIT5---67# macOS-Trace: Autonomous Application Performance Optimization89`macOS-Trace` is a closed-loop performance optimization engine for native macOS applications (SwiftUI, AppKit, Metal, CoreAudio, WebKit, native binaries). Its core objective is to eliminate manual Instruments GUI interaction: an agent aligns on targets, captures headless traces, isolates hotspots, applies code fixes, re-tests with differential benchmarking, and iterates until performance targets are verified with empirical data.1011---1213## Phase 1: User Goal Alignment (Pre-Flight Questionnaire)1415Before modifying code or collecting traces, align with the user on optimization targets and success criteria. Use an interactive modal if available (`ask_question`, option lists); otherwise ask directly with structured options.16171. **Primary Optimization Objective**:18 - A: Reduce CPU utilization, power consumption, and thermal throttling.19 - B: Lower memory footprint / transient allocation spikes / eliminate leaks.20 - C: Eliminate UI frame stuttering and dropped frames (Hitches).21 - D: Accelerate cold launch time.22232. **Specific Performance Targets (recommended defaults)**:24 - **CPU / Energy**: idle < 20 M/s instructions, CPU Impact < 0.5; active < 100 M/s (or reduce 30–50%).25 - **Memory**: resident RAM < 150 MB (utilities/audio) / < 300 MB (rich UI); allocation rate < 500 events/sec steady-state; 0 persistent leaks.26 - **UI Smoothness**: hitch ratio < 5.0 ms/s (acceptable), < 1.0 ms/s (fluid/no dropped frames).27 - **Launch Time**: time to first frame < 400 ms (excellent), < 800 ms (acceptable).28293. **Benchmark User Scenario**: ask which specific screen, interaction, or workload to benchmark.3031Once targets are confirmed, proceed to Phase 2.3233---3435## Scope and Prerequisites3637- **Target platform**: macOS native desktop apps only (SwiftUI, AppKit, Metal, CoreAudio / AVAudioEngine, WebKit host views, native CLI executables). Does not support iOS simulators, remote mobile devices, or browser-only web apps.38- **Xcode tooling**: macOS 12+, full Xcode or Xcode Command Line Tools (`xcrun xctrace version`).39- **Hardware metrics**: `Power Profiler` and energy impact counters require Apple Silicon (M1/M2/M3/M4).40- **Python**: 3.8+ (standard library only, zero pip dependencies).41- **Process permissions**: debug builds or binaries with `get-task-allow` entitlement are required for `--attach <PID>` under Hardened Runtime.4243---4445## Rules for Agents46471. **Establish a baseline first**: always capture an idle baseline (app open, workload paused) before the active workload. Compute `Delta = Active - Baseline`.482. **Verify target state before recording**: confirm the process exists (`pgrep -x <name>`) and the target feature is actively executing during the recording window.493. **Keep the window in foreground**: macOS throttles rendering/display links for occluded or minimized windows (`NSWindowOcclusionState`) — an occluded window produces falsely low GPU/CPU readings.504. **Use equal test parameters**: identical durations (default 60s), display scales, window sizes, and input data. Never compare Debug vs Release builds.515. **Zero third-party Python dependencies**: bundled scripts use the standard library only (`compare_elements.py`, `parse_power.py`, `top_categories.py`, `top_time.py`, `activity_cpu.py`, `compare_cpu.py`).526. **Save outputs to `/tmp/macos-traces/`**: timestamped, scenario-tagged filenames.537. **Protect context budget**: never dump raw `.trace` bundles, call-trees, or unparsed XML into the conversation — they can be hundreds of MB. Always stream/filter/rank via the bundled scripts before reading.548. **Focus on primary bottlenecks**: profile first to confirm the dominant contributor; don't scatter micro-optimizations across innocent utilities.559. **Never silently alter UI, visual effects, or core behavior**: if an optimization affects visual fidelity or essential behavior, formally ask the user first and articulate the exact before/after tradeoff with quantified expected gain.5610. **Clean up recording artifacts**: `run_trace.sh` auto-cleans the several-GB transient kernel traces (`instruments*.ktrace` in `$TMPDIR`). When running `xctrace` directly, clean them yourself before concluding:57 ```bash58 find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true59 ```6011. **Resolve `SKILL_DIR` dynamically, never hardcode it**: the skill's install path varies by host and agent (Claude Code: `~/.claude/skills/macos-trace`; DSH: `~/.dsh/skills/macos-trace`; project scope: `<root>/.dsh/skills/macos-trace`). Locate it before calling bundled scripts, and reference scripts only via `"$SKILL_DIR/scripts/..."`.6112. **Never edit files inside the skill directory**: if you need to adapt a bundled script, copy it to a temp directory first (e.g. `/tmp/my-trace-tools/`), modify the copy, and run the copy. Keep the originals untouched so every run sees the same baseline.6213. **Check the hardware before choosing Power Profiler**: `Power Profiler` and energy counters require **Apple Silicon** (M1/M2/M3/M4). On Intel Macs use `--template time` (hot call-trees) + `--template activity` (per-process CPU ms/s) as the fallback pair, and never invent energy figures. See `references/device-commands.md` for exact process/launch commands.6364---6566## The 4-Phase Optimization Protocol6768### Phase 2: Diagnostic Profiling & Attribution6970```bash71APP_NAME="YourApp"7273# Locate the skill install dir (path varies by host/agent; see Rule 11)74SKILL_DIR="$(ls -d "$HOME/.claude/skills/macos-trace" "$HOME/.dsh/skills/macos-trace" 2>/dev/null | head -1)"75[ -n "$SKILL_DIR" ] || SKILL_DIR="$(find "$HOME" -maxdepth 6 \( -type d -o -type l \) -name macos-trace 2>/dev/null | head -1)"7677# Idle baseline (workload paused, window visible)78"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "01-baseline"7980# Active workload (user triggers the scenario in the app while this records)81"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "02-pre-opt"8283# Pre-optimization delta84python3 "$SKILL_DIR/scripts/compare_elements.py" \85 /tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \86 /tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt"87```8889> **Non-Apple-Silicon fallback** (Power Profiler requires Apple Silicon): use Time90> Profiler for attribution and Activity Monitor for magnitude, then compare those91> numbers:92> ```bash93> "$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template time --duration 60s --label "01-baseline"94> "$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template time --duration 60s --label "02-pre-opt"95> python3 "$SKILL_DIR/scripts/top_time.py" /tmp/macos-traces/01-baseline-*-time.xml 15 --leaf96> python3 "$SKILL_DIR/scripts/top_time.py" /tmp/macos-traces/02-pre-opt-*-time.xml 15 --leaf97>98> "$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template activity --duration 30s --label "01-baseline"99> "$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template activity --duration 30s --label "02-pre-opt"100> python3 "$SKILL_DIR/scripts/compare_cpu.py" \101> /tmp/macos-traces/01-baseline-*-actmon.xml:"Idle Baseline" \102> /tmp/macos-traces/02-pre-opt-*-actmon.xml:"Active Pre-Opt" \103> --process "$APP_NAME"104> ```105> Compare avg CPU ms/s (compare_cpu.py) and top-function sample weights106> (top_time.py) across runs; never report energy figures that Power Profiler107> could not produce.108109Attribute the bottleneck with specialized templates: `--template time` for hot call-trees, `alloc` with `top_categories.py` for allocation thrashing, `hitches` during UI interactions (scrolling, transitions, gestures) for render vs commit delays, `sys` for lock contention. See `references/templates.md` for the full template reference.110111> **If the target workload requires interaction or reproduction** (clicks, scrolling, gestures), **read `references/workload-reproduction.md` before recording** and decide which reproduction tier to use.112113### Phase 3: Targeted Code Modification114115Apply minimal, surgical fixes based on findings:116- **Real-time audio threads allocating heap memory?** Replace with pre-allocated lock-free ring buffers.117- **WebKit IPC saturated?** Throttle state updates and switch to CSS transform animations.118- **Metal fragment shader overdrawing on Retina?** Add dynamic resolution scaling or pause offscreen render loops.119- **Memory spikes from decoding large assets?** Downsample images at decode time (`CGImageSourceCreateThumbnailAtIndex`), decode video frames at playback size, or paginate PDF/large-document rendering instead of materializing full-resolution buffers.120121Rebuild the application.122123### Phase 4: Re-Test, Quantitative Review & Decision Gate124125```bash126# $SKILL_DIR = skill install dir, resolved as in Phase 2 (Rule 11)127# Post-optimization active workload128"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "03-post-opt"129130# Compare Pre-Opt vs Post-Opt against Baseline131python3 "$SKILL_DIR/scripts/compare_elements.py" \132 /tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \133 /tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt" \134 /tmp/macos-traces/03-post-opt-power.xml:"Active Post-Opt"135```136137Example Decision Output:138139```text140Scenario Sec CPU Avg CPU Max Display GPU Avg Total Instr Instr M/s141============================================================================================142Idle Baseline 60 0.15 0.80 0.05 0.00 1.02G 17.0143Active Pre-Opt 60 2.40 4.80 1.10 1.50 16.20G 270.0144Active Post-Opt 60 0.65 1.20 0.25 0.10 4.80G 80.0145----------------------------------------------------------------------------------------------146Optimization Delta (Post-Opt vs Pre-Opt):147 Instruction throughput: -70.4% (80.0 vs 270.0 M/s)148 CPU Average Impact: -72.9% (0.65 vs 2.40)149```150151**Decision Gate**: target met → present the comparison table and conclude. Target not met → keep the current optimization, isolate the next hotspot, repeat Phases 3–4.152153**Post-Report Cleanup**: after the user accepts the report, delete accumulated `.trace` bundles under `/tmp/macos-traces/` (each can be tens of GB) unless the user asks to keep them.154155---156157## Direct CLI158159You may call `xctrace` directly instead of the bundled scripts. Run `xcrun xctrace record --help` and `xcrun xctrace export --help` for full options. You may also adapt the bundled scripts for a specific task — **copy them to a temp directory first and modify the copies; never edit files inside the skill directory** (Rule 12).160161```bash162# Record an attached-process sample163xcrun xctrace record --template 'Time Profiler' --time-limit 60s \164 --output /tmp/macos-traces/run.trace --attach $(pgrep -x YourApp)165166# Export the Power Impact table167xcrun xctrace export --input /tmp/macos-traces/power.trace \168 --xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \169 > /tmp/macos-traces/power.xml170```171172---173174## Reference Documents (load on demand)175176- `references/templates.md` — Instruments template picker (which template for which bottleneck).177- `references/subsystems.md` — per-subsystem optimization patterns (audio, Metal, WebKit, UI/memory, media decoding).178- `references/workload-reproduction.md` — how to reproduce the workload (Tier 0–2), including Accessibility-driven UI automation.179- `references/device-commands.md` — exact process/launch/export commands, hardware template limits, Accessibility UI automation, and the script-copy rules.