@furongjun1999/dsh-memory 0.4.7 → 0.4.9

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 (325) hide show
  1. package/README.md +130 -47
  2. package/codebuddy/CODEBUDDY.md +21 -10
  3. package/codebuddy/README.md +13 -1
  4. package/codebuddy/mcp.json +9 -0
  5. package/docs/GBrain/345/217/257/345/200/237/351/211/264/347/202/271_/347/201/265/346/236/242/350/220/275/347/202/271/344/272/244/346/216/245_20260919.md +169 -0
  6. package/docs/Pi/345/217/257/345/255/246/344/271/240/344/274/230/347/202/271_/347/201/265/346/236/242/345/244/247/350/204/221/346/224/271/350/277/233/344/272/244/346/216/245_20260915.md +144 -0
  7. package/docs/README.md +111 -0
  8. package/docs/discipline/harnesses.yaml +226 -152
  9. package/docs/discipline/templates/full.md.tmpl +61 -58
  10. package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.md +127 -0
  11. package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.png +0 -0
  12. package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_/347/201/265/346/236/242_vs_dejavu_/347/273/237/344/270/200/350/257/204/345/210/206_v7.md +202 -0
  13. package/docs/experiments/linkref_backfill/candidates_20260917.json +726 -0
  14. package/docs/experiments/linkref_backfill/candidates_internal_20260917.json +602 -0
  15. package/docs/experiments/linkref_backfill/candidates_internal_v2.json +603 -0
  16. package/docs/experiments/linkref_backfill/candidates_secret_20260917.json +884 -0
  17. package/docs/experiments/linkref_backfill/candidates_secret_v2.json +789 -0
  18. package/docs/experiments/m4-role-probe/census.py +86 -0
  19. package/docs/experiments/m4-role-probe/probe.py +89 -0
  20. package/docs/experiments/mapped_confidence/bench_mapped_conf.py +216 -0
  21. package/docs/experiments/mapped_confidence/post_check.py +75 -0
  22. package/docs/experiments/mapped_confidence/repro_thirdparty_tol.py +83 -0
  23. package/docs/experiments/mapped_confidence/result_mapped_conf.json +215 -0
  24. package/docs/hive//345/244/232/347/253/257harness/351/200/232/344/277/241/345/245/221/347/272/246_v0.1.md +42 -0
  25. package/docs/hive//346/243/200/347/264/242/346/224/266/346/225/233/345/256/236/346/265/213/344/270/216S1b/350/256/276/350/256/241_v0.1.md +43 -0
  26. 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 +102 -0
  27. package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S1b/344/270/216/345/217/254/345/233/236/346/235/203/350/241/241_v0.1.md +57 -0
  28. package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S7/345/200/222/346/216/222/345/200/231/351/200/211/345/261/202_v0.1.md +126 -0
  29. 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 +503 -0
  30. package/docs/{ → hive/}/350/234/202/345/267/242/345/267/245/344/275/234/350/256/260/345/277/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +14 -2
  31. package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -0
  32. package/docs/{README → mdcg/README}/350/257/246/347/273/206/347/211/210_v0.4.5.md +631 -625
  33. package/docs/{ → mdcg/}/344/270/273/344/273/243/347/220/206/345/255/220/344/273/243/347/220/206/350/256/260/345/277/206/346/236/266/346/236/204/350/256/276/350/256/241.md +1 -1
  34. package/docs/mdcg//344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/345/245/221/347/272/246_v0.1.md +82 -0
  35. package/docs/mdcg//345/205/250/345/272/223/344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/350/256/241/345/210/222_v0.1.md +600 -0
  36. 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 +263 -0
  37. package/docs/{ → mdcg/}/345/215/225/345/205/203/350/207/252/346/210/221/351/224/232/347/202/271_/347/263/273/347/273/237/346/217/220/347/244/272/350/257/215/346/240/207/345/207/206_v0.3.md +1 -1
  38. package/docs/mdcg//345/255/220/344/273/243/347/220/206/351/205/215/347/275/256/346/240/207/345/207/206_v0.5.md +236 -0
  39. package/docs/{ → mdcg/}/346/272/220/347/240/201/347/272/247/346/236/266/346/236/204/345/256/241/350/256/241_GPT/346/211/271/350/257/204/345/257/271/347/205/247_v1.0.md +2 -2
  40. package/docs/{ → mdcg/}/347/201/265/346/236/242/344/270/211/345/261/202/346/213/206/345/210/206/350/247/204/345/210/222_v0.1.md +181 -181
  41. 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 +172 -0
  42. package/docs/mdcg//347/216/257/344/272/214_/347/231/275/347/256/261/345/241/253/345/205/205/346/265/201/346/260/264/347/272/277_v0.1.md +31 -0
  43. package/docs/{ → mdcg/}/347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +2 -2
  44. package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_G4-G8/347/274/272/345/217/243/350/243/201/345/256/232/345/215/225_v0.1.md +1 -1
  45. 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 +4 -4
  46. package/docs/{ → mdcg/}/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_MdCGOS/344/270/216MCP/346/216/245/345/205/245_v0.1.md +2 -2
  47. package/docs/mdcg//350/267/250/347/253/257/351/252/214/350/257/201/344/270/216/345/220/214/346/255/245/345/215/217/350/256/256_v0.1.md +93 -0
  48. package/docs/plans/GridWorld/346/234/200/345/260/217/351/227/255/347/216/257/350/247/204/346/240/274_v0.1.md +176 -0
  49. package/docs/{ → swarm/}/350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +3 -3
  50. package/docs/swarm//350/234/202/347/276/244/345/220/214/351/224/231/346/243/200/346/265/213/345/256/236/351/252/214/345/215/217/350/256/256_v0.1.md +242 -0
  51. package/docs/theory//345/215/225/347/272/277/347/250/213/344/270/216/346/263/250/346/204/217/345/212/233/351/233/206/344/270/255_/346/227/240/344/272/211/350/256/256/347/220/206/350/256/272/346/226/207/346/241/243_v1.0.md +129 -0
  52. package/docs/theory//345/271/266/345/217/221/345/277/205/347/204/266/346/200/247/347/220/206/350/256/272_v0.2.md +134 -0
  53. package/docs/theory//346/246/202/345/277/265/345/210/206/345/261/202/345/257/271/351/275/220/350/241/250_v0.1.md +145 -0
  54. package/docs/{ → theory/}/347/220/206/350/256/272_/346/234/272/345/210/266_/344/273/243/347/240/201_/345/256/236/351/252/214_/347/274/272/345/217/243/347/237/251/351/230/265_v0.1.md +6 -6
  55. package/docs/{ → theory/}/347/220/206/350/256/272/344/273/223/346/213/206/345/210/206/344/270/216/347/231/275/347/256/261/347/237/245/350/257/206/345/272/223/345/206/205/350/277/201_v0.1.md +1 -1
  56. package/docs/theory//350/256/244/347/237/245/344/273/243/347/220/206/344/270/216/346/224/266/346/225/233/347/273/223/346/236/204_/346/235/241/344/273/266/350/256/272/351/207/215/346/236/204_v0.1.md +221 -0
  57. package/docs/world_model//344/270/226/347/225/214/346/250/241/345/236/213_/347/245/236/347/273/217/347/275/221/347/273/234/345/272/225/345/261/202/346/236/266/346/236/204_v1.0.md +237 -0
  58. package/docs//345/255/230/347/256/227/344/270/200/344/275/223/346/236/266/346/236/204/345/255/246/344/271/240_/345/244/226/351/203/250/347/220/206/350/256/272/345/257/271/347/205/247/344/270/216/350/267/257/347/272/277/344/272/244/346/216/245_20260916.md +98 -0
  59. package/docs//345/255/230/347/256/227/344/270/200/344/275/223/347/245/236/347/273/217/347/275/221/347/273/234/346/236/266/346/236/204_/346/200/273/347/272/262/344/270/216/344/272/244/346/216/245_20260916.md +109 -0
  60. 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 +434 -405
  61. package/docs//347/201/265/346/236/242/350/207/252/346/210/221/346/224/271/350/277/233/345/267/245/344/275/234/350/256/241/345/210/222_/345/244/226/351/203/250/347/240/224/347/251/266/347/263/273/345/210/227/345/220/270/346/224/266_v1_20260919.md +286 -0
  62. package/docs//347/231/275/347/256/261/345/214/226/347/272/262/351/242/206_/344/270/211/351/241/271/347/233/256/345/255/246/344/271/240/346/200/273/346/236/266/346/236/204/344/270/216Ghidra/344/272/244/346/216/245_20260916.md +104 -0
  63. package/docs//350/256/260/345/277/206/350/257/204/345/256/241/347/263/273/347/273/237_/347/253/213/351/241/271/350/256/276/350/256/241/344/270/216/346/226/275/345/267/245/344/272/244/346/216/245_20260915.md +183 -0
  64. package/dsh/README.md +34 -1
  65. package/dsh/cordis.yml.example +13 -7
  66. package/dsh/hive-mcp-probe.mjs +94 -0
  67. package/dsh/hive-mcp.example.yml +62 -0
  68. package/dsh/update-lingshu.bat +11 -0
  69. package/dsh/update-lingshu.ps1 +337 -0
  70. package/lib/hooks.d.ts +8 -0
  71. package/lib/hooks.js +27 -24
  72. package/lib/index.d.ts +4 -2
  73. package/lib/index.js +29 -6
  74. package/lib/lib/datapath.d.ts +76 -1
  75. package/lib/lib/datapath.js +199 -13
  76. package/lib/lib/mdcg_client.d.ts +6 -3
  77. package/lib/lib/mdcg_client.js +6 -5
  78. package/lib/lib/mutual.js +4 -4
  79. package/lib/lib/prompt_safety.d.ts +48 -0
  80. package/lib/lib/prompt_safety.js +62 -0
  81. package/lib/lib/token_store.js +4 -5
  82. package/md_cg/audit.py +91 -2
  83. package/md_cg/autonomy.py +86 -15
  84. package/md_cg/backfill.py +36 -1
  85. package/md_cg/backfill_bigdomain.py +34 -0
  86. package/md_cg/bench6_arms.py +28 -1
  87. package/md_cg/bench6_common.py +10 -1
  88. package/md_cg/bench6_competitors.py +6 -1
  89. package/md_cg/bench_axis_domain.py +9 -1
  90. package/md_cg/bench_blind_comp.py +7 -1
  91. package/md_cg/bench_en_atoms_public.py +9 -0
  92. package/md_cg/bench_governance.py +348 -0
  93. package/md_cg/bench_lme_zh.py +16 -1
  94. package/md_cg/bench_locomo.py +2 -1
  95. package/md_cg/bench_locomo_zh.py +16 -1
  96. package/md_cg/bench_locomo_zh_public.py +4 -1
  97. package/md_cg/bench_longmem.py +2 -1
  98. package/md_cg/bench_membench.py +37 -6
  99. package/md_cg/bench_p0.py +4 -1
  100. package/md_cg/bench_progressive.py +61 -10
  101. package/md_cg/bench_role_views.py +238 -0
  102. package/md_cg/bench_task_ab.py +8 -1
  103. package/md_cg/bench_task_ab_llm.py +13 -1
  104. package/md_cg/bench_unified_en.py +6 -1
  105. package/md_cg/bench_zh_mad.py +20 -1
  106. package/md_cg/blindspot_tickets.py +123 -0
  107. package/md_cg/branches.py +286 -0
  108. package/md_cg/build_postings.py +73 -0
  109. package/md_cg/ccgc.py +949 -0
  110. package/md_cg/census.py +5 -1
  111. package/md_cg/chain.py +24 -3
  112. package/md_cg/codeindex.py +134 -17
  113. package/md_cg/coldverify.py +265 -0
  114. package/md_cg/comment_gate.py +338 -0
  115. package/md_cg/cond_compose.py +190 -0
  116. package/md_cg/cond_facts.py +155 -0
  117. package/md_cg/cond_template.json +107 -0
  118. package/md_cg/condition_anchor.py +143 -0
  119. package/md_cg/conformance.py +727 -0
  120. package/md_cg/consistency.py +25 -2
  121. package/md_cg/consolidate.py +53 -2
  122. package/md_cg/corpus.py +5 -1
  123. package/md_cg/crosscheck.py +42 -2
  124. package/md_cg/crypto.py +35 -1
  125. package/md_cg/d_meta.py +310 -0
  126. package/md_cg/datapath.py +201 -26
  127. package/md_cg/docindex.py +122 -1
  128. package/md_cg/eval_common.py +35 -6
  129. package/md_cg/evidence.py +27 -1
  130. package/md_cg/evolution.py +21 -1
  131. package/md_cg/export.py +11 -1
  132. package/md_cg/forgetting.py +34 -4
  133. package/md_cg/fsutil.py +81 -2
  134. package/md_cg/hotcache.py +214 -0
  135. package/md_cg/hyperedge.py +251 -0
  136. package/md_cg/identity.py +20 -3
  137. package/md_cg/insight.py +19 -3
  138. package/md_cg/lexicon/build_cedict_en_zh.py +9 -0
  139. package/md_cg/lexicon/build_standard_en.py +171 -168
  140. package/md_cg/lexicon/expand_en_zh.py +6 -0
  141. package/md_cg/lifecycle.py +273 -0
  142. package/md_cg/linkref.py +281 -0
  143. package/md_cg/links.py +29 -1
  144. package/md_cg/mcp_server.py +894 -168
  145. package/md_cg/md_whitebox.py +53 -1
  146. package/md_cg/mdcg.py +1205 -41
  147. package/md_cg/mdcos.py +1060 -76
  148. package/md_cg/metacognition.py +39 -4
  149. package/md_cg/migrate.py +4 -0
  150. package/md_cg/migrate_aeis.py +221 -213
  151. package/md_cg/migrate_roleplay.py +8 -0
  152. package/md_cg/migrate_wisdom_graph.py +14 -1
  153. package/md_cg/mreview/__init__.py +25 -0
  154. package/md_cg/mreview/__main__.py +110 -0
  155. package/md_cg/mreview/bundle.py +178 -0
  156. package/md_cg/mreview/candidates.py +262 -0
  157. package/md_cg/mreview/govern.py +694 -0
  158. package/md_cg/mreview/locate.py +939 -0
  159. package/md_cg/mreview/pipeline.py +729 -0
  160. package/md_cg/mreview/rules/duplication.json +21 -0
  161. package/md_cg/mreview/rules/field_coverage.json +54 -0
  162. package/md_cg/mreview/rules/source_license.json +21 -0
  163. package/md_cg/mreview/rules/template_flow.json +21 -0
  164. package/md_cg/mreview/ruleset.py +253 -0
  165. package/md_cg/nodefile.py +269 -1
  166. package/md_cg/pooling.py +23 -1
  167. package/md_cg/postings.py +298 -0
  168. package/md_cg/predict.py +113 -15
  169. package/md_cg/progressive.py +3 -0
  170. package/md_cg/protect.py +18 -5
  171. package/md_cg/protocol.py +372 -0
  172. package/md_cg/provenance.py +262 -0
  173. package/md_cg/reach.py +453 -0
  174. package/md_cg/refindex.py +88 -4
  175. package/md_cg/refine.py +20 -1
  176. package/md_cg/roleviews.py +89 -0
  177. package/md_cg/routing.py +76 -0
  178. package/md_cg/scrub.py +68 -3
  179. package/md_cg/security.py +26 -1
  180. package/md_cg/self_state.py +65 -2
  181. package/md_cg/selfreport.py +151 -0
  182. package/md_cg/semantic/canonical.py +5 -0
  183. package/md_cg/semantic/en_normalizer.py +364 -295
  184. package/md_cg/semantic/zh_en_atoms.py +139 -136
  185. package/md_cg/signer.py +41 -1
  186. package/md_cg/sources.py +583 -547
  187. package/md_cg/statushdr.py +179 -0
  188. package/md_cg/stg.py +59 -18
  189. package/md_cg/subgraph.py +23 -0
  190. package/md_cg/sustain.py +74 -1
  191. package/md_cg/tasks.py +471 -0
  192. package/md_cg/test_action_derive.py +203 -0
  193. package/md_cg/test_audit_rotate.py +270 -0
  194. package/md_cg/test_autonomy.py +26 -0
  195. package/md_cg/test_bench_governance.py +102 -0
  196. package/md_cg/test_blindspot_tickets.py +166 -0
  197. package/md_cg/test_branches.py +249 -0
  198. package/md_cg/test_ccg_perturb.py +1 -1
  199. package/md_cg/test_ccgc.py +433 -0
  200. package/md_cg/test_codeindex.py +338 -0
  201. package/md_cg/test_comment_gate.py +187 -0
  202. package/md_cg/test_cond_compose_anchors.py +76 -0
  203. package/md_cg/test_condition_anchor.py +82 -0
  204. package/md_cg/test_conformance.py +343 -0
  205. package/md_cg/test_d_meta.py +412 -0
  206. package/md_cg/test_datapath_root.py +188 -0
  207. package/md_cg/test_en_pipeline.py +24 -0
  208. package/md_cg/test_gain_gate.py +47 -1
  209. package/md_cg/test_health_scale.py +173 -0
  210. package/md_cg/test_hot_cold.py +187 -0
  211. package/md_cg/test_hyperedge.py +245 -0
  212. package/md_cg/test_identity_attribution.py +6 -0
  213. package/md_cg/test_index_durability.py +224 -0
  214. package/md_cg/test_lifecycle.py +309 -0
  215. package/md_cg/test_linkref.py +306 -0
  216. package/md_cg/test_md_access_parity.py +15 -3
  217. package/md_cg/test_mr_m1.py +769 -0
  218. package/md_cg/test_mr_m2.py +587 -0
  219. package/md_cg/test_mr_m3.py +710 -0
  220. package/md_cg/test_mr_m4.py +485 -0
  221. package/md_cg/test_p1.py +1 -1
  222. package/md_cg/test_p11_consistency.py +1 -1
  223. package/md_cg/test_p12_metacognition.py +2 -2
  224. package/md_cg/test_p16_self_state.py +1 -1
  225. package/md_cg/test_p26_refindex.py +50 -21
  226. package/md_cg/test_p27_docindex.py +258 -4
  227. package/md_cg/test_p28_refcheck.py +1 -1
  228. package/md_cg/test_p29_session_ingest_export.py +1 -1
  229. package/md_cg/test_p2_mcp.py +7 -1
  230. package/md_cg/test_p31_insight.py +24 -0
  231. package/md_cg/test_p38_contextualize.py +1 -1
  232. package/md_cg/test_p39_vision_evidence.py +1 -1
  233. package/md_cg/test_p40_refine_worklist.py +1 -1
  234. package/md_cg/test_p41_evolve_patrol.py +1 -1
  235. package/md_cg/test_p42_provenance.py +1 -1
  236. package/md_cg/test_p43_pooling.py +41 -13
  237. package/md_cg/test_p44_md_whitebox.py +14 -1
  238. package/md_cg/test_protocol.py +243 -0
  239. package/md_cg/test_reach.py +378 -0
  240. package/md_cg/test_reach_keys.py +201 -0
  241. package/md_cg/test_reach_meta_exits.py +145 -0
  242. package/md_cg/test_read_clip.py +141 -0
  243. package/md_cg/test_retr_s1.py +340 -0
  244. package/md_cg/test_retr_s1b.py +209 -0
  245. package/md_cg/test_retr_s3.py +194 -0
  246. package/md_cg/test_retr_s4.py +163 -0
  247. package/md_cg/test_retr_s5.py +200 -0
  248. package/md_cg/test_retr_s6.py +157 -0
  249. package/md_cg/test_retr_s7.py +385 -0
  250. package/md_cg/test_retr_s8_time.py +316 -0
  251. package/md_cg/test_retr_s9_edges.py +286 -0
  252. package/md_cg/test_retr_s9_entity_ctx.py +175 -0
  253. package/md_cg/test_review_conformance.py +367 -0
  254. package/md_cg/test_role_views.py +354 -0
  255. package/md_cg/test_tasks.py +409 -0
  256. package/md_cg/test_tool_face.py +189 -0
  257. package/md_cg/test_trust.py +361 -0
  258. package/md_cg/test_twophase.py +286 -0
  259. package/md_cg/test_units_poll.py +71 -0
  260. package/md_cg/test_v14_fixes.py +397 -0
  261. package/md_cg/test_validity_filter.py +280 -0
  262. package/md_cg/test_wisdom_md_store.py +7 -3
  263. package/md_cg/test_writepipe.py +214 -0
  264. package/md_cg/theory.py +17 -2
  265. package/md_cg/tokens.py +134 -12
  266. package/md_cg/tool_face.py +261 -0
  267. package/md_cg/trust.py +943 -0
  268. package/md_cg/twophase.py +232 -0
  269. package/md_cg/units.py +665 -0
  270. package/md_cg/vision_evidence.py +25 -2
  271. package/md_cg/weights.py +25 -2
  272. package/md_cg/whitebox.py +33 -2
  273. package/md_cg/whitebox_kb/data/verify_cache.json +21233 -360
  274. package/md_cg/whitebox_kb/data/verify_savings.jsonl +5124 -0
  275. package/md_cg/whitebox_kb/wisdom/audit_log/chain_heat.json +10 -10
  276. package/md_cg/whitebox_kb/wisdom/code_compose.py +113 -6
  277. package/md_cg/whitebox_kb/wisdom/code_solidified.json +1 -1
  278. package/md_cg/whitebox_kb/wisdom/verifier.py +340 -55
  279. package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db +0 -0
  280. package/md_cg/writelimit.py +37 -7
  281. package/md_cg/writepipe.py +543 -0
  282. package/package.json +2 -2
  283. package/skills/skills/designer-perspective/scripts/__pycache__/designer.cpython-310.pyc +0 -0
  284. package/skills/skills/designer-perspective/scripts/designer.py +17 -1
  285. package/skills/skills/designer-perspective/tests/selftest.py +3 -1
  286. package/src/hooks.ts +27 -22
  287. package/src/index.ts +33 -6
  288. package/src/lib/datapath.ts +211 -13
  289. package/src/lib/mdcg_client.ts +12 -8
  290. package/src/lib/mutual.ts +411 -411
  291. package/src/lib/prompt_safety.ts +62 -0
  292. package/src/lib/token_store.ts +4 -5
  293. package/zcode/AGENTS.md +21 -10
  294. package/zcode/README.md +4 -0
  295. package/docs//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +0 -221
  296. /package/docs/{AGI → eval/AGI}/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v1.0.md" +0 -0
  297. /package/docs/{AGI → eval/AGI}/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v2.0.md" +0 -0
  298. /package/docs/{ → eval/}/345/256/236/351/252/214/346/226/271/346/241/210_/345/255/246/344/271/240/351/227/255/347/216/257AB/344/270/216/346/250/252/350/257/204_v1.0.md" +0 -0
  299. /package/docs/{ → eval/}/346/250/252/350/257/204_/345/205/255/345/256/266100/351/242/230/344/270/255/350/213/261/345/217/214/346/237/245_v1.0.md" +0 -0
  300. /package/docs/{guardrail-charter.md → mdcg/guardrail-charter.md} +0 -0
  301. /package/docs/{lingshu_tutorial.html → mdcg/lingshu_tutorial.html} +0 -0
  302. /package/docs/{memory-assessment.html → mdcg/memory-assessment.html} +0 -0
  303. /package/docs/{memory_score.html → mdcg/memory_score.html} +0 -0
  304. /package/docs/{memory_score.png → mdcg/memory_score.png} +0 -0
  305. /package/docs/{release_v0.3.0.md → mdcg/release_v0.3.0.md} +0 -0
  306. /package/docs/{release_v0.4.5.md → mdcg/release_v0.4.5.md} +0 -0
  307. /package/docs/{tool_table_v0.3.0.md → mdcg/tool_table_v0.3.0.md} +0 -0
  308. /package/docs/{ → mdcg/}/344/273/244/347/211/214/344/270/216/350/247/222/350/211/262/346/235/203/350/201/214/345/210/206/347/246/273_v0.1.md" +0 -0
  309. /package/docs/{ → mdcg/}/347/201/265/346/236/24282/345/267/245/345/205/267_/345/212/237/350/203/275/346/225/264/347/220/206/344/270/216/350/277/201/347/247/273/346/230/240/345/260/204_v0.1.md" +0 -0
  310. /package/docs/{ → mdcg/}/347/201/265/346/236/242MCP/345/267/245/345/205/267/346/200/273/350/241/250_v3.4.md" +0 -0
  311. /package/docs/{ → mdcg/}/347/201/265/346/236/242_/350/207/252/346/210/221/345/261/202/345/256/232/344/271/211.md" +0 -0
  312. /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_MD/347/233/256/345/275/225/346/226/271/346/241/210_v0.1.md" +0 -0
  313. /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_/346/235/241/344/273/266/347/251/272/351/227/264/345/220/210/346/210/220/344/270/216/347/224/237/346/225/210/346/235/241/344/273/266/345/217/243/345/276/204_v0.1.md" +0 -0
  314. /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276/344/275/234/344/270/272/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_/350/257/204/344/274/260/344/270/216/350/267/257/347/272/277_v0.1.md" +0 -0
  315. /package/docs/{ → plans/}/345/221/275/345/220/215/346/262/273/347/220/206_/351/241/271/347/233/256/350/256/241/345/210/222.md" +0 -0
  316. /package/docs/{ → plans/}/347/237/245/350/257/206/345/233/276/350/260/261/351/241/271/347/233/256_/344/272/244/346/216/245/346/226/207/346/241/243_20260914.md" +0 -0
  317. /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/344/275/277/347/224/250/346/212/245/345/221/212_20260913.md" +0 -0
  318. /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/345/212/237/350/203/275/350/257/264/346/230/216_v0.6.md" +0 -0
  319. /package/docs/{ → swarm/}/350/234/202/347/276/244/347/233/262/345/214/272/346/240/207/350/256/260_v1.0.md" +0 -0
  320. /package/docs/{ → theory/}/344/277/241/346/201/257/345/267/256/344/270/272/344/273/200/344/271/210/345/277/205/347/204/266/345/255/230/345/234/250/344/270/224/350/207/252/347/204/266/346/211/251/345/244/247.md" +0 -0
  321. /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/345/205/254/347/220/206/345/214/226/345/237/272/347/237/263.md" +0 -0
  322. /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/350/256/244/347/237/245/350/277/207/347/250/213.md" +0 -0
  323. /package/docs/{ → theory/}/346/231/272/350/203/275/350/256/2723.4.md" +0 -0
  324. /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/346/230/257/344/273/200/344/271/210/357/274/237.md" +0 -0
  325. /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/347/263/273/345/210/227/302/267/347/254/254/344/272/224/347/257/207/357/274/232/350/256/251AI/347/234/237/346/255/243/350/243/205/344/270/212/350/256/260/345/277/206.md" +0 -0
@@ -0,0 +1,238 @@
1
+ # -*- coding: utf-8 -*-
2
+ """角色化读取视图四臂对照 bench(第四阶段计划批次 D,H5 验收)。
3
+
4
+ 臂:
5
+ A0 基线 view=None + include_work=True(无差别全量读取:
6
+ 不看角色、含工作回执——真无差别口径)
7
+ A1 main 主代理(结论与修正历史)
8
+ A2 verifier 验证端(判据面与环境陷阱)
9
+ A3 receipt 回执审计(命令与预期输出)
10
+
11
+ 指标(复用 budget_tokens 装包口径):
12
+ tokens = recall(budget_tokens=BIG) 的 tokens_used——同等读取意图下
13
+ 实际装入内容的消耗;budget 给足以免截断干扰四臂横比;
14
+ hit@k = gold 在 pack 内位置(k=1/5/10)+ MRR。
15
+
16
+ 跑法:
17
+ 对齐跑 Q_role × view=role 对比 Q_role × 基线——H5 主判据
18
+ (各对齐臂 token 下降 且 命中率不降);
19
+ 隔离跑 错配组合(如 Q_receipt × main 臂)gold 期望不可见——
20
+ view 过滤真实生效的硬边界实证。
21
+
22
+ 语料:确定性构造(固定词面、无随机、无外部数据依赖),临时库自建自清理。
23
+ 退出码:0 = H5 通过;1 = 权衡(如实报告,禁止为凑指标调规则表后不复跑)。
24
+
25
+ 运行:python -m md_cg.bench_role_views
26
+ """
27
+
28
+ import shutil
29
+ import sys
30
+ import tempfile
31
+
32
+ from .mdcos import MdCGSecure
33
+ from .security import Principal
34
+
35
+ BIG_BUDGET = 100000 # 给足预算:四臂横比看内容消耗差异,不受截断干扰
36
+ # 候选集由词面命中决定(检索器语义,非全池排序——探针实证),k 只是宽松
37
+ # 上限:给足以免截断干扰四臂横比;命中率报 hit@1/5/10 + MRR(窗口内位置)。
38
+ TOP_K = 32
39
+
40
+ # ---------------- 语料(确定性;(nid, layer, content_kind, role, content)) ----------------
41
+ _CORPUS = [
42
+ # main 域:结论与修正历史(knowledge + text/work_done,无 role)
43
+ ("bm1", "knowledge", "text", None,
44
+ "发布回滚结论:主支合并验证完成,回滚脚本已归档备查"),
45
+ ("bm2", "knowledge", "work_done", None,
46
+ "编译链修复工作完成:名实校验五处缺陷全部清零"),
47
+ ("bm3", "knowledge", "text", None,
48
+ "缓存刷新结论:快照增量重放语义已锁定不变"),
49
+ ("bm4", "knowledge", "work_done", None,
50
+ "索引迁移完成:三处白名单补齐内容类型字段"),
51
+ ("bm5", "knowledge", "text", None,
52
+ "检索对齐结论:四路融合排序与基线逐位一致"),
53
+ # verifier 域:判据面与环境陷阱(ccg_marks 或 contextual 层 text)
54
+ ("bv1", "knowledge", "ccg_marks", None,
55
+ "环境陷阱判据:GBK 解码异常须显式声明 UTF-8 标志"),
56
+ ("bv2", "knowledge", "ccg_marks", None,
57
+ "静默失败判据:多行内联命令退出码不可信,须脚本文件驱动"),
58
+ ("bv3", "contextual", "text", None,
59
+ "情境上下文实录:命令链尾部被引号换行吞没"),
60
+ ("bv4", "contextual", "ccg_marks", None,
61
+ "情境判据:提交显示成功但推送静默未执行的取证要点"),
62
+ ("bv5", "contextual", "text", None,
63
+ "上下文补充:重建成果曾被陈旧常驻进程覆盖回滚"),
64
+ # receipt 域:命令与预期输出(code + WORK_ROLES)
65
+ ("br1", "knowledge", "code", "command",
66
+ "推送命令:git push origin main,预期输出复核通过"),
67
+ ("br2", "knowledge", "code", "tool-output",
68
+ "状态命令输出:ahead 2 尚未推送,工作区存在改动"),
69
+ ("br3", "knowledge", "code", "edit",
70
+ "补丁片段:--root 参数移动到子命令之后生效"),
71
+ ("br4", "knowledge", "code", "command",
72
+ "导入命令:python migrate_receipts 脚本文件驱动执行"),
73
+ ("br5", "knowledge", "code", "tool-output",
74
+ "测试命令输出:53 ok 0 fail 全绿通过"),
75
+ # 干扰:无差读取臂的背景噪声(视图臂应剔除或降位)
76
+ ("bd1", "knowledge", "text", None, "会议纪要:季度规划讨论了若干方向性议题"),
77
+ ("bd2", "knowledge", "text", None, "读书笔记:系统一致性与反馈回路的一般性介绍"),
78
+ ("bd3", "contextual", "text", None, "闲聊上下文:天气与周末安排的对话残留"),
79
+ ("bd4", "knowledge", "code", None, "示例代码片段:打印问候语的演示脚本"),
80
+ ("bd5", "knowledge", "work_done", None, "例行工作完成记录:周报已按时提交"),
81
+ ("bd6", "knowledge", "ccg_marks", None, "通用判据示例:正常路径与边界条件各自成立"),
82
+ # 跨域诱饵:词面横跨多域——基线(无差别)会命中,视图臂应剔除,
83
+ # 打破「各域词面天然隔离」的失真(首跑实证:verifier 臂 -0.0% 的根因)。
84
+ ("dk1", "knowledge", "work_done", None,
85
+ "判据复盘工作完成:陷阱用例与命令输出的归档记录"),
86
+ ("dk2", "contextual", "text", None,
87
+ "结论情境补充:命令归档上下文中的判据留痕"),
88
+ ("dk3", "knowledge", "code", "command",
89
+ "对照命令:结论与判据的输出对照脚本"),
90
+ ]
91
+
92
+ # ---------------- 三角色查询集(每题唯一 gold;词面与 gold 共享中文 2-gram) ----------------
93
+ _QUERY_SETS = {
94
+ "main": [
95
+ ("回滚 结论 归档", "bm1"),
96
+ ("编译链 修复 完成", "bm2"),
97
+ ("缓存 刷新 结论", "bm3"),
98
+ ("索引 迁移 完成", "bm4"),
99
+ ("检索 对齐 一致", "bm5"),
100
+ ],
101
+ "verifier": [
102
+ ("陷阱 判据 编码", "bv1"),
103
+ ("判据 静默 失败", "bv2"),
104
+ ("上下文 吞没 陷阱", "bv3"),
105
+ ("情境 判据 取证", "bv4"),
106
+ ("上下文 覆盖 成果", "bv5"),
107
+ ],
108
+ "receipt": [
109
+ ("推送 命令 输出", "br1"),
110
+ ("状态 输出 推送", "br2"),
111
+ ("补丁 参数 子命令", "br3"),
112
+ ("导入 命令 脚本", "br4"),
113
+ ("测试 输出 全绿", "br5"),
114
+ ],
115
+ }
116
+
117
+ # 对齐跑:查询集 → 自己的视图臂
118
+ _ALIGNED = {"main": "main", "verifier": "verifier", "receipt": "receipt"}
119
+ # 隔离跑(硬边界):这些组合 gold 期望不可见
120
+ # receipt 域 gold 带 WORK_ROLES → main/verifier 臂 include_work=False 一票否决;
121
+ # main/verifier 域 gold 无 role → receipt 白名单不收。
122
+ _ISOLATED = [("receipt", "main"), ("receipt", "verifier"),
123
+ ("main", "receipt"), ("verifier", "receipt")]
124
+
125
+
126
+ def _mk_cg():
127
+ tmp = tempfile.mkdtemp(prefix="mdcg_bench_rv_")
128
+ p = Principal(tenant="default", actor="bench_role_views", role="designer",
129
+ can_write=True, can_admin=True)
130
+ cg = MdCGSecure(tmp, principal=p)
131
+ for nid, layer, ck, role, content in _CORPUS:
132
+ kw = {"layer": layer, "content_kind": ck}
133
+ if role is not None:
134
+ kw["role"] = role
135
+ cg.add(nid, content, **kw)
136
+ return cg, tmp
137
+
138
+
139
+ def _run_arm(cg, query, view, include_work=False):
140
+ """单题单臂:返回 (pack 内 id 序列, tokens_used)。
141
+
142
+ 基线臂传 include_work=True——「无差别全量读取」的忠实口径:
143
+ 若基线沿用默认 include_work=False,receipt 域(WORK_ROLES)在基线
144
+ 完全不可见(首跑实证 hit 0%),对照便不公平;视图臂保持默认
145
+ include_work=False——view 非空时 role 维度由视图规则接管(receipt
146
+ 是默认剔除的补集,这正是视图存在的理由之一)。
147
+ """
148
+ rec = cg.recall(query, budget_tokens=BIG_BUDGET, k=TOP_K,
149
+ view=view, include_work=include_work)
150
+ return ([p["id"] for p in rec.get("pack") or []],
151
+ int(rec.get("tokens_used") or 0))
152
+
153
+
154
+ def _metrics(hits_by_k, token_list):
155
+ """hits_by_k: 每题 gold 在 pack 的 1-based 位置(不可见=0)。"""
156
+ n = len(token_list)
157
+ mrr = sum(1.0 / h for h in hits_by_k if h > 0) / max(n, 1)
158
+ return {"hit@1": sum(1 for h in hits_by_k if 1 <= h <= 1) / n,
159
+ "hit@5": sum(1 for h in hits_by_k if 1 <= h <= 5) / n,
160
+ "hit@10": sum(1 for h in hits_by_k if 1 <= h <= 10) / n,
161
+ "mrr": mrr,
162
+ "tokens": sum(token_list) / n}
163
+
164
+
165
+ def _fmt(m):
166
+ return ("hit@1 %.0f%% hit@5 %.0f%% hit@10 %.0f%% MRR %.3f tokens %.0f"
167
+ % (m["hit@1"] * 100, m["hit@5"] * 100, m["hit@10"] * 100,
168
+ m["mrr"], m["tokens"]))
169
+
170
+
171
+ def main():
172
+ cg, tmp = _mk_cg()
173
+ ok = True
174
+ try:
175
+ print("==== bench_role_views:角色化读取视图四臂对照(H5) ====")
176
+ print("语料 %d 节点(main 域 5 / verifier 域 5 / receipt 域 5 / "
177
+ "干扰 6 / 跨域诱饵 3),查询 3 类 × 5 题,k=%d,budget=%d"
178
+ % (len(_CORPUS), TOP_K, BIG_BUDGET))
179
+
180
+ # ---------- 对齐跑(H5 主判据) ----------
181
+ print("\n---- 对齐跑:Q_role × view=role vs 基线(含诱饵词面跨域命中) ----")
182
+ token_pass, hit_pass = True, True
183
+ for role, view in _ALIGNED.items():
184
+ qs = _QUERY_SETS[role]
185
+ pos0, tok0 = [], []
186
+ posv, tokv = [], []
187
+ for q, gold in qs:
188
+ ids0, t0 = _run_arm(cg, q, None, include_work=True)
189
+ idsv, tv = _run_arm(cg, q, view)
190
+ pos0.append(ids0.index(gold) + 1 if gold in ids0 else 0)
191
+ posv.append(idsv.index(gold) + 1 if gold in idsv else 0)
192
+ tok0.append(t0)
193
+ tokv.append(tv)
194
+ m0, mv = _metrics(pos0, tok0), _metrics(posv, tokv)
195
+ drop = (m0["tokens"] - mv["tokens"]) / m0["tokens"] * 100.0
196
+ t_ok = mv["tokens"] < m0["tokens"]
197
+ h_ok = (mv["hit@1"] >= m0["hit@1"] and mv["hit@5"] >= m0["hit@5"]
198
+ and mv["hit@10"] >= m0["hit@10"] and mv["mrr"] >= m0["mrr"])
199
+ token_pass &= t_ok
200
+ hit_pass &= h_ok
201
+ print("\n[%s] view=%s(token %s)" %
202
+ (role, view, "下降" if t_ok else "未下降"))
203
+ print(" 基线 %s" % _fmt(m0))
204
+ print(" %s %s (%+.1f%% tokens)" %
205
+ (view.ljust(9), _fmt(mv), -drop))
206
+
207
+ # ---------- 隔离跑(硬边界实证) ----------
208
+ print("\n---- 隔离跑:错配组合 gold 期望不可见 ----")
209
+ iso_pass = True
210
+ for role, view in _ISOLATED:
211
+ missed = 0
212
+ for q, gold in _QUERY_SETS[role]:
213
+ ids, _t = _run_arm(cg, q, view)
214
+ if gold not in ids:
215
+ missed += 1
216
+ this_ok = missed == len(_QUERY_SETS[role])
217
+ iso_pass &= this_ok
218
+ print(" Q_%s × view=%-8s gold 不可见 %d/%d %s"
219
+ % (role, view, missed, len(_QUERY_SETS[role]),
220
+ "" if this_ok else " <-- 泄漏"))
221
+
222
+ # ---------- H5 判定 ----------
223
+ print("\n==== H5 判定 ====")
224
+ print(" 各对齐臂 token 下降 : %s" % ("PASS" if token_pass else "FAIL"))
225
+ print(" 各对齐臂 命中率不降 : %s" % ("PASS" if hit_pass else "FAIL"))
226
+ print(" 隔离跑 无泄漏(辅助证据): %s" % ("PASS" if iso_pass else "FAIL"))
227
+ if not (token_pass and hit_pass):
228
+ print("\n权衡(如实报告,不作单向通过声明):")
229
+ print(" 存在「token 未下降或命中率下降」的对齐臂——")
230
+ print(" 上表数字为准;禁止为凑指标调规则表后不复跑。")
231
+ ok = token_pass and hit_pass
232
+ finally:
233
+ shutil.rmtree(tmp, ignore_errors=True)
234
+ return 0 if ok else 1
235
+
236
+
237
+ if __name__ == "__main__":
238
+ sys.exit(main())
@@ -93,6 +93,7 @@ CASES = [
93
93
  ]
94
94
 
95
95
 
96
+ # 生效条件:给定 text,当 expand_query_terms_weighted(text) 为真值字典时返回其中键不以 `__` 开头的项(键转 str、值转 float),并先弹出 `__source__`;当该调用返回假值(None/空/其他假值)时返回空字典 {};
96
97
  def _terms(text):
97
98
  tw = expand_query_terms_weighted(text) or {}
98
99
  tw.pop("__source__", None)
@@ -100,6 +101,7 @@ def _terms(text):
100
101
  if not str(k).startswith("__")}
101
102
 
102
103
 
104
+ # 生效条件:candidates 非空且 error 可被 _terms 处理时,按 _weighted_coverage 返回覆盖得分最高的候选,字面平局时取候选顺序最前者。
103
105
  def _pick_lexical(error, candidates):
104
106
  """无记忆臂的确定性策略:按字面覆盖选 top-1(字面平局时按候选顺序)。"""
105
107
  tw = _terms(error)
@@ -111,6 +113,7 @@ def _pick_lexical(error, candidates):
111
113
  return best
112
114
 
113
115
 
116
+ # 生效条件:给定 error、candidates、fix、max_turns,在 pool 非空且 turns<max_turns 时每轮把 _pick_lexical(error, pool) 选中的 last 记入 touched:若 last==fix 立即返回 {'success': True, 'turns': turns, 'pick': last, 'touched': touched},否则从 pool 移除 last 继续;候选耗尽或 max_turns 为 0/负值时退出,返回 {'success': False, 'turns': turns, 'pick': last, 'touched': touched}(未进入循环时 success=False、turns=0、pick=None、touched=[]);
114
117
  def _trial(error, candidates, fix, max_turns):
115
118
  """无记忆臂:选错就排除该动作、下一轮重选(模拟试错)。"""
116
119
  pool = list(candidates)
@@ -128,6 +131,7 @@ def _trial(error, candidates, fix, max_turns):
128
131
  "touched": touched}
129
132
 
130
133
 
134
+ # 生效条件:case["fix"] 为真且其字符串出现在 cg.recall(query, budget_tokens=budget, k=20) 返回 pack 各项 content 拼接成的 text 中时返回 hit=True、turns=1、touched=[];否则以 case["error"]、candidates、case["fix"]、max_turns 调 _trial 并回填 hit=False、turns=1+fb["turns"]、tokens=int(tokens_used or 0)。
131
135
  def _decide_mem(cg, query, case, candidates, max_turns, budget):
132
136
  """有记忆臂:先召回,命中修复知识则一次到位;否则回退到试错。"""
133
137
  res = cg.recall(query, budget_tokens=budget, k=20)
@@ -141,10 +145,12 @@ def _decide_mem(cg, query, case, candidates, max_turns, budget):
141
145
  return fb
142
146
 
143
147
 
148
+ # 生效条件:传入 x 时,返回 f"{100.0 * x:.1f}%" 的字符串(即 x 乘以 100 后保留一位小数的百分比表示);
144
149
  def _pct(x):
145
150
  return f"{100.0 * x:.1f}%"
146
151
 
147
152
 
153
+ # 生效条件:rows 为非空序列(n>0)且每项可解包为 (c, rn, rm)、c 含 trap/id/error、rn/rm 含 success/turns/touched(tokens 经 .get('tokens') or 0 把缺键或假值计 0,hit 经 .get 缺键或假值不计数),mined 含 pairs/knowledge_ids/rejected_ids 键,max_turns 为数值时,打印两臂指标与逐例清单,并按首次正确率与重复犯错率的大小关系(提升/相等/其余)输出三分支结论;
148
154
  def _report(rows, mined, max_turns):
149
155
  n = len(rows)
150
156
  print("\n" + "=" * 74)
@@ -204,6 +210,7 @@ def _report(rows, mined, max_turns):
204
210
  print()
205
211
 
206
212
 
213
+ # 生效条件:调用 main(argv) 时由 argparse 解析 argv(argv 为 None 则取 sys.argv[1:]),--cases 为 0 用全部 CASES、非 0(含负值)用 CASES[:a.cases],--max-turns 默认 2,--budget 默认 2000;随后在临时目录创建 none_arm/mem_arm,先用 mem_arm.mine_fix_pairs 从 cases 的 error/fix 写入修复对作为记忆臂命中前置,再逐例以 _trial 与 _decide_mem 生成 rows 并 _report,最终返回 0;
207
214
  def main(argv=None):
208
215
  ap = argparse.ArgumentParser(description="任务级 A/B:无记忆 vs 有记忆")
209
216
  ap.add_argument("--cases", type=int, default=0, help="只用前 N 个用例(0=全部)")
@@ -234,4 +241,4 @@ def main(argv=None):
234
241
 
235
242
 
236
243
  if __name__ == "__main__":
237
- sys.exit(main())
244
+ sys.exit(main())
@@ -134,6 +134,7 @@ for _c in CASES:
134
134
 
135
135
 
136
136
  # ---- LLM 客户端(OpenAI 兼容,零第三方依赖)-------------------------------
137
+ # 生效条件:给定 model/base/key/messages 即构造 JSON POST 到 base.rstrip("/")+"/chat/completions",返回 (choices[0].message 的 content 或缺失/假值回落 ""、data.get("usage") 或缺失/假值回落 {}、耗时 dt),timeout/max_tokens/temperature 仅作为请求参数传入。
137
138
  def llm_chat(model, base, key, messages, timeout=180, max_tokens=200,
138
139
  temperature=0.0):
139
140
  payload = json.dumps({
@@ -154,6 +155,7 @@ def llm_chat(model, base, key, messages, timeout=180, max_tokens=200,
154
155
  return content, (data.get("usage") or {}), dt
155
156
 
156
157
 
158
+ # 生效条件:raw(None/空串视为 "")中首个 "{" 至末个 "}" 的子串能解析出 pick,或全文匹配到单个数字 1-9,且该编号落在 1..n 内时返回该编号(pick 为数字字符串先转 int),否则返回 None。
157
159
  def _parse_pick(raw, n):
158
160
  """从模型输出里抠出候选编号(1..n);解析失败返回 None。"""
159
161
  s = raw or ""
@@ -174,6 +176,7 @@ def _parse_pick(raw, n):
174
176
  return None
175
177
 
176
178
 
179
+ # 生效条件:以 case["id"] 播种打乱 [(fix,case["fix"]),(trap,case["trap"]),(decoy,case["decoy"])] 后取三种循环排列,n<=3 返回其前 n 个,n>3 返回 6 种全排列的前 n 个。
177
180
  def _orders(case, n):
178
181
  """候选顺序。默认取 3 种循环排列(每个候选在 3 个位置各出现一次,天然去位置偏差);
179
182
  n>3 时退回全 6 种排列。基准顺序由 case id 播种打乱,避免跨用例雷同。"""
@@ -186,6 +189,7 @@ def _orders(case, n):
186
189
  return list(itertools.permutations(base))[:n]
187
190
 
188
191
 
192
+ # 生效条件:case 含 task 且 opts 为 (kind, txt) 序列时,返回含场景、编号候选与选择指令的提示文本,memory 非空时在开头插入记忆段。
189
193
  def _user_prompt(case, opts, memory=None):
190
194
  lines = []
191
195
  if memory:
@@ -203,12 +207,14 @@ def _user_prompt(case, opts, memory=None):
203
207
  return "\n".join(lines)
204
208
 
205
209
 
210
+ # 生效条件:cg 存在时把模块常量 CASES 逐条以 c["task"] 为 error、c["lesson"] 为 fix 组成列表传给 cg.mine_fix_pairs 并原样返回其结果。
206
211
  def _build_memory(cg):
207
212
  """Phase A:把 5 条「项目规范」写进记忆(真实 mine_fix_pairs)。"""
208
213
  return cg.mine_fix_pairs(
209
214
  [{"error": c["task"], "fix": c["lesson"]} for c in CASES])
210
215
 
211
216
 
217
+ # 生效条件:以 "本项目规范:"+case["query"] 且 budget_tokens=budget、k=10 调用 cg.recall,取 pack 各项 content(缺失/假值为 "")拼接,返回其前 1500 字符与 case["marker"] 是否出现在未截断拼接文本中。
212
218
  def _recall_memory(cg, case, budget):
213
219
  res = cg.recall("本项目规范:" + case["query"],
214
220
  budget_tokens=budget, k=10)
@@ -216,6 +222,7 @@ def _recall_memory(cg, case, budget):
216
222
  return text[:1500], (case["marker"] in text)
217
223
 
218
224
 
225
+ # 生效条件:在 cfg["max_turns"] 轮内以 cfg["model"]/cfg["base"]/cfg["key"] 调 llm_chat(timeout=cfg["timeout"]、max_tokens=cfg["max_tokens"])并累加 usage["total_tokens"],pick 等于 correct_pos 或为 None 时中止(否则在仍有剩余轮次时追加 assistant/user 消息重选),最终 pick 为 None 则 kind="invalid"、否则 kind=opts[pick-1][0]。
219
226
  def _run_one(cfg, case, opts, correct_pos, memory):
220
227
  messages = [{"role": "system", "content": SYS_PROMPT},
221
228
  {"role": "user", "content": _user_prompt(case, opts, memory)}]
@@ -239,6 +246,7 @@ def _run_one(cfg, case, opts, correct_pos, memory):
239
246
  "turns": turns, "tokens": tokens, "latency": dt}
240
247
 
241
248
 
249
+ # 生效条件:cfg["use_mem"] 为真时对每个 case 以 cfg["budget"] 先串行召回写入 mems、否则存 (None, False),再对每 case × _orders(case, n_perms) 的排列 × ("none","mem") 两臂建任务交 ThreadPoolExecutor(max_workers=workers) 执行,返回按 arm 分组的 {"none": [...], "mem": [...]} 行表。
242
250
  def _run_model(label, cfg, cases, cg, n_perms, workers):
243
251
  # 记忆召回先串行算好(MdCGOS 非线程安全),LLM 调用再并发。
244
252
  mems = {}
@@ -254,6 +262,7 @@ def _run_model(label, cfg, cases, cg, n_perms, workers):
254
262
  for arm in ("none", "mem"):
255
263
  tasks.append((case, oi, opts, correct_pos, arm))
256
264
 
265
+ # 生效条件:t 解包为 (case, oi, opts, correct_pos, arm),arm=="mem" 时 memory/hit 取闭包 mems[case["id"]]、否则为 (None, False),_run_one 抛异常时以 kind="error"、pick=None 的占位行替代,随后补上 case/arm/hit 并打印该行后返回 r。
257
266
  def work(t):
258
267
  case, oi, opts, correct_pos, arm = t
259
268
  memory, hit = mems[case["id"]] if arm == "mem" else (None, False)
@@ -276,10 +285,12 @@ def _run_model(label, cfg, cases, cg, n_perms, workers):
276
285
  return rows
277
286
 
278
287
 
288
+ # 生效条件:n 为真值时返回 f"{100.0*x/n:.1f}%",n 为假值(0)时返回 "-"。
279
289
  def _pct(x, n):
280
290
  return f"{100.0 * x / n:.1f}%" if n else "-"
281
291
 
282
292
 
293
+ # 生效条件:以 rows["none"] 的行数 n 汇总 none/mem 两臂的 correct、kind=="trap"、kind∈("invalid","error")、tokens、latency、hit 与 pick∈(1,2,3) 的分布并打印(n_perms 仅用于表头文字),返回该 agg 字典。
283
294
  def _report(label, rows, n_perms):
284
295
  n = len(rows["none"])
285
296
  print(f"\n{'-' * 78}")
@@ -333,6 +344,7 @@ def _report(label, rows, n_perms):
333
344
  return agg
334
345
 
335
346
 
347
+ # 生效条件:argv 为 None 时改读 sys.argv;若 --key 与 DEEPSEEK_API_KEY 均为空则返回 2,否则按 --only/--cases 从 CASES 取用例跑完双臂后返回 0。
336
348
  def main(argv=None):
337
349
  ap = argparse.ArgumentParser(
338
350
  description="先验陷阱 A/B:无记忆 vs 有记忆(真实 LLM)")
@@ -394,4 +406,4 @@ def main(argv=None):
394
406
 
395
407
 
396
408
  if __name__ == "__main__":
397
- sys.exit(main())
409
+ sys.exit(main())
@@ -48,6 +48,7 @@ ARM_ROOT = os.path.join(HERE, "_md_cg_eval_unified_en") # gitignore 已覆盖
48
48
  K = 10
49
49
 
50
50
 
51
+ # 生效条件:传入 root 使 os.path.isdir(root) 为真时先执行 shutil.rmtree(root, ignore_errors=True)、否则跳过,随后遍历 corpus 每项 c,semantic_of 不为 None 且 semantic_of(c) 返回真值时以 semantic=sem 传入,正文按 zh_body 真值取 c.get("zh")、假值取 b6.ingest_text_en(c),并以 c["id"] 为键 add 后 flush 并 install_read_cache,最终返回 cg;
51
52
  def build(root, corpus, semantic_of=None, zh_body=False):
52
53
  """单库构建:正文形态与 fm.semantic 摘要层是仅有的两个自由度。"""
53
54
  if os.path.isdir(root):
@@ -67,6 +68,7 @@ def build(root, corpus, semantic_of=None, zh_body=False):
67
68
  return cg
68
69
 
69
70
 
71
+ # 生效条件:cg 可对 questions 做 evaluate_group 时,按 semantic 设置或清除 MDCG_SEMANTIC,返回词法路 rows 及其按 qtype 汇总的 by_type。
70
72
  def run_arm(cg, questions, tag, semantic=False):
71
73
  if semantic:
72
74
  os.environ["MDCG_SEMANTIC"] = "1"
@@ -82,6 +84,7 @@ def run_arm(cg, questions, tag, semantic=False):
82
84
  return rows, by_type
83
85
 
84
86
 
87
+ # 生效条件:questions 为真时逐 q 取 q["question"](缺该键抛 KeyError)经 query_atoms,仅当 atom 含任一满足 "A" <= ch <= "z" 的字符才计入 n_keep,n_tok 为 0 时 keep_ratio 为 0.0、否则 round(n_keep/n_tok,4),questions 为空时 q_with_keep_ratio 为 0.0、否则 round(n_q_with_keep/len(questions),4),返回含 n_questions/n_atoms/n_en_keep 的 dict;
85
88
  def oov_stats(questions):
86
89
  """题级 en→zh 归一覆盖统计:英文保留词占比 = 词表覆盖瓶颈的直接量化。"""
87
90
  n_tok = n_keep = n_q_with_keep = 0
@@ -100,6 +103,7 @@ def oov_stats(questions):
100
103
  if questions else 0.0}
101
104
 
102
105
 
106
+ # 生效条件:不适用(无必需形参与模块级常量)
103
107
  def main():
104
108
  t0 = time.time()
105
109
  rows500 = list(ec.iter_jsonl(b6.QUESTIONS500))
@@ -115,6 +119,7 @@ def main():
115
119
  ec.unlock_global_cap()
116
120
  ec.use_jaccard()
117
121
 
122
+ # 生效条件:对 c 先取 (c.get("zh_fields") or {}).get("summary") 再 or "" 并 str().strip(),该值为空时回落为 (c.get("zh") or "") 的 str().strip(),所得 s 非空则返回 " ".join(semantic_atoms(s))、否则返回空串;
118
123
  def sem_of(c):
119
124
  s = str((c.get("zh_fields") or {}).get("summary") or "").strip()
120
125
  if not s:
@@ -197,4 +202,4 @@ def main():
197
202
 
198
203
 
199
204
  if __name__ == "__main__":
200
- main()
205
+ main()
@@ -62,6 +62,7 @@ QUESTIONS20 = os.path.join(ZP, "questions20.jsonl")
62
62
  AXES = ("person", "event", "time", "identity", "place", "condition")
63
63
 
64
64
 
65
+ # 生效条件:path 以 UTF-8 打开后逐行读取,仅 strip 后非空的行经 json.loads 产出,空白行被跳过。
65
66
  def iter_jsonl(path):
66
67
  with open(path, encoding="utf-8") as f:
67
68
  for line in f:
@@ -70,11 +71,13 @@ def iter_jsonl(path):
70
71
  yield json.loads(line)
71
72
 
72
73
 
74
+ # 生效条件:path 以 UTF-8 打开成功时返回 json.load(f) 的解析结果,片段内无其它分支。
73
75
  def load_json(path):
74
76
  with open(path, encoding="utf-8") as f:
75
77
  return json.load(f)
76
78
 
77
79
 
80
+ # 生效条件:raw 经 str() 后按“;”切分,仅含“=”的段被解析,其中键为身份/时间/摘要时写对应槽位、键为条件时按“|”与“:”写入 condition、键为词时按“,”拆出非空项写入 terms,其它键或未出现的槽位保持 out 的默认空值。
78
81
  def parse_zh(raw):
79
82
  """中文层串 → 槽位 dict。
80
83
 
@@ -107,6 +110,7 @@ def parse_zh(raw):
107
110
  return out
108
111
 
109
112
 
113
+ # 生效条件:当 MANUAL_ZH/MANUAL_Q/LM_Q/LM_H 可读取、hay 覆盖 want_ids 且 meta 含 man_q 全部 qid 时写出 CORPUS20/QUESTIONS20 并返回 (corpus, questions),缺 turn 或 qid 分别 raise SystemExit,verbose(默认 True)为真值时额外打印统计、假值时静默。
110
114
  def prepare(verbose=True):
111
115
  """生成 corpus20.jsonl 与 questions20.jsonl(幂等覆盖)。"""
112
116
  man_zh = load_json(MANUAL_ZH)
@@ -125,6 +129,7 @@ def prepare(verbose=True):
125
129
  raise SystemExit(f"[失败] haystack 缺以下 turn:{sorted(missing)}")
126
130
 
127
131
  # corpus:按 turn id 的数值序(= 时间序),保证「承接前一条」有确定语义
132
+ # 生效条件:tid 经 rsplit("t",1) 得到至少两段且最后一段可被 int() 解析时返回该整数,否则源码未做校验会抛错。
128
133
  def turn_no(tid):
129
134
  return int(tid.rsplit("t", 1)[1])
130
135
 
@@ -171,6 +176,7 @@ def prepare(verbose=True):
171
176
  return corpus, questions
172
177
 
173
178
 
179
+ # 生效条件:prepare(verbose=False) 返回 corpus/questions 后,对每题以 evidence_turns[0](空则 "")取 ev0,命中词限于 ev0 非空且词出现在 zh_of[ev0] 中,df1 收集池内 df==1 的词、all_df 收集 df==len(corpus) 的词,verbose(默认 True)为真值时打印后返回 per_q、为假值时直接返回 per_q。
174
180
  def analyze(verbose=True):
175
181
  """诊断:查询词能否落到 gold 中文层 / 池内其他条目(决定各轴是否有可桥接的实体)。
176
182
 
@@ -254,6 +260,7 @@ EN_NAME_RE = re.compile(r"\b[A-Z][a-z]{2,}(?:[ ][A-Z][a-z]{2,})*\b")
254
260
  DATE_RE = re.compile(r"(\d{4})[/-](\d{1,2})[/-](\d{1,2})")
255
261
 
256
262
 
263
+ # 生效条件:DATE_RE.search(str(raw or "")) 有匹配时返回零填充的 YYYY-MM-DD,无匹配(含 raw 为假值回落成 "")时返回 ""。
257
264
  def norm_time(raw):
258
265
  """'2023/05/24 04:49' → '2023-05-24'(跨条目统一格式,使日期查询可命中)。"""
259
266
  m = DATE_RE.search(str(raw or ""))
@@ -263,6 +270,7 @@ def norm_time(raw):
263
270
  return f"{int(y):04d}-{int(mo):02d}-{int(d):02d}"
264
271
 
265
272
 
273
+ # 生效条件:对 str(text or "") 用 EN_NAME_RE 扫描,匹配串按空白切分后任一部分命中 EN_STOP 即跳过,其余项按首次出现顺序去重加入 out 并返回;text 为假值时扫描空串返回 []。
266
274
  def en_names(text):
267
275
  """英文原文中的专名候选(跨语言桥:中文查询里的英文专名可经 entity 路命中)。"""
268
276
  out, seen = [], set()
@@ -276,6 +284,7 @@ def en_names(text):
276
284
  return out
277
285
 
278
286
 
287
+ # 生效条件:遍历 corpus,对每条记录的 zh_fields["terms"] 去重后逐词判断,词非空且不在 STOP_ZH 时使 df[词] 计数加一,返回 df。
279
288
  def build_tables(corpus):
280
289
  """全库统计:# 词项 df(**只读语料**,与查询集无关)。"""
281
290
  df = {}
@@ -286,6 +295,7 @@ def build_tables(corpus):
286
295
  return df
287
296
 
288
297
 
298
+ # 生效条件:c 含 zh_fields(terms/condition/time/identity)且 df 为词到频次的映射时,返回 person/event/time/identity/place/condition 六轴取值字典。
289
299
  def axis_values(c, df):
290
300
  """一条 turn 的六个关系轴取值(用户裁决:条件链 + 人物/事件/时间/身份/地点)。"""
291
301
  f = c["zh_fields"]
@@ -321,6 +331,7 @@ INTENT_CLASSES = (
321
331
  )
322
332
 
323
333
 
334
+ # 生效条件:按 INTENT_CLASSES 顺序检查 c["zh_fields"]["summary"],首个命中类目的首个包含于摘要的动词返回 (cls, v),全不命中返回 ('', '')。
324
335
  def intent_of(c):
325
336
  """意图抽象:摘要 → (规范类目, 命中的动词原形)。
326
337
 
@@ -338,6 +349,7 @@ def intent_of(c):
338
349
  return "", ""
339
350
 
340
351
 
352
+ # 生效条件:把 c["zh_fields"]["terms"] 与 en_names(c["text"]) 逐项 strip 后跳过空串、STOP_ZH(原形或小写)及已见项去重入 out,再用 norm_time(条件.get("时间窗口") or c 的 time) 得到非空且未出现的时窗串追加;df 形参在该片段内未参与条件判断。
341
353
  def normalize_terms(c, df):
342
354
  """实体规范化:去停用 + 去重 + 附时间规范式 + 附英文专名(跨语言对齐)。"""
343
355
  f = c["zh_fields"]
@@ -354,6 +366,7 @@ def normalize_terms(c, df):
354
366
  return out
355
367
 
356
368
 
369
+ # 生效条件:遍历 corpus 并以 root=os.path.join(HERE, root_base or f"_md_cg_eval_zhprobe_{arm['name']}")(root_base 为 None/空串时回落)建库,graph 分支仅当 arm.get("graph") 为真且某轴取值的同值 id 数落在 [2, max_df](默认 5)时为这些 id 两两建有向边,coref 仅当 arm.get("coref") 为真、本条 own 为空(own 只在 arm.get("norm") 为真时由 normalize_terms 生成,否则恒为 [])且 prev_own 非空时承接前一条自身 canonical,intent 分支仅当 arm.get("intent") 为真且 intent_of 返回 cls 非空时写意图行并把意图词与长度>=2 的动词加入 tags,verbose(默认 True)为真值时打印臂统计、root 已是目录时先整树删除再建 MdCGOS。
357
370
  def build_arm(corpus, arm, max_df=5, root_base=None, verbose=True):
358
371
  """按消融臂建库。每臂一个独立 root,互不污染。
359
372
 
@@ -453,6 +466,7 @@ ARMS = [
453
466
  ]
454
467
 
455
468
 
469
+ # 生效条件:先执行 prepare(verbose=False) 取得 corpus,再对 ARMS 每臂以 max_df=max_df(默认 5,原样下传不做假值回落)调用 build_arm 并汇总为 roots 返回。
456
470
  def build_all(max_df=5):
457
471
  corpus, _ = prepare(verbose=False)
458
472
  print(f"== 建库(消融 {len(ARMS)} 臂,max_df={max_df})==")
@@ -469,6 +483,7 @@ ROW_RE = re.compile(
469
483
  GROUPS = ["precise", "temporal", "interference", "reference"]
470
484
 
471
485
 
486
+ # 生效条件:os.path.exists(RUST_BIN) 为真时以 argv=[RUST_BIN,"--dataset","mad","--tag",name,"--lib",lib](extra 为真值时追加 list(extra))执行 subprocess,返回码非 0 或 ROW_RE 在 stdout 未匹配到任何组时 raise SystemExit,否则返回 {组:(n,hit@1,hit@5,MRR)}。
472
487
  def run_one(name, lib, extra=None):
473
488
  """调用 **Rust 检索器** 跑一臂,返回 {组: (n, hit@1, hit@5, MRR)}。
474
489
 
@@ -496,6 +511,7 @@ def run_one(name, lib, extra=None):
496
511
  return got
497
512
 
498
513
 
514
+ # 生效条件:先打印 title 与表头,再遍历 rows 的 (label, got, note),对 GROUPS 每组用 got[g] 取 (n,h1,h5,mrr) 并累计总体 hit@1/MRR,仅当 baseline 不为 None 且 label==baseline 时记 ref,仅当 ref 已记录且 label!=baseline 时输出 Δ。
499
515
  def print_table(title, rows, baseline=None):
500
516
  """rows: [(label, got, note)];baseline = 参照行 label(算 Δ)。"""
501
517
  print(f"\n== {title} ==")
@@ -524,6 +540,7 @@ def print_table(title, rows, baseline=None):
524
540
  + f"{ov_h1 * 100:>10.1f}%{ov_mrr:>10.3f}{delta}{suffix}")
525
541
 
526
542
 
543
+ # 生效条件:对 ARMS 每臂以 lib=f"_md_cg_eval_zhprobe_{name}"、无 extra 调用 run_one 组成 rows,并以 ARMS[0]["name"] 为 baseline 调 print_table 后返回 rows。
527
544
  def run_ablation():
528
545
  """消融主表:逐臂调用 Rust 检索器并汇总(种子口径 = 缺省,即生产现状)。"""
529
546
  rows = []
@@ -537,6 +554,7 @@ def run_ablation():
537
554
  return rows
538
555
 
539
556
 
557
+ # 生效条件:以最后一个臂 ARMS[-1]['name'] 对应的库路径,先无 extra 调 run_one("a4_index", lib)、再以 extra=("--graph-seeds","sorted") 调 run_one("a4_sorted", lib) 组成 rows,并以 baseline="a4/index" 调 print_table 后返回。
540
558
  def run_seed_control():
541
559
  """对照:**同一个 a4 库**(写入侧与边结构完全相同),只切换 graph 路种子口径。
542
560
 
@@ -555,6 +573,7 @@ def run_seed_control():
555
573
  return rows
556
574
 
557
575
 
576
+ # 生效条件:cmd 取 argv[1](len(argv)<=1 时为 "prepare"),cmd=="prepare"/"analyze"/"build"/"run"/"seed-control" 分别调用 prepare/analyze/build_all/run_ablation/run_seed_control,cmd=="all" 依次调用 prepare、analyze、build_all、run_ablation、run_seed_control,其余值 raise SystemExit。
558
577
  def main(argv):
559
578
  cmd = argv[1] if len(argv) > 1 else "prepare"
560
579
  if cmd == "prepare":
@@ -580,4 +599,4 @@ def main(argv):
580
599
 
581
600
 
582
601
  if __name__ == "__main__":
583
- main(sys.argv)
602
+ main(sys.argv)