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/ 知识文件,按口径入库)
This commit is contained in:
admin committed 2026-10-10 23:13:22 +08:00
1 parent 30b46dbd0c
commit c1b5e4d966
735 files changed
+153192 -2415

No files matched your search

@@ -0,0 +1,110 @@
# 手机接入 · 目标与协同计划(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|new` 必须带 `cwd` + `mcpServers`**(缺则 `-32602`) |
| **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)