- 变更规模:新增 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/ 知识文件,按口径入库)
17 KiB
17 KiB
DSH 平台 — 记忆(状态层)
判据:不看会不会「违规/事故」?会 ⇒ 写实体;只"更慢更绕" ⇒ 给指针。落点:规则 →
CODEBUDDY.md(⛔不重复)|状态 → 本文件|方法论 → 技能|一次性事 →PLAYBOOK/当日日志。 📄 报障先读PLAYBOOK-实例与插件坑.md(§21 浏览器侧验收假阴性|§23 真机取证三坑)⚠️ 注入上限 ≈7,800 字符 ⇒ 只减不增(09-23 19:0x 已瘦身:8191 → 7,713)
一、状态速查(会变的都在这)
| 项 | 状态 |
|---|---|
| 在途单 | 覆盖网络线 序①–㊿ 收官;序46 在途(步7 受阻:缺 client-artifact-missing)。🔴 序47 在途(档案 145;步1–7 已落并真跑,⛔ 步8–9 未做=卡桌面线拨号载体+门户 UI)。🔵 IM 线(档案 142)A–E 五单全部落地;🔴 三项拍板(09-23,见选型单 §十四):E2EE=强度档(≈55 µs/条 OK;⚠️ 三代价=棘轮须持久化/群聊须 Megolm 化(误用严格双棘轮⇒O(N²))/agent 代答须重做)· 上限预算 2000/10/30 s 固化(⚠️ 前提=单进程自研扇出)· 连接层=B 引 Centrifugo(⚠️ 须补发自建心跳)。🔴 资源口径(09-22):机器可换 ⇒ ⛔ 别用单机规模限制规划。 🔴 D8(09-26 用户拍板)=「先不开端口,后续有需要再开」 ⇒ 由「唯一在册红」转主动搁置、⛔ 不再当待办;重开=要做跨节点内容分发时;⛔ 不影响群聊(全走 443 中继)。🔴 「高性能设备当中继」路径已在(中继白名单默认拒绝⇒加节点=配置动作;桌面端节点接入已实测);⚠️ 但中继方需"别人能连到它"=用户侧 NAT 门槛(⛔ 同源但不同于云安全组;同局域网零门槛)。🔴 推荐替代(⛔ 不需任何端口)=设备主动拉(fan-out on read)。📂 交付物/端口决策与设备中继可行性-20260926.md。🔴 背压已修(09-26 第15棒):ws.ts 投递点原丢弃 socket.write() 返回值 ⇒ 慢客户端可顶爆内存(单点即可打垮)⇒ 现:水位满记 backpressureEvents但⛔不虚减 delivered(已排队≠丢帧)/>上限(4 MiB 可注入)具名断开 1013/观测面 HubStats.{peakPendingBytes,closedByBackpressure};⚠️ 阈值待生产标定。🔴 判据分两类:新增能力⇒纯插入;修 bug⇒可改既有逻辑但须「回归用例+新行为可观测+阈值可注入」。⚠️ 测试跑 lib/ ⇒ 改完必 build(否则新旧产物混跑、症状像"注入无效")。🔴 持久禁令:⛔ 调 RELAY_FAILOVER_DEADLINE_MS、⛔ 动 HB_SEC/burst、⛔ COOLDOWN_MS=0。 |
| 并发锁(09-22 域锁落地) | 🔴 域锁取代全局独占:域不重叠即真并行;无 --domains ⇒ 退化独占。🔴 域键算法 shell/hook 必须逐字一致(_ANCHOR_SEGS⇄_DOMAIN_SEGS,先长后短)否则静默失效。开工第 0 步 = bash scripts/preflight-lock.sh "<会话名>" <文件...>(【D】未归类 或【E】机制层非空 ⇒ rc=1 拒开工)。🔴 机制层须独占(config/crypto/isolation/index/scripts/CODEBUDDY.md/锁本身)。🔴 释放一律带会话名:ME="<会话名>" bash …handoff-guard.sh --release-exec(或 --release-exec "<会话名>")—— ✅ 09-25 已修(不带名 ⇒ fail-closed 拒绝;--release-skeleton/--release-publish 同加归属校验)+ 6 处载体已同步(--release-exec "<会话名>" 写法);⚠️ 技能服务器镜像 /opt/dsh/docs/08-skills 自 09-24 起整体滞后(库≠镜像 21 文件 / 3 仅本地)。⚠️ 护栏额度耗尽时 release 会 rc=124 卡住 ⇒ 用 mv 等效释放(阈值真名 CODEBUDDY_SAFE_DELETE_BULK_GUARD)。。⚠️ 非 ASCII 会话名锁目录带 cksum 后缀|⚠️ 验收 hook 必带 DSH_SESSION_NAME(否则假绿)。 |
| 生产形态 / 路径 / 环境 | 47 的 PG 是本机进程(127.0.0.1:15432)非容器 ⇒ 「docker exec dshs-pg psql」全失败;su postgres 无 socket、需 TCP+口令(⛔ 不取凭据)。47 = Manager(dshs;PG13 15432)+ Worker w-47(19100);106 = w-106(19000)。🔴 drop-in 才是唯一载体(同名键写 /etc/dshs.env = 静默压掉)|回滚 = 删 cluster.conf → daemon-reload → restart dshs。106:users/ 权限必须 711(700 ⇒ 实例必崩)。nginx 归宝塔 ⇒ is-active nginx=inactive 属正常|npm test 用 Node 22|bt-server 别名已修 22 端口。 |
| 🔴 会话分组 / cwd(09-23 二修·判据冻结) | 真源 = workspaces.path(宿主自登记·全小写;sessions.cwd 已被污染 ⛔ 不作依据)⇒ cwds 逐字复制该值;新会话 cwd 逐字继承 cwds ⇒ 错一字面即裂组(现 e:160/E:5/d:11)。🔴 裂出的组会自我强化(手动新会话继承所在组字面)⇒ 只改 automation 不够,须清已裂组。📂 技能 §0.6。 |
| 配置外置线(140) | 单一秘密副本 = config/platform.env(不入库·600);优先级 = 系统 env > 文件 > 代码默认。🔴 drop-in 必留 DSH_PLATFORM_DIR=/opt/dsh(删 ⇒ 目录静默搬家)|改后必须重生成服务器 platform.env|涉密复扫须 0。 |
| 覆盖网络线 | 入口 = 工作区根 接续入口_覆盖网络线_20260916.md(§0 最新行+§2 首行 = 唯一依据);⛔ 勿重做已完成棒。🔴 判据五条+坑清单 全在该入口+参数表_覆盖网络_20260917.md(指纹以 §10 现算为准)—— ⛔ 别凭记忆做。已落:relay 两台(只绑回环 20080)+切流/寻址/组密钥/jitter+打洞(D8 待验);sshd 反向隧道已下线。🔴 域名唯一 = ai1net.com;relay 候选 3 条(⛔ 别加伪多样性)|改候选链须「删 directory.json+二次重启控制面」才生效。🔴🔴 中继走 443 ⇒ 功能全可用、⛔ 不用开任何端口(relay-direct = 443 兜底中继入口,⛔ 不是 P2P);UDP 21100-21115 只服务 P2P = 可选优化(按内容面算账省 75–93.75%,⛔ 别按群聊算账——消息是小包)。 |
| 🔴 形态元假设(09-21 立 · 最易犯) | ⛔ 默认「一个控制面」=错(用户两次纠正)⇒ 正确 = 控制面联邦(各区 Manager 各带 Worker/节点/设备)。全文 ⇒ 定稿 dsh-server-docs/02-架构设计/覆盖网络-顶层架构全貌.md(唯一权威) ⇒ ⛔ 别凭本行做设计。🔴 必背三句(① 两张图分离=分水岭在根是否处于数据路径 ② 跟用户走/全局唯一/区域内唯一 三分 ③ 根密钥只管授权撤回签名者)。🔴 多根=any-of-N(任一沦陷=全网沦陷;Manager 可升格 ⇒ N 台=N 根)。🔴 F1.5(G1 序号+G6 撤根)=一切前置。🔴 未自决:105 §3.2 骨干资格签发权|跨区可见性 ✅已定(09-24)=跟随「用户×区」成员关系。 |
| 📁 文档分层(09-21 立 · 找文件先看这条) | 🔴 过程 ≠ 成品:04-调整方案/=过程|架构设计/=定稿。冲突 ⇒ 以 架构设计/ 为准。⚠️ 过程档案过时结论**⛔ 不改正文**,只加头部状态块指向定稿。机制 ⇒ 技能 dsh-architecture-lifecycle。 |
| 插件数据落点(硬标准) | 🔴 一插件一库 dshs_pl_<pluginId> ⇒ ⛔ 不得拿实例本地 SQLite/文件当权威(只可缓存);内归属列 user_id/room_id 强制。⛔ homedir() 必错(实例 HOME=ws)。🔴 判版本只看 node_modules/<pkg>/package.json;源权威副本 = dsh-plugin-mcn/lib/。🔴 47 代码根 = /opt/dshs、106 = /opt/dshs-cluster(106 无 /opt/dshs)|/opt/dsh = 平台数据根,三台同名|取 DSHS_DB_URL 只从 drop-in cluster.conf grep(source /etc/dshs.env 拿到错的 5432)。⚠️ 真机取证清理必须写进 catch。🔴 装配协议 = link: ⇒ 待落地 4 处;⚠️ 软链目标须两机同路径。🔴 插件取数口已落地(09-25·⛔未部署):端口+装配+/api/im/data/*+SDK;⛔ 改 im.ts。🔴 改插件必读:yaml 须 package.json 指·自增 id 不能照搬·带声明先建库再投放·UI ≤900px 必须独占。🔴 列级 maxBytes 平台无强制点(schema.ts:500-515 只做声明期校验;写入只查行级 64 KiB maxRowBytes)⇒ 列上限唯一把关人 = 插件侧 COLUMN_MAX_BYTES,改声明 ≠ 改功能;⚠️ 改声明后必回读 yaml 实际值(09-25 第 33 棒实测:口头记「声明+代码同步」而 yaml 漏落)。📂 全文 ⇒ 2026-09-23.md。🔴 插件跑在「用户实例内」· IM 内核在「平台进程」⇒ 跨进程(09-25 审计):用户自配模型(credential_vault → spawn 写实例 settings.yaml/.credentials.yaml)只有实例内可用 ⇒ 插件必须在实例内;而扩展点注册/入向回调/出向投递三者无跨进程通路 = 当前接入缺口(数据面走 HTTP 有通路)。📂 交付物/IM插件接入完备性审计-20260925.md|接入面代码 ⇒ 交付物/IM插件接入面-20260925.md。 |
| 其他线 / 基线 / 品牌 | 其他线 ⇒ BRIEF.md。🔴 D4(09-18)跨云=目标形态,⛔ 作废「须同云」。🔑 基线/档案号 ⛔ 不写死 ⇒ 现查 state.py+INDEX.md;分叉走 git ls-remote 裸 sha + merge-base --is-ancestor。🔴 品牌 = 「能力网络」/CapabilityNet|favicon ⇒ PLAYBOOK-品牌与标识资产.md。🔴 共享模型 = 管理员逐用户授权(users.shared_model_granted v11 默认 0)|🔴 用户卷在 worker 上时,写 home 必须走 UserFs(直写 fs = 静默空操作)⇒ ⛔ 不得 cp/mv/直写 fs 动 home。🔴 数据库 ⇒ 数据库/DB-00…03。 |
二、本机铁律(⛔ 违反即事故)
- 🔴🔴 活库改动铁律(09-23 血教训 · 已有结局) ——
workbuddy.db= WAL 三件套(.db+-wal+-shm,app 运行中持有)。⛔ 禁文件级cp/mv(只换一部分 ⇒ salt 世代错位 ⇒file is not a database)。⇒ ① ⛔ 仅文件级操作须停 app(SQL 变更可在线·22:0x 实证)② 备份用官方backup()API(不碰三件套)③ 改数据只走 SQL +busy_timeout④ 改完跑integrity_check。⚠️ 判据两条都须过:①change counter(off24)=version-valid-for(off92) ② 头部 16B=SQLite format 3。🔴?immutable=1读不出 ≠ 仅 WAL 错位(实测=主库头部级损坏:建报database disk image is malformed/查报file is not a database)。🔴 判活动库/配置目录看CODEBUDDY_CONFIG_DIR(实测E:\ProgramData\.workbuddy);~/.workbuddy/workbuddy.db(09-12)=旧库,⛔ 不当备份。🔴 09-23 救治结论:头部坏 + WAL 无page_no=1帧 + 零 db 备份 ⇒ 只剩「重建空库」;⚠️ 需停 app ⇒ 影响面超本平台 ⇒ 红线门禁,⛔ 不擅自修。18:55 app 自愈实测:新库 magic 正常、旧库改名*.corrupt-*留档 ⇒ 代价=数据全丢(automation 记录清空)。 - 🔴 R10 实例起不来先查属主/EACCES,别先怀疑 OOM —— root 跑
dsh --profile⇒ 属主变 root ⇒ 崩溃循环/404。修find <home> -user root -exec chown <uid>:<uid> {} +→ 重启。⚠️ 平台侧备份一律/opt/dsh/backups/。报 503/「一直重启」另查endpoints[].streams恒 = 64 ⇒ 代理连接泄漏占满中继额度(146;已修proxy.ts);清空 =restart dshs。 - 🔴 改 bwrap 参数前先看目标机 bubblewrap 版本(47=0.4.0/106=0.11.0):
--perms属 0.5+ ⇒ 47 上Unknown option⇒ 沙箱起不来 = 所有实例全挂;要权限用--tmpfs。⚠️smoke-isolation不能作 account 模式验收。 - 🔴 集群化数据分层判据:① 归属/租约 ⇒ 只有 Manager 能写(双写 = 脑裂)② 跟用户走 ⇒ 实例 home ③ 本机运维 ⇒ Worker 本地库。
- 🔴 hook 脚本必须走
sys.stdout.buffer.write(bytes)(否则文案含⛔⇒UnicodeEncodeError⇒ stdout 空 ⇒ 静默放行);判据 = 写日志 + emit 双动作。 - 🔴 四条取数坑(全文 ⇒ PB):①
pkill -f匹配实际 argv ⇒ 用ss -lntpH 'sport = :PORT';②fetch静默丢Host头 ⇒ 假 404/200 ⇒curl -H "Host: …";③ 本机md5sum出hash *path、远端hash path⇒ 先cut -d' ' -f1;④journalctl --since不吃date -Is⇒ 用--since @<epoch>,且"查询失败"与"确无该行"必须可分;⚠️|grep …||true把"上游失败"伪装成"无命中"。 - ⚠️
--scene all演练含 120 s+90 s 观察窗 ⇒ ⛔ 不许套 < ~8 min 外层超时(截断 ⇒restore()不跑 ⇒ 106 relay 停机)。 - 🔴
ssh '…'单引号里不能再有单引号 ⇒ ✅cat > f <<"EOF"/ssh host 'bash -s' < 本地脚本。⚠️systemctl is-activeinactive 时退出码 3 ⇒ 读状态的远端命令一律|| true。 - 🔴 「单机自用」≠「不需要互联」(用户原话:「单机用也要互联,这正是建立覆盖网络的目的」)⇒ 租户维度与网络维度收窄正交。
- 🔴 覆盖网络按异构设计:中继 45%/55% 余量(⛔ 别用同构 15%)· 必须补 443/TCP 兜底 · VPN/代理检测即降级。
- 🔴 技术讨论不谈法规(⛔ 不引条文当论据、⛔ 不主动提合规、⛔ 不把合规前置或上抛)⇒ 判据见
CODEBUDDY.md §1。 - 🔴 接手前人结论先做最小取证 ⇒ ⛔ 别拿旧结论当既成事实。
- ⚠️ 本机执行环境:⛔ 别给 PATH 前置
/c/Windows/System32(那里bash= WSL 启动器)。⚠️bash报dirname: command not found(或ls/grep成片 not found、rc=127)⇒ ✅export PATH=<PortableGit 1.2.0 的 usr/bin:bin>:$PATH一次即恢复(09-22 复测,PB §22.6);🔴 工具调用间不共享 shell 状态 ⇒ 每条 bash 命令都要前置。⚠️ 只有 export 也救不回才改走 PowerShell + 托管 python —— 该情形至今未复现,⛔ 别一遇 127 就跳。🔴 MSYS 路径(/e/…)⛔ 不许交给 Windows 原生程序(python.exe/Chromium/node)—— 按「当前盘根+相对」解释 ⇒ 落到E:\e\…(09-22 实测长出 29 MB 影子目录,仍在增长)⇒ 一律传E:/…;hook 已_norm_path()兜底。 - ⚠️ 四条小规矩:行尾只信字节级(
b.count(b'\r'))|含反引号一律 Write/Edit|引用用户口径只写原话|python -c先落.py|⛔ 进程替换diff <(a) <(b)不可用。
三、成本与自动化(全文 ⇒ 技能 dsh-auto-handoff-chain)
- 🔴 成本 ≈ 单价 × 一轮工具调用次数 ⇒ 杠杆 = 压一轮次数:大输出先落盘只读关键行|限流(
head -30)|脚本内部聚合只 print 摘要。⚠️ 无人值守 prompt 必写「本轮只做一件事,做完即停」。 - 🔴 自动化四律:自动化 = 开新会话唯一通道(钩子无此能力)|开机第 0 步=跑
state.py|prompt ⛔ 不抄任务细节|并行口令必带线名、抢不到锁只报告|🔴 下一棒 id 只来自工具返回值|🔴 排期 = 收口 + 5~8 分钟、每条线只挂一个(域不重叠可各挂一棒)|入口只一份(本工作区,头部写工作区)|🔴cwds逐字同形(判据 = 实测sessions.cwd;现解 =E:/ProgramData/AIProject/aliyun-dsh-server正斜杠 —— 宿主去重键 =path.trim().toLowerCase(),只小写、不统一斜杠 ⇒ 斜杠/大小写不同即裂同名分组;目录改名后须同步cwds+ 历史sessions.cwd)|🔴 判据:入口头部声明的「工作区」决定归属(外来副本 ⇒state.py把别线当自家线)。
四、仓库 / 推送 / 授权 → 📂 全文 ⇒ .workbuddy/memory/MEMORY-仓库推送与授权.md(双推/文档库并入/行尾/技能三处/抢锁 R9/授权)
文档库结构与命名规则 ⇒ ⛔ 动 dsh-server-docs 前先读库内 CODEBUDDY.md 同名章(序号两位阿拉伯数字;04-调整方案/ 号不动;05-交接单/ 是锁根、07-scripts/ 绑宿主 hook;动文档库先抢锁,与工具无关;整理类任务必须有顶层可见变化)。
工作区 git(2026-09-24 立)
- 工作区
E:/ProgramData/AIProject/aliyun-dsh-server已入 git:remote[email protected]:maogeigei/dsh_shenxian_workspace.git(master);身份仓库级maogeigei/[email protected];core.autocrlf=false。 - 入库 = 文档与文件(CODEBUDDY.md/README.md/state.py/.gitignore、接续入口与接续包、docs/、交付物/、交接单/、归档/、.codebuddy/、.workbuddy/memory/);⛔ 不入库
tmp/、待清理/、运行态日志与缓存、*.db*、*.tar.gz|*.tgz、.backup-*/。 - ⛔ 工作区不留脚本副本 ⇒ 一律绝对路径调文档库
07-scripts/<name>。