pi-multi-viewers 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -21,15 +21,18 @@ fake_agent.py 测试薄壳:responder = 随机决策
21
21
  start_discussion.py 组合层:CLI 分发 + 环境创建/启动/清理(_resolve_spec / setup_environment)
22
22
  spec_gen.py spec 生成层(question/骨架/viewers 校验与快照/agent 定义 + pi 环境探测)
23
23
  observability.py 观测层(check_status / --report / --wait / loop 存活检测)
24
+ ↑ 分析目录内含 4 个模块的**运行快照**(非事实源):改主仓代码
25
+ 对已启动的分析不生效,排查时用同名文件 diff 溯源
24
26
  human_viewer.py 【human 通道】只读展示(增量/--follow/游标)
25
27
  human_sayer.py 【human 通道】插话命令(单次/stdin/交互 -i)
26
28
  scripts/mv.sh 稳定入口 shim(exec mv_cli.py;路径被 prompt/README 引用)
27
29
  scripts/pi-probe.sh LLM 探针(跑 pi + 登记新 session → 残留检查器可追溯)
30
+ scripts/check-residue.sh 残留检查(session/进程/目录三类;增删 scripts/ 时同步本节)
28
31
  mv_cli.py 命令行实现(prepare/start/status/report/wait/cleanup/view/say)
29
32
  prompts/multi-viewers.md /multi-viewers 入口(视角设计三原则 + 审核闸门)
30
33
  extensions/multi-viewers-say/ /multi-viewers-say 插话(registerCommand,零 LLM)
31
34
  docs/design.md 设计文档(fork 源模式与规模口径 + 决策记录)
32
- package.json npm 包 pi-multi-viewers(pi.prompts 注册;发版待办)
35
+ package.json npm 包 pi-multi-viewers(pi.prompts 注册;**版本号唯一事实源**)
33
36
  templates/ AGENTS.md.tpl / agent.md.tpl / gitignore.tpl / spec-readme.md.tpl
34
37
  viewers/ 示例视角(效率/简单/铁律——仅是形态示例,视角内容由用户按需自定)
35
38
  docs/examples/first-experiment/ 首次实验存档(机制验证 + 模板原型 + 真实消息)
@@ -54,17 +57,33 @@ tests/ 测试(unittest discover tests)
54
57
  移除,fork 使其冗余;background 只写显式边界,不复述对话)。
55
58
 
56
59
  **agent 进程环境**:`GIT_CEILING_DIRECTORIES`(git 上溯防护)——注入点
57
- `meeting_loop._spawn_env`。**扩展策略(决策 20):默认零扩展** ——
58
- `--no-extensions --no-skills --no-prompt-templates --no-themes`,只留 pi 内置
59
- 工具与项目内 AGENTS.md。为什么:两类插件在**我们这种 session 形态**上都是分钟级
60
- 负担、且都在关键路径上(loop 等进程退出才继续)——
60
+ `meeting_loop._spawn_env`。**扩展策略(决策 20):三档**
61
+ (`meeting_fs.EXTENSION_POLICIES` / 协议 `extensionPolicy` / CLI `--extension-policy`):
62
+
63
+ | 档 | 唤醒命令 | 用途 |
64
+ |---|---|---|
65
+ | **mc-tools**(默认) | 四个 `--no-*` + `-e <MC 的 subagent-entry.js>` | 给 agents **按需检索项目背景**(`ctx_search`)——背景蒸馏机制已移除,这是其补充通道。**允许而非要求 MC**:找不到 MC → 降级为零扩展 + 一行可见说明(`ctx_search` 本次不可用)|
66
+ | **none** | 四个 `--no-*` | 零扩展、**零依赖**(无 MC 的机器/CI 用这档)|
67
+ | **all** | 不加任何 `--no-*`(pi 默认发现)| A/B 实验与显式 opt-in |
68
+
69
+ 为什么**不能**用插件全档(`all`):两类插件在**我们这种 session 形态**上都是分钟级负担、
70
+ 且都在关键路径上(loop 等进程退出才继续)——
61
71
  · **AFT**:大 session 上进程退出前多活数分钟(受控对照 445.9s → 0.5s);
62
- · **MC**:它的 historian 对"带大段未处理历史"的 session **每次必失败并立刻重试**
63
- (受控对照:同输入 **447s → 10.3s,43 倍**)。
64
- 零扩展**真场实测**:墙钟 12m31s / 每次唤醒 48.1s / 收尾≈0% / historian 0 次。
65
- 加回扩展 = **显式 opt-in**(`--extensions` / 协议 `extensions: true`),且须自证
66
- 净收益(design.md 决策 20 的门槛条款)。**主 pi 完全不受影响**(只改我们 spawn 的
67
- agent 进程命令行;主 pi MC/历史学家照常)。
72
+ · **MC 全档**:它的 historian 对"带大段未处理历史"的 session **在默认输出上限
73
+ (32000)下**每次必失败并立刻重试(受控对照:同输入 **447s → 10.3s,43 倍**;根因 =
74
+ 推理流吃光输出上限——该上限**可调**:主 pi 抬到 131072 后首跑即成功、输出 36954 ✓)。
75
+ 零扩展**真场实测**:每次唤醒约 48–82s、收尾≈0%、historian 0 次(墙钟随唤醒数变动,
76
+ 区间与测点见 docs/design.md §二)。
77
+ **mc-tools 档的实测**:entry **只注册工具、不装 hook** → historian 0/6 ✓(生产 0/3 ✓);
78
+ `ctx_search` 实测可用 ✓;成本**未测得显著差异**(受控探针 n 小、组内方差>组间差 ✗;
79
+ 生产基线:本场 strict=1、n=19,唤醒启动段中位 **0.68s**、收尾中位 0.04s ✓)。
80
+ **入口解析 fail-fast**(`meeting_fs.resolve_mc_tools_entry`:从 pi 的 packages 找 MC 包 →
81
+ 读它声明的扩展入口 → 取同目录的 subagent-entry.js);缺 MC 时**可见降级**为零扩展。
82
+ **依赖边界**:mc-tools 档**允许而非要求** MC——缺 MC 时降级为零扩展,且**可见**
83
+ (打印一行"本次按零扩展运行:ctx_search 不可用";无静默铁律);`none` 档零依赖
84
+ (无 MC 的机器/CI 显式选它)。**测试/探针保真**:设 `MV_MC_TOOLS_STRICT=1` →
85
+ 缺 MC 即报错退出(否则测试可能在"没装 MC"下通过而 ctx_search 从未生效)。
86
+ **主 pi 完全不受影响**(只改我们 spawn 的 agent 进程命令行;主 pi 的 MC/历史学家照常)。
68
87
 
69
88
  **关键约定**:pi sessions 目录编码 = `--` + 去首尾斜杠内斜杠换 `-` + `--`
70
89
  (`/tmp` → `--tmp--`;wrapper 解析 fork 源依赖它,编码错一根横线 = 静默
@@ -184,6 +203,21 @@ loop、状态从 git 共享事实推导、单一事实源 = protocol.json、无
184
203
  `docs/test-methodology.md`——新方法在那里追加,AGENTS.md 不逐条同步
185
204
  (避免 100 个方法全堆进来)。
186
205
 
206
+ ## 文档维护纪律(2026-09-14 文档漂移自审共识)
207
+
208
+ **文档不做第二事实源**——同一事实被多处抄写,抄本必随实现演进漂移(本轮实测:
209
+ "目录发现兜底"一处行为被抄 3 份、全部滞后于代码;版本号 2 处、状态列举 3 版不一)。
210
+
211
+ 1. **有唯一事实源 → 一律引用,不复制**(与变更频率无关):版本号 → `package.json`;
212
+ 命令行选项 → `--help`;报告字段 → `docs/design.md`「观测面契约」;状态取值 →
213
+ `observability.check_status` 定义处;容量/规模 → `docs/design.md §二`。
214
+ **无事实源 → 补一行 + 增删同步**(按变更频率分级,如 `scripts/` 清单)。
215
+ 2. **复述类问题的改法优先级**:**删复述引权威** > **最短准确陈述**(无权威入口的
216
+ 行为描述)> **就地改准确**(必须保留语境时)。
217
+ 3. **两条判据**:① 重复"计算"在冷路径可接受、重复"**事实**"在文档不可接受
218
+ (报告的两次遍历不合并;文档的复述必去)② **数字必须带口径**(测点/样本/是否
219
+ `--force`;单点数字不宜当承诺)。
220
+
187
221
  ## Git 准则(用户约定,沿用)
188
222
 
189
223
  1. **每次改动先更新本地 git**:对本项目代码/文档的每次修改,先 `git add` + `git commit` 记录。
@@ -197,9 +231,9 @@ loop、状态从 git 共享事实推导、单一事实源 = protocol.json、无
197
231
 
198
232
  - **当前形态**:prompt × 1(multi-viewers,开发机已注册可用)+
199
233
  extension × 1(multi-viewers-say 插话:零 LLM,直接 spawn human_sayer.py;
200
- 目录发现 = `<cwd>/mv-<sessionId>-*` 最新,兜底 `mv-*`(排除
201
- `mv-spec-*`)并警告)
202
- + wrapper。**npm 已发布 0.3.0(2026-09-12)**。
234
+ 目录发现 = `<cwd>/mv-<sessionId>-*` 最新——**无兜底**:未匹配即报错
235
+ rc 1,需显式传目录)
236
+ + wrapper。**npm 已发布**(版本以 `package.json` / registry 为准)。
203
237
  - **开发机安装(两步,缺一不可;2026-09-10 实测)**:
204
238
  ① `pi install /root/pi-multi-viewers`——**注册包**(写
205
239
  `~/.pi/agent/settings.json` 的 `packages` 数组);pi 不是"扫 node_modules
package/README.md CHANGED
@@ -33,7 +33,8 @@
33
33
  2026-09-10;随主会话增长漂移),加模型 384k completion 预留即超 1M 窗口,
34
34
  provider 直接 400 拒绝(`pi --fork` 原生命令同样超窗)。budget 把基线压到
35
35
  ~80k est,首唤(唤醒 1 首请求)≈132k tokens,可正常进行(e2e 实测:
36
- 三视角 1519 分钟完整收敛)。权威口径与测点见 docs/design.md §二。
36
+ 三视角约 1235 分钟完整收敛——决定因素是**扩展策略与唤醒数**,区间与测点见
37
+ docs/design.md §二)。
37
38
 
38
39
  ## 安装
39
40
 
@@ -75,8 +76,9 @@ ls ~/.pi/agent/npm/node_modules/pi-multi-viewers/scripts/mv.sh
75
76
  执行",不需要经过 LLM)。
76
77
 
77
78
  **目录可以省略**:`--view`/`--say`/`--status`/`--report`/`--wait`/`--cleanup`
78
- 不带目录时自动定位"本 session 当前分析"(`mv-<sessionId>-*` 最新;找不到
79
- 则取最新 `mv-*` 并警告;判据 = 含 `repo.git`)。传目录仍支持(显式优先)。
79
+ 不带目录时自动定位"本 session 当前分析"(只匹配 `mv-<sessionId>-*` 最新;**未匹配
80
+ 即报错退出、不猜目录**——破坏性命令尤其不能猜;判据 = 含 `repo.git`)。传目录仍支持
81
+ (显式优先)。
80
82
  这样路径不需要经过任何 LLM 记忆——此前命令都要求绝对路径,等于让主 pi
81
83
  把长路径记在上下文里复用。
82
84
 
@@ -91,17 +93,19 @@ ls viewers/
91
93
  scripts/mv.sh --prepare "<主题>" # spec = question.md(+background.md)
92
94
  scripts/mv.sh --start <spec目录> # 启动(自动挂载主 session;默认 budget 模式)
93
95
  # 可选:--fork-mode compaction|budget|full(见上表;一般不调)
96
+ # 可选:--extension-policy mc-tools|none|all(默认 mc-tools = agents 带 MC 的只读检索工具
97
+ # ctx_search;none = 零扩展、零依赖;all = 走 pi 默认发现。缺 MC 时 mc-tools 可见降级)
94
98
  # 高级:--agents "a,b" 起一次性视角(不建 viewers/ 时用;prompt 入口不传它)
95
99
 
96
100
  # 观看:--start 会输出可直接执行的 !! 流式观看命令(复制执行)
97
101
  scripts/mv.sh --view # 一次性增量查看(主 pi 记录 HEAD 作下轮 --since)
98
102
  # --follow 会打印【状态】(meeting/all-freezing/round-robin/concluded)
99
103
  # 与【进度】(meeting 消耗/上限 | freezing 集合 | rr → 下一位)
100
- # 结束时自动附【分析报告】(消息/墙钟/配额/进程跨度/LLM 用量)
104
+ # 结束时自动附【分析报告】(字段集以 docs/design.md「观测面契约」为准)
101
105
 
102
106
  # 插话 / 状态 / 收尾(目录可省略——自动定位本 session 当前分析)
103
107
  scripts/mv.sh --say "<文本>" # 插话(命令行形态;pi 内用 /multi-viewers-say)
104
- scripts/mv.sh --status # running / done / stalled / stopped(done 时附 [result] 路径)
108
+ scripts/mv.sh --status # 状态 + 路径(取值与含义以该命令输出为准)
105
109
  scripts/mv.sh --report # 只读报告(流程/配额/进程/LLM/档位对照;冷路径,不持久化)
106
110
  scripts/mv.sh --cleanup # 收尾(result.md 自动留存到 <dir>-result.md)
107
111
  ```
@@ -159,7 +163,7 @@ human_viewer/sayer human 插话通道
159
163
  ## 开发
160
164
 
161
165
  ```bash
162
- ./tests/run_tests.sh # 全量(~280s)
166
+ ./tests/run_tests.sh # 全量(`--force` 语义,本机 ~300s;指纹未变时 --reuse 毫秒级)
163
167
  ./tests/run_tests.sh --reuse # 指纹未变跳过
164
168
  ```
165
169
 
package/docs/design.md CHANGED
@@ -102,7 +102,8 @@ compaction 的 `firstKeptEntryId` 起 + 其后的条目"——窗口内含 compa
102
102
  | `result.md`(固定位) | resultWriter loop | 结论文档 | 人 | 是(收尾判据) | — |
103
103
  | `--report`(视图) | observability | 文本行 | 人(**三个出口**,见下) | **否**(不得升级为验收 gate) | 冷路径一次性 —— **O(session 大小)**:每 agent 读整个 fork-src jsonl(实测 3 × 789KB ≈ 2.4MB/次、50–150ms/次,×3 出口 <0.3s/次分析),**不得进入任何轮询路径**(e2e16 评审量化) |
104
104
 
105
- **报告的字段集**(e2e17 评审后定稿)——**四组谓词分组 + 一组对照**,
105
+ **报告的字段集**(e2e17 评审后定稿,后续增补不计数——字段行以本表为准)——
106
+ **谓词分组 + 对照 + 事实行**,
106
107
  全部**只读已有家**(session 的文档化字段 + loop log 登记字段),不新增度量、
107
108
  不在 loop log 增记(同一事实两处 = 双写):
108
109
 
@@ -113,6 +114,7 @@ compaction 的 `firstKeptEntryId` 起 + 其后的条目"——窗口内含 compa
113
114
  | `seconds_by_stopReason` | `{键=stopReason 原值: Δ 合计}` | 同上;**口径 = 相邻条目 Δ 合计**(每次唤醒首条响应**也计入**;跨唤醒空闲不进入 Δ——唤醒 prompt 本身是一条 user 条目,空闲落在"上一唤醒末条 → 本次 user 条目"之间)。⚠️ 曾短暂采用"首响不计时",理由(跨唤醒空闲)经 e2e20 评审批证伪后**已撤回**(见决策 19 的 e2e20 修正段) |
114
115
  | `effective_levels` | `[thinkingLevel…]`(session 侧,去重保序) | `档位:声明 X | 生效 Y | ✓一致 / ⚠不一致` |
115
116
  | (对照)`declared` | `pi-agent.json.thinking` | 同上——声明值与生效值**并列**(此前从没人对照过:探测失败会静默取档,spec 表面正常) |
117
+ | `扩展策略` 行 | `声明 / 生效 / strict / 降级原因` | 声明 = `protocol.extensionPolicy`;生效 = loop log 的**登记行**(首唤打一次:`扩展策略: 声明=X 生效=Y strict=0\|1[ 降级原因=…]`)→ 报告给"声明 vs 生效 + ⚠ 生效≠声明"(与"档位:声明/生效"同型;e2e24 评审 E2)|
116
118
  | `终止` 行 | 分类 + 原料计数 | `终止:共识(RR 全体 pass)|freezing N / all-freezing N / pass N / stall 接管行 N`;分类判据只有事实(bare 的 type 计数 + loop log 的"超时兜底/声明接管"字样)——**不做评分** |
117
119
  | `唤醒构成` 表 | 每次唤醒一行 + 每 agent 合计 | 四端点(spawn / 首事件 / 末事件 / exit)+ 往返数 + `Δ助手` + `Δ工具` + retry + 本唤醒内的 commit;合计给 `跨度 = 启动前 + 事件内 + 收尾` 与平均/往返/retry(e2e23 分析产出,见下) |
118
120
 
@@ -269,9 +271,8 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
269
271
  结果经 `ctx.ui.notify` 反馈——**不经过 LLM**(插话本质是本地命令执行;
270
272
  经 LLM 会引入不确定性与额外延迟)。目录发现零状态文件:
271
273
  `ctx.cwd` + `sessionManager.getSessionId()` → `mv-<sid>-*` 最新
272
- (session 隔离);无 sid 目录时兜底项目下最新 `mv-*`(排除
273
- `mv-spec-*`)并**警告降级**
274
- (宁可提示也不静默插错分析)。观看仍用 `!!` 流式(命令 API 无原生流式
274
+ (session 隔离);**无兜底**——未匹配即报错 rc 1(行为事实源 = 决策 15:
275
+ 破坏性命令不猜目录)。观看仍用 `!!` 流式(命令 API 无原生流式
275
276
  通道,bash 流式是平台原生能力)。
276
277
  10. **question.md 的主题行措辞 = `# 分析主题:`(唯一)**:生成端
277
278
  (`gen_question` / `gen_spec_skeleton`)、模板(`spec-readme`)、prompt、
@@ -279,6 +280,17 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
279
280
  消费端**只认它**,旧措辞 spec → fail-fast(明确报错,不静默退化)。
280
281
  曾出现双轨(生成产 `# 讨论主题:`、消费端写兼容循环兜两种)——那
281
282
  正是"补丁掩盖设计缺陷"的形态(不改生产、只兜消费端)。
283
+ 10b. **无产出重试上限 3 + stall 兜底 600s**(机制事实,2026-09-14 补记):
284
+ `meeting_engine.MAX_RETRY = 3` —— agent 唤醒后未产出消息时最多重试 3 次,每次重试
285
+ 相当于**一次完整唤醒**(真场 48–87s/唤)→ 单轮最坏 **+2.5–4.5 分钟**;仍无产出则
286
+ loop 代写(不耗该 agent 配额)。`meeting_fs.DEFAULT_STALL_TIMEOUT = 600` —— 全体
287
+ 无新 commit 达 600s 即进入"接管"分支(死锁的墙钟下限 = 10 分钟/次)。
288
+ 10c. **分析目录内的代码副本 = 运行快照(非事实源)**(机制事实,2026-09-14 补记):
289
+ `start_discussion.setup_environment` 把 4 个模块拷进分析目录,`meeting_loop`
290
+ **从副本运行**(`start_discussion.py:416-419` / `:710`)。因此"改主仓代码对
291
+ 正在跑的分析不生效"是**设计如此**;排查时可用副本与主仓同名文件 `diff` 溯源,
292
+ cleanup 后副本随目录消失、不可再追。
293
+
282
294
  11. **stall 接管 = 心跳式软仲裁(非互斥)**:非 rw 在无进展超时时接管收尾,
283
295
  先 pull 重检共享事实(concluded / result.md)→ 写接管声明 commit
284
296
  (**只为推进 HEAD**,使对方 `_stall_elapsed` 归零而退出该分支)→
@@ -392,7 +404,10 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
392
404
  - 现状只关**语义搜索**,AFT 仍加载(trigram 索引、LSP、工具集、每 agent
393
405
  一个 `aft` 索引服务)。剩余实测成本:无扩展 2.2s / 仅 MC 2.8s /
394
406
  AFT(语义关)3.3–4.5s → **~1–2s/唤醒 ≈ 2% 墙钟**(33 唤醒 ≈ 1 分钟
395
- / 55 分钟)。最初那 57s 已经拿回,**速度上几乎无剩余收益**。
407
+ / 55 分钟)。最初那 57s 已经拿回,**小 session 上几乎无剩余收益**。
408
+ **限定(2026-09-14 注记)**:"2%" 仅来自**小 session 单点探针**、**不可外推**——
409
+ 生产规模下 AFT 的收尾成本可达数分钟(见本节后文 445.9s 对照);"是否屏蔽 AFT"
410
+ 以决策 20(默认 mc-tools / none)为准,本句仅存档。
396
411
  - 三种屏蔽方式:`--no-extensions` + `-e <MC 扩展入口>`(AFT 不加载、
397
412
  MC 保留;入口可从 `~/.pi/agent/settings.json` 的 `packages` + 包的
398
413
  `pi.extensions` 解析,不硬编码);`--pure`(全关,已实现);现状。
@@ -450,8 +465,8 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
450
465
  (具名推导 `agent_config_aft_file`,写入侧与判定侧共用),未注入时打一行
451
466
  **事实**日志;`build_agent_config` 只返回 warnings(目录不再返回——
452
467
  生产端本来就不用),并删掉只有测试在用的 `source_config_home` 参数。
453
- 20. **agent 进程默认零扩展**(2026-09-13 用户定;取代决策 19 的"屏蔽 AFT、
454
- 保留 MC"):
468
+ 20. **agent 进程扩展策略三档(默认 mc-tools)**(2026-09-13 定零扩展、
469
+ 2026-09-14 用户定为默认 mc-tools 并改“允许而非要求”;取代决策 19):
455
470
 
456
471
  **证据(两类插件都在关键路径上,都是分钟级)**:
457
472
  - **AFT**:大 session 上进程退出前多活数分钟——同一份 1.9MB session、同一模型
@@ -460,16 +475,59 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
460
475
  fork 自大历史)**每次必失败并立刻重试**——同一份 fork 源、同一极小任务受控
461
476
  对照:**给 MC 447.2s(其中 435.5s 是 3 次连续失败的 historian、尾部占 97%)
462
477
  vs 不给 MC 10.3s(43 倍)**。曾疑为 historian 模型 id 过期(已修,实测**仍然**
463
- 失败)→ 结论:对本项目的 session 形态,MC 的压缩机制**结构性不工作**。
478
+ 失败)→ **修正(2026-09-14)**:根因至少含**可调默认上限**——MC 源码
479
+ `maxOutputTokens: historian?.maxTokens ?? 32000`,而 historian 模型是
480
+ reasoning:true(推理流吃光上限 → "all reasoning, no text")。主 pi 把
481
+ `historian.maxTokens` 抬到 131072 后**首跑即成功**(其 context.db #916:
482
+ completed、输出 36954 > 旧上限 32000)。故原结论应限定为"**在该默认上限
483
+ (32000)下不工作**";agents 会话(fork 大历史)在抬高上限后**未复测**。
464
484
  - **真场验证(零扩展)**:墙钟 **12m31s** / 32 次唤醒 / **每次唤醒 48.1s** /
465
485
  **收尾 ≈0%**(对照插件在场时 66–78%)/ **historian 0 次** / 并行度 2.42/3.0 /
466
486
  档位对照 ✓。同一机制的对照:e2e19 71.6s·17m19s、e2e20 81.6s·20m34s、
467
487
  e2e21 **330s·1h13m**(historian 风暴 62 次 60 失败)。
468
488
 
469
- **做法**:默认唤醒命令带 `--no-extensions --no-skills --no-prompt-templates
470
- --no-themes`(保留内置工具与项目内 AGENTS.md);加回扩展是**显式 opt-in**
471
- (CLI `--extensions` / 协议字段 `extensions: true`,`gen_protocol` **恒写**该
472
- 字段——默认 `false`)。**主 pi 不受影响**(只改我们 spawn 的 agent 命令行)。
489
+ **做法(三档;值域/默认值的家 = `meeting_fs.EXTENSION_POLICIES` /
490
+ `DEFAULT_EXTENSION_POLICY`,协议字段 `extensionPolicy`,CLI
491
+ `--extension-policy`)**:
492
+
493
+ | 档 | 唤醒命令 | 语义 |
494
+ |---|---|---|
495
+ | `mc-tools`(默认) | 四个 `--no-*` + `-e <MC subagent-entry.js>`(找不到 MC 时退化为四个 `--no-*`)| 只要 MC 的**只读检索工具**(`ctx_search`);**允许而非要求** MC |
496
+ | `none` | 四个 `--no-*` | 零扩展:最快、**零依赖** |
497
+ | `all` | 不加任何 `--no-*` | pi 默认发现(A/B 与显式 opt-in)|
498
+
499
+ **`mc-tools` 档 = 默认档**(2026-09-14 加并定为默认,用户裁定"提供 ctx_search
500
+ 是必要的 background 补充”):**fork 本身是主背景通道**(agent 继承主会话的开发
501
+ 上下文),覆盖面受 ① fork 源内容 ② `budget` 裁剪比例限制;`ctx_search` 是它的
502
+ **兜底**(按需检索记忆/文档/历史)。MC 的
503
+ `subagent-entry.js`(MC **自己**给它的"搜索类子代理"用的入口)**只注册工具、
504
+ 不装任何 hook** → 给 agents 按需检索能力(memories / docs / 历史),
505
+ **不含** historian/压缩/打标。实测:`ctx_search` 可用 ✓;historian 0/6 ✓;
506
+ **成本未测得显著差异**(受控探针 n 小、组内方差 > 组间差 ✗;生产基线:首次真场
507
+ strict=1、n=19 → 唤醒启动段中位 **0.68s**、收尾中位 0.04s ✓)。
508
+ **入口解析 fail-fast**(`resolve_mc_tools_entry`:pi 的 packages → MC 包 →
509
+ 它声明的扩展入口 → 同目录 `subagent-entry.js`);缺 MC 时**可见降级**(严格模式
510
+ `MV_MC_TOOLS_STRICT=1` 才报错退出)。
511
+ **实现纪律(e2e24 评审 S1 的教训)**:三档共用**同一段零扩展前缀**,
512
+ `_build_wake_cmd` **只有一个出口**——降级只是"少追加一个 `-e`"。此前降级
513
+ 分支自拼前缀后提前 `return`,把 model/thinking/system-prompt/`--print` 与
514
+ spawn cwd 全截断("无 MC 的机器"上产出残缺命令)。**登记行**:首唤打
515
+ `扩展策略: 声明=X 生效=Y strict=0|1 [降级原因=…]`——报告据此给"声明 vs 生效"
516
+ (E2;与"档位"同型),否则降级只在 loop log 里、产品面看不见。
517
+
518
+ **依赖边界(用户 2026-09-14 定)**:mc-tools **允许而非要求** MC——缺 MC 时
519
+ **降级为零扩展并按 none 运行**,但**必须可见**(打印一行"mc-tools 档未生效
520
+ (原因)——本次按零扩展运行:ctx_search 不可用";无静默铁律)。
521
+ `none` 零依赖(无 MC 的机器/CI 显式选它)。**死代码纪律**:`--extensions`
522
+ 别名与 `extensions: true` 历史字段(只存在约 1 天)**已删净**(无移除条件的
523
+ 兼容层不留——同 `--pure` 先例);扩展策略只有一个入口:`--extension-policy`
524
+ + 协议字段 `extensionPolicy`。
525
+ **测试/探针保真开关**:`MV_MC_TOOLS_STRICT=1` → 缺 MC 即报错退出。
526
+ 为什么需要它(测试阶段语义):降级虽可见,但"没降级"这件事在测试里必须可断言——
527
+ 否则测试可能在"没装 MC"的环境下通过,而 `ctx_search` 从未生效
528
+ (测试环境准确性优先;成版行为 = 允许降级)。
529
+
530
+ **主 pi 不受影响**(只改我们 spawn 的 agent 命令行)。
473
531
 
474
532
  **代价**:agents 用 pi 内置 read/write/edit/bash/grep/glob;无 `ctx_*` 与知识
475
533
  注入。零扩展真场里三视角自述:"内置工具胜任本任务、未因缺工具放弃或简化检查
@@ -488,7 +546,7 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
488
546
  将来若要为 agents 加回任何扩展,须**显式 opt-in + 净收益账**(本次实证:
489
547
  AFT/MC 两次都是"加了才知道贵")。
490
548
 
491
- 21. **git 守卫范围 = 从讨论 workdir 发起的操作**21. **git 守卫范围 = 从讨论 workdir 发起的操作**(`GIT_CEILING_DIRECTORIES`
549
+ 21. **git 守卫范围 = 从讨论 workdir 发起的操作**(`GIT_CEILING_DIRECTORIES`
492
550
  注入于 spawn);主项目仓库不在守卫范围(agent 的 cwd 就是主项目,其
493
551
  约束归指令层 + 主项目 `.gitignore`)。要拦主仓库需换机制类(沙箱/钩子),
494
552
  经评估收益不支撑扩面。
@@ -538,6 +596,10 @@ commit 是溯源记录、本节是长期引用点——不并存两份权威值
538
596
 
539
597
  ---
540
598
 
599
+ - **README 计时样本里的离群值 2494s**(2026-09-11,≈8× 中位):成因未查(疑机器
600
+ 负载/挂起)。**观测点**:`tests/.cache/last.log` 的 `Ran N tests in Ns` 序列
601
+ —— 若再次出现 >1000s 的单次值,比对同批 `--force` 的 CPU 时间以区分负载与挂起。
602
+
541
603
  ## 五、已知边界与未覆盖
542
604
 
543
605
  - `compaction` / `full` 两模式在长会话下的实跑行为未验证(分析中仅用
@@ -0,0 +1,146 @@
1
+ <!-- 存档:docs/reviews/2026-09-14-e2e24-extension-policy-review.md
2
+ 来源:一次真实多视角分析的 result.md 原文(未删改,仅加本头与下方说明)。
3
+ 分析场次目录已随 --cleanup 删除;文中的消息编号(如 `铁律/0002`)不可再核验,
4
+ 仅作溯源线索(与代码注释引用约定一致:行为以自描述为准)。 -->
5
+
6
+ # 存档说明
7
+
8
+ - **主题**:审阅「扩展策略三档(默认 mc-tools)」的实现与证据链;并如实评估给
9
+ agents 提供 `ctx_search` 的实际价值与风险
10
+ - **场次**:`mv-mv-main-20260914-112746`(3 视角:效率 / 简单 / 铁律;真实 pi 讨论,
11
+ 以 `MV_MC_TOOLS_STRICT=1` 启动——确保本场确实带着 `ctx_search` 在跑)
12
+ - **抓到的问题**:
13
+ - **S1(高,生产可达)**:缺 MC 时的降级分支**提前 return** 截断命令构造 →
14
+ 在"无 MC 的机器"上产出残缺命令(缺 `--model`/`--print`/视角与协议注入、
15
+ spawn cwd 也错)——正是用户要求的"没装 MC 自动切回 none"那条路;
16
+ 两视角独立复现,我随后用零 LLM 复核确认。
17
+ - **S1a**:新增的那条测试只断言 token 有无 → 没抓到 S1(装置判别力不足)。
18
+ - **E2**:报告层没有"扩展策略(声明 vs 生效)"事实 → 无 MC 机器上的降级在
19
+ 产品面**看不见**(当天为确认"MC 生效没有"花了好几轮探针 + DB 查询)。
20
+ - **E1**:我在文档里写的"成本与 none 无差"**超出精度**(可比样本 n=2 vs n=3、
21
+ 组内方差 > 组间差)→ 应表述为"未测得显著差异"。
22
+ - **T1/T2/T3**:默认档翻转后的过时文本;"缺 MC 时响亮失败"与"可见降级"矛盾;
23
+ "agents 没有任何主项目背景通道"与 fork 模型矛盾(fork 本身就是主背景通道)。
24
+ - **F5/F6/F7/S2/F9**:解析链的 5 处缺陷(子串匹配可命中他包 / 首个候选失败即停 /
25
+ `pi.extensions` 字符串形态 / 条目形态解析两处 / pi agent 目录两处实现)。
26
+ - **ctx_search 的价值评估(第一手证据)**:9 次调用**全部由问卷诱导**、
27
+ **0 次决定性帮助**;命中 1 条**过期记忆**(指向已删机制);结构性解释 =
28
+ "检索的边际价值与 fork 新鲜度成反比"。
29
+ - **落地**:`91a1171`(Batch 1 修 S1 + 解析链重构 + 文本同步 + 报告"声明 vs 生效")·
30
+ `b9329fb`(Batch 2 删死代码:`--extensions` 别名 / `extensions: true` 兼容 /
31
+ 启动 loop 的 3 行转发)· 决策 20 同步(含 S1 教训与登记行)。
32
+
33
+ ---
34
+
35
+ # 多视角分析结果:审阅「扩展策略三档(默认 mc-tools)」的实现与证据链;并如实评估给 agents 提供 ctx_search 的实际价值与风险
36
+
37
+ - **参与者**:效率、简单、铁律(3 视角;resultWriter = 铁律)
38
+ - **分析类型**:审阅 + 建议(只读:未改文件、未跑测试、未启动分析)
39
+ - **主题来源**:`mv-spec-20260914-112728/question.md`
40
+ - **结论一句话**:三档机制**方向与分层正确**(值域/解析在 fs、命令与守卫在 loop、写入在 spec_gen、engine 不感知),但有两个必须分开的紧要项——**S1:默认档(mc-tools)的无 MC 降级路径是坏的**(提前 return 截断唤醒命令:缺 prompt/注入、cwd 错,生产可达)应**第一优先修复**;**E2:报告层没有"扩展策略(声明 vs 生效)"事实**,导致"本场到底带没带 ctx_search"只能靠外部考古,列第二。证据链本身有两处需改口(成本声称超精度;"agents 没有任何背景通道"过度陈述);**ctx_search 对"审阅本仓库代码"非必要能力**(9 次调用全部由问卷诱导、零决定性帮助、1 例过期记忆),但成本已实测有界(每唤醒启动中位 0.68s、收尾 0.04s),维持默认档 + 待自然场次数据复核。
41
+
42
+ ---
43
+
44
+ ## 运行元信息(本场)
45
+
46
+ | 项 | 值 | 来源 |
47
+ |---|---|---|
48
+ | 配置身份 | `extensionPolicy=mc-tools`(**首次生产运行**);`forkMode=budget`;`model=commandcode-goat/deepseek/deepseek-v4.1-flash`;`thinking=max`;`maxMeetingRounds=10`;`maxRRRounds=7`;`stallTimeoutSeconds=600` | `protocol.json` |
49
+ | 测试保真 | `MV_MC_TOOLS_STRICT=1` **实测在三个 loop 进程环境中**(不是"以为设了");wake-log 中 `-e <MC>/dist/subagent-entry.js` 在场 | `/proc/*/environ` + wake-logs |
50
+ | **终止原因** | **consensus**(RR 全员 pass,1 轮;非配额、非 stall) | loop 日志(引擎确定性事实) |
51
+ | 墙钟(首末 commit) | **853s ≈ 14.2 分钟**(setup → 铁律/0010;result 提交后略增) | `git log` |
52
+ | 唤醒 / 跨度 | **32 次唤醒**(效率 9 / 简单 12 / 铁律 11)——其中铁律第 11 次为写 result 的收尾唤醒(进行中);**已完成 31 次**的进程跨度合计 **2180s**,均 **70.3s**,max 238s(效率) | loop 日志 `elapsed_ms` |
53
+ | retry / stall | retry 3(每 agent 1 次,11:32 前后同批);stall 0 | loop 日志 |
54
+ | 配额使用 | 消息数:效率 6 / 简单 9 / 铁律 7(上限 10)→ **未撞配额** | 消息统计 |
55
+ | fork 源 | 601 条 / 丢弃 203 条 / est≈79k(字符/3)/ 构建 373ms | loop 日志 |
56
+ | **MC historian(生产验证)** | 三个 agent session 在 MC 账本中的 `subagent_invocations` 行数 **0/3**(+ 早前探针 0/11)——entry"只注册工具、不装 hook"在生产形态获得实证 | `context.db` |
57
+ | ctx_search 用量 | 本 agent 侧 **9 次**(效率 2 / 简单 3 / 铁律 4),**全部落在首唤窗口**;fork 源另含 2 次主会话继承的调用(**不属 agent 用量**——计数须按边界剔除继承历史) | session transcript 按边界核对 |
58
+
59
+ > 口径纪律:ctx_search 的统计只能在"边界之后"计数——fork 源携带的历史里有 2 次主 pi 自己的检索调用,全文件计数会把它们算成 agent 行为(本次核对中实测踩到过这个陷阱)。
60
+
61
+ ---
62
+
63
+ ## 一、确认问题清单
64
+
65
+ | 编号 | 严重度 | 文件:行 | 现象 | 依据 | 建议 |
66
+ |---|---|---|---|---|---|
67
+ | **S1** | **高(生产可达)** | `meeting_loop.py:340-342` | 缺 MC 的降级分支追加四个 `--no-*` 后 **`return cmd, session_dir` 提前截断**命令构造 → 缺 `--model`/`--thinking`/视角+协议 `--append-system-prompt`/`--approve`/`--print`,且 cwd 变成 `pi-sessions` 而非项目目录 | **两视角独立复现**(mock `resolve_mc_tools_entry` 失败):降级 11 项 / none 18 项、逐字相同=False、尾无 `--print`、cwd 错(简单/0001 + 铁律/0002) | 守卫先行 → **单一零扩展前缀** → mc-tools 只决定"能否追加 `-e`" → **删除提前 return** → 单一尾流程;验收四条(见下) |
68
+ | S1a | 中(S1 漏网根因) | `tests/test_meeting_loop.py:788-812` | 测试 docstring 把"命令形态 = 四个 `--no-*`、无 `-e`"写成验收口径;断言只查 token 有无,"等价 none 档"只存在于注释;配置全空值 | 读码 + 两视角核对 | 断言改为"降级返回与 none 返回**逐字同形**(除日志行)+ cwd=项目";配置带**非空** model/thinking/prompt_file;断言注释措辞与断言强度一致 |
69
+ | **E2**(=铁律 F8;效率 E2/E3) | 中 | `observability.py`(无 `extensionPolicy`/`mc-tools` 命中)+ `meeting_loop.py:337-339` + `start_discussion.py:424` | 报告层无"扩展策略(声明 vs 生效)"事实;降级说明只进 `loop-<agent>.log`;产品面只打印**声明**值 → 无 MC 机器上的降级在用户可见面静默;跨场成本/行为无法自动归因(今天为确认"MC 生效没有"付出多轮探针+DB 查询) | grep + 先例对照:thinking 已有"档位对照(声明 vs 生效)" | 报告头**一行**:`声明 / 生效(含真实降级原因)`(fail-open);strict 走 loop **启动时一行日志**(测试语义不进报告);若实施须同步 `docs/design.md` 观测面登记表 |
70
+ | T1 | 中 | `meeting_loop.py:313-314,323`;`start_discussion.py:558-559`;`docs/design.md:453` | 默认档翻转后的过时文本:"none(默认)…为什么默认它"、"代价:本档要求本机装有 MC"、help"none=零扩展(默认)"、"mc-tools…(需要本机装有 MC)"、决策 20 标题"agent 进程默认零扩展" | 常量已是 `mc-tools`(`meeting_fs.py:696`);代码实为"允许而非要求 + 可见降级" | 删除/同步为一句现规则(默认是谁 + 缺 MC 怎么办),规则本体指向 `DEFAULT_EXTENSION_POLICY` / 决策 20 |
71
+ | T2 | 中 | `AGENTS.md:75`、`docs/design.md:486-487`;`meeting_fs.py:94-95`;`tests/test_meeting_loop.py:783` | "缺 MC 时**响亮失败**、不静默退回 none"残留句(与已改的"允许降级"矛盾);`resolve_mc_tools_entry` 契约句"调用方必须报错"与调用方实际可见降级矛盾;测试注释旧契约残留 | 读文件行 | **删残留行为句**(依赖边界句已写正确行为);契约句改为"返回故障原因,由调用方按策略决定报错/可见降级" |
72
+ | T3 | 中 | `docs/design.md:480` | "背景蒸馏机制移除后,agents **没有任何主项目背景**通道"——**与 fork 模型矛盾**:fork 自身就是主背景通道(本场实例:agent fork 到的开发上下文远比检索有用);`AGENTS.md:62` 的"补充通道"措辞才准确 | 读码 + 本场三视角一致同意 | 改为"fork 是主通道;覆盖面受 ① fork 源内容 ② `budget` 裁剪限制;`ctx_search` 为兜底";**result 不得复制绝对句**(本场 question.md 已扩散过一次) |
73
+ | E1(证据) | 中 | `AGENTS.md:73`、`docs/design.md:484`(及 question.md) | "成本与 none 无差(受控 6 次:中位 7.8s vs 9.2s,差在噪音内 ✓)"**超出精度**:可比样本仅 n=2 vs n=3(左组混入 mcprobe2 bootstrap 源 A 臂 3.9s),组内方差 > 组间差 | 探针原始记录(`/tmp/mcprobe2/run.py` 臂定义 + mcprobe3 结果) | 改口为"**未测得显著差异**(n 小、组内方差>组间差)",并补生产基线(见下);长期由「唤醒构成表」启动段序列承担 |
74
+ | F5 | 低 | `meeting_fs.py:110` | `MC_PACKAGE in name` 为**子串匹配**;模拟注册 `@cortexkit/pi-magic-context-legacy`(带 sibling 入口)会被命中 → 潜在**静默加载他包** | 临时目录模拟实测(铁律/0002) | 解析裸包名后 `==` 比较 |
75
+ | F6 | 低(待验) | `meeting_fs.py:109-112` | 首个匹配条目解析失败即 `break`;模拟 `npm:…@0.1.0`(目录缺)+ `npm:…`(有效)→ 报"没有可解析"并忽略有效次条(文案误导) | 临时目录模拟实测 | 遍历全部候选取首个可解析;错误文案列候选 |
76
+ | F7 | 低 | `meeting_fs.py:123` | `pi.extensions` 非列表(字符串)时 `[0]` 取首字符 → 解析错路径后报"版本可能改了布局"(**方向误导,但不静默**) | 模拟实测 | 显式类型校验/兼容字符串 |
77
+ | S2 | 低 | `meeting_fs.py:70-73` 与 `107-110` | packages 条目形态解析写两遍、宽严不一(空白串处理不同) | 读码 | 抽 `_entry_source()`(≤3 行)两处共用 |
78
+ | F9 | 低(预存在) | `meeting_fs.py:133-137` vs `spec_gen.py:20` | pi agent 目录解析**两处实现**(docstring 自认同规则) | 读码 | 收敛一处(spec_gen 引 `meeting_fs.pi_agent_dir`) |
79
+ | S3 | 低 | `start_discussion.py:714-715` | CLI `--extension-policy` 向 loop 的转发**冗余**(`gen_protocol` 恒写协议字段,loop 协议后读覆盖 CLI);例外:旧协议目录无字段 + `--skip-setup` 时转发是唯一通道 | 读码 + grep(tests 无引用) | 删 3 行 + 一行文档("旧目录按默认档")——**需用户点头**(Batch 2) |
80
+ | S5 | 低(决策) | `start_discussion.py:560-562`;`meeting_loop.py:610-611,623-624` | `--extensions` 别名 + `extensions: true` 历史字段兼容(3 处),为只存在约 1 天的字段而设、**无移除条件** | git:`98786d6` 引入 → `47fbcd6` 取代;先例:`--pure` 同日全删 | 现在删,或写明移除条件——**需用户点头**(Batch 2) |
81
+ | E4("不要做") | 低 | `meeting_loop.py:328` → `meeting_fs.resolve_mc_tools_entry`(:85) | 每唤醒 ms 级解析(settings+package.json+目录探测)——**不要为它加缓存** | 失效复杂度(多份 MC/升级/相对路径)> 收益(毫秒) | 以"零机制"字样记入决策,防后手 |
82
+
83
+ **正面实测(职责边界合规)**:entry 的硬排除在生产成立——`ctx_expand` 调不到(`Tool ctx_expand not found`,效率实测);"工具面收窄"不是纸面声明。
84
+
85
+ ## 二、风险与可检测性
86
+
87
+ | 风险 | 触发条件 | 能否被检测 | 检测点 |
88
+ |---|---|---|---|
89
+ | **S1 降级路径缺 prompt** | **默认档 + 无 MC**(或 F6 使装着 MC 的机器走进来) | 修复前:仅 loop 日志的"无产出重试"间接暴露;修复后:命令形状与 none 同形 | P0 修复 + 验收四条 |
90
+ | MC 升级改布局 | `pi install` 升级/换机 | 能(**fail-safe**:解析失败→零扩展,不会加载错版本) | 目前 loop log 一行;E2 落地后报告可见 |
91
+ | F5 子串匹配加载他包 | 存在同前缀包且带 sibling 入口 | **否(静默)** | 无(需 F5 修复) |
92
+ | 行为漂移(工具面/prompt surface) | 后续改动 | 能(事后) | session transcript 按工具名计数 + 唤醒构成表;本场 9 次全在首唤、无异常(n=19),探针 90s 级异常**未复现**(支持"探针装置产物"判断,但单场 n=19,不作定论) |
93
+ | **陈旧知识注入**(ctx_search) | 记忆滞后于代码 | 仅能事后读 session(无自动检测) | 已观测 1 例:简单检索到 `#765`(作用域配置目录)——该机制前一天已删;"计数≠utility"的实例 |
94
+ | MC DB 争用(3 agents + 主 pi 并发写) | 并发 | 未测 | 无 |
95
+ | strict 假阳性(测试/探针忘设严格) | 无 MC 机器 + 忘设 `MV_MC_TOOLS_STRICT` | 修复前:否;修复后:loop 启动一行 `strict=1/0` + 报告降级行 | P1 落地 |
96
+
97
+ ## 三、ctx_search 使用情况与价值评估(附加题 1–4,三视角合并)
98
+
99
+ 1. **用过吗**:用过——本 agent 侧共 **9 次**(效率 2 / 简单 3 / 铁律 4),**全部在首唤窗口**;另 fork 源含 2 次主会话继承调用(不计入)。三家查询词均围绕"本场决策/近期改动"。
100
+ 2. **帮到了吗:0 次决定性帮助**。
101
+ - 代表性结果:效率①问 mc-tools 实测记录 → 返回 6 条"相邻记忆"(score 0.64–0.66)**不含所问事实**;简单三次共 15 条**无一回答查询**,并命中 **1 条过期记忆**(`#765` 指向已删的作用域配置机制——若信任即拿到错误背景);铁律 4 次中 2 次 message 源 **0 结果**,1 次命中相关规则(探针纪律 #752)但原文在仓库文档里更权威。
102
+ - 结构性解释(效率):**ctx_search 的边际价值与 fork 新鲜度成反比**——本类 agents 总是 fork 自刚工作完的主会话,背景已在 fork 窗口内。
103
+ 3. **工具面**:内置 read/bash/edit/write + `ctx_search`(+ `todowrite` 等按配置);`ctx_note`/`ctx_expand` 实测不可调(entry 的硬排除,符合设计);**无工具打扰**——三家均自选动作,未被迫管理上下文;检索是**一次性定向**(全部首唤),不是每唤醒重复成本。
104
+ 4. **诚实评估**:对"审阅本项目代码"这类任务,**ctx_search 可有可无、当前证据偏"非必要"**。依据:① 事实源是文件+git,仓库规模下 read/grep 直接命中;② 它最该发挥的"跨会话背景"场景本场未出现正面样本(且 message 源今日数据未索引到);③ 它有真实的反向风险(陈旧知识注入,已观测实例);④ 能力上界:**它是指针不是阅读替代**(search-only、无下钻,snippet 即全部)。
105
+ - **处置共识**:保持默认 mc-tools(成本已实测有界:每唤醒启动中位 **0.68s**(max 0.75)/ 收尾中位 **0.04s**(max 0.10),n=19,无异常);**回退评估规则 pending**——只在"**自然使用**"(排除问卷/指示诱导)登记,连续 ≥2 场 utility≈0 → 提议回退默认 `none`(mc-tools 留 opt-in);**回退本身属产品决策,需用户点头**。
106
+ - ⚠️ 本场 9 次调用**全部由附加题诱导**(为回答问卷而做),**不构成需求证据**;本场数据同样不能校准该规则。
107
+
108
+ ## 四、只改一处 → **S1**(三方一致;第二处 = E2)
109
+
110
+ **理由**:S1 是本次审阅唯一"**默认档生产可达的功能破损**"——用户显式要求的"没装 MC 自动切换回 none"走的正是这条路径;它同时是**复杂度问题**(四个 `--no-*` 抄三遍 + 短路)与**设计符合度问题**(`docs/design.md:488-492` 承诺"降级为零扩展并**按 none 运行**",实际是残缺命令)。修复**净减代码**(前缀提为单一构造、删提前 return),修改约 15 行 + 验收四条。
111
+ 第二处 = **E2 一行**(报告"声明 vs 生效 + 真实降级原因"):S1 修好后,降级至少是"可用的 none",但"本场带没带 ctx_search"仍需产品面可见。
112
+
113
+ **S1 验收四条(定稿,全部零 LLM)**:
114
+ 1. `_build_wake_cmd` 降级返回与 none 返回**逐字同形**(除日志行)+ cwd=项目;
115
+ 2. 装置配置带**非空** model/thinking/prompt_file(空值会削弱这两项的判别力);
116
+ 3. 在**既有 Popen-mock harness** 上断言 argv/cwd(`tests/test_meeting_loop.py:108-109/137/348`)——**不新增假 pi 装置**(仓库无 stub-pi;新装置判别力≈0、只加失败面);若两层被认为重复,保底保留第 1 条;
117
+ 4. 未知档**直调** `_build_wake_cmd` → raise;同批删 `meeting_loop.py:345` 的 `# pragma: no cover`。
118
+
119
+ ## 五、数据缺口(要测什么、怎么测)
120
+
121
+ | 缺口 | 现状 | 补法 |
122
+ |---|---|---|
123
+ | 降级路径端到端 | 缺(S1 漏网与"允许降级"承诺的共同盲区) | 验收四条(零 LLM、既有装置);**构造层断言必须保留** |
124
+ | `none` 档启动段基线 | 缺(e2e23 早于构成表功能) | 下次任一 none 场自动获得(唤醒构成表启动段);与 0.68s 对照即得 MC 边际 |
125
+ | 自然场次 usage/utility | 本场 9 次被问卷污染,不可校准 | **零机制 join**:fork 裁剪比例(loop log)× 检索计数(transcript)按场登记;**前提**:`--cleanup` 会 `rmtree(base)` 连数据源一起删(`start_discussion.py:458`)→ 须**清理前**把两个数抽进 result 固定小节;join 只检验 usage 侧预测,**utility 仍人工判读** |
126
+ | 跨场漂移(DB 增长/并发) | 无序列 | 连续 ≥3 场记录启动段中位数(报告已含);MC DB 争用未测(单列) |
127
+
128
+ ## 实施批次(三方共识)
129
+
130
+ - **Batch 1(无需用户决策)**:**S1**(守卫先行 + 单一零扩展前缀 + 删提前 return)+ 验收四条 + **文本同步**(T1/T2 删残留句、T3 `design.md:480` 改"主通道+条件限制+兜底"、E1 成本改口)+ **解析链一次重构**(S2/F5/F6/F7/F9;约束:只服务 MC 一个具名包、总长 ~60 行内、不引入推测性抽象)+ F9。
131
+ - **Batch 2(需用户点头)**:S3 转发删除(含"旧目录按默认档"文档)+ S5 兼容别名/历史字段删除(或写明移除条件)。
132
+ - **Batch 3(可选增强)**:E2 报告一行(三字段;strict 走启动日志;同步观测面登记表)。
133
+
134
+ ## 证据分级(防混用)
135
+
136
+ - **机制事实(源码/读码)**:entry 只注册工具不装 hook;S1 截断位置;F5/F6/F7 行为(模拟复现);E2 报告缺字段。
137
+ - **生产实测(本场,strict=1)**:MC historian **0/3**(账本);ctx_search **9 次全首唤**(按边界核对);成本基线 n=19(启动中位 0.68s / 收尾中位 0.04s / 无异常)——**单场样本**,跨场由构成表序列承担。
138
+ - **受控探针**:historian 0/11(两批 11 个探针 session);C 臂 `ctx_search` 真实返回结果;成本探针对照"**未测得显著差异**"(n=2 vs n=3)。
139
+ - **估算(不得当实测用)**:S1 残命令若触发,"每次唤醒最多 600s / 整场报废"——S1 立论不依赖它("缺 prompt 的每次唤醒"已足够)。
140
+ - **推测**:探针 D 臂 90s 异常"因提示词非生产形态"——合理未证;生产 n=19 未复现。
141
+
142
+ ## 过程记录(收敛路径)
143
+
144
+ 铁律/0001 首轮(F1–F9 + 证据分级)→ 简单/0001 独立发现 **S1**(高)→ 效率/0001(E1–E5)→ 铁律/0002 独立复核 S1 并**改选优先序**(撤回 F8 第一)→ 简单/0002、铁律/0003 定 S1 修法(守卫先行/单一前缀)→ 效率/0002、/0003 生产实测(启动/收尾成本)与撤回审计建议 → 铁律/0004 裁定 E2 范围(不并审计计数)+ 指出 usage 度量被问卷污染 → 简单/0005 修法定稿、反对计数进报告、修正验收③(弃假 pi 用 Popen-mock)→ 效率/0005、/0006 全部接受并补零机制 join → 铁律/0005(strict 折中三条件 + `design.md:480` 修正)、/0006(验收③定稿 + n=16 口径)、/0007(零机制 join 的清理前前提 + result 口径承诺)→ 三视角 freezing → RR 全员 pass(效率/0009、简单/0012、铁律/0010)。
145
+
146
+ **遗留(需用户)**:S5 兼容去留;usage 回退规则(pending,待自然场次);E4"零机制"记档。