Files
dsh_ai1net_server/.workbuddy/memory/.backup-20260916/MEMORY.md.before-slim
T

60 lines
14 KiB
Plaintext
Raw Normal View History

# DSH 平台 — 记忆(**状态层**)
> **判据**:不看它会不会导致「违规」或「事故」?会 ⇒ 写实体;只"更慢更绕" ⇒ 只留指针。
> **落点**:动作前必须生效的规则 → 根 `CODEBUDDY.md`(**不在此重复**)|**会变的状态**(在途单/版本/基线/位置)→ 本文件|方法论 → 技能|一次性事实·复盘·命令原文 → `PLAYBOOK` / `04/<NN>`|当天流水 → `memory/YYYY-MM-DD.md`|跨项目偏好 → `~/.workbuddy/MEMORY.md`。
> 📄 **详版 = `.workbuddy/memory/PLAYBOOK-实例与插件坑.md`**(**报障第一件事就开它**)。§ 速查:1 插件边界|2 GLIBC|3 插件加载失败三真因|4 铺插件陷阱|5 ETag|6 技术债|7 K8s 清理|8 兼容收口|9 实例取数四坑 + UI 分区三步定位 + 部署硬规矩|10 本机 Python 编码坑|11 去查索引|12 省积分。
> ⚠️ **本文件有注入上限(会截断)** ⇒ **新增内容按「越靠前越常驻」插入,⛔ 别追加到末尾**;体积**只减不增**(2026-09-16 已按此压过一轮)。
## 一、最近闭环(只留"还在影响今天"的)
- **09-16 覆盖网络线**:10 份规划 → 档案 **103–112**(`4e3a1a4`)+ 会合/中继拆分方案(S0–S4);同日 **S0 落地**(见 §二)。
- **09-15 T08 集群化 + 生产整体切换**(Manager 47 / Worker `w-47`+`w-106`)|档案 96 实例内存与插件开关解耦|档案 100/101 实例内「我的技能」→ 改名「能力管理」+ 页内 tab|档案 102 语言切换搬入「用户设置」。
- 🔑 **「用户设置」= 我们自己的 `@dsh-local/portal-entry`**(id `user-settings`);label 存**转义 unicode** ⇒ 按 UTF-8 grep 搜不到。⇒ `07-实例UI分区登记表.md`;🔧 `node scripts/find-ui.mjs [关键词]`。
- 交互规则(待拍板项**置末 + 逐条编号 + 候选竖排成段 + 必写优缺点**)已固化进 `dsh-change-workflow §5`。
## 二、状态速查
| 项 | 状态 |
|---|---|
| **在途单** | **无在途**(`T01–T08` 全完成归档)。T08 残留见 `03-路线图 §二` 🟡 |
| **生产形态** | 47 = **Manager**(cluster;控制面库 = 47 上 PG13,单元 `dshs-pg`,`127.0.0.1:15432`)+ 本地 Worker `w-47`(19100);**106 = Worker `w-106`**(19000,经 SSH 反向隧道)。存量用户锚 `w-47`、新用户按容量落 `w-106`(**粘性优先**);`guest` 已于 09-16 迁 `w-106`(epoch 4)。⚠️ **权威库 = 47 的 PG**(`/var/lib/dshs/dshs.db` 仅回滚用)。⛔ 47 兼作 Worker 是**有意设计**。**回滚** = 删 `/etc/systemd/system/dshs.service.d/cluster.conf` + `daemon-reload` + `restart dshs`(cluster 配置在这个 **drop-in** 里,不在 `/etc/dshs.env`) |
| **106 节点** | 实例运行能力已补齐(dsh 0.1.5-rc.1 + `/usr/local/dsh-runtime` + `/var/lib/dshs/*` + **`users/` 权限必须 711** —— 原 700 **会致实例必崩**);ffmpeg/ffprobe 用内网源 dnf 装。⏳ **provisioner 未铺**(新用户落 106 无人建号);⚠️ 旧控制面 `dsh-users-platform.service`(3080) 待清 ⇒ `跨节点迁移与节点自举_完整流程方案_20260916.md` |
| 集群化 | 单一来源 = 项目根 `集群化改造方案_Manager-Worker_20260914.md`;D1–D5 已定,⏳ 仅 **D6**(不阻塞);数据分层判据见 §三 |
| 实例内存(档案 96) | 与插件开关**解耦**:`MemoryHigh=MIN=448` + `MemoryMax=MAX=1024`;`/api/dsh/status` 带 `quota{...}`。⚠️ `MEM_TABLE` **仅预估、不驱动配额** |
| **覆盖网络线** | 入口 = 工作区根 `接续入口_覆盖网络线_20260916.md`(**唯一入口,先读它**)。**S0 ✅ 本机、未部署**(与 S1 合并上线;依据 = 零行为变化、部署零收益却要重启)。🔴 **方案 §8 三处勘误**,最要命一条:**`proxy.ts:109` 是发给上游 dsh 的 Host 头、不是中继连接目标**(dsh `/api` 信任栅栏要求 loopback),改它 = `/api` 全量 403;另一条:**S2 回填 `via` 不能一刀切**(w-47=`local` / w-106=`manager-ssh`)。⏳ 唯一待拍板 = 骨干服务范围(档案 **105 §七**,倾向 A→B 渐进,**不阻塞** S0–S4)。🟢 本机已获许可作「客户端类型」测试节点(Windows 无 bwrap ⇒ 只能 soft 模式,**正是客户端目标模式、不是降级**) |
| **代码分层** | ✅ **P0 已立(09-16)**:代码仓 `docs/architecture.md`(四层 `①入口 → ②领域 → ③能力 → ④基础`,`net/*` = 能力层一员 + **R1–R4 判据**)。🔴 旧结论「有 3 处基础层反向依赖」**已勘误为 0 处** —— 那几处是**入口层 `cli.ts`** 的合法依赖(`①→③`)⇒ 剩 **P1 补 `src/domain/*`**(行为敏感重构,先出清单)/ P2 模块头注释 |
| 归档编号 | 至 **112**(103–112 = 覆盖网络线 10 份);**63 空号**,勿补占 |
| 熔断 / MCN / univer | 熔断 78:冷却 6h + 双通道告警已上线,**L1 实测未做**|MCN 0.3.10 已铺发,`mcn-task` 重复建组未解|univer = **内存探针,有意保留 ⇒ 勿以下架** |
**提交基线**:代码仓 **`59f1a89`** —— 09-16 13:0x 已 push,远端 `master` 一致,**工作区全干净**。
🔑 **本机 `refs/remotes/**` 写不进去** ⇒ `git fetch` **静默失败**、`origin/master` **不可用** ⇒ **分叉判定必须** `git ls-remote origin refs/heads/master` 取**裸 sha** + `git merge-base --is-ancestor <sha> HEAD`(用本地 ref 会得到**假"非快进"**、白白停手)。推前 `--dry-run`、推后重 `ls-remote` 复核。
🗣 **称谓**:**「本机」只能指跑 WorkBuddy 的开发机**;47 / 106 一律写「远程服务器」或用 IP。
## 三、本机铁律(CODEBUDDY.md 未覆盖的部分)
- 🔴 **R10 实例起不来先查属主 / EACCES,别先怀疑 OOM** —— root 跑 `dsh --profile` ⇒ 属主变 root ⇒ 崩溃循环 / 404。修 `find <home> -user root -exec chown <uid>:<uid> {} +` → 重启。⚠️ 用户 home 是 watch 域 ⇒ 读不了的文件同样致命 ⇒ 平台侧备份一律 `/opt/dsh/backups/`。
- 🔴 **改 bwrap 参数前先看目标机 bubblewrap 版本**(**47 = 0.4.0 / 106 = 0.11.0**):`--perms` 属 0.5+ ⇒ 47 上 `Unknown option` ⇒ **沙箱起不来 = 所有实例全挂**;要权限**用 `--tmpfs`**。⚠️ `smoke-isolation` **不能**作 account 模式验收。⇒ `交接单/T08-§10`。
- 🔴 **集群化数据分层判据**(用户原话:「不一定 worker 不连数据库…」):① 归属/租约 ⇒ **只有 Manager 能写**(双写 = 脑裂)② 跟着用户走 ⇒ 放**实例 home**,别塞控制面 PG ③ 本机运维用 ⇒ **Worker 本地库**。⇒ 设计文档 §1.3。
- 🔴 **hook 脚本必须走 `sys.stdout.buffer.write(bytes)`** —— 文本层 `sys.stdout.write` + 文案含 `⛔` ⇒ 宿主 stdout 非 UTF-8 ⇒ `UnicodeEncodeError` ⇒ **stdout 空 ⇒ 静默放行**(日志却写 deny ⇒ 表现成"判了但拦不住")。判据 = **"写日志 + emit"双动作且 emit 走 buffer**。`PreToolUse` 的 `deny` **确有效**;锁主力仍是三把锁 + `handoff-guard.sh` + 约定,hook 是加固层。⛔ 别再写"hook 拦不住"。📂 自证日志真路径 = `D:\github\dsh_shenxian\.workbuddy\lock-hook.log`(跟 `DOCS_ROOT` 走)。⇒ PB §10。
- 🔔 **技能加载闸门(09-16 装)**:钩子 `dsh-server-docs/scripts/skill-load-guard.py` —— 命中「决策方法 / 参考决策 / 按你的规划 / 别问我 / 自行决策 / 自主决策」⇒ 自动注入"必须先加载 `dsh-decision-method`"(急停 `DSH_SKILL_GUARD_OFF=1` 或 `.workbuddy/skill-guard.disabled`)。⚠️ **需完全重启才加载**。
- 🔴 **两条命令坑**:① `pkill -f` 要匹配"实际 argv" ⇒ ✅ 按端口定位 `ss -lntpH 'sport = :PORT' | grep -oP 'pid=\K[0-9]+' | head -1`。② **`fetch` 静默丢 `Host` 头**(undici)⇒ 多租户验证落到"无租户"路由、**假 404/200** ⇒ ✅ `curl -H "Host: …"`、别跨用户测、判据别只看状态码。
- 🔴 **「单机自用」≠「不需要互联」**(09-16 用户原话:「**单机用也要互联,这正是建立覆盖网络的目的**」):**租户维度收窄(1 个用户)与网络维度收窄(1 台机器)正交** ⇒ ⛔ 不得再用"单机自用所以没流量要互联"当前提(推演 v1 因此作废、已重写 v2)。
- 🔴 **覆盖网络按异构设计**:① **中继按 45% 设计、55% 留余量**(⛔ 别用同构假设的 15%)② **必须补 443/TCP 兜底**(否则封 UDP 的整类节点进不来)③ 有公网 IP 的节点自动升格为中继候选,但**权威状态仍必须单点 Manager** ④ VPN/代理类**检测即降级中继**,不重试 ⑤ **节点自报网络画像**。
- 🔴 **方案只做技术实现,合规不进方案**(09-16 用户原话:「**方案只考虑技术实现,跨境数据合规是谁用谁自己考虑**」)⇒ ⛔ 不再把合规 / 数据主权 / 备案当前置条件、约束或上抛项。多区域就近 = **性能**最优,不是合规动作。
- 🔴 **接手前人结论,先做一次最小取证**(09-16 同日踩两次):① 方案说 `proxy.ts:109` 是中继落点 ⇒ 实为**上游 Host 头**;② 评估文档说"3 处基础层反向依赖" ⇒ 实为**入口层 `cli.ts` 的合法依赖,违规 0 处**。⛔ 别拿上一份文档的结论当既成事实直接执行。
- ⚠️ **本机执行环境**:**Python stdin/stdout 必须走 `buffer` 显式 UTF-8**(`-E` 屏蔽 `PYTHONUTF8=1` ⇒ cp936 ⇒ 含中文静默炸)|改文件**必用 `newline=""`(读也要)**|**ESM**|bash **PATH 被 shim 重置** ⇒ 先 `export PATH=<PortableGit>/usr/bin:…:/c/Windows/System32:/c/Windows:$PATH`|**Python 原生 exe 不认 `/e/…`** ⇒ 传参 `E:/…`|bash 内联 `\` 被 MSYS 改写 ⇒ 含 Windows 路径的 Python **落成 .py 再跑**|`tar czf E:/…` 加 `--force-local`|**bash 的 `cd` 认中文路径、`ls` 等被 MSYS 编码搞坏** ⇒ 先 `cd` 再用相对路径。⇒ PB §10。
- ⚠️ **行尾只信字节级**(`grep -c $'\r$'` 会误报)⇒ Python `b.count(b'\r')`。BRIEF/README/`skills/**`/`memory/**` = 纯 LF;**`INDEX.md` = 混合** ⇒ 改它走**字节级单行插入**;⛔ 别对它跑 `git checkout --`。⚠️ **源仓 `refs/remotes/**` 写不进去**(报成功但引用不存在 ⇒ `[gone]`)⇒ 对账一律 `git ls-remote origin refs/heads/master`;`git` 走 SSH 加 `GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"`。
- ⚠️ **引用用户口径只写原话**|**含反引号的内容一律用 Write/Edit 写**|**进程替换 `diff <(a) <(b)` 不可用**|**`Edit` 是替换不是追加**。⇒ PB §12。
- 🔴 **成本公式(09-16 实测 `workbuddy.db` 原始计费字段,勿再凭直觉)**:**省积分四招** = 批量活写脚本 / 拦大输出(`bash-output-guard.py`)/ 命令限流 / 切会话 —— 但**四招效力天差地别**,判据是:**积分 ≈ 单价 × 一轮内工具调用次数**;单价随水位涨(<10 万 ≈**0.10**、15 万 ≈**0.41** 积分/次,同会话受控实测 **4 倍**)。⛔ **「切会话能归零」是错的** —— 三个自动化**全新会话的首轮**分别烧 **8.93 / 10.05 / 13.82** 积分(因首轮跑了 31–54 次工具调用)⇒ **切会话只压单价膨胀、压不了次数**。**真杠杆排序 = ① 一轮工具次数(线性、主导)→ ② 水位 → ③ 固定注入 35,192 tok(缓存命中 99.5%,很轻)**。数据源 = `session_usage.credit_json` + `automation_runs.runs_json`。
- ⚠️ **自动化 = 开新会话的唯一通道**(取证:`automation_runs.metadata_json` 每次运行都带**新** `sessionId`);**钩子无创建/切换会话能力**(输出只有「注入上下文」与「拦工具」)⇒ 自动接续**只能半自动**:钩子注入收口指令 → **模型调 `automation_update`** 登记 +2min 一次性自动化。⛔ 钩子脚本**不得**绕过 `automation_update` 写库建自动化。
- ⚠️ **打包与改名**(`npm pack` 前核断言锚点、先删 `lib/*.bak` 与 `*.tgz`、升号前确认号没用过、每包必须有 `.npmignore` 排除 `*.tgz`;`--force` 只准替换自己那一段;改名三件套 = SQLite `.db`+`-wal`+`-shm` 一起改 / 压缩包内 grep-sed 够不到 ⇒ 解压→改→重压 / 改完真环境跑一次)。⇒ PB。
- 浏览器只准 `agent-browser` / `browser-harness`(CDP 9223);⛔ **Playwright 全面禁止**。
## 四、仓库 / 推送 / 授权
- 📦 **09-15 文档库已并入代码仓**(R4 选 a)⇒ **`D:\github\dsh_shenxian\dsh-server-docs\`**(git = `D:/github/dsh_shenxian/.git`)。锁脚本 = `…\dsh-server-docs\scripts\handoff-guard.sh`。镜像 `/opt/dsh/docs` 不变。⚠️ hooks 路径改动要**完全重启**才生效。
- 代码仓 `D:\github\dsh_shenxian` → `…dsh_shenxian.git`(master)|**推送只能从本机**;服务器改码走 `git bundle`。文档库 `autocrlf=false` + `.gitattributes(* -text)` **必须保持**。
- ⚠️ **技能是「三处」**:本机 `.workbuddy/skills/<name>/` ← 文档库 `skills/<name>/` ← 镜像 `/opt/dsh/docs/skills/`。**验收 = 两副本 md5 一致 + 镜像一致 + `README.md` / `INDEX.md` 登记跟着改**;同步前先抢全局执行锁。
- ⚠️ **改任何文件前先抢全局执行锁**(`--claim-exec`),**释放了再想继续写就得重抢** —— 一次抢锁只对"本轮任务"有效,跨轮必须重抢(09-16 实测:释放后下一轮直接 Write 被钩子拦下)。
- 📄 **「去查」索引 = PLAYBOOK §11**(权限档位 / 插件启停 / UI·univer / 个人技能 / docx / `business-plugins` 升级 / admin 跨用户 / 加新能力 / dsh 版本 / 开源导出)。
- 🔒 **授权类**:文件已全部移除(不属改造范围、不得再列为待办或上抛)。上游 MIT、**不得对上游代码附加限制**;**对外发布前先放回那三份**(`_授权归档_发布时再放回\`)。