Phone-local AI toolchain: layers, switching, and bounded acceptance

简体中文 · English

This lab composes six repositories without copying their installation logic.

Ownership

Layer Repository Success condition
Android, Termux, Kali PRoot pocket-pentest Base runtime starts and privilege boundaries are explicit
OpenCode, Claude Code, local Happy stack, and Mobile Lab Control android-ai-stack CLI/TUI/Web, local server/daemon, and three native widgets pass separately
User-facing assistant and action layer xiaohei-phone-agent Invocation, short command, risk policy, action, global stop, and rollback have independent state and evidence
On-device interaction evidence android-device-test Prefer text assertions; capture one screenshot only when needed
Optional remote Happy relay happy-relay-deploy Add only for an explicit remote-access requirement
Cross-repository review this hub Facts, inferences, unknowns, versions, and dates remain traceable

The default phone is a self-contained control plane: the Happy app connects to the server on phone loopback, and its daemon and Claude Code are also local. Model inference may still use a cloud or private-relay URL/token. A remote Happy relay is not a prerequisite.

Minimal sequence

  1. Record device, Android, Termux, Kali, and tool versions without serials or credentials.
  2. Run quick, tui, and web-start from android-ai-stack: zero model calls.
  3. Only after they pass, make one exact-echo request from OpenCode and one from Claude.
  4. Perform one complete Happy-app message round trip; a connected badge is not end-to-end proof.
  5. Use Xiaohei’s explicit entry to run one deterministic low-risk action. Select a model profile only for a planning case, and verify that profile change did not start or stop services.
  6. Stop at the first failure and retain at most 60 redacted log lines. Change one cause before one retry.

Phone control surface

Keep model configuration separate from service lifecycle. ai-model use PROFILE changes configuration only; Happy and llama.cpp have explicit, independent controls. The native Mobile Lab Control app exposes three widgets that can be placed separately: Happy, llama.cpp, and Model profiles. The first two manage only their service lifecycle, while the model widget changes configuration only. If a profile changes while Happy is running, its status becomes STALE until the operator chooses to restart it.

The app requests the Termux command permission but no Internet permission. A phone-local mode-0600 mapping gives fixed slots readable labels without exposing tokens, endpoint URLs, or the CC Switch database to the app. The public repository contains bilingual UI, complete source, the allow-listed bridge, deploy/validate Skills, CI builds, and a release-signed APK. Version 0.3.0 completed the three-widget device exercise; public version 0.4.0 then generalized configuration, added English/Chinese localization and scoped widget state, and passed repository tests plus APK build, permission, and signature checks. Moving once from a debug-signed build to the public signature requires uninstalling the old app and re-adding the widgets.

The verified optional fallback is Qwen3 0.6B Q8 through llama.cpp with context 8192, one request slot, and four CPU threads. It passed a short no-tool local-lite OpenCode case but not the default build-agent budget. Keep it loopback-only, authenticated, and stopped when unused; exact evidence belongs in the android-ai-stack case study.

The result must report each layer as PASS, FAIL, BLOCKED, or NOT TESTED and state the model-call count. “Installed” must not be rewritten as “working.”

Xiaohei is the product action layer in this chain, not a sixth runtime. It reuses model profiles and device evidence while owning invocation, bounded sessions, risk policy, confirmation, and rollback. Base mode does not depend on root, pocket-pentest, or a remote Happy relay.