@furongjun1999/dsh-memory 0.4.11 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) hide show
  1. package/README.md +552 -465
  2. package/codebuddy/CODEBUDDY.md +11 -3
  3. package/codebuddy/README.md +92 -90
  4. package/codebuddy/mcp.json +27 -27
  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 -169
  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 -144
  7. package/docs/README.md +143 -111
  8. package/docs/discipline/harnesses.yaml +244 -226
  9. package/docs/discipline/templates/full.md.tmpl +61 -61
  10. package/docs/discipline/templates/rules.mdc.tmpl +68 -0
  11. package/docs/discipline/templates/skill.md.tmpl +23 -23
  12. package/docs/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 +299 -299
  13. package/docs/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 +239 -239
  14. package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
  15. package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
  16. package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
  17. package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
  18. 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 +174 -174
  19. package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
  20. 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 +223 -223
  21. package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
  22. package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
  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_v1.md +156 -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_v10.md +210 -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_v11.md +227 -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_v12.md +203 -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_v13.md +233 -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_v14.md +191 -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_v15.md +213 -0
  30. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
  31. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
  32. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
  33. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
  34. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
  35. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
  36. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
  37. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
  38. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
  39. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
  40. package/docs/{mdcg → hive}//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 +165 -160
  41. package/docs/hive//344/273/244/347/211/214/350/257/255/344/271/211/344/277/256/346/255/243_/344/273/262/350/243/201/344/275/215_v0.1.md +76 -0
  42. package/docs/{mdcg → hive}//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 -236
  43. package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
  44. 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 -43
  45. package/docs/hive//346/243/200/347/264/242/347/256/227/346/263/225/345/217/243/345/276/204/345/257/271/347/205/247_v0.1.md +85 -0
  46. 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 -102
  47. 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 +47 -0
  48. 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 +519 -503
  49. 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 +85 -85
  50. package/docs/hive//350/234/202/345/267/242/350/256/276/350/256/241_/347/220/206/350/256/272/345/257/271/351/275/220_v0.1.md +191 -0
  51. package/docs/hive//350/234/202/345/267/242/350/277/255/344/273/243_/345/256/217/350/247/202/344/270/216/347/276/244/344/275/223/350/260/203/345/272/246_v0.1.md +90 -0
  52. package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
  53. package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
  54. package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -216
  55. package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +646 -646
  56. package/docs/mdcg/lingshu_tutorial.html +14449 -14449
  57. package/docs/mdcg/release_v0.4.11.md +49 -0
  58. package/docs/mdcg/release_v0.4.5.md +55 -55
  59. package/docs/mdcg/tool_table_v0.3.0.md +117 -117
  60. 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 -600
  61. 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
  62. 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 +275 -275
  63. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +54 -0
  64. 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 +130 -130
  65. 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 +278 -278
  66. 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 -172
  67. package/docs/mdcg//347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +270 -270
  68. 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 +491 -491
  69. 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 +340 -340
  70. 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 +588 -588
  71. 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 -176
  72. 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 +81 -81
  73. package/docs/swarm//350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +704 -704
  74. 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 -242
  75. package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
  76. 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 -129
  77. 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 -134
  78. package/docs/theory//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
  79. 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 -145
  80. 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 +144 -144
  81. 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 +198 -198
  82. 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 -221
  83. 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 -237
  84. package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
  85. package/docs//345/217/221/345/270/203/344/273/266/345/233/236/346/272/257/350/257/264/346/230/216_v0.1.md +82 -82
  86. 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 +28 -2
  87. package/dsh/README.md +82 -82
  88. package/dsh/cordis.yml.example +139 -139
  89. package/dsh/update-lingshu.bat +11 -11
  90. package/lib/bridge.d.ts +9 -0
  91. package/lib/bridge.js +35 -0
  92. package/lib/hooks.js +36 -2
  93. package/lib/index.js +7 -1
  94. package/lib/lib/roleplay_web.js +116 -29
  95. package/lib/lib/token_store.d.ts +7 -1
  96. package/lib/lib/token_store.js +12 -3
  97. package/md_cg/__init__.py +7 -7
  98. package/md_cg/audit.py +379 -368
  99. package/md_cg/autonomy.py +287 -287
  100. package/md_cg/backfill.py +1328 -1327
  101. package/md_cg/backfill_bigdomain.py +34 -34
  102. package/md_cg/backfill_bucket_zh.py +35 -0
  103. package/md_cg/bench6_arms.py +410 -410
  104. package/md_cg/bench6_common.py +230 -230
  105. package/md_cg/bench6_competitors.py +212 -212
  106. package/md_cg/bench_axis_domain.py +257 -257
  107. package/md_cg/bench_blind_comp.py +308 -308
  108. package/md_cg/bench_e2e_judge.py +532 -0
  109. package/md_cg/bench_e2e_locomo_qa.py +368 -0
  110. package/md_cg/bench_e2e_qa.py +256 -0
  111. package/md_cg/bench_en_atoms_public.py +230 -230
  112. package/md_cg/bench_governance.py +348 -348
  113. package/md_cg/bench_lme_zh.py +410 -410
  114. package/md_cg/bench_locomo.py +121 -121
  115. package/md_cg/bench_locomo_zh.py +450 -450
  116. package/md_cg/bench_locomo_zh_public.py +147 -147
  117. package/md_cg/bench_longmem.py +112 -112
  118. package/md_cg/bench_membench.py +632 -632
  119. package/md_cg/bench_p0.py +149 -149
  120. package/md_cg/bench_progressive.py +287 -287
  121. package/md_cg/bench_role_views.py +238 -238
  122. package/md_cg/bench_task_ab.py +243 -243
  123. package/md_cg/bench_task_ab_llm.py +408 -408
  124. package/md_cg/bench_unified_en.py +204 -204
  125. package/md_cg/bench_zh_mad.py +601 -601
  126. package/md_cg/blindspot_tickets.py +123 -123
  127. package/md_cg/branches.py +301 -285
  128. package/md_cg/build_postings.py +73 -73
  129. package/md_cg/ccgc.py +1006 -948
  130. package/md_cg/census.py +132 -132
  131. package/md_cg/chain.py +315 -300
  132. package/md_cg/codeindex.py +531 -531
  133. package/md_cg/coldverify.py +292 -292
  134. package/md_cg/comment_gate.py +337 -337
  135. package/md_cg/cond_compose.py +190 -190
  136. package/md_cg/cond_facts.py +154 -154
  137. package/md_cg/cond_template.json +106 -106
  138. package/md_cg/condition_anchor.py +142 -142
  139. package/md_cg/conformance.py +726 -726
  140. package/md_cg/consistency.py +717 -717
  141. package/md_cg/consolidate.py +1537 -1439
  142. package/md_cg/corpus.py +110 -110
  143. package/md_cg/crosscheck.py +1098 -1097
  144. package/md_cg/crypto.py +3 -1
  145. package/md_cg/d_meta.py +310 -310
  146. package/md_cg/datapath.py +78 -18
  147. package/md_cg/docindex.py +473 -473
  148. package/md_cg/eval_common.py +575 -575
  149. package/md_cg/evidence.py +4 -2
  150. package/md_cg/evolution.py +477 -477
  151. package/md_cg/export.py +222 -220
  152. package/md_cg/forgetting.py +581 -581
  153. package/md_cg/fsutil.py +377 -329
  154. package/md_cg/hotcache.py +48 -7
  155. package/md_cg/hyperedge.py +251 -251
  156. package/md_cg/identity.py +390 -390
  157. package/md_cg/insight.py +500 -500
  158. package/md_cg/interop.py +338 -0
  159. package/md_cg/judgment_manifest.py +177 -0
  160. package/md_cg/lexicon/build_cedict_en_zh.py +329 -329
  161. package/md_cg/lexicon/build_standard_en.py +171 -171
  162. package/md_cg/lexicon/expand_en_zh.py +211 -211
  163. package/md_cg/lifecycle.py +272 -272
  164. package/md_cg/linkref.py +280 -280
  165. package/md_cg/links.py +140 -107
  166. package/md_cg/mcp_server.py +403 -55
  167. package/md_cg/md_whitebox.py +345 -345
  168. package/md_cg/mdcg.py +783 -233
  169. package/md_cg/mdcos.py +500 -70
  170. package/md_cg/metacognition.py +591 -591
  171. package/md_cg/migrate.py +119 -119
  172. package/md_cg/migrate_aeis.py +221 -221
  173. package/md_cg/migrate_roleplay.py +293 -293
  174. package/md_cg/migrate_wisdom_graph.py +360 -360
  175. package/md_cg/mreview/__init__.py +25 -25
  176. package/md_cg/mreview/__main__.py +110 -110
  177. package/md_cg/mreview/bundle.py +178 -178
  178. package/md_cg/mreview/candidates.py +262 -262
  179. package/md_cg/mreview/govern.py +694 -693
  180. package/md_cg/mreview/locate.py +939 -939
  181. package/md_cg/mreview/pipeline.py +728 -728
  182. package/md_cg/mreview/rules/duplication.json +21 -21
  183. package/md_cg/mreview/rules/field_coverage.json +54 -54
  184. package/md_cg/mreview/rules/source_license.json +21 -21
  185. package/md_cg/mreview/rules/template_flow.json +21 -21
  186. package/md_cg/mreview/ruleset.py +252 -252
  187. package/md_cg/nodefile.py +575 -575
  188. package/md_cg/pooling.py +484 -472
  189. package/md_cg/postings.py +300 -298
  190. package/md_cg/predict.py +1100 -1100
  191. package/md_cg/progressive.py +123 -123
  192. package/md_cg/protect.py +272 -272
  193. package/md_cg/protocol/md_cg_gate.proto +33 -33
  194. package/md_cg/protocol.py +372 -372
  195. package/md_cg/provenance.py +582 -582
  196. package/md_cg/reach.py +453 -453
  197. package/md_cg/readcache.py +143 -0
  198. package/md_cg/reconcile.py +228 -0
  199. package/md_cg/refindex.py +833 -833
  200. package/md_cg/refine.py +604 -604
  201. package/md_cg/review_cli.py +170 -0
  202. package/md_cg/roleviews.py +89 -89
  203. package/md_cg/routing.py +393 -365
  204. package/md_cg/run_tests.py +211 -0
  205. package/md_cg/scrub.py +13 -3
  206. package/md_cg/security.py +128 -18
  207. package/md_cg/self_state.py +1029 -1029
  208. package/md_cg/selfreport.py +152 -151
  209. package/md_cg/semantic/__init__.py +10 -10
  210. package/md_cg/semantic/canonical.py +122 -122
  211. package/md_cg/semantic/en_normalizer.py +364 -364
  212. package/md_cg/semantic/en_zh_map.json +28694 -0
  213. package/md_cg/semantic/export_en_zh_map.py +64 -0
  214. package/md_cg/semantic/unify.py +45 -0
  215. package/md_cg/semantic/zh_en_atoms.py +139 -139
  216. package/md_cg/signer.py +7 -4
  217. package/md_cg/sources.py +816 -582
  218. package/md_cg/statushdr.py +179 -179
  219. package/md_cg/stg.py +54 -37
  220. package/md_cg/subgraph.py +729 -729
  221. package/md_cg/sustain.py +35 -5
  222. package/md_cg/tasks.py +470 -470
  223. package/md_cg/test_access_hints.py +147 -0
  224. package/md_cg/test_action_derive.py +203 -203
  225. package/md_cg/test_audit_rotate.py +270 -270
  226. package/md_cg/test_autonomy.py +143 -143
  227. package/md_cg/test_bench_governance.py +102 -102
  228. package/md_cg/test_blindspot_tickets.py +166 -166
  229. package/md_cg/test_branch_discard_tombstone.py +136 -0
  230. package/md_cg/test_branches.py +13 -3
  231. package/md_cg/test_ccg_perturb.py +184 -184
  232. package/md_cg/test_ccgc.py +433 -433
  233. package/md_cg/test_census_prune.py +81 -81
  234. package/md_cg/test_chain_read_isolate.py +168 -0
  235. package/md_cg/test_cond_compose_anchors.py +76 -76
  236. package/md_cg/test_cond_match.py +165 -165
  237. package/md_cg/test_condition_anchor.py +81 -81
  238. package/md_cg/test_d_meta.py +412 -412
  239. package/md_cg/test_datapath_device_name.py +203 -0
  240. package/md_cg/test_datapath_root.py +199 -199
  241. package/md_cg/test_emit_negtail_cache.py +156 -0
  242. package/md_cg/test_en_pipeline.py +22 -2
  243. package/md_cg/test_gain_gate.py +212 -212
  244. package/md_cg/test_govern_directread.py +421 -0
  245. package/md_cg/test_health_scale.py +173 -173
  246. package/md_cg/test_hive_ingest.py +285 -0
  247. package/md_cg/test_hot_cold.py +215 -215
  248. package/md_cg/test_hyperedge.py +245 -245
  249. package/md_cg/test_i26_empty_first_write.py +116 -0
  250. package/md_cg/test_i27_e041_identity.py +128 -0
  251. package/md_cg/test_i28_hotcache_prodpath.py +122 -0
  252. package/md_cg/test_i32_hotcache_env_key.py +218 -0
  253. package/md_cg/test_identity_attribution.py +96 -15
  254. package/md_cg/test_index_durability.py +17 -3
  255. package/md_cg/test_interop.py +95 -0
  256. package/md_cg/test_interop_judgment.py +228 -0
  257. package/md_cg/test_issue39_utf8_stdio.py +273 -0
  258. package/md_cg/test_lifecycle.py +309 -309
  259. package/md_cg/test_linkref.py +306 -306
  260. package/md_cg/test_links_concurrent_write.py +188 -0
  261. package/md_cg/test_lock.py +43 -43
  262. package/md_cg/test_md_access_parity.py +255 -255
  263. package/md_cg/test_md_writepath.py +345 -345
  264. package/md_cg/test_mdstore_search_parity.py +160 -0
  265. package/md_cg/test_merge_upsert.py +168 -0
  266. package/md_cg/test_mr_m2.py +587 -587
  267. package/md_cg/test_mr_m3.py +710 -710
  268. package/md_cg/test_mr_m4.py +485 -485
  269. package/md_cg/test_n123_derive_expiry_chain.py +205 -0
  270. package/md_cg/test_n130_verify_falsified_protect.py +185 -0
  271. package/md_cg/test_n131_merge_gate.py +205 -0
  272. package/md_cg/test_p0.py +250 -250
  273. package/md_cg/test_p1.py +316 -316
  274. package/md_cg/test_p10_identity.py +173 -173
  275. package/md_cg/test_p11_consistency.py +233 -233
  276. package/md_cg/test_p12_metacognition.py +212 -212
  277. package/md_cg/test_p13_encryption.py +241 -241
  278. package/md_cg/test_p14_sustain.py +249 -249
  279. package/md_cg/test_p15_scrub.py +280 -280
  280. package/md_cg/test_p16_self_state.py +301 -301
  281. package/md_cg/test_p17_predict.py +354 -354
  282. package/md_cg/test_p18_whitebox.py +171 -171
  283. package/md_cg/test_p19_migrate_roleplay.py +149 -149
  284. package/md_cg/test_p1x_ref_root.py +160 -0
  285. package/md_cg/test_p20_evolution.py +315 -315
  286. package/md_cg/test_p21_tokens.py +293 -270
  287. package/md_cg/test_p22_theory.py +175 -175
  288. package/md_cg/test_p23_links.py +311 -311
  289. package/md_cg/test_p24_evidence.py +227 -227
  290. package/md_cg/test_p25_weights.py +156 -156
  291. package/md_cg/test_p26_refindex.py +416 -416
  292. package/md_cg/test_p27_docindex.py +16 -7
  293. package/md_cg/test_p28_refcheck.py +305 -305
  294. package/md_cg/test_p29_session_ingest_export.py +354 -333
  295. package/md_cg/test_p2_mcp.py +3 -0
  296. package/md_cg/test_p3.py +11 -2
  297. package/md_cg/test_p30_maintain.py +330 -330
  298. package/md_cg/test_p31_insight.py +534 -534
  299. package/md_cg/test_p32_backfill.py +7 -1
  300. package/md_cg/test_p33_ccg_wiring.py +293 -293
  301. package/md_cg/test_p34_crosscheck.py +331 -331
  302. package/md_cg/test_p35_conditioned_claim.py +252 -252
  303. package/md_cg/test_p36_kp_align.py +230 -230
  304. package/md_cg/test_p37_condition_space.py +248 -248
  305. package/md_cg/test_p38_concurrent_flush.py +102 -0
  306. package/md_cg/test_p38_contextualize.py +273 -273
  307. package/md_cg/test_p39_verify_flow.py +153 -0
  308. package/md_cg/test_p39_vision_evidence.py +369 -369
  309. package/md_cg/test_p40_refine_worklist.py +241 -241
  310. package/md_cg/test_p41_evolve_patrol.py +224 -224
  311. package/md_cg/test_p42_provenance.py +269 -269
  312. package/md_cg/test_p43_pooling.py +412 -398
  313. package/md_cg/test_p44_md_whitebox.py +231 -231
  314. package/md_cg/test_p45_session_identity.py +219 -219
  315. package/md_cg/test_p46_unit_scope.py +272 -272
  316. package/md_cg/test_p47_session_view.py +316 -0
  317. package/md_cg/test_p4_fuzzy.py +223 -223
  318. package/md_cg/test_p5_semantic.py +226 -226
  319. package/md_cg/test_p6_consolidate.py +440 -387
  320. package/md_cg/test_p7_goals_recent.py +202 -202
  321. package/md_cg/test_p8_subgraph_chain.py +200 -200
  322. package/md_cg/test_p9_forget_protect.py +231 -231
  323. package/md_cg/test_predict_beta.py +135 -135
  324. package/md_cg/test_preflight_failclosed.py +100 -100
  325. package/md_cg/test_progressive.py +146 -146
  326. package/md_cg/test_propose_tail_index.py +157 -0
  327. package/md_cg/test_protocol.py +243 -243
  328. package/md_cg/test_reach.py +378 -378
  329. package/md_cg/test_reach_keys.py +201 -201
  330. package/md_cg/test_read_clip.py +141 -141
  331. package/md_cg/test_read_scope_b27.py +277 -0
  332. package/md_cg/test_readcache_default_on.py +168 -0
  333. package/md_cg/test_readcache_precise_inval.py +270 -0
  334. package/md_cg/test_readcache_prodpath.py +203 -0
  335. package/md_cg/test_reconcile_v0.py +294 -0
  336. package/md_cg/test_retr_gates_prodpath.py +140 -0
  337. package/md_cg/test_retr_s1.py +344 -340
  338. package/md_cg/test_retr_s1b.py +276 -209
  339. package/md_cg/test_retr_s3.py +194 -194
  340. package/md_cg/test_retr_s4.py +163 -163
  341. package/md_cg/test_retr_s5.py +200 -200
  342. package/md_cg/test_retr_s6.py +157 -157
  343. package/md_cg/test_retr_s7.py +392 -384
  344. package/md_cg/test_retr_s8_time.py +369 -316
  345. package/md_cg/test_retr_s9_edges.py +286 -286
  346. package/md_cg/test_retr_s9_entity_ctx.py +9 -3
  347. package/md_cg/test_retr_score_once.py +208 -0
  348. package/md_cg/test_review_conformance.py +367 -367
  349. package/md_cg/test_review_onepass.py +170 -0
  350. package/md_cg/test_role_views.py +354 -354
  351. package/md_cg/test_rrf_graph_seed_cache.py +154 -0
  352. package/md_cg/test_security_audit.py +155 -0
  353. package/md_cg/test_security_audit_b26.py +161 -0
  354. package/md_cg/test_security_audit_v21.py +250 -0
  355. package/md_cg/test_sem_noise.py +242 -242
  356. package/md_cg/test_semantic_canonical.py +16 -2
  357. package/md_cg/test_session_isolation.py +168 -0
  358. package/md_cg/test_snapshot_autoclose.py +187 -0
  359. package/md_cg/test_subproc_encoding.py +192 -192
  360. package/md_cg/test_sustain_mutual.py +153 -153
  361. package/md_cg/test_tail_watermark_race.py +208 -0
  362. package/md_cg/test_tasks.py +409 -409
  363. package/md_cg/test_tenant_env_override_warn.py +139 -0
  364. package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
  365. package/md_cg/test_tool_face.py +189 -189
  366. package/md_cg/test_transfer.py +180 -180
  367. package/md_cg/test_trust.py +361 -361
  368. package/md_cg/test_twophase.py +286 -286
  369. package/md_cg/test_v14_fixes.py +38 -20
  370. package/md_cg/test_validity_filter.py +280 -280
  371. package/md_cg/test_verify_answer.py +138 -138
  372. package/md_cg/test_verify_dirty_reconcile.py +157 -0
  373. package/md_cg/test_wisdom_md_store.py +292 -292
  374. package/md_cg/test_writelimit.py +197 -197
  375. package/md_cg/test_writepipe.py +214 -214
  376. package/md_cg/theory.py +6 -3
  377. package/md_cg/tokens.py +85 -14
  378. package/md_cg/tool_face.py +260 -260
  379. package/md_cg/trust.py +986 -950
  380. package/md_cg/twophase.py +231 -231
  381. package/md_cg/units.py +668 -667
  382. package/md_cg/vision_evidence.py +667 -666
  383. package/md_cg/weights.py +624 -624
  384. package/md_cg/whitebox.py +527 -527
  385. package/md_cg/whitebox_kb/__init__.py +37 -37
  386. package/md_cg/whitebox_kb/aeis_core/__init__.py +42 -42
  387. package/md_cg/whitebox_kb/aeis_core/semantic.py +280 -280
  388. package/md_cg/whitebox_kb/aeis_core/textutil.py +13 -13
  389. package/md_cg/whitebox_kb/engine.py +310 -310
  390. package/md_cg/whitebox_kb/seed_knowledge//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
  391. package/md_cg/whitebox_kb/wisdom/browser_units.py +2631 -2631
  392. package/md_cg/whitebox_kb/wisdom/causal_discover.py +432 -432
  393. package/md_cg/whitebox_kb/wisdom/chat_engine.py +1506 -1506
  394. package/md_cg/whitebox_kb/wisdom/compiler_code_units.py +3033 -3033
  395. package/md_cg/whitebox_kb/wisdom/condition_algebra.py +112 -112
  396. package/md_cg/whitebox_kb/wisdom/condition_frame.py +315 -315
  397. package/md_cg/whitebox_kb/wisdom/condition_kb.py +108 -108
  398. package/md_cg/whitebox_kb/wisdom/conflict_map.json +4445 -4445
  399. package/md_cg/whitebox_kb/wisdom/core/lexer.py +512 -512
  400. package/md_cg/whitebox_kb/wisdom/core/name_checker.py +1023 -1023
  401. package/md_cg/whitebox_kb/wisdom/cspmn.py +258 -258
  402. package/md_cg/whitebox_kb/wisdom/csre.py +264 -264
  403. package/md_cg/whitebox_kb/wisdom/danmaku_audit.py +252 -252
  404. package/md_cg/whitebox_kb/wisdom/distilled_condition_units.json +6417 -6417
  405. package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902b.json +1950 -1950
  406. package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902c.json +1296 -1296
  407. package/md_cg/whitebox_kb/wisdom/docs/whitebox_capability_graph_demo.json +59 -59
  408. package/md_cg/whitebox_kb/wisdom/graph_db_units.py +3089 -3089
  409. package/md_cg/whitebox_kb/wisdom/knowledge_points.py +318 -318
  410. package/md_cg/whitebox_kb/wisdom/md_access.py +470 -470
  411. package/md_cg/whitebox_kb/wisdom/md_store.py +276 -251
  412. package/md_cg/whitebox_kb/wisdom/migrate_wisdom.py +476 -476
  413. package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
  414. package/md_cg/whitebox_kb/wisdom/navigate.py +248 -248
  415. package/md_cg/whitebox_kb/wisdom/neural_retrieve.py +224 -224
  416. package/md_cg/whitebox_kb/wisdom/os_units.py +2735 -2735
  417. package/md_cg/whitebox_kb/wisdom/pattern_separation.py +376 -376
  418. package/md_cg/whitebox_kb/wisdom/prereq_map.json +364 -364
  419. package/md_cg/whitebox_kb/wisdom/python_code_units.py +2766 -2766
  420. package/md_cg/whitebox_kb/wisdom/role_solidified.json +7 -7
  421. package/md_cg/whitebox_kb/wisdom/route_memory.py +244 -244
  422. package/md_cg/whitebox_kb/wisdom/scene_reconstruction.py +148 -148
  423. package/md_cg/whitebox_kb/wisdom/snr_report.json +40 -40
  424. package/md_cg/whitebox_kb/wisdom/test_code_compose_domains.py +7541 -7541
  425. package/md_cg/whitebox_kb/wisdom/test_compiler_self_bootstrap.py +354 -354
  426. package/md_cg/whitebox_kb/wisdom/test_ecosystem_assembly.py +158 -158
  427. package/md_cg/whitebox_kb/wisdom/test_ecosystem_demos.py +193 -193
  428. package/md_cg/whitebox_kb/wisdom/test_graph_db.py +292 -292
  429. package/md_cg/whitebox_kb/wisdom/test_python_self_bootstrap.py +160 -160
  430. package/md_cg/whitebox_kb/wisdom/trigger_words_index.json +4366 -4366
  431. package/md_cg/whitebox_kb/wisdom/verifier.py +1297 -1297
  432. package/md_cg/writelimit.py +356 -356
  433. package/md_cg/writepipe.py +20 -8
  434. package/package.json +101 -96
  435. package/skills/plugin.json +54 -54
  436. package/skills/skills/designer-perspective/SKILL.md +158 -158
  437. package/skills/skills/designer-perspective/references/01-observation-position.md +66 -66
  438. package/skills/skills/designer-perspective/references/02-structure-recognition.md +62 -62
  439. package/skills/skills/designer-perspective/references/03-direction-judgment.md +55 -55
  440. package/skills/skills/designer-perspective/references/04-qualification-verdict.md +72 -72
  441. package/skills/skills/designer-perspective/references/05-condition-attribution.md +74 -74
  442. package/skills/skills/designer-perspective/scripts/designer.py +545 -545
  443. package/skills/skills/designer-perspective/tests/cases.jsonl +17 -17
  444. package/skills/skills/designer-perspective/tests/selftest.py +61 -61
  445. package/skills/skills/lingshu-browser/SKILL.md +60 -60
  446. package/skills/skills/lingshu-compiler/SKILL.md +56 -56
  447. package/skills/skills/lingshu-compiler/units/analyze-type-infer/SKILL.md +45 -45
  448. package/skills/skills/lingshu-compiler/units/check-name-real/SKILL.md +45 -45
  449. package/skills/skills/lingshu-compiler/units/compile-assign/SKILL.md +45 -45
  450. package/skills/skills/lingshu-compiler/units/compile-expr-tree/SKILL.md +45 -45
  451. package/skills/skills/lingshu-compiler/units/compile-full-pipeline/SKILL.md +45 -45
  452. package/skills/skills/lingshu-compiler/units/compile-func-def/SKILL.md +45 -45
  453. package/skills/skills/lingshu-compiler/units/compile-if-then/SKILL.md +45 -45
  454. package/skills/skills/lingshu-compiler/units/compile-logic-expr/SKILL.md +45 -45
  455. package/skills/skills/lingshu-compiler/units/compile-recursive/SKILL.md +45 -45
  456. package/skills/skills/lingshu-compiler/units/compile-scope/SKILL.md +45 -45
  457. package/skills/skills/lingshu-compiler/units/compile-type-check/SKILL.md +45 -45
  458. package/skills/skills/lingshu-compiler/units/compile-while/SKILL.md +45 -45
  459. package/skills/skills/lingshu-compiler/units/compiler-0010c4bf/SKILL.md +45 -45
  460. package/skills/skills/lingshu-compiler/units/compiler-0355bffb/SKILL.md +45 -45
  461. package/skills/skills/lingshu-compiler/units/compiler-0361708a/SKILL.md +45 -45
  462. package/skills/skills/lingshu-compiler/units/compiler-054a0414/SKILL.md +45 -45
  463. package/skills/skills/lingshu-compiler/units/compiler-05a1691a/SKILL.md +45 -45
  464. package/skills/skills/lingshu-compiler/units/compiler-05eeed1e/SKILL.md +45 -45
  465. package/skills/skills/lingshu-compiler/units/compiler-0622a1f6/SKILL.md +45 -45
  466. package/skills/skills/lingshu-compiler/units/compiler-08b54217/SKILL.md +45 -45
  467. package/skills/skills/lingshu-compiler/units/compiler-0a62b70c/SKILL.md +45 -45
  468. package/skills/skills/lingshu-compiler/units/compiler-0ab24d00/SKILL.md +45 -45
  469. package/skills/skills/lingshu-compiler/units/compiler-0e093688/SKILL.md +45 -45
  470. package/skills/skills/lingshu-compiler/units/compiler-0e82b966/SKILL.md +45 -45
  471. package/skills/skills/lingshu-compiler/units/compiler-0ee9b9b9/SKILL.md +45 -45
  472. package/skills/skills/lingshu-compiler/units/compiler-0f3787e6/SKILL.md +45 -45
  473. package/skills/skills/lingshu-compiler/units/compiler-1028685f/SKILL.md +45 -45
  474. package/skills/skills/lingshu-compiler/units/compiler-11897630/SKILL.md +45 -45
  475. package/skills/skills/lingshu-compiler/units/compiler-16661b9b/SKILL.md +45 -45
  476. package/skills/skills/lingshu-compiler/units/compiler-1f722303/SKILL.md +45 -45
  477. package/skills/skills/lingshu-compiler/units/compiler-25be1262/SKILL.md +45 -45
  478. package/skills/skills/lingshu-compiler/units/compiler-2a76ba07/SKILL.md +45 -45
  479. package/skills/skills/lingshu-compiler/units/compiler-2dbea54a/SKILL.md +45 -45
  480. package/skills/skills/lingshu-compiler/units/compiler-2df52f16/SKILL.md +45 -45
  481. package/skills/skills/lingshu-compiler/units/compiler-2ec2c9d2/SKILL.md +45 -45
  482. package/skills/skills/lingshu-compiler/units/compiler-2f8c8f39/SKILL.md +45 -45
  483. package/skills/skills/lingshu-compiler/units/compiler-38378ac7/SKILL.md +45 -45
  484. package/skills/skills/lingshu-compiler/units/compiler-39457d2e/SKILL.md +45 -45
  485. package/skills/skills/lingshu-compiler/units/compiler-39fb5926/SKILL.md +45 -45
  486. package/skills/skills/lingshu-compiler/units/compiler-47f4fbfa/SKILL.md +45 -45
  487. package/skills/skills/lingshu-compiler/units/compiler-4a8cd1f1/SKILL.md +45 -45
  488. package/skills/skills/lingshu-compiler/units/compiler-4b230b6b/SKILL.md +45 -45
  489. package/skills/skills/lingshu-compiler/units/compiler-4cbbda95/SKILL.md +45 -45
  490. package/skills/skills/lingshu-compiler/units/compiler-4d5a68ff/SKILL.md +45 -45
  491. package/skills/skills/lingshu-compiler/units/compiler-56dc9bdd/SKILL.md +45 -45
  492. package/skills/skills/lingshu-compiler/units/compiler-57e76ebe/SKILL.md +45 -45
  493. package/skills/skills/lingshu-compiler/units/compiler-61ff016b/SKILL.md +45 -45
  494. package/skills/skills/lingshu-compiler/units/compiler-63eae588/SKILL.md +45 -45
  495. package/skills/skills/lingshu-compiler/units/compiler-64c4224b/SKILL.md +45 -45
  496. package/skills/skills/lingshu-compiler/units/compiler-66377955/SKILL.md +45 -45
  497. package/skills/skills/lingshu-compiler/units/compiler-674ab4f6/SKILL.md +45 -45
  498. package/skills/skills/lingshu-compiler/units/compiler-6af76fd6/SKILL.md +45 -45
  499. package/skills/skills/lingshu-compiler/units/compiler-6d979db2/SKILL.md +45 -45
  500. package/skills/skills/lingshu-compiler/units/compiler-6de326c0/SKILL.md +45 -45
  501. package/skills/skills/lingshu-compiler/units/compiler-6f1c0eea/SKILL.md +45 -45
  502. package/skills/skills/lingshu-compiler/units/compiler-724d6c9b/SKILL.md +45 -45
  503. package/skills/skills/lingshu-compiler/units/compiler-7690177f/SKILL.md +45 -45
  504. package/skills/skills/lingshu-compiler/units/compiler-7b229a7d/SKILL.md +45 -45
  505. package/skills/skills/lingshu-compiler/units/compiler-7f471b3a/SKILL.md +45 -45
  506. package/skills/skills/lingshu-compiler/units/compiler-815cad08/SKILL.md +45 -45
  507. package/skills/skills/lingshu-compiler/units/compiler-83c61634/SKILL.md +45 -45
  508. package/skills/skills/lingshu-compiler/units/compiler-8c798c81/SKILL.md +45 -45
  509. package/skills/skills/lingshu-compiler/units/compiler-8dd747ac/SKILL.md +45 -45
  510. package/skills/skills/lingshu-compiler/units/compiler-90324d0a/SKILL.md +45 -45
  511. package/skills/skills/lingshu-compiler/units/compiler-94b8d72d/SKILL.md +45 -45
  512. package/skills/skills/lingshu-compiler/units/compiler-94f12231/SKILL.md +45 -45
  513. package/skills/skills/lingshu-compiler/units/compiler-95937c16/SKILL.md +45 -45
  514. package/skills/skills/lingshu-compiler/units/compiler-98a5625b/SKILL.md +45 -45
  515. package/skills/skills/lingshu-compiler/units/compiler-98b4c42f/SKILL.md +45 -45
  516. package/skills/skills/lingshu-compiler/units/compiler-98e3894a/SKILL.md +45 -45
  517. package/skills/skills/lingshu-compiler/units/compiler-9bdfe4b8/SKILL.md +45 -45
  518. package/skills/skills/lingshu-compiler/units/compiler-9d9b4e83/SKILL.md +45 -45
  519. package/skills/skills/lingshu-compiler/units/compiler-9f7be5ad/SKILL.md +45 -45
  520. package/skills/skills/lingshu-compiler/units/compiler-a6daf076/SKILL.md +45 -45
  521. package/skills/skills/lingshu-compiler/units/compiler-a7995a0c/SKILL.md +45 -45
  522. package/skills/skills/lingshu-compiler/units/compiler-a8399248/SKILL.md +45 -45
  523. package/skills/skills/lingshu-compiler/units/compiler-aabbd099/SKILL.md +45 -45
  524. package/skills/skills/lingshu-compiler/units/compiler-afe169d8/SKILL.md +45 -45
  525. package/skills/skills/lingshu-compiler/units/compiler-b0678bda/SKILL.md +45 -45
  526. package/skills/skills/lingshu-compiler/units/compiler-b09bd196/SKILL.md +45 -45
  527. package/skills/skills/lingshu-compiler/units/compiler-b1396e23/SKILL.md +45 -45
  528. package/skills/skills/lingshu-compiler/units/compiler-b9b31ce0/SKILL.md +45 -45
  529. package/skills/skills/lingshu-compiler/units/compiler-c10264a7/SKILL.md +45 -45
  530. package/skills/skills/lingshu-compiler/units/compiler-cb1e8e4b/SKILL.md +45 -45
  531. package/skills/skills/lingshu-compiler/units/compiler-ccafd438/SKILL.md +45 -45
  532. package/skills/skills/lingshu-compiler/units/compiler-cda9c262/SKILL.md +45 -45
  533. package/skills/skills/lingshu-compiler/units/compiler-ce648068/SKILL.md +45 -45
  534. package/skills/skills/lingshu-compiler/units/compiler-cf5776a4/SKILL.md +45 -45
  535. package/skills/skills/lingshu-compiler/units/compiler-d974e5d3/SKILL.md +45 -45
  536. package/skills/skills/lingshu-compiler/units/compiler-e3979fd3/SKILL.md +45 -45
  537. package/skills/skills/lingshu-compiler/units/compiler-eb1cf2b5/SKILL.md +45 -45
  538. package/skills/skills/lingshu-compiler/units/compiler-ecb30d5b/SKILL.md +45 -45
  539. package/skills/skills/lingshu-compiler/units/compiler-f8c8b24b/SKILL.md +45 -45
  540. package/skills/skills/lingshu-compiler/units/compiler-f99fedbe/SKILL.md +45 -45
  541. package/skills/skills/lingshu-compiler/units/compiler-fa8ff5f7/SKILL.md +45 -45
  542. package/skills/skills/lingshu-compiler/units/compiler-fe1b058d/SKILL.md +45 -45
  543. package/skills/skills/lingshu-compiler/units/lex-chinese-program/SKILL.md +45 -45
  544. package/skills/skills/lingshu-compiler/units/lex-dao-de-jing/SKILL.md +45 -45
  545. package/skills/skills/lingshu-compiler/units/lex-nine-chapters/SKILL.md +45 -45
  546. package/skills/skills/lingshu-compiler/units/vm-arithmetic/SKILL.md +45 -45
  547. package/skills/skills/lingshu-compiler/units/vm-array-ops/SKILL.md +45 -45
  548. package/skills/skills/lingshu-compiler/units/vm-closure-call/SKILL.md +45 -45
  549. package/skills/skills/lingshu-compiler/units/vm-closure-create/SKILL.md +45 -45
  550. package/skills/skills/lingshu-compiler/units/vm-compare/SKILL.md +45 -45
  551. package/skills/skills/lingshu-compiler/units/vm-cond-jump/SKILL.md +45 -45
  552. package/skills/skills/lingshu-compiler/units/vm-cond-space/SKILL.md +45 -45
  553. package/skills/skills/lingshu-compiler/units/vm-exception/SKILL.md +45 -45
  554. package/skills/skills/lingshu-compiler/units/vm-func-call/SKILL.md +45 -45
  555. package/skills/skills/lingshu-compiler/units/vm-loop-run/SKILL.md +45 -45
  556. package/skills/skills/lingshu-compiler/units/vm-profiling/SKILL.md +45 -45
  557. package/skills/skills/lingshu-compiler/units/vm-refcount/SKILL.md +45 -45
  558. package/skills/skills/lingshu-compiler/units/vm-run-loop/SKILL.md +45 -45
  559. package/skills/skills/lingshu-compiler/units/vm-short-circuit/SKILL.md +45 -45
  560. package/skills/skills/lingshu-compiler/units/vm-stack-guard/SKILL.md +45 -45
  561. package/skills/skills/lingshu-compiler/units/vm-stack-ops/SKILL.md +45 -45
  562. package/skills/skills/lingshu-compiler/units/vm-trust-accum/SKILL.md +45 -45
  563. package/skills/skills/lingshu-graph/SKILL.md +63 -63
  564. package/skills/skills/lingshu-net/SKILL.md +48 -48
  565. package/skills/skills/lingshu-os/SKILL.md +64 -64
  566. package/skills/skills/lingshu-pylang/SKILL.md +71 -71
  567. package/src/bridge.ts +33 -0
  568. package/src/hooks.ts +38 -2
  569. package/src/index.ts +526 -518
  570. package/src/lib/datapath.ts +326 -326
  571. package/src/lib/mdcg_client.ts +413 -413
  572. package/src/lib/mutual.ts +428 -428
  573. package/src/lib/prompt_safety.ts +62 -62
  574. package/src/lib/python_path.ts +71 -71
  575. package/src/lib/roleplay_web.ts +116 -29
  576. package/src/lib/token_store.ts +13 -3
  577. package/src/tools.ts +212 -212
  578. package/zcode/AGENTS.md +11 -3
  579. package/zcode/README.md +41 -41
  580. /package/docs/{mdcg → hive}//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" +0 -0
package/md_cg/weights.py CHANGED
@@ -1,625 +1,625 @@
1
- # -*- coding: utf-8 -*-
2
- """位置权重矩阵(序标定)——「不同身份,参数偏好不同」。
3
-
4
- 理论出处(本仓原文,非外部知识)
5
- --------------------------------
6
- `docs/theory/智能的公理化基石.md` §4.3:信任合成是
7
- P_trust = f(一致性, 位置可预测性, 版本对齐度)
8
- 其中 `版本对齐度` 已由 `theory` + `links.version_alignment` 提供,
9
- `位置可预测性` 见 `predict`,`一致性` 见 `consistency`。本模块只补一件
10
- 此前缺失的东西:**三个分量在不同位置下的偏好序**。
11
-
12
- 六个位置分为**两类**(由功能身份决定,非人为指定):
13
-
14
- · 认知视角(viewpoint):设计者 / 反思 / 验证
15
- ——「思考的不同视角」,**三分量都涉及**,只标定主导,**不设零**。
16
- · 功能单元(functional):记录 / 输出 / 维生
17
- ——功能需求决定,**身份即排除**:主导 + 明确排除一项(≈0)。
18
-
19
- 排除项可**推导**(派生律:功能身份 → 缺失分量),不是选出来的:
20
-
21
- · 记录单元**不猜** → 不做预测 → 排除 位置可预测性
22
- · 输出单元**不记** → 不复现对账 → 排除 一致性
23
- · 维生系统**不对外** → 无外部协议 → 排除 版本对齐度
24
-
25
- 设计者定位(本轮裁决):
26
- · **不参与日常评估**——它是元视角,思考总体规律;细节由反思/验证承担,
27
- 否则要做全局细节整理,耗时极长。
28
-
29
- 可推导不变量(`invariants()` 逐条自检)
30
- --------------------------------------
31
- 1. **排除唯一**——每个分量恰被 **1** 个位置排除;因视角「3 项都涉及」,
32
- 故每个分量的参与度 = **5/6**(不是 3/6);
33
- 2. **排除项只属功能单元**,且 A/B/C 各被排除一次;
34
- 3. **视角主导 ↔ 功能单元排除**一一配对:
35
- 设计者(A)↔维生、反思(B)↔记录、验证(C)↔输出。
36
-
37
- 诚实边界
38
- --------
39
- · 本模块只声明**序**(谁能压过谁),**不宣称数值**——与 `links.py` 的
40
- `UP_STEP`/`DECAY_DAYS` 同一纪律(文档 §4.3:「v0.1 只声明结构」)。
41
- · `blend()` 里的权重是**占位值**(用序秩当量级),仅供仿真,标定属 v0.3。
42
-
43
- 零第三方依赖。
44
- """
45
- from __future__ import annotations
46
-
47
- import math
48
- import os
49
- import time
50
-
51
- from .fsutil import append_jsonl, read_jsonl
52
-
53
- # --------------------------------------------------------------------------
54
- # 常量
55
- # --------------------------------------------------------------------------
56
-
57
- #: 三个分量(顺序即 A/B/C,稳定,供外部按位引用)
58
- COMPONENTS = ("version_alignment", "predictability", "consistency")
59
-
60
- #: 分量中文名(日志/自描述用)
61
- COMPONENT_LABELS = {
62
- "version_alignment": "版本对齐度",
63
- "predictability": "位置可预测性",
64
- "consistency": "一致性",
65
- }
66
-
67
- #: 位置类别
68
- VIEWPOINT = "viewpoint" # 认知视角:3 项都涉及,只标主导,不设零
69
- FUNCTIONAL = "functional" # 功能单元:主导 + 明确排除一项
70
-
71
- #: 位置 → 权重序规格
72
- #: primary 主导分量(权重最高)
73
- #: secondary 次主导分量(功能单元的第二个偏好;视角为 None=另两项并列)
74
- #: excluded 被排除分量(≈0;仅功能单元有;视角为 None=不设零)
75
- SPEC = {
76
- # ---- 认知视角(不参与日常评估者仅 designer)----
77
- "designer": {"class": VIEWPOINT, "primary": "version_alignment",
78
- "secondary": None, "excluded": None},
79
- "reflect": {"class": VIEWPOINT, "primary": "predictability",
80
- "secondary": None, "excluded": None},
81
- "verify": {"class": VIEWPOINT, "primary": "consistency",
82
- "secondary": None, "excluded": None},
83
- # ---- 功能单元(身份即排除)----
84
- "record": {"class": FUNCTIONAL, "primary": "consistency",
85
- "secondary": "version_alignment", "excluded": "predictability"},
86
- "output": {"class": FUNCTIONAL, "primary": "predictability",
87
- "secondary": "version_alignment", "excluded": "consistency"},
88
- "sustain": {"class": FUNCTIONAL, "primary": "consistency",
89
- "secondary": "predictability", "excluded": "version_alignment"},
90
- }
91
-
92
- POSITION_ORDER = ("designer", "record", "reflect", "verify", "output", "sustain")
93
-
94
- #: 参与**日常评估**的位置(设计者是元参照系,不入日常)
95
- DAILY = ("record", "reflect", "verify", "output", "sustain")
96
-
97
- #: 序秩(占位量级,仅仿真用):主导 2 / 次主导 1 / 排除 0;视角另两项 = 1
98
- RANK_PRIMARY = 2.0
99
- RANK_SECONDARY = 1.0
100
- RANK_EXCLUDED = 0.0
101
-
102
-
103
- class WeightError(Exception):
104
- """未知位置 / 未知分量。"""
105
-
106
-
107
- # --------------------------------------------------------------------------
108
- # 基础查询
109
- # --------------------------------------------------------------------------
110
-
111
- # 生效条件:position 经 str(position or "").strip() 作为 SPEC 的键,命中时返回对应 spec dict,未命中(含 position 为 None/空串/未知)抛 WeightError;
112
- def _spec(position: str) -> dict:
113
- s = SPEC.get(str(position or "").strip())
114
- if s is None:
115
- raise WeightError(f"未知位置:{position!r}(允许:{POSITION_ORDER})")
116
- return s
117
-
118
-
119
- # 生效条件:component 经 str(component or "").strip() 后若结果在 COMPONENTS 中返回该规范分量字符串,否则抛 WeightError;
120
- def _comp(component: str) -> str:
121
- c = str(component or "").strip()
122
- if c not in COMPONENTS:
123
- raise WeightError(f"未知分量:{component!r}(允许:{COMPONENTS})")
124
- return c
125
-
126
-
127
- # 生效条件:position 可被 _spec 解析且其结果 "class" 等于 VIEWPOINT 时返回 True,非 VIEWPOINT 返回 False,未知 position 抛 WeightError;
128
- def is_viewpoint(position: str) -> bool:
129
- """是否认知视角(3 项都涉及,不设零)。"""
130
- return _spec(position)["class"] == VIEWPOINT
131
-
132
-
133
- # 生效条件:position 可被 _spec 解析且其结果 "class" 等于 FUNCTIONAL 时返回 True,非 FUNCTIONAL 返回 False,未知 position 抛 WeightError;
134
- def is_functional(position: str) -> bool:
135
- """是否功能单元(身份即排除)。"""
136
- return _spec(position)["class"] == FUNCTIONAL
137
-
138
-
139
- # 生效条件:position 经 _spec(position) 验证可解析后,返回原始 position 是否在模块级 DAILY 中;带首尾空白等未 strip 的值会因不在 DAILY 返回 False,未知 position 抛 WeightError;
140
- def in_daily_eval(position: str) -> bool:
141
- """是否参与日常评估(设计者=False,元参照系)。"""
142
- _spec(position)
143
- return position in DAILY
144
-
145
-
146
- # 生效条件:position 可被 _spec 解析且其 spec 含 "primary" 键时返回该值,未知 position 抛 WeightError;
147
- def dominant(position: str) -> str:
148
- """主导分量(权重最高者)。"""
149
- return _spec(position)["primary"]
150
-
151
-
152
- # 生效条件:position 可被 _spec 解析且其 spec 含 "secondary" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
153
- def secondary(position: str):
154
- """次主导分量;视角返回 None(另两项并列、均 >0)。"""
155
- return _spec(position)["secondary"]
156
-
157
-
158
- # 生效条件:position 可被 _spec 解析且其 spec 含 "excluded" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
159
- def excluded(position: str):
160
- """被排除分量(≈0);视角返回 None(不设零)。"""
161
- return _spec(position)["excluded"]
162
-
163
-
164
- # --------------------------------------------------------------------------
165
- # 序比较(本模块的权威结论:只有序,没有数值)
166
- # --------------------------------------------------------------------------
167
-
168
- # 生效条件:position 与 component 分别经 _spec 与 _comp 验证后,若 component 等于该位置 spec["excluded"] 返回 RANK_EXCLUDED,否则若等于 spec["primary"] 返回 RANK_PRIMARY,否则返回 RANK_SECONDARY;
169
- def rank(position: str, component: str) -> float:
170
- """分量在该位置的序秩(占位量级):2 主导 / 1 参与 / 0 排除。"""
171
- s = _spec(position)
172
- c = _comp(component)
173
- if s["excluded"] == c:
174
- return RANK_EXCLUDED
175
- if s["primary"] == c:
176
- return RANK_PRIMARY
177
- return RANK_SECONDARY
178
-
179
-
180
- # 生效条件:position、a、b 经 rank 可得序秩,若 rank(position,a)==rank(position,b) 返回 None,否则返回 ra>rb 的 bool;任一参数未知则抛 WeightError;
181
- def prefers(position: str, a: str, b: str):
182
- """该位置是否**严格**偏好 a 胜过 b。
183
-
184
- 返回 True / False / None(None = 二者并列,无严格序)。
185
- """
186
- ra, rb = rank(position, a), rank(position, b)
187
- if ra == rb:
188
- return None
189
- return ra > rb
190
-
191
-
192
- # 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,按 -rank(position,c) 与 COMPONENTS.index(c) 排序,返回 {"preferred":[rank>0], "excluded":[rank==0], "primary":dominant(position), "secondary":secondary(position)}(无 dominant 键);
193
- def order(position: str):
194
- """从高到低排列的分量(并列者按 COMPONENTS 稳定序);排除项单独列出。"""
195
- _spec(position)
196
- ranked = sorted(COMPONENTS, key=lambda c: (-rank(position, c), COMPONENTS.index(c)))
197
- kept = [c for c in ranked if rank(position, c) > 0]
198
- exc = [c for c in ranked if rank(position, c) == 0]
199
- return {"preferred": kept, "excluded": exc,
200
- "primary": dominant(position), "secondary": secondary(position)}
201
-
202
-
203
- # 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,将各分量 rank 归一化到 4 位小数返回;若 total 为 0 则按 total=1.0 计算;
204
- def weights(position: str) -> dict:
205
- """占位数值权重(序秩归一化);**未标定**,仅供仿真。"""
206
- _spec(position)
207
- raw = {c: rank(position, c) for c in COMPONENTS}
208
- total = sum(raw.values()) or 1.0
209
- return {c: round(raw[c] / total, 4) for c in COMPONENTS}
210
-
211
-
212
- # --------------------------------------------------------------------------
213
- # 合成(占位:f(一致性, 位置可预测性, 版本对齐度))
214
- # --------------------------------------------------------------------------
215
-
216
- # 生效条件:position 经 _spec 可解析且 COMPONENTS 可用时,components 对每个分量经 .get(c,0.0) 取值并截到 [0,1];若 components 无 .get 或该值不能 float 则该分量值记 0.0,仍按 weights(position) 加权求和返回含 score/values/weights/dominant 的 dict;
217
- def blend(position: str, components: dict) -> dict:
218
- """按位置的权重合成单一信任标量。
219
-
220
- `components` 形如 {"version_alignment": 1.0, "predictability": 0.8,
221
- "consistency": 0.6};缺省按 0 计。
222
-
223
- **数值未标定**:这里用序秩当量级,只保证「主导分量对结果影响最大」这
224
- 一方向性事实。标定属路线图 v0.3。
225
- """
226
- s = _spec(position)
227
- w = weights(position)
228
- vals = {}
229
- for c in COMPONENTS:
230
- try:
231
- vals[c] = max(0.0, min(1.0, float(components.get(c, 0.0))))
232
- except (AttributeError, TypeError, ValueError):
233
- vals[c] = 0.0
234
- score = sum(w[c] * vals[c] for c in COMPONENTS)
235
- return {"position": position, "class": s["class"],
236
- "weights": w, "values": vals, "score": round(score, 4),
237
- "dominant": s["primary"],
238
- "note": "权重为占位序秩(未标定);仅方向性结论可信"}
239
-
240
-
241
- # --------------------------------------------------------------------------
242
- # 不变量自检(把上轮的三条结构约束落成可执行断言)
243
- # --------------------------------------------------------------------------
244
-
245
- # 生效条件:模块级 POSITION_ORDER、COMPONENTS、SPEC、VIEWPOINT、FUNCTIONAL 等常量齐备时,invariants() 逐条自检并返回 {"ok": all(checks[*].ok), "checks": ...};
246
- def invariants() -> dict:
247
- """逐条自检结构约束,返回 {ok, checks{name: {ok, detail}}}。"""
248
- checks = {}
249
-
250
- # ① 排除唯一:每分量恰被 1 个位置排除 ⇒ 参与度 = 5/6
251
- part = {c: [p for p in POSITION_ORDER if rank(p, c) > 0] for c in COMPONENTS}
252
- exc_of = {c: [p for p in POSITION_ORDER if rank(p, c) == 0] for c in COMPONENTS}
253
- checks["excluded_exactly_once"] = {
254
- "ok": all(len(exc_of[c]) == 1 for c in COMPONENTS)
255
- and all(len(part[c]) == len(POSITION_ORDER) - 1 for c in COMPONENTS),
256
- "detail": {c: {"participants": len(part[c]), "excluded_by": exc_of[c]}
257
- for c in COMPONENTS}}
258
-
259
- # ② 排除项只属功能单元,且每分量各被排除一次
260
- excs = {}
261
- for p in POSITION_ORDER:
262
- e = excluded(p)
263
- if e is None:
264
- continue
265
- excs.setdefault(e, []).append(p)
266
- only_functional = all(is_functional(p)
267
- for vs in excs.values() for p in vs)
268
- both = all(len(excs.get(c) or []) == 1 for c in COMPONENTS)
269
- checks["exclusion_functional_only_once_each"] = {
270
- "ok": bool(excs) and only_functional and both,
271
- "detail": {c: excs.get(c, []) for c in COMPONENTS}}
272
-
273
- # ③ 视角主导 ↔ 功能单元排除 一一配对
274
- dom_pairs = {} # 分量 → 视角
275
- for p in POSITION_ORDER:
276
- if is_viewpoint(p):
277
- dom_pairs.setdefault(dominant(p), []).append(p)
278
- pairing = {}
279
- for p in POSITION_ORDER:
280
- if not is_functional(p):
281
- continue
282
- e = excluded(p)
283
- if e and len(dom_pairs.get(e) or []) == 1:
284
- pairing[dom_pairs[e][0]] = p
285
- checks["viewpoint_dominant_pairs_unit_exclusion"] = {
286
- "ok": len(pairing) == 3,
287
- "detail": pairing}
288
-
289
- # ④ 功能单元恰有一个排除项;视角一个都没有
290
- checks["functional_excludes_exactly_one"] = {
291
- "ok": all(excluded(p) is not None for p in POSITION_ORDER
292
- if is_functional(p))
293
- and all(excluded(p) is None for p in POSITION_ORDER
294
- if is_viewpoint(p)),
295
- "detail": {p: excluded(p) for p in POSITION_ORDER}}
296
-
297
- # ⑤ 排除项序秩严格最低
298
- checks["excluded_is_lowest"] = {
299
- "ok": all(rank(p, excluded(p)) < rank(p, c)
300
- for p in POSITION_ORDER if excluded(p)
301
- for c in COMPONENTS if c != excluded(p)),
302
- "detail": "排除分量序秩 0,严格低于其余分量"}
303
-
304
- return {"ok": all(c["ok"] for c in checks.values()), "checks": checks}
305
-
306
-
307
- # --------------------------------------------------------------------------
308
- # 自描述
309
- # --------------------------------------------------------------------------
310
-
311
- # 生效条件:模块级 COMPONENTS、COMPONENT_LABELS、VIEWPOINT、FUNCTIONAL、SPEC、POSITION_ORDER、DAILY 齐备时,返回位置权重矩阵自描述 dict,其中 components 按 COMPONENT_LABELS、positions 按 SPEC、daily_eval 按 DAILY 展开;
312
- def catalog() -> dict:
313
- """位置权重矩阵自描述(供 MCP / 文档对照验证)。"""
314
- return {
315
- "question": "不同身份,参数偏好不同",
316
- "components": {c: COMPONENT_LABELS[c] for c in COMPONENTS},
317
- "classes": {
318
- VIEWPOINT: "认知视角:3 项都涉及,只标主导,不设零",
319
- FUNCTIONAL: "功能单元:身份即排除(不猜/不记/不对外)",
320
- },
321
- "positions": {p: dict(SPEC[p]) for p in POSITION_ORDER},
322
- "daily_eval": list(DAILY),
323
- "meta_reference": [p for p in POSITION_ORDER if p not in DAILY],
324
- "derivation": {"record": "不猜 → 排除 位置可预测性",
325
- "output": "不记 → 排除 一致性",
326
- "sustain": "不对外 → 排除 版本对齐度"},
327
- "formula": "P_trust = f(一致性, 位置可预测性, 版本对齐度)",
328
- "honest_boundary": "只声明序,不宣称数值;blend() 权重为占位序秩",
329
- }
330
-
331
-
332
- # ==========================================================================
333
- # 结构重要性重算(maintain.importance)
334
- # ==========================================================================
335
- #
336
- # 与上面的「位置权重矩阵」是**两件事**,不要混:
337
- # · 上面回答「不同身份偏好哪些信任分量」(序标定,作用于位置);
338
- # · 下面回答「一个节点在认知图结构里该有多大重要性」(重算,作用于节点)。
339
- #
340
- # 三个**可测**分量(对齐计划:按覆盖度、冗余度、验证基底重排):
341
- # coverage 覆盖度 —— 有多少节点指向/包含它(入度,结构中枢性)
342
- # redundancy 冗余度 —— 与同层节点内容哈希撞车的比例(越冗余越该降权)
343
- # basis 验证基底 —— 外部验证档位(formal_proof/compiler > test > measurement > data > other)
344
- #
345
- # 纪律:只改 `frontmatter.importance` 与索引快照,**不动正文**(减小 diff 与重写成本);
346
- # 全流程可预演(apply=False)、可留痕(`_maintain.jsonl`)、可回滚(rollback)。
347
- # 性能:dry-run 不读任何节点文件(只用索引快照);apply 只写「变动超阈值」的节点。
348
-
349
- MAINTAIN_LOG = "_maintain.jsonl"
350
-
351
- #: 验证基底 → 可信权重(枚举来自 nodefile.VERIFICATION_BASIS)
352
- #: 文科来源一致性档(textbook/public_kb)低于可复现档、高于 other:
353
- #: 教材/公开知识库是权威二手来源,但不是可复算证据。
354
- BASIS_TRUST = {
355
- "formal_proof": 1.00,
356
- "compiler": 0.90,
357
- "test": 0.80,
358
- "measurement": 0.65,
359
- "textbook": 0.60,
360
- "data": 0.45,
361
- "public_kb": 0.40,
362
- "other": 0.25,
363
- }
364
- BASIS_TRUST_MISSING = 0.25
365
-
366
- #: 三分量合成权重(占位量级,沿用「只声明序」纪律;分量序主导→次要)
367
- IMPORTANCE_MIX = {"basis": 0.40, "coverage": 0.35, "redundancy": 0.25}
368
- COV_SAT = 12.0 # 入度饱和点:约 12 条入边即视为覆盖满
369
- IMPORTANCE_FLOOR = 0.10
370
- IMPORTANCE_CEIL = 1.00
371
- IMPORTANCE_PROTECT = 0.70 # ≥ 此值:保护下限(已保护/高危节点不被降破)
372
- APPLY_DELTA = 0.05 # 变动小于此值不写盘(防 IO 放大)
373
-
374
-
375
- # 生效条件:e 为可 .get 的映射时,遍历 e.get("edges")(假值视为空)逐项按 dict 的 to/target/node/id 或标量转 str 追加非假值,再取 e.get("subgraph"),若为 dict 取其 "nodes" 否则取 subgraph 本身,且当其为 list/tuple 时追加其中 dict 的 id 或标量转 str 的非假值,返回 out;
376
- def _targets(e: dict):
377
- """索引快照里的「出边目标」:edges ∪ subgraph.nodes(兼容 dict/str)。"""
378
- out = []
379
- for x in (e.get("edges") or []):
380
- if isinstance(x, dict):
381
- t = x.get("to") or x.get("target") or x.get("node") or x.get("id")
382
- else:
383
- t = x
384
- if t:
385
- out.append(str(t))
386
- sg = e.get("subgraph")
387
- raw = sg.get("nodes") if isinstance(sg, dict) else sg
388
- if isinstance(raw, (list, tuple)):
389
- for n in raw:
390
- nid = n.get("id") if isinstance(n, dict) else n
391
- if nid:
392
- out.append(str(nid))
393
- return out
394
-
395
-
396
- # 生效条件:basis 为 None 时返回 BASIS_TRUST_MISSING;否则把 str(basis).strip().lower() 作为 BASIS_TRUST 的键,命中返回对应权重,未命中(含空串)返回 BASIS_TRUST_MISSING;
397
- def basis_trust(basis):
398
- """验证基底 → 可信权重;缺失/未知一律给最低档(不假装可信)。"""
399
- if basis is None:
400
- return BASIS_TRUST_MISSING
401
- return BASIS_TRUST.get(str(basis).strip().lower(), BASIS_TRUST_MISSING)
402
-
403
-
404
- # 生效条件:cg 的 index(getattr(cg,"index",None) or {})与其 "nodes" 同为真值时,返回以这些节点 id 为键的入度表,仅当 _targets(e) 给出的目标 t 也在 nodes 且 t != nid 时计数 +1;index 或 "nodes" 为假值(None/{})时 nodes 回落 {},直接返回空 dict。
405
- def coverage_index(cg) -> dict:
406
- """入度表:nid → 被多少节点指向(覆盖度,O(N) 免读文件)。"""
407
- nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
408
- indeg = {nid: 0 for nid in nodes}
409
- for nid, e in nodes.items():
410
- for t in _targets(e):
411
- if t in indeg and t != nid:
412
- indeg[t] += 1
413
- return indeg
414
-
415
-
416
- # 生效条件:cg.index 的 "nodes" 为 dict 时,layer 真值仅处理 e.get("layer")==layer 的节点,layer 假值不过滤;content_hash 为假值(None/空串/0 等)的节点输出 0.0,同 (e.get("layer"), content_hash) 第二次撞车时当前与首次节点均输出 1.0,否则输出 0.0;
417
- def redundancy_map(cg, layer=None) -> dict:
418
- """同层内容哈希撞车 → 冗余度 1.0,否则 0.0(精确冗余,O(N) 免读文件)。
419
-
420
- 诚实边界:这是**精确冗余**(同一层出现完全相同的正文),不是语义近似冗余。
421
- 语义近似由 `forgetting.redundancy`(bigram 覆盖)在写入侧单独负责。
422
- """
423
- nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
424
- seen, out = {}, {}
425
- for nid, e in nodes.items():
426
- if layer and e.get("layer") != layer:
427
- continue
428
- h = e.get("content_hash") or ""
429
- if not h:
430
- out[nid] = 0.0
431
- continue
432
- key = (e.get("layer"), h)
433
- if key in seen:
434
- out[nid] = 1.0
435
- out[seen[key]] = 1.0
436
- else:
437
- seen[key] = nid
438
- out.setdefault(nid, 0.0)
439
- return out
440
-
441
-
442
- # 生效条件:cg.index 的 nodes 为 dict 且 entry 非 None 或 nodes.get(nid) 命中时,e 按 entry 优先否则 nodes.get(nid);indeg/red 分别仅在为 None 时回落 coverage_index(cg)/redundancy_map(cg, layer=e.get("layer"))(空容器不回落);按 IMPORTANCE_MIX、COV_SAT 及 e.get("verification_basis") 的 basis_trust 计算 coverage/redundancy/basis 分量,按 bool(e.get("protected")) 选择 IMPORTANCE_PROTECT 或 IMPORTANCE_FLOOR 作下限、IMPORTANCE_CEIL 作上限,返回含 before(e.get("importance",0.5) or 0.5)、after、components、protected 的 dict;entry 与 nodes.get(nid) 均为 None 返回 None;
443
- def node_importance(cg, nid, indeg=None, red=None, entry=None):
444
- """单节点结构重要性分解(可审计:给出分量而非只给分)。"""
445
- nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
446
- e = entry if entry is not None else nodes.get(nid)
447
- if e is None:
448
- return None
449
- indeg = indeg if indeg is not None else coverage_index(cg)
450
- red = red if red is not None else redundancy_map(cg, layer=e.get("layer"))
451
- d = int(indeg.get(nid, 0) or 0)
452
- cov = min(1.0, math.log1p(d) / math.log1p(COV_SAT))
453
- rr = max(0.0, min(1.0, float(red.get(nid, 0.0) or 0.0)))
454
- bt = basis_trust(e.get("verification_basis"))
455
- score = (IMPORTANCE_MIX["basis"] * bt
456
- + IMPORTANCE_MIX["coverage"] * cov
457
- + IMPORTANCE_MIX["redundancy"] * (1.0 - rr))
458
- protected = bool(e.get("protected"))
459
- floor = IMPORTANCE_PROTECT if protected else IMPORTANCE_FLOOR
460
- score = max(floor, min(IMPORTANCE_CEIL, score))
461
- return {"node_id": nid,
462
- "before": float(e.get("importance", 0.5) or 0.5),
463
- "after": round(score, 4),
464
- "components": {"coverage": round(cov, 4), "redundancy": round(rr, 4),
465
- "basis_trust": round(bt, 4), "in_degree": d,
466
- "verification_basis": e.get("verification_basis")},
467
- "protected": protected,
468
- "protected_floor": protected}
469
-
470
-
471
- # 生效条件:给定 cg 且 nodes = cg.index["nodes"] 时按 layer 过滤、limit 为真值才 ids = ids[:int(limit)] 逐节点重算,abs(after-before) < float(min_delta) 记 unchanged;仅 apply=True 才把 frontmatter.importance/importance_source/importance_components 写回(after >= IMPORTANCE_PROTECT 且未 protected 时补写 protected/protection_reason),并向 cg.root 下 append_jsonl(..., MAINTAIN_LOG) 记 batch 后 rebuild_index。
472
- def recalc(cg, layer=None, limit=None, apply=False, min_delta=APPLY_DELTA,
473
- actor="maintain", dry_run_samples=10):
474
- """结构重要性重算:覆盖度 + 冗余度 + 验证基底 → 重排节点重要性。
475
-
476
- apply=False(默认)只出报表,不写盘(对应计划「可预演」)。
477
- apply=True 逐节点改写 `frontmatter.importance`,每批写一条 `_maintain.jsonl`
478
- (before/after/分量/actor),并提供 rollback 反向应用。
479
- """
480
- nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
481
- indeg = coverage_index(cg)
482
- red = redundancy_map(cg, layer=layer)
483
- ids = [nid for nid, e in nodes.items()
484
- if not layer or e.get("layer") == layer]
485
- ids.sort()
486
- if limit:
487
- ids = ids[:int(limit)]
488
- t0 = time.time()
489
- planned, changed, unchanged, skipped = [], 0, 0, 0
490
- before_sum = after_sum = 0.0
491
- by_layer = {}
492
- batch = time.strftime("%Y%m%d-%H%M%S")
493
- samples = []
494
- for nid in ids:
495
- info = node_importance(cg, nid, indeg=indeg, red=red)
496
- if info is None:
497
- skipped += 1
498
- continue
499
- before, after = info["before"], info["after"]
500
- before_sum += before
501
- after_sum += after
502
- lay = (nodes.get(nid) or {}).get("layer") or "?"
503
- bl = by_layer.setdefault(lay, {"nodes": 0, "changed": 0,
504
- "avg_before": 0.0, "avg_after": 0.0})
505
- bl["nodes"] += 1
506
- if abs(after - before) < float(min_delta):
507
- unchanged += 1
508
- continue
509
- changed += 1
510
- bl["changed"] += 1
511
- plan = dict(info)
512
- plan["batch"] = batch
513
- plan["delta"] = round(after - before, 4)
514
- planned.append(plan)
515
- if len(samples) < int(dry_run_samples):
516
- samples.append(plan)
517
- for lay, bl in list(by_layer.items()):
518
- bl["avg_before"] = 0.0
519
- bl["avg_after"] = 0.0
520
- written = 0
521
- if apply:
522
- for plan in planned:
523
- nid = plan["node_id"]
524
- node = cg.get(nid)
525
- if not node:
526
- continue
527
- fm = node.get("frontmatter") or {}
528
- fm["importance"] = plan["after"]
529
- fm["importance_source"] = "recalc"
530
- fm["importance_components"] = plan["components"]
531
- if plan["after"] >= IMPORTANCE_PROTECT and not fm.get("protected"):
532
- fm["protected"] = True
533
- fm["protection_reason"] = (f"recalc importance={plan['after']:.2f}"
534
- f"≥{IMPORTANCE_PROTECT}")
535
- path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
536
- or node.get("path") or f"{nid}.md")
537
- cg._write_node(nid, path, fm, node.get("content") or "")
538
- e = nodes.get(nid)
539
- if e is not None:
540
- e["importance"] = plan["after"]
541
- if fm.get("protected"):
542
- e["protected"] = True
543
- e["protection_reason"] = fm["protection_reason"]
544
- rec = {"t": time.time(), "action": "importance", "batch": batch,
545
- "id": nid, "layer": (e or {}).get("layer"),
546
- "before": plan["before"], "after": plan["after"],
547
- "delta": plan["delta"], "components": plan["components"],
548
- "actor": actor}
549
- append_jsonl(os.path.join(cg.root, MAINTAIN_LOG), rec)
550
- written += 1
551
- if written and hasattr(cg, "rebuild_index"):
552
- cg.rebuild_index() # 索引与盘面重新对齐,防内存/磁盘分叉
553
- n = max(1, len(ids))
554
- return {
555
- "ok": True, "action": "importance", "dry_run": not apply,
556
- "batch": batch, "nodes_scanned": len(ids), "changed": changed,
557
- "unchanged": unchanged, "skipped": skipped, "written": written,
558
- "min_delta": float(min_delta),
559
- "avg_before": round(before_sum / n, 4),
560
- "avg_after": round(after_sum / n, 4),
561
- "by_layer": {k: {"nodes": v["nodes"], "changed": v["changed"]}
562
- for k, v in by_layer.items()},
563
- "samples": samples, "elapsed_ms": int((time.time() - t0) * 1000),
564
- "log": MAINTAIN_LOG,
565
- "note": ("dry-run:未写盘;apply=True 才改写 importance"
566
- if not apply else
567
- f"已改写 {written} 个节点;回滚见 rollback(batch={batch})"),
568
- }
569
-
570
-
571
- # 生效条件:cg.root/MAINTAIN_LOG 可读出 action=="importance" 记录后,entry_ids 为真值时按记录 id 是否在 {str(x) for x in entry_ids} 过滤;否则 batch 为真值时按 r.get("batch")==batch 过滤;否则取最后一条记录的 batch 再按其过滤;无 importance 记录返回 {"ok":False,"error":"no_records","reverted":0},过滤后无记录返回 {"ok":False,"error":"batch_not_found",...};对命中且 cg.get(nid) 为真的记录写回 rec.get("before") 并计数,若 reverted 且 cg 有 rebuild_index 则调用,最后 append_jsonl 写 actor 并返回 {"ok":True,"batch":batch,"reverted":reverted,"ids":ids};
572
- def rollback(cg, batch=None, entry_ids=None, actor="maintain"):
573
- """把重要性重算反向应用(bulk 改写的可回滚兑现)。
574
-
575
- batch 为空则回滚**最近一批**。返回 {ok, reverted, batch, ids}。
576
- """
577
- log_path = os.path.join(cg.root, MAINTAIN_LOG)
578
- records = [r for r in read_jsonl(log_path)
579
- if r.get("action") == "importance"]
580
- if not records:
581
- return {"ok": False, "error": "no_records", "reverted": 0}
582
- if entry_ids:
583
- want = {str(x) for x in entry_ids}
584
- records = [r for r in records if str(r.get("id")) in want]
585
- elif batch:
586
- records = [r for r in records if r.get("batch") == batch]
587
- else:
588
- batch = records[-1].get("batch")
589
- records = [r for r in records if r.get("batch") == batch]
590
- if not records:
591
- return {"ok": False, "error": "batch_not_found", "batch": batch,
592
- "reverted": 0}
593
- nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
594
- reverted, ids = 0, []
595
- # 同一节点多条记录时以最早一条的 before 为准
596
- for rec in records:
597
- nid = rec.get("id")
598
- node = cg.get(nid)
599
- if not node:
600
- continue
601
- fm = node.get("frontmatter") or {}
602
- fm["importance"] = rec.get("before")
603
- fm["importance_source"] = "recalc_rollback"
604
- path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
605
- or node.get("path") or f"{nid}.md")
606
- cg._write_node(nid, path, fm, node.get("content") or "")
607
- e = nodes.get(nid)
608
- if e is not None:
609
- e["importance"] = rec.get("before")
610
- reverted += 1
611
- ids.append(nid)
612
- if reverted and hasattr(cg, "rebuild_index"):
613
- cg.rebuild_index()
614
- append_jsonl(log_path, {"t": time.time(), "action": "importance_rollback",
615
- "batch": batch, "reverted": reverted, "actor": actor})
616
- return {"ok": True, "batch": batch, "reverted": reverted, "ids": ids}
617
-
618
-
619
- # 生效条件:cg.root/MAINTAIN_LOG 可读出 JSONL 记录后,action 为真值时按 r.get("action")==action 过滤,假值不过滤;返回 recs[-int(limit):],其中 limit=0 时 int(0)=0 使切片为 recs[0:] 返回全部而非空;
620
- def history(cg, limit=100, action=None):
621
- """维护留痕(最近 limit 条),可按 action 过滤。"""
622
- recs = list(read_jsonl(os.path.join(cg.root, MAINTAIN_LOG)))
623
- if action:
624
- recs = [r for r in recs if r.get("action") == action]
1
+ # -*- coding: utf-8 -*-
2
+ """位置权重矩阵(序标定)——「不同身份,参数偏好不同」。
3
+
4
+ 理论出处(本仓原文,非外部知识)
5
+ --------------------------------
6
+ `docs/theory/智能的公理化基石.md` §4.3:信任合成是
7
+ P_trust = f(一致性, 位置可预测性, 版本对齐度)
8
+ 其中 `版本对齐度` 已由 `theory` + `links.version_alignment` 提供,
9
+ `位置可预测性` 见 `predict`,`一致性` 见 `consistency`。本模块只补一件
10
+ 此前缺失的东西:**三个分量在不同位置下的偏好序**。
11
+
12
+ 六个位置分为**两类**(由功能身份决定,非人为指定):
13
+
14
+ · 认知视角(viewpoint):设计者 / 反思 / 验证
15
+ ——「思考的不同视角」,**三分量都涉及**,只标定主导,**不设零**。
16
+ · 功能单元(functional):记录 / 输出 / 维生
17
+ ——功能需求决定,**身份即排除**:主导 + 明确排除一项(≈0)。
18
+
19
+ 排除项可**推导**(派生律:功能身份 → 缺失分量),不是选出来的:
20
+
21
+ · 记录单元**不猜** → 不做预测 → 排除 位置可预测性
22
+ · 输出单元**不记** → 不复现对账 → 排除 一致性
23
+ · 维生系统**不对外** → 无外部协议 → 排除 版本对齐度
24
+
25
+ 设计者定位(本轮裁决):
26
+ · **不参与日常评估**——它是元视角,思考总体规律;细节由反思/验证承担,
27
+ 否则要做全局细节整理,耗时极长。
28
+
29
+ 可推导不变量(`invariants()` 逐条自检)
30
+ --------------------------------------
31
+ 1. **排除唯一**——每个分量恰被 **1** 个位置排除;因视角「3 项都涉及」,
32
+ 故每个分量的参与度 = **5/6**(不是 3/6);
33
+ 2. **排除项只属功能单元**,且 A/B/C 各被排除一次;
34
+ 3. **视角主导 ↔ 功能单元排除**一一配对:
35
+ 设计者(A)↔维生、反思(B)↔记录、验证(C)↔输出。
36
+
37
+ 诚实边界
38
+ --------
39
+ · 本模块只声明**序**(谁能压过谁),**不宣称数值**——与 `links.py` 的
40
+ `UP_STEP`/`DECAY_DAYS` 同一纪律(文档 §4.3:「v0.1 只声明结构」)。
41
+ · `blend()` 里的权重是**占位值**(用序秩当量级),仅供仿真,标定属 v0.3。
42
+
43
+ 零第三方依赖。
44
+ """
45
+ from __future__ import annotations
46
+
47
+ import math
48
+ import os
49
+ import time
50
+
51
+ from .fsutil import append_jsonl, read_jsonl
52
+
53
+ # --------------------------------------------------------------------------
54
+ # 常量
55
+ # --------------------------------------------------------------------------
56
+
57
+ #: 三个分量(顺序即 A/B/C,稳定,供外部按位引用)
58
+ COMPONENTS = ("version_alignment", "predictability", "consistency")
59
+
60
+ #: 分量中文名(日志/自描述用)
61
+ COMPONENT_LABELS = {
62
+ "version_alignment": "版本对齐度",
63
+ "predictability": "位置可预测性",
64
+ "consistency": "一致性",
65
+ }
66
+
67
+ #: 位置类别
68
+ VIEWPOINT = "viewpoint" # 认知视角:3 项都涉及,只标主导,不设零
69
+ FUNCTIONAL = "functional" # 功能单元:主导 + 明确排除一项
70
+
71
+ #: 位置 → 权重序规格
72
+ #: primary 主导分量(权重最高)
73
+ #: secondary 次主导分量(功能单元的第二个偏好;视角为 None=另两项并列)
74
+ #: excluded 被排除分量(≈0;仅功能单元有;视角为 None=不设零)
75
+ SPEC = {
76
+ # ---- 认知视角(不参与日常评估者仅 designer)----
77
+ "designer": {"class": VIEWPOINT, "primary": "version_alignment",
78
+ "secondary": None, "excluded": None},
79
+ "reflect": {"class": VIEWPOINT, "primary": "predictability",
80
+ "secondary": None, "excluded": None},
81
+ "verify": {"class": VIEWPOINT, "primary": "consistency",
82
+ "secondary": None, "excluded": None},
83
+ # ---- 功能单元(身份即排除)----
84
+ "record": {"class": FUNCTIONAL, "primary": "consistency",
85
+ "secondary": "version_alignment", "excluded": "predictability"},
86
+ "output": {"class": FUNCTIONAL, "primary": "predictability",
87
+ "secondary": "version_alignment", "excluded": "consistency"},
88
+ "sustain": {"class": FUNCTIONAL, "primary": "consistency",
89
+ "secondary": "predictability", "excluded": "version_alignment"},
90
+ }
91
+
92
+ POSITION_ORDER = ("designer", "record", "reflect", "verify", "output", "sustain")
93
+
94
+ #: 参与**日常评估**的位置(设计者是元参照系,不入日常)
95
+ DAILY = ("record", "reflect", "verify", "output", "sustain")
96
+
97
+ #: 序秩(占位量级,仅仿真用):主导 2 / 次主导 1 / 排除 0;视角另两项 = 1
98
+ RANK_PRIMARY = 2.0
99
+ RANK_SECONDARY = 1.0
100
+ RANK_EXCLUDED = 0.0
101
+
102
+
103
+ class WeightError(Exception):
104
+ """未知位置 / 未知分量。"""
105
+
106
+
107
+ # --------------------------------------------------------------------------
108
+ # 基础查询
109
+ # --------------------------------------------------------------------------
110
+
111
+ # 生效条件:position 经 str(position or "").strip() 作为 SPEC 的键,命中时返回对应 spec dict,未命中(含 position 为 None/空串/未知)抛 WeightError;
112
+ def _spec(position: str) -> dict:
113
+ s = SPEC.get(str(position or "").strip())
114
+ if s is None:
115
+ raise WeightError(f"未知位置:{position!r}(允许:{POSITION_ORDER})")
116
+ return s
117
+
118
+
119
+ # 生效条件:component 经 str(component or "").strip() 后若结果在 COMPONENTS 中返回该规范分量字符串,否则抛 WeightError;
120
+ def _comp(component: str) -> str:
121
+ c = str(component or "").strip()
122
+ if c not in COMPONENTS:
123
+ raise WeightError(f"未知分量:{component!r}(允许:{COMPONENTS})")
124
+ return c
125
+
126
+
127
+ # 生效条件:position 可被 _spec 解析且其结果 "class" 等于 VIEWPOINT 时返回 True,非 VIEWPOINT 返回 False,未知 position 抛 WeightError;
128
+ def is_viewpoint(position: str) -> bool:
129
+ """是否认知视角(3 项都涉及,不设零)。"""
130
+ return _spec(position)["class"] == VIEWPOINT
131
+
132
+
133
+ # 生效条件:position 可被 _spec 解析且其结果 "class" 等于 FUNCTIONAL 时返回 True,非 FUNCTIONAL 返回 False,未知 position 抛 WeightError;
134
+ def is_functional(position: str) -> bool:
135
+ """是否功能单元(身份即排除)。"""
136
+ return _spec(position)["class"] == FUNCTIONAL
137
+
138
+
139
+ # 生效条件:position 经 _spec(position) 验证可解析后,返回原始 position 是否在模块级 DAILY 中;带首尾空白等未 strip 的值会因不在 DAILY 返回 False,未知 position 抛 WeightError;
140
+ def in_daily_eval(position: str) -> bool:
141
+ """是否参与日常评估(设计者=False,元参照系)。"""
142
+ _spec(position)
143
+ return position in DAILY
144
+
145
+
146
+ # 生效条件:position 可被 _spec 解析且其 spec 含 "primary" 键时返回该值,未知 position 抛 WeightError;
147
+ def dominant(position: str) -> str:
148
+ """主导分量(权重最高者)。"""
149
+ return _spec(position)["primary"]
150
+
151
+
152
+ # 生效条件:position 可被 _spec 解析且其 spec 含 "secondary" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
153
+ def secondary(position: str):
154
+ """次主导分量;视角返回 None(另两项并列、均 >0)。"""
155
+ return _spec(position)["secondary"]
156
+
157
+
158
+ # 生效条件:position 可被 _spec 解析且其 spec 含 "excluded" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
159
+ def excluded(position: str):
160
+ """被排除分量(≈0);视角返回 None(不设零)。"""
161
+ return _spec(position)["excluded"]
162
+
163
+
164
+ # --------------------------------------------------------------------------
165
+ # 序比较(本模块的权威结论:只有序,没有数值)
166
+ # --------------------------------------------------------------------------
167
+
168
+ # 生效条件:position 与 component 分别经 _spec 与 _comp 验证后,若 component 等于该位置 spec["excluded"] 返回 RANK_EXCLUDED,否则若等于 spec["primary"] 返回 RANK_PRIMARY,否则返回 RANK_SECONDARY;
169
+ def rank(position: str, component: str) -> float:
170
+ """分量在该位置的序秩(占位量级):2 主导 / 1 参与 / 0 排除。"""
171
+ s = _spec(position)
172
+ c = _comp(component)
173
+ if s["excluded"] == c:
174
+ return RANK_EXCLUDED
175
+ if s["primary"] == c:
176
+ return RANK_PRIMARY
177
+ return RANK_SECONDARY
178
+
179
+
180
+ # 生效条件:position、a、b 经 rank 可得序秩,若 rank(position,a)==rank(position,b) 返回 None,否则返回 ra>rb 的 bool;任一参数未知则抛 WeightError;
181
+ def prefers(position: str, a: str, b: str):
182
+ """该位置是否**严格**偏好 a 胜过 b。
183
+
184
+ 返回 True / False / None(None = 二者并列,无严格序)。
185
+ """
186
+ ra, rb = rank(position, a), rank(position, b)
187
+ if ra == rb:
188
+ return None
189
+ return ra > rb
190
+
191
+
192
+ # 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,按 -rank(position,c) 与 COMPONENTS.index(c) 排序,返回 {"preferred":[rank>0], "excluded":[rank==0], "primary":dominant(position), "secondary":secondary(position)}(无 dominant 键);
193
+ def order(position: str):
194
+ """从高到低排列的分量(并列者按 COMPONENTS 稳定序);排除项单独列出。"""
195
+ _spec(position)
196
+ ranked = sorted(COMPONENTS, key=lambda c: (-rank(position, c), COMPONENTS.index(c)))
197
+ kept = [c for c in ranked if rank(position, c) > 0]
198
+ exc = [c for c in ranked if rank(position, c) == 0]
199
+ return {"preferred": kept, "excluded": exc,
200
+ "primary": dominant(position), "secondary": secondary(position)}
201
+
202
+
203
+ # 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,将各分量 rank 归一化到 4 位小数返回;若 total 为 0 则按 total=1.0 计算;
204
+ def weights(position: str) -> dict:
205
+ """占位数值权重(序秩归一化);**未标定**,仅供仿真。"""
206
+ _spec(position)
207
+ raw = {c: rank(position, c) for c in COMPONENTS}
208
+ total = sum(raw.values()) or 1.0
209
+ return {c: round(raw[c] / total, 4) for c in COMPONENTS}
210
+
211
+
212
+ # --------------------------------------------------------------------------
213
+ # 合成(占位:f(一致性, 位置可预测性, 版本对齐度))
214
+ # --------------------------------------------------------------------------
215
+
216
+ # 生效条件:position 经 _spec 可解析且 COMPONENTS 可用时,components 对每个分量经 .get(c,0.0) 取值并截到 [0,1];若 components 无 .get 或该值不能 float 则该分量值记 0.0,仍按 weights(position) 加权求和返回含 score/values/weights/dominant 的 dict;
217
+ def blend(position: str, components: dict) -> dict:
218
+ """按位置的权重合成单一信任标量。
219
+
220
+ `components` 形如 {"version_alignment": 1.0, "predictability": 0.8,
221
+ "consistency": 0.6};缺省按 0 计。
222
+
223
+ **数值未标定**:这里用序秩当量级,只保证「主导分量对结果影响最大」这
224
+ 一方向性事实。标定属路线图 v0.3。
225
+ """
226
+ s = _spec(position)
227
+ w = weights(position)
228
+ vals = {}
229
+ for c in COMPONENTS:
230
+ try:
231
+ vals[c] = max(0.0, min(1.0, float(components.get(c, 0.0))))
232
+ except (AttributeError, TypeError, ValueError):
233
+ vals[c] = 0.0
234
+ score = sum(w[c] * vals[c] for c in COMPONENTS)
235
+ return {"position": position, "class": s["class"],
236
+ "weights": w, "values": vals, "score": round(score, 4),
237
+ "dominant": s["primary"],
238
+ "note": "权重为占位序秩(未标定);仅方向性结论可信"}
239
+
240
+
241
+ # --------------------------------------------------------------------------
242
+ # 不变量自检(把上轮的三条结构约束落成可执行断言)
243
+ # --------------------------------------------------------------------------
244
+
245
+ # 生效条件:模块级 POSITION_ORDER、COMPONENTS、SPEC、VIEWPOINT、FUNCTIONAL 等常量齐备时,invariants() 逐条自检并返回 {"ok": all(checks[*].ok), "checks": ...};
246
+ def invariants() -> dict:
247
+ """逐条自检结构约束,返回 {ok, checks{name: {ok, detail}}}。"""
248
+ checks = {}
249
+
250
+ # ① 排除唯一:每分量恰被 1 个位置排除 ⇒ 参与度 = 5/6
251
+ part = {c: [p for p in POSITION_ORDER if rank(p, c) > 0] for c in COMPONENTS}
252
+ exc_of = {c: [p for p in POSITION_ORDER if rank(p, c) == 0] for c in COMPONENTS}
253
+ checks["excluded_exactly_once"] = {
254
+ "ok": all(len(exc_of[c]) == 1 for c in COMPONENTS)
255
+ and all(len(part[c]) == len(POSITION_ORDER) - 1 for c in COMPONENTS),
256
+ "detail": {c: {"participants": len(part[c]), "excluded_by": exc_of[c]}
257
+ for c in COMPONENTS}}
258
+
259
+ # ② 排除项只属功能单元,且每分量各被排除一次
260
+ excs = {}
261
+ for p in POSITION_ORDER:
262
+ e = excluded(p)
263
+ if e is None:
264
+ continue
265
+ excs.setdefault(e, []).append(p)
266
+ only_functional = all(is_functional(p)
267
+ for vs in excs.values() for p in vs)
268
+ both = all(len(excs.get(c) or []) == 1 for c in COMPONENTS)
269
+ checks["exclusion_functional_only_once_each"] = {
270
+ "ok": bool(excs) and only_functional and both,
271
+ "detail": {c: excs.get(c, []) for c in COMPONENTS}}
272
+
273
+ # ③ 视角主导 ↔ 功能单元排除 一一配对
274
+ dom_pairs = {} # 分量 → 视角
275
+ for p in POSITION_ORDER:
276
+ if is_viewpoint(p):
277
+ dom_pairs.setdefault(dominant(p), []).append(p)
278
+ pairing = {}
279
+ for p in POSITION_ORDER:
280
+ if not is_functional(p):
281
+ continue
282
+ e = excluded(p)
283
+ if e and len(dom_pairs.get(e) or []) == 1:
284
+ pairing[dom_pairs[e][0]] = p
285
+ checks["viewpoint_dominant_pairs_unit_exclusion"] = {
286
+ "ok": len(pairing) == 3,
287
+ "detail": pairing}
288
+
289
+ # ④ 功能单元恰有一个排除项;视角一个都没有
290
+ checks["functional_excludes_exactly_one"] = {
291
+ "ok": all(excluded(p) is not None for p in POSITION_ORDER
292
+ if is_functional(p))
293
+ and all(excluded(p) is None for p in POSITION_ORDER
294
+ if is_viewpoint(p)),
295
+ "detail": {p: excluded(p) for p in POSITION_ORDER}}
296
+
297
+ # ⑤ 排除项序秩严格最低
298
+ checks["excluded_is_lowest"] = {
299
+ "ok": all(rank(p, excluded(p)) < rank(p, c)
300
+ for p in POSITION_ORDER if excluded(p)
301
+ for c in COMPONENTS if c != excluded(p)),
302
+ "detail": "排除分量序秩 0,严格低于其余分量"}
303
+
304
+ return {"ok": all(c["ok"] for c in checks.values()), "checks": checks}
305
+
306
+
307
+ # --------------------------------------------------------------------------
308
+ # 自描述
309
+ # --------------------------------------------------------------------------
310
+
311
+ # 生效条件:模块级 COMPONENTS、COMPONENT_LABELS、VIEWPOINT、FUNCTIONAL、SPEC、POSITION_ORDER、DAILY 齐备时,返回位置权重矩阵自描述 dict,其中 components 按 COMPONENT_LABELS、positions 按 SPEC、daily_eval 按 DAILY 展开;
312
+ def catalog() -> dict:
313
+ """位置权重矩阵自描述(供 MCP / 文档对照验证)。"""
314
+ return {
315
+ "question": "不同身份,参数偏好不同",
316
+ "components": {c: COMPONENT_LABELS[c] for c in COMPONENTS},
317
+ "classes": {
318
+ VIEWPOINT: "认知视角:3 项都涉及,只标主导,不设零",
319
+ FUNCTIONAL: "功能单元:身份即排除(不猜/不记/不对外)",
320
+ },
321
+ "positions": {p: dict(SPEC[p]) for p in POSITION_ORDER},
322
+ "daily_eval": list(DAILY),
323
+ "meta_reference": [p for p in POSITION_ORDER if p not in DAILY],
324
+ "derivation": {"record": "不猜 → 排除 位置可预测性",
325
+ "output": "不记 → 排除 一致性",
326
+ "sustain": "不对外 → 排除 版本对齐度"},
327
+ "formula": "P_trust = f(一致性, 位置可预测性, 版本对齐度)",
328
+ "honest_boundary": "只声明序,不宣称数值;blend() 权重为占位序秩",
329
+ }
330
+
331
+
332
+ # ==========================================================================
333
+ # 结构重要性重算(maintain.importance)
334
+ # ==========================================================================
335
+ #
336
+ # 与上面的「位置权重矩阵」是**两件事**,不要混:
337
+ # · 上面回答「不同身份偏好哪些信任分量」(序标定,作用于位置);
338
+ # · 下面回答「一个节点在认知图结构里该有多大重要性」(重算,作用于节点)。
339
+ #
340
+ # 三个**可测**分量(对齐计划:按覆盖度、冗余度、验证基底重排):
341
+ # coverage 覆盖度 —— 有多少节点指向/包含它(入度,结构中枢性)
342
+ # redundancy 冗余度 —— 与同层节点内容哈希撞车的比例(越冗余越该降权)
343
+ # basis 验证基底 —— 外部验证档位(formal_proof/compiler > test > measurement > data > other)
344
+ #
345
+ # 纪律:只改 `frontmatter.importance` 与索引快照,**不动正文**(减小 diff 与重写成本);
346
+ # 全流程可预演(apply=False)、可留痕(`_maintain.jsonl`)、可回滚(rollback)。
347
+ # 性能:dry-run 不读任何节点文件(只用索引快照);apply 只写「变动超阈值」的节点。
348
+
349
+ MAINTAIN_LOG = "_maintain.jsonl"
350
+
351
+ #: 验证基底 → 可信权重(枚举来自 nodefile.VERIFICATION_BASIS)
352
+ #: 文科来源一致性档(textbook/public_kb)低于可复现档、高于 other:
353
+ #: 教材/公开知识库是权威二手来源,但不是可复算证据。
354
+ BASIS_TRUST = {
355
+ "formal_proof": 1.00,
356
+ "compiler": 0.90,
357
+ "test": 0.80,
358
+ "measurement": 0.65,
359
+ "textbook": 0.60,
360
+ "data": 0.45,
361
+ "public_kb": 0.40,
362
+ "other": 0.25,
363
+ }
364
+ BASIS_TRUST_MISSING = 0.25
365
+
366
+ #: 三分量合成权重(占位量级,沿用「只声明序」纪律;分量序主导→次要)
367
+ IMPORTANCE_MIX = {"basis": 0.40, "coverage": 0.35, "redundancy": 0.25}
368
+ COV_SAT = 12.0 # 入度饱和点:约 12 条入边即视为覆盖满
369
+ IMPORTANCE_FLOOR = 0.10
370
+ IMPORTANCE_CEIL = 1.00
371
+ IMPORTANCE_PROTECT = 0.70 # ≥ 此值:保护下限(已保护/高危节点不被降破)
372
+ APPLY_DELTA = 0.05 # 变动小于此值不写盘(防 IO 放大)
373
+
374
+
375
+ # 生效条件:e 为可 .get 的映射时,遍历 e.get("edges")(假值视为空)逐项按 dict 的 to/target/node/id 或标量转 str 追加非假值,再取 e.get("subgraph"),若为 dict 取其 "nodes" 否则取 subgraph 本身,且当其为 list/tuple 时追加其中 dict 的 id 或标量转 str 的非假值,返回 out;
376
+ def _targets(e: dict):
377
+ """索引快照里的「出边目标」:edges ∪ subgraph.nodes(兼容 dict/str)。"""
378
+ out = []
379
+ for x in (e.get("edges") or []):
380
+ if isinstance(x, dict):
381
+ t = x.get("to") or x.get("target") or x.get("node") or x.get("id")
382
+ else:
383
+ t = x
384
+ if t:
385
+ out.append(str(t))
386
+ sg = e.get("subgraph")
387
+ raw = sg.get("nodes") if isinstance(sg, dict) else sg
388
+ if isinstance(raw, (list, tuple)):
389
+ for n in raw:
390
+ nid = n.get("id") if isinstance(n, dict) else n
391
+ if nid:
392
+ out.append(str(nid))
393
+ return out
394
+
395
+
396
+ # 生效条件:basis 为 None 时返回 BASIS_TRUST_MISSING;否则把 str(basis).strip().lower() 作为 BASIS_TRUST 的键,命中返回对应权重,未命中(含空串)返回 BASIS_TRUST_MISSING;
397
+ def basis_trust(basis):
398
+ """验证基底 → 可信权重;缺失/未知一律给最低档(不假装可信)。"""
399
+ if basis is None:
400
+ return BASIS_TRUST_MISSING
401
+ return BASIS_TRUST.get(str(basis).strip().lower(), BASIS_TRUST_MISSING)
402
+
403
+
404
+ # 生效条件:cg 的 index(getattr(cg,"index",None) or {})与其 "nodes" 同为真值时,返回以这些节点 id 为键的入度表,仅当 _targets(e) 给出的目标 t 也在 nodes 且 t != nid 时计数 +1;index 或 "nodes" 为假值(None/{})时 nodes 回落 {},直接返回空 dict。
405
+ def coverage_index(cg) -> dict:
406
+ """入度表:nid → 被多少节点指向(覆盖度,O(N) 免读文件)。"""
407
+ nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
408
+ indeg = {nid: 0 for nid in nodes}
409
+ for nid, e in nodes.items():
410
+ for t in _targets(e):
411
+ if t in indeg and t != nid:
412
+ indeg[t] += 1
413
+ return indeg
414
+
415
+
416
+ # 生效条件:cg.index 的 "nodes" 为 dict 时,layer 真值仅处理 e.get("layer")==layer 的节点,layer 假值不过滤;content_hash 为假值(None/空串/0 等)的节点输出 0.0,同 (e.get("layer"), content_hash) 第二次撞车时当前与首次节点均输出 1.0,否则输出 0.0;
417
+ def redundancy_map(cg, layer=None) -> dict:
418
+ """同层内容哈希撞车 → 冗余度 1.0,否则 0.0(精确冗余,O(N) 免读文件)。
419
+
420
+ 诚实边界:这是**精确冗余**(同一层出现完全相同的正文),不是语义近似冗余。
421
+ 语义近似由 `forgetting.redundancy`(bigram 覆盖)在写入侧单独负责。
422
+ """
423
+ nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
424
+ seen, out = {}, {}
425
+ for nid, e in nodes.items():
426
+ if layer and e.get("layer") != layer:
427
+ continue
428
+ h = e.get("content_hash") or ""
429
+ if not h:
430
+ out[nid] = 0.0
431
+ continue
432
+ key = (e.get("layer"), h)
433
+ if key in seen:
434
+ out[nid] = 1.0
435
+ out[seen[key]] = 1.0
436
+ else:
437
+ seen[key] = nid
438
+ out.setdefault(nid, 0.0)
439
+ return out
440
+
441
+
442
+ # 生效条件:cg.index 的 nodes 为 dict 且 entry 非 None 或 nodes.get(nid) 命中时,e 按 entry 优先否则 nodes.get(nid);indeg/red 分别仅在为 None 时回落 coverage_index(cg)/redundancy_map(cg, layer=e.get("layer"))(空容器不回落);按 IMPORTANCE_MIX、COV_SAT 及 e.get("verification_basis") 的 basis_trust 计算 coverage/redundancy/basis 分量,按 bool(e.get("protected")) 选择 IMPORTANCE_PROTECT 或 IMPORTANCE_FLOOR 作下限、IMPORTANCE_CEIL 作上限,返回含 before(e.get("importance",0.5) or 0.5)、after、components、protected 的 dict;entry 与 nodes.get(nid) 均为 None 返回 None;
443
+ def node_importance(cg, nid, indeg=None, red=None, entry=None):
444
+ """单节点结构重要性分解(可审计:给出分量而非只给分)。"""
445
+ nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
446
+ e = entry if entry is not None else nodes.get(nid)
447
+ if e is None:
448
+ return None
449
+ indeg = indeg if indeg is not None else coverage_index(cg)
450
+ red = red if red is not None else redundancy_map(cg, layer=e.get("layer"))
451
+ d = int(indeg.get(nid, 0) or 0)
452
+ cov = min(1.0, math.log1p(d) / math.log1p(COV_SAT))
453
+ rr = max(0.0, min(1.0, float(red.get(nid, 0.0) or 0.0)))
454
+ bt = basis_trust(e.get("verification_basis"))
455
+ score = (IMPORTANCE_MIX["basis"] * bt
456
+ + IMPORTANCE_MIX["coverage"] * cov
457
+ + IMPORTANCE_MIX["redundancy"] * (1.0 - rr))
458
+ protected = bool(e.get("protected"))
459
+ floor = IMPORTANCE_PROTECT if protected else IMPORTANCE_FLOOR
460
+ score = max(floor, min(IMPORTANCE_CEIL, score))
461
+ return {"node_id": nid,
462
+ "before": float(e.get("importance", 0.5) or 0.5),
463
+ "after": round(score, 4),
464
+ "components": {"coverage": round(cov, 4), "redundancy": round(rr, 4),
465
+ "basis_trust": round(bt, 4), "in_degree": d,
466
+ "verification_basis": e.get("verification_basis")},
467
+ "protected": protected,
468
+ "protected_floor": protected}
469
+
470
+
471
+ # 生效条件:给定 cg 且 nodes = cg.index["nodes"] 时按 layer 过滤、limit 为真值才 ids = ids[:int(limit)] 逐节点重算,abs(after-before) < float(min_delta) 记 unchanged;仅 apply=True 才把 frontmatter.importance/importance_source/importance_components 写回(after >= IMPORTANCE_PROTECT 且未 protected 时补写 protected/protection_reason),并向 cg.root 下 append_jsonl(..., MAINTAIN_LOG) 记 batch 后 rebuild_index。
472
+ def recalc(cg, layer=None, limit=None, apply=False, min_delta=APPLY_DELTA,
473
+ actor="maintain", dry_run_samples=10):
474
+ """结构重要性重算:覆盖度 + 冗余度 + 验证基底 → 重排节点重要性。
475
+
476
+ apply=False(默认)只出报表,不写盘(对应计划「可预演」)。
477
+ apply=True 逐节点改写 `frontmatter.importance`,每批写一条 `_maintain.jsonl`
478
+ (before/after/分量/actor),并提供 rollback 反向应用。
479
+ """
480
+ nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
481
+ indeg = coverage_index(cg)
482
+ red = redundancy_map(cg, layer=layer)
483
+ ids = [nid for nid, e in nodes.items()
484
+ if not layer or e.get("layer") == layer]
485
+ ids.sort()
486
+ if limit:
487
+ ids = ids[:int(limit)]
488
+ t0 = time.time()
489
+ planned, changed, unchanged, skipped = [], 0, 0, 0
490
+ before_sum = after_sum = 0.0
491
+ by_layer = {}
492
+ batch = time.strftime("%Y%m%d-%H%M%S")
493
+ samples = []
494
+ for nid in ids:
495
+ info = node_importance(cg, nid, indeg=indeg, red=red)
496
+ if info is None:
497
+ skipped += 1
498
+ continue
499
+ before, after = info["before"], info["after"]
500
+ before_sum += before
501
+ after_sum += after
502
+ lay = (nodes.get(nid) or {}).get("layer") or "?"
503
+ bl = by_layer.setdefault(lay, {"nodes": 0, "changed": 0,
504
+ "avg_before": 0.0, "avg_after": 0.0})
505
+ bl["nodes"] += 1
506
+ if abs(after - before) < float(min_delta):
507
+ unchanged += 1
508
+ continue
509
+ changed += 1
510
+ bl["changed"] += 1
511
+ plan = dict(info)
512
+ plan["batch"] = batch
513
+ plan["delta"] = round(after - before, 4)
514
+ planned.append(plan)
515
+ if len(samples) < int(dry_run_samples):
516
+ samples.append(plan)
517
+ for lay, bl in list(by_layer.items()):
518
+ bl["avg_before"] = 0.0
519
+ bl["avg_after"] = 0.0
520
+ written = 0
521
+ if apply:
522
+ for plan in planned:
523
+ nid = plan["node_id"]
524
+ node = cg.get(nid)
525
+ if not node:
526
+ continue
527
+ fm = node.get("frontmatter") or {}
528
+ fm["importance"] = plan["after"]
529
+ fm["importance_source"] = "recalc"
530
+ fm["importance_components"] = plan["components"]
531
+ if plan["after"] >= IMPORTANCE_PROTECT and not fm.get("protected"):
532
+ fm["protected"] = True
533
+ fm["protection_reason"] = (f"recalc importance={plan['after']:.2f}"
534
+ f"≥{IMPORTANCE_PROTECT}")
535
+ path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
536
+ or node.get("path") or f"{nid}.md")
537
+ cg._write_node(nid, path, fm, node.get("content") or "")
538
+ e = nodes.get(nid)
539
+ if e is not None:
540
+ e["importance"] = plan["after"]
541
+ if fm.get("protected"):
542
+ e["protected"] = True
543
+ e["protection_reason"] = fm["protection_reason"]
544
+ rec = {"t": time.time(), "action": "importance", "batch": batch,
545
+ "id": nid, "layer": (e or {}).get("layer"),
546
+ "before": plan["before"], "after": plan["after"],
547
+ "delta": plan["delta"], "components": plan["components"],
548
+ "actor": actor}
549
+ append_jsonl(os.path.join(cg.root, MAINTAIN_LOG), rec)
550
+ written += 1
551
+ if written and hasattr(cg, "rebuild_index"):
552
+ cg.rebuild_index() # 索引与盘面重新对齐,防内存/磁盘分叉
553
+ n = max(1, len(ids))
554
+ return {
555
+ "ok": True, "action": "importance", "dry_run": not apply,
556
+ "batch": batch, "nodes_scanned": len(ids), "changed": changed,
557
+ "unchanged": unchanged, "skipped": skipped, "written": written,
558
+ "min_delta": float(min_delta),
559
+ "avg_before": round(before_sum / n, 4),
560
+ "avg_after": round(after_sum / n, 4),
561
+ "by_layer": {k: {"nodes": v["nodes"], "changed": v["changed"]}
562
+ for k, v in by_layer.items()},
563
+ "samples": samples, "elapsed_ms": int((time.time() - t0) * 1000),
564
+ "log": MAINTAIN_LOG,
565
+ "note": ("dry-run:未写盘;apply=True 才改写 importance"
566
+ if not apply else
567
+ f"已改写 {written} 个节点;回滚见 rollback(batch={batch})"),
568
+ }
569
+
570
+
571
+ # 生效条件:cg.root/MAINTAIN_LOG 可读出 action=="importance" 记录后,entry_ids 为真值时按记录 id 是否在 {str(x) for x in entry_ids} 过滤;否则 batch 为真值时按 r.get("batch")==batch 过滤;否则取最后一条记录的 batch 再按其过滤;无 importance 记录返回 {"ok":False,"error":"no_records","reverted":0},过滤后无记录返回 {"ok":False,"error":"batch_not_found",...};对命中且 cg.get(nid) 为真的记录写回 rec.get("before") 并计数,若 reverted 且 cg 有 rebuild_index 则调用,最后 append_jsonl 写 actor 并返回 {"ok":True,"batch":batch,"reverted":reverted,"ids":ids};
572
+ def rollback(cg, batch=None, entry_ids=None, actor="maintain"):
573
+ """把重要性重算反向应用(bulk 改写的可回滚兑现)。
574
+
575
+ batch 为空则回滚**最近一批**。返回 {ok, reverted, batch, ids}。
576
+ """
577
+ log_path = os.path.join(cg.root, MAINTAIN_LOG)
578
+ records = [r for r in read_jsonl(log_path)
579
+ if r.get("action") == "importance"]
580
+ if not records:
581
+ return {"ok": False, "error": "no_records", "reverted": 0}
582
+ if entry_ids:
583
+ want = {str(x) for x in entry_ids}
584
+ records = [r for r in records if str(r.get("id")) in want]
585
+ elif batch:
586
+ records = [r for r in records if r.get("batch") == batch]
587
+ else:
588
+ batch = records[-1].get("batch")
589
+ records = [r for r in records if r.get("batch") == batch]
590
+ if not records:
591
+ return {"ok": False, "error": "batch_not_found", "batch": batch,
592
+ "reverted": 0}
593
+ nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
594
+ reverted, ids = 0, []
595
+ # 同一节点多条记录时以最早一条的 before 为准
596
+ for rec in records:
597
+ nid = rec.get("id")
598
+ node = cg.get(nid)
599
+ if not node:
600
+ continue
601
+ fm = node.get("frontmatter") or {}
602
+ fm["importance"] = rec.get("before")
603
+ fm["importance_source"] = "recalc_rollback"
604
+ path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
605
+ or node.get("path") or f"{nid}.md")
606
+ cg._write_node(nid, path, fm, node.get("content") or "")
607
+ e = nodes.get(nid)
608
+ if e is not None:
609
+ e["importance"] = rec.get("before")
610
+ reverted += 1
611
+ ids.append(nid)
612
+ if reverted and hasattr(cg, "rebuild_index"):
613
+ cg.rebuild_index()
614
+ append_jsonl(log_path, {"t": time.time(), "action": "importance_rollback",
615
+ "batch": batch, "reverted": reverted, "actor": actor})
616
+ return {"ok": True, "batch": batch, "reverted": reverted, "ids": ids}
617
+
618
+
619
+ # 生效条件:cg.root/MAINTAIN_LOG 可读出 JSONL 记录后,action 为真值时按 r.get("action")==action 过滤,假值不过滤;返回 recs[-int(limit):],其中 limit=0 时 int(0)=0 使切片为 recs[0:] 返回全部而非空;
620
+ def history(cg, limit=100, action=None):
621
+ """维护留痕(最近 limit 条),可按 action 过滤。"""
622
+ recs = list(read_jsonl(os.path.join(cg.root, MAINTAIN_LOG)))
623
+ if action:
624
+ recs = [r for r in recs if r.get("action") == action]
625
625
  return recs[-int(limit):]