- 变更规模:新增 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/ 知识文件,按口径入库)
121 lines
9.0 KiB
Markdown
121 lines
9.0 KiB
Markdown
# 会话哑掉线 · 收尾报告(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 未动。
|