@furongjun1999/dsh-memory 0.5.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.
Files changed (138) hide show
  1. package/README.md +552 -465
  2. package/docs/README.md +1 -0
  3. package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
  4. package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
  5. package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
  6. package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
  7. package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
  8. package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
  9. package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
  10. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
  11. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
  12. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
  13. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
  14. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
  15. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
  16. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
  17. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
  18. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
  19. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
  20. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
  21. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
  22. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
  23. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
  24. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
  25. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
  26. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
  27. package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
  28. package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +19 -3
  29. package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
  30. package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
  31. package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
  32. package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
  33. package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
  34. package/lib/bridge.d.ts +9 -0
  35. package/lib/bridge.js +35 -0
  36. package/lib/index.js +7 -1
  37. package/lib/lib/roleplay_web.js +530 -443
  38. package/lib/lib/token_store.d.ts +7 -1
  39. package/lib/lib/token_store.js +12 -3
  40. package/md_cg/audit.py +12 -1
  41. package/md_cg/backfill.py +16 -15
  42. package/md_cg/backfill_bucket_zh.py +35 -0
  43. package/md_cg/bench_e2e_judge.py +532 -0
  44. package/md_cg/bench_e2e_locomo_qa.py +368 -0
  45. package/md_cg/bench_e2e_qa.py +256 -0
  46. package/md_cg/branches.py +18 -2
  47. package/md_cg/ccgc.py +3 -2
  48. package/md_cg/chain.py +19 -4
  49. package/md_cg/consolidate.py +7 -6
  50. package/md_cg/crosscheck.py +4 -3
  51. package/md_cg/crypto.py +439 -437
  52. package/md_cg/datapath.py +395 -335
  53. package/md_cg/evidence.py +582 -580
  54. package/md_cg/export.py +3 -1
  55. package/md_cg/forgetting.py +2 -2
  56. package/md_cg/fsutil.py +48 -0
  57. package/md_cg/hotcache.py +255 -238
  58. package/md_cg/interop.py +161 -22
  59. package/md_cg/judgment_manifest.py +177 -0
  60. package/md_cg/links.py +655 -622
  61. package/md_cg/mcp_server.py +280 -29
  62. package/md_cg/mdcg.py +616 -125
  63. package/md_cg/mdcos.py +430 -66
  64. package/md_cg/mreview/govern.py +5 -4
  65. package/md_cg/postings.py +4 -2
  66. package/md_cg/readcache.py +76 -18
  67. package/md_cg/reconcile.py +228 -0
  68. package/md_cg/review_cli.py +170 -0
  69. package/md_cg/routing.py +28 -0
  70. package/md_cg/run_tests.py +211 -0
  71. package/md_cg/scrub.py +862 -852
  72. package/md_cg/security.py +385 -275
  73. package/md_cg/selfreport.py +3 -2
  74. package/md_cg/signer.py +565 -562
  75. package/md_cg/sources.py +3 -2
  76. package/md_cg/stg.py +6 -0
  77. package/md_cg/sustain.py +1168 -1138
  78. package/md_cg/test_access_hints.py +147 -0
  79. package/md_cg/test_branch_discard_tombstone.py +136 -0
  80. package/md_cg/test_branches.py +259 -249
  81. package/md_cg/test_chain_read_isolate.py +168 -0
  82. package/md_cg/test_datapath_device_name.py +203 -0
  83. package/md_cg/test_emit_negtail_cache.py +156 -0
  84. package/md_cg/test_en_pipeline.py +186 -166
  85. package/md_cg/test_govern_directread.py +421 -0
  86. package/md_cg/test_i32_hotcache_env_key.py +218 -0
  87. package/md_cg/test_identity_attribution.py +228 -147
  88. package/md_cg/test_index_durability.py +238 -224
  89. package/md_cg/test_interop.py +4 -2
  90. package/md_cg/test_interop_judgment.py +228 -0
  91. package/md_cg/test_issue39_utf8_stdio.py +273 -0
  92. package/md_cg/test_links_concurrent_write.py +188 -0
  93. package/md_cg/test_merge_upsert.py +168 -0
  94. package/md_cg/test_n123_derive_expiry_chain.py +205 -0
  95. package/md_cg/test_n130_verify_falsified_protect.py +185 -0
  96. package/md_cg/test_n131_merge_gate.py +205 -0
  97. package/md_cg/test_p1x_ref_root.py +160 -0
  98. package/md_cg/test_p27_docindex.py +774 -765
  99. package/md_cg/test_p2_mcp.py +3 -0
  100. package/md_cg/test_p32_backfill.py +304 -298
  101. package/md_cg/test_p39_verify_flow.py +90 -50
  102. package/md_cg/test_p47_session_view.py +60 -25
  103. package/md_cg/test_propose_tail_index.py +157 -0
  104. package/md_cg/test_read_scope_b27.py +277 -0
  105. package/md_cg/test_readcache_default_on.py +168 -0
  106. package/md_cg/test_readcache_precise_inval.py +270 -0
  107. package/md_cg/test_readcache_prodpath.py +55 -7
  108. package/md_cg/test_reconcile_v0.py +294 -0
  109. package/md_cg/test_retr_s1.py +6 -2
  110. package/md_cg/test_retr_s1b.py +67 -0
  111. package/md_cg/test_retr_s7.py +8 -0
  112. package/md_cg/test_retr_s9_entity_ctx.py +181 -175
  113. package/md_cg/test_retr_score_once.py +208 -0
  114. package/md_cg/test_review_onepass.py +170 -0
  115. package/md_cg/test_rrf_graph_seed_cache.py +154 -0
  116. package/md_cg/test_security_audit.py +155 -0
  117. package/md_cg/test_security_audit_b26.py +161 -0
  118. package/md_cg/test_security_audit_v21.py +250 -0
  119. package/md_cg/test_semantic_canonical.py +255 -241
  120. package/md_cg/test_session_isolation.py +168 -0
  121. package/md_cg/test_snapshot_autoclose.py +187 -0
  122. package/md_cg/test_tail_watermark_race.py +208 -0
  123. package/md_cg/test_tenant_env_override_warn.py +139 -0
  124. package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
  125. package/md_cg/test_v14_fixes.py +415 -397
  126. package/md_cg/test_verify_dirty_reconcile.py +157 -0
  127. package/md_cg/theory.py +276 -273
  128. package/md_cg/tokens.py +734 -677
  129. package/md_cg/units.py +3 -2
  130. package/md_cg/vision_evidence.py +4 -3
  131. package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
  132. package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
  133. package/md_cg/writepipe.py +554 -550
  134. package/package.json +6 -2
  135. package/src/bridge.ts +434 -401
  136. package/src/index.ts +526 -518
  137. package/src/lib/roleplay_web.ts +1019 -932
  138. package/src/lib/token_store.ts +202 -192
@@ -0,0 +1,197 @@
1
+ # 端到端干扰池评测:确定性裁决层 vs LLM-as-judge v1.1
2
+
3
+ > **日期**:2026-09-23 · **基线**:`main@30afc94`(灵枢 v0.5.0)
4
+ > **评测问题**(外部建议口径):此前全部实证是「零干扰池检索命中率上界」;本报告补上缺失的三面——
5
+ > **pinpoint**(干扰下 LLM 能否抽取正确事实)、**answerability**(该拒答时是否拒答)、
6
+ > **decision-making**(裁决层是否改变下游行为),并把「确定性裁决层」与「LLM-as-judge」正面对比。
7
+ > **一句话结论**:词法候选健康时(`MDCG_UNIFY_QUERY=0`)三臂检索持平(hit@1 94-96%)而
8
+ > **防火墙与 LLM 裁决对无标记干扰均无增益**(REJECT 恒 0 / LLM 误杀 gold ~14%);
9
+ > 端到端 QA **43.3%(零干扰)→ 40.0%(全干扰)**,对抗题正确拒答仅 3/27——
10
+ > answerability 是最大短板;另附**统一归一层 A/B**(批次 15 边界反馈):
11
+ > 归一开在 CCG 卡 + RRF 融合形态下 **−11.7pp**,根因是 query 拆原子与 doc 侧原子面缺位的形态不对称。
12
+ >
13
+ > v1.1 变更:用户质询「语义归一化做了么」触发归一层 A/B——v1.0 的「防火墙负增益 −2.5~−3.3pp」
14
+ > 判定为**归一层伪影**(详见 §4),主口径切换为归一关态,全部三臂 + QA 已双态复测。
15
+
16
+ ---
17
+
18
+ ## 1 · 设计
19
+
20
+ ### 1.1 数据与写入面
21
+
22
+ - 语料/题面:公开集 [`locomo-zh-500`](../../data/benchmarks/locomo-zh-500/)(567 turn / 500 题)。
23
+ - **gold 与合成干扰走同一 CCG 六要素写入函数**(公平性原则):生效条件由节点自身字段机械合成
24
+ (`主体=…;时间窗口=…;主题=…`),不接触题面;不适用条件一律诚实写「无」——
25
+ **合成干扰不携带任何方便防火墙剔除的标记**。
26
+ - 全部节点过 `ccg_completeness` 断言(6 行缺一不可,杜绝 BLINDSPOT 面混入)。
27
+
28
+ ### 1.2 干扰家族(每题合成,500 题全部注入、池全局共享)
29
+
30
+ | 家族 | 构造 | 威胁面 |
31
+ |---|---|---|
32
+ | **D2 实体互换** | 摘要中双方名字互换 + 主体换人 | 「谁说的/谁做的」答案错,词面几乎同款 |
33
+ | **D3p/D3m 时间错位** | 同一事实 ±1 年 | 查询不含时间词时原则上不可区分(诚实边界) |
34
+ | **D4 否定澄清** | 「澄清:此前所说「…」并不属实」 | 否认该事实,词面高度重叠 |
35
+ | D1 同话题硬负例 | 不合成——其余 566 条天然 turn 即干扰池 | 全 level 在场 |
36
+
37
+ **浓度梯度**:level ∈ {0,1,2,4} = 每题注入前 level 条(池 567 / 1067 / 1567 / 2567 节点)。
38
+ id 前缀 `x_`(字典序排在 gold 之后——平局兜底**偏向 gold**,对我方保守)。
39
+
40
+ ### 1.3 三臂(检索裁决面)与 QA 管线
41
+
42
+ - **arm_base**:裸五路融合(`search_rrf`,lexical/bucket/entity/graph/fuzzy · sum)top-10。
43
+ - **arm_firewall**:同候选面 + 确定性裁决(`judge=True, judge_ranking=True` 证据防火墙)。
44
+ - **arm_llm**:同候选面 + deepseek-chat 逐卡资格裁决(qualified 优先重排,与防火墙
45
+ keep/降权同构),temperature=0,两轮独立调用测自一致性。
46
+ - **QA 管线**(120 题 × level {0,4} × 候选臂 {base,firewall}):reader(deepseek-chat)
47
+ 只据 top-10 候选卡作答(不足答「无法确定」)→ judge 对 gold 语义判等
48
+ (correct / incorrect / refused)。
49
+ - **gold 答案来源**:上游 LoCoMo 原始标注——`mteb/LoCoMo@02e2c3de` 1976 题英文题面与
50
+ `snap-research/locomo` `locomo10.json` 逐题文本精确匹配(**1976/1976 全中、零跨 scene 错配**),
51
+ 本仓 500 题答案覆盖 **500/500**;113 题 adversarial 上游 gold 为空 = **正确行为是拒答**。
52
+ - 采样:seed=7 确定性采样 120 题(qtype 分布与全集同构)。
53
+ - **归一口径**:主表 `MDCG_UNIFY_QUERY=0`(理由见 §4——归一开在 CCG 形态是净负效应,
54
+ 属批次 15 边界缺陷而非评测对象属性);§4 给双态对照。doc 侧摘要正文不做词典归一
55
+ (与主链路一致——主链路的标准词加工就是五槽「词」槽本身,本评测卡片在「主题=」行
56
+ 原样携带同一批派生标准词);同义扩展经 fuzzy 路在场。
57
+
58
+ ## 2 · 结果一:检索裁决面(hit@1 / MRR,120 题,归一关)
59
+
60
+ | level(池) | base | firewall | llm(r1/r2) |
61
+ |---|---|---|---|
62
+ | 0 (567) | 95.0% / 0.972 | **95.8%** / 0.977 | 94.2% / 0.967(两轮同值) |
63
+ | 1 (1067) | 94.2% / 0.968 | **95.0%** / 0.971 | 93.3% / 0.960(r2 同) |
64
+ | 2 (1567) | 95.0% / 0.972 | **95.8%** / 0.975 | 92.5% / 0.953(r2 同) |
65
+ | 4 (2567) | **95.8%** / 0.976 | **95.8%** / 0.975 | 95.0% / 0.969(r2 94.2%) |
66
+
67
+ - **三臂持平在 94-96%**,hit@10 = 100% 全线:干扰不把 gold 挤出候选池,胜负全在排序与裁决,
68
+ 而两种裁决器都**不能把 95% 的词法排序再抬高**。
69
+ - **确定性防火墙**:+0.8pp×2 档、持平×2 档(±1 题,噪声量级)——「微正但无实质增益」。
70
+ 四态分布(top10):ACCEPT 68-71%、DEFER 29-32%、**REJECT/BLINDSPOT 恒 0**。
71
+ 诚实写入面下无负条件可命中,REJECT 路结构性缺席——`test_sem_noise` 的正增益依赖
72
+ 「否定节点声明负条件」这一前提,**词面条件裁决对无标记对抗干扰无免疫力**(可证伪结论)。
73
+ - **LLM 裁决器**:无增益(−0.8~−2.5pp vs base)——它会把 gold 判不合格(gold 获
74
+ qualified 仅 82.5-85.8%)、全弃权 10.8-13.3%,误杀盖过其剔噪收益。自一致性
75
+ (两轮独立):**top1 一致 98.3-100%**、qualified 集一致 84-92%——排序面高度可复现。
76
+ - 合成干扰对 top1 的直接置换仅 **1-2/120**(D2,L1 起出现、不随浓度增长);且均为
77
+ **交叉冒充**——`scene_0_q_66` 被 `x_d2_scene_0_q_198`(另一题的干扰)压过、
78
+ `scene_7_q_91` 被 `x_d2_scene_0_q_184` 压过。全局共享池下「别题干扰冒充本题」是真实威胁面。
79
+
80
+ ## 3 · 结果二:QA 端到端(pinpoint / answerability / decision-making,归一关)
81
+
82
+ | 组 | QA准确率 | 常规题准确率 | 常规题拒答 | 对抗题正确拒答 | 对抗题被骗 |
83
+ |---|---|---|---|---|---|
84
+ | L0 · base 候选 | **43.3%** | 52.7% | 26/93 (28%) | 3/27 (11%) | 6/27 (22%) |
85
+ | L0 · firewall 候选 | 44.2% | 53.8% | 26/93 | 3/27 | 6/27 |
86
+ | L4 · base 候选 | 40.0% | 46.2% | 40/93 (43%) | 5/27 | 11/27 (41%) |
87
+ | L4 · firewall 候选 | 39.2% | 45.2% | 42/93 | 5/27 | 10/27 |
88
+
89
+ (归一开态对照:L0 base 40.8% / L4 base 39.2%——归一关略优 +2.5pp,格局不变。)
90
+
91
+ - **pinpoint**:全家族干扰下 QA 总准确率 −3.3pp(43.3→40.0),常规题 −6.5pp
92
+ (52.7→46.2)且拒答 +14 题——reader 在干扰下**更保守但不更准**,退化以
93
+ 「该答不敢答」而非「答错」的形态出现。
94
+ - **answerability(最大短板)**:对抗题(gold=拒答)正确拒答仅 3/27(L0)→ 5/27(L4),
95
+ 被骗编造答案 6→11。被骗样例(L4·base):`连帽衫`/`乌龟`/`Finding Home`——检索命中的
96
+ 相似记忆诱导 reader 拼出自信答案。《Why Johnny Can't Persist》指出的记忆系统通病
97
+ (检索命中 → 编答案而非拒答)在本系统**端到端实证成立**。
98
+ - **decision-making**:firewall 候选与 base 候选的 QA 成绩无差异(44.2 vs 43.3;39.2 vs 40.0)
99
+ ——**确定性裁决层不改变下游行为**。
100
+ - 常规题拒答样例(L0):gold=`2022`/`Sunsets`/`Roast marshmallows`——多为时间推理与细节题:
101
+ hit@10 虽 100%,**摘要卡信息密度不足以还原原始对话细节**,reader 宁拒答不猜。
102
+
103
+ ## 4 · 结果三:统一归一层 A/B(批次 15 边界反馈 · 双态对照)
104
+
105
+ > 触发:用户质询「中文摘要按现有流程做语义归一化了么」。查证:`search_rrf` 入口
106
+ > `q = unify_query(q)`(`mdcos.py:1210`)默认开——**v1.0 全部数字即生产同口径(归一开)**。
107
+ > A/B 后判定 v1.0「防火墙 −2.5~−3.3pp 负增益」为归一层伪影,主口径切归一关。
108
+
109
+ ### 4.1 三组对照(L0,120 题)
110
+
111
+ | 形态 | 归一开(默认) | 归一关 | 差 |
112
+ |---|---|---|---|
113
+ | **CCG 卡 + `search_rrf` 五路**(本评测)base hit@1 | 83.3% | **95.0%** | **−11.7pp** |
114
+ | 同上 · firewall hit@1 | 80.0% | **95.8%** | −15.8pp |
115
+ | **五槽裸串 + `cg.search` 阶梯路**(生产主形态,第三方 A_zh5 同款)hit@1 | 95.8% | 95.8% | **0(持平)** |
116
+
117
+ 归一实际作用面:120 题中 39 题含拉丁字母(纯中文 query 按设计零变更),全部 39 题被改写。
118
+
119
+ ### 4.2 根因(改写样例实证)
120
+
121
+ 1. **形态不对称(主因)**:含拉丁字母的 query 被拆成单字标准原子
122
+ (`绘画 作品`→`绘 画 作 品`)——`unify.py` 注释明示该形态与「doc 侧 `fm.semantic`
123
+ 原子面同构」;CCG 卡与五槽裸串均无该面 → RRF 词法路的加权覆盖被拆散形态破坏。
124
+ 2. **撞词错译**:`Matt`→`哑 光`(CEDICT matt=哑光,人名撞词)、`hikes`→`健 行`
125
+ ——README ④ 臂记录过的机械直译病在批次 15 重演。
126
+ 3. **数字丢失**:`Gina 2023 时尚实习`→ 归一后 `2023` 消失——时间词丢失对 temporal 题致命。
127
+
128
+ 阶梯路持平的解释:char-bigram 对「拆单字加空格」几乎无损(bigram 集合不变),
129
+ 故生产主形态未现回归;RRF 词法路的**词级加权覆盖**对拆散形态敏感,故 CCG 形态崩。
130
+
131
+ ### 4.3 建议(供批次 15 口径拍板人)
132
+
133
+ - 归一层加边界闸:**库内无 `fm.semantic` 原子面时跳过拆原子**(原样传 query),
134
+ 仅在 doc 侧原子面在场时启用形态归一;
135
+ - 英文普通词作用于中文题面时保持 unknown_keep(人名/普通词撞词错译 `Matt→哑光` 应拒译);
136
+ - 数字 token(年份)不应被归一层丢弃;
137
+ - 回归口径补「CCG 卡 + RRF 融合路 × 中文题面含拉丁字母」形态(本 A/B 脚本可直接复用)。
138
+
139
+ ## 5 · 归因链(三层证据合读)
140
+
141
+ 1. **检索面(hit@10 100%)→ QA 面(43.3%)的 57pp 落差**:瓶颈不在检索在读写两侧——
142
+ 写入面(摘要卡压缩掉细节)与读出面(reader 无「证据不充分检测」)。
143
+ 2. **两种裁决器都救不了检索面,也都不改变 QA 面**:词面条件(REJECT 恒 0)与语义阅读
144
+ (误杀 gold ~14%)在「干扰与 gold 同款条件、同款词面」的对抗设定下均无增益——
145
+ **裁决层的增益边界=干扰与 gold 之间是否存在可机读的差异面**(负条件标记 / 证据基底 /
146
+ 时间线冲突),这正是 bench_progressive 预告的「另案」方向。
147
+ 3. **LLM 裁决器的价值是条件性的**:候选质量被归一层打崩时(v1.0 归一开态)它能捞回
148
+ +5pp(88.3 vs 83.3);候选健康时(归一关)无增益。**「LLM-as-judge 优于确定性裁决」
149
+ 不成立为一般结论,仅在低质量候选面上成立**。
150
+
151
+ ## 6 · 诚实边界
152
+
153
+ - 本评测为 **CCG 化写入口径**(摘要卡 + 机械条件面);生产主形态(五槽裸串+阶梯路)
154
+ 归一开/关已单独对测(§4.1),但三臂主表仅在 CCG 形态上运行。
155
+ - L0 base 95.0%(归一关)与主链路 94.6%(五槽口径)同量级——**量级对照,非逐位复现**
156
+ (写入面与检索路均不同)。
157
+ - reader 同时拿中文关键词串与上游英文原题(真实用户问题面),记忆卡为中文,judge 对
158
+ 英文 gold 跨语语义判等——双语口径;judge 亦为 LLM(LLM-as-a-judge),边界例按 judge
159
+ 裁决计入、未人工复核。
160
+ - QA 43.3% 不能直接对标 Mem0/Letta 论文的 LoCoMo QA 数字(他们用完整对话原文做记忆、
161
+ 自然问句做查询);本口径是「摘要卡 + 关键词面」的保守下界。对标前须换装完整对话记忆面重跑。
162
+ - 合成干扰为机械构造(名字互换/年份平移/否认包裹);D3 在查询无时间词时原则上不可区分
163
+ (两臂均无法免疫),如实计入。
164
+ - 120 题采样(seed=7)下 1pp ≈ 1.2 题;±3pp 内差异不构成结论。
165
+
166
+ ## 7 · 复现
167
+
168
+ ```bash
169
+ # 前置:DEEPSEEK_API_KEY;数据根默认 D:\program\test\e2e_judge(--data-root 可改)
170
+ # 主口径(MDCG_UNIFY_QUERY=0;归一开对照去掉该前缀即可)
171
+ MDCG_UNIFY_QUERY=0 python -X utf8 -m md_cg.bench_e2e_judge --quick # 冒烟(确定性两臂)
172
+ MDCG_UNIFY_QUERY=0 python -X utf8 -m md_cg.bench_e2e_judge --skip-llm # 全量确定性矩阵
173
+ MDCG_UNIFY_QUERY=0 python -X utf8 -m md_cg.bench_e2e_judge --arms llm # LLM 裁决臂 ×2 轮
174
+ MDCG_UNIFY_QUERY=0 python -X utf8 -m md_cg.bench_e2e_qa # QA 端到端
175
+ # gold 答案映射(上游对齐,500/500):D:\program\test\e2e_judge\upstream\answers_map.json
176
+ ```
177
+
178
+ 产物:`results/summary_*.json`(三臂指标+LLM 逐题)、`results/qa_*.json`(QA 逐题)、
179
+ `results/detail_L{lv}_n120_s7.json`(行级明细)。LLM 调用带缓存(`llm_cache/`、`qa_cache/`),
180
+ 键含轮次与完整 prompt——双态复跑自然分键,两轮自一致性仍是真实独立调用。
181
+
182
+ ## 8 · 结论与下一步(早暴露早修)
183
+
184
+ | 发现 | 状态 | 行动项 |
185
+ |---|---|---|
186
+ | 端到端 QA 43.3%(L0)→ 40.0%(L4),检索→QA 落差 57pp | **新基线数字** | 写入面细节槽(时间/实体保真),读写两侧补 |
187
+ | 对抗题正确拒答 3/27、被骗 6→11 | **最大短板** | reader 侧证据不充分检测 / 裁决器 BLINDSPOT 面扩展 |
188
+ | 防火墙与 LLM 裁决对无标记干扰均无增益(±1 题;REJECT 恒 0) | **可证伪双负结果** | 裁决差异面升级:证据基底 / 时间线冲突(bench_progressive「另案」落地依据) |
189
+ | **统一归一层在 CCG+RRF 形态 −11.7pp**(拆原子×doc 侧原子面缺位;撞词错译;数字丢失) | **批次 15 边界反馈** | §4.3 三条修复建议;回归口径补 CCG 形态 |
190
+ | LLM 裁决器增益是条件性的(低质候选 +5pp / 健康候选 −1~−3pp) | 一般结论证伪 | 混合架构仅按候选质量自适应启用 LLM 裁决 |
191
+ | D2 交叉冒充(别题干扰压过本题 gold) | 新威胁面 | 干扰敏感性:按题隔离池 vs 全局池对照(后续实验) |
192
+
193
+ ---
194
+
195
+ *评测器:`md_cg/bench_e2e_judge.py`(三臂裁决)· `md_cg/bench_e2e_qa.py`(QA 层)。
196
+ 数据根:`D:\program\test\e2e_judge`(池缓存 / LLM 缓存 / 结果与逐题明细)。
197
+ v1.0(2026-09-23 归一开态)已被 v1.1 双态复核取代;v1.0 数字保留于 §4 对照列。*
@@ -0,0 +1,156 @@
1
+ # 缺陷挖掘报告 · 自主迭代 v1
2
+
3
+ - **日期**:2026-09-25
4
+ - **范围**:md_cg(认知图内核与安全层)、hive(编排与工作记忆)、scripts(纪律校验/投影同步)、compiler(中文协议编译器)、swarm(Rust 群体引擎封装)
5
+ - **总量**:候选缺陷 29 → 确认 27 → 修复 6 → 跳过 0
6
+ - **严重度分布**(确认 27 项):high 7 / medium 11 / low 9
7
+ - **行号口径**:下文缺陷行号为挖掘时快照行号;修复落盘后行号有漂移,凡本报告写作者本会话复核过的位置均另注当前行号。
8
+
9
+ ---
10
+
11
+ ## 一、执行摘要
12
+
13
+ 本轮自主迭代对五个子系统做了一次全量缺陷挖掘,产出 29 个候选,经复核确认 27 个(2 个候选未通过复核,明细未随任务输入提供,本报告不展开)。确认项覆盖四类问题:
14
+
15
+ 1. **数据完整性**(mdcg.py 覆写双文件、restore() 元数据丢失、trust.py 审计时间戳污染);
16
+ 2. **安全边界**(mdcg.py `_read` 越界读、hive/wm.py 路径穿越删目录、hive/orch.py 越权读子任务、MdCGSecure.propose 层权限校验与落盘口径分裂);
17
+ 3. **功能可用性**(codegen.py 产物 100% 无法 compile、api.py LLM 辅助路径 100% NameError、audit.py 外部验证器加载必崩、语法错误静默吞掉导致含错源码报成功);
18
+ 4. **一致性/可维护性**(Python/Rust 聚合数值分歧、文档与实现矛盾、自检正则与其守护目标矛盾、死代码)。
19
+
20
+ 修复批次落盘 6 项:候选清单内 5 项(全部 4 个 high 级"必崩/必坏"类:mdcg 覆写双文件、restore 元数据丢失、writepipe importance=null 崩溃、编译器语法错误回流 + codegen 非法产物),外加修复过程中暴露并一并修复的 codegen 行协议族潜伏缺陷 1 项(清单外)。8 个 compiler 测试套件全数通过(共 77+ 用例,详见第六节)。其余 21 项确认缺陷遗留待后续批次处置,无跳过项。
21
+
22
+ **修复映射的口径说明**:任务输入报"修复缺陷 6"。本报告写作者以 `git diff`(工作树未提交改动,见第四节逐项引证)核对:候选清单内被完整修复的为 5 项(#1、#2、#7、#19、#20);第 6 项修复为 codegen 行协议族(`_writeln` 无 `\n` 终结、`"\n".join` 双换行、if 冒号另起行、赋值不终结行、空块无 `pass`),系修复 #20 时暴露的**清单外同族缺陷**。另 #5(`_stage` 桶计数漂移)随 #1 的修复附带处置了"跨桶不扣减"半边,同桶覆写自增按既有口径显式保留(见第三节 #5 行),记为部分修复。
23
+
24
+ ---
25
+
26
+ ## 二、发现列表(确认 27 项)
27
+
28
+ 状态取值:**已修复** / **部分修复** / **未修复(遗留)**。证据标注:
29
+ - `输入复核`=任务输入所附复核结论(复核: confirmed),本会话未复跑;
30
+ - `本会话验证`=报告写作者本轮实际读取代码或运行复现脚本核对。
31
+
32
+ ### high(7 项)
33
+
34
+ | # | 位置 | 缺陷摘要 | 状态 | 证据 |
35
+ |---|------|----------|------|------|
36
+ | 1 | md_cg/mdcg.py:1189-1201,1403 | `add()` 覆写既有节点且路由键变化时,新文件写入新桶目录但旧桶同 id 文件永不清理——磁盘留下同 id 双文件,`rebuild_index()` 后索引条目取哪个文件取决于 `os.walk` 枚举序,旧内容可能静默回退顶掉新内容 | **已修复**(现 mdcg.py:1404-1427) | 本会话验证(git diff hunk:旧路径 realpath 双闸校验后 `os.remove`,先写新后删旧) |
37
+ | 2 | md_cg/mdcos.py:2105-2126 | `restore()` 从 trash 读出完整 frontmatter 却只用 8 个字段重建节点,edges/depends_on/验证态/生命周期/created_at/semantic/证据计数等全丢,随后 `os.remove` 删 trash 源——元数据永久丢失 | **已修复**(现 mdcos.py:2117-2162) | 本会话验证(git diff hunk:显式形参逐项透传 + `**_extra` 回写其余键,生命周期/验证态按合法迁移过滤) |
38
+ | 6 | md_cg/audit.py:349 | `load_external_verifiers` 用了未导入的 `sys`(函数内只 `import sys as _sys`),任何外部验证器模块成功导入即在 `sys.stderr.write` 处抛 NameError,外部验证器加载功能整体不可用 | 未修复(遗留) | 本会话验证(audit.py 模块头仅 import json/os/re;:323 `import sys as _sys`;:349 裸用 `sys.stderr`) |
39
+ | 7 | md_cg/writepipe.py:474 | 链尾执行器 `float(a.get("importance", 0.5))`:显式传 importance=null(JSON null→None)时 `float(None)` 抛 TypeError,主写路径崩溃 | **已修复**(现 writepipe.py:474-476) | 本会话验证(git diff hunk:`_imp is None` 判定回退 0.5,falsy 合法数值照传) |
40
+ | 18 | compiler/parser.py:346 | `parse()` 对返回 None 的语句再次 `_advance()`,与 `_parse_statement` 的 PERIOD 分支(已自行推进)叠加成双倍推进,把句号后的下一条顶层语句整个静默吞掉 | 未修复(遗留) | 本会话验证(现 parser.py:349-351 `else: self._advance()` 仍在;:357 生效条件注释确认 PERIOD 分支自行推进) |
41
+ | 19 | compiler/parser.py:326 | `Parser.__init__` 用 `errors or []`:调用方传空列表(常态)时被换成内部新列表,语法错误回不到调用方;api.py:144 又用 `getattr(ast,'errors',[])`(ProgramNode 无该属性,恒 [])——含语法错误的源码在两个编译入口都报成功 | **已修复**(现 parser.py:329、1089-1102;api.py:142-149) | 本会话验证(git diff hunk:`errors if errors is not None else []` 共享列表语义;api.py 传列表回流;test_loop_compile.py:109-116 用例⑧改为如实报错断言) |
42
+ | 20 | compiler/codegen.py:350 | `_gen_instruction` 用 `_writeln(f" → {code}")` 另起一行,每条指令都生成以 → 开头的非法 Python;且 footer 调用的 `main()` 从未定义(只生成 `def protocol_procedure()`)——产物过不了 `compile()`,而 compile_source 仍报 success=True | **已修复**(现 codegen.py:358-362、280-283) | 本会话验证(git diff hunk:指令降为行内注释 `{code} # {instr_name}`;footer 改调 `protocol_procedure()`) |
43
+
44
+ ### medium(11 项)
45
+
46
+ | # | 位置 | 缺陷摘要 | 状态 | 证据 |
47
+ |---|------|----------|------|------|
48
+ | 3 | md_cg/mdcg.py:2016-2022 | `_read()` 裸拼 `os.path.join(self.root, entry["path"])` 读文件,绕过 `_node_disk_path` 的 P2-20 越界校验(get():2004 有校验);`_read` 是检索主读路径(`_read_many`:2607 喂 search),索引被污染时越界路径可把 root 外任意文件读进检索结果;`_emit` 负记忆读取(2703、2785)同样裸拼 | 未修复(遗留) | 本会话验证(现 mdcg.py:2039-2040 `_read` 生效条件注释仍为裸 `os.path.join`) |
49
+ | 4 | md_cg/mdcos.py:3536-3539 | `MdCGSecure.propose` 层校验用 `kw.get("layer") or "contextual"`,基类缺省却是 `layer="knowledge"`——不传 layer 时校验 contextual、落盘 knowledge,两头皆错:knowledge-only 身份被误拒;contextual-only 身份入队成功但 accept 裁决因 `require_layer_write("knowledge")` 被拒成死提案 | 未修复(遗留) | 本会话验证(运行只读复现脚本 `python _repro_verify_3536.py`:S1 knowledge-only 被 AccessDenied 拒;S2 contextual-only propose 成功且落盘 `layer='knowledge'`;S3 同身份 accept 被 AccessDenied 拒——三场景与缺陷描述逐一吻合;现位置 mdcos.py:3575-3578) |
50
+ | 8 | md_cg/trust.py:208 | `stamp()` 对所有验证态迁移无条件写 `fm["verified_at"]=rec["at"]`,标 doubted/expired/unverified 时也覆盖真正的"何时验证过"时间戳,审计字段被污染 | 未修复(遗留) | 本会话验证(trust.py:208 无条件赋值仍在) |
51
+ | 10 | hive/orch.py:447 | `poll_subtasks` 接受任意 job_ids 且 `_card` 无归属校验,越权读取(含 `../` 路径穿越)非本编排者派发任务的 result 内容,违背文件头声明的"只允许读本编排者派发的子任务"纪律 | 未修复(遗留) | 本会话验证(orch.py:447 仍直接采信 `a.get("job_ids")`,无归属过滤) |
52
+ | 11 | hive/wm.py:138 | `cmd_snapshot` 把 result.json 的 job_id 原样拼进 `os.path.join(wm,"jobs",job_id)` 后无条件 `shutil.rmtree(dest)`,无路径净化——穿越形态的 job_id 可删除工作记忆仓之外任意已存在目录 | 未修复(遗留) | 本会话验证(wm.py:136-138 裸 join + isdir 即 rmtree) |
53
+ | 14 | scripts/verify_discipline.py:253-256 | `--target` 传未知目标名不校验,空 target 字典流入 `target["path"]` 抛未捕获 KeyError,实测退出码 1 与"存在漂移"混同,违反文件头 :13 "用法错误→退出码 2" 契约(render_discipline.py:533-536 对同一矩阵有校验,行为不一致) | 未修复(遗留) | 输入复核 |
54
+ | 21 | compiler/api.py:259 | `_ast_to_text` 使用 `NodeType`,但 api.py 导入清单(12-15 行)只有 parse_tokens/ProgramNode——LLM 辅助路径 100% NameError,llm_assist 整体失效(被 except 降级为 warning 静默) | 未修复(遗留) | 本会话验证(api.py:261 `stmt.type == NodeType.CONDITION_STMT` 仍引用未导入名) |
55
+ | 22 | compiler/parser.py:719 | `_parse_instruction` 的 `_INST_STOP` 缺 DANG(当)/ZHIXING(执行)/DINGYI(定义)/FANHUI(返回),指令操作数扫描越过这些语句开头关键字,把紧随的整条循环/函数/返回语句吞成操作数(与 `_parse_single_statement` 的 `_STOP` 在 684-689 含 DANG/ZHIXING 明确不一致) | 未修复(遗留) | 本会话验证(现 parser.py:722-741 的 `_INST_STOP` 枚举确无 DANG/ZHIXING/DINGYI/FANHUI) |
56
+ | 23 | swarm/rust_swarm.py:106 | `verify_wal_signatures` 对坏尾(半行截断)或被篡改成非法 JSON 的 WAL 行无守卫,`json.loads` 直接抛 JSONDecodeError(缺 hmac 字段时 KeyError)——CLI 安全模型声明的"中途被杀/坏尾"场景(swarm_cli.py:23-24)会让 verify 子命令以 traceback 崩溃而非输出验签结果,违反 stdout 恒为单行 JSON 契约(swarm_cli.py:5) | 未修复(遗留) | 输入复核 |
57
+ | 24 | swarm/swarm_cli.py:78 | `cmd_run` 调 `make_swarm_config` 未透传 `cfg_in.get("condition_space")`,swarm.json 里的 G-R2 条件空间卡在 CLI 入口被静默丢弃,永远到不了 Rust 引擎(swarm.rs:152 校验、:665 消费),条件空间注入经 CLI 不可达 | 未修复(遗留) | 本会话验证(swarm_cli.py:78-80 实调用参数表确无 condition_space) |
58
+ | 25 | swarm/swarm_cli.py:96 | `--out` 为相对路径时报告写入 base_dir/args.out(config 所在目录),摘要 `report_path` 却按 CWD 的 `os.path.abspath` 解析——从非 config 目录调用时返回的指针指向不存在的位置 | 未修复(遗留) | 输入复核 |
59
+
60
+ ### low(9 项)
61
+
62
+ | # | 位置 | 缺陷摘要 | 状态 | 证据 |
63
+ |---|------|----------|------|------|
64
+ | 5 | md_cg/mdcg.py:1831-1838 | `_stage()` 对同节点重复写入无条件 +1,不扣减旧桶、不按节点去重——覆写 N 次后 `index["buckets"]` 计数为 N,bucket_health/health() 巨桶占比与扫描率虚增,触发假"分区失效"告警(重启重扫自愈) | **部分修复**(跨桶半边随 #1 修复:mdcg.py:1421-1427 旧桶计数递减;同桶覆写自增按修复注释明示为"既有口径"保留——缺陷主场景"同桶 N 次覆写计数 N"仍在,现 `_stage` 位于 mdcg.py:1855-1860) | 本会话验证(git diff + 现行代码读取) |
65
+ | 9 | md_cg/trust.py:789-791 | `propagate()` 把全部 roots 预填进 seen 后才查 `len(seen)<max_nodes`:expired/rechecking 根数 ≥ max_nodes 时 BFS 整体被跳过,多跳失效传播静默返回 ok=True/reachable=0;内层 break 只退内层循环,frontier 各兄弟节点仍各放行 1 个穿透帽 | 未修复(遗留) | 输入复核 |
66
+ | 12 | hive/exec_cmd.py:16 | 模块 docstring 声称单步超时回落链"缺省 spec.timeout_s → 600",实现刻意不继承 spec.timeout_s(批次 23 D-5/v19 改动),文档与代码矛盾 | 未修复(遗留) | 输入复核 |
67
+ | 13 | hive/orch.py:407 | `_spawn` 中 `if not tools: tools = list(SUB_TOOLS_ALLOW)` 为不可达死分支——tools 此前已结构性非空 | 未修复(遗留) | 输入复核 |
68
+ | 15 | scripts/verify_discipline.py:208-215 | 孤儿声明处理段死代码:内层循环算的 snippet 从未使用,`res["orphans"] = res.get("orphans")` 为无效自赋值;:211 条件因 and 优先于 or,右支不要求该行含声明形态,与意图不符 | 未修复(遗留) | 输入复核 |
69
+ | 16 | scripts/render_discipline.py:439-455 | `read_config_key`/`write_config_key` 往返不对称:write 侧受管块含 YAML 键头行,read 侧只滤注释行——实测 dsh 目标读出首行 `personaPrefix: |-` 而非纯渲染值;以读出值再 write 会双重嵌入键头 | 未修复(遗留) | 输入复核 |
70
+ | 17 | scripts/cogmap_sync.py:216-222 | 分支数自检宽松正则与注释矛盾:`r"if\s+op\s*==\s*['\"]"` 只认 == 形态(仅 whitebox 含 in 分支)——若 dispatch 出现 `if op in (...)` 分支,严格提取与宽松计数双双漏计且两数相等,自检恒过,该 op 静默消失于投影与覆盖门禁,恰是该自检要堵的窗口 | 未修复(遗留) | 输入复核 |
71
+ | 26 | swarm/rust_codegen.py:57 | `build_rust_exe` 两候选路径均不存在、cargo build 成功后不重探 .exe 直接返回无后缀路径——Windows 首次构建返回的"可执行文件路径"实际不存在(真身 protocol_vm.exe),仅因 CreateProcess 自动补 .exe 未崩;按文件路径用返回值(exists/copy/hash)的调用方都会失败,与 build_and_run 构建后先探 .exe 不一致 | 未修复(遗留) | 输入复核 |
72
+ | 27 | swarm/rust_swarm.py:178 | `aggregate_health_python` 的 integrity 分子 `(t - vf.get(iid,0))` 无饱和夹取,verify_fail > total_events 时得负 integrity_rate 拉低 score,而 Rust health.rs:69 用 saturating_sub 夹 0——两实现异常输入下数值分歧,违背交叉验证定位 | 未修复(遗留) | 输入复核 |
73
+
74
+ > 证据口径统计:27 项中 16 项经本会话独立验证(读码 15 + 复现脚本 1,其中 5 项兼有 git diff 修复证据),其余 11 项采信任务输入所附复核结论、本会话未复跑。
75
+
76
+ ---
77
+
78
+ ## 三、修复清单(6 项)
79
+
80
+ 以下均为工作树未提交改动(`git diff` 本会话核对),修复文件 7 个:md_cg/mdcg.py、md_cg/mdcos.py、md_cg/writepipe.py、compiler/codegen.py、compiler/parser.py、compiler/api.py、compiler/tests/test_loop_compile.py。
81
+
82
+ ### F1(对应 #1,high)mdcg.py `add()` 覆写旧桶文件清理
83
+ - **修复**:md_cg/mdcg.py:1404-1427。写新文件后,若旧索引条目携带 path:`os.path.realpath` 归一后双闸校验(仍在 root 内——与 P2-20 同口径;不等于本次新路径——同桶覆写是同一文件不可删)再 `os.remove` 旧文件;删除失败不阻断主写路径。顺序先写新后删旧。
84
+ - **附带**:同 hunk 内 md_cg/mdcg.py:1421-1427 对旧桶计数递减(与 `_unstage` 同口径),修复 #5 的"跨桶不扣减"半边。
85
+
86
+ ### F2(对应 #2,high)mdcos.py `restore()` 元数据全量透传
87
+ - **修复**:md_cg/mdcos.py:2117-2162。add 显式形参对应的键(edges/semantic/depends_on/时间四元组/believed_at/verification_state/derived_from 等)逐项透传;其余键经 `**_extra` 回写(`_skip` 覆盖 add 全部形参名避免 TypeError);lifecycle_state 仅在 active→该态合法迁移时透传,verification_state 仅合法值透传——脏数据不阻断恢复主流程。
88
+
89
+ ### F3(对应 #7,high)writepipe.py importance=null 崩溃
90
+ - **修复**:md_cg/writepipe.py:474-476。`_imp = a.get("importance")`,`0.5 if _imp is None else float(_imp)`——显式 null 回退默认(与 add 缺省同口径),0/0.0 等合法 falsy 数值照传。
91
+
92
+ ### F4(对应 #19,high)parser/api 语法错误回流
93
+ - **修复**:compiler/parser.py:329(`__init__` 改 `errors if errors is not None else []`,空列表共享不被替换)、parser.py:1089-1091(parse_tokens 同口径)、parser.py:1097-1102(parse_source 经共享列表收集)、compiler/api.py:142-149(compile_source 传共享列表并 extend 进 result.errors)。
94
+ - **配套测试更正**:compiler/tests/test_loop_compile.py:109-116——用例⑧源码本含真实语法错误(L4 步骤号 `2。` 的 NUMBER 开头),旧断言 11/11 通过依赖的正是吞错假成功;改为"编译失败且错误可见"断言,待步骤号语法支持补齐后可还原执行断言。
95
+
96
+ ### F5(对应 #20,high)codegen 指令非法输出 + main() 未定义
97
+ - **修复**:compiler/codegen.py:358-362(指令改单行"代码 + 行内注释"`{code} # {instr_name}`,代码成为真语句);codegen.py:280-283(footer 改调真实存在的 `protocol_procedure()`)。
98
+
99
+ ### F6(清单外,high 同族)codegen 行协议系统性修复
100
+ 修复 #20 时暴露的同族潜伏缺陷,一并落盘(均不在候选清单内,本会话经 diff 验证):
101
+ - codegen.py:458-468:`_writeln` 行尾补 `\n` 终结——旧行不带 `\n`,后续 `_write` 会拼进前一行尾部(如 `... # 道` + `if 条件:` 拼成一行),产物必坏;
102
+ - codegen.py:112:`generate()` 由 `"\n".join` 改 `"".join`(行已自带 `\n`,旧法叠双空行);
103
+ - codegen.py:315-318:if 冒号改 `_write(":\n")`(旧 `_writeln(":")` 另起一行生成 `if 条件\n:` 两行,compile() 必败);
104
+ - codegen.py:367-369:赋值行改 `_write("\n")` 显式终结(旧 `_writeln("")` 只追加空行终结不了本行);
105
+ - codegen.py:374-390 与 450-456:新增 `_ensure_block_body`——def/if 块体只含注释时补 `pass` 占位(否则 compile() 抛 expected an indented block)。
106
+
107
+ ---
108
+
109
+ ## 四、遗留项(确认未修复,21 项 + 1 项部分修复)
110
+
111
+ 按模块分组,供后续批次排期:
112
+
113
+ | 模块 | 数量 | 编号(严重度) |
114
+ |------|------|----------------|
115
+ | md_cg | 5 + 1 部分 | #3 _read 越界读(medium)、#4 propose 层校验分裂(medium,已留复现脚本 `_repro_verify_3536.py`)、#6 audit sys NameError(high)、#8 trust 审计时间戳(medium)、#9 propagate 帽穿透(low);#5 _stage 桶计数(low,同桶半边遗留) |
116
+ | hive | 4 | #10 poll 越权读(medium)、#11 snapshot 路径穿越删目录(medium)、#12 exec_cmd 文档矛盾(low)、#13 _spawn 死分支(low) |
117
+ | scripts | 4 | #14 verify_discipline 退出码契约(medium)、#15 孤儿段死代码(low)、#16 render 往返不对称(low)、#17 cogmap 自检正则矛盾(low) |
118
+ | compiler | 3 | #18 parse 双推进吞语句(high)、#21 api NodeType NameError(medium)、#22 _INST_STOP 缺语句关键字(medium) |
119
+ | swarm | 5 | #23 WAL 坏尾崩溃(medium)、#24 condition_space 丢弃(medium)、#25 report_path 指针错位(medium)、#26 build_rust_exe 路径(low)、#27 聚合数值分歧(low) |
120
+
121
+ 合计 21 项整 + #5 部分修复(md_cg 5 整 + hive 4 + scripts 4 + compiler 3 + swarm 5 = 21),与第二节状态列一致。
122
+
123
+ 优先级建议:#18(high,静默吞语句)与 #6(high,功能整体不可用)为下一批首选;#3/#4/#11(安全边界三项)紧随;#21 修复成本极低(补一个导入)。
124
+
125
+ ---
126
+
127
+ ## 五、跳过项及原因
128
+
129
+ **无(跳过 = 0)**。本轮无任何确认缺陷被主动跳过;全部 27 项要么已修复(5 项)要么列入遗留清单(21 项 + #5 部分)。
130
+ 另:候选 29 与确认 27 之间的 2 项差值为复核阶段未获确认的候选,非"确认后跳过",明细未随任务输入提供,本报告不虚构展开。
131
+
132
+ ---
133
+
134
+ ## 六、测试验证结果
135
+
136
+ 以下命令均为本会话实际运行(Windows,仓库根目录),非转述:
137
+
138
+ | 命令 | 结果 | 退出码 |
139
+ |------|------|--------|
140
+ | `python compiler/tests/test_loop_compile.py` | 11/11 通过(含改写后的用例⑧"含语法错误源码如实报错") | 0 |
141
+ | `python compiler/tests/test_c4_tooling.py` | 8/8 通过 | 0 |
142
+ | `python compiler/tests/test_compiler_c2.py` | 12/12 通过 | 0 |
143
+ | `python compiler/tests/test_condition_vm.py` | 13/13 通过 | 0 |
144
+ | `python compiler/tests/test_func_compile.py` | 10/10 通过 | 0 |
145
+ | `python compiler/tests/test_full_pipeline.py` | 全部通过("协议编译器 v0.2 就绪") | 0 |
146
+ | `python compiler/tests/test_pbc.py` | 5/5 通过 | 0 |
147
+ | `python compiler/tests/test_defect_regression.py` | 18/18 通过 | 0 |
148
+ | `python _repro_verify_3536.py`(只读复现,非测试) | 缺陷 #4 仍复现:S1 误拒 / S2 落盘 layer='knowledge' / S3 accept 拒绝 | —(复现脚本) |
149
+
150
+ **合计**:compiler 侧 8 套 77+ 用例全绿,与任务输入"测试通过"一致。
151
+
152
+ **未运行项(如实说明)**:md_cg 无独立测试目录(`md_cg/tests` 不存在),md_cg 三处修复(F1/F2/F3)本会话未跑专属回归套件——其正确性证据限于 diff 审读 + 上述 compiler 全绿不受影响;F2 的 restore 元数据透传建议后续批次补一条"restore 后字段保全"回归用例。
153
+
154
+ ---
155
+
156
+ *报告依据:任务输入的缺陷清单与统计数据(候选 29/确认 27/修复 6/跳过 0/测试通过);本会话的 `git diff` 工作树核对、现行代码读取复核、`_repro_verify_3536.py` 复现运行,以及 compiler/tests 全套 8 件实测。*