A mobile AI agent needs an in-process runtime because an iPhone or Android app is not a smaller Linux server. App stores restrict downloaded executable code, operating systems isolate app data, background work has narrow purposes, and cross-app actions must pass through platform-approved interfaces. Moving the agent loop, file tools, scripting, and subagents into one process addresses part of that mismatch.
It does not create an App Store compliance certificate. This audit of PhoneBuddySDK found credible static evidence for a process-free Rust runtime, path jailing, bounded JavaScript, timeouts, cancellation, and native bindings. It also found claims that the public evidence does not support, including a passed-review claim and guaranteed FFI panic containment. The right conclusion is promising architecture with an incomplete verification stack.
Audit target: PhoneBuddySDK main commit c661ba0, reviewed 23 August 2026. The published v0.1.2 release points to an earlier commit, so main-branch findings should not be attributed to the release package without retesting.
TL;DR
- In-process execution solves a real mobile constraint: the audited Rust workspace contains no
std::process,tokio::process, or child-process launch path in its core crates. - Apple Guideline 2.5.2 still restricts downloaded or executed code that introduces or changes app functionality. An embedded JavaScript interpreter does not make that policy question disappear.
- Google Play prohibits downloading dex, JAR, and native libraries outside Play. It allows interpreter or VM code under conditions, but runtime-loaded scripts must still comply with every Play policy.
- PhoneBuddySDK has static controls for file boundaries, SSRF screening, tool timeouts, script loop limits, repeated-tool detection, cancellation, and Swift/Kotlin/C integration.
- The repository defines 174 Rust tests but has no public GitHub Actions workflow or Android instrumentation suite. This audit could not run the tests because the host lacked a Rust toolchain.
- No public App Store or Google Play review record was found. The README's passed-review claim remains a project assertion.
Why desktop agent architecture breaks on phones
Desktop coding agents often assume they can spawn shells, install packages, start child processes, read a broad filesystem, and remain alive for hours. Mobile platforms reverse those defaults.
Apple's App Review Guideline 2.5.2 says apps should be self-contained, stay inside their designated container, and avoid downloading, installing, or executing code that introduces or changes functionality. Guideline 2.5.4 limits background services to their intended purposes. Apple's background execution documentation also states that apps are normally suspended in the background and receive extra execution only through specific modes.
Google Play's Device and Network Abuse policy prohibits apps and SDKs from downloading executable dex, JAR, or .so files outside Play. Code running in a VM or interpreter has an exception, but runtime-loaded JavaScript, Python, or Lua must not enable policy violations. Foreground services must be useful, user-initiated or perceptible, and stoppable by the user.
These policies move the architecture toward a bounded runtime embedded inside a host app:
Host UI and permissions
-> typed tool boundary
-> in-process agent loop
-> bounded file, network, and script capabilities
-> durable session checkpoints
The host app remains responsible for permissions, user consent, platform APIs, and product policy. The runtime cannot grant itself powers that the operating system did not give the app.
This is an architectural baseline rather than an Android legal requirement. Android's Application Sandbox uses Linux user IDs and kernel enforcement across Java, Kotlin, native, and interpreted code. Android can support more than one app process. An in-process design is valuable here because it removes desktop shell assumptions and creates one inspectable capability boundary that can also run on iOS.
What PhoneBuddySDK actually implements
PhoneBuddySDK describes itself as a mobile adaptation of xAI's grok-build agent engine. Its workspace manifest disables Tokio's process feature and uses Rust-native components for HTTP, asynchronous tasks, file operations, and a Boa JavaScript engine.
Static inspection supports several concrete claims:
| Capability | Static evidence | Evidence level |
|---|---|---|
| No child-process tool path | No process dependency or launch call in the audited core crates | Source inspection |
| File jail | Sandbox::resolve performs lexical containment and canonicalized ancestor checks |
Source plus unit tests defined |
| Bounded scripting | run_script runs Boa with a 20 million iteration limit and a small host API |
Source plus unit tests defined |
| Tool timeout | The engine wraps built-in and host tools in a 120-second timeout | Source inspection |
| Repetition stop | The doom-loop guard nudges after eight identical calls and breaks after sixteen | Source plus unit tests defined |
| Cooperative task cancellation | The in-memory task manager propagates cancellation tokens and records terminal state | Source plus integration tests defined |
| Native host surface | C ABI, Swift wrapper, Kotlin/JNI wrapper, and demo apps are present | Source inspection and release artifacts |
This is useful engineering. It turns common desktop actions into explicit library calls and creates a place to enforce policy before the model touches a file, network endpoint, or host tool.
Five boundary tests before shipping
Feature lists are weak evidence. A mobile runtime needs a frozen test matrix that captures its real failure modes.
1. File boundary
Test relative traversal, absolute paths, existing symlinks, nonexistent descendants below a symlink, Unicode-confusable names, simultaneous symlink replacement, imported files, and OS file-provider handoffs.
PhoneBuddySDK's path resolver handles lexical traversal and canonicalizes existing paths or the deepest existing ancestor. That is stronger than checking a string prefix. It still needs device-level race tests around the interval between validation and file use. The app container is also only the outer boundary; the runtime should create a narrower workspace for each user or session.
2. Network boundary
Test public URLs, literal private addresses, public DNS resolving to private ranges, redirect chains, DNS changes, IPv6, oversized responses, slow streams, TLS failures, and user cancellation.
The SDK includes an SSRF guard that blocks loopback, private, link-local, and other non-public ranges during URL validation. Public evidence does not show an end-to-end redirect and DNS-rebinding suite. A preflight check and the actual HTTP connection must enforce the same destination policy.
The demo configurations also broaden transport policy: the Android manifest allows cleartext traffic, while the iOS demo enables NSAllowsArbitraryLoads. Those flags may help development against arbitrary gateways, but they require narrowing or explicit review justification before production.
3. Platform interface boundary
Test every tool against the permissions and public APIs the host app actually declares. On iOS, cross-app work should use capabilities such as App Intents, document pickers, share extensions, and approved frameworks. An App Intent is an action that the target app deliberately exposes to the system; it is not arbitrary GUI control over another app. On Android, Intents, scoped storage, foreground services, and other privileged surfaces must preserve consent and Play policy.
The audited repository exposes dynamic host tools in its C ABI, but the Kotlin wrapper does not expose every corresponding registration method. API parity should be tested mechanically across C, Swift, Kotlin, and the published headers.
4. Force-kill and restart boundary
Start a task, kill the app during the first model response, during a file write, between tool calls, and after the visible result but before session persistence. Relaunch and verify exactly which state survives.
PhoneBuddySDK saves sessions around completed turn steps. Its subagent tasks remain in memory. Cooperative cancellation therefore differs from OS process death. A durable task ledger needs an idempotency key, last committed step, external-side-effect record, and explicit resume policy.
The scheduler persists intent metadata and emits a generic host event. The iOS demo does not register BGTaskScheduler jobs, and the Android demo does not connect WorkManager or AlarmManager. A saved schedule definition is therefore not evidence that the operating system will wake the app and execute it.
5. Infinite-loop boundary
Test a JavaScript loop, repeated identical tool calls, alternating calls that evade exact repetition, a host tool that ignores cancellation, a slow network stream, and many concurrent subagents.
The current code has three useful limits: a Boa iteration budget, a 120-second tool timeout, and exact-call repetition detection. A blocking script may continue on its worker thread until Boa reaches its budget even after the outer future times out. Host callbacks also need deadlines and cancellation conformance tests.
In-process is necessary, not sufficient
The phrase in-process can hide three separate questions.
Can the code execute inside the app sandbox? PhoneBuddySDK's core design points in that direction.
May the app execute that code under store rules? Apple may treat remotely supplied scripts that change product behavior differently from static app logic. Google provides an interpreter exception but still evaluates what the scripts can do. Only a concrete app submission and review can settle the exact product configuration.
Can the runtime fail safely? That requires tests for data boundaries, network destinations, cancellation, persistence, permissions, and side effects. A single-process crash can take the entire host app down, so FFI and panic behavior matter more, not less.
Two claims the evidence does not support
The README at the audited commit says the SDK passes Apple App Store and Google Play sandbox reviews. No linked store listing, review record, TestFlight result, Play track, or approval artifact was found. Source compatibility with platform rules is not the same as product approval.
The repository guide also promises catch_unwind around C FFI boundaries. The audited FFI implementation contains no catch_unwind, while the release profile sets panic = "abort". Aborting prevents a Rust unwind from crossing the ABI, but it terminates the process instead of converting failure into a recoverable C error. Documentation should describe that behavior accurately.
A release evidence ladder
Use four separate labels when evaluating a mobile agent runtime:
- Project assertion: a README or architecture document says a control exists.
- Static evidence: code and dependency graphs implement the control.
- Repeatable test: the pinned release passes a published test command on supported targets.
- Product evidence: signed apps pass real-device tests, lifecycle tests, and the relevant store review.
PhoneBuddySDK reaches level two for many core controls. It contains 174 Rust test definitions and a downloadable v0.1.2 release, but the repository exposes no GitHub Actions runs and no Android instrumentation suite. The release tag also precedes the audited main commit by three commits. A green result for main would not automatically validate the distributed v0.1.2 package.
This is the content gap most comparisons miss. Competing mobile runtimes usually list on-device inference, tools, memory, and sandboxing. Google's official ADK for Android, Napaxi, agentlib, and remote-control frameworks represent different architectures. The meaningful comparison is a boundary matrix measured on the exact artifact users install.
ClawMobile provides a useful product counterexample. It has a public iOS App Store listing, while its iOS capability set is narrower than its Android control path: app-local tasks, shared content, artifacts, and skills replace broad Accessibility or ADB-style control. Store evidence validates that exact app configuration, not every capability in its repository and not another SDK.
A minimum shipping gate
Before calling a mobile agent runtime production-ready, require these artifacts:
- a commit and release-asset digest;
- green core, FFI, Swift, Kotlin, emulator, simulator, and real-device tests;
- a policy map from every dynamic capability to Apple and Google rules;
- negative tests for file escape, redirects, cancellation, restart, and repeated actions;
- a durable side-effect ledger and crash-recovery test;
- proof that documentation matches actual panic, timeout, permission, and background behavior;
- store-review evidence for the exact host app and enabled feature set.
An in-process runtime is the correct architectural starting point because it accepts the phone's real constraints. Its maturity is determined by the failures it can expose, contain, and recover from.
FAQ
Does zero child processes make an AI agent App Store compliant?
No. It removes one incompatible desktop assumption. Apple and Google also evaluate dynamic code, permissions, data access, background behavior, cross-app actions, harmful functionality, and the submitted product experience.
Can an iOS app run model-generated JavaScript?
The technical ability to interpret JavaScript does not settle Guideline 2.5.2. If downloaded or generated code introduces or changes app functionality, review risk remains. Educational apps have a limited exception with source visibility requirements. Product-specific review is required.
Does Google Play allow interpreter-based agent skills?
Play distinguishes interpreter or VM code from downloaded dex, JAR, and native libraries. Runtime scripts must still be prevented from enabling policy violations, unauthorized access, or sandbox bypass.
Is cooperative cancellation the same as killing a task?
No. A cancellation token works only when each component observes it. Blocking code, host callbacks, and OS process death require separate deadlines, termination behavior, and recovery tests.
Can an embedded agent control other apps?
Only through capabilities the platform and user grant to the host app. An in-process runtime does not bypass app isolation. Cross-app actions should use public, consented interfaces and remain inside store policy.