2026-10-09 校注:文中部署目录、服务、版本和验收计数为各段标注日期的历史记录;当前可验证状态见 current-status-2026-10-09,本次未复跑历史测试或读取私有健康/对话数据。
Humon 手机派生上下文 v1
目标
在桌面锁屏、离开或无法观测时,Humon 需要知道用户是否正在另一台设备上活动;但这不能变成通知、截图、位置与应用内容的监控。本层只保留能帮助判断跨设备可用性的最小派生状态,并把断连视为 source unknown,而不是“用户离开”。
权威实现
- 模块:
humon_phone.py - 私有配置:
~/.config/humon/phone.json,权限 600 - Observation source:
android-phone-derived - Schema:
humon-phone-derived-v1 - 默认 TTL:600 秒
- 正式回滚点:
${HOME}/.hermes/backups/humon-v3-pre-phone-derived-20260716-224005
最小权限通道
Termux SSH 使用现有 Tailscale SSH、key/known-host 认证和固定短超时;只调用 battery-status 与短时 accelerometer,原始电量/向量只在内存中解析,最终仅保留 battery band 与 stationary/moving。
ADB 只读取 adb devices 中已经连接的单一设备;永不自动连接、配对或扫描。固定读取 battery、power、window policy,只派生 screen_interactive 与 keyguard_locked。
广权限旧 alaya-phone-mcp.service 不是 Humon 依赖,当前 inactive。Humon 不启动它,也不调用 notification、screenshot、shell 或 control 工具。
允许持久化的固定字段
- schema_version / observed_at / freshness_seconds
- reachable
- screen_interactive / keyguard_locked
- charging
- battery_band = unknown|critical|low|normal|high
- motion = unknown|stationary|moving
- available_signals
缓存同样只含上述派生字段,原子写入;重复使用同一缓存时 source_ref 不变,因此 observation 自动去重。
写入级禁止字段
android-phone-derived 观察除通用 raw-content denylist 外,额外拒绝:
- location/latitude/longitude;
- SSID/BSSID/Wi-Fi/IP/MAC/network/RSSI;
- app/package/foreground_app;
- notification、clipboard、contact;
- screenshot/image;
- device_id/IMEI/serial/phone_number;
- exact battery percentage/level/temperature;
- accelerometer/acceleration/values/steps/step_count。
拒绝时只记录被拒绝的键名,不记录值。
融合边界
只有 observed_at≤600 秒、reachable、screen_interactive=true 且 keyguard_locked=false,手机才能把桌面 away|idle|locked|unknown 改为跨设备 active,activity_type=mobile。motion 单独永远不能改变 availability;任何手机字段都不能把 mood/energy/focus/stress 标为 known。
设备断连时只写 source health unavailable;缓存过期后字段恢复 unknown。Agent/perception context 只返回相同的粗粒度 phone block,过期字段先转成 null/unknown。
验证证据
- Windows 开发镜像与正式 WSL 运行目录:25 项测试通过,compileall 与定向 Ruff 通过。
- 覆盖 disabled 不探测、SSH 粗化、原始值不落库、ADB 不自动连接、断连缓存/过期、敏感字段拒绝、跨设备可用性、内在维度 unknown、run_once 和 Agent context。
- 正式 verification 与 22:45 natural cron 均写入 phone-source-status:reachable=false,其余 null/unknown,source health=unavailable。
- 当前手机离线:Termux SSH 超时,ADB devices 为空;没有把离线解释为人的 away。
- 22:45 已达 27 条 natural v3,重复五分钟槽 0。
- 正式库 privacy_events=0、delivered=0、delivery_eligible=0、ground_truth=0、feedback=0,integrity=ok。
/api/perception返回 phone source_status=unavailable、reachable=false、其余 unknown/null、privacy=coarse-derived-only。- 私有配置与 known_hosts 权限均为 600;operational_ready=true,delivery_ready=false。
当前缺口
- 手机重新在线后需用真实 Termux 输出确认运动传感器名称和 movement 可用率。
- 只有短时运动类别,没有睡眠、HRV、静息心率或锻炼摘要。
- 可穿戴接入必须沿用本地派生、逐源授权、TTL、固定 schema、可关闭、不可用即 unknown。
- 手机源不单独授权主动投递;所有帮助仍 shadow-only。