Files
dsh_ai1net_server/交付物/手机接入-目标与协同计划-20260929.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

11 KiB
Raw Permalink Blame History

手机接入 · 目标与协同计划(2026-09-29)

工作区 E:/ProgramData/AIProject/ai1net-dsh-server(本工作区 = 目标与协同的唯一入口) 权威架构 = 交付物/手机App经覆盖网络操作WorkBuddy-架构定稿v2-20260928.md 工单 = ai1net-dsh-anywhere/docs/交接单/对接单_WorkBuddy手机客户端-Android_20260928.md


一、目标(终态,一句话)

手机 App 通过 ai1net 覆盖网络(HTTPS 443)操作自己电脑上的 WorkBuddy 会话,能力做成 DSH 插件 (@dsh-local/ai1net 的客户端半 + 平台半同一个包),并由账号核对保证「我的账号只能连我的客户端、访问我的 WorkBuddy」。

验收判据(终态,全部要过)

# 判据 怎么验
V1 手机(真机、非 USB)能看到桌面会话列表与最新消息 设备入口地址 https://<门户>/u/<uid>/desk/<hostId>/… 打开即见
V2 手机发出的消息进入桌面会话(任意同项目会话) 目标会话 replay 出现 user_message_chunk,文本逐字一致
V3 桌面正在用的会话不被夺走(发消息不产生 writer 冲突) 活会话路径走 reply;非活会话走 ACP 借用并归还
V4 src/net/relay/** 零协议改动(不复用第二套中继) 该目录无新增 op
V5 权限面不扩大:不开任何对外端口、准入四道闸保持、默认关 端口清单 + device_web_enabled 默认值
V6 插件形态正确:垫片是 DSH 客户端插件(并入 ai1net 包第 6 模块),⛔ 不是独立进程 包内模块清单 + dsh.profile.bundles
V7 🔴 绝不影响 WorkBuddy 本身的运行(2026-09-29 用户明令):单向依赖,fail-safe 方向 = 关掉自己 见 v3 §0.5(七条技术条款 T1–T7 + 六项验收):连续 1 h / ≥50 次操作期间 —— WorkBuddy pid 恒定 · 宿主会话能回 idle · 桌面"当前对话"未被改 · 无 429 · 无新增对外端口 · 配置目录哈希零差异

二、🔴 现状 vs 定稿:偏差表(必须承认,不是按定稿实施的)

近两天(tmp/wb-phone/)做的是本机旁路原型 + 能力取证,三处与定稿不符:

维度 定稿 v2 要求 我实际做的 判定
传输路径 手机经 ai1net 设备入口(443 + 覆盖网络)到电脑 USB adb reverse + 手机浏览器访问 localhost:18899 ❌ 不符(旁路)
承载形态 垫片 = DSH Host 插件,只绑 127.0.0.1:20090,并入 @dsh-local/ai1net 第 6 模块 独立 Python 进程 bridge.py,绑 127.0.0.1:18899 ❌ 不符
凭据方式 首跳 ?password= 换 Cookie,之后复用 Cookie(§5.3) 实测 ?password= 在受保护路径永远失效 ⇒ 改 x-access-token 头 ⚠️ 定稿需更正(见 §三·C1)
手机侧形态 Android App(com.dsh.client,棒 3 产物) 手机浏览器页面(APK 未安装) ⚠️ 原型,未走 App

没打开 DSH 客户端的原因(如实说):G-A 未解 —— C:/Users/Administrator/.dsh/profiles/ 只剩 rescue/web,没有 desktop,垫片无处可挂。⇒ 棒 1 被这一条卡住。

「手机 APP 插件功能在哪」:架构里的「插件」指电脑侧的 DSH 客户端插件(垫片),不是手机上的东西;手机侧只需要是 App。 而插件目前还没做(棒 1 未开工)。手机上你看到的是我起的本机桥的浏览器页面。


三、🔴 我方取证对定稿的 6 条更正(回写 v2 → v3 前,各线按本清单为准)

每条都有源码实读 + 真机实测双依据,脚本在 tmp/wb-phone/(⛔ 不入库)。

# 更正 依据 影响
C1 🔴 令牌可自动取得,不再需要人工:口令就在 process.env.CODEBBUDDY_GATEWAY_PASSWORD,唯一稳定带法是 x-access-token: <明文> gateway 源码 GatewayAuth.resolve:env → settings → 随机生成;实测 env 值 + x-access-token ⇒ 200 §5.3「首跳换 Cookie」整段可删;且 v2 §1.1 的一条论据("凭据只在进程内存里 ⇒ 垫片必须进程内")被削弱 —— 需插件线复核是否还坚持"进程内"
C2 ?password= 在 requireAuth 保护的路径上永远失效 源码:requireAuth 构造请求对象时写死 query:{} 照 §5.3 写必然踩坑
C3 🔴 Origin 透传 ⇒ 写操作一律 403 实测:无 Origin → 409(正常);带 Origin → 403 {"error":"Origin not allowed"} §5.1「Origin 归一」必须做,且是"剥掉",⛔ 不许走"给网关加 CORS 白名单"(那条违背红线)
C4 🔴 网关只读写"与自己同工作目录"的会话;跨项目会话 history/replay 一律 404 SESSION_NOT_FOUND 实测:同目录 5 条可达 / 跨项目 19 条不可达(直连网关亦然) 对接单与架构都没写这条 ⇒ 手机端的会话列表必须按"可操作"过滤
C5 🔴 「活会话」= 桌面当前打开的那一个(sessionManager.sessionSubject.value),reply 只认它;往任意会话发消息要靠 ACP session/load+session/prompt 源码 + 实测(load 后 /sessions/live 切换;prompt 后目标 replay 出现 user_message_chunk) 对接单「发送」一节需重写;另:**`session/load
C6 ⚠️ 被 writer 占用的会话,外部接管不了:session/load 报 -32000 "already has an external writer" {reason:"writer_occupied"} 实测 「往任意会话发」的边界:正被桌面占用的会话暂时发不进去(空闲的可以)

四、棒次、归属、依赖(按定稿 §6 + 本轮更正)

棒 归属线(工作区) 做什么 判据 前置
棒 0 ✅ 本工作区(已完成) 端口发现脚本 + 取证 交付物 棒0-…mjs —
棒 0b ✅ 本工作区(已完成) 手机经网关操作会话的取证与打通(含本节 §三 六条更正) 交付物/棒0b-…md —
棒 0c ✅ 本工作区(已完成 09-29 07:2x) 把 §三 六条更正回写 → 出架构 v3,并同步对接单/执行交接单 v3 发布 + 两个工单同步 棒 0b ✅
🅐G-A 🔴 desktop 线(ai1net-dsh-desktop) 恢复/确认 desktop profile 与垫片挂载点 给出 desktop profile 落点 + 加载证据 —
棒 1 🔴 插件线(ai1net_ui) 垫片归并入 @dsh-local/ai1net 第 6 模块 + 改造(上游改指 gateway、动态发现、去 webServer、凭据改 x-access-token、剥 Origin) curl 127.0.0.1:20090/api/v1/sessions 返回 JSON;连续 50 次无 429 🅐(挂载点)可并行做代码
棒 2 🔴 插件线(同包 · 平台半) G-B:准入零改动 ⇒ 装同一包 + 开关登记 经设备入口访问垫片通;两条通道互不影响 棒 1
棒 4 🟡 手机接入线(ai1net-dsh-anywhere)+ 三方联调 对接单同步更正 + 端侧按新契约调整 + 真机端到端 + 断网重连 V1–V4 棒 1/2 + 棒 3(✅ 已完)

五、协同分工(派活 · 一棒一线)

线(工作区) 本轮派什么 为什么是它
ai1net-dsh-desktop 🅐G-A:解 desktop profile 缺口 + 给垫片挂载点结论 桌面/客户端线的地盘
ai1net_ui 棒 1(+棒 2 代码半):垫片归并 + 改造 插件线的地盘(ai1net 包属它)
ai1net-dsh-anywhere 对接单同步 + 端侧调整 + 联调准备 手机接入线的地盘
本工作区 棒 0c 回写 v3 + 全程协同/验收 本工作区是目标与协同的唯一入口

纪律(各线必守):开工先抢锁(bash D:/github/dsh_shenxian/dsh-server-docs/07-scripts/handoff-guard.sh --claim-exec "<会话名>" --domains <域>)|做完 --release-exec|一次只做一件事、做完即停|⛔ 不替别线干活。

🔴🔴 【收尾即叫监管 · 2026-09-29 新规 · 各线必须逐字执行】 任何一棒做完后,必须立即创建一个一次性自动化把「监管棒」叫起来,然后才停:

  • name:协同监管棒 · 立即轮(<你的线> 收尾)
  • scheduleType:once|scheduledAt:当前时间 + 2 分钟|status:ACTIVE
  • cwds:E:/ProgramData/AIProject/ai1net-dsh-server(监管棒跑在本工作区)
  • prompt 至少写:「本工作区=手机接入协同监管。立即按 交付物/手机接入-目标与协同计划-20260929.md 与定稿 v3 做一轮:抢锁 → 收三线产出 → 判 V1–V7 → 覆写 交付物/手机接入-进度看板.md → 按缺口派下一棒(一棒一线,排期=收口+5~8 分钟)→ 追加当日记忆 → 释放锁并停。⛔ 不起常驻任务。抢不到锁只报告。」

为什么必须这样做:钩子不能开新会话(自动化才是唯一通道),而整点轮询太慢(你要的是"完成即推进")。 ⇒ 由完成方在收尾那一刻叫监管棒,延迟≈2 分钟,且不需要任何常驻进程。 ⛔ 不要等整点、⛔ 不要等用户催、⛔ 不要用会话后台任务去等(那会把宿主会话反复唤醒 ⇒ 用户看到"卡死")。 每小时那一轮 1eaf45c3 只是兜底(防链条断掉),不是主通道。


六、红线(不得触碰)

🔴 【最高·2026-09-29 用户明令】做这些功能都不能影响 WorkBuddy 本身的运行,要禁止这种锁死,技术实现上要严格遵循。 见 v3 §0.5(T1–T7 + 禁止清单 + V7 验收)。总则:单向依赖,fail-safe 方向 = 关掉自己。 ⚠️ 已发生的反例(别再犯):把长跑服务放进会话后台任务 ⇒ 每轮输出唤醒宿主会话 ⇒ 永不空闲 ⇒ 用户看到"卡死"(我 09-29 违反 6 次复现)。

  1. ⛔ 不给网关加 CORS 白名单 / 不开任何对外端口(C3 的正解是"剥掉 Origin")
  2. ⛔ 不动 src/net/relay/**(V4)
  3. ⛔ 不改 DSH 那条已验通的通道(两条通道并存,端口/设备行分开)
  4. ⛔ 令牌不落盘、不进平台库、不进日志(现在靠 env 自动取,恰好最干净 —— 别退回"写文件")
  5. ⛔ 动 E:/github/dsh-client 前先入库(该仓 0 commit)