@furongjun1999/dsh-memory 0.5.1 → 0.6.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 (187) hide show
  1. package/README.md +588 -552
  2. package/codebuddy/CODEBUDDY.md +10 -10
  3. package/data/policy.json +27 -0
  4. package/docs/discipline/harnesses.yaml +31 -0
  5. package/docs/discipline/templates/full.md.tmpl +1 -1
  6. package/docs/discipline/templates/rules.mdc.tmpl +1 -1
  7. package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225v2_/345/217/202/350/200/203dsh-TUI_v1.0.md +248 -0
  8. package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225/346/225/210/346/236/234/351/252/214/350/257/201_v1.0.md +209 -0
  9. package/docs/eval/DSH/347/253/257/347/274/272/351/231/267/344/270/223/351/241/271_v1.0.md +254 -0
  10. package/docs/eval/N225_/347/264/242/345/274/225/346/227/245/345/277/227/351/235/236/345/257/271/350/261/241/350/243/205/350/275/275/351/235/242/347/261/273/345/236/213/351/227/270_v1.0.md +418 -0
  11. package/docs/eval/P1b2_/350/257/273/351/235/242/344/273/243/351/231/205/344/277/256/345/244/215_v1.0.md +124 -0
  12. package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/344/270/216/351/224/256/347/261/273/345/236/213/351/227/270_v1.1.md +441 -0
  13. package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/345/212/240/350/275/275/344/270/216/345/207/255/346/215/256/346/230/216/346/226/207/351/230/237/345/210/227_v1.0.md +398 -0
  14. package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/200/346/211/271_/346/216/245/347/272/277/344/270/216/347/255/211/344/273/267/345/217/230/346/215/242_v1.0.md +498 -0
  15. package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/211/346/211/271_/351/227/250/347/246/201/350/275/254/346/255/243/344/270/216/350/260/203/345/272/246/346/255/242/350/241/200/344/270/216/351/227/250/346/216/247/346/224/266/345/217/243_v1.0.md +669 -0
  16. package/docs/eval//344/274/230/345/214/226/347/254/254/344/272/214/346/211/271_/344/276/235/350/265/226/351/200/217/344/274/240/344/270/216/345/257/271/346/213/215/345/217/243/345/276/204/344/270/216/350/264/237/347/274/223/345/255/230_v1.0.md +683 -0
  17. package/docs/eval//345/217/221/345/270/20306_/344/270/200/351/224/256/351/205/215/347/275/256/344/270/216DSH0172_v1.0.md +171 -0
  18. package/docs/eval//345/217/221/345/270/20307_/345/244/226/351/203/250/346/212/245/345/221/212/345/233/233/346/211/271/344/277/256/345/244/215/344/270/216/346/217/222/344/273/266/351/235/242/345/212/240/345/233/272_v1.0.md +205 -0
  19. package/docs/eval//346/200/247/350/203/275/344/270/223/351/241/271_/345/206/267/346/237/245/350/257/242/344/270/216/345/206/205/345/255/230_v1.0.md +218 -0
  20. package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +10 -0
  21. package/docs/eval//347/274/226/347/240/201/351/235/242/345/211/215/347/275/256_/345/205/245/345/217/243/350/207/252/344/277/235/350/257/201UTF8/344/270/216/346/226/207/346/234/254open/345/256/210/345/215/253_v1.0.md +646 -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_v18.md +183 -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_v19.md +207 -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_v20.md +283 -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_v21.md +224 -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_v22.md +223 -0
  27. 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_v23.md +293 -0
  28. 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_v24.md +303 -0
  29. 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_v25.md +230 -0
  30. package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +20 -0
  31. package/docs/hive//350/234/202/345/267/242M6_ingest/345/256/236/346/226/275/350/256/241/345/210/222_v0.1.md +1 -1
  32. package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +12 -0
  33. 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
  34. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +21 -9
  35. package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +7 -2
  36. package/docs/mdcg//350/256/244/347/237/245/345/233/276_/347/264/242/345/274/225/344/270/216/345/267/245/347/250/213/350/247/204/350/214/203/345/214/226_/350/256/241/345/210/222_v0.1.md +39 -3
  37. package/docs/plans//345/205/250/344/270/255/346/226/207/347/274/226/347/240/201/344/270/216/350/234/202/345/267/242/344/273/273/345/212/241/346/240/207/350/257/206/345/245/221/347/272/246_v2.0.md +220 -0
  38. package/docs/plans//347/234/237/346/272/220/347/264/242/345/274/225_/351/200/232/347/224/250/346/234/272/345/210/266_v0.3.md +227 -0
  39. package/docs/plans//350/234/202/345/267/242/346/250/241/345/236/213/345/257/206/351/222/245/351/205/215/347/275/256/351/235/242_v1.0.md +385 -0
  40. package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +460 -460
  41. package/dsh/cordis-patch-profile-web.example.yml +35 -0
  42. package/lib/bridge.js +24 -2
  43. package/lib/cli.d.ts +3 -0
  44. package/lib/cli.js +66 -0
  45. package/lib/hooks.d.ts +31 -2
  46. package/lib/hooks.js +219 -16
  47. package/lib/init.d.ts +88 -0
  48. package/lib/init.js +302 -0
  49. package/lib/lib/prompt_safety.d.ts +52 -1
  50. package/lib/lib/prompt_safety.js +76 -1
  51. package/md_cg/audit.py +652 -379
  52. package/md_cg/bench6_arms.py +1 -1
  53. package/md_cg/bench_p0.py +1 -1
  54. package/md_cg/branches.py +2 -2
  55. package/md_cg/ccgc.py +1071 -1006
  56. package/md_cg/chain.py +1 -1
  57. package/md_cg/consistency.py +97 -9
  58. package/md_cg/consolidate.py +34 -9
  59. package/md_cg/crypto.py +59 -26
  60. package/md_cg/docindex.py +16 -1
  61. package/md_cg/evidence.py +585 -582
  62. package/md_cg/evolution.py +17 -1
  63. package/md_cg/export.py +1 -1
  64. package/md_cg/forgetting.py +309 -13
  65. package/md_cg/fsutil.py +454 -8
  66. package/md_cg/identity.py +3 -3
  67. package/md_cg/insight.py +24 -3
  68. package/md_cg/linkref.py +1 -1
  69. package/md_cg/logref.py +327 -0
  70. package/md_cg/mcp_server.py +4152 -3818
  71. package/md_cg/mdcg.py +4208 -3462
  72. package/md_cg/mdcos.py +4491 -4137
  73. package/md_cg/mreview/pipeline.py +15 -1
  74. package/md_cg/nodefile.py +639 -575
  75. package/md_cg/protect.py +158 -11
  76. package/md_cg/protocol.py +41 -2
  77. package/md_cg/provenance.py +22 -4
  78. package/md_cg/reach.py +4 -4
  79. package/md_cg/readcache.py +76 -15
  80. package/md_cg/reconcile.py +1 -1
  81. package/md_cg/refindex.py +246 -37
  82. package/md_cg/refine.py +1 -1
  83. package/md_cg/review_cli.py +49 -4
  84. package/md_cg/routing.py +32 -5
  85. package/md_cg/run_tests.py +17 -0
  86. package/md_cg/scrub.py +30 -3
  87. package/md_cg/security.py +47 -1
  88. package/md_cg/self_state.py +5 -5
  89. package/md_cg/sources.py +23 -6
  90. package/md_cg/srcindex.py +352 -0
  91. package/md_cg/stg.py +47 -3
  92. package/md_cg/subgraph.py +2 -2
  93. package/md_cg/sustain.py +1299 -1168
  94. package/md_cg/tasks.py +469 -470
  95. package/md_cg/test_b1_auto_id_multiproc.py +277 -0
  96. package/md_cg/test_b1b2_write_face.py +417 -0
  97. package/md_cg/test_b2_sensitivity_landing.py +223 -0
  98. package/md_cg/test_b3_merge_keeps_content.py +576 -0
  99. package/md_cg/test_b4_shard_dir_selfheal.py +843 -0
  100. package/md_cg/test_b4_shard_dir_selfheal_guard.py +238 -0
  101. package/md_cg/test_c3_transient_read_negative.py +793 -0
  102. package/md_cg/test_c8_search_rrf_gates.py +502 -0
  103. package/md_cg/test_ccg_form_parity.py +188 -0
  104. package/md_cg/test_ccgc.py +28 -3
  105. package/md_cg/test_govern_directread.py +17 -4
  106. package/md_cg/test_h2_session_view_norm.py +233 -0
  107. package/md_cg/test_h4_sustain_snapshot.py +1377 -0
  108. package/md_cg/test_hive_ingest.py +285 -285
  109. package/md_cg/test_index_crossprocess_reload.py +301 -0
  110. package/md_cg/test_issue39_utf8_stdio.py +307 -16
  111. package/md_cg/test_issue43_default_policy.py +865 -0
  112. package/md_cg/test_legacy_p3_node_id_type.py +375 -0
  113. package/md_cg/test_linkref.py +10 -3
  114. package/md_cg/test_lock.py +2 -2
  115. package/md_cg/test_logref.py +1109 -0
  116. package/md_cg/test_m3_h9_bucket_health_protect_mark.py +301 -0
  117. package/md_cg/test_m3_h9_semantic_guard.py +525 -0
  118. package/md_cg/test_mr_m2.py +15 -3
  119. package/md_cg/test_n130_verify_falsified_protect.py +1 -1
  120. package/md_cg/test_n139_dek_provision_failclosed.py +185 -0
  121. package/md_cg/test_n176_link_trust.py +221 -0
  122. package/md_cg/test_n178_units_jobid_gate.py +212 -0
  123. package/md_cg/test_n184_keys_concurrent_provision.py +307 -0
  124. package/md_cg/test_n195_writepath_reload.py +283 -0
  125. package/md_cg/test_n196_stale_gate_skip.py +169 -0
  126. package/md_cg/test_n197_n208_write_face_gates.py +471 -0
  127. package/md_cg/test_n198_tokens_corrupt_failclosed.py +225 -0
  128. package/md_cg/test_n199_tokens_concurrent_write.py +378 -0
  129. package/md_cg/test_n201_proposal_visibility.py +382 -0
  130. package/md_cg/test_n202_session_notes_visibility.py +461 -0
  131. package/md_cg/test_n204_n205_n226_n227_n228_n229_exit_gates.py +542 -0
  132. package/md_cg/test_n206_stdio_jsonrpc_type.py +403 -0
  133. package/md_cg/test_n209_verify_write_face_gates.py +461 -0
  134. package/md_cg/test_n212_n213_n224_generation_gates.py +513 -0
  135. package/md_cg/test_n214_n215_n221_n222_write_face_gates.py +563 -0
  136. package/md_cg/test_n225_nonobject_load.py +1110 -0
  137. package/md_cg/test_n62_tenant_bind_failclosed.py +200 -0
  138. package/md_cg/test_neg_condition_hits.py +333 -0
  139. package/md_cg/test_neg_tail_honesty.py +663 -0
  140. package/md_cg/test_none_id_write_guard.py +166 -0
  141. package/md_cg/test_opt_batch1_md_cg.py +451 -0
  142. package/md_cg/test_p1.py +5 -5
  143. package/md_cg/test_p11_consistency.py +161 -12
  144. package/md_cg/test_p26_refindex.py +2 -2
  145. package/md_cg/test_p27_docindex.py +777 -774
  146. package/md_cg/test_p28_refcheck.py +740 -13
  147. package/md_cg/test_p29_session_ingest_export.py +2 -2
  148. package/md_cg/test_p2_mcp.py +12 -1
  149. package/md_cg/test_p30_maintain.py +33 -2
  150. package/md_cg/test_p31_insight.py +1 -0
  151. package/md_cg/test_p9c_dedup_hints.py +276 -0
  152. package/md_cg/test_policy_required_ccg.py +426 -0
  153. package/md_cg/test_protocol.py +22 -0
  154. package/md_cg/test_rank_parity_score_mode.py +516 -0
  155. package/md_cg/test_read_face_input_gates.py +363 -0
  156. package/md_cg/test_read_face_semantics.py +489 -0
  157. package/md_cg/test_recall_face_guards.py +812 -0
  158. package/md_cg/test_rejected_credential_forms.py +188 -0
  159. package/md_cg/test_rejected_redact.py +146 -0
  160. package/md_cg/test_retr_s1b.py +2 -2
  161. package/md_cg/test_retr_s5.py +20 -7
  162. package/md_cg/test_review_cli_attribution.py +177 -0
  163. package/md_cg/test_review_cli_visibility.py +235 -0
  164. package/md_cg/test_review_conformance.py +21 -3
  165. package/md_cg/test_security_audit_v21.py +2 -2
  166. package/md_cg/test_server_version.py +67 -0
  167. package/md_cg/test_srcindex.py +171 -0
  168. package/md_cg/test_tenant_env_override_warn.py +63 -50
  169. package/md_cg/test_token_lowercase_form.py +315 -0
  170. package/md_cg/test_v21r1_package_version.py +310 -0
  171. package/md_cg/test_writepipe.py +10 -4
  172. package/md_cg/tokens.py +225 -95
  173. package/md_cg/tool_face.py +4 -4
  174. package/md_cg/trust.py +49 -5
  175. package/md_cg/units.py +204 -6
  176. package/md_cg/weights.py +4 -4
  177. package/md_cg/whitebox_kb/wisdom/knowledge_points.py +1 -1
  178. package/md_cg/writelimit.py +42 -8
  179. package/md_cg/writepipe.py +651 -554
  180. package/package.json +8 -2
  181. package/skills/plugin.json +1 -1
  182. package/src/bridge.ts +25 -2
  183. package/src/cli.ts +65 -0
  184. package/src/hooks.ts +229 -16
  185. package/src/init.ts +361 -0
  186. package/src/lib/prompt_safety.ts +88 -1
  187. package/zcode/AGENTS.md +10 -10
@@ -0,0 +1,293 @@
1
+ # 缺陷挖掘·自主迭代 第 24 轮报告(md_cg 核心面·三圈第九站)
2
+
3
+ > **元信息**:第 24 轮 = md_cg 核心面深挖·三圈第九站(承接 v22 = 第 23 轮 hive 四轮深挖·三圈第八站〔编号用至 N194〕);落盘文件名 `缺陷挖掘_自主迭代_v23.md` 为编排指定(v22 之后顺延)。基线 HEAD `3069d14b`(第 23 轮落码提交,批次 65);本轮修复落工作区未提交(提交由编排会话负责)。日期 2026-09-28。
4
+ > **报告会话核验口径**:编号基线扫描(docs/eval 系列 + 源码树占号)、6 件新守卫逐件复跑、`python -X utf8 -m md_cg.run_tests` 全量、hive/rust 两 crate `cargo test`、`npm run gate` 逐面归因,均由本报告会话**第一手实跑**(命令与输出见第四节);四区攻防复现与修复红绿双态(git stash 双态)为复核/修复会话第一手实测(材料附命令与输出),本报告如实转述并逐项标注归属;凡本会话未跑的检查,文中一律标注来源(第七节集中列出跳过项)。
5
+
6
+ ---
7
+
8
+ ## 一、执行摘要
9
+
10
+ 本轮为**四区复核(core / legacy / retrieval / surface)+ 五批次修复落闸**的 md_cg 核心面轮:
11
+
12
+ - **四区确认 23 条目**(core 6 / legacy 7 / retrieval 6 / surface 4)→ 去重后 **27 项独立缺陷**(其中含 1 条**已修复核记录** N184〔非缺陷,链条复测维持〕、1 处 **N178 跨区重复报告**〔legacy 区与 retrieval 区各一次,同一缺陷〕)。**证伪·剔除 3 条**(见 3.3)。
13
+ - **修复 7 项(落 5 个修复批次,工作区未 commit)**〔口径说明:编排材料记「修复 5 项」为**修复批次**数;本报告按**缺陷粒度**计 7 项,即 N195 / N196 / N198 / legacy P3 / N178 / v21-R1 / N191——其中 N195 与 N196 同根、同批落码,N178 与 v21-R1 同批落码〕:
14
+ - **3 项 new high/medium**:**N195**(写/删路径无代际感知 → anchor/self 不可覆盖闸跨进程静默失效,覆写无痕不可恢复)、**N198**(令牌库损坏静默回落 + 整份写回 → 全库凭据无痕注销)、**N196**(索引缺条目即跳过闸判定 → 读隔离与 N130 层写闸双面失效;修复期读码+实测新发现,与 N195 同根)。
15
+ - **4 项 legacy 欠账闭合**:**legacy P3**(非字符串 node_id 混型索引键 → 整库永久打不开,首修)、**N178**(units.poll job_id 裸拼路径越池读,v21 留档)、**v21-R1**(`_package_version` 顶层非对象即 import 期崩,v21 留档)、**N191**(claim 与状态改写间崩溃窗致任务永久卡 pending,v22 留档·次轮首补候选)。
16
+ - **留档 15 条目 = 21 项在档缺陷**(新未修 11:N197 / N199–N208 + legacy 未修 10:N68 / N177 / A1-e / N90 / N91 / N186 / N187 / N188 / N192 / N193)。其中 **3 项大设计决策**(N200 执行器密钥面、N68 mdcg_root 去留、N203 日志节点 id 口径)、**3 项次轮首补候选**(N199 令牌库并发写、N202 会话要点 restricted 泄漏、N206 stdio 主循环入口兜底——均为「高危低风险、修复面明确」)。
17
+ - **编号裁定(本轮核心工程事实)**:复核面把 ccgc recalibrate 条编为 N196,而修复面已把 N196 **树内实占**(`md_cg/mdcos.py` 注释 + 守卫文件名 `md_cg/test_n196_stale_gate_skip.py`)。按 v22 3.0-② 先例(守卫文件名实占优先),维持 **N196 = stale 闸跳过条**,ccgc 免闸条**重编 N208**;N195–N208 全局唯一经本会话扫描核对,**次轮自 N209 续编**(3.0)。
18
+ - **门禁**:python 全量回归 **234/234 通过、3 跳过、退出码 0**(本会话第一手实跑;**较上轮 228 增加 6 件新守卫且既有失败已闭合**);hive `cargo test` **50/50 退出码 0**、rust `cargo test` **16/16 退出码 0**(本会话第一手实跑,树外临时 target 构建,未触碰在役 serve 持有的仓内二进制);**`npm run gate` → VERDICT=FAIL、退出码 1**:内容面 R1(凭据)/R2(私有数据)/R3(隐私文本)**全 PASS**,唯一 FAIL 为 **R4 非追踪件面 命中=7**(本轮 6 件新守卫 + 本报告未入库,`&&` 短路于该检查器);本会话**逐条补跑**其后的四检查器:`link_check`/`workspace_index --check`/`verify_discipline --allow-missing` 全绿,**`cogmap_sync check` 红**(本轮 `md_cg/mcp_server.py` +15 行致 `docs/mdcg/功能调用映射表_v0.1.md` 行号漂移,需 `python scripts/cogmap_sync.py build` 重挂;详见第四节-5 与第五节第 23 项)。
19
+ - **纪律**:全部攻防复现在系统临时目录/哑令牌/哑密钥环境,未触真实令牌库/真实在役 serve/在役数据目录;测毕清理(第六节)。
20
+
21
+ ---
22
+
23
+ ## 二、修复清单(7 项缺陷,5 个修复批次;落工作区未 commit)
24
+
25
+ ### 修复① N195(high,new):写/删路径无索引代际感知——「不可覆盖」闸跨进程静默失效
26
+
27
+ - **where**:`md_cg/mdcg.py:1508`(`MdCG.add` 内 `protect.guard_write` 调用点之前新增 `self._maybe_reload_index()`)|`md_cg/mdcos.py:2355`(`MdCGOS.forget` 内在 `self.index` 直读之前)——被修正的判定链:`md_cg/protect.py:57-58`(`_entry` 只读 `cg.index`)、`md_cg/mdcg.py:1607`(`prev_entry` 取 `self.index`)。**本会话读码核实**:`_maybe_reload_index` 现全仓调用点=读面 5 处(`md_cg/mdcg.py:2164/:2429/:2633`、`md_cg/mdcos.py:767/:1315`)+写/删面 2 处(`md_cg/mdcg.py:1508`、`md_cg/mdcos.py:2355`)+get 未命中面(`md_cg/mdcos.py:4049`)+verify 面(`md_cg/mdcos.py:3896`)+maintain 显式动作(`md_cg/mdcos.py:2759`)。
28
+ - **缺陷面**:`_maybe_reload_index`(`md_cg/mdcg.py:1038`)此前只在读路径接线,写路径(`add`)与删除路径(`forget`)全程直读本进程内存索引:他进程(serve 常驻之外的 review_cli / hive worker / 脚本写方——即 P1b-2 所针对的同一多进程共享库形态)刚写入并 compact 的 self·anchor 节点在本进程索引中**不存在** → `protect.guard_write` 的 is_immutable 判定得 None → 判 False → 闸静默失效:覆写不抛 `ProtectionError`、不落 `_protected_history` 快照、不写 `_protected_audit.jsonl`,旧正文被无痕覆写且不可恢复;删除面同根(他进程新建节点恒 `not_found`,静默无操作)。同一次重载同时修正 `prev_entry` 的继承面(他进程已置 converged 的节点被覆写后不再静默打回 active)。
29
+ - **修复(最小改动 4 处,判定入口 `protect.py` 未动、接线留在调用点)**:①`md_cg/mdcg.py:1508` 写面代际感知;②`md_cg/mdcos.py:2355` 删除面代际感知;③`md_cg/mdcos.py:4049` `MdCGSecure.get` 索引未命中时先探活重载再判可见性(命中路径零变化,成本只在未命中路径一次 stat);④`md_cg/mdcos.py:3896` `MdCGSecure.verify` falsified 分支前置重载,N130 层写闸不再因索引缺条目被跳过。自身未 flush 的写入由 `_maybe_reload_index` 的 `_dirty` 重放保住(与读路径同款语义);签名未变时只一次 stat。
30
+ - **攻防前后对比(修复会话第一手,临时库 + 哑主密钥)**:
31
+ - 覆写面——常驻 A 建库 → 独立 B 写 `layer="anchor"` 节点后 close(compact 落快照)→ A 未发生任何读面调用时 `add` 同 id:**修前** A.add 成功(无 `ProtectionError`),盘上正文变为「被覆写的伪造内容」,`_protected_history` 目录与 `_protected_audit.jsonl` 均不存在(旧正文不可恢复且无痕);**修后** 抛 `ProtectionError('节点 … 受写保护(层保护:anchor(不可篡改层));覆盖需显式 override=True')`,盘上正文保持 B 原文,`override=True` 时快照落 `_protected_history/<node>/` 且审计记 override_write。
32
+ - 删除面——**修前** A.forget 返回 `{'ok': False, 'error': 'not_found'}`(静默无操作)且盘上文件仍在;**修后** 先抛 `ProtectionError`(不可遗忘),`override=True` 后文件仅存于 `trash/`。
33
+ - 继承面——他进程置 `lifecycle_state=converged` 的 knowledge 节点被覆写后不再被打回 active。
34
+ - **守卫**:`md_cg/test_n195_writepath_reload.py`(20 断言):接线自证(写路径经签名探测 ≥1 次)+覆写被拒+盘面正文保持+快照/审计落痕+override 正常路径+删除面同构+converged 继承+**反向腿防过度收紧**(同 session 可读、真不存在节点仍走原语义)+**自重载防线**(自身 3 次 add+flush 触发重载 0 次,防「写一次触发一次全量重载」的性能回退)。环境:`tempfile.mkdtemp` 临时库 + 哑主密钥,finally 清理。
35
+ - **红→绿(材料第一手,git stash 双态)**:`python -X utf8 -m md_cg.test_n195_writepath_reload` 修前 PASS=9 FAIL=11(失败项含「写路径 add 经签名探测 0 次」「A.add 未被 ProtectionError 拒绝」「盘上正文已被覆写」「A.forget 返回 not_found」「无保护历史/无保护审计」「converged 被打回 active」)→ 修后 **PASS=20 FAIL=0**。
36
+
37
+ ### 修复② N196(medium,new):索引缺条目即跳过闸判定——读隔离与层写闸双面失效(与 N195 同根)
38
+
39
+ - **where**:`md_cg/mdcos.py:4049`(`MdCGSecure.get`)|`md_cg/mdcos.py:3896`(`MdCGSecure.verify` falsified 分支)。**编号**:本条即 3.0 裁定的「树内实占 N196」;修复会话自编 N196,本报告维持。
40
+ - **缺陷面**:①读隔离——`get` 先读 `self.index["nodes"].get(node_id)`,**缺条目即整段跳过 `_readable`**(`super().get` 内部才重载);他进程(同 actor、异 session)刚写入并 compact 的 private(会话绑定档)节点在常驻实例**首次** get 即被解出,第二次读才归 None(此时条目已随重载进索引)——「不可见即不存在」单点口径被首次读击穿。②授权——`verify(verdict="falsified")` 的 N130 层写闸只在「索引中有该条目」时执行;他进程刚写入的 knowledge 层节点在常驻 verifier 实例索引中不存在 → 闸整段跳过 → verifier(`layers_allow=('rejected','contextual')`)可 falsified 删掉 knowledge 层节点,盘上原文消失。
41
+ - **修复**:两处均在闸判定前先 `_maybe_reload_index()`——「本进程陈旧」与「节点真不存在」两态由此可区分;真不存在时 not_found / None 语义不变(fail-closed,未改成无条件拒绝)。成本只在未命中路径(一次 stat)。
42
+ - **攻防前后对比(修复会话第一手,临时库 + 哑主密钥)**:①常驻 A(actor=X, session=S1, can_admin=False) + 独立写方 B(同 actor X, session=S2) 写 `sensitivity=private` 节点后 close:**修前** A.get 首读即解出 S2 的 private 正文(第二读才归 None);**修后** 首读即 None,且**同 session 实例仍可读**(反向腿,未过度收紧),search 面一致不可见。②常驻 V(role=verifier, `layers_allow=('rejected','contextual')`) + 独立写方 W 写 knowledge 层节点后 close:**修前** V.verify(verdict=falsified) 正常返回(N130 闸被跳过),knowledge 层残留空、原文被替换为 rejected 层节点;**修后** 抛 `AccessDenied('角色 verifier 无权写入 knowledge 层(可写层 [...])')`,原文保留;真不存在节点仍走 not_found 透传。
43
+ - **守卫**:`md_cg/test_n196_stale_gate_skip.py`(10 断言):读隔离含**首次读即拒**+同 session 可读反向腿;授权含 AccessDenied+原文保留+真不存在节点语义不变。红态由 `git stash push -- md_cg/mdcg.py md_cg/mdcos.py` 后复跑取得(诚实标注:本条修复先于守卫落码,红态为 stash 复跑,stash pop 已还原),**修前 PASS=7 FAIL=3 → 修后 PASS=10 FAIL=0**。
44
+ - **本会话复跑**:`python -X utf8 -m md_cg.test_n196_stale_gate_skip` → **PASS=10 FAIL=0,rc=0**。
45
+
46
+ ### 修复③ N198(high,new):令牌库损坏静默回落 + 整份写回——全库凭据无痕注销
47
+
48
+ - **where**:`md_cg/tokens.py:287-311`(新增判据生产者 `_load_raw`)|`:315-325`(`_load` 消费并告警)|`:329-350`(`_save` 写前对账闸)。写点唯一出口 `_save`,调用点 `issue`(:383-386 区)、`derive`、`revoke` 共用。对照面 `md_cg/crypto.py:265-284`(N139 置 load_error + stderr)/`:288-301`(`_save_keys` 写前对账)/`:318-325`(provision_dek 拒签)。
49
+ - **缺陷面**:`_load` 对不可解析/不可读/顶层非对象的令牌库**静默**回落空表(无 stderr 告警、无损坏标记),而 issue/derive/revoke 是「读→改→整份写回」:一次签发就把「空表 + 新记录」覆盖写回,盘上全部既有令牌记录被**永久抹除且零告警**,旧令牌此后一律验签失败,使用者仅见「令牌不存在(可能已吊销或来自其他令牌文件)」。同型 `crypto/_keys.json` 在 N139 已 fail-closed,令牌库未同步——凭据面仅此一处仍是「损坏 → 静默清空 → 覆盖」。
50
+ - **修复(最小改动,只动 `md_cg/tokens.py`,读面语义零变化)**:①`_load_raw(p)` 把「可解析性」抽成**单一判据生产者**,返回 `(快照, 损坏描述)`(不存在 → 空骨架+None;可解析且 tokens 为映射 → 快照+None;解析抛 OSError/ValueError、顶层非 dict、tokens 非映射 → 空骨架+err);②`_load` 有 err 时向 stderr 写告警并返回带 `load_error` 标记的空结构——**读面行为不变**(仍回落空表、verify 仍 TokenError),但「零告警」不再成立;③`_save` 加写前对账:盘面不可解析**或**本次 data 带 load_error → 抛 `TokenError` 拒绝整份写回;`_save` 是 issue/derive/revoke 唯一共用出口,一行闸三面同时收口。
51
+ - **攻防前后对比(修复会话第一手 + 本会话复跑守卫)**:CLI 端到端——签发 2 枚 → 文件截断为非法 JSON → `python -X utf8 -m md_cg.tokens --token-file <临时> issue --role record --actor c`:**修前** 输出 `ok=true`、EXIT=0、**stderr 空**,随后盘上 token 记录数 = **1**(既有 2 条被永久抹除且零告警);**修后** 输出双行告警(含损坏描述与路径)、EXIT=2、盘面仍为损坏原文(未被覆盖)。库层守卫:损坏时 verify 仍 TokenError(fail-closed 不变)+stderr 开口;顶层数组 `[]` 修前静默清空、`{"tokens": []}` 修前 `TypeError` 崩(同样无闸),修后两者均 TokenError 且盘面不变。
52
+ - **守卫**:`md_cg/test_n198_tokens_corrupt_failclosed.py`(23 断言):①截断→verify 仍拒+stderr 开口→issue 必须拒写且盘面不变;②顶层数组 / tokens 非映射同拒且盘面不变;③`_save` 单点拒写(issue/derive/revoke 共用出口)+ derive/revoke 盘面不变回归钉;④盘面恢复后旧令牌重新可用、签发恢复(**非永久拒签**);⑤缺文件(fresh install)零告警不误伤;⑥合法库全流程零告警不误报。**修前 PASS=12 FAIL=11 → 修后 PASS=23 FAIL=0**(材料第一手)。
53
+ - **本会话复跑**:`python -X utf8 -m md_cg.test_n198_tokens_corrupt_failclosed` → **PASS=23 FAIL=0,rc=0**。
54
+ - **已知残余(如实声明)**:损坏库上每次 `_load` 都写一行 stderr(含每请求 verify 的读面)——与 N139 `_load_keys` 同款口径(告警必须开口、不静默),非本次引入的新行为模式。**本条不覆盖并发写面**:`_save` 仍用固定共享临时名(见留档 N199)。
55
+
56
+ ### 修复④ legacy P3(high,首修):非字符串 node_id 混型索引键——整库永久打不开
57
+
58
+ - **where**:`md_cg/mdcg.py:1474-1480`(`add` 白名单校验前新增 `if not isinstance(node_id, str): raise ValueError(...)`;本会话读码核实)|派生面 `md_cg/mdcg.py:1325`(`_scan_nodes` 的 `nid = str(nid)` 归一)、`:1006`(`_load_index` 日志重放)、`:1148`(`compact_index` 的 `_apply_log`);崩点面 `md_cg/mdcg.py:1338`(`return {k: nodes[k] for k in sorted(nodes)}`)|MCP 入口 `md_cg/mcp_server.py:3090`(未变,直传原始 node_id)。
59
+ - **缺陷面**:MCP 工具面 schema 声明 node_id 为 string,但 server 不做类型校验,`mdcg_remember({node_id:123})` 原样进 `add()`;`add` 只用 `str(node_id or "")` 做白名单与文件路径,而索引键(`_stage`)、frontmatter `id`、分片日志 `{"id": …}` 仍写**原对象**。此后库内只要另有字符串 id 节点,任何全量重扫都在 `sorted(nodes)` 撞 `TypeError`,崩点在 `MdCGSecure.__init__`(早于启动对账 `reconcile_state`)⇒ **整库永久打不开、无自愈路径**。
60
+ - **修复(最小改动 4 处,两层各司其职)**:①写面 fail-closed——非字符串 node_id 一律拒(`bool` 亦拒:True 是 int 子类且 `str(True)` 会匹配白名单),与既有 `add(None)`/`add("")`/`add(0)` 拒绝同族;②派生面自愈——`_scan_nodes` 从盘面 frontmatter 取 id 时归一为字符串(存量毒文件/外部编辑/新机复制还原的库由此自愈);③④分片日志重放两处(`_load_index` / `_apply_log`)同样归一,旧版本落下的 `{"id": 123}` 不再以 int 键进索引(否则 evidence/reach/trust 等 sorted 消费面同样混型 TypeError)。
61
+ - **攻防前后对比(修复会话第一手 + 本会话复跑守卫)**:**库层**——修前 `add(123)`/`add(True)`/`add(1.5)` 全部成功 → 内存索引键混型(实测打印 `['1.5','123','True']`)→ 紧随的 `close()` 即 `TypeError: '<' not supported between instances of 'str' and 'float'`;修后三者一律 ValueError 拒、索引键全为 str。**存量毒数据三形态**(缺 `_index.json` / 快照在 + 事后落外部 .md / 显式 `rebuild_index`):修前均崩在 `__init__`,修后正常打开且 `get("123")` 能取回毒节点原文(语义未丢)。**分片日志毒**:手写 `{"id": 123}` 记录后重开,修前索引残留 int 键、修后为字符串 `"123"`。**MCP 端到端**(真实 stdio 子进程):`mdcg_remember({node_id:123})` 修前回 `{'ok': True, 'id': 123}` 并落 int id 毒文件,修后回结构化 `error`(ValueError 文本含类型与修法)、**盘面零毒、进程未崩**,随后同根写字符串节点、删快照重开(首会话+任一字符串 id 形态)修前整库打不开、修后正常打开。
62
+ - **守卫**:`md_cg/test_legacy_p3_node_id_type.py`(23 断言):[1] 写面契约(非 str 三形态拒 + falsy 契约不变 + 字符串 `"123"` 不误伤 + close/rebuild 不崩);[2] 存量毒文件两形态自愈;[3] 分片日志 int 键归一;[4] MCP 真实 stdio 端到端(哑令牌 + 哑主密钥 + 临时 root/aux/token 文件);[5] 合法字符串路径不回归。**修前 PASS=9 FAIL=10 → 修后 PASS=23 FAIL=0**;`md_cg/test_none_id_write_guard.py` 的原自注(「add(123) 属相邻缺陷,超出本守卫目标」)本轮更新为指向本修复与守卫(注释级,语义断言未动,`git diff` 实读确认)。
63
+ - **本会话复跑**:`python -X utf8 -m md_cg.test_legacy_p3_node_id_type` → **PASS=23 FAIL=0,rc=0**;`md_cg.test_none_id_write_guard` 在全量套件内 PASS。
64
+
65
+ ### 修复⑤ N178(low,legacy)+ v21-R1(low,legacy):池外路径成分闸 + 包版本回落全形态
66
+
67
+ - **where(N178)**:`md_cg/units.py:277-306`(新增 `_valid_job_id` 结构闸)、`:308-320`(`_bad_job_id` 统一拒答)、`:342-346`(`submit` 落盘前过闸)、`:376-382`(`poll` 入口过闸,替换原 `str(job_id or "")` join)、`:427-432`(`wait` 入口 fail-fast)。**本会话读码核实**上述五处均在位。
68
+ - **where(v21-R1)**:`md_cg/mcp_server.py:54-66`(`_package_version` 全形态回落)+ `:72`(模块级立即求值)|`hive/hive_mcp/mcp_server.py:55-67` + `:73`(同族同源,逐字对齐)。**本会话读码核实**:两处均为「读得 dict 且 version 为 strip() 后非空的 str 才返回,否则回落 `"0.1.0"`」,except 补 `(TypeError, AttributeError)`。
69
+ - **缺陷面(N178)**:`units.poll` 把调用方 job_id 裸拼进路径,`../` 或绝对路径即读池外 `result.json` 正文;`submit` 的 jobs/job_id 一路直通 `makedirs` + 写 spec.json/status.json = 「任意目录 + 生成名」的建目录写文件原语(库层/CLI 可达;MCP `op=ccg action=review` 面不接受调用方 job_id)。**缺陷面(v21-R1)**:except 面只捕 `(OSError, ValueError)`,package.json 为合法 JSON 但顶层非对象时 `json.load(f).get("version")` 抛 AttributeError 逃逸;因该句在 import 期求值,**两个 stdio server 及所有 import 该模块的 CLI 直接崩**,违背「读不到回落保底值不阻塞启动」的书面契约;另 `{"version": 123}` 被原样返回为 int(非字符串版本号进握手)。
70
+ - **修复**:N178——`units.py` 新增单点结构闸 `_valid_job_id`(str、1..128、首尾无空白、首尾非点、字符白名单 `[A-Za-z0-9_.-]`,deny-by-default;非 str 一律拒且**不** str() 归一,与 legacy P3 同纪律),poll/wait/submit 三面接线,submit 在 `makedirs` **之前**拒(不建目录不写文件);口径取舍:**有意不抄** hive 的 `startswith("h")`——`md_cg/test_units_poll.py` 的 `j_empty`/`j_good`/`j_fail` 是既有对外契约,前缀收紧会误杀。v21-R1——两处 `_package_version` 改为「读得 dict 且 version 为 strip() 后非空的 str 才返回」,顶层非对象直接判 None,except 补 TypeError/AttributeError,其余一律回落 `"0.1.0"`。
71
+ - **攻防前后对比(修复会话第一手)**:N178 **修前** `units.poll('../outside', jobs=<临时池>)` → `{'state':'done','ok':True,'content':'SECRET-OUTSIDE'}`(池外全文被读出)、反斜杠与绝对路径形态同、`wait` 同泄漏、`submit` 注入 `_job_id→'../escaped'` → ok=True 且池外 `escaped/spec.json` 被真实建出;**修后** 上述五种一律回 `{'state':'invalid_job_id','ok':False,'content':None,'job_dir':None,'error':'job_id 非法:…'}`,池外文件不存在;合法 id 全放行(`test_units_poll` 7/0 不回归)。v21-R1 **修前** 临时包根 package.json `[1,2]` → 两服务 **import 期即死**(stderr AttributeError,initialize 无响应),`{"version":123}` → SERVER_VERSION=123(int);**修后** 同一包根下两服务均正常起来、initialize 自报 `'0.1.0'`(str),换合法 `{"version":"9.9.9"}` 时自报 `'9.9.9'`(判别力对照),真实仓库包根仍为 `'0.6.0'`。
72
+ - **守卫**:`md_cg/test_n178_units_jobid_gate.py`(41 断言:闸门自洽 + 相对穿越 + 绝对路径 + 拒形态清单 18 组 + 5 组非 str + wait fail-fast〔断言不进轮询〕+ submit 落盘前拒〔注入生成器证明落点无闸〕+ 合法闭环不回归);`md_cg/test_v21r1_package_version.py`(41 断言:16 形态×2 模块真实 import 与 reload 矩阵 + 两服务真实 stdio initialize 握手端到端 + 真实包根版本联动)。红→绿:N178 **修前 PASS=3 FAIL=38 → 修后 PASS=41 FAIL=0**;v21-R1 **修前 PASS=19 FAIL=22 → 修后 PASS=41 FAIL=0**(材料第一手)。
73
+ - **本会话复跑**:`python -X utf8 -m md_cg.test_n178_units_jobid_gate` → **PASS=41 FAIL=0,rc=0**;`python -X utf8 -m md_cg.test_v21r1_package_version` → **PASS=41 FAIL=0,rc=0**。
74
+ - **范围外观察(未修、未编号,建议另开 ask)**:`scripts/check_registry_tarball.py:40-42` 的 `json.load(fh)["version"]` 对顶层非对象抛 TypeError,而其调用方只捕 `(OSError, ValueError, KeyError)` → 发布门禁脚本会裸崩;`scripts/check_publish_artifact.py:256-265` 返回非对象 JSON 由调用方 `.get` 触发 AttributeError——同属「顶层非对象」族,但为 fail-loud 的开发/CI 脚本(材料所载,本会话未复跑)。
75
+
76
+ ### 修复⑥ N191(medium,legacy,v22 首报·第 2 轮落闸):claim 与状态改写间崩溃窗致任务永久卡 pending
77
+
78
+ - **where**:`hive/src/scheduler.rs:251-259`(主循环:`patch_status("claimed")` 失败即删锁回滚并 `continue`,不再吞错投递)|`:312-354`(`recover_orphans` 判据改为 `state=="claimed" || (state=="pending" && claimed.lock 在盘)`,走**既有同一段** `classify_result` 处置,未分叉第二套判据)|守卫 `hive/tests/judgment_surface.rs:482`/`:563`(承重断言 7/8)+ 夹具 `:459`。**本会话读码核实**上述三处在位,且 `hive/tests/judgment_surface.rs` 的 8 件测试在本会话 `cargo test` 中全绿。
79
+ - **缺陷面**:`claim()` 成功(原子锁 create_new)与 `patch_status("claimed")` 之间存在崩溃/失败窗口,失败被 `let _` 静默吞;留下 `state=pending + claimed.lock` 组合态后,`recover_orphans` 只 match claimed/running(pending+锁落 `_ => {}`),主循环对 pending 任务每拍 claim() 必失败即 continue → 任务**永久卡 pending**、下游经 deps_gate 永久 `Ok(false)` 连带悬置,无任何自动恢复路径(doctor 只报计数)。
80
+ - **修复**:①主循环不再吞错——`patch_status` 返回 Err 即删 `claimed.lock` 回滚领取并 continue(本拍不投递,下一拍重试),保证不变量「锁在手 ⇔ 状态已 claimed」;②`recover_orphans` 补残留领取态分支(有产物 → 按产物定终态、绝不重跑;`spec.rerun_on_recover` 时旧产物更名留痕并重投;无产物 → 删锁回 pending 重投);附注释同步(模块头/`serve` 头/`recover_orphans` 头,明写「恢复期假定无活 serve,单实例守卫在 CLI 层」——双 serve 配错场景见留档 N194 的既有假设,未越权改 serve 单实例守卫)。
81
+ - **攻防前后对比(修复会话第一手,临时池 + 假执行器,测毕全删)**:A 类(静态造场等价 kill -9 残留组合态)——**修前** `pending+claimed.lock` 无产物者恒 pending、无任何自动恢复路径(守卫 0.01s 即红);**修后** 删锁重投、真 serve 起来后被重新领取跑到 done;同组合态但已有产物者按 `classify_result`「产物说了算」定 done 且旧产物字节不被覆盖(防双执行)。B 类(活 serve 窗口,`attrib +R status.json` 使 patch_status 恒 Err)——**修前** serve 照旧投递:执行器照常运行,18.13s 后任务目录为 `state="pending" + claimed.lock + result.json {ok:true,content:"ran"}`(状态从未记录却已执行、锁永不释放),解除只读后仍恒 pending;**修后** 只读期间不投递(无 result.json)、锁每拍回滚不留存,盘面恢复可写后下一拍正常领取跑到 done。
82
+ - **守卫红→绿(材料第一手)**:`cargo test --test judgment_surface pending_with_residual_claim_recovers` 修前 FAILED(:512 断言);`claim_rollback_on_status_write_failure` 修前 FAILED(:603,18.13s);修后 `cd hive && cargo test` 全绿,`--test judgment_surface` 8 passed / 0 failed(4.48s)。既有三格 chaos(fi_r02 杀 serve 恢复 / fi_r03 假结果 ok / fi_r07 双 serve 抢锁)经树外构建二进制复跑 verdict=pass、rc=0。
83
+ - **本会话复跑**:hive `cargo test` → 退出码 0,**lib 33/33 + 集成 9/9 + judgment_surface 8/8 = 50/50**(含本条两件守卫与 N189/N190 既有守卫),见第四节。
84
+
85
+ ---
86
+
87
+ ## 三、发现明细
88
+
89
+ ### 3.0 编号裁定(本轮)
90
+
91
+ 1. **基线核对(本报告会话第一手)**:①`docs/eval/缺陷挖掘_自主迭代_v*.md` 全系列扫描,`N\d{3}` 全局最大 **N195**——仅出现在 v22 报告文本「次轮全局自 N195 续编」,**报告面无 N195+ 的既有登记**;②源码树扫描(排除 `.git`/`node_modules`/`target`/`lib`/`__pycache__`/`.zcode`)实测:**N195 实占**=`md_cg/mdcg.py`、`md_cg/mdcos.py` 注释 + `md_cg/test_n195_writepath_reload.py`;**N196 实占**=`md_cg/mdcos.py` 注释 + `md_cg/test_n196_stale_gate_skip.py`;**N197–N208 树内空闲**(唯一同名命中为 `_md_cg_p27` 测试夹具抄录的 v22 报告原文,非占号);N198 实占=`md_cg/tokens.py` + 其守卫。故「新发现自 N195 续编」成立。
92
+ 2. **撞号消歧(本轮唯一冲突)**:复核面把 **ccgc recalibrate 免闸条**编为 **N196**(纯报告面,无代码/守卫实占),而修复面把 **N196 树内实占**(`md_cg/test_n196_stale_gate_skip.py` + 两处代码注释,且修复材料自述「按新缺陷自 N195 续编自编 N196」)。裁定:**按 v22 3.0-② 先例(守卫文件名实占优先)维持 N196 = stale 闸跳过条,ccgc 条重编 N208**。N195–N208 全局唯一(本会话扫描核对),**次轮自 N209 续编**。
93
+ 3. **其余裁定沿分诊材料,理由实证**:hive 面源暂编 N195(执行器密钥面)与 core 面 N195 撞号 → 重编 **N200**;surface 面两条源暂编 N195/N196(stdio 主循环 / isMainEntry)分别撞 core 面 N195/N196 → 重编 **N206 / N207**;retrieval 面五条(源清单未编号)新编 **N201–N205**。分诊对 N199(令牌库并发写)维持原复核号。
94
+ 4. **残留注记(如实声明,未代改代码)**:本轮新增守卫文件名与代码注释均按 N195/N196/N198 落码,与本裁定一致,无需归一;复核面材料中的「N196 = ccgc」字样按本裁定应读作 **N208**(纯报告面编号,无树内残留)。另:v22 遗留的第 23 轮编号残留(`hive/src/exec.rs`/`keyres.rs` 注释与夹具哑值字样「N185」按 v22 裁定应读作 N190)**本轮未见归一**(扫描仍在位),维持 v22 第五节第 18 项的处置建议。
95
+
96
+ ### 3.1 新发现(14 号:N195–N208;已修 3 / 留档 11)
97
+
98
+ #### A. N195(high,已修=修复①)——写/删路径无代际感知:anchor/self 不可覆盖闸跨进程静默失效
99
+
100
+ `md_cg/mdcg.py:1508`(写面接线)× `md_cg/mdcos.py:2355`(删除面接线);判定链 `md_cg/protect.py:57-58`、`md_cg/mdcg.py:1607`。多进程共享库(serve 常驻 + review_cli/hive worker/脚本写方)下,常驻实例在他进程写入/保护锚点后、自身尚未发生任何读操作前 `add` 同 id 即**无 override 覆写不可篡改锚点**,且无 ProtectionError / 无快照 / 无审计(旧正文不可恢复且无痕);`forget` 同根返回 `not_found` 静默无操作。既有守卫 `md_cg/test_index_crossprocess_reload.py`(本会话实跑 PASS=21 FAIL=0)断言全走读面,无写面用例——与候选「只覆盖读面」一致(该套件全量内 PASS)。
101
+
102
+ #### B. N196(medium,已修=修复②)——索引缺条目即跳过闸判定:读隔离与 N130 层写闸双面失效
103
+
104
+ `md_cg/mdcos.py:4049`(`get` 首读放行跨会话 private)× `md_cg/mdcos.py:3896`(`verify` falsified 跳过 `require_layer_write`,knowledge 层原文被删)。详见修复②。
105
+
106
+ #### C. N197(medium,留档)——insight verify 零证据自报确证 + 越层直写
107
+
108
+ - **where**:`md_cg/insight.py:241-247`(显式 verdict「直接采信」)、`:283-293`(落 `insight_state=verified` + `importance≥0.9` + `protected=True` + `verification_basis="data"`)、`:297`(直写 `cg._write_node`)|`md_cg/mcp_server.py:2816-2822`(`act in (record, verify)` 只看 `can_write`,不看目标节点所在层)。**本会话读码核实**:三处均在位(verdict 非 None 即跳过全部证据门槛;`_write_node` 前后无 `require_layer_write`、无 `protect.guard_write`;分发层仅按 action 分档要求 `can_write`)。
109
+ - **缺陷面**:洞见节点的 `verify` 写面直走 `cg._write_node`,无层闸、无写保护闸;显式 `verdict` 被**零证据直接采信** → 落盘即 `insight_state=verified` + `importance≥0.9` + `protected=True`(此后 `forget` 需 override,即转为不可遗忘)+ `verification_basis="data"`,把无证据记忆标成「外部确证」。
110
+ - **证据(复核会话实测,临时库 + 哑 Principal;本会话读码复核)**:reflect(`layers_allow=('contextual',)`,`ops_allow` 含 `insight`—— 本会话于 `md_cg/tokens.py:147-153` 读码确认)对 knowledge 层 `insight_event` 节点:对照同位直接 `add` knowledge 被拒 `AccessDenied`,而 `call_tool(cg, op=insight, action=verify, verdict="verified")` 返回 `{'ok': True, 'state': 'verified', 'decided': True, 'reason': '显式裁决', 'importance': 0.9, 'protected': True}`;落盘 fm 实读 `verification_basis=data`、`tags=['insight_event','insight_verified']`,`_protected_history` 不存在。
111
+ - **处置**:单点补闸(层闸 + `guard_write`)+ 显式 verdict 的凭据口径需一并裁决(是否要求 `evidence` 非空或令牌签章),属「机械修 + 口径小裁」,建议次轮与 N208 同批。
112
+
113
+ #### D. N198(high,已修=修复③)——令牌库损坏静默回落 + 整份写回
114
+
115
+ `md_cg/tokens.py:287-350`。详见修复③。诚实边界(复核材料声明):损坏前置态由复核方直接截断构造(模拟磁盘错误/手工编辑/部分写);12 轮 10 进程并发签发未观察到主令牌文件被撕成不可解析(同时确认 N199 的固定临时名缺陷本身)。本会话读码复核:`_load_raw`/`_load`/`_save` 三处均在位。
116
+
117
+ #### E. N199(medium,留档·次轮首补候选)——令牌库写回固定共享临时名且读-改-写无跨进程锁
118
+
119
+ - **where**:`md_cg/tokens.py:343`(`tmp = p + ".tmp"` 后 `publish(tmp, p)`)与 `:666`(`_write_secret` 同款);对照 `md_cg/fsutil.py:57-86`(`atomic_write` 用 `tempfile.mkstemp` 唯一名)与 `md_cg/crypto.py:318`(`FileLock` 临界区)。**本会话读码核实**:`grep -n "atomic_write|FileLock|mkstemp" md_cg/tokens.py` **零命中**,两处固定共享临时名均在位。
120
+ - **缺陷面**:并发签发互相消费对方的临时名——一部分调用直接崩(FileNotFoundError),另一部分**返回成功但凭据在盘上不存在**(被后写者整份覆盖),调用方拿到明文却永远验不过。这是批次 65 N184(crypto `FileLock` + `mkstemp` + 写前对账)在 md_cg 相邻面的同款未同步缺口,也是本轮预期重点面之一;与已修复的 N198 同文件。
121
+ - **证据(复核会话实测,临时令牌库 + 哑令牌;本会话未复跑)**:10 进程 barrier 对齐并发签发连跑 8 轮,汇总「成功返回 36,其中盘上查无(静默丢失凭据)24,显式报错 44」;单轮样例 trial 0「成功=3 报错=7 盘上=2 静默丢失=1」、trial 5「成功=6 报错=4 盘上=1 静默丢失=5」;stderr 含 `FileNotFoundError …_tokens.json.tmp -> …_tokens.json`。对照 `crypto.provision_dek` 同规模 8 进程并发 8/8 全绿、dek 前缀互异。
122
+ - **处置**:次轮首补——按 N184 家法给 `_save` 落 `FileLock`(strict) + `mkstemp` 唯一临时名 + 写前对账(与 N198 已落的对账闸同一趟即可,两闸互补不重复)。
123
+
124
+ #### F. N200(high,留档·大设计决策)——执行器密钥面:N185 env 剥离致 serve 派发的 LLM 任务确定性全断
125
+
126
+ - **where**:`hive/src/exec.rs:85-86`(`ORCH_SECRET_ENV_KEYS` 三键),:134-144(三键 `env_remove`,仅按 `spec.orchestrate` 条件重注 ORCH_TOKEN/_FILE)、`hive/exec.py:1329-1331`(`_post_chat` 读 `HIVE_API_KEY`,空即 `RuntimeError`)、`:906`(web_search 回落同键)、`hive/src/keyres.rs:17-35`(锚密钥链尾=`HIVE_API_KEY`,与 LLM 网关密钥**同变量**)、`hive/README.md:343`/`:504`(书面「执行器必填,缺失任务即 error」)。**本会话读码核实**:`hive/src/exec.rs:85-86` 三键表、`:134-144` 剥离+条件重注、`hive/exec.py:1329-1331` 的 RuntimeError 三处均在位。
127
+ - **缺陷面**:一变量双角色(锚密钥链尾 × 执行器网关密钥)——批次 65 N185 把 `HIVE_API_KEY` 从每个执行器子进程无条件剥离且永不重注,serve 派发的全部 LLM 任务(`exec.py` 直路与 `orch.py` 编排路,后者复用同一 `_post_chat`)在首次 API 调用前即确定性落 error,**主能力全断**;且在役 serve 仍是批 65 之前构建的旧二进制时该回归「尚未落地、下次 --rebuild/重启后落地」。契约侧反证:全仓仅 `exec.rs:141` 一处条件重注且只含 ORCH_TOKEN/_FILE,job.rs/main.rs 无 spec 级 api_key 支持。
128
+ - **证据(复核会话第一手 A/B 实跑,系统临时池 + 哑值 + 本机丢弃端口,绝不出网)**:①哑 dumper 作执行器经 serve 跑 → 执行器落盘 env 实测**无 `HIVE_API_KEY`**(`HIVE_EXEC_PY`/`HIVE_RESULT_ANCHOR`/`HIVE_WORKERS` 在);②同 spec 以仓内 `exec.py` 经 serve 跑 → poll `state=error`、`error="RuntimeError: HIVE_API_KEY 未设置(执行器环境缺密钥)"`(未触网);③同一 spec 带哑密钥**直跑** `exec.py` → exit=3、`URLError: … 由于目标计算机积极拒绝…`(密钥已到达执行器并走到网络调用)——两臂唯一变量即 env 剥离;④反向证据:`hive/src/exec.rs:257` 的 N185 守卫已把「`HIVE_API_KEY` 不在执行器 env」**固化为契约**,仓内 serve 相关测试用 dumper/字符串结构断言,无任何用例跑「serve→真 exec.py」。
129
+ - **处置**:**大设计决策(④)**——修复必须先裁决「重注 LLM 网关密钥」与 N190「执行器不持 serve 密钥」的安全边界冲突(改即改契约,守卫须同步改)。处置建议见第五节。
130
+
131
+ #### G. N201(high,留档)——私有/会话绑定档提案明文落 inbox,review_list 无可见性过滤
132
+
133
+ - **where**:`md_cg/mdcos.py:1768-1776`(`propose` 把 `content` 原样进 `rec` 后 `append_jsonl(self.inbox_log, rec)`,无 `_seal_content`)、`:1922-1937`(`review_list` 仅按 `_pid_status` 终态过滤,无 `_readable`/密级/会话判定)|`md_cg/mcp_server.py:3067`(`mdcg_review_list` 要求 `op="read"`,`src/lib/mdcg_client.ts:121` 强制 full 面)。**本会话读码核实**:上述三处均在位(封套只存在于节点落盘路径 `_write_node→_seal_content`)。
134
+ - **缺陷面**:`sensitivity=private|secret` 的提案正文以**明文**落 `hippocampus/inbox.jsonl`,而低密级或异会话只读身份经 full 面 `mdcg_review_list`(只需 `read`)即拿到 secret 提案完整明文——与 get/search/recall 的「不可见即不存在」单点口径冲突。
135
+ - **证据(复核会话实测,临时库 + 哑主密钥)**:designer `propose(sensitivity='secret', session='sess_A')` → 盘面行内明文、`extra={'sensitivity':'secret','session':'sess_A'}`;output 角色(`clearance=internal`、异会话)`require_op('read')` PASS、`review_list()` 含该明文;同身份 `cg.get→None`、`search→[]`、`allows('secret')=False`;kernel 面 `cg(op=review,action=list)` 被 `require_op('review')` 拦下,full 面 `_dispatch('mdcg_review_list')` 可达。附带事实:`mdcg_propose` 不透传 sensitivity(`_proposal_extras` 无该键),secret 提案来源只有库级 `MdCGSecure.propose(sensitivity=)`。
136
+ - **处置**:次轮候选——单点给 inbox 记录加可见性过滤(或落盘即封套),需与「提案落地策略」一并定。
137
+
138
+ #### H. N202(high,留档·次轮首补候选)——会话要点 restricted 档经 session_recall 明文回给处置链路之外身份
139
+
140
+ - **where**:`md_cg/mdcos.py:2523-2537`(`_session_notes`:`fm, content = self._read(e)` 后 `if content is None: continue # 不可读(无密钥/身份不符)→ 视为不存在`——把「读盘成功」当成「可读」,**从不调 `_readable`**)|`:2562`(`session_recall` ①notes 段)。**本会话读码核实**:该注释与 `_read` 调用在位;`md_cg/crypto.py:62` `ENCRYPTED_LEVELS = ("private","secret")`(**restricted 不在其内 → 明文落盘**,本会话实读);`md_cg/security.py:379-384` `can_read_restricted` 仅 designer/orchestr/verify(本会话实读)。
141
+ - **缺陷面**:restricted 档节点正文(`_session_digest` 取「# 执行:」前 500 字)经 `session_recall` 明文回给任何持 `session` op 的只读身份,绕过 `_readable` 的 restricted 分支(`mdcos.py:3942-3945` → `security.can_read_restricted`)。触发面含存量迁移:`scripts/migrate_restricted.py:72-77` 的 passthrough 排除表不含 `tags`/`session` → 存量 private 会话要点迁为 restricted 后仍带 `session:*` 标签自动落入该面。
142
+ - **证据(复核会话实测,临时库 + 哑主密钥)**:designer 写 `session_note(summary 含 'MK-RESTRICTED-AAA', session='S1', sensitivity='restricted')`;output 角色(internal、异会话)逐面读——`cg.get→None`、`search→[]`、`recall` 无标记(均正确拒绝),而 `session_recall(session=None, limit=10).notes` 条数=2、含该明文;对照 private 同级只回密文摘要 → 泄漏面专属于**不加密**的 restricted 档。
143
+ - **处置**:次轮首补——单点补 `_readable`(低风险高危项);`migrate_restricted.py` 排除表同批补 `tags`/`session`。
144
+
145
+ #### I. N203(high,留档·大设计决策)——日志索引节点 id 位置化:中途插话即永久错位(静默丢索引 + 重复落节点)
146
+
147
+ - **where**:`scripts/dsh_log_index.py:564-568`(`nid = f"dsh-log-{token}-{i:04d}"` 位置化 + 已存在即跳过)、`:551-561`(归属核验)、`:487-493`(token 只由 `createdAt` + 首条 user 派生)。**本会话读码核实**:三处均在位。
148
+ - **缺陷面**:节点 id 由**抽取序位**而非内容决定,重跑幂等只在日志纯追加时成立:日志中途多出一条消息(含本工具 KNOWN 清单内事件 agent/inbox/spliced)即整体错位——新正文落在已占用 id 上被静默跳过(**永久丢索引**),尾部旧正文被重复落成新节点,而跑批仍报成功、stderr 无告警;N167 的归属核验只在既有节点 frontmatter 指向**别的**会话时才切 ext_token,本会话内容漂移不可见。
149
+ - **证据(复核会话第一手,真跑在役 CLI 入口,会话根/活库/aux 全临时目录)**:V1(u1,a1,u2 各长文)→ `chapters=25 nodes_indexed=25 skipped=0`;在 u1 与 a1 之间补真实 `agent/inbox/spliced` 事件(首条 user 未变 → 同 token、`token_collision=None`、stderr 空)成 V2 → `chapters=33 nodes_indexed=8 nodes_skipped_existing=25`;盘面核对:新增节点仅 `…-0025..0032`,`MARKER-SPLICED`(新插话正文)在全部 `dsh-log-` 节点零命中,`MARKER-U2` 出现两份(`…-0017` 与 `…-0025`);本次 `token_collisions=0`、rc=0。
150
+ - **处置**:**大设计决策(④)**——改内容派生 id 涉及既有位置化 id 节点的迁移与幂等契约变更,须与模块「一次性/可重跑」docstring 契约同时裁决。建议见第五节。
151
+
152
+ #### J. N204(medium,留档)——父节摘要占满即吃掉并入的子节摘要(这些子节正文落到索引之外)
153
+
154
+ - **where**:`md_cg/docindex.py:192`(`summary = _summary(info[i]['direct'])`,上限 `MAX_SUMMARY=200`)→ `:195-199`(`merged=[…80…]` 后 `summary = (summary + ";" + ";".join(merged))[:MAX_SUMMARY]`);`small` 判据在 `:186`。**本会话读码核实**:追加发生在父节摘要算满之后再做整体截断,代码如期在位。
155
+ - **缺陷面**:父节直接正文摘要 ≥200 字时,并入的子节摘要恒被截断吃掉(对这类父节等于死代码):这些子节既无独立节点、正文又未进任何节点摘要 = **静默落到索引之外**,与模块头 `:8-14` 及 `:194-195` 注释声明的「并入父摘要,否则这些小节的正文…检索不到」相反;render 节点正文只带 `summary_parts`,故正文确实不可经 search 命中。
156
+ - **证据(复核会话实测,合成样本直调 `docindex.extract`)**:A(h1/h2 各 ≥200 字直文 + h3 子节 54 字)→ 2 节点且「任何节点摘要含子节独有文本=False」;B(父节无直接正文)/C(父摘要未占满)对照均并入=True → 失效条件确为「父摘要占满 200 字」。量级扫本仓 docs/:md 文件 114、节点 1842;按复核口径「无独立节点且正文前 20 字不进任何产出节点 summary_parts」≈4.7 万字符(候选报 85,328,差异来自字符记账口径,现象与最大文件一致,如实声明)。
157
+ - **处置**:低风险机械修——合并段先截断父摘要再拼接(或对 merged 单独限长),并为 `small` 子节记账;随低危批次。
158
+
159
+ #### K. N205(medium,留档)——op=status 对不可读节点不做可见性判定(存在性/依赖图/台账证据串泄漏)
160
+
161
+ - **where**:`md_cg/trust.py:911-940`(`describe` 在 `cg.get→None` 时回落索引条目 `e = cg.index['nodes'].get(node_id)` 仍返回 `ok=True` 及 deps/validity/verification_state/lifecycle_state)、`:952-963`(`load_ledger` 逐行读 `_trust.jsonl` **仅按 node_id 相等过滤**)|`md_cg/mcp_server.py:1817+`(`_status_call`)|`md_cg/mdcg.py`(set_verification 的 reason 由 verify 调用方文本拼成)。**本会话读码核实**:`trust.py` 两处在位(无 `_readable` 调用)。
162
+ - **缺陷面**:任何持 `status` op 的身份(`output`/`guest` 的 `ops_allow` 含 status)即可确认密件存在、读其依赖图与 validity/verification_state/lifecycle_state,并经 `action=ledger` 读到该节点验证留痕的 reason 文本(≤80 字证据串)——与 get/search 的单点口径冲突。
163
+ - **证据(复核会话实测,临时库 + 哑主密钥)**:secret 节点以 output 角色(internal、异会话)走 `cg(op=status, node_id=…)` → `ok=True`、`depends_on=['n_other']`、`verification_state='unverified'`,而同身份 `cg.get→None`;designer `verify(evidence='…')` 后同身份 `action=ledger` → `count=1`、`rows[0].reason='外部裁决 confirmed:…'`。边界如实声明:**未回带节点正文明文**,泄漏的是存在性/依赖图/有效性/验证态与台账 reason 文本。
164
+ - **处置**:低风险机械修——`describe`/`load_ledger` 出口统一过 `_readable`(与 get/search 同口径);随低危批次。
165
+
166
+ #### L. N206(high,留档·次轮首补候选)——stdio 主循环未校验解析结果类型:一行非对象 JSON 即杀进程
167
+
168
+ - **where**:`md_cg/mcp_server.py:3783-3789`(`try: msg = json.loads(line) except ValueError: continue`,紧随 `method = msg.get("method")`;`:3793` 区 `name = params.get("name")`)|对照已修同族 `hive/hive_mcp/mcp_server.py:766-774`(`try: _rpc(req) except Exception` 入口兜底)。**本会话读码核实**:md_cg 侧的 try 仅包 `json.loads`,`msg.get`/`params.get` 无外层 try;hive 侧兜底在位。
169
+ - **缺陷面**:一行非对象 JSON(`[]`/`123`/`"x"`/`null`)或 `params` 非对象(`[1,2]`)时 `msg.get`/`params.get` 抛 AttributeError 且不在任何 try 内,逃出 `main()` → **整个 MCP server 进程死亡**(此后 stdout 再无任何应答)。任何能写该 server stdin 的一方(MCP 宿主/被注入的宿主插件/stdio 管道被其它进程交织写入)发一行即可杀进程,无需凭据;进程死亡后 DSH 桥进入重试链,期间记忆面(含写入)全部不可用。
170
+ - **证据(复核会话实测,`python -m md_cg.mcp_server` 走 stdio,临时根)**:输入 `[initialize, [], tools/list]` → EXIT=1、stderr 栈指向 `msg.get("method")` 的 AttributeError,`tools/list` 永无应答;`{"method":"tools/call","params":[1,2]}` → EXIT=1 指向 `params.get`;`123`/`null`/`"x"` 三形态同为 EXIT=1,五例均仅 initialize 一条应答后进程即死。
171
+ - **处置**:次轮首补——**3 行镜像** hive 面入口兜底(`try: _rpc(req) except Exception` 回 `-32603`),高危低风险。
172
+
173
+ #### M. N207(medium,留档)——`isMainEntry` 未做 realpath 归一:`lingshu init` 经间接路径入口静默空跑且 exit 0
174
+
175
+ - **where**:`src/cli.ts:46-56` 与 `src/init.ts:342-352`(同款复制的 `isMainEntry`:`pathToFileURL(resolve(process.argv[1])).href` 与 `import.meta.url` 比较)。**本会话读码核实**:两处代码逐字同款、均无 realpath 归一。
176
+ - **缺陷面**:经间接路径入口调用时 argv[1] 保留间接路径而 Node 已把主入口解析为真实路径 → 判定恒假 → `if (isMainEntry())` 整块被跳过:`lingshu init …` / `lingshu-init …` **什么都不做、零输出、exit 0**(成功码),既未打印 mcp.json 片段也未落盘 snippet,且不再打印 USAGE。README 主推的 `npx @furongjun1999/dsh-memory init` 在 POSIX 上经 `node_modules/.bin` 符号链接(标准形态)执行即命中;Windows 上 npm 的 .cmd shim 传真实路径故本机不暴露,仓库 CI/测试在 Windows 上跑,故长期未被捕获。
177
+ - **证据(复核会话实测,win32 + Node v24.18.0;用目录 junction 建模「argv1≠realpath」根因,未改仓库文件)**:①机制自证——经 junction 跑探针打印 `argv1=<临时>/link/probe.mjs`、`metaUrl=file:///<临时>/real/probe.mjs`;②真实产物对照(临时 cwd)——经 junction 跑 `lib/init.js` → **EXIT=0、stdout 0 字节、stderr 0 字节、无 snippet 落盘**,直跑同参 → EXIT=0、stdout 1512 字节、落盘 snippet;③`lib/cli.js` 无参经 junction → EXIT=0 零输出,直跑 → 1518 字节;④无守卫(grep 仅命中源码两处与构建产物)。**未实测腿(如实声明)**:POSIX/.bin 符号链接与 `npx` 实链路本机无法执行(无 POSIX Node;文件符号链接创建 EPERM),该腿依 Node 主入口默认 realpath 解析语义推得。
178
+ - **处置**:低风险小修(`realpathSync` 双向归一)+ 补一条守卫;因复现腿有边界,本轮留档。
179
+
180
+ #### N. N208(high,留档;复核材料原编 N196)——ccgc recalibrate 免闸写入 + 换行注入
181
+
182
+ - **where**:`md_cg/ccgc.py:830-892`(recalibrate:`:839` 自证判据 `_same_subject(verifier, compiled_by)`、`:880` 四槽与正文行重合成后直写 `_write_node`、`:889` `rebuild_index`)|`md_cg/mcp_server.py:2563+`(分发入口,`verifier`/`compiled_by` 均由调用方自报)|`md_cg/mdcos.py:3841/3850/3860/3869/3876/3883/3899`(`require_layer_write` **全部接线点**——recalibrate 不在其中)。**本会话读码核实**:`_same_subject`(`ccgc.py:590-603`)为纯字符串归一比较(无令牌/签章维度);recalibrate 分支在 dry_run 后直接 `_cg._write_node(...)`,前后无 `require_layer_write`、无 `protect.guard_write`;`ccgc_field_value`(`md_cg/nodefile.py:203-219` 区)取**首个命中行**。
183
+ - **缺陷面**:①判据 `_same_subject(verifier, compiled_by)` 两串均由同一调用方自报(对照 link 侧 N176 的 E052 已拒无凭据签章),recalibrate 无令牌、无签章、无 `verifier_identity` 维度;②直接 `cg._write_node`,不经层闸也不经写保护闸 → **任意层(含 anchor/self 保护层)** 节点的 condition_space 四槽与「生效条件」行可被任意可调 ccgc 的角色改写,无快照、无审计;③corrections 槽值未过滤换行 → 可向节点正文注入任意行(`ccgc_field_value` 取首个命中行 ⇒ **正文读面被顶替**)。
184
+ - **证据(复核会话实测,临时库 + 哑 Principal)**:①record 角色(`layers_allow` 不含 anchor,`ops_allow` 含 ccg——本会话于 `md_cg/tokens.py:139-141` 实读确认)对 anchor 层节点 `recalibrate` → `{"ok": true}`、`errors=[]`,盘上正文变为伪造生效条件行,保护历史/保护审计均 False;对照同 principal `add(同 id, layer="anchor")` 被拒 `AccessDenied`、designer 无 override 的 add 被拒 `ProtectionError`——坐实闸只拦 add 族;knowledge 层节点同样被改写成功。②换行注入实测:`corrections.observation_tool` 传含 `\n# 正文:…` 的值 → `ok=True`,盘上正文出现注入行,且注入的「# 正文:」行排在原作者正文行**之前**。③证伪候选一部分:reflect 实测抛 `AccessDenied 角色 reflect 无权执行 op=ccg`(`md_cg/tokens.py:147-153` 的 reflect `ops_allow` 确实不含 ccg,本会话读码确认)——可达角色是 **record**。
185
+ - **处置**:机械修部分(补层闸 + `guard_write` + 换行过滤)明确,但「谁算编外验证方」须先裁决(与 N176 的 E052 口径对齐),故与设计项同批;建议次轮与 N197 同批(两者同属「写面绕过层闸」族)。
186
+
187
+ ### 3.2 legacy 复核确认(14 项独立缺陷 + 1 条已修复核记录;复测轮数按缺陷号在历轮报告文件现身 grep 计,本会话实跑——早期轮或以文字指涉未带号,计数为下限)
188
+
189
+ | # | 编号 | where(本会话读码核实) | sev | 原轮次 → 复测轮数 | 现状与本轮复核 |
190
+ |---|---|---|---|---|---|
191
+ | L1 | **N191** | hive/src/scheduler.rs:251-259(主循环回滚)/ :312-354(recover_orphans 残留领取态) | medium | v22 首报 → 本轮第 2 轮 | **本轮落闸=修复⑥**(v22 遗留第 2 项「次轮首补候选」如约落地)。本会话 cargo 复跑 judgment_surface 8/8 含两件新守卫 |
192
+ | L2 | **N68** | hive/exec.py:814(env 优先,:845 直接 `MdCGSecure(root, principal=…)` 无 realpath/read_roots/归属闸)|hive/hive_mcp/mcp_server.py:403-409/:456-457/:638|hive/orch.py:496 | medium | v8 → v10/v15/v17/v21/v22 → 本轮第 **7** 轮 | 维持留档·大设计决策。本轮新增限定:`exec.py:814` 是 **env 优先**,serve 级已设 `MDCG_ROOT` 时 spec 值被完全忽略——而 README「唯一推荐正路」正是注入该 env,故缺口只在「部署未设 serve 级 MDCG_ROOT(或设空)」时是活路径。复核实测(临时哑根):指定目录被建成/挂载为记忆根(整套结构 + 加密身份信封落盘)、`op=read` 未读出正文;反向对照(设 serve 级 MDCG_ROOT)时 spec 指向目录 listdir 为空 |
193
+ | L3 | **N178** | md_cg/units.py:334-336(修复前 `os.path.join(jobs_dir(jobs), str(job_id or ""))`)| low | v21 → v22 → 本轮第 3 轮 | **本轮落闸=修复⑤**(闸在 units.py:277-306/:342-346/:376-382/:427-432)。retrieval 区同报告一次,同一缺陷 |
194
+ | L4 | **N177** | hive/exec.py:1017-1032(`_sensitive_read` 后缀族只匹配末段、名字族只匹配前/中缀) | low | v21 → v22 → 本轮第 3 轮 | 维持留档。复核实测(仅用临时目录内不存在的名字):`token.txt`/`db.kdbx.bak2`/`notes.txt:secret`(ADS)/`metrics.token.bak`/`prod.env.txt`/`secret.key.txt` 全部放行,对照 `id_rsa`/`prod.env`/`id_rsa.bak`/`credentials.json`/`config.local.json` 命中——知晓部署侧命名的攻击者改名/加尾缀/挂 ADS 即免检外发网关(read_file / context_files / system_prompt_from 三通道共用同一判据) |
195
+ | L5 | **A1-e** | hive/exec.py:963-971(`HIVE_READ_ROOTS` 未设/空串/纯空白/纯分隔 → 空 tuple = 读全放开) | low | 对抗报告 A1-e(v21/v22 记录)→ 本轮第 3 轮 | 维持留档。定性注记不变:`:965-970` docstring 明写空值语义为**刻意设计**(要收窄必须给出至少一个真实目录),故属加固项(建议显式告警);真正风险是与 N91(`serve_start.load_config` 放行空串)叠加——部署方以为锁了、实际全放开且无提示 |
196
+ | L6 | **N90** | hive/hive_mcp/mcp_server.py:381-394(`_result_view` 顶层非 dict 照旧 `.get`)+ `_t_poll` 单查与无参全量两路均无条目级 try | low | v10 → v17 → v22 → 本轮第 4 轮 | 维持留档。复核实测(临时池):池内病态 `result.json='[1,2,3]'` → `_t_poll({})`(宿主默认无参观测调用)逃逸 `AttributeError: 'list' object has no attribute 'get'`,`_t_poll({'job_id':…})` 同;对照合法 job 单查 ok=True。注记:`_t_doctor` 只在 status 为 dict 时统计、不调 `_result_view`,故未复现 doctor 崩点(与候选自注一致) |
197
+ | L7 | **N91** | hive/serve_start.py:62-75(`resolve()` str 直值不 strip 不归失败 vs `{"env":…}` 形态 `or None`)、:91-95(`load_config` 只判 `val is None`)、:237(`merged={**os.environ, **env}`) | low | v10 → v17 → v22 → 本轮第 4 轮 | 维持留档。复核实测:`resolve('')=''`、`resolve(' ')=' '`;经真 `load_config` 得 `{'HIVE_API_KEY':'','HIVE_API_BASE':' '}` 且 `err=None`;merged 实测宿主已设的真实值被空串**静默覆盖**——serve 带残缺 env 上岗,每个任务烧一次完整调度后才落 error(与 N200 叠加时更隐蔽) |
198
+ | L8 | **N186** | hive/exec.py:387-397(`system_prompt_from` 真源 `f.read()` 无上限;对照 :452 `CONTEXT_TEXT_MAX=256KB`) | low | v22 首报 → 本轮第 2 轮 | 维持留档。复核实测(临时 1MiB 真源):log 记「系统提示词重建自 …(1048576 字符)」无截断,随即走到网络调用(本机丢弃端口) |
199
+ | L9 | **N187** | hive/exec.py:386-397(读取面只捕 OSError,非 UTF-8 真源抛的 UnicodeDecodeError 裸逃) | low | v22 首报 → 本轮第 2 轮 | 维持留档。复核实测(GBK 真源):`python hive/exec.py <临时job目录>` exit=3、`result.error=UnicodeDecodeError…`——按头注契约应为 2(规格错被记成 API 错) |
200
+ | L10 | **N188** | hive/src/main.rs:489-524(`cmd_kill` 只有 job_id 校验 + is_dir,无终态闸) | low | v22 首报 → 本轮第 2 轮 | 维持留档。复核实测:对 `state=done` 任务 `hive kill` → `{"ok":true,…,hint:"worker 检测到 kill 标志后强杀(≤1s)"}`,kill 文件残留、poll 仍 `state=done`(假回执) |
201
+ | L11 | **N192** | hive/src/scheduler.rs:516-524(`classify_result` 只认 error 字段) | low | v22 首报 → 本轮第 2 轮 | 维持留档。复核实测:执行器写 `{"ok": false, "content": …}`(无 error 字段)经 serve 跑 → poll `state=done`、`error=None`、`conflict=None`,与 `wm.py` 凭证闸(`ok is not True` 即拒)两套成败语义;上游 ok=false 产物可被下游 deps_gate 当成功依赖放行 |
202
+ | L12 | **N193** | hive/wm.py:159-163(job_id 只拒 `.`/`..`/`/`/`\`)、:173(`dest=os.path.join(wm,"jobs",job_id)`) | low | v22 首报 → 本轮第 2 轮 | 维持留档。**后果按实测更正**:同盘形态(job_id=`C:xxx` 且 wm 也在 C 盘)**不会逃出** wm 树,而是被 `ntpath.join` 静默改写为 `wm/jobs/<末段名>`(路径与分支名不一致),随后 `cmd_snapshot` 抛**未捕获** `WmError`(快照调用崩);真正逃出 wm 树的是**跨盘**形态(job_id=`D:xxx` → join 直接得 `D:xxx`,按该盘 cwd 相对落盘)。跨盘形态只做路径级核实、未落盘(如实声明) |
203
+ | L13 | **legacy P3** | md_cg/mdcg.py:1474-1480(写面类型闸)/ :1325/:1006/:1148(派生面归一)/ :1338(崩点 `sorted(nodes)`) | high | DSH端缺陷专项_v1.0.md:106/:204/:249(v0.6.0 修复报告第 4 条「相邻发现(未修)」)→ 本轮**首修** | **本轮落闸=修复④**。沿革核对:`md_cg/test_none_id_write_guard.py` 原自注「add(123) 属相邻缺陷,超出本守卫目标」(本轮已更新指向本修复与守卫) |
204
+ | L14 | **v21-R1** | md_cg/mcp_server.py:54-66/:72|hive/hive_mcp/mcp_server.py:55-67/:73 | low | v21(报告内 R1 行编号)→ v22 留档 14 号 → 本轮第 2 轮 | **本轮落闸=修复⑤**(v22 处理建议「if 入 N 系自 N195 顺延」) |
205
+
206
+ **并入 L14 条目的 1 条已修复核记录**:**N184**(`md_cg/crypto.py:309-347` 并发 provision 次生面复核;v22 修复①)——**维持已修,未发现次生缺口,非缺陷、不占新号**。本会话未复跑;复核会话实测(临时根 + 哑 KEK=32 零字节):8 进程 barrier 对齐 → 成功 8 / 报错 0,dek 前缀 8/8 互异,`_keys.json` 信封数 8 且键全在,无 LockedError;读码复核:读-签-写全程在 `FileLock(keys_path(root), strict=True)` 内,`_save_keys` 先对账再整份写,`load_error` 在 `provision_dek` 与 `_save_keys` 双点拒写。
207
+
208
+ ### 3.3 证伪·剔除(3 项)
209
+
210
+ 1. **`md_cg/mdcg.py:1019-1031`(`_index_signature`)× `:1034-1056`(`_maybe_reload_index`)——快照签名同 tick 碰撞候选:机制为真但自然写路径不可达**,判为**加固项而非缺陷**。①已核实 `_index.json` 全仓只有两个写者(`compact_index`、`rebuild_index`),二者整体包在 `FileLock(self.index_path)` 内(跨进程串行,不可能并发落盘);②实测量化:本机签名粒度 ≈1ms(同尺寸文件连续改写 50 次的最小 mtime_ns 增量 999400 ns),而单次 `compact_index` 最小 1.218ms、`rebuild_index` 最小 1.337ms——相邻两次快照写入的最小间隔已 ≥1 个时钟 tick,「同一 tick 内两次快照」在算术上不可能;③自然触发实测:300 次连续 compact / 60 次连续 rebuild / 300 次 add+compact 组合,签名碰撞均 **0**;④候选复现依赖 `os.utime` 手工把新快照 mtime_ns 复位为旧值(构造态);⑤候选称「Windows tick ~15.6ms」与本机实测 ≈1ms 不符。**残余风险如实记录**:签名不含内容——若部署在时间戳粒度更粗的文件系统(FAT/exFAT ≈2s、部分网络盘)或快照写入稳定快于一个 tick 的机器上,该机制会兑现;建议顺手把哨兵升级为 `(mtime_ns, size, 内容哈希前缀)`,成本一次前缀读。**本会话读码核实**(`md_cg/mdcg.py:1019-1031`):签名确为 `(st_mtime_ns, st_size)`,不含内容——残余风险描述与代码一致;动态量化数据为复核会话第一手(材料所载,本会话未复跑)。
211
+ 2. **`hive/serve_start.py:234-247`(`start()` 判已在跑 → `Popen` 整段无跨进程互斥)——双 serve 抢同一池候选:代码前提成立但声称后果被既有防护拦下**。**本会话读码核实**:`start()` 中 `serve_alive(jobs)` 判死(`:245-247`)与 `Popen([EXE,"serve","--jobs",jobs])`(`:266-270`)之间确无任何跨进程锁,且 `Popen` 不带 `--force`。证伪依据(复核会话实测):(a) 缺互斥属实——stub 把 `serve_alive` 恒判 false 后并发调用 `start()`(双线程 + Barrier),两次调用**都**走到 `Popen`(argv 均不含 `--force`),即 Python 层确无临界区;(b) 但 6 轮近同时双起(同一临时池、Popen 背靠背),**6/6 只存活 1 个** serve 进程,第二个打印 `{"ok":false,"error":"serve 已在运行(pid=…,已核对进程身份)…"}`——`hive/src/main.rs:157-172` 的 rust 侧单实例守卫(判活三层:心跳 + pid 存活 + pid 身份)在同一约束上生效。结论:**加固机会**(把 rust 已有守卫在 Python 侧用现成 `md_cg/fsutil.py` 的 `FileLock` 前移,消除误导性报错与理论窗口),**不是可复现缺陷,不入缺陷号**。
212
+ 3. **`scripts/review_cli.py:86` × `md_cg/review_cli.py:106`(孪生件漂移:`autoflush=1` 缺失)——代码漂移事实成立,但声称的可见性后果被既有防护证伪**。**本会话读码核实**:`scripts/review_cli.py:86` 为 `MdCGSecure(_root(args), principal=p)`(无 autoflush),`md_cg/review_cli.py:106` 为 `… principal=p, autoflush=1)` — 漂移属实。证伪依据(复核会话实测):`review_decide` 自身已有显式 flush(accept/edit 分支 add 后 flush,函数尾部又有裁决链路统一收尾 flush,覆盖 reject/noop),实测以缺省 autoflush 形态调 `review_decide(accept)` 后、在 close/退出**之前**读分片日志即已含接受节点——即跨进程可见性由 `review_decide` 的显式 flush 保底,`autoflush=1` 对 review_cli **不是承重参数**。残余项(建议按「孪生件漂移 + 文档失真」处置,非安全项):a) 归一化行尾后 diff 两文件,实质差异仅 `autoflush` 与入口措辞;b) `git show --stat` 确认某 commit 改了脚本版但未补 autoflush;c) 某缺陷专项文档声称两文件「逐字一致已 diff 验证」与现盘面不符;d) 守卫缺口成立(脚本侧构造无任何断言)。
213
+
214
+ ---
215
+
216
+ ## 四、验证(门禁)
217
+
218
+ **本报告会话第一手实跑**(当前工作区 = HEAD 3069d14b + 本轮 7 项修复未提交 + 本报告):
219
+
220
+ 1. **编号基线**:python 扫描 `docs/eval/缺陷挖掘_自主迭代_v*.md` 全系列 → `N\d{3}` 全局最大 **N195**(仅出现在 v22 文本「次轮自 N195 续编」),**报告面无 N195+ 既有登记**;源码树扫描(排除 `.git`/`node_modules`/`target`/`lib`/`__pycache__`/`.zcode`)→ **N195/N196/N198 实占**(注释 + 两件守卫文件名),**N197、N199–N208 空闲**(唯一「N195/N196」同名命中为 `_md_cg_p27` 测试夹具抄录的 v22 报告原文,非占号);另 `hive/src/exec.rs`/`keyres.rs`/`scheduler.rs`/`tests/judgment_surface.rs` 的 N185/N191 字样为历轮既有(v22 第五节第 18 项处置中)。
221
+ 2. **6 件新守卫逐件复跑(全绿)**:`python -X utf8 -m md_cg.test_n195_writepath_reload` → **PASS=20 FAIL=0 rc=0**;`md_cg.test_n196_stale_gate_skip` → **PASS=10 FAIL=0 rc=0**;`md_cg.test_n198_tokens_corrupt_failclosed` → **PASS=23 FAIL=0 rc=0**;`md_cg.test_legacy_p3_node_id_type` → **PASS=23 FAIL=0 rc=0**;`md_cg.test_n178_units_jobid_gate` → **PASS=41 FAIL=0 rc=0**;`md_cg.test_v21r1_package_version` → **PASS=41 FAIL=0 rc=0**(合计 158 断言)。
222
+ 3. **python 全量回归**:`python -X utf8 -m md_cg.run_tests` → **SUMMARY 234/234 通过,3 跳过(依赖缺失/平台不符),退出码 0**。较上轮 228/228 增加 6 件新守卫(228→234 与本轮修复落码顺序一致);上轮起存在的既有失败 `md_cg.test_subproc_encoding`(指向 hive 池推导测试的 subprocess 文本模式未声明 encoding)**本轮已闭合**(该测试文件在工作区已随修复补齐 encoding;本会话全量运行 234/234 全绿即其证据)。run_tests 目标发现为 `glob(md_cg/test_*.py)`(本会话实读 `md_cg/run_tests.py:_discover`),故 6 件新守卫均在套件内执行。
223
+ 4. **cargo(两 crate)**:`cd hive && CARGO_TARGET_DIR=<系统临时目录> cargo test` → **退出码 0,lib 33/33 + 集成 9/9 + judgment_surface 8/8 = 50/50**(judgment_surface 含 N191 两件新守卫 `pending_with_residual_claim_recovers` / `claim_rollback_on_status_write_failure`,全绿);`cd rust && CARGO_TARGET_DIR=<系统临时目录> cargo test` → **退出码 0,14+0+1+1+0 = 16/16**。**注**:仓内 `hive/target/release/hive.exe` 被在役 serve(pid 19648,`hive.exe serve --jobs …`)持有,为不触碰在役进程与在役二进制,两 crate 均使用**树外临时 target 目录**构建(本会话先 `tasklist` 确认在役 serve 存活,全程未动)。
224
+ 5. **npm run gate(本会话第一手实跑,逐面归因)**:`npm run gate` → **VERDICT=FAIL,退出码 1**;输出面逐条:
225
+ - `check_unreachable` **PASS**(445 文件,命中 0,语法失败 0);
226
+ - `check_publish_artifact`:发布清单 `@furongjun1999/dsh-memory@0.6.0` 文件数 1432;**R1 凭据/密钥面 PASS(文件面=0 内容面=0)、R2 私有数据面 PASS、R3 隐私文本 PASS(本报告内容零命中)**;**R4 非追踪件面 FAIL:命中=7,非追踪=35、允许=28** —— 点名的 7 件即 `docs/eval/缺陷挖掘_自主迭代_v23.md`(本报告)与 6 件新守卫(`md_cg/test_n195_writepath_reload.py`、`test_n196_stale_gate_skip.py`、`test_n198_tokens_corrupt_failclosed.py`、`test_legacy_p3_node_id_type.py`、`test_n178_units_jobid_gate.py`、`test_v21r1_package_version.py`),判据为「包内非追踪件仅允许 `lib/`」;
227
+ - 检查链 `&&` **短路于 R4**,故后四检查器未由 gate 执行——本会话**逐条补跑**(非 gate 链,如实标注):`python scripts/link_check.py` → 受管 md 1241 个、判定链接 228 条、**OK=228 BROKEN=0**,退出码 0;`python scripts/workspace_index.py --check` → **[OK] 工作区索引与仓库一致(顶层目录 20 · 追踪 2014 件)**,退出码 0;`python scripts/verify_discipline.py --allow-missing` → **结论 9/9 目标一致**,退出码 0;**`python scripts/cogmap_sync.py check` → 退出码 1(红)**,两条 FUNCMAP 段不一致:`cg(op=help)` 行号期望 L1980/`_help_call` L1899、文档实际 L1965/L1884;`stg(op=relation)` 期望 L2969、文档实际 L2954。
228
+ - **cogmap 红点的归因(本会话非侵入式定位)**:`git show HEAD:md_cg/mcp_server.py | grep -n "def _help_call"` → **1884**(与文档现值一致),工作区同查询 → **1899**(+15);工作区 `if op == "relation"` 在 **2969**、HEAD 值 2954(+15)。两处偏移恰为 **+15**,与本轮 `md_cg/mcp_server.py` 的 diff 净增行数一致(`git diff --numstat` = **+17/−2**,hunks 全在 `:46-68` 头部即 v21-R1 的 `_package_version` 改写区)——即**该红点由本轮在飞改动引入、非既有**,处置为重生成投影段 `python scripts/cogmap_sync.py build`(工具自述「代码动了行号漂了即红灯,build 一键重挂」)。该红点**未改任何代码**即可消除,列入第五节第 23 项。
229
+ - **VERDICT 判定**:FAIL 完全由「未追踪新件 + 生成投影未重挂」两类**提交前置动作**构成,内容面(R1/R2/R3)零命中——报告面与守卫随编排会话入库、cogmap 投影重挂后重跑 gate 即应全绿;本报告不代编排会话中断言届时的 VERDICT。
230
+ 6. **读码核实清单(本会话第一手,逐条指向行号)**:`md_cg/mdcg.py:1038/:1508/:1607/:1474-1480/:1325`;`md_cg/mdcos.py:2355/:4049/:3896/:1768-1776/:1922-1937/:2523-2537/:3841-3899`;`md_cg/tokens.py:287-350/:343/:139-141/:147-153`;`md_cg/units.py:277-320/:342-346/:376-382/:427-432`;`md_cg/mcp_server.py:54-72/:3067/:3783-3789/:2563`;`hive/hive_mcp/mcp_server.py:55-73`;`md_cg/ccgc.py:590-603/:830-892`;`md_cg/insight.py:236-300`;`md_cg/docindex.py:183-200`;`md_cg/trust.py:909-963`;`md_cg/crypto.py:62`;`md_cg/security.py:379-384`;`md_cg/nodefile.py:203-219`;`scripts/dsh_log_index.py:555-568`;`src/cli.ts:46-56`;`src/init.ts:342-352`;`hive/serve_start.py:234-247/:266-270`;`hive/src/exec.rs:85-86/:134-144`;`hive/exec.py:1329-1331`;`scripts/review_cli.py:86`;`md_cg/review_cli.py:106`;`md_cg/run_tests.py:_discover`。
231
+ 7. **历轮复测计数**(本会话 grep `N0*<n>` 于 docs/eval 全系列):N68 = v8/v10/v15/v17/v21/v22(本轮第 7 轮);N90/N91 = v10/v17/v22(第 4 轮);N177/N178/A1-e = v21/v22(第 3 轮);N186/N187/N188/N191/N192/N193/v21-R1 = v22(第 2 轮);legacy P3 = `DSH端缺陷专项_v1.0.md`(首修)。
232
+
233
+ **门禁归因**:`npm run gate` 的 FAIL 面归因见本节第 5 条(R4 非追踪件面命中=7 由本轮未入库新件构成 + 链式短路后补跑发现的 `cogmap_sync` 投影漂移);两项均属提交前动作,与报告内容面无关。
234
+
235
+ **修复侧红绿双态**:git stash 双态机械证据为修复会话第一手实测(材料附命令与输出,见第二节各条);本报告未重复 stash 操作(避免扰动并行会话工作区),绿态已由上述第 2/3/4 项独立复跑佐证。
236
+
237
+ ---
238
+
239
+ ## 五、遗留清单(21 项在档缺陷 + 4 项流程/残留/范围外)
240
+
241
+ | # | 编号 | where | sev | 处置去向与建议 |
242
+ |---|---|---|---|---|
243
+ | 1 | **N200** | hive/src/exec.rs:85-86/:134-144 × hive/exec.py:1329-1331 × keyres.rs:17-35 | high | **大设计决策(④)**:一变量双角色(锚密钥链尾 × LLM 网关密钥)——修复须先裁决「重注 LLM 网关密钥」与 N190「执行器不持 serve 密钥」的边界冲突,且 `exec.rs:257` 守卫已把「`HIVE_API_KEY` 不在执行器 env」固化为契约(改即改契约)。**建议方向(供裁决,非结论)**:**拆分变量**——为执行器引入独立网关密钥(如 `HIVE_LLM_API_KEY`,serve 侧供、随 spec 条件注入),三键剥离面与锚链尾保持不变,N190 契约零改动;次选为「按 `spec.orchestrate`/LLM 任务显式重注 `HIVE_API_KEY`」并同步改守卫与 README 契约。裁决前 honest 事实:标准部署下 serve 派发的全部 LLM 任务确定性 error,主能力全断,属**功能回归优先级最高**项 |
244
+ | 2 | **N68** | hive/exec.py:814/:845/:1588 × hive_mcp/mcp_server.py:403-409/:638 × orch.py:496 | medium | **大设计决策(④)**(v8 首报,本轮第 7 轮):mdcg_root 去留/加闸须裁定。**建议方向**:保留键 + 加「归属闸」——`spec.mdcg_root` 必须是 `realpath` 且在 serve 级配置的允许根(`MDCG_ROOT` 的父/白名单)之下,否则拒;serve 级已设 `MDCG_ROOT` 时维持 env 优先(本轮实测的现有语义),并在部署文档明写「不设 serve 级 MDCG_ROOT 即等于放开该参数」 |
245
+ | 3 | **N203** | scripts/dsh_log_index.py:564-568/:551-561/:487-493 | high | **大设计决策(④)**:id 口径(位置化 → 内容派生)涉及既有节点迁移与「一次性/可重跑」幂等契约变更。**建议方向**:token 扩为「会话全文摘要 + 首条 user」双因子,token 变化即视为新会话空间;id 改 `dsh-log-<token>-<内容哈希前 8>`;对存量位置化节点做一次性迁移或加「位置化兼容读」;同时在跑批输出中把「跳过的既有 id 与本次序位不一致」显式记账(消除静默丢索引) |
246
+ | 4 | **N199** | md_cg/tokens.py:343/:666 | medium | **次轮首补候选**:按 N184 家法给 `_save` 落 `FileLock`(strict) + `mkstemp` 唯一临时名(写前对账闸 N198 已落,两闸互补);守卫可扩现有 `test_n198_*` 或新增并发件 |
247
+ | 5 | **N202** | md_cg/mdcos.py:2523-2537 × :2562 | high | **次轮首补候选**:`_session_notes` 单点补 `_readable`(低风险高危);`scripts/migrate_restricted.py:72-77` passthrough 排除表同批补 `tags`/`session` |
248
+ | 6 | **N206** | md_cg/mcp_server.py:3783-3789/:3793 | high | **次轮首补候选**:3 行镜像 hive 面入口兜底(`try: _rpc(req) except Exception` 回 `-32603`);守卫可直接对 stdio 喂非对象行断言进程存活与 `-32603` 应答 |
249
+ | 7 | **N197** | md_cg/insight.py:241-247/:283-293/:297 × mcp_server.py:2816-2822 | medium | 小修批次(与 N208 同批,两者同属「写面绕过层闸」族):`verify` 写面补层闸 + `guard_write`;显式 verdict 是否要求证据/签章需一并小裁 |
250
+ | 8 | **N208** | md_cg/ccgc.py:830-892 × mcp_server.py:2563 × mdcos.py:3841-3899 | high | 小修 + 口径裁定:recalibrate 补层闸 + `guard_write` + corrections 换行过滤(机械修);「谁算编外验证方」对齐 N176 的 E052 口径(须裁决) |
251
+ | 9 | **N201** | md_cg/mdcos.py:1768-1776/:1922-1937 × mcp_server.py:3067 | high | inbox 记录加可见性过滤(或落盘即封套)+ `review_list` 过 `_readable`;与「提案落地策略」一并定 |
252
+ | 10 | **N204** | md_cg/docindex.py:192-199 | medium | 低风险机械修:合并段先截断父摘要再拼接(或对 merged 单独限长);`small` 子节记账;随低危批次 |
253
+ | 11 | **N205** | md_cg/trust.py:911-940/:952-963 × mcp_server.py:1817+ | medium | 低风险机械修:`describe`/`load_ledger` 出口统一过 `_readable`(与 get/search 同口径);随低危批次 |
254
+ | 12 | **N207** | src/cli.ts:46-56 × src/init.ts:342-352 | medium | 低风险小修:`realpathSync` 双向归一 + 补一条守卫(junction/软链形态);随低危批次 |
255
+ | 13 | **N90** | hive/hive_mcp/mcp_server.py:381-394 + `_t_poll` 两路 | low | 低危批次:`_t_poll` 条目级 try/except + `_result_view` 顶层 dict/content str 类型守卫(坏 job 隔离,不拖垮观测面) |
256
+ | 14 | **N91** | hive/serve_start.py:62-75/:91-95/:237 | low | 低危批次:`resolve()` 两形态对称 `or None` 归失败 + `load_config` 空白值进 bad 触发 fail fast(空串键不得静默覆盖宿主 env;与 A1-e 叠加风险一并处置) |
257
+ | 15 | **N177** | hive/exec.py:1017-1032 | low | 低危批次:后缀族改整段/中缀匹配补全 + NTFS ADS 形态(`notes.txt:secret`)纳入 |
258
+ | 16 | **A1-e** | hive/exec.py:963-971 | low | 维持文档化语义(v21 裁定),显式空值告警随低危批次(与 N91 同批最有价值) |
259
+ | 17 | **N186** | hive/exec.py:387-397 | low | 低危批次:`system_prompt_from` 对齐 `CONTEXT_TEXT_MAX=256KB` 截断 + 预算闸前置到读取之前 |
260
+ | 18 | **N187** | hive/exec.py:386-397 | low | 低危批次:读取 except 面补 UnicodeDecodeError → SpecError 归一(退出码 3→2,兑现头注契约) |
261
+ | 19 | **N188** | hive/src/main.rs:489-524 | low | 小修:`cmd_kill` 加终态闸(终态任务返回明确「强杀不适用」,非 ok:true 假回执),不留 kill 标志残留 |
262
+ | 20 | **N192** | hive/src/scheduler.rs:516-524 | low | `classify_result` 采信面纳入 ok 字段(或反向矛盾 `done+ok=false` 置 conflict),deps_gate 放行口径与 wm 凭证闸对齐 |
263
+ | 21 | **N193** | hive/wm.py:159-163/:173 | low | 校验补盘符相对形态判据(含 `:` 且无分隔符即拒);守卫补同盘/跨盘两样本;可达性受限,随低危批次 |
264
+ | 22 | (流程) | `npm run gate` R4 非追踪件面 | — | 非内容缺陷:本轮 6 件新守卫 + 本报告均为发布清单内未追踪新件,随编排会话入库提交后 R4 转绿(判据同 v21/v22 先例;见第四节-5 与第七节第 1 项) |
265
+ | 23 | (流程) | `docs/mdcg/功能调用映射表_v0.1.md` FUNCMAP 段 ×2 | — | **本轮报告会话实跑发现**:`python scripts/cogmap_sync.py check` 退出码 1——`cg(op=help)` 与 `stg(op=relation)` 的行号引用比真源低 15 行(文档 L1965/L1884 vs 真源 L1980/L1899)。归因已非侵入式坐实:`git show HEAD:md_cg/mcp_server.py` 的 `_help_call` 在 1884(与文档一致)、工作区在 1899,偏移恰为本轮 `md_cg/mcp_server.py` 净增的 +15 行(`git diff --numstat` +17/−2,hunks 全在 v21-R1 改动区)。**处置:提交前执行 `python scripts/cogmap_sync.py build` 重挂投影段**(零代码改动),再重跑 gate;建议把该 check 纳入修复会话的自检清单(本轮修复方未跑) |
266
+ | 24 | (残留) | 历轮编号字样 | — | v22 第 18 项(`hive/src/exec.rs`/`keyres.rs` 的「N185」按 v22 裁定应读作 N190)**本轮扫描仍在位**,未代改;另本轮的复核面「N196 = ccgc」字样按本报告 3.0-2 应读作 N208(仅存在于复核材料,无树内残留) |
267
+ | 25 | (范围外) | scripts/check_registry_tarball.py:40-42 × check_publish_artifact.py:256-265 | — | 同类「顶层非对象 package.json」族缺口(发布门禁脚本裸崩/AttributeError),fail-loud 开发件,建议另开 ask 处置,本轮未修未编号 |
268
+
269
+ ---
270
+
271
+ ## 六、纪律合规声明
272
+
273
+ 1. **复现环境红线**:四区攻防复现与修复验证全部在系统临时目录/临时库/哑令牌/哑密钥环境进行(哑主密钥 32 字节常量、哑令牌、哑 KEK、临时 jobs 池、临时图根/临时包根、本机丢弃端口,绝不出网)——**未触真实令牌库、真实在役 serve、真实在役数据目录与 DSH 探针节点**。本会话额外确认:在役 serve(pid 19648)全程未触碰,两 crate cargo test 均在**树外临时 target 目录**构建(仓内 `hive/target/release/hive.exe` 被在役进程持有,本会话按纪律不覆盖、不杀进程)。
274
+ 2. **本报告会话第一手实跑清单**:`WORKSPACE_INDEX.md` 查阅定位(工作纪律第 18 条);编号基线与源码树占号扫描(第四节-1);6 件新守卫逐件复跑(第四节-2);`python -X utf8 -m md_cg.run_tests` 全量 234/234(第四节-3);hive/rust 两 crate `cargo test`(第四节-4);`npm run gate`(第四节-5,含短路后四检查器逐条补跑);前述 20 余处源码行号读码核实(第四节-6);历轮复测计数 grep(第四节-7)。**未跑项**(未跑 `cargo fmt`、未跑 TS 面 `npm test`/`tsc`、未做 `git commit`、未在报告落盘后重跑 gate、未执行 `cogmap_sync build`)在第七节集中声明。
275
+ 3. **转述与归属**:四区攻防复现、修复红绿双态(git stash)为复核/修复会话第一手实测(材料附命令与输出),本报告如实转述并逐项标注归属(第二节各条「修复会话第一手」、3.1/3.2 各条证据来源);未重复 stash 操作(避免扰动并行会话工作区)。凡本会话未跑的动态检查,文中一律标注来源,不冒充第一手结论。
276
+ 4. **编号裁定**:见 3.0——N195–N208 全局唯一(本会话扫描核对),次轮自 **N209** 续编;本轮唯一撞号(N196)按 v22 3.0-② 先例消歧并如实注记(3.0-4)。报告员未代改任何源码注释/守卫文件名。
277
+ 5. **报告面纪律**:本报告**未写入本机绝对路径**(材料证据与实测输出中的本机盘符路径已转写为「系统临时目录/临时池/临时根/仓内构建目录」等中性表述;N193 的「盘符:名字」样例系缺陷本体攻击形态的类目描述,非本机路径);**未执行 git commit**(工作区改动与报告落盘由编排会话负责提交)。
278
+ 6. **门禁如实呈现**:python 全量回归与两 crate cargo 通过为本会话第一手复跑;`npm run gate` **实跑 VERDICT=FAIL、退出码 1**,本报告按原样输出逐面归因(内容面 R1/R2/R3 全 PASS;R4 非追踪件面命中=7 点名在册;链式短路未及的四检查器由本会话逐条补跑并如实呈报 `cogmap_sync check` 红及其 +15 行漂移归因)——未粉饰、未绕过、**未以「内容面合格」替代整体 VERDICT**,也未把 FAIL 说成 PASS。
279
+ 7. **隐私卫生**:本报告不含真实凭据/密钥/令牌与 PII;哑值以「哑主密钥/哑令牌/哑 KEK」类目表述,hash/锚值与临时路径不作为可复用的凭据形态串出现——报告随 npm 包发布(`package.json files` 含 docs/),不携带可误认的凭据/PII 形态串。
280
+
281
+ ---
282
+
283
+ ## 七、跳过项及原因
284
+
285
+ 1. **`npm run gate` 的最终归因与「入库后转绿」断言**:本会话实跑结果已全量如实呈报(第四节-5:VERDICT=FAIL、内容面三项 PASS、R4 命中=7 为未追踪新件、其后四检查器逐条补跑中 `cogmap_sync` 红且归因到本轮 +15 行漂移)。**未做**的部分:①未在报告落盘**之后**再跑一次 gate(当前落盘稿即本报告,与实跑时点一致,故无需重跑;下一次实跑应在编排会话入库 + `cogmap_sync build` 之后);②未代编排会话断言「入库后 gate 必绿」——`cogmap_sync` 需先重挂投影(第五节第 23 项),否则即便 R4 转绿该检查器仍会红。这两点均为提交前置动作,本报告不越位执行(未执行 `cogmap_sync build`,避免改动生成投影文件而与编排会话的提交面冲突)。
286
+ 2. **修复项红态的重复执行**:报告员未重复 git stash 双态验证(避免扰动并行会话工作区状态);红态输出以修复会话材料为准,绿态已由本会话独立复跑佐证(第四节-2/3/4)。
287
+ 3. **N196 红态的取得方式**:该条修复先于其守卫落码,红态由修复会话 `git stash push -- md_cg/mdcg.py md_cg/mdcos.py` 后复跑取得(材料如实标注,非「先写红守卫再修」的标准序)——本报告照实转述,未粉饰为标准序。
288
+ 4. **POSIX 侧 N207 复现腿**(`.bin` 符号链接 / `npx` 实链路):本机无 POSIX Node,Windows 文件符号链接创建 EPERM,该腿依 Node 主入口默认 realpath 解析语义**推得**,未实测(材料与 3.1-M 均如实声明)。
289
+ 5. **N68 的跨租户正文读出**:复核会话只实测到「指定目录被建成/挂载为记忆根(整套结构 + 加密身份信封落盘)」与 `op=read` 未读出正文,未证跨租户正文读出、也不主张在已设 serve 级 `MDCG_ROOT` 的标准部署形态下可达——边界如实保留(3.2-L2)。
290
+ 6. **`cargo fmt` / TS 面 `npm test` / `tsc`**:本轮改动含 TS 面跳过(`src/` 未改);未跑 `cargo fmt`(工具链未装 rustfmt,修复材料声明,本会话未复核);未跑 `npm test`(本轮无 TS 改动)。
291
+ 7. **N203 的「删首条 user 致 token 变化」支线**:复核材料未复跑,本报告不作结论(3.1-I 已如实标注)。
292
+ 8. **N90 的 `_t_doctor` 崩点**:复核实测只在 status 为 dict 时统计、不调 `_result_view`,故未复现 doctor 崩点——本条只主张 `_t_poll` 两路实测崩(与候选自注一致)。
293
+ 9. **本轮未复跑的 legacy 动态证据**(N68/N177/A1-e/N90/N91/N186–N193 的复现输出、N184 的并发复测):本会话只做**读码核实**(行号见第四节-6),动态证据按材料转述并标注来源;如需重新实测,建议随其对应修复批次同批进行(避免重复消耗临时环境)。