Files
Jane Alesi ad8c738160 feat(spec): add 003-autonomous-agent-control specification
Spec for full AI agent mobile control capability:
- Voice call control (dial/answer/hangup/status/list)
- App lifecycle management (install --url, update, permissions, grant, info)
- Device backup & restore (create/list/restore/app/verify, AES-256 encrypt)
- SMS send/delete + wait-reply via KDE Connect
- Audio control (volume/mute/route)
- Contacts management (list/add/export VCF)

56 tasks across 7 phases. TDD: fixtures → RED tests → GREEN impl.
Target: ≥130 BATS tests on completion.

Closes: specs/003-autonomous-agent-control/{spec,plan,tasks}.md
2026-03-02 18:38:35 +01:00

7.1 KiB

Implementation Plan: Autonomous AI Agent Mobile Control

Feature: 003-autonomous-agent-control Created: 2026-03-02 Status: Draft Spec: specs/003-autonomous-agent-control/spec.md


Technical Context

Component Technology Rationale
Call control adb shell am start -a android.intent.action.CALL + UIAutomator ADB intent for dial; UIAutomator for answer/hangup (no root needed)
Call state adb shell dumpsys telephony.registry Exposes call state without root
App install (URL) curl download → adb install Reuses existing adb install path
App update adb install -r (replace) Standard ADB replace-install
App permissions adb shell dumpsys package <pkg> Full permission dump
App grant adb shell pm grant <pkg> <perm> Runtime permission grant
Backup adb backup -apk -shared -all + adb pull for SMS/contacts Android 9 supports adb backup
SMS send kdeconnect-cli --send-sms Already paired, used in existing sms commands
SMS wait-reply Poll kdeconnect-cli --list-notifications with timeout KDE Connect exposes incoming SMS as notifications
Audio control adb shell media volume + adb shell service call audio Media volume API
Contacts adb shell content query --uri content://contacts/phones Content provider query

Constitution Check

  • Library-First: New commands added to lib/call.sh, lib/backup.sh, lib/contacts.sh
  • CLI Interface: All new commands exposed via fs5 entrypoint with --help
  • Test-First: BATS tests written before implementation (RED → GREEN)
  • Simplicity: Extends existing fs5 CLI — no new entrypoints
  • Anti-Abstraction: Direct ADB/KDE Connect calls, no wrapper frameworks
  • Integration-First: Tests run against real device where possible; fixtures for offline

Architecture

New Library Modules

lib/
├── adb.sh          (existing — adb_check_device, adb_cmd, etc.)
├── output.sh       (existing — out_human, out_json, out_error)
├── input.sh        (existing — tap, swipe, key, type)
├── call.sh         (NEW — call_dial, call_answer, call_hangup, call_status, call_list)
├── backup.sh       (NEW — backup_create, backup_list, backup_restore, backup_app, backup_verify)
└── contacts.sh     (NEW — contacts_list, contacts_add, contacts_export)

fs5 Entrypoint Extensions

New subcommands added to fs5:

Subcommand Library P1/P2/P3
call dial/answer/hangup/status/list lib/call.sh P1
app install --url lib/adb.sh (extend) P1
app update [--all] lib/adb.sh (extend) P1
app permissions/grant/info lib/adb.sh (extend) P1
backup create/list/restore/app/verify lib/backup.sh P1
sms send [--wait-reply] lib/adb.sh (extend) P2
sms delete lib/adb.sh (extend) P2
audio volume/mute/route lib/call.sh (extend) P2
contacts list/add/export lib/contacts.sh P3

Data Model

Call State JSON

{
  "state": "active",
  "number": "+49123456789",
  "direction": "outgoing",
  "duration_seconds": 42,
  "timestamp": "2026-03-02T18:30:00Z"
}

Backup Manifest JSON

{
  "id": "backup-20260302-183000",
  "timestamp": "2026-03-02T18:30:00Z",
  "path": "/backups/backup-20260302-183000.tar.gz",
  "size_bytes": 524288000,
  "checksum": "sha256:abc123...",
  "contents": ["apks", "appdata", "sms", "contacts", "calllog"],
  "device_serial": "RD51QE202392",
  "android_version": "9"
}

AppInfo JSON

{
  "package": "com.example.app",
  "version_name": "1.2.3",
  "version_code": 123,
  "install_date": "2026-01-15T10:00:00Z",
  "size_bytes": 10485760,
  "is_system": false,
  "permissions": {
    "granted": ["android.permission.CAMERA"],
    "denied": ["android.permission.READ_CONTACTS"]
  }
}

Key Technical Decisions

ADR-001: Call Control via ADB Intent + UIAutomator

Decision: Use adb shell am start -a android.intent.action.CALL tel:<number> for dialing. Use UIAutomator to tap answer/hangup buttons (no root required on Android 9).

Alternative rejected: adb shell service call phone — requires root on Android 9.

Consequence: call answer requires UIAutomator XML dump to find button coordinates. Add fixture for offline testing.

ADR-002: Backup via adb backup + Content Providers

Decision: Use adb backup -apk -shared -all -f backup.ab for app data. Use content provider queries for SMS (content://sms) and contacts (content://contacts).

Alternative rejected: Third-party backup apps — requires installation and UI automation.

Consequence: adb backup is deprecated in Android 12+ but fully functional on Android 9 (FS5 target). Document this limitation.

ADR-003: SMS Send via KDE Connect

Decision: Use kdeconnect-cli --send-sms "<msg>" --destination <number> -d <device-id>

Alternative rejected: adb shell service call isms — requires root.

Consequence: KDE Connect must remain paired. Add pairing check to sms send.


Test Strategy

Offline Tests (no device required)

  • backup verify — checksum validation against fixture
  • backup list — parse fixture backup directory
  • app info — parse fixture dumpsys package output
  • call status — parse fixture dumpsys telephony.registry output
  • contacts list — parse fixture content provider output

Online Tests (device required, marked @requires_device)

  • call dial — initiates call (verify via call status)
  • backup create — creates archive (verify size > 0)
  • app install --url — downloads and installs test APK
  • sms send — sends SMS (verify via sms list)

Fixture Files

tests/fixtures/
├── ui_dump.xml              (existing)
├── dumpsys_telephony.txt    (NEW — call state output)
├── dumpsys_package.txt      (NEW — app info output)
├── content_sms.txt          (NEW — SMS content provider output)
└── content_contacts.txt     (NEW — contacts content provider output)

Dependencies

Dependency Status Notes
adb Available Used throughout existing commands
kdeconnect-cli Paired Used in existing sms commands
curl Available For APK URL download
sha256sum Available For backup verification
openssl Available For AES-256 backup encryption
bats 1.13.0 Available Test runner
UIAutomator Available Used in existing ui commands

Risks

Risk Likelihood Mitigation
adb backup blocked by device policy Low Android 9 allows it; document if blocked
Call answer via UIAutomator fails (button layout changes) Medium Use multiple selector strategies (text + content-desc)
KDE Connect pairing lost Low Add sms send pairing check with re-pair instructions
APK URL download fails (network) Medium Retry logic + clear error message