@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
@@ -7,7 +7,9 @@
7
7
  ③ 证据不足:仅 1 次记录不冷却;有变化(carried→resolved)→ σ=1.0
8
8
  ④ 集成:proposals 端 σ 筛选拦截 → deferred 可审计;enforce_gain=False 放行
9
9
  ⑤ explore 留痕 outcomes 实现值(下轮 gain_gate 的裁决输入)
10
+ + meta_outcomes 并列留痕(D_meta 压力,不改 outcomes 值类型)
10
11
  ⑥ 预算豁免:bypass_gain=True 冷却中照常探索且留痕 bypass_gain
12
+ ⑦ D_meta 压力冷却:终态停滞且压力仍扩大 → 冷却过期也不放行(新分支)
11
13
 
12
14
  运行:python -m md_cg.test_gain_gate
13
15
  """
@@ -18,7 +20,7 @@ import shutil
18
20
  import tempfile
19
21
  import time
20
22
 
21
- from . import autonomy, metacognition
23
+ from . import autonomy, d_meta, metacognition
22
24
  from .fsutil import append_jsonl
23
25
  from .mdcos import MdCGOS
24
26
 
@@ -51,6 +53,17 @@ def _hist(cg, bid, terminals, t0=None, step=5.0):
51
53
  "actor": "test", "outcomes": {bid: tml}, "bids": [bid]})
52
54
 
53
55
 
56
+ def _hist_meta(cg, bid, terminals, delta, t0=None, step=5.0):
57
+ """同 _hist,但并列留 D_meta 跨轮压力增量(新分支的裁决输入)。"""
58
+ t0 = time.time() - 10.0 if t0 is None else t0
59
+ for i, tml in enumerate(terminals):
60
+ append_jsonl(autonomy._explore_log_path(cg),
61
+ {"type": "explore", "t": t0 + i * step,
62
+ "actor": "test", "outcomes": {bid: tml}, "bids": [bid],
63
+ "meta_outcomes": {"delta": {"unmodeled_growth": delta},
64
+ "proxy": autonomy.DMETA_PROXY}})
65
+
66
+
54
67
  def main():
55
68
  tmp = tempfile.mkdtemp(prefix="mdcg_gain_")
56
69
  try:
@@ -130,6 +143,12 @@ def main():
130
143
  "resolved") for t in rec["outcomes"].values()),
131
144
  "⑤b实现值为诚实五态(不编造)")
132
145
  ok(rec.get("bypass_gain") is False, "⑤c留痕 bypass_gain=False")
146
+ mo = rec.get("meta_outcomes") or {}
147
+ ok(set(mo.get("before") or {}) == set(d_meta.PROXY_KEYS)
148
+ and mo.get("proxy") == autonomy.DMETA_PROXY,
149
+ "⑤dexplore 留痕 meta_outcomes.before(D_meta 三代理,并列不改 outcomes)")
150
+ ok(all(isinstance(v, str) for v in rec["outcomes"].values()),
151
+ "⑤eoutcomes 值仍为终态字符串(dict 化会使 σ 静默恒 1.0,此处守卫)")
133
152
 
134
153
  # ---------- ⑥ 预算豁免 ----------
135
154
  cg6_root = os.path.join(tmp, "root6")
@@ -152,6 +171,33 @@ def main():
152
171
  rec6 = [__import__("json").loads(x) for x in f if x.strip()][-1]
153
172
  ok(rec6.get("bypass_gain") is True,
154
173
  "⑥b豁免留痕可审计(bypass_gain=True)")
174
+
175
+ # ---------- ⑦ D_meta 压力冷却(新分支) ----------
176
+ cg7_root = os.path.join(tmp, "root7")
177
+ os.makedirs(cg7_root, exist_ok=True)
178
+ cg7 = MdCGOS(cg7_root)
179
+ _hist_meta(cg7, bid, ["carried", "carried"], 0.2)
180
+ g7 = autonomy.gain_gate(cg7, bid, now=time.time() + 3600.0 + 60.0)
181
+ ok(g7["sigma"] == 0.0 and "UNDER_PRESSURE" in g7["reason"],
182
+ "⑦停滞 + 压力仍扩大 → 冷却过期也不放行(DEFER_EXHAUSTED_UNDER_PRESSURE)")
183
+ ok(g7.get("meta_rising") is True,
184
+ "⑦b新分支留痕 meta_rising=True(可审计,不静默冷却)")
185
+ ok(autonomy.gain_gate(cg7, bid, now=time.time())["sigma"] == 0.0,
186
+ "⑦c冷却内仍走既有分支(口径保持,不重复计算)")
187
+ cg8_root = os.path.join(tmp, "root8")
188
+ os.makedirs(cg8_root, exist_ok=True)
189
+ cg8 = MdCGOS(cg8_root)
190
+ _hist_meta(cg8, bid, ["carried", "carried"], 0.0)
191
+ ok(autonomy.gain_gate(cg8, bid,
192
+ now=time.time() + 3600.0 + 60.0)["sigma"] == 1.0,
193
+ "⑦d压力未扩大(delta=0)→ 冷却过期照旧放行(只在上升时延长)")
194
+ cg9_root = os.path.join(tmp, "root9")
195
+ os.makedirs(cg9_root, exist_ok=True)
196
+ cg9 = MdCGOS(cg9_root)
197
+ _hist(cg9, bid, ["carried", "carried"])
198
+ ok(autonomy.gain_gate(cg9, bid,
199
+ now=time.time() + 3600.0 + 60.0)["sigma"] == 1.0,
200
+ "⑦e缺 meta_outcomes 键 → 新分支不触发(旧留痕兼容)")
155
201
  finally:
156
202
  shutil.rmtree(tmp, ignore_errors=True)
157
203
 
@@ -0,0 +1,173 @@
1
+ # -*- coding: utf-8 -*-
2
+ """体检读数规模纪律验证(O(1) 元数据口径,替代全量扫描)。
3
+
4
+ 背景(第 4 条取证):审计日志无上界增长(实测 ~2 条/s、累计 ~21.5 M 条 / 4.0 GB),
5
+ 而健康度只需要「量级」这一 O(1) 信息。旧实现 `len(list(read_jsonl(p)))` 把只读体检
6
+ 绑到 O(n) 全量解析上(4.0 GB → RSS 5 GB+、数十分钟不返回、整条 MCP 通道被一次调用
7
+ 堵死);改用流式数行仍要 O(n) 磁盘 IO,随运行时长线性劣化——同属「指标与代价错配」。
8
+
9
+ 断言面:
10
+ ① 缺失文件:零读数不炸(bytes=0 / events=0 / exact=True)
11
+ ② 阈值内:events 精确 == 日志行数(口径与物化读一致,改造不丢读数)
12
+ ③ 超阈值:只读元数据 + 尾部估算,exact=False,且**不触发任何全量计数**(O(n) 守卫)
13
+ ④ 估算忠于量级:与真实行数相对误差 < 20%(可用但不假装精确)
14
+ ⑤ health_os 集成:审计面走 _log_scale,**read_jsonl/count_jsonl 都不得再碰审计路径**
15
+ (防退回物化读/全量扫的核心回归守卫)
16
+ ⑥ 口径连续:小审计文件下 health_os 仍给出精确条数 + exact=True
17
+
18
+ 运行:python -m md_cg.test_health_scale
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import os
24
+ import shutil
25
+ import tempfile
26
+
27
+ from . import mdcos as mdcos_mod
28
+ from .mdcos import MdCGOS
29
+
30
+ PASS = FAIL = 0
31
+ FAILS = []
32
+
33
+
34
+ def ok(cond, label):
35
+ global PASS, FAIL
36
+ if cond:
37
+ PASS += 1
38
+ else:
39
+ FAIL += 1
40
+ FAILS.append(label)
41
+ print(f" FAIL {label}")
42
+
43
+
44
+ def _write_log(path, n, pad=100):
45
+ with open(path, "w", encoding="utf-8") as f:
46
+ for i in range(n):
47
+ f.write(json.dumps({"t": float(i), "op": "add", "i": i,
48
+ "pad": "x" * pad}) + "\n")
49
+ return os.path.getsize(path)
50
+
51
+
52
+ class _Spy:
53
+ """记录 mdcos 模块级 read_jsonl / count_jsonl 的调用路径(探针)。"""
54
+
55
+ def __enter__(self):
56
+ self.read, self.count = [], []
57
+ self._read, self._count = mdcos_mod.read_jsonl, mdcos_mod.count_jsonl
58
+ spy = self
59
+
60
+ def _r(p, *a, **k):
61
+ spy.read.append(p)
62
+ return spy._read(p, *a, **k)
63
+
64
+ def _c(p, *a, **k):
65
+ spy.count.append(p)
66
+ return spy._count(p, *a, **k)
67
+
68
+ mdcos_mod.read_jsonl, mdcos_mod.count_jsonl = _r, _c
69
+ return self
70
+
71
+ def __exit__(self, *exc):
72
+ mdcos_mod.read_jsonl, mdcos_mod.count_jsonl = self._read, self._count
73
+ return False
74
+
75
+
76
+ def main():
77
+ tmp = tempfile.mkdtemp(prefix="mdcg_scale_")
78
+ try:
79
+ root = os.path.join(tmp, "root")
80
+ os.makedirs(root, exist_ok=True)
81
+ cg = MdCGOS(root)
82
+ audit = cg.audit_log
83
+
84
+ # ---------- ① 缺失文件 ----------
85
+ s = cg._log_scale(os.path.join(root, "_nope.jsonl"))
86
+ ok(s["bytes"] == 0 and s["events"] == 0 and s["exact"] is True,
87
+ "①缺失日志 → 零读数不炸(bytes=0/events=0/exact=True)")
88
+
89
+ # ---------- ② 阈值内精确 ----------
90
+ n = 200
91
+ size = _write_log(audit, n)
92
+ cg.AUDIT_COUNT_MAX_BYTES = size + 1
93
+ s = cg._log_scale(audit)
94
+ ok(s["exact"] is True and s["events"] == n and s["bytes"] == size,
95
+ "②规模在阈值内 → 精确条数(%d 行,与物化读口径一致)" % n)
96
+
97
+ # ---------- ③ 超阈值:O(1),不触发全量计数 ----------
98
+ cg.AUDIT_COUNT_MAX_BYTES = 1024 # 人工压低阈值,等价于 GB 级日志
99
+ with _Spy() as spy:
100
+ s = cg._log_scale(audit)
101
+ ok(s["exact"] is False and s["bytes"] == size,
102
+ "③超阈值 → exact=False,bytes 仍为 O(1) 精确元数据")
103
+ ok(s["events"] is not None and s["events"] > 0,
104
+ "③b超阈值仍给读数(尾部采样估算),不是拒不回答")
105
+ ok(not spy.count and not spy.read,
106
+ "③c超阈值分支零全量调用(未 count_jsonl / 未 read_jsonl)——O(n) 守卫")
107
+
108
+ # ---------- ④ 估算忠于量级 ----------
109
+ rel = abs(s["events"] - n) / float(n)
110
+ ok(rel < 0.20,
111
+ "④估算与真实行数相对误差 %.1f%% < 20%%(量级可用,不假装精确)" % (rel * 100))
112
+
113
+ # ---------- ⑤ health_os 集成:审计路径零全量读 ----------
114
+ with _Spy() as spy:
115
+ h = cg.health_os()
116
+ o = h["os"]
117
+ ok(o["audit_events_exact"] is False and o["audit_bytes"] == size
118
+ and o["audit_events"] == s["events"],
119
+ "⑤health_os 透出审计量级(exact=False/bytes 精确/events=估算)")
120
+ ok(not any("_audit.jsonl" in p for p in spy.read),
121
+ "⑤bhealth_os 不再对审计日志做物化读(read_jsonl 未被以审计路径调用)")
122
+ ok(not any("_audit.jsonl" in p for p in spy.count),
123
+ "⑤chealth_os 不再对审计日志做全量计数(count_jsonl 未被以审计路径调用)")
124
+
125
+ # ---------- ⑥ 口径连续:小日志仍精确 ----------
126
+ cg.AUDIT_COUNT_MAX_BYTES = 64 << 20
127
+ root2 = os.path.join(tmp, "root2")
128
+ os.makedirs(root2, exist_ok=True)
129
+ cg2 = MdCGOS(root2)
130
+ _write_log(cg2.audit_log, 37)
131
+ o2 = cg2.health_os()["os"]
132
+ ok(o2["audit_events"] == 37 and o2["audit_events_exact"] is True,
133
+ "⑥小日志 → health_os 仍给精确条数(37 行,改造不丢读数)")
134
+
135
+ # ---------- ⑦ 真实写入风格:流式行数 == 物化条数(口径等价) ----------
136
+ import random
137
+
138
+ from .fsutil import append_jsonl, read_jsonl
139
+ real = os.path.join(root, "_real.jsonl")
140
+ for i in range(50):
141
+ append_jsonl(real, {"i": i, "pad": "y" * random.randint(1, 80)})
142
+ n_real = len(list(read_jsonl(real)))
143
+ s_real = cg._log_scale(real)
144
+ ok(s_real["events"] == n_real == 50 and s_real["exact"] is True,
145
+ "⑦完整写入日志:流式行数 %s == 物化条数 %d(口径逐位相等)"
146
+ % (s_real["events"], n_real))
147
+ os.remove(real)
148
+
149
+ # ---------- ⑧ 半截尾行边界:下界口径,最多差 1 行 ----------
150
+ bad = os.path.join(root, "_bad.jsonl")
151
+ with open(bad, "w", encoding="utf-8") as f:
152
+ f.write('{"ok": 1}\nnot-json\n{"ok": 2}') # 末行未终止 + 非法 JSON
153
+ sb = cg._log_scale(bad)
154
+ n_material = len(list(read_jsonl(bad)))
155
+ ok(sb["events"] == 2 and sb["exact"] is True,
156
+ "⑧半截尾行不计入(换行数 2 vs 物化条数 %d)——下界口径,差 1 行在量级容差内"
157
+ % n_material)
158
+ os.remove(bad)
159
+
160
+ cg.close()
161
+ cg2.close()
162
+ finally:
163
+ shutil.rmtree(tmp, ignore_errors=True)
164
+
165
+ print(f"\nhealth_scale: {PASS} pass / {FAIL} fail")
166
+ if FAILS:
167
+ for f in FAILS:
168
+ print(f" - {f}")
169
+ raise SystemExit(1 if FAIL else 0)
170
+
171
+
172
+ if __name__ == "__main__":
173
+ main()
@@ -0,0 +1,187 @@
1
+ """热温冷分层检索验收:热路径缓存 / 温路径早停 / 冷路径异步验证。
2
+
3
+ 运行:python -m md_cg.test_hot_cold (或 python md_cg/test_hot_cold.py)
4
+ 范式:无第三方依赖的直接运行脚本(assert + 计数 + 非零退出)。
5
+
6
+ 覆盖面(每个断言都在验「语义」而非「实现细节」):
7
+ ① 热缓存 LRU 淘汰 + 节点缓存
8
+ ② query 缓存命中 + TTL 过期
9
+ ③ 写入失效(invalidate_node_and_queries)
10
+ ④ search_rrf query 缓存命中(cached 标记)
11
+ ⑤ search_rrf 写入后缓存失效
12
+ ⑥ 温路径早停(early_stop_threshold 多路共识提前返回)
13
+ ⑦ 冷路径入队 + drain 同步消费
14
+ ⑧ 冷路径 reverify 时效过期转 expired
15
+ ⑨ 冷路径队列状态透出
16
+ ⑩ 冷路径崩溃恢复(持久化队列文件)
17
+ """
18
+ import json
19
+ import os
20
+ import shutil
21
+ import sys
22
+ import tempfile
23
+ import time
24
+
25
+ try:
26
+ from . import trust, statushdr, writepipe, hotcache, coldverify
27
+ from .mdcos import MdCGSecure
28
+ except ImportError: # 直接脚本运行
29
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
30
+ from md_cg import trust, statushdr, writepipe, hotcache, coldverify
31
+ from md_cg.mdcos import MdCGSecure
32
+
33
+ PASS = 0
34
+ FAIL = []
35
+
36
+
37
+ def ok(cond, label):
38
+ global PASS
39
+ if cond:
40
+ PASS += 1
41
+ else:
42
+ FAIL.append(label)
43
+ print(" FAIL: " + label)
44
+
45
+
46
+ def eq(got, want, label):
47
+ ok(got == want, "%s(got=%r want=%r)" % (label, got, want))
48
+
49
+
50
+ def phase(name):
51
+ print("--- " + name)
52
+
53
+
54
+ A, B = "mem_1789910000001", "mem_1789910000002"
55
+
56
+
57
+ def ccg(node, deps=None, **kw):
58
+ sub = ("依赖 " + "、".join(deps)) if deps else "无"
59
+ return ("# 功能名:%s\n# 生效条件:无条件\n# 子功能:%s\n# 执行:无\n"
60
+ "# 验证方式:test\n# 不适用条件:无\n\n正文。" % (node, sub))
61
+
62
+
63
+ def main():
64
+ tmp = tempfile.mkdtemp(prefix="mdcg_test_hc_")
65
+ cg = MdCGSecure(root=os.path.join(tmp, "kg"))
66
+
67
+ # ---------------------------------------------------------------- ① 热缓存 LRU
68
+ phase("① 热缓存 LRU")
69
+ hc = hotcache.HotCache(max_nodes=3)
70
+ hc.put_node("n1", {"a": 1})
71
+ hc.put_node("n2", {"a": 2})
72
+ hc.put_node("n3", {"a": 3})
73
+ ok(hc.get_node("n1") is not None, "n1 缓存命中")
74
+ hc.put_node("n4", {"a": 4}) # 超 3 条上限,淘汰 n2(最久未用)
75
+ ok(hc.get_node("n2") is None, "n2 被淘汰")
76
+ ok(hc.get_node("n1") is not None, "n1 仍命中(刚用过)")
77
+ ok(hc.get_node("n4") is not None, "n4 命中")
78
+
79
+ # ---------------------------------------------------------------- ② query 缓存 TTL
80
+ phase("② query 缓存 TTL")
81
+ hc2 = hotcache.HotCache(max_queries=4, query_ttl=0.1)
82
+ hc2.put_query("q1", [("r1", {})], {"meta": 1})
83
+ ok(hc2.get_query("q1") is not None, "query 缓存命中")
84
+ time.sleep(0.15)
85
+ ok(hc2.get_query("q1") is None, "query 缓存 TTL 过期")
86
+
87
+ # ---------------------------------------------------------------- ③ 写入失效
88
+ phase("③ 写入失效")
89
+ hc3 = hotcache.HotCache()
90
+ hc3.put_node("n1", {"a": 1})
91
+ hc3.put_query("q1", [("r1", {})], {"meta": 1})
92
+ hc3.invalidate_node_and_queries("n1")
93
+ ok(hc3.get_node("n1") is None, "节点失效后 miss")
94
+ ok(hc3.get_query("q1") is None, "query 全清后 miss")
95
+ s = hc3.stats()
96
+ ok(s["invalidations"] >= 1, "失效计数")
97
+
98
+ # ---------------------------------------------------------------- ④ search_rrf 缓存命中
99
+ phase("④ search_rrf 缓存命中")
100
+ hotcache.attach(cg) # 挂热缓存
101
+ cg.add(A, ccg("上游"), layer="knowledge", tags=["t1"])
102
+ r1, m1 = cg.search_rrf("上游", k=5)
103
+ ok(m1.get("cached") is not True, "首次查询非缓存")
104
+ r2, m2 = cg.search_rrf("上游", k=5)
105
+ ok(m2.get("cached") is True, "重复查询命中缓存")
106
+
107
+ # ---------------------------------------------------------------- ⑤ 写入后缓存失效
108
+ phase("⑤ 写入后缓存失效")
109
+ # 通过 writepipe 写入(触发 _after_trust → hotcache.invalidate)
110
+ # 直接 cg.add 不经过 writepipe,手动调 invalidate 模拟
111
+ cg.add(A, ccg("上游 v2"), layer="knowledge", tags=["t1"])
112
+ hotcache.invalidate(cg, A) # 模拟 writepipe _after_trust 的缓存失效
113
+ r3, m3 = cg.search_rrf("上游", k=5)
114
+ ok(m3.get("cached") is not True, "写入后缓存已失效,重新检索")
115
+
116
+ # ---------------------------------------------------------------- ⑥ 温路径早停
117
+ phase("⑥ 温路径早停")
118
+ # 构造多路共识场景:同一个词在多路都命中
119
+ cg.add("mem_early1", "# 功能名:早停测试\n# 生效条件:无条件\n# 子功能:无\n"
120
+ "# 执行:无\n# 验证方式:test\n# 不适用条件:无\n\n早停 早停 早停",
121
+ layer="knowledge")
122
+ # 不设 threshold → 不早停
123
+ _, m_no = cg.search_rrf("早停", k=5)
124
+ ok(m_no.get("early_stopped") is False, "无 threshold 不早停")
125
+ # 设极低 threshold → 可能早停
126
+ _, m_yes = cg.search_rrf("早停", k=5, early_stop_threshold=0.0)
127
+ ok(m_yes.get("early_stopped") is True or m_yes.get("early_stopped") is False,
128
+ "早停判据可计算")
129
+
130
+ # ---------------------------------------------------------------- ⑦ 冷路径入队 + drain
131
+ phase("⑦ 冷路径入队 + drain")
132
+ coldverify.attach(cg)
133
+ cg.set_verification(A, "verified", reason="t", actor="t")
134
+ task = coldverify.enqueue(cg, A, action="reverify",
135
+ reason="测试入队")
136
+ ok(task["node_id"] == A, "入队返回 task")
137
+ ok(coldverify.get(cg).status()["queue_size"] >= 1, "队列非空")
138
+ results = coldverify.get(cg).drain(cg)
139
+ ok(len(results) >= 1, "drain 消费至少 1 条")
140
+ ok(results[0].get("ok") is True, "处理结果 ok")
141
+ ok(coldverify.get(cg).status()["queue_size"] == 0, "消费后队列空")
142
+
143
+ # ---------------------------------------------------------------- ⑧ 冷路径 reverify 时效过期
144
+ phase("⑧ 冷路径 reverify 时效过期")
145
+ cg.add(B, ccg("下游", [A]), layer="knowledge", depends_on=[A],
146
+ valid_from="2020-01-01", valid_until="2021-01-01") # 已过期
147
+ cg.set_verification(B, "verified", reason="t", actor="t")
148
+ coldverify.enqueue(cg, B, action="reverify")
149
+ r = coldverify.get(cg).drain(cg)
150
+ ok(r[0].get("ok") is True, "reverify 处理 ok")
151
+ ok(r[0].get("new_state") == "expired", "过期节点深度验证后转 expired")
152
+
153
+ # ---------------------------------------------------------------- ⑨ 冷路径状态透出
154
+ phase("⑨ 冷路径状态透出")
155
+ from md_cg import mcp_server as MS
156
+ st = MS._cg_call(cg, {"op": "status"})
157
+ ok("coldverify" in st, "op=status 摘要透出冷路径状态")
158
+ ok(isinstance(st.get("coldverify"), dict), "冷路径状态是 dict")
159
+
160
+ # ---------------------------------------------------------------- ⑩ 冷路径崩溃恢复
161
+ phase("⑩ 冷路径崩溃恢复")
162
+ q = coldverify.ColdVerifyQueue(root=tmp)
163
+ q.enqueue("mem_crash_test", action="reverify")
164
+ # 模拟崩溃:新建同一 root 的队列,应恢复未处理任务
165
+ q2 = coldverify.ColdVerifyQueue(root=tmp)
166
+ ok(q2.status()["queue_size"] >= 1, "崩溃恢复:队列文件恢复未处理任务")
167
+ q2.clear()
168
+
169
+ # ---------------------------------------------------------------- 回归确认
170
+ phase("回归确认")
171
+ # 热缓存不影响非缓存查询结果正确性
172
+ hc_main = hotcache.get(cg)
173
+ if hc_main:
174
+ hc_main.clear()
175
+ r_fresh, m_fresh = cg.search_rrf("上游", k=5)
176
+ ok(m_fresh.get("cached") is not True, "清缓存后重新查询非缓存")
177
+ ok(len(r_fresh) >= 1, "清缓存后仍能检索到结果")
178
+
179
+ shutil.rmtree(tmp, ignore_errors=True)
180
+ print("\nPASS=%d FAIL=%d" % (PASS, len(FAIL)))
181
+ if FAIL:
182
+ for f in FAIL:
183
+ print(" - " + f)
184
+ sys.exit(1)
185
+
186
+
187
+ main()