- 变更规模:新增 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/ 知识文件,按口径入库)
9.0 KiB
会话哑掉线 · 收尾报告(2026-10-01)
线:多会话协作机制 · 会话哑掉 | 本棒会话:
345e6839(自动化 · 阈值交接棒) 范围:上棒遗留 4 项(一件一件做,做完即停) | 并发锁:本轮持全局独占(机制层),已释放
一、结论(先读)
| # | 遗留项 | 结果 |
|---|---|---|
| 1 | selftest.py 补「会话哑掉」回归用例 |
✅ 已补 2 条;python selftest.py PASS 37 / FAIL 0(基线 35 + 新增 2) |
| 2 | board_ext.py 清退役文案 |
✅ 已清 2 处(详见 §三) |
| 3 | 已哑主会话 f8a792ab 的归属 |
⛔ 未动 —— 取证后判不准,按任务书报用户(详见 §四) |
| 4 | 报告 + 释放锁 | ✅ 本报告 + 锁已 --release-exec |
二、遗留 1:回归用例(⛔ 不碰生产)
新增到 ~/.workbuddy/skills/multi-session-collab/scripts/selftest.py:
| 用例 | 判据 |
|---|---|
哑会话:诊断日志 ≥ 9.5 MiB ⇒ _deaf_sids() 判哑 |
① ≥9.5 MiB 判哑 ② 9,499,999 B(差 1 字节)不判哑(边界)③ KB 级不判哑 ④ 结果恰好只有那一条 |
哑会话:投递命中已哑目标 ⇒ skipped=target-deaf |
① 判读=target-deaf ② 投递台账零增量 ③ 已把喊话落到 NEED-USER.md |
怎么做到不碰生产:_deaf_sids() 每次调用现读 CODEBUDDY_CONFIG_DIR ⇒ 用例把它临时指到
tmp/selftest/fake-cfg/(用 truncate 建稀疏文件拿到 10 MiB 体积读数,不真写),跑完 finally 还原
(_db() 也读这变量,不还原会把后面的用例一起带偏)。元用例「本测试不碰生产」仍全绿。
三、遗留 2:board_ext.py 清掉的 2 处退役文案
文件:E:/ProgramData/AIProject/ai1net-dsh-server/.workbuddy/collab/board_ext.py
| 处 | 原文 | 改成 | 为什么 |
|---|---|---|---|
| 文件头 | 「手机接入」线的看板扩展 |
「本机协作」的看板扩展 |
「手机接入」是已退役线名(用户 2026-09-30:「后面也不叫手机接入」);现行目标名=goal.json 的「本机协作」 |
| chip① 标题 | dsh-client · 设备接入 · 本地中转 :20090 |
dsh-plugin-ai1net · 设备接入 · 本地中转 :20090 |
dsh-client 在此是退役包名:原 @dsh-client/device-shim 已退役,2026-09-29 归并进 dsh-plugin-ai1net/lib/device-access.js(模块⑥「设备接入」)⇒ 换成现承载方真名 |
验证:py_compile 过;直调 build() 打印面向用户文案 ⇒ 「手机接入」0 命中、「垫片」0 命中,chip① 已显示新系统名。
保留未动(判据=有客观可判的取舍,⛔ 不擅自扩大):
- 「本地中转」是 2026-09-30「说人话」批量替换有意定下的说法(术语对照表
| 本地反代 | 「本地中转」 |)⇒ ⛔ 改回去会推翻那次决定。 - chip②
dsh-client · 覆盖网络节点 · 中继客户端属另一条组件(覆盖网络线),其系统名本轮未取证 ⇒ ⛔ 不确定不改。 :20090裸端口是真读数(netstat/日志真值),⛔ 不是抽象词 ⇒ 保留。
四、遗留 3:f8a792ab 归属 —— ⛔ 未动,报用户
取证(只读):
| 会话 | 标题 | 状态 | 诊断日志 |
|---|---|---|---|
f8a792ab |
检查多会话协作机制并修复问题 | completed(08:55) | 今天 10.0 MB ⇒ 已哑 🔴 |
a202550c |
主控 · 唤醒机制线 · … | completed(07:13) | 昨天 10.0 MB 🔴/今天 4.2 MB(已轮转恢复) |
345e6839 |
主控 · 协作机制 · 阈值交接收尾 | working | 1.8 MB ✅ |
- 协作登记
collabd-state.json里roles.main = f8a792ab(陈旧,它已结束且已哑)。 - 本会话
345e6839就是唯一带「主控」前缀的活会话,而它是自动化会话(is_background_automation=1,用户看不见、不可接续)。
⇒ 工作区当前没有任何「活的且可接续」的候选主会话 ⇒ 改认谁都是错的(把通知投给用户看不见的会话 = 比现在更糟)。
⇒ 按任务书「判不准 ⇒ 报用户,⛔ 不要自己动」:本轮未改 roles、未归档任何会话(宿主库 sessions 属活库,⛔ 更不碰)。
🔴 需用户拍板的一件事(下一节单列)。
五、本轮新发现(不在清单内,⛔ 未动手,仅登记)
_deaf_sids() 扫的是 今天+昨天 两个日期目录。而宿主日志是按天分目录(logs/<日期>/sdk/conversations/),
昨天的文件是历史、永远不会再增长 ⇒ 任何「昨天撞过 10 MiB 上限、今天已正常轮转」的会话,会被永久判哑。
- 实证:
a202550c昨天 10,485,758 B、今天 4,354,629 B(宿主今天仍在写它) ⇒ 它没哑,却仍被判哑。 - 后果是方向相反的新假绿:本该投递的目标被拦下 ⇒ 通知落空。09:12 那条
NEED-USER(称a202550c已哑)即由此而来。 - 判据收窄的取舍(留给下一棒/用户):只认最新一天(今天)—— 好处是消除上述假阳性;代价是「跨天后还没写过日志」的会话当天扫不到(它当天没写 = 也没在增长,影响有限)。
- ⛔ 本轮未改:超出 4 项清单,且属机制层(改后须重跑 selftest)。
六、上一棒改动清单(⛔ 未 commit)
| 文件 | 改动 |
|---|---|
~/.workbuddy/skills/multi-session-collab/scripts/selftest.py |
+2 用例(+_fake_cfg/_with_fake_cfg 工具 + DEAF_MIB 常量) |
…/.workbuddy/collab/board_ext.py |
2 处退役文案 |
锁状态:上一棒持全局独占 → 已 --release-exec "会话哑掉收尾"。
七、本棒(接续会话)已修:_deaf_sids() 永久判哑(2026-10-01 09:2x–09:4x)
来源:本线接续会话(上一棒
345e6839达阈值按 §1.5 G 开的接续会话,顶替主会话职能)。 锁:机制层 ⇒ 全局独占。
改了什么(~/.workbuddy/skills/multi-session-collab/scripts/collabd.py::_deaf_sids()):
| 旧 | 新 | |
|---|---|---|
| 判据 | 今天+昨天 任一 ≥9.5 MiB ⇒ 判哑 | 每个会话取它最新一天那份日志 ≥9.5 MiB ⇒ 判哑 |
- 🔴 旧写法的病:宿主会话日志按天分目录、昨天那份永不再增长 ⇒「昨天撞过上限、今天已正常轮转」的会话被永久判哑 ⇒ 本该投出去的唤醒被静默拦下(方向相反的新假绿)。
- ⚠️ 今天的兜底保留:某会话今天没有日志(宿主今天没写过它)⇒ 仍退到昨天那份判 —— 比"直接放行"保守。
生产数据实测(只读,⛔ 未跑 --tick):
- 旧判据 7 条哑 → 新判据 6 条哑;唯一被收窄掉的正是
a202550c(昨天 10.49 MB / 今天 4.35 MB,宿主仍在写)✅ f8a792ab(今日 10,485,715 B)仍判哑 ✅ —— 第一轮那道闸没有被削掉。- 副作用面=零:主会话解析(旧 vs 新)结果逐字相同(
5f607d3e·prefix:主控)。
回归用例(scripts/selftest.py):+1 条「只认最新一天」(昨 10 MB/今 4.2 MB ⇒ ⛔ 不判哑;今天才撞上限 ⇒ 判哑;只有昨天 ⇒ 仍判哑;含精确集合断言)。
_fake_cfg()增day_offset(0=今天 / 1=昨天);_prepare()每轮清空tmp/selftest/fake-cfg(防"第二轮才红"的跨轮污染)。- ✅
python selftest.py⇒ PASS 38 / FAIL 0(基线 37 + 新增 1);连跑两次均绿。
顺带修掉一条环境假红(⛔ 与本次改动无关,是既有用例的前提覆盖不全):「僵尸对账」用例只靠 adopted 反推前提的一半,
而僵尸分支的完整前提是「除观察者外无人在跑」∧「无 IN_PROGRESS 运行」 ⇒ 自动化会话跑本自测时,它自己的
automation run 必然 IN_PROGRESS ⇒ 前提不成立却不 SKIP ⇒ 必然假红(实测:收窄前整套 36/1,只有本条红)。
⇒ 照该用例既有的"前提不成立就 SKIP"姿势补上后一半(纯测试侧,⛔ 未动生产逻辑)。
七-b 本棒改动清单(⛔ 未 commit)
| 文件 | 改动 |
|---|---|
multi-session-collab/scripts/collabd.py |
_deaf_sids() 判据收窄为「每个会话只认最新一天」 |
multi-session-collab/scripts/selftest.py |
+1 用例「只认最新一天」;_fake_cfg(day_offset);_prepare() 清 fake-cfg;僵尸用例补 SKIP 前提 |
⛔ 未做(不属本棒清单,如实挂着):未 commit/push(未获指令);未把技能本机→服务器单向推(改的是技能,
两处落点 ~/.workbuddy/skills/ 与服务器副本需 md5 双端一致,留给后续按 §1.5 B 阶段 5 处理)。
锁状态:本棒持全局独占(机制层 --claim-exec "5f607d3e")→ 已 --release-exec "5f607d3e";服务器侧那把
storyforge-e2e 操作锁属他人,按 R9 未动。