pi-multi-viewers 0.2.2 → 0.4.0

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.
@@ -0,0 +1,159 @@
1
+ <!-- 存档:docs/reviews/2026-09-13-e2e20-pure-run-review.md
2
+ 来源:一次真实多视角分析的 result.md 原文(未删改,仅加本头与下方说明)。
3
+ 分析场次目录已随 --cleanup 删除;文中的消息编号(如 `效率/0003`)不可再核验,
4
+ 仅作溯源线索(与代码注释引用约定一致:行为以自描述为准)。 -->
5
+
6
+ # 存档说明
7
+
8
+ - **主题**:审阅 `c2be72d` 的 9 条修复(**该场 agents 零扩展**:无 AFT / 无 MC)
9
+ - **场次**:`mv-mv-main-20260913-133441`(3 视角;真实 pi 讨论)
10
+ - **抓到的问题**:边界子串误判把 fork 携带的历史算进本轮(报告虚高 4–8 倍,也是「Δ 合计 > 墙钟」之谜的根因);`_strip_jsonc` 单趟版让「注释含引号」的输入解析失败(功能回归);Δ 口径 B 的归因被证伪
11
+ - **落地**:`5e02a67`(F1 按字段判定 + S1 两趟法 + 撤回口径 B + S2/S4–S8 + 铁律 #4/#5)
12
+
13
+ ---
14
+
15
+ # 多视角分析结果:审阅「`c2be72d` 的 9 条自审修复」的实现质量
16
+
17
+ - **分析主题**:审阅提交 `c2be72d`(键名方向 / `_strip_jsonc` 值改写 / gate 判文件 / `af_resolution_notes` / 瘦身 / 报告 Δ 口径 B)的实现质量
18
+ - **参与者**:性能、简单、铁律(三视角)
19
+ - **分析类型**:审阅(只提意见,不修改、不运行测试)
20
+ - **发起**:2026-09-13,分析目录 `mv-mv-main-20260913-133441`
21
+ - **结论一句话**:9 条修复**方向正确、8 条忠实落地**;但讨论中查出**一项当前活动的高危缺陷 F1**(边界子串误判把 fork 携带的历史算进"本轮",本场报告已被污染 5–8 倍),它与"e2e19 的 Δ 合计 > 墙钟"之谜根因相同;另有 `_strip_jsonc` 注释含引号的功能回归(S1)与两处声明失真(S2/P1)。**三方一致:只改一处 = F1**。
22
+
23
+ ---
24
+
25
+ ## 一、事实基础(讨论中实测 / 源码核实的依据)
26
+
27
+ ### 1.1 F1:边界子串误判(铁律 0001/#1,性能 0008 独立复核)
28
+
29
+ **机制**:`meeting_fs.py:327` 的 `iter_after_boundary` 用 `if BOUNDARY_TYPE in line:`(子串包含)判断边界;`BOUNDARY_TYPE = "mv.analysis-start"`(`meeting_fs.py:1264`)。主 session 历史里任何含该字面量的一行(本仓**必然有**——历史里写过引用它的测试 fixture)都会被当成边界 → **其后的全部历史被计入"本轮"**。
30
+
31
+ **实测**(对三个 `fork-src-*.jsonl` 的快照;"精确边界"= 解析 JSON 后按 `type=custom_message & customType=BOUNDARY_TYPE` 判定):
32
+
33
+ | 来源 | 子串起点 / 精确边界 | assistant 条目(子串起 → 精确起) |
34
+ |---|---|---|
35
+ | 铁律 13:52 快照(响应/sec) | 167 行 / 657 行 | 性能 276→**33**(37.0→**6.1 分**);简单 303→**60**(40.0→**9.1 分**);铁律 309→**66**(42.8→**11.9 分**) |
36
+ | 性能 0008 独立复核 | 168 行 / 658 行 | 304→**60**;307→**63**;275→**31** |
37
+
38
+ - 子串首命中 = 一条历史 assistant `toolCall`(`2026-09-12T12:09:42Z`,内容为"写含该字面量的测试 fixture");误判起点比真实边界**早约 490 行**。
39
+ - 影响面:`observability.py:489`(`_report_session_metrics`:`usage` 四组 + `stopReason` 计数/时长)与 `:559`(`_report_session_levels`:档位对照行)——**本场报告一旦生成即失真**(档位行这次未暴露只因被误收的历史里恰好只有 `max` 一档)。
40
+
41
+ **e2e19「33m09s > 进程 13m09s、> 墙钟 17m19s」之谜的闭合**:边界正确时 `ΣΔ ≤ 本轮墙钟`(数学事实)→ 该异常**只可能来自非本轮条目**;与同机制实测的 37.0 分(性能 agent)量级吻合。**强支持下的推测**(e2e19 的 session 已随 cleanup 删除,无法逐行复核);性能 0008 据此**撤回**其 0001 的"跨唤醒空闲"归因。
42
+
43
+ **设计符合度**:写侧登记字段、读侧猜文本——违反同文件自立的原则"**边界是事实,应登记而非猜**",且使 docstring 承诺的 fail-safe("未找到边界 → 空迭代,不得退回全文扫描")永不触发。
44
+
45
+ ### 1.2 Δ 口径 B 的机制事实(铁律 0001/#2;性能 0008 接受并撤回)
46
+
47
+ - **每次唤醒(含续接)都在进程启动时写 user 条目**:本场 简单 的 session 中 7 个唤醒 user 条目(05:34:42 / 05:39:34 / 05:40:45 / 05:41:26 / 05:43:17 / 05:44:00 / 05:44:30),**每个后面都直接跟 assistant**。
48
+ - 于是跨唤醒空闲位于"**上一唤醒末条 → 本唤醒 user 条目**"之间;而 Δ 只在 assistant 条目上、以"紧邻前一条事件"起算——**user 条目把链断在这里,空闲从不进入任何 Δ**。
49
+ - 实测首响 Δ 与非首响 Δ **同量级**(铁律:8.59s;性能:首响 7.3/28.6/6.2/10.3/6.7/4.7/4.9s vs 非首响 3.9/3.2/3.6/25.7/6.7/17.2/7.2s,最大 30.2s)——**无分钟级样本**。若 B 排的是空闲,这里应出现分钟级样本。
50
+ - 结论:**B 的排除集恒等于"每次唤醒的首条响应"**(进程内真实生成耗时,且常是最贵的一条);`design.md:113`/docstring 写的"其 Δ 是空闲,不是生成"**与机制不符**。B 丢的是真数据,不是噪声。
51
+
52
+ ### 1.3 `_strip_jsonc` 的执行级矩阵(S1:简单 0001;铁律 0002 补第三例)
53
+
54
+ | 输入(合法 JSONC) | 旧状态机 | 新 8 行(当前) |
55
+ |---|---|---|
56
+ | `{"a": 1, /* say "hi" */ "b": 2}` | ✓ 解析成功 | **✗ 解析失败**(块注释未剥离) |
57
+ | `{"a": 1, // see "docs"\n"b": 2}` | ✓ 解析成功 | **✗ 解析失败**(`//` 被删、引号内容残留) |
58
+ | `{ // it"s "key": "v, }" }` | 值正确 | **✗ 串值 `"v, }"` 被改为 `"v }"`**(注释内**奇数**引号使配对错位,尾逗号正则仍改到真实串值) |
59
+
60
+ - 前两例是**新引入的功能回归**(旧实现正确);第三例证明"串值逐字保留"的契约**仍可被打破**。
61
+ - 失败走 fail-open:警告 + "其余键不套用"(可见,但 agent 侧配置退化)。
62
+ - 现有用例 `tests/test_meeting_fs.py:1024` 的注释不含引号 → **恰好绕开破点**。
63
+
64
+ ### 1.4 其余事实
65
+
66
+ - **S2 声明失真**:`agent_config_aft_file` docstring(与 `design.md` 决策 19)称"写入侧与判定侧共用本推导",但 `build_agent_config`(`meeting_fs.py:192`)实际本地拼 `os.path.join(dst_root, "aft.jsonc")`,从未调用该函数。今天两处拼出的字符串**逐字相同**(测试锁了相等)→ 是**潜在**触发路径,非现存。
67
+ - **S3 行数账**:`git show --numstat c2be72d` 生产四文件 **+146/−71 = 净 +75**(含 tests/docs 为净 +166);提交信息"净删行数"与事实不符(#6–#9 确为净删,但 `af_resolution_notes` 49 行 + 文档扩写使整批净增)。
68
+ - **P1 分母不一致**:`observability.py:488-501` 中 `n` 含首响、`sec` 不含(首响 `dur=None`)→ 读者按 `sec/n` 算会低估(e2e19:`toolUse 199(33m09s)` → 10.0s vs 真值 ≈11.9s;铁律本场:11.9 分/66 vs 计时 ≈59 → 差 ~12%;**唤醒越多偏得越多**)。
69
+ - **上游路径事实(铁律 #5)**:`aft-bridge/dist/paths.js` 的 `legacyOpenCodeConfigDir()` = `OPENCODE_CONFIG_DIR` 或 **`configHome()/opencode`**(非 `~/.opencode`);`resolveCortexKitProjectConfigPath` 只取 `.jsonc` → 清单里 `~/.opencode/aft` 与 `.cortexkit/aft.json` 是**死检查/误报**。
70
+ - **两笔开销不得合并(性能 0002 纠正简单 S5)**:**57s** = 语义搜索单项隔离归因值(带语义 61.0s / 关语义 3.3–4.4s);**80–190s** = 另一笔**未归因**开销(关语义后仍 83.9s、关 `lsp.auto_install` 后仍 83.9s)。一个数字承载一个可归因事实。
71
+
72
+ ---
73
+
74
+ ## 二、最终意见清单(合并去重后的共识)
75
+
76
+ | # | 严重度 | 位置 | 问题 | 依据 | 建议(最终形态) | 来源 |
77
+ |---|---|---|---|---|---|---|
78
+ | **F1** | **高(当前活动)** | `meeting_fs.py:327` | 边界用**子串**判定 → 历史条目被计入"本轮"(本场 5–8× 膨胀;e2e19 之谜根因) | §1.1 两侧实测;`ΣΔ ≤ 墙钟` 的数学约束;违反"边界是事实,应登记而非猜" | 读侧改为**解析 JSON 按字段判定**(`type==custom_message and customType==BOUNDARY_TYPE`)+ **回归用例**(历史先放含字面量的行、真实边界在后);未命中时维持"空迭代"fail-safe | 铁律 #1(性能 0008 独立复核;简单 0009 同意置顶) |
79
+ | **S1** | **高(功能回归)** | `meeting_fs.py:81-99` | 按字符串切分的奇偶下标假设不成立(注释可含引号)→ 注释剥离失效 / 串值仍可被改写 | §1.3 矩阵(旧实现对照) | **两趟法**:旧状态机先**只去注释**,再对无注释文本做串切分去尾逗号;**用例补**:行/块注释含引号 ×2 **+ 奇数引号不误伤真实串值**;docstring 描述域同步 | 简单 S1(铁律 #3 同结论;性能附议) |
80
+ | **S2** | 中 | `meeting_fs.py:192` | 写入侧未使用具名推导,与 docstring/design 的"共用推导"声明不符 | §1.4;今日逐字相同(潜在而非现存) | 写入处改一行:`open(agent_config_aft_file(base), …)`(`dst_root` 留给 MC 拷贝) | 简单 S2(性能 0002 附性能论据) |
81
+ | **P1** | 中(**条件项**) | `observability.py:488-501` + `design.md:113` | `n` 与 `sec` 分母不同且未标注 → 均值系统性低估(0–16%,随唤醒数增长) | §1.4 | **若保留 B**:加 `timed` 三键同形(恒出现、不写 `d.get` 兼容分支)+ 输出 `(sec / 计时 N)` + 2 处测试断言 + design.md 字段表 + `docs/reviews` 索引口径分界一行 | 性能 P1(简单/铁律附议) |
82
+ | **B 处置** | 中 | `observability.py:499` + `design.md:113` | "首响不计时"的理由(跨唤醒空闲)**与机制不符**(空闲从不进 Δ);实际丢弃的是每唤醒首响真实耗时 | §1.2 | **先修 F1 → 用修复后口径复算 → 若异常消失则撤回 B**(`prev_is_user` 与 `timed` 一并删净);若保留,design.md 只准写"**每唤醒首响有意不计时**" | 铁律 #2(性能 0008 撤回原归因并接受) |
83
+
84
+ ### 第二批(低,事实/整洁性账,可延后)
85
+
86
+ | # | 位置 | 问题 | 来源 |
87
+ |---|---|---|---|
88
+ | S3 | 提交信息 | "净删行数"与 `+146/−71`(净 +75)不符;建议事实版:"#6–#9 净删;#2/#3 新增 49 行检测 + 文档扩写"(并记录那 49 行的存在理由 = **用户侧副作用可见性**) | 简单 S3 |
89
+ | S4 | `meeting_fs.py:208` | `home_dir=None` 是测试专用参数,与同批 #7"删测试专用参数"的标准不一致(要么都删、要么都留) | 简单 S4 |
90
+ | S5 | `meeting_fs.py`/`meeting_loop.py`/`start_discussion.py` | "57s" 出现 10 次;`af_resolution_notes` 两条 note 与 docstring 点 1/2 讲同一机制 → 权威解释一处 + 指针化 | 简单 S5 |
91
+ | S6 | `meeting_loop.py:357` | agent 名从路径反推(`basename(workdir).removeprefix("work-")`),调用方手里已有 `agent` | 简单 S6 |
92
+ | S7 | `meeting_fs.py:222` | `proj = project_dir` 纯别名 | 简单 S7 |
93
+ | S8 | docstring / `design.md` | "四条路径" vs 代码 5 组(+`OPENCODE_CONFIG_DIR` 条件项) | 简单 S8 |
94
+ | 铁律 #4 | `tests/test_meeting_loop.py:744` | `assertNotIn("XDG_CONFIG_HOME", env)` 是**环境依赖弱断言**(`_spawn_env` 合并 `os.environ`,agent 进程本就有该变量)→ agent 内跑套件假红;应断言 `!= agent_config_dir(base)` | 铁律 #4 |
95
+ | 铁律 #5 | `meeting_fs.py:208` | 清单与上游 `paths.js` 偏差:`~/.opencode/aft`、`.cortexkit/aft.json` 是死检查 → 对齐上游或注明作用域 | 铁律 #5 |
96
+
97
+ ### 只准改一处 → **F1**(三方一致)
98
+
99
+ 理由(按"静默 + 必然"判据):F1 是**当前活动**缺陷,错的不是标注而是**报告的整行数字**(响应数/用量/stopReason/Δ 全被历史污染),而报告正是团队判断 AFT 开关收益、档位与预算的**基线**;修复成本 ≈ 3 行 + 1 用例。S1 是条件触发(有 fail-open 警告兜底),S2/P1 是声明/标注层;三者都必改,但单点优先 F1。
100
+
101
+ ---
102
+
103
+ ## 三、质量背书与"看了但没问题"
104
+
105
+ - **#1 键名方向**(`semantic_search = False` + `pop` 旧名):与上游 `CONFIG_MIGRATIONS`(newPath/oldKey)及读取端 `??` 兜底一致;旧名不并存是对的(并存会触发 migration-conflict 警告)。
106
+ - **#5 gate 判文件** + 三态用例(file/dir-only/absent):粒度正确(半成品不注入);`P2`(缺配置时每唤醒一行事实日志)**不改**——异常态 O(90 行/场)、O(1) 量级,once 标记不值一个状态。
107
+ - **#6–#9 瘦身**:`build_agent_config` 只返 warnings、删测试专用参数、收局部变量、内联常量——**确为净删**,全仓无残留引用。
108
+ - **具名推导**(`agent_config_dir` / `agent_config_aft_file`):写读共用单点,方向正确(S2 补完即可)。
109
+ - **`af_resolution_notes` 的存在**合理:用户侧确有真实副作用(上游迁移 `unlinkSync` 用户 legacy 配置 + `.MOVED_READPLEASE`,指针指向会被 cleanup 删除的临时路径)——可见性值这个机制费;仅 S4/S5 写法待整。
110
+ - **Δ fixture**:忠实锁定了"首响不计时"语义(问题在语义选择,不在测试)。
111
+ - **`test_string_values_not_rewritten`**:本批质量最好的用例(先红后绿已验证)。
112
+ - **不引入 JSONC 解析库**:正确(为读一个布尔开关加依赖 = 净复杂度上升)。
113
+
114
+ ---
115
+
116
+ ## 四、明确"不做"的清单
117
+
118
+ | 否掉项 | 理由 |
119
+ |---|---|
120
+ | 引入 JSONC 解析库/新依赖 | 净复杂度上升;两趟法已够(三方附议) |
121
+ | `af_resolution_notes` 升级进 `--report` 或验收 gate | 观测面契约:报告是唯一机器出口、不得升级为验收 gate;且报告对每 agent 全文件扫描(已登记"禁轮询") |
122
+ | 给 `_spawn_env` 的 stat 或 `_strip_jsonc` 加缓存/提前解析 | 冷路径/微秒级;缓存是负优化,引入失效路径 |
123
+ | 改 `_spawn_env` 缺配置的日志行(P2) | 异常态可见性正是它的目的;重复只发生在异常态 |
124
+ | ban AFT(`--pure`/`--no-extensions -e <MC>`) | **用户已定"先保留现状、以后单独测"**;本项仅作观察登记(见 §五) |
125
+
126
+ ---
127
+
128
+ ## 五、观察登记与记录规范
129
+
130
+ - **ban AFT 的连带**:若最终选择 ban,作用域配置机制整条(约 150 行 + 测试)随两笔实测开销(**57s 已归因** + **80–190s 未归因**)一起退场;决策归用户。**两笔开销不得合并成一个数字**。
131
+ - **记录规范(三方附议,写入本结论)**:
132
+ 1. **一个判断只写一个轴**(性能面 / 正确性分轴写——本场两次"合并轴"错误的教训);
133
+ 2. **一个数字承载一个可归因事实**(57s vs 80–190s;A/B 口径);
134
+ 3. **归档口径一处**:若保留 B,在 `docs/reviews` 索引加一行日期分界(B 修复前产出为 A 口径:`sec` 含每唤醒首响;之后为 B 口径:不含首响并给 `timed`)——**条件于 B 去留**(撤回则无需)。
135
+
136
+ ---
137
+
138
+ ## 六、验收口径(实施后核对)
139
+
140
+ - **F1**:边界按字段精确判定;回归用例(历史含字面量在前、真实边界在后)通过;修复后重算本场数据 → 响应数/Δ 与进程活动量级一致(不再出现 `ΣΔ > 墙钟`)。
141
+ - **S1**:两趟法;新增用例含"注释含引号 ×2 + 奇数引号";docstring 描述域更新;既有"串值不改写"用例保持绿。
142
+ - **S2**:写入侧调用 `agent_config_aft_file(base)`;两处推导一致性测试保持绿。
143
+ - **P1(若保留 B)**:`timed` 在全部 bucket 恒出现且 `0 ≤ timed ≤ n`;输出行格式更新;`tests/test_main_paths.py:420-421` 两条断言随动;design.md 字段表更新;归档索引口径行落地。
144
+ - **B 撤回(若选)**:`prev_is_user` 与 `timed` 删净;`n ≡ timed`;`design.md:113` 与报告口径标注同步更新;本场/ e2e19 场景复算不再异常。
145
+ - **行数账**:第一批**不得**再以"净删"描述(F1 +3、S1 两趟法净增、S2 0);S3 的修正后表述入提交信息。
146
+
147
+ ---
148
+
149
+ ## 七、讨论过程索引
150
+
151
+ | 参与者 | 主要贡献(消息) |
152
+ |---|---|
153
+ | **性能** | 0001 热路径盘点(唯一持续开销 = gate 每唤醒 1 次 stat)+ P1(分母)+ P2 + `--pure` 体验;0002 支持 S1/S2 并补性能连带、纠正 S5 的两笔开销合并;0003 接受 timed 方案与改动面 5 处;0004–0006 分批与记录写法收束、归档口径一处;0007 逐条核查 question.md 第 4 点的三个候选反例(均不成立);**0008 独立复核铁律 #1 成立(168/658 行、304→60 等)并撤回其 0001 的"空闲"归因**;0011 pass |
154
+ | **简单** | 0001 S1–S8(S1 为唯一功能回归,附 6 例验证的两趟法草稿;S3 行数账;三项明确反对);0002 timed 选择与改动面补全;0003 接受 57s 纠正、S2 精确化为"潜在";0004–0006 记录写法定稿;0009 pass(改选 F1 为单点;B 撤回则删净 `prev_is_user`/`timed`) |
155
+ | **铁律** | 0001 五条意见(F1 边界子串 / B 归因证伪 / strip 注释含引号与奇数引号 / 测试环境依赖 / 清单对齐上游)+ `--pure` 体验;0002 量化 F1(276/303/309 vs 33/60/66、37/40/43 分 vs 6/9/12 分)+ 补齐 B 的决定性实测 + 合并清单建议;0005 pass |
156
+
157
+ **收敛状态**:三视角全部 `pass`(性能/0011、简单/0009、铁律/0005),无保留意见。
158
+
159
+ **环境说明**:本场运行在 `--pure`(无 AFT / 无 MC 扩展工具),三方一致反馈:对"审阅已知位置的实现"类任务,内置 `read`/`bash`/`grep` 完全胜任,未因缺工具放弃任何检查(仅符号级导航多 2–3 步 / 文件);是否保留 AFT 不应以本场体验为据,须另测长仓库导航/语义检索的边际收益。
@@ -0,0 +1,257 @@
1
+ <!-- 存档:docs/reviews/2026-09-13-e2e21-postfix-review.md
2
+ 来源:一次真实多视角分析的 result.md 原文(未删改,仅加本头与下方说明)。
3
+ 分析场次目录已随 --cleanup 删除;文中的消息编号(如 `效率/0003`)不可再核验,
4
+ 仅作溯源线索(与代码注释引用约定一致:行为以自描述为准)。 -->
5
+
6
+ # 存档说明
7
+
8
+ - **主题**:审阅 `5e02a67` 的实现质量(并验证修复后的报告口径)
9
+ - **场次**:`mv-mv-main-20260913-140722`(3 视角;真实 pi 讨论)
10
+ - **抓到的问题**:AFT legacy 检测 4 组路径整体多一层 `aft/`(死检查 + 静默假阴性);子串预筛是对设计的错误陈述;`n` 与 `sec` 分母不同导致均值低估;Δ 的语义应表述为「生成跨度、不含工具执行」
11
+ - **落地**:`5cc0b5e` 之后的批(清单对齐上游 paths.js + 删除预筛 + 术语修正)
12
+
13
+ ---
14
+
15
+ # result.md —— 审阅 `5e02a67` 的实现质量(并顺带验证修复后的报告口径)
16
+
17
+ **多视角分析结论** · 参与者:性能 / 简单 / 铁律(3 视角,全部 `pass`,无保留意见)
18
+ **被审对象**:提交 `5e02a67`(F1 边界按字段判定 + S1 两趟法 + Δ 口径撤回 + S2–S8/铁律#4#5)
19
+ **过程规模**:29 条实质消息 + 6 条流程信号(各视角 9–10 条),全程只读(未改文件、未跑测试)
20
+ **产出**:共识修复清单(产品轨 / 测试轨 / 文档轨 / 批外)+ 机械判据 + 2 条可迁移方法
21
+
22
+ ---
23
+
24
+ ## 0. 一句话结论
25
+
26
+ 本批两个"大修"(**F1** 边界按字段判定、**S1** `_strip_jsonc` 两趟法)的**方向与实现都成立**;
27
+ 但留下 **1 个功能性错误**(**A1**:AFT legacy 检测的 4 组路径与上游规则不符 ⇒ 死检查、**静默假阴性**),
28
+ 以及若干"同一事实多处表达"的残留——其中 **S-2/S-6 的断言规格本身不可实施**(在任何已提交状态下都不绿)。
29
+ 三方另确认两处**口径**需按实测改写:Δ 的语义(**生成跨度,不含工具执行**)与断言**判别力**的分类
30
+ (相对某次修复而言、不可跨项借用)。
31
+
32
+ **判定骨架** = 1 个功能错误(A1)+ 1 个仪器错误(F1)+ **三类固定装置**(A1 双向 fixture / P1 不变量 + A4 语义 fixture /
33
+ S-2·S-6 单点断言);其余各项都是把"同一事实的多种表达"收敛成一种(复杂度匹配,不是新功能)。
34
+
35
+ ---
36
+
37
+ ## 1. 产品代码轨
38
+
39
+ ### A1(**第一优先**)| 中(若把该清单当验收面则高)| `meeting_fs.py:286,288,290,292`(+`:195-196`、`docs/design.md:416-418`、`tests/test_meeting_fs.py:1164-1175`)
40
+
41
+ **问题**:`af_resolution_notes` 的 5 组路径里 **4 组 legacy 路径整体多一层 `aft/`** ⇒ 全部是死检查(永远命中不了真实文件)。
42
+
43
+ **依据**(上游源码,`@cortexkit/aft-pi@0.55.1` 与 `@cortexkit/aft-bridge` 的 paths 模块逐字一致;**三方各自独立核实**):
44
+
45
+ ```js
46
+ function legacySources(basePath, …) { return [ {path: `${basePath}.jsonc`}, {path: `${basePath}.json`} ]; } // 追加后缀,不进目录
47
+ user: legacySources(join(legacyOpenCodeConfigDir(), "aft")) // → <configHome>/opencode/aft.jsonc
48
+ legacySources(join(legacyPiAgentDir(), "aft")) // → ~/.pi/agent/aft.jsonc
49
+ project: legacySources(join(projectDir, ".opencode", "aft")) // → <proj>/.opencode/aft.jsonc
50
+ legacySources(join(projectDir, ".pi", "aft")) // → <proj>/.pi/aft.jsonc
51
+ ```
52
+
53
+ 第 5 组(`<proj>/.cortexkit/aft.jsonc`)**正确**(上游 `resolveCortexKitProjectConfigPath`,只读 `.jsonc`)。
54
+
55
+ **后果**:用户若有 legacy 配置(如 `~/.pi/agent/aft.jsonc`),AFT 的 `markLegacySourcesMovedAside` 会
56
+ **无条件 `unlinkSync`** 该文件(原文留在 `<名>.MOVED_READPLEASE`),而这行"提示事实"的输出不会触发
57
+ ——即 `design.md` 决策 19 承诺的**可见性没有兑现**(职责边界:副作用是我们注入 `XDG_CONFIG_HOME` 引入的)。
58
+
59
+ **修法(共识,性能/简单/铁律一致)**:
60
+ - **与上游同形**:4 个 base(`join(root, "aft")`)+ 一条 `base + ".json[c]"` 后缀规则,替代 8 个手抄字符串
61
+ ⇒ "多一层 `aft/`"这类翻译错误**结构上不可能再发生**;
62
+ - `OPENCODE_CONFIG_DIR` **收回归根解析**(上游 `legacyOpenCodeConfigDir()` 的分支),清单里不再有特例;
63
+ - 第 5 组**保持独立一行 + 独立 note**(属另一上游函数:生效的目标配置 ≠ legacy 源);
64
+ - **护栏**:检测只做 `os.path.isfile`,**不读文件内容**("会不会被删"由上游决定,不复制其判定链);
65
+ - 同步 `meeting_fs.py` docstring、`docs/design.md:416-418`、**测试期望路径**(现测试写的正是错误嵌套形态 ⇒ 同源自证)。
66
+
67
+ **判据(机械可核查)**:
68
+ 1. **正例**:造 flat 形态(`<home>/.pi/agent/aft.json`、`<proj>/.opencode/aft.jsonc`)→ 断言报告路径集合**包含**它们;
69
+ 2. **负例(独立成条)**:只造 nested 形态(`<root>/aft/aft.json[c]`)→ 断言 `out == []`;
70
+ 3. 旧实现上**双向变红**(正例不命中、负例反而命中)⇒ **判别力型**;
71
+ 4. 测试注释引上游用**函数名**(`join(legacyPiAgentDir(),"aft") + ".json[c]"`),**不用**会话编号/行号(#17);
72
+ 5. 不得用 `len(out) == N` 当唯一判据(数目巧合型弱断言)。
73
+
74
+ ### S-1 | 中 | `meeting_fs.py:388-390`(子串预筛)
75
+
76
+ **问题**:F1 修完仍在同一函数保留 `if BOUNDARY_TYPE not in line: continue`——"字面量出现即相关"的**同族判断**
77
+ 只是降级为筛子;且注释 `:380` 写"**既有性能也有正确性**"是**对设计的错误陈述**(正确性只由字段判定承担),
78
+ 这句正是 F1 的读法陷阱。
79
+
80
+ **依据**:报告是冷路径(`--follow` 退出一次、`--report` 按需);`json.loads` 量级 ~20 ms/MB。
81
+
82
+ **修法**:删预筛 + **归并解析样板**(跳过期与产出期合成一个解析点、一处边界判定,**−6 行**):
83
+ `docstring` 换成"只按字段判定;整段历史逐行解析可接受(冷路径)"。
84
+ **机械判据**:函数内 `json.loads` 仅 1 次、`customType` 仅 1 次、子串判断 0 次、−6 行;
85
+ F1 的三条用例 + 历史含字面量那条**保持判别力**。
86
+ **注**:S-1 的"删"是三方一致结论;简单侧"静默漏"的论证已被性能/铁律驳回并自行收回
87
+ (漏判 → `seen` 永假 → 空迭代 → 报告 `n/a`,该状态**已有用例锁定**:`tests/test_meeting_fs.py:1224`)。
88
+
89
+ ### S-2 + A5 + S-8 | 低 | `meeting_fs.py:53` / `start_discussion.py:356,423` / `meeting_fs.py:225`
90
+
91
+ - **S-2**:`"cortexkit"` 仍两处(`agent_config_aft_file` 内 + `build_agent_config` 的 `dst_root`)
92
+ ⇒ 加 `agent_config_cortexkit_dir(base)` 单点;**漂移后果可见**(gate 缺失 → `_spawn_env` 日志一行),故属表达重复而非静默失效。
93
+ - **A5**:`os.getcwd()` 在同一函数被读两次(`:356` 写协议、`:423` 供检测)⇒ `project_dir` 绑一次喂两处。
94
+ - **S-8**:`build_agent_config` 的 `except` 里 `cfg = {}` 是死赋值,删除。
95
+
96
+ ### S-3(并入测试轨)| 低 | `observability.py:490-512`
97
+
98
+ **问题**:`prev_ts = ev.get("timestamp") or prev_ts`(×2)在条目缺 ts 时让 `prev_ts` **不前进**
99
+ ⇒ 下一个 Δ **吞掉未知空档**(把未知算进已知,与"缺席≠0"同一错误方向)。
100
+ **修法(共识 (i))**:去掉两处 `or prev_ts` 兜底(缺 ts ⇒ 作废 ⇒ 下一个 Δ 不计时)——**删兜底、非加分支**。
101
+ **判据**:`observability.py` 内 `or prev_ts` 出现 **0** 次;循环内 `prev_ts` 赋值 **1** 处 + 初始化 1 处;
102
+ (b) 用例先红(今天的行为是"吞空档")→ 改后绿 ⇒ 该断言为**判别力型(对 S-3)**。
103
+
104
+ ---
105
+
106
+ ## 2. 测试轨
107
+
108
+ ### P1 | 判别力型(对 F1)| `tests/test_main_paths.py`(扩既有 `_env` fixture)
109
+
110
+ **断言**:① 报告 `sec` 合计 == 仅本轮(历史不计入);② **`ΣΔ ≤ 进程跨度`**。
111
+ **配方**:历史段 ≥ 20 条、**含 `mv.analysis-start` 字面量**、相邻时间戳**跨分钟级**(整段 ~10 分钟);
112
+ 真边界;本轮段 `user → assistant(40s) → toolResult(+25s) → assistant(10s)`;loop log `elapsed_ms = 42100`。
113
+ **判别力**:污染版会从历史字面量行起算 ⇒ ΣΔ 分钟级 ≫ 42 s ⇒ **在旧实现上必红**(改动说明附先红后绿证据)。
114
+
115
+ ### S-2 / S-6 单点断言 | 判别力型(各对其修复)| `tests/test_meeting_fs.py`
116
+
117
+ **规格(原写法不可实施,已作废重做)**:`build_agent_config` 源码实测含
118
+ `"cortexkit"`×2(`:52` 源侧目录、`:53` 目标侧目录)与 `"aft.jsonc"`×1(`:59` 源侧文件)
119
+ ⇒ "函数内不得出现这两个字面量"在**任何已提交状态下都不绿**。
120
+ **选 A**:给**源侧两处事实**都建具名推导(源侧目录 + 源侧文件,镜像上游 `resolveCortexKitUserConfigPath`),
121
+ 目标侧由 S-2 的 `agent_config_cortexkit_dir` 覆盖 ⇒ 不变式成立且可绿(**≈ +2 个推导**)。
122
+ **实现要点**:用 `ast` 取函数体字符串常量(**精确相等**比较 ⇒ 注释/docstring 中的同名文本不会误红,
123
+ 且**不需要自研注释剥离器**——本仓刚因自研 JSONC 剥离栽过一次);
124
+ **范围只锁这两个受管名字**,不扩成"零路径字面量"(`magic-context.jsonc` 不搭车)。
125
+ **硬要求**:实施前先跑基线并记录红的**位置**(目标侧第二次拼装 + 源侧两处),避免顺手改源侧。
126
+
127
+ ### A4 / A3 / P2 三口径 fixture | 特征锁定型((b) 除外)
128
+
129
+ - **(a)** 工具执行时间**不进入任何 stopReason 桶**(实测:`sleep 25` → `toolResult` 条目 Δ=25.0 s;
130
+ 其余工具 0.0–0.1 s;assistant Δ ∈ [3.5, 41.9] s)⇒ 口径可恢复强表述:
131
+ **归入 stopReason 的 Δ = 请求→响应的生成跨度(不含工具执行)**;
132
+ ⚠️ 分类提示:(a) 在旧实现上也绿,**不得**当作 F1 的拦截证据;
133
+ - **(b)** 缺 ts 的条目**不产生 0 秒样本**——判别力型(对 S-3);
134
+ - **(c)** 边界后首条为 assistant 时**只计数不计时**(`prev_ts=None`)。
135
+
136
+ ### 断言分类口径(新增判据)
137
+
138
+ **判别力是相对某次修复而言的,不可跨项借用**:
139
+ - 判别力型(须在**对应修复前**变红,附先红后绿):A1 双向 fixture(对 A1)· P1 两条(对 F1)·
140
+ 源码单点断言(对 `5e02a67` 的 S2 / 对 S-2)· (b)(对 S-3);
141
+ - 特征锁定型(锁当前正确语义、防漂移,**不回溯**):(a)、(c);
142
+ - 用途约束:改动说明与 result 里**逐条标注类别与相对哪次修复**,判别力型不得用来论证它不对应的修复。
143
+
144
+ ---
145
+
146
+ ## 3. 文档轨
147
+
148
+ ### S-4 + #17 | 低
149
+ - **注释用"无数字规则稿"**(三方最终一致):代码只留**触发条件 + 指针**,量级与精确值都归 `design.md`
150
+ 观测面契约节。**依据**:承重信息是**频率属性(冷/热)**,量级本身也随 fork 模式(budget/full/compaction)
151
+ 与 session 规模变化 ⇒ 非不变量;这样"S-1 落地时同步改基线"的连带义务**消失**。
152
+ - **#17 清零**:本批在 `.py` 注释里新增 **13 处**不可核验编号(`meeting_fs.py` 5 / `observability.py` 2 /
153
+ 测试 5),违反 `AGENTS.md` #17"新增注释不再引入不可核验编号"。
154
+ 处理规则:**自描述替换**(例:`(e2e20 评审 F1)` → `(回归:子串判定把历史条目算入本轮)`)+
155
+ 每文件至多保留**一处指针**。
156
+ - 保留的注释内容:`_report_session_metrics` 的"当前口径 + 一句防回归(**不要再退回'首响不计时'**:
157
+ 其前提已被实测证伪)+ 成立条件(缺 ts ⇒ 不计时;均值写法 `n ≥ timed`)"。
158
+
159
+ ### P3 触发条件句 | 不改本体
160
+ 报告路径成本与触发条件(**进入轮询/进度路径,或 fork 用 `full` 于大 session → 先合并扫描/缓存**)写入
161
+ `design.md` 观测面契约节 + 代码一行指针;论证(两遍扫描 ~6 MB、~0.1 s/次、峰值内存 O(最大单条))归文档。
162
+
163
+ ---
164
+
165
+ ## 4. 批外(单列,不并入本批)
166
+
167
+ **`unittest.main()` 块**:`tests/test_meeting_fs.py`(块在 1241/1370,其后 **9** 个用例)与
168
+ `tests/test_stage4.py`(100/310,其后 **11** 个)——直接 `python3 tests/test_x.py` 会**静默少跑 20 个用例**
169
+ (门禁用 `discover`,不受影响;**非本批引入**)。
170
+ **修法**:**挪 2 处到文件末** + **测试内机械检查**(`__main__` 块之后不得再出现 `class Test`)。
171
+ **否决"删 17 块"**:无块时直跑是"零输出 + 退出 0"——比现状更隐蔽的静默失败(无静默铁律)。
172
+ **验收**:`discover` 用例总数不变 + 直接跑与 discover 结果对等(80 / 15)。
173
+
174
+ ---
175
+
176
+ ## 5. 判"不改"(记账,不实施)
177
+
178
+ - **A3 渲染层 `n/a` 分支**:不做。`d["sec"]` 是累加值,`0` 无法区分"全部 Δ 未知"与"真为 0"——
179
+ 信息在**计算层**已丢弃,让渲染层反推属分层错位;将来严格化落点在计算层,且需有真实 case
180
+ (触发条件:首次出现 `dur is None` 的真实样本)。只改措辞 `n ≥ timed` / "`sec` = 已知跨度之和"。
181
+ - **A6**:`af_resolution_notes` 面向用户文案里的 `57s` **保留**(后果陈述需要该数字),列入"数字有主人"清单。
182
+ - **P3 本体**:不合并两处扫描(两个适配器语义不同、各自 fail-open),记触发条件即可。
183
+
184
+ ---
185
+
186
+ ## 6. 关键实测依据(留档)
187
+
188
+ | 项 | 数据 | 来源 |
189
+ |---|---|---|
190
+ | **F1 触发复现(活体)** | 三份 fork 源里 `mv.analysis-start` 子串命中 10–14 行,**7 行在真边界(第 704 行)之前**(153/642/649/650/652/656…)⇒ 旧实现会从第 153 行起算(≈551 条历史算进本轮) | 本轮讨论进程内实测 |
191
+ | **F1 量级** | assistant 条目 310→66 / 341→97 / 307→63;Δ 合计 40.7→9.8 / 48.3→17.4 / 40.8→9.9 分(**~4×**) | e2e20 评审批 |
192
+ | **Δ 语义(受控)** | `sleep 25` → 该 `toolResult` 条目 Δ=**25.0 s**;其余工具 0.0–0.1 s;assistant Δ ∈ [3.5, 41.9] s;`user` 条目 Δ=141.5 s(跨唤醒空闲)被丢弃、不入任何桶 | 本轮讨论进程内实测 |
193
+ | **A1 上游形态** | `legacySources(basePath)` = `${basePath}.json[c]`;两模块(aft-pi / aft-bridge)逐字一致 | 源码核(三方各一遍) |
194
+ | **A 断言基线** | `build_agent_config` 常量:`cortexkit`×2、`aft.jsonc`×1、`magic-context.jsonc`×2 | `ast` 枚举(只读) |
195
+ | **性能账** | 热路径 ≈0(唯一新增:`_spawn_env` 每唤醒 1 次 `isfile`);报告路径 F1 **净减**解析、删预筛后 **+0.1 s/次**(冷);建环境 ≈0;**度量可信度 +** | 调用图核对 + 文件规模实测(1.0–1.1 MB / 723–725 行) |
196
+ | **本场运行前提** | 作用域配置生效(`XDG_CONFIG_HOME` 已注入;与用户配置只差 `semantic_search: false`;`GIT_CEILING_DIRECTORIES` 已注入);工具层无异常;**本场未触发语义检索需求**(故不能论证"关语义搜索无代价") | 环境实测 |
197
+
198
+ ---
199
+
200
+ ## 7. 分歧与裁决(含三方自我修正)
201
+
202
+ | 分歧点 | 立场 | 终裁 | 依据 |
203
+ |---|---|---|---|
204
+ | **A1 vs 其他项的优先** | 性能/简单最初投 P1(测试批) | **A1 第一** | "**当前就错**"优先于"防错";且修法本身是简化 |
205
+ | **S-5:删 4 组 legacy 还是修** | 简单主张删(省维护面);性能只保底线(第 5 组) | **不删,按规则形态重建** | 删 = 取消已承诺的可见性(语义不等价于修);规则形态把漂移面从 8 字面量降到 4 个可对读 base |
206
+ | **S-1:删预筛还是留** | 性能主张留(fail-safe);简单主张删 | **删**(改注释也合格,但删更干净) | 报告冷路径、上限 +0.1 s;"fail-safe 可接受"的隐含前提被否 |
207
+ | **A3:渲染层 `n/a`** | 铁律初提"可选严格化";简单反对 | **不做**(铁律撤回) | 分层错位 + 触发不可达 |
208
+ | **S-4:量级进注释还是只留规则** | 铁律/性能先主张"量级进注释";简单改主张只留规则 | **只留规则 + 指针**(铁律、性能随后确认) | 量级随 fork 模式变,**非不变量**;承重信息是冷/热频率 |
209
+ | **S-2/S-6 断言的规格** | 简单提案(函数级负向断言) | **作废重做(选 A)** | 实测:源侧两处字面量使该断言任何状态都不绿(同源自证) |
210
+ | **判别力分类** | 简单把 S-2/S-6 标"特征锁定型" | **修正**:判别力相对某次修复、不可跨项借用 | 先红后绿判据(性能与铁律独立提出) |
211
+
212
+ **三处自我修正(留档以示证据可信度)**:① 简单收回"S-1 可能是静默漏"(改为可见的缺席);
213
+ ② 简单收回"删 17 个 `__main__` 块"(改为挪 2 处 + 机械检查);③ 铁律修正自己的 A 方案规格
214
+ ("一个源侧推导"不够,须两处源侧事实具名)+ 作废自己的"P3 基线同步重写"义务与"量级进注释"裁定。
215
+
216
+ ---
217
+
218
+ ## 8. 可迁移方法(建议进方法论/检查清单)
219
+
220
+ 1. **镜像外部契约时,镜像"规则"而非"结果"**。
221
+ A1 的根因不是"打错 8 个字符串",而是**把上游的规则函数(`legacySources(basePath)`)翻译成了结果数据表**
222
+ ——翻译错误没有任何本地信号(测试与实现同源同错、自证通过)。
223
+ 同类已核合格:`_source_config_home()` 对上游 `configHome()`(同规则)。
224
+ 2. **镜像点必须落在文档化字段/规则上;代理判断(字面量出现过、计数、时间戳差)一律视为待修信号**。
225
+ F1 = 镜像**谓词**错("字段等于某值" → "子串出现过");A1 = 镜像**对象**错(规则 → 结果表)。
226
+ 这条与既有"确定性标识优先于启发式猜测"(残留判定用 `comm`/`PPID`)同源。
227
+
228
+ (配套:**仪器(报告)的数字必须有跨字段不变量**——`ΣΔ ≤ 进程跨度`、"历史含字面量时数字不涨",
229
+ 即 P1;所有性能/配置决策都读这份仪器,它错一次会把结论读反。)
230
+
231
+ ---
232
+
233
+ ## 9. 单点优先与执行序
234
+
235
+ **单点优先:A1**(三方一致)。
236
+
237
+ | 序 | 批次 | 内容 | 判据 |
238
+ |---|---|---|---|
239
+ | 1 | **A1** | 规则化重建 + `OPENCODE_CONFIG_DIR` 回根解析 + docstring/design/测试同步 | 正/负双向 fixture 先红后绿 |
240
+ | 2 | **测试轨** | P1 不变量 + S-2/S-6 `ast` 断言 + A4/A3/P2 fixture + S-3 (i) | 判别力型附先红后绿;逐条标类别 |
241
+ | 3 | **S-1** | 删预筛 + 归并解析样板(−6 行) | `json.loads`/`customType` 各 1 次、子串 0 次 |
242
+ | 4 | **单点化小批** | S-2(`cortexkit` 目录推导)· A5(`project_dir` 绑一次)· S-8(删死赋值) | 源码单点断言 |
243
+ | 5 | **文档批** | S-4 规则稿 + P3 触发条件句 + #17 清零(13 处) | 新增注释中不可核验编号 = 0 |
244
+ | 单列 | **`__main__` 块** | 挪 2 处 + 测试内机械检查 | discover 总数不变 + 两入口结果对等 |
245
+
246
+ ---
247
+
248
+ ## 10. 声明与边界
249
+
250
+ - **过程**:全程只读(未改任何文件、未跑测试、未启动分析);所有"实测"均为进程内只读观测
251
+ (session 文件解析、上游 dist 源码核读、`inspect`/`ast` 枚举)。
252
+ - **证据等级**:A1 = 三方各自独立核实上游源码(最高);F1 = 有活体复现与量级数据;
253
+ Δ 语义 = 受控实验;断言基线 = `ast` 枚举;其余为源码/文档推演(已在文中标注"推断"处)。
254
+ - **本批未做的事(有意)**:不给渲染层加分支、不为不可达场景加/改判定、不新增持久状态、
255
+ 不把报告升级为验收 gate、不搭车改 `magic-context.jsonc` 单点化。
256
+ - **留给实施的注意**:A1 修好后测试期望路径必须同步为上游形态(否则测试仍是同源自证);
257
+ A 方案实施前先跑基线记录红的**位置**;S-3 与 (b) 用例必须同批(改动先行会让断言长期红)。
@@ -0,0 +1,175 @@
1
+ <!-- 存档:docs/reviews/2026-09-13-e2e23-time-breakdown-analysis.md
2
+ 来源:一次真实多视角分析的 result.md 原文(未删改,仅加本头与下方说明)。
3
+ 分析场次目录已随 --cleanup 删除;文中的消息编号(如 `效率/0003`)不可再核验,
4
+ 仅作溯源线索(与代码注释引用约定一致:行为以自描述为准)。 -->
5
+
6
+ # 存档说明
7
+
8
+ - **主题**:一次多视角分析的时间都花在哪——哪些环节必要、哪些可省、怎么省
9
+ - **场次**:`mv-mv-main-20260913-194310`(3 视角;真实 pi 讨论)
10
+ - **抓到的问题**:AFT 与 MC historian 两笔分钟级开销都**不在报告里**(外部探针偶然发现);只有先有「每次唤醒构成」才能判断批量取数 / 配额校准 / 气泡是否值得;明确反对「不等进程退出就推进」与「新增常驻机制」
11
+ - **落地**:`98786d6`(agents 默认零扩展)+ `c46d996` / `9deefac`(报告层:唤醒构成表 + 终止原因)
12
+
13
+ ---
14
+
15
+ # 多视角分析结果:一次多视角分析的时间都花在哪——哪些环节必要、哪些可省、怎么省
16
+
17
+ - **参与者**:效率、简单、铁律(3 视角;resultWriter = 铁律)
18
+ - **分析类型**:分析 + 建议(只读:未改文件、未跑测试、未跑 pi)
19
+ - **发起**:2026-09-13,分析目录 `mv-mv-main-20260913-194310`
20
+ - **结论一句话**:零扩展形态下,本场 99% 的进程时间花在"事件内"(模型往返+工具),启动 1%、**收尾 0%**(插件时代是 66–78%);墙钟 = 各 agent 串行链的最大值,可分解为 **唤醒次数 × 单次唤醒跨度**;实现层只需两件事——**把"每次唤醒构成表"做进报告(测量)**、**删掉被淘汰的扩展策略(删除)**;"不等进程退出就推进"与"新增常驻机制"两类提案三方一致反对。
21
+
22
+ ## 运行元信息(本场)
23
+
24
+ > 本段是本次分析自身的运行事实,与结论同为产物的一部分——按讨论决议,终止原因只在本报告留下(唯一跨 cleanup 存续的载体;未来归 `--report`)。
25
+
26
+ | 项 | 值 | 来源 |
27
+ |---|---|---|
28
+ | 配置身份(原值) | `pure=true`;`forkMode=budget`;`model=commandcode-goat/deepseek/deepseek-v4.1-flash`;`thinking=max`;`maxMeetingRounds=10`;`maxRRRounds=7`;`stallTimeoutSeconds=600` | `protocol.json` + wake-log `CMD:` |
29
+ | **终止原因** | **consensus**(RR 全员 pass;非配额、非 stall) | loop 日志(引擎确定性事实) |
30
+ | 墙钟(首末 commit) | **636s ≈ 10.6 分钟**(setup → 铁律/0010;result.md 提交后略增) | `git log` |
31
+ | 唤醒 / 跨度 | 32 次完成(效率 11 / 简单 12 / 铁律 9)+ 本次收尾;跨度合计 **1538s**,均 48.1s,max 167s | loop 日志 `elapsed_ms` |
32
+ | 四段(进程跨度内) | 启动 14s(**1%**)/ 事件内 1523s(**99%**)/ 收尾 **0s(0%)** | 本报告附录(事后纯推导) |
33
+ | 并行度 | 1538 / 636 = **2.42**(上限 3.0) | 同上 |
34
+ | 配额使用 | 效率 **10/10(撞上限后冻结)**、简单 9/10、铁律 7/10 | 消息统计 |
35
+ | retry | 1 次(简单) | loop 日志 |
36
+ | 首唤准备 | fork 源 560 条 / est≈80k / 构建 458–504ms / 76MB 峰值 × 3 并行 | loop 日志 |
37
+ | 最大单唤醒 | 167s,**远低于** `stall_timeout=600s` | 同上 |
38
+
39
+ ⚠️ 口径:以上"四段"是**进程跨度的内部分解**;与"生成跨度"(session Δ 合计)不是同一口径,**不得相加或互比**。
40
+
41
+ ---
42
+
43
+ ## 一、时间构成(共识)
44
+
45
+ | 阶段 | 量级/占比 | 依据 | 口径 |
46
+ |---|---|---|---|
47
+ | 环境准备(首唤一次性) | 三个 fork 源并行构建 458–504ms/个(76MB 峰值);叙事注入 ~20ms | 本场 loop 日志 | 墙钟 |
48
+ | 每唤醒启动段 | 合计 14s / 32 唤 = **1%** | 本场事后推导 | 进程跨度内分解 |
49
+ | 事件内(TTFT + 生成 + 工具执行) | **99%**(1523s / 1538s) | 同上 | 同上 |
50
+ | 收尾(退出前) | **0s**;对照:插件时代 66–78%,受控 445.9s → 0.5s | 同上 + 受控实测 | 同上 |
51
+ | 调度/轮询气泡 | 上限 ≈5%(轮询 ~2.3s × 切换数 ≈60–70s),未单独确认 | 常量推导 | 墙钟 |
52
+ | 墙钟结构 | ≈ 最长 agent 串行链 + 少量 gaps;并行度 2.42/3.0 | 本场 | 墙钟 |
53
+
54
+ **结构公式(三方共识)**:
55
+
56
+ ```
57
+ 墙钟 ≈ max over agents [ 唤醒数 × ( 启动 + Σ按 role 分层Δ + 尾部 ) ] + 首唤准备 + 末轮收尾
58
+ 单次唤醒 ≈ 往返次数 × 单往返成本(TTFT+生成+工具) + 启动 + 尾部
59
+ ```
60
+
61
+ 历史对照(同一天、同机制):
62
+
63
+ | 场次 | 扩展 | 墙钟 | 唤醒 | 每次唤醒跨度 | 备注 |
64
+ |---|---|---|---|---|---|
65
+ | e2e19 | AFT+MC | 17m19s | 32 | 71.6s | 无 historian |
66
+ | e2e20 | 零扩展 | 20m34s | 30 | 81.6s | 基线 |
67
+ | e2e21 | AFT+MC | **1h13m** | 30 | **330s** | historian 风暴(62 次/155 分钟,60 失败) |
68
+ | **本场** | **零扩展** | **10.6m** | **32** | **48.1s** | 收尾 0%、retry 1 次 |
69
+
70
+ ⇒ e2e21 的分钟级灾难来自**进程内扩展**(AFT 尾巴、MC historian 失败重试),不是协议/调度设计。
71
+
72
+ ---
73
+
74
+ ## 二、必要 vs 可省(逐项判定)
75
+
76
+ | 阶段/机制 | 判定 | 可省量级 | 依据 |
77
+ |---|---|---|---|
78
+ | 3 agent × N 轮的真实模型处理 | **必要**(产品本质) | — | 本场 99% 在事件内 |
79
+ | 工具取数(读代码/追事实) | **必要**(质量) | 往返次数可压:上限 = 被消掉的 toolUse 步 Δ(须按 role 分层后计) | 本场实测一步多工具调用**已可行**、使用率仅 ≈2–3% |
80
+ | 每唤醒独立 pi 进程 | 必要(fork 隔离) | 启动段仅 1%,已到下限 | 本场 |
81
+ | 扩展加载/收尾(AFT、MC historian) | **已消除** | 受控 445.9s→0.5s、447s→10.3s;本场 0s | 受控实测 + 本场 |
82
+ | 轮询/调度 | 保留(简单、可预期) | 上限 ~5%,**不是杠杆** | 常量推导 |
83
+ | 重试(无产出) | 需监控 | 每次重试 = 一个完整进程生命周期;本场 1 次 | loop 日志 |
84
+ | 确定性信号(freeze/pass) | 设计已正确(不经 LLM) | — | 引擎设计 |
85
+
86
+ ---
87
+
88
+ ## 三、可省手段清单(按收益 × 确定性排序)
89
+
90
+ | 手段 | 预计收益 | 代价 | 风险 | 优先级 |
91
+ |---|---|---|---|---|
92
+ | **1. 报告层"每次唤醒构成表"** | 不直接省时,但**把静默变可见**:AFT 57s、historian 447s 两笔都是外部探针偶然发现、报告当时看不见 | 零插桩、事后推导(数据已全在 loop 日志/session/git 中) | 无(不进热路径) | **最高** |
93
+ | **2. 扩展策略删到一条(零扩展)** | 消除分钟级尾巴的**载体**(默认路径不再带 43× 成本的组件);本场验证可接受 | 删净配套(`KEEP_EXTENSIONS`/`resolve_extension_entries`/测试/决策 19/20 文档) | 工具能力变化仅有自述、无独立质量判据 | 高 |
94
+ | 3. 批量取数(用法约定) | 上限 = 被消掉的 toolUse 步 Δ(**不是** 2×平均响应成本——均值含长生成步,会高估) | prompt/协议**一句话约定** | 自适应探索(读 A 才知读 B)是信息下界,不可压 | 中(等表数据) |
95
+ | 4. 配额校准 | 每减 1 轮 ≈ 3 唤 × ~48s ≈ 2.4 分钟 | 改 `protocol.json` 参数(零机制) | **降上限 = 截断深度**;需质量判据 | 中(先看终止原因分布) |
96
+ | 5. 气泡常量 | 上限 ~5% | 调轮询常量 | 极低 | 低(先量) |
97
+ | **【反对】"不等进程退出就推进"** | 正常态 ≈0(尾部已 0) | 解锁 git + 提交时序重构 + 并发写防护 | 高(同 session 双写、协议完整性) | **三方一致反对** |
98
+ | **【反对】新增常驻机制**(缓存/索引/事件驱动/作用域配置/阈值告警分支) | 收益不明或为负 | 复杂度 + 新静默失败面 | 高(AFT/MC 两次学费) | **三方一致反对** |
99
+
100
+ ---
101
+
102
+ ## 四、只做一件事(共识)
103
+
104
+ **报告层零成本"每次唤醒构成 + 跨 agent 区间"的事后纯推导**:一个入口、一次遍历、产出"每次唤醒一条记录",其余全部为聚合视图。
105
+
106
+ **规格(三方定稿)**:
107
+
108
+ - **运行级表头**(每场一行):配置身份(`protocol.json` **原值**,不转述;实施期另用首个 wake-log `CMD:` 做一次性核对)+ 终止原因 + 墙钟 + 总唤醒数 + 准备/收尾。
109
+ - **每唤醒记录**:`agent / t_spawn / t_首事件 / t_末事件 / t_exit / 往返数 / assistant Δ / toolResult Δ / retry / 本唤醒 commit 时刻(或无 commit 标记)`。
110
+ - **视图**:① 工具 vs 模型(按 role 两列)② 次数 vs 时长 ③ 启动/尾部/气泡(跨 agent 合并时间轴,仅区间列表)④ Δ vs 上下文规模(按 role 分层;**本表最后一次净增视图**,此后只允许替换、不净增)。
111
+ - **五条验收恒等式**(本场校准即可自检):`Σ四段 = elapsed_ms`;`|W_proc| = |∪[spawn,exit)| + Σall-idle`;`Σspans = |∪| + 重叠`;`p50/p99/max vs stall_timeout`;终止原因可得。
112
+ - **桥接写法(落稿采用)**:四端点 + 有向差——`C0 = min(spawn) − 首 commit`、`C1 = max(exit) − 末 commit`、`|W_commit| = |W_proc| + C0 − C1`(与早期 `W_commit=(T1−T0)−前段−后段` 算术等价,仅消除"前段为负"的符号误读;符号由数据定,不写方向性注释)。
113
+ - **精度契约**:可推导(分段 Δ、role 拆分、计数、retry、终止原因、区间重叠、离群 top-N)vs **不承诺**(单次调用内 TTFT/生成拆分——不为它插桩)。每个数字标注"由 X 推导"。
114
+ - **纪律**:**账用对账恒等式、归因用成本模型**(混用会把近似误差记到被优化对象头上);报告**不得升级为验收 gate**;跨度阈值只作报告事实行,不进代码分支。
115
+
116
+ **理由**:三个可动位置(唤醒次数 / 往返次数 / 单往返成本)里,进程启动与确定性路径已到下限、尾部已消除;剩余决策(批量是否值得、配额怎么调、气泡是否可回收、离群归口)**全部依赖构成已知**。而两笔最大开销都不是报告发现的——**把"猜"变成"查"本身最省**。
117
+
118
+ ---
119
+
120
+ ## 五、数据缺口(要测什么、怎么测)
121
+
122
+ 1. **工具执行 vs 模型**:按条目 role(`assistant(toolUse)` / `assistant(stop)` / `toolResult`)的 Δ 拆分,离线推导(同一遍历)。
123
+ 2. **单次调用内 TTFT vs 生成**:**不承诺**——session 只有完成时间戳;为它插桩的收益不支撑成本。
124
+ 3. **retry 率**:loop 日志"无产出"行 ÷ 唤醒数;本场 1 次。
125
+ 4. **终止原因分布**:本场可得(已入本报告);**历史场次已随 cleanup 消失** ⇒ 未来必须进 `--report`(读既有日志,零新落盘、零 sidecar)。
126
+ 5. **每轮增量信息量**(配额校准输入):优先**协议可观测代理**(冻结/pass 率、未决项数);LLM 标注只作辅助证据(自述≠测量)。
127
+ 6. **上下文规模 vs Δ**(视图④):判断墙钟对轮次是线性还是超线性;agent 数不直接乘墙钟(三链取 max),但加速每轮上下文增长。
128
+
129
+ ---
130
+
131
+ ## 六、附加反馈(无扩展工具体验)
132
+
133
+ - **实况核实**:本场 agents 实际运行在 `--pure`(零扩展:无 AFT、无 MC,`CMD:` 含 `--no-extensions --no-skills`);question.md 附加反馈段写"pi 内置工具 + MC"与实际不符——三方均指出,属文档措辞问题,随收尾修正。
134
+ - **自述(注明:自述 ≠ 测量)**:内置 `read`/`grep`/`bash` 胜任本任务,未因缺工具放弃或简化检查;效率:符号级导航多 2–3 步/文件;简单:未经历完整工具链;铁律:用内置工具完成 protocol/引擎/loop 源码核对与"锁 git → 提交"调用链追查。
135
+ - **观察到的等待**:无重试轰炸、无重复准备;首唤 fork 源由三 agent 并行构建(~0.5s/个)。最大单唤醒 167s,距 stall 阈值有充足余量。
136
+
137
+ ---
138
+
139
+ ## 七、收尾清单(实施项)
140
+
141
+ 1. [ ] 报告层构成表实施(含五条恒等式自检;桥接用"四端点 + 有向差"写法)。
142
+ 2. [ ] 终止原因进 `--report`(读既有 loop 日志,零新落盘)。
143
+ 3. [ ] 扩展策略删到一条(零扩展)+ 删净配套(`KEEP_EXTENSIONS` / `resolve_extension_entries` / 测试 / 决策 19/20 文档);将来若加回 MC,须**显式 opt-in 且带净收益账**。
144
+ 4. [ ] question.md 附加反馈措辞修正("内置工具+MC" → 零扩展)。
145
+ 5. [ ] **门槛条款**:任何"省时"提案先按 `净收益 = 节省 − 机制自身成本 × 频率 − 失效代价(含检测延迟)` 自证;凡需改 `meeting_engine`/`meeting_loop` 或新增常驻机制者,先过**审计三问**(① 职责归属怎么变 ② 净收益数据来源 ③ 新增失败面与检测延迟),不得直接实施。
146
+ 6. [x] 本场终止原因与运行元信息已由本报告头部留存。
147
+
148
+ ---
149
+
150
+ ## 过程记录(收敛路径)
151
+
152
+ 1. **效率/0001** 提出双乘数与"缺每次唤醒四段计时";**简单/0001** 主张"能删除的不要用新机制解决";**铁律/0001** 给出 `commit-after-exit` 机制(进程退出绑在消息可见性上)与设计符合度核对。
153
+ 2. **口径拉齐**:简单指"大头在加载"(插件时代成立),效率修正为"删除后加载仅 ~5%"——同一事实的两个时间点;三方对"不等进程退出就推进"**一致反对**(收益≈0、并发复杂度高)。
154
+ 3. **测量设计**:四段计时 → 一条链(复用 `observability` 单次遍历)→ 运行级表头 + 每唤醒记录 + 聚合视图 → 精度契约(不为 TTFT 细分插桩)→ 窗口锚定与桥接公式(消除 commit 口径与进程口径混用)。
155
+ 4. **补正与撤回**:效率撤回"砍 2 次往返省 22–28s"(均值口径高估,改按 stopReason 分层);铁律提出并收回"跨度上界告警"(改为报告事实行 + 流程验收);铁律的"唤醒次数校准"被限定为"先看终止原因分布、且 cap 是上限非行程"。
156
+ 5. **实测支点**:本场 fork 源统计证明 harness 支持一步多工具调用(使用率 2–3%)→ 批量取数属**用法**而非机制;本场事后推导给出首张构成表(附录,启动 1% / 事件内 99% / 收尾 0%)。
157
+ 6. **收敛**:三方全部 pass;无保留异议。
158
+
159
+ ---
160
+
161
+ ## 附录:本场首个校准样本(事后纯推导,零成本、零插桩)
162
+
163
+ > 此表即"报告层构成表"要自动化的内容;由本场 `wake-logs` + `loop-*.log` + session 条目 + `git log` 事后推导。本场为 `--pure`(零扩展)。
164
+
165
+ | agent | 唤醒 | 启动段 | 事件内 | 收尾 | 进程跨度 |
166
+ |---|---|---|---|---|---|
167
+ | 效率 | 11 | 5s | 454s | 0s | 459s |
168
+ | 简单 | 12 | 5s | 505s | 0s | 511s |
169
+ | 铁律 | 9 | 4s | 564s | 0s | 568s |
170
+ | **合计** | **32** | **14s(1%)** | **1523s(99%)** | **0s(0%)** | **1538s** |
171
+
172
+ - 墙钟(首末 commit):**636s**;并行度 = 1538 / 636 = **2.42**(上限 3.0);
173
+ - 口径:启动段 = `t_spawn → t_首事件`(**不含**首次模型调用,其 TTFT 落在事件内);事件内 = `t_首 → t_末`(模型往返 + 工具执行混合,按 role 可再细分);收尾 = `t_末 → t_exit`;
174
+ - 精确边界取自 `customType=mv.analysis-start`(字段判定,非子串——F1 修正);
175
+ - 缺口:本表尚未含跨 agent 区间重叠/空位、逐唤醒 commit 时刻与 retry 标记——即"报告层构成表"的实施内容。