TASKS.md 37.8 KB

Agent Phone Runtime — Task Queue

状态说明

  • [ ] 待执行
  • [>] 执行中
  • [x] 已完成(功能真实可用,非 stub)
  • [!] 阻塞/需人工介入(环境/账号缺失,代码本身未验证或不可达)
  • [✗] 实测失效(连真机实跑,工具报错或返回假成功——代码缺陷或运行时依赖缺失)

注意:本文件于 2026-06-12 根据真实代码和设备验证结果重写。 之前版本所有任务都标为 [x] 是错误的 —— 实际大量为 stub。

🔬 全工具真机审计(2026-06-16,B1):对 android_mcp.py _build_server() 注册的全部 35 个 MCP 工具, 在 Pixel 8 Pro / Android 16 / Root 上用 venv python 直驱 _tool_manager._tools[name].fn(**args) 逐个实跑。 结果:真可用 11 / 降级 1 / 失效 23。两类核心失效:

  1. EVENT_BUS_DIR 未定义(android_mcp.py 引用 11 次、HEAD/本地/设备三版本均无赋值)—— 连带 connector / persona / cloud 共 11 个工具全部 NameError,而这些任务此前都标 [x] 验收通过 ✓(从未真正可用)。
  2. _run_sqlcipher() 不支持参数化——get_wechat_messages 把 LIMIT ? 原样下发(datatype mismatch); ingest_wechat_to_memory 因 _run_sqlcipher 返回 dict 而非 list 导致 isinstance(...,list) 恒 False → 空转 added:0。 此外 get_wechat_contacts/chatrooms 查询列(imgFlag/chatroomowner)与本机 WeChat 8.x schema 不符; send_wechat_message/send_message 返回 "sent" 但 DB 无记录(假成功);frida_call 因 Mac 无 frida 模块、桥崩溃而不可达。 详见本次审计的工具对照表(随 PR/汇报附)。

当前可用基线(已验证)

  • [x] BASE-01 Python 事件服务器(event_server.py 监听 8765,SQLite 持久化)
  • [x] BASE-02 通知监控(notification_monitor.py root dumpsys 轮询,2s 延迟)
  • [x] BASE-03 MCP android-phone 服务(android_mcp.py,Hermes 已连接)
    • 🔬实测2026-06-16:_build_server() 共注册 39 个工具 = android_mcp.py 内 35 个(grep -cE "^ def [a-z_]+\(" android_mcp.py = 35)+ telephony_tools.py 4 个(call/send_sms/read_sms/list_call_log)。35 工具实跑结果见顶部审计banner(真可用 11/降级 1/失效 23)。
  • [x] BASE-04 Hermes 网关 API(localhost:8642,hermes-agent 模型,已验证)
  • [x] BASE-05 hermes-cli 终端工具(config.yaml 已配置,shell 命令可执行)
  • [x] BASE-06 WeChat SQLCipher 查询(sqlcipher 已链接,query_wechat 联系人表已验证)
  • [x] BASE-07 Android APK 聊天 UI(ChatFragment SSE 流式,会话持久化,复制按钮)
  • [x] BASE-08 Android APK 安装部署(APK 安装在 Pixel 8 Pro 上)
  • [x] BASE-09 Kimi API 已配置(.env 新 key,auth.json 重置,approvals.mode=auto)

Sprint 1 — 事件源打通(高优先级,1-2 周)

目标:把 APK 的实时事件源替换掉 dumpsys 轮询,使 Hermes 拿到毫秒级的真实事件

APK → EventServer 集成

  • [x] S1-01 APK 编译并重新部署到设备

    • 前置:无
    • 工作:用 Android Studio 或 ./gradlew assembleDebug && adb install 构建安装
    • 验收:adb shell pm list packages | grep lemon 能看到最新版本号
  • [x] S1-02 AgentNotificationListenerService → POST 到 EventServer

    • 前置:S1-01
    • 工作:在 AgentNotificationListenerService.kt 的 onNotificationPosted() 里增加 OkHttp POST http://localhost:8765/events,payload 格式与 notification_monitor.py 保持一致
    • 验收:收到微信通知后 event_server.log 能看到 APK 推来的 notification 事件
    • 说明:完成后可停止 notification_monitor.py,延迟从 2s 降至
  • [x] S1-03 AgentAccessibilityService → POST UI Tree 事件到 EventServer

    • 前置:S1-01
    • 工作:在 AgentAccessibilityService.kt 的 onAccessibilityEvent() 里过滤 TYPE_WINDOW_STATE_CHANGED / TYPE_VIEW_TEXT_CHANGED,POST 到 localhost:8765/events
    • 验收:切换到微信时 event bus 收到 ui_event 类型事件,含 package 和 window title
    • 说明:这是 phoneuse.md 核心能力,目前 event bus 里没有任何 accessibility 事件
  • [x] S1-04 设备上启用 NotificationListenerService 权限

    • 前置:S1-01
    • 工作:Settings → Apps → Special app access → Notification access → 开启 lemon.phoneuse
    • 验收:MCP get_latest 能看到来自 APK 的 notification 事件(source 字段区分)
  • [x] S1-05 设备上启用 AccessibilityService 权限

    • 前置:S1-01
    • 工作:Settings → Accessibility → Installed apps → lemon.phoneuse Agent → 开启
    • 验收:切换 App 时 event bus 收到 app_foreground 事件
  • [x] S1-06 更新 android_mcp.py:区分事件来源(dumpsys vs APK)

    • 前置:S1-02, S1-03
    • 工作:events 表增加 source 字段('monitor'/'apk'),get_events 支持 source_filter
    • 验收:get_events(source_filter='apk') 只返回 APK 推来的事件
  • [x] S1-07 废弃 dumpsys 轮询,改为 APK 实时推送

    • 前置:S1-02, S1-04,并验证 APK 推送稳定运行 24h
    • 工作:start_all.sh 去掉 notification_monitor.py 启动;stop_all.sh 同步更新
    • 验收:不启动 notification_monitor.py,通知事件仍能进入 event bus

Sprint 2 — WeChat 数据深度提取(高优先级,1-2 周)

目标:从只能查联系人,扩展到能读消息、群聊、朋友圈

WeChat SQLite 扩展

  • [x] S2-01 验证 WeChat 消息表(message)结构

    • 前置:BASE-06
    • 工作:通过 query_wechat 工具执行 SELECT * FROM message LIMIT 5,记录字段名
    • 验收:找到消息内容字段(content)、发送者(talker)、时间戳(createTime)
  • [✗] S2-02 在 android_mcp.py 增加 get_wechat_messages(contact?, limit?, since_ts?) 工具

    • 前置:S2-01
    • 工作:封装 message 表查询,支持按联系人过滤,返回结构化消息列表
    • 验收:get_wechat_messages(contact='wxid_xxx', limit=20) 返回正确消息
    • 🔬实测2026-06-16 失效:{"error":"Error near line 5: datatype mismatch","sql":"...LIMIT ?"}。 根因:_run_sqlcipher(sql,db,key) 不接收 params,工具构造的 LIMIT ? 占位符原样下发给 sqlcipher CLI。 对照:query_wechat("SELECT count(*) FROM message") 返回 4380 条 → 底层 DB/key 正常,仅本工具封装有 bug。
  • [✗] S2-03 在 android_mcp.py 增加 get_wechat_contacts(query?) 工具

    • 前置:BASE-06
    • 工作:封装 rcontact 表,支持名字/wxid 模糊搜索,返回 {wxid, alias, nickname, remark}
    • 验收:get_wechat_contacts(query='张') 返回所有相关联系人
    • 🔬实测2026-06-16 失效:{"error":"...no such column: imgFlag..."}。本机 WeChat 8.x rcontact 表无 imgFlag 列(schema 漂移)。
  • [✗] S2-04 验证群聊消息提取

    • 前置:S2-01
    • 工作:查 chatroom 表结构,在 message 表过滤群聊消息(talker 含 @chatroom)
    • 验收:能从 DB 读取群聊消息并识别发送者
    • 🔬实测2026-06-16 失效:get_wechat_chatrooms() → {"error":"...no such column: chatroomowner..."}。本机 chatroom 表无 chatroomowner 列(schema 漂移)。
  • [!] S2-05 WeChat 朋友圈数据表探索(可选)

    • 前置:S2-01
    • 工作:查找 Feed / SnsInfo 相关表名,验证是否可读
    • 验收:找到朋友圈相关表并能读取样本数据
    • 阻塞:SnsMicroMsg.db 存在但使用不同加密 key(非 EnMicroMsg.db 的 e03ce81),需单独推导

Sprint 3 — Frida Runtime 基础设施(中优先级,2-3 周)

目标:让 frida_call MCP 工具真正可用,为 send_message 能力打基础

Frida Server 部署

  • [x] S3-01 下载 frida-server ARM64 二进制

    • 前置:无
    • 工作:从 GitHub releases 下载对应 frida-server 版本(arm64),adb push 到 /data/local/tmp/
    • 验收:frida-server 17.9.10 已推到 /data/local/tmp/frida-server,已 chmod 755,已运行(pid=10096)
  • [x] S3-02 验证 frida-server 与 frida Python 客户端通信

    • 前置:S3-01
    • 验收:Mac frida 17.9.10 通过 USB 连接设备,enumerate_processes() 返回 288 个进程
    • 说明:frida Python 在 Mac 端运行(Termux 无法编译 frida 17.x),通过 frida_bridge.py + adb reverse tcp:8767 与设备通信
  • [✗] S3-03 验证 frida_call MCP 工具

    • 前置:S3-02
    • 验收:frida_call 成功注入 WeChat 8.0.72(Android 16),Java.perform 返回 Model/SDK 信息
    • 说明:frida 17.x 需处理 frida:load-bridge 协议才能使用 Java 全局变量(已在 frida_bridge.py 实现)
    • 🔬实测2026-06-16 失效(运行时依赖缺失):{"error":"frida_bridge unreachable: Remote end closed connection..."}。 设备 frida-server 在跑(pid 10096),但 Mac 端 python3 frida_bridge.py 启动即 ModuleNotFoundError: No module named 'frida'—— 本机未装 frida pip 包,桥无法运行,工具链断。属环境缺失而非工具代码缺陷。
  • [x] S3-04 将 frida-server 加入 start_all.sh 自动启动

    • 验收:start_all.sh 已加入 frida-server 启动段(以 root 运行 /data/local/tmp/frida-server)

WeChat Frida Hook

  • [x] S3-05 探索 WeChat sendMessage() 方法签名

    • 验收:WeChat 8.0.72 深度混淆,枚举到 normsg.、chatting. 包,sendTextMessage 无法直接定位
    • 说明:version-specific hook 需要持续维护,转为 Accessibility 方案(S3-07)
  • [!] S3-06 实现 WeChat sendMessage JS hook script

    • 阻塞:WeChat 8.x ProGuard 混淆需要逆向工程,frida hook 路径需专门版本研究
    • 降级:send_wechat_message 工具使用 Accessibility Service 方案(S3-07)
  • [x] S3-07 在 android_mcp.py 增加 send_wechat_message(to, content) 工具

    • 工作:新模块 wechat_send.py(send_wechat_message_ui)真 UI 自动化:自带搜索框导航(放弃被微信拦截的 am start --es username)+ ADBKeyboard base64 广播输入(解决中文/Latin 被 IME 篡改)+ 发送后以 message.isSend=1 为准返回真实状态,失败诚实报错绝不假 "sent"。
    • 🔬F3 修复并真机验证 2026-06-16(claude-yi 亲跑 ground-truth)真可用: send_wechat_message_ui("filehelper", "phoneuse-F3-1781595137") → {"status":"sent","msgId":4461,"verified":"message.isSend=1"}; 独立 DB 复查 content LIKE 'phoneuse-F3-1781595137' AND isSend=1 命中 1 行(talker=filehelper); 反向测试不存在联系人 → {"status":"failed"} 不假 "sent"。
    • 修两处真机暴露的缺陷:① 发送前 _wake_and_unlock() 唤醒+解非安全锁屏(否则设备息屏时全部 tap 落空——已验证息屏起跑仍 sent msgId 4464); ② _capture_restore_ime() 持久化用户真实 IME,防止上一轮中断把 ADBKeyboard 残留为默认输入法后被错误"还原"(修前实测残留过,已修复并回归)。

通用 Frida 深度检视(Intent / Bitmap,2026-06-24)

目标:把"注入目标进程拿完整 Java 对象图"封装成两个通用(不需要逆向任何具体 App)MCP 工具, 跟 S3-05/S3-06 的 per-app hook 路线区分开。字符串解密能力明确排除(per-app 逆向,超出本次范围)。

  • [x] MAC-01 修通 Mac 端 Frida 链路(此前 S3-03 因 Mac 缺 frida pip 包而完全不可达)

    • 工作:phoneuse/.venv + pip install frida==17.9.10 frida-tools==14.8.0 fastapi uvicorn;新增 start_frida_bridge.sh(adb reverse tcp:8767 tcp:8767 + 起 frida_bridge.py)
    • 🔬验证 2026-06-24:版本锁定经实测确认——frida-tools 最新版对 frida 有严格版本范围依赖,与设备上跑的 frida-server 17.9.10 不匹配会直接报错;frida==17.9.10+frida-tools==14.8.0 这组干净安装且匹配。venv 内 import frida, frida_tools, fastapi, uvicorn 通过。
  • [!] S3-08 新增 inspect_foreground_intent(package, timeout) 工具

    • 工作:新模块 frida_inspect_tools.py,Java.choose('android.app.Activity', ...) 枚举目标进程内所有存活 Activity,按 hasWindowFocus() 识别真正前台的那个,dump getIntent() 的 action/dataString/component/extras。
    • 🔬JS 脚本本身的正确性已对一个真实在跑进程验证过(hasWindowFocus 准确识别出唯一前台 Activity,extras 正确提取出非空字段,Parcelable 类型 extras 按预期落到 Java 默认 toString())。
    • [!] 阻塞:本次会话设备从 adb devices 掉线,MCP 工具本身(经 deploy.sh 推送 + 真实 adb reverse 隧道 + android_mcp.py 注册)的端到端验证未完成,待设备重新连接后用 com.android.settings/Calculator 之类无隐私数据的单进程 App 补测。本地 _build_server() 已确认能正常注册此工具(60 个工具总数,无注册期异常)。
    • 已知限制:frida_bridge.py 现有的进程名子串匹配对微信这类多进程 App 会匹配错进程(主进程标签是 "WeChat" 不含包名子串,回退逻辑会捡到无 UI 的 :push 子进程),导致静默空结果——工具已对空结果附加 note 诊断提示,但根因留作后续修复(不在本次范围内,怕影响 frida_call 其它调用方)。
  • [!] S3-09 新增 dump_live_bitmaps(package, max_export, timeout) 工具

    • 工作:同模块,Java.choose('android.graphics.Bitmap', ...) 枚举目标进程堆里所有存活 Bitmap,单次 Java.choose 内直接持有引用、按 allocationByteCount 排序,对最大的 max_export 张调 compress(CompressFormat.PNG.value, 100, baos) + Base64.encodeToString(..., NO_WRAP) 经 send() 回传。
    • 🔬JS 脚本本身的正确性已对一个真实在跑进程验证过(导出的 base64 解码后是合法 PNG,magic bytes 正确,尺寸跟 width/height 字段一致);同时验证了两处易错点:CompressFormat.PNG.value(去掉 .value 会报 overload 不匹配)、回收过的 Bitmap 要整段跳过元数据读取(而非只在 compress() 处兜底,否则会有垂悬 0 值污染排序)。
    • [!] 阻塞:同 S3-08,设备掉线,MCP 工具端到端验证待补。
    • 已知限制:同 S3-08 的多进程匹配问题;另外单次调用只导出"当下堆里恰好有什么",不保证是调用者想要的那一张。

Sprint 4 — Memory Graph(中优先级,3-4 周)

目标:实现跨 App 知识图谱,Agent 记得人和事

Graph 存储与写入

  • [x] S4-01 实现 MemoryGraph(Python SQLite + FTS5 邻接表)

    • 说明:架构决定改为 Python/SQLite 而非 Kotlin Room DB
    • 工作:memory_graph.py,含 person/message/entity/relation 表 + FTS5 全文索引
    • 验收:DB 初始化成功,写入 Person + Message 节点,FTS 查询返回结果
  • [x] S4-02 实现 WeChat 联系人 → Person 节点 ingestion

    • 验收:500+ WeChat 联系人写入 Memory Graph person 表,含 wxid/nickname/remark
  • [x] S4-03 实现 WeChat 消息 → Message 节点 ingestion

    • 验收:1205 条文字消息写入 Memory Graph,FTS5 索引同步,LIKE 搜索均可用
  • [!] S4-04 实现跨 App 联系人去重(WeChat + Telegram)

    • 前置:S4-02
    • 工作:基于手机号/名字相似度合并同一自然人的多个来源节点
    • 验收:微信和 Telegram 中的同一联系人合并为一个 Person 节点
    • 🔬实测2026-06-16 更正:Telegram 已安装未登录(event bus 有 org.telegram.messenger.web 233 条事件;cache4.db 存在但无表)。 阻塞点由"未安装"改为"未登录"——登录后即可推进。
  • [✗] S4-05 在 android_mcp.py 增加 search_memory + ingest_wechat_to_memory 工具

    • 验收:search_memory('谢谢') 返回 2 条含关键词的微信消息;时间范围过滤正常
    • 🔬实测2026-06-16:search_memory('的') 真可用(返回结果 + stats persons:522/messages:1205/vectors:510+)。 但 ingest_wechat_to_memory(50) 失效(空转):返回 contacts added:0 / messages added:0。 根因:_run_sqlcipher 返回 dict({"rows":...}/{"raw":...}),工具用 isinstance(x, list) 判断恒 False → 永远 ingest 空列表。 现有 memory graph 数据是更早版本/其他途径写入的,本工具当前为 no-op。

Sprint 5 — Semantic MCP API(低优先级,依赖前面 Sprint)

目标:实现 phoneuse.md 的核心语义接口,Agent 不用关心底层 App

  • [x] S5-01 实现 send_message(to, content, app?) 语义路由工具

    • 验收:根据联系人名查找 wxid 并路由到 send_wechat_message;联系人解析通过测试
    • 🔬F3 修复后 2026-06-16 真可用:app=auto 时用 F2 修好的 rcontact 解析确认联系人后路由到 wechat,委派给 send_wechat_message(即 send_wechat_message_ui,DB isSend=1 为准)。filehelper 走 wechat 分支,端到端发送链已随 S3-07 一并验证为真。
  • [!] S5-02 实现 create_event(title, time, attendees?) 日历工具

    • 阻塞:设备无 Google 账号,CalendarContract ContentProvider 无可写日历账户
    • 代码已写,insert 命令需要 calendar_id(当前无账号)
    • 🔬实测2026-06-16 确认 失效(无账号):返回 {"status":"created","event_id":""}(id 为空 = 未真正插入); content query .../calendars → "No result found"(设备无任何日历账户)。代码可达,缺账号。
  • [!] S5-03 实现 create_task(title, deadline?, note?) 任务工具

    • 前置:无
    • 工作:写系统 Reminders / Google Tasks
    • 验收:创建的任务在手机 Tasks App 可见
    • 阻塞:设备无 Google Tasks/Reminders App(com.google.android.gms.tasks ContentProvider 不存在);create_task 工具已实现,但 am start INSERT 无法路由到任何 Tasks App(rc=1)
    • 🔬实测2026-06-16 确认 失效(无 Tasks App):{"ok":false,"error":"Activity not started, unable to resolve Intent { act=...INSERT dat=content://com.android.task/...}","hint":"No Tasks account configured"}。
  • [x] S5-04 实现 read_document(source?, query?) 文档工具

    • 验收:read_document('谢谢') 返回 2 条相关消息;同时搜索 Memory Graph + Event Bus

Sprint 6 — 其他 Data Extraction(低优先级)

  • [x] S6-01 MMKV 读取器实现(补全 stub)

    • 工作:data-extraction/ 模块的 MMKV 读取实现,使用 root cp + mmap 解析 MMKV 格式
    • 验收:能读取微信 MMKV 配置键值对 ✓
    • 实现:android_mcp.py read_wechat_mmkv();root cp /data/data/com.tencent.mm/files/mmkv/mmkv.default → /data/local/tmp;protobuf varint 解析;50 个 WeChat KV 键读取验证(SnsFeatureStorage_create_time_v1、LiveHomePageRedDot_create_time_v1 等)✓
  • [!] S6-02 Telegram SQLite connector

    • 工作:找到 Telegram DB 路径,适配表结构,封装为 MCP 工具 get_telegram_messages()
    • 验收:能读取最近 50 条 Telegram 消息
    • 🔬实测2026-06-16 更正:Telegram 已安装未登录(非"未安装")。 get_telegram_messages() → {"error":"schema mismatch","tables":[]};get_telegram_contacts() → {"error":"no such table: users"}。 cache4.db 存在但无表(未登录)。工具代码可达,阻塞点为登录态,登录后即可验证。
  • [x] S6-03 系统通讯录 ContentProvider 读取

    • 工作:通过 adb shell content query 或 APK ContentResolver 读取通讯录
    • 验收:能读取手机通讯录联系人,与 WeChat 联系人关联 ✓
    • 实现:android_mcp.py get_system_contacts();content://com.android.contacts/contacts + phone_v2 两步查询;1720 个联系人读取;name 与 phone_map 关联 ✓
  • [x] S6-04 系统日历 ContentProvider 读取

    • 工作:读取 CalendarContract,返回近期事件
    • 验收:能读取系统日历中的事件列表 ✓
    • 实现:android_mcp.py get_calendar_events();content://com.android.calendar/events;设备无 Google 账号,返回空列表("No result found")——工具功能完整,账号缺失非代码问题 ✓
    • 🔬实测2026-06-16 真可用:get_calendar_events() 无报错返回 {"events":[],"count":0}(设备确无日历账户,空结果正确)。

Sprint 7 — Layer 4 Network MITM(中优先级,phoneuse.md Layer 4)

目标:在 Root 环境拦截 App 的 HTTPS/WebSocket/gRPC 流量,反向发现 App 数据 Schema 说明:这是 phoneuse.md 明确的 Layer 4,当前 TASKS.md 完全缺失

  • [x] S7-01 在设备上安装 mitmproxy 系统证书为受信 CA

    • 工作:adb push cert.pem /system/etc/security/cacerts/ (需 root 挂载 /system 可写)
    • 验收:mitmproxy 能拦截任意 App 的 HTTPS 请求,无证书报错
    • 实现:Mac openssl 生成 CA cert → adb push → tmpfs mount over /system/etc/security/cacerts/ → cp 117c9d0a.0;144个系统CA证书+自定义CA ✓
  • [x] S7-02 在 Termux 运行 mitmproxy,配置透明代理

    • 工作:安装 mitmproxy,配置 iptables 将 App 流量重定向到 mitmproxy 端口
    • 验收:mitmproxy 能看到 WeChat 的 HTTP/HTTPS 请求(host/port)
    • 实现:mitm_proxy.py 纯Python代理,port 8082(8080被llama-swap占用);iptables NAT redirect WeChat UID 10304 tcp:80+443→8082;已捕获WeChat HTTP POST szextshort.weixin.qq.com:80 ✓
  • [x] S7-03 实现流量 → Event Bus 写入器

    • 工作:mitmproxy addon 脚本,捕获 HTTP request/response,POST 到 event_server.py
    • 验收:WeChat 发消息时能在 event bus 看到对应的网络请求 event
    • 实现:mitm_proxy.py post_event() 写入 event_server:8765/events;95条 MITM 事件已入库;source='mitm' 标记 ✓
  • [x] S7-04 分析 WeChat API Schema(反向工程)

    • 工作:通过拦截到的流量分析 WeChat 服务端 API 的数据格式和字段
    • 验收:文档化 WeChat 至少 3 个关键 API 的请求/响应 Schema ✓
    • 实现:cryptography 库已可用;821 条 MITM 事件分析;531 个唯一 mmtls 端点识别
    • WeChat API Schema(基于 mmtls 流量分析,821 events):
    • WeChat 使用 mmtls(自有应用层加密)覆盖 HTTP(port 80);body 为加密 protobuf,无法解密
    • 端点格式:POST /mmtls/{8位hex操作ID} HTTP/1.1 → host: szextshort.weixin.qq.com 或 szminorshort.weixin.qq.com
    • API-1: /mmtls/78a7c6d7 — 心跳/保活(Heartbeat)
      • 频率:14次(最高频),规律间隔
      • req_size=~844B resp_size=~781B(对称小包,典型心跳特征)
      • 推断:KeepAlive/Presence,维持长连接
    • API-2: /mmtls/70c4e8a4 — 同步/消息拉取(SyncCheck)
      • 频率:14次,主要在 szextshort.weixin.qq.com
      • req_size=~3029B resp_size=~397B(大请求小响应 → 上报状态,服务器返回 delta)
      • 推断:ContactSync 或 MessageSync,类似微信网页版 synccheck 机制
    • API-3: /mmtls/39bffdc2 — 媒体/内容下载(MediaDownload)
      • 频率:4次
      • req_size=~919B resp_size=~17711B(小请求,超大响应 → 内容下载特征)
      • 推断:图片/语音下载,响应大小与典型缩略图一致
    • API-4: /mmtls/75baf2f8 — 媒体上传(MediaUpload)
      • 频率:5次
      • req_size=~7572B resp_size=~407B(大请求小响应 → 文件上传 ACK)
      • 推断:图片/语音上传,host 通常为 szextshort
    • API-5: /mmtls/0fc172a5 — Ping(最小包)
      • 频率:3次
      • req_size=~690B resp_size=~335B(最小数据包,纯 ping)
      • 推断:TCP-level ping,防止 NAT 超时
    • DNS 查询 (dns.weixin.qq.com.cn): 64次 GET/POST,WeChat 内部 DNS-over-HTTP 解析服务器列表
    • WeChat Pay (szshort.mixpay.wechatpay.cn, paydns.wechatpay.cn): 3次各,支付相关 DNS 和数据
    • HTTP Headers(已验证):Content-Type: application/octet-stream | User-Agent: MicroMessenger Client | 响应 HTTP/1.1 200 OK
    • 注:mmtls body 为 WeChat 自有加密协议,覆盖在 HTTP 上(非 HTTPS CONNECT),需 WeChat 私钥才可解密正文
  • [ ] S7-05 分析 Alipay API Schema

    • 工作:同上,分析 Alipay 账单/支付相关 API
    • 验收:文档化 Alipay 账单查询 API Schema
    • 🔬实测2026-06-16 解除阻塞:Alipay 已安装(com.eg.android.AlipayGphone,event bus 560 条事件)。 原"[BLOCKED] 未安装"过时。可派 worker 推进 MITM/DB 分析。

Sprint 8 — Connector 抽象层(中优先级,phoneuse.md 核心架构)

目标:实现 phoneuse.md 设计的 App Connector 模式 + Connector Knowledge Base 说明:phoneuse.md 明确要求 WeChatConnector.read_messages() 这种类级抽象, 当前实现是散碎的工具函数,没有封装,也没有 Knowledge Base

Connector Knowledge Base

  • [x] S8-01 设计并实现 Connector Knowledge Base 存储结构

    • 工作:在设备上创建 ~/.hermes/connectors/ 目录,每个 App 一个 YAML 配置文件
    • 验收:cat ~/.hermes/connectors/wechat.yaml 包含完整配置
    • 实现:connectors.py init_knowledge_base() 生成 wechat.yaml/alipay.yaml/calendar.yaml/mail.yaml;含db_path/tables/hooks/actions/stats字段 ✓
    • 🔬实测2026-06-16:MCP 工具 get_connector_kb('wechat') 失效 → {"error":"name 'EVENT_BUS_DIR' is not defined"}(KB 文件或在,但工具封装挂)。
  • [✗] S8-02 实现 WeChatConnector 类(Python)

    • 工作:封装为 WeChatConnector 类,方法 read_contacts/read_messages/read_chatrooms/send_message
    • 验收:所有方法通过 Knowledge Base 配置驱动,不硬编码路径
    • 实现:connectors.py WeChatConnector;read_messages(3条) + read_contacts(3条) 验收通过 ✓
    • 🔬实测2026-06-16 失效:MCP 工具 connector_read_wechat_messages() 与 connector_read_wechat_contacts() 均 {"error":"name 'EVENT_BUS_DIR' is not defined"}。android_mcp.py 这些工具体内 sys.path.insert(0, EVENT_BUS_DIR) 引用了未定义全局。 connectors.py 类本身或可直接 import 使用,但 MCP 工具封装层从未可用(HEAD/本地/设备三版本同样未定义 EVENT_BUS_DIR)。
  • [!] S8-03 实现 AlipayConnector 类

    • 前置:S7-05 提供 API Schema 参考
    • 验收:能读取 Alipay 最近 30 天账单
    • 🔬实测2026-06-16 更正:Alipay 已安装(com.eg.android.AlipayGphone,560 条事件),原"未安装"过时;AlipayConnector 仍为 stub,可推进。
  • [!] S8-04 实现 MailConnector 类(系统邮件 App)

    • 验收:能读取系统邮件 App 最近 20 封邮件的 subject/sender/body
    • 🔬实测2026-06-16 更正:Gmail 已安装(缺 Google 账号),原"未安装邮件 App"过时;MailConnector 仍为 stub,待账号后推进。
  • [!] S8-05 实现 CalendarConnector 类

    • 验收:能读取近 7 天日程;能创建新事件(验证在系统日历可见)
    • 🔬实测2026-06-16 确认阻塞:设备 无任何日历账户(content query .../calendars → "No result found");CalendarConnector stub。
  • [x] S8-06 实现 Connector 执行优先级链

    • 工作:每个操作按优先级尝试:Frida → Accessibility → Intent,失败自动降级
    • 验收:Frida hook 失效时自动降级到 Accessibility 自动化发送消息
    • 实现:connectors.py ExecutionChain 类 + BaseConnector.try_methods() + _log_result() 记录到 knowledgelog.jsonl ✓

Discovery Sub-agent

  • [✗] S8-07 实现 Discovery Sub-agent 框架

    • 工作:扫描 App DB 结构变化、验证 hook 有效性、更新 Knowledge Base
    • 验收:WeChat 版本升级后手动触发 Discovery Sub-agent,能自动更新 Knowledge Base
    • 实现:connectors.py DiscoveryAgent 类;discover_wechat() 检测版本 + 枚举所有表名 + 更新 KB;android_mcp.py run_discovery_agent 工具;实测列出 WeChat 所有 DB 表 ✓
    • 🔬实测2026-06-16 失效:MCP 工具 run_discovery_agent('wechat') → {"error":"name 'EVENT_BUS_DIR' is not defined"}(同 EVENT_BUS_DIR 缺陷)。
  • [x] S8-08 实现 hook 失效自动触发 Discovery Sub-agent

    • 前置:S8-07
    • 验收:模拟 hook 失效,60 秒内 Discovery Sub-agent 自动启动
    • 实现:BaseConnector.try_methods() 失败时记录 knowledge_log.jsonl;ExecutionChain 自动降级链;androidmcp.py run_discovery_agent 工具供外部触发 ✓

Sprint 9 — Memory 完整实现(中优先级,phoneuse.md Data 层)

目标:phoneuse.md 要求三种记忆:Vector Memory + Timeline Memory + Graph Memory 说明:Sprint 4 只覆盖了 Graph Memory,Vector 和 Timeline 缺失

  • [x] S9-01 实现 Vector Memory(语义向量搜索)

    • 工作:在设备 Termux 安装轻量向量库(chromadb 或 sqlite-vss), 对消息/文档内容生成 embedding(使用 Kimi API 或本地轻量模型), 支持余弦相似度搜索
    • 验收:search_memory("项目进展") 能返回语义相关的消息,不只是关键词匹配
    • 实现:memory_graph.py embed_messages() + semantic_search();Kimi API moonshot-v1-embedding 1024维;10条消息已向量化;semantic_search('介绍产品') 返回3条结果 ✓
    • 🔬实测2026-06-16 真可用:embed_memory_messages(5) → embedded:5/pending:0(vectors 510→515);semantic_search_memory('吃饭') 返回 3 条带 score(0.74/0.73/0.70)。Kimi embedding 实联通。
  • [x] S9-02 实现 Timeline Memory(时间线索引)

    • 工作:所有 Event/Message 写入时附带时间戳索引,支持:
    • "今天发生了什么"
    • "上周和张三的对话"
    • "3月份的账单"
    • 验收:search_memory("上周", person="张三") 能按时间范围过滤返回
    • 实现:search_memory() 支持 since/until 参数时间过滤;android_mcp.py search_memory 工具已接入 ✓
  • [x] S9-03 三种 Memory 统一查询接口

    • 工作:search_memory(query, person?, since?, until?, source_app?) 内部并联三种检索: Vector(语义相关)+ Timeline(时间范围)+ Graph(关系链路),结果合并去重
    • 验收:复杂查询("张三上个月和我说过什么关于项目的事")能同时命中三种索引
    • 实现:android_mcp.py search_memory + semantic_search_memory + embed_memory_messages 三工具统一接口;FTS5关键词 + 时间过滤 + Kimi向量检索并联 ✓

Sprint 10 — Persona 模块(低优先级,phoneuse.md Agent Formula)

目标:实现 phoneuse.md Agent Formula 里的 Persona 组件 说明:Agent = LLM × Tools × Data × Persona,当前 Persona 完全缺失

  • [✗] S10-01 设计 Persona 数据结构

    • 工作:~/.hermes/persona.yaml 存储用户画像:
    • Preference(语言风格、工作习惯、常用 App)
    • Goal(当前项目、优先级)
    • Style(回复简洁/详细、中文/英文)
    • Relationship(重要联系人列表及关系类型)
    • 验收:Hermes system prompt 从 persona.yaml 动态生成
    • 实现:persona.py 完成;get_persona/update_persona/generate_system_prompt_fragment;yaml/json自适应 ✓
    • 🔬实测2026-06-16 失效:MCP 工具 get_persona() / update_persona('_selftest','phoneuse') 均 {"error":"name 'EVENT_BUS_DIR' is not defined"}(同 EVENT_BUS_DIR 缺陷)。
  • [✗] S10-02 实现 Persona 自动更新(从行为推断)

    • 工作:从 event bus 的用户行为(常用 App、活跃时间段、常联系人)自动更新 Persona
    • 验收:Persona 里的"常用 App"和"重要联系人"能从真实使用数据中提炼
    • 实现:infer_from_memory_graph() 从 memory_graph.db 提取高频联系人 top-10;android_mcp.py infer_persona_from_behavior 工具 ✓
    • 🔬实测2026-06-16 失效:MCP 工具 infer_persona_from_behavior() → {"error":"name 'EVENT_BUS_DIR' is not defined"}。
  • [✗] S10-03 Persona 接入 Hermes System Prompt

    • 工作:Hermes 启动时加载 Persona,注入到 system prompt 作为背景上下文
    • 验收:Hermes 能根据 Persona 调整回复风格和任务优先级判断
    • 实现:generate_system_prompt_fragment() 生成 Markdown 片段;android_mcp.py get_persona_prompt 工具 ✓
    • 🔬实测2026-06-16 失效:MCP 工具 get_persona_prompt() → [persona error: name 'EVENT_BUS_DIR' is not defined]。

Sprint 11 — Collective Knowledge Network(长期目标)

目标:phoneuse.md 横向层,跨设备分享 App 操作经验 说明:当前完全未实现,属于产品护城河层,排在所有本地功能之后

  • [x] S11-01 设计云端 Knowledge 上传格式

    • 工作:定义上传 schema(只含结构性知识,不含用户数据)
    • 验收:格式文档评审通过,隐私字段清单确认
    • 实现:cloud_knowledge.py make_knowledge_entry() schema_version/intent/app/app_version/execution_path/success_rate/validated_by;无用户数据字段 ✓
  • [✗] S11-02 实现本地经验上传客户端

    • 工作:Connector 操作成功后,异步上传结构性知识到云端 API
    • 验收:成功发送一条微信后,上传记录出现在云端
    • 实现:cloud_knowledge.py upload_knowledge();无 API key 时本地缓存 pending_*.json;android_mcp.py upload_operation_knowledge 工具 ✓(需配置 HERMES_CLOUD_KEY 生效)
    • 🔬实测2026-06-16 失效:upload_operation_knowledge(...) 与 retry_cloud_uploads() 均 {"error":"name 'EVENT_BUS_DIR' is not defined"}(同 EVENT_BUS_DIR 缺陷,未触及网络)。
  • [✗] S11-03 实现云端经验拉取(Pull 模式)

    • 工作:执行意图前,先查询云端是否有该 App 版本的已验证经验
    • 验收:新设备能从云端直接拉取 WeChat hook 配置,不需要本地探索
    • 实现:cloud_knowledge.py pull_knowledge()/get_best_execution_path();本地缓存降级;android_mcp.py pull_cloud_knowledge 工具 ✓
    • 🔬实测2026-06-16 失效:pull_cloud_knowledge('wechat','send_message') → {"error":"name 'EVENT_BUS_DIR' is not defined"}。
  • [ ] S11-04 实现云端 Knowledge 服务端(需独立后端项目)

    • 工作:部署收集→去重→验证(N 台交叉验证)→分发管道的后端服务
    • 验收:多台设备上传同一 App 经验后,云端正确合并并分发
    • 状态:[DEFERRED] 需要独立后端项目,超出当前范围

技术债务 & 维护

  • [ ] DEBT-01 gRPC protoc codegen 接通(低优先级)

    • 说明:AndroidRuntimeServer.kt 的 gRPC 接口已设计,但未跑 protoc 生成代码
    • 只有当 Hermes 需要从 Mac 远程控制 Android 时才需要,当前 Termux 本机够用
  • [x] DEBT-02 approvals.cron_mode 从 deny 改为 auto(中优先级)

    • 说明:当前 cron_mode=deny,定时任务里 terminal 命令会被拒绝
    • 工作:sed -i 's/cron_mode: deny/cron_mode: auto/' in config.yaml 后重启 gateway
    • 验证:config.yaml 已有 cron_mode: auto ✓
  • [x] DEBT-03 notification_monitor.py 到 APK 集成后的过渡删除

    • 前置:S1-07 验证稳定
    • 工作:从 start_all.sh 彻底移除 notification_monitor.py 相关逻辑
    • 验证:notification monitor 启动段已从 start_all.sh 移除;status 输出中对应行已删除 ✓
  • [x] DEBT-04 Android APK 添加自动重连 EventServer 逻辑

    • 说明:APK 启动时如果 event_server.py 还未跑起来,推送会失败,需要带 retry
    • 实现:EventServerClient.kt post() 增加 maxRetries=3 指数退避(500ms/1000ms/2000ms);APK 重新编译安装 ✓

覆盖度验证

phoneuse.md 模块 对应任务 覆盖状态
Layer 2 — Event Collection (Accessibility) S1-03, S1-05 ✅ 覆盖
Layer 2 — Event Collection (Notification) S1-02, S1-04 ✅ 覆盖
Layer 2 — Event Collection (Intent/Clipboard) S6-03(系统);APK Intent 未规划 ⚠️ 部分
Layer 3 — SQLite (WeChat/Telegram/Mail/Notes) S2, S6-02, S8-04 ✅ 覆盖
Layer 3 — MMKV / Realm / LevelDB S6-01;Realm/LevelDB 仍缺 ⚠️ 部分
Layer 4 — Network MITM S7 ✅ 覆盖
Layer 5 — Frida (WeChat/Alipay/Telegram) S3, S8-02~S8-03 ✅ 覆盖
Semantic Extraction Engine (统一实体映射) S8-02~S8-05 Connector 层 ✅ 覆盖
Personal Memory Graph S4 ✅ 覆盖
Vector Memory S9-01 ✅ 覆盖
Timeline Memory S9-02 ✅ 覆盖
MCP Generic APIs (send/search/create/read) S5 ✅ 覆盖
Connector Knowledge Base S8-01 ✅ 覆盖
Discovery Sub-agent S8-07, S8-08 ✅ 覆盖
Execution Priority Chain S8-06 ✅ 覆盖
Persona (Preference/Goal/Style/Relationship) S10 ✅ 覆盖
Collective Knowledge Network (云端) S11 ✅ 覆盖
Agent Hypervisor 长期目标 依赖所有 Sprint 完成 🔮 愿景

仍有小缺口(可接受):

  • APK Intent broadcast 捕获(S6-03 只覆盖通讯录 ContentProvider,Intent 监听未单独规划)
  • Realm / LevelDB 读取器(S6-01 只有 MMKV,Realm/LevelDB 可按需补充)

优先级汇总

Sprint 核心价值 难度 周期
Sprint 1 — APK 事件源打通 实时事件(替换 2s 轮询) 低 1-2 周
Sprint 2 — WeChat 深度提取 能读消息(现在只有联系人) 低 1 周
Sprint 3 — Frida 基础设施 能发消息(只读 → 读写) 中 2-3 周
Sprint 4 — Memory Graph Agent 记住人和事 高 3-4 周
Sprint 5 — Semantic MCP 语义 API(phoneuse.md 核心) 中 依赖 S3/S4
Sprint 6 — 其他数据源 覆盖更多 App 中 按需
Sprint 7 — Network MITM Layer 4 拦截流量 高 2-3 周
Sprint 8 — Connector 抽象层 App Connector + Knowledge Base 中 3-4 周
Sprint 9 — Memory 完整实现 Vector + Timeline Memory 中 2 周
Sprint 10 — Persona 模块 用户画像 + 个性化 低 1-2 周
Sprint 11 — Collective Knowledge 云端经验共享(护城河) 极高 独立项目

推荐执行顺序:Sprint 1 → 2 → 3 → 4 → 8 → 5 → 9 → 7 → 10 → 11