You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pnpm check:unit outside sandbox: 247 unit files, 2332 unit tests, 8 smoke tests.
pnpm format.
git diff --check.
Android emulator E2E:
Emulator: emulator-5554, Pixel 9 Pro XL API 37.
App/package: com.justforfun.neoncity.
Session: perf-e2e-696.
Baseline perf metrics and perf frames succeeded with compact JSON.
Perfetto start/stop succeeded and pulled /private/tmp/agent-device-696-app.perfetto-trace at 5,392,410 bytes.
Simpleperf reached the device binary but the emulator denied perf_event_open; the command returned the intended actionable hint to use a debuggable/profileable app or system image that permits profiling.
SkillGym case was added but not runnable in the sandbox because external runner approval was denied.
This PR is Android-only. iOS native profiling remains separate.
Verdict: significant issues — solid scaffolding and bounded outputs, but lifecycle gaps (default stop path, double-start, artifact integrity on stop) need fixing before merge.
Findings
Major — src/daemon/handlers/session-native-perf.ts:156,192 + :218-233: stop without --out passes the session's absolute active.outPath as fallbackFileName into pathJoinSessionArtifact, producing a mangled nested path like <sessionDir>/2026-06-11T...-/home/user/.../cpu.perf.data instead of reusing the outPath that start advertised. Should be if (!requestedPath) return active.outPath. The daemon test always passes --out on stop, so this path is untested and masked.
Major — src/daemon/handlers/session-native-perf.ts:127-136,179-188: start never checks for an already-running session.nativePerf.android session. A second perf cpu profile start (or a perf trace start while simpleperf runs — the single android slot is shared across both kinds) silently overwrites the stored session, orphaning the previous on-device process for up to the 60-minute cap and leaking its remote artifact with no way to stop or pull it.
Major — src/platforms/android/perf-native.ts:386-392 + :204-212: stop sends SIGINT, waits at most 2 s, sends SIGTERM, and returns — adb pull then races the profiler still flushing perf.data/the perfetto trace. Simpleperf's post-SIGINT write easily exceeds 2 s for non-trivial profiles, yielding a truncated artifact reported as a successful stop with a valid size.
Minor — src/platforms/android/perf-native.ts:294-306,402-421: no device-side cleanup — remotePath is never rm'd after pull, and the stderr temp file is only removed on the failure branch, so every successful start leaks an .err file in /data/local/tmp.
Minor — daemon restart or session close mid-profile loses the in-memory nativePerf state with no kill/cleanup hook, orphaning the device profiler (mitigated by the 3600 s hard cap, but worth a cleanup hook on session delete).
Minor — src/platforms/android/perf-native.ts:12,408-410: adb pull reuses the 30 s ANDROID_NATIVE_PROFILE_TIMEOUT_MS; long runs can produce hundreds of MB, and stop then fails after the profiler was already killed.
Minor — src/platforms/android/perf-native.ts:318 vs :260-262: perfetto --background-wait is only available on Android 12+ while the unavailable-hint promises "Android 10+"; on 10/11 the flag fails with a confusing error rather than the actionable hint.
Minor (tests) — the perfetto collector path has zero unit coverage (only the iOS-rejection case is tested), and there are no tests for double-start or stop-without---out (which would have caught findings 1–2).
Verified clean
Command injection — composed shell strings consistently use shellQuote, remotePath is built from a sanitized package name, and the unquoted pidof <package> argv matches existing repo convention. Output boundedness — report entries capped at 50, compact projections, report JSON kept on disk.
Overall
The seams (injectable executor, compact projections, actionable hints) are well designed and quoting discipline is good, but session lifecycle is the weak spot — the default stop path bug, the unguarded double-start, and the 2-second flush window are real correctness risks agents will hit in normal use. Note also high merge-conflict risk with #755/#756/#759 on the shared perf contract/CLI grammar files (see the cross-PR note on #755) — these should land sequentially with deliberate reconciliation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Android native profiling collectors under the consolidated
perffamily for #694.perf cpu profile start|stop|report --kind simpleperfandperf trace start|stop --kind perfettoacross command contracts, CLI grammar, daemon routing/projection, typed client metadata, MCP-facing input, and compact output.Refs #696
Refs #694
Touched files: 24.
Validation
Worker validation passed:
pnpm check:quick.pnpm build.pnpm check:unitoutside sandbox: 247 unit files, 2332 unit tests, 8 smoke tests.pnpm format.git diff --check.Android emulator E2E:
emulator-5554, Pixel 9 Pro XL API 37.com.justforfun.neoncity.perf-e2e-696.perf metricsandperf framessucceeded with compact JSON./private/tmp/agent-device-696-app.perfetto-traceat 5,392,410 bytes.perf_event_open; the command returned the intended actionable hint to use a debuggable/profileable app or system image that permits profiling.SkillGym case was added but not runnable in the sandbox because external runner approval was denied.
This PR is Android-only. iOS native profiling remains separate.