@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
@@ -1,338 +1,338 @@
1
- # -*- coding: utf-8 -*-
2
- """comment_gate · 代码符号「条件化注释」抽样闸门(计划四环之环二入口)。
3
-
4
- **换对象不换机制**:复用 refine.py 的闸门范式(分层抽样 → 只读工单 → 人工裁决留痕 →
5
- 通过率放行),把处理对象从「node_ 前缀的记忆节点 CCG 字段缺口」换成
6
- 「code_ 前缀的代码符号注释缺口」。
7
-
8
- 候选判据(唯一、机械、不做语义猜测):**代码节点且正文缺『生效条件』**。
9
- 依 Phase 0 契约,代码节点的生效条件只能来自源码人工声明——缺它即 BLINDSPOT
10
- (缺证据),正是本闸门要治理的对象。落点按使用者裁决 q-0:写进源码、定义行紧邻的
11
- 井号注释(**两个窗口**,见 docs/mdcg/代码评审与条件化注释_契约_v0.1.md §三.2)。
12
-
13
- 本模块只做**候选池 / 工单 / 留痕 / 闸门**:不生成注释、不改任何节点。
14
- 生成与评审方式按 q-2(LLM 生成 + 人工抽检,复用 0.90 闸门)。
15
-
16
- 诚实边界(honest_limits 已随 SPEC 一并输出):
17
- · 分层抽样的**分配**沿用 refine.sample_ids 对 code_ 节点的口径(家族=大域),
18
- 而非对候选池重新分配——故 sample_adequacy 会如实报出样本里的候选产出率;
19
- 若产出率不足,应先扩大 n 或改用候选池重分配(已知待办,不在本片)。
20
- """
21
- from __future__ import annotations
22
-
23
- import json
24
- import os
25
- import time
26
-
27
- from . import codeindex, nodefile, refine
28
-
29
- #: 放行阈值**唯一真源在 refine**(不在此处再定义一份,防口径漂移)
30
- GATE_MIN_PASS_RATE = refine.GATE_MIN_PASS_RATE
31
- SAMPLE_N = refine.SAMPLE_N
32
- #: 本闸门自己的抽样种子(与 refine 的 g6-sample-v1 分离,样本可各自复算)
33
- SAMPLE_SEED = "comment-gate-v1"
34
- #: 代码节点 id 前缀(见 codeindex.node_id = code_ + sha1 前 12 位)
35
- PREFIX = "code_"
36
- LOG_NAME = "_comment_gate.jsonl"
37
-
38
- #: 人工核对清单(与工单逐项对应;对照 refine.SPEC.review_items 的同构位置)
39
- REVIEW_ITEMS = (
40
- "生效条件是否为**功能前置条件**(何种输入/状态下正确),而非索引元条件",
41
- "条件可否被机械复核(有输入/状态判据;不是「常用条件默认省略」)",
42
- "落点是否为源码定义行紧邻的井号注释(两窗口之一),且不覆盖既有实现说明",
43
- "公开仓合规:过第 14 条「内容政策 + 隐私」双清单(补写内容随源码公开)",
44
- )
45
-
46
- SPEC = {
47
- "goal": "为代码符号补写功能级生效条件注释,使其在检索侧可判(不再因缺证据恒 BLINDSPOT)",
48
- "target": "code_ 前缀节点中正文缺『生效条件』者",
49
- "landing": "源码定义行紧邻的井号注释(leading/body 两窗口,物理序合并)",
50
- "review_items": list(REVIEW_ITEMS),
51
- "gate": {"min_pass_rate": GATE_MIN_PASS_RATE, "basis": "人工核对忠实比例",
52
- "rule": "低于阈值不得扩批"},
53
- "honest_limits": [
54
- "本闸门只覆盖已索引的代码节点;未索引的源码不在面内(先跑 index_code)",
55
- "分层分配沿用 code_ 节点口径而非候选池,样本候选产出率由 sample_adequacy 如实上报",
56
- "不生成注释、不改节点:生成与评审属另一环节(LLM 生成 + 人工抽检)",
57
- ],
58
- }
59
-
60
-
61
- # 生效条件:cg 传入后返回 os.path.join(cg.root, LOG_NAME),即以 cg.root 与模块级常量 LOG_NAME 拼接的日志路径(cg 缺 root 属性时抛 AttributeError)。
62
- def _log_path(cg) -> str:
63
- return os.path.join(cg.root, LOG_NAME)
64
-
65
-
66
- # 生效条件:cg 与 nid 传入后,先看 str(nid) 是否以模块级常量 PREFIX 开头(不以则返回 False);以 PREFIX 开头时取 cg.get(nid)(缺节点按空字典)的 content(假值按空串)经 nodefile.ccg_completeness 判断,若 "生效条件" 不在其 required_present 中则返回 True,否则 False。
67
- def is_candidate(cg, nid) -> bool:
68
- """候选判据:代码节点且正文缺『生效条件』(机械判据,唯一)。"""
69
- if not str(nid).startswith(PREFIX):
70
- return False
71
- node = cg.get(nid) or {}
72
- comp = nodefile.ccg_completeness(node.get("content") or "")
73
- return "生效条件" not in comp["required_present"]
74
-
75
-
76
- # 生效条件:cg 与 nid 传入后,从 cg.get(nid)(缺节点按空字典)的 frontmatter(假值按空字典)的 code_ref(假值按空字典)中按 path/name/kind/lineno/end/lang/precise 各键取 ref.get(k)(缺键为 None),返回含 code_ref 与固定 landing_rule、landing_note 字段的落点字典。
77
- def _landing(cg, nid) -> dict:
78
- """工单条目 → 源码落点(坐标 + 落点规则),供补写者直接定位。"""
79
- node = cg.get(nid) or {}
80
- fm = node.get("frontmatter") or {}
81
- ref = fm.get("code_ref") or {}
82
- return {
83
- "code_ref": {k: ref.get(k) for k in
84
- ("path", "name", "kind", "lineno", "end", "lang", "precise")},
85
- "landing_rule": "定义行紧邻上方连续井号注释(leading)或定义行紧邻下方、体首语句之前(body)",
86
- "landing_note": "两窗口按源码物理行序合并;靠前者胜出(契约 §三.2)",
87
- }
88
-
89
-
90
- # 生效条件:cg 与 nid 传入后,取 cg.get(nid)(缺节点按空字典)的 content(假值按空串)算长度与 refine._sha(content)[:16] 作为 source_sha,并结合 refine._entry(cg, nid) 的 layer/tags(tags 假值按空列表)与 nodefile.CCG_MARKS 得出 ccg_missing,最后合并 _landing(cg, nid) 的返回构成工单条目字典。
91
- def _item(cg, nid) -> dict:
92
- node = cg.get(nid) or {}
93
- content = node.get("content") or ""
94
- comp = nodefile.ccg_completeness(content)
95
- e = refine._entry(cg, nid)
96
- it = {
97
- "id": nid, "family": refine._family(cg, nid),
98
- "layer": e.get("layer"), "tags": list(e.get("tags") or []),
99
- "ccg_present": comp["present"],
100
- "ccg_missing": [m for m in nodefile.CCG_MARKS if m not in comp["present"]],
101
- "body_len": len(content),
102
- "source_sha": refine._sha(content)[:16],
103
- }
104
- it.update(_landing(cg, nid))
105
- return it
106
-
107
-
108
- # 生效条件:ids 非空时返回经 is_candidate(cg, i) 过滤后的显式候选与 meta.source='explicit_ids';ids 为空时经 refine._pool(cg, PREFIX) 扫描返回候选与 meta.source='scan'(含 skipped_protected)。
109
- def candidates(cg, ids=None):
110
- """候选池(只读)→ (ids, meta)。"""
111
- if ids:
112
- pool = sorted({str(i) for i in ids if is_candidate(cg, i)})
113
- return pool, {"source": "explicit_ids", "pool": len(pool),
114
- "requested": len(pool), "candidates": len(pool)}
115
- all_ids, protected = refine._pool(cg, PREFIX)
116
- cands = sorted(i for i in all_ids if is_candidate(cg, i))
117
- return cands, {"source": "scan", "prefix": PREFIX, "pool": len(all_ids),
118
- "skipped_protected": protected, "candidates": len(cands)}
119
-
120
-
121
- # 生效条件:seed 为假值(None/空串)时回落模块常量 SAMPLE_SEED,n 仅当为 None 时取 SAMPLE_N、否则 int(n)(n=0 保留 0);ids 为真值时样本取全部候选,为假值(含空列表)时经 refine.sample_ids 抽样后按 is_candidate 过滤。
122
- def plan(x, ids=None, n=None, seed=None) -> dict:
123
- """抽检工单(只读):确定性样本 + 源码落点 + 口径声明 + 样本充分性。"""
124
- cg = refine._as_cg(x)
125
- seed = seed or SAMPLE_SEED
126
- n = SAMPLE_N if n is None else int(n)
127
- cands, cmeta = candidates(cg, ids=ids)
128
- if ids:
129
- sample = sorted(cands)
130
- smeta = {"pool": len(cands), "sampled": len(cands), "families": 0, "strata": {}}
131
- else:
132
- picked, smeta = refine.sample_ids(cg, n=n, seed=seed, prefix=PREFIX)
133
- sample = sorted(i for i in picked if is_candidate(cg, i))
134
- items = [_item(cg, nid) for nid in sample]
135
- strata = {}
136
- for it in items:
137
- s = strata.setdefault(it["family"], {"picked": 0, "missing_fields": {}})
138
- s["picked"] += 1
139
- for m in it["ccg_missing"]:
140
- s["missing_fields"][m] = s["missing_fields"].get(m, 0) + 1
141
- adequacy = {
142
- "sample_of_code_nodes": smeta.get("sampled", len(sample)),
143
- "candidates_in_sample": len(sample),
144
- "candidate_yield": round(len(sample) / float(smeta.get("sampled") or 1), 4),
145
- "note": "分配沿用 code_ 节点口径;产出率不足时应扩大 n 或改候选池重分配",
146
- }
147
- return {
148
- "root": cg.root, "dry_run": True, "readonly": True,
149
- "action": "comment_gate", "op": "maintain",
150
- "prefix": PREFIX, "seed": seed, "requested": n,
151
- "pool": cmeta, "sampled": len(items), "families": len(strata),
152
- "sample": sample, "sample_sha": refine._sha(*sample)[:16] if sample else "",
153
- "strata": strata, "items": items, "worklist": items,
154
- "spec": SPEC, "gate_rule": SPEC["gate"], "sample_adequacy": adequacy,
155
- "note": ("代码注释补写工单(只读):供人工核对补写口径;"
156
- "核对通过率未达阈值前不得扩批。本动作不改任何节点。"),
157
- }
158
-
159
-
160
- # 生效条件:verdicts(None 按 [])中可哈希且属于 okv 字面集合(True/"1"/"true"/"True"/"pass"/"PASS"/"faithful"/"忠实"/"accept"/"ACCEPT")的项计 passed,dict 项在 `v in okv` 处不可哈希先抛 TypeError,故源码里 v.get("verdict") 的计数分支不可达;reviewed 为 0 时 rate=0.0、expand_allowed=False、reason="no_review",否则按 rate 与模块常量 GATE_MIN_PASS_RATE 比较给出 expand_allowed 与 reason。
161
- def _stats(verdicts) -> dict:
162
- """通过率(只认忠实/pass/True),阈值取 refine 唯一真源。"""
163
- vs = list(verdicts or [])
164
- okv = {True, "1", "true", "True", "pass", "PASS", "faithful", "忠实",
165
- "accept", "ACCEPT"}
166
- passed = 0
167
- for v in vs:
168
- if v in okv:
169
- passed += 1
170
- elif isinstance(v, dict) and v.get("verdict") in okv:
171
- passed += 1
172
- reviewed = len(vs)
173
- rate = (passed / float(reviewed)) if reviewed else 0.0
174
- allowed = reviewed > 0 and rate >= GATE_MIN_PASS_RATE
175
- return {"reviewed": reviewed, "passed": passed, "pass_rate": round(rate, 4),
176
- "min_pass_rate": GATE_MIN_PASS_RATE, "expand_allowed": allowed,
177
- "reason": ("" if allowed else
178
- ("no_review" if reviewed == 0 else
179
- "rate %.4f < %.2f" % (rate, GATE_MIN_PASS_RATE)))}
180
-
181
-
182
- # 生效条件:x 传入后经 refine._as_cg 得到 cg,若 cg.principal 非 None 则调用其 require_admin("maintain_comment_gate");随后调用 plan(cg, ids=ids, n=n, seed=seed) 取工单、调用 _stats(verdicts) 取闸门统计,batch 假值回落 time.strftime("%Y%m%d-%H%M%S"),os.makedirs(cg.root, exist_ok=True) 后把含 batch/actor/seed/pool/sample/verdicts/gate 等字段的记录以追加方式写入 _log_path(cg),并返回 ok=True 的留痕结果。
183
- def apply(x, ids=None, n=None, seed=None, verdicts=None, actor=None, note=None,
184
- batch=None) -> dict:
185
- """落抽检批次 + 人工裁决到 _comment_gate.jsonl。**不改写任何节点**。
186
-
187
- 权限**自持在模块内**(与 refine 同档):apply 虽只落留痕,但它决定后续是否放行
188
- **扩批**,故按管理面处理。放在此处而非分发层,是为避免「分发面漏挂一道闸」
189
- 这类易失同步的权限缺口。
190
- """
191
- cg = refine._as_cg(x)
192
- _principal = getattr(cg, "principal", None)
193
- if _principal is not None:
194
- _principal.require_admin("maintain_comment_gate")
195
- p = plan(cg, ids=ids, n=n, seed=seed)
196
- batch = batch or time.strftime("%Y%m%d-%H%M%S")
197
- stats = _stats(verdicts)
198
- rec = {"t": time.time(), "action": "comment_gate", "batch": batch, "actor": actor,
199
- "seed": p["seed"], "requested": p["requested"], "pool": p["pool"],
200
- "sampled": p["sampled"], "sample": p["sample"], "sample_sha": p["sample_sha"],
201
- "sample_adequacy": p["sample_adequacy"], "verdicts": list(verdicts or []),
202
- "gate": stats, "note": note}
203
- os.makedirs(cg.root, exist_ok=True)
204
- with open(_log_path(cg), "a", encoding="utf-8") as f:
205
- f.write(json.dumps(rec, ensure_ascii=False) + chr(10))
206
- return {"ok": True, "action": "comment_gate", "op": "maintain", "batch": batch,
207
- "root": cg.root, "sampled": p["sampled"], "gate": stats, "log": LOG_NAME,
208
- "note": ("抽检留痕已落盘(未改任何节点);" +
209
- ("闸门放行扩批" if stats["expand_allowed"] else
210
- "闸门未放行:" + stats["reason"]))}
211
-
212
-
213
- # 生效条件:x 传入后经 refine._as_cg 得到 cg,读取 _log_path(cg) 且仅当 os.path.exists 为真时逐行解析(空行跳过、json.loads 抛 ValueError 的行跳过),batch 为真时仅保留 batch 字段匹配的记录;recs 为空时返回 expand_allowed=False、reason="no_batch",否则取 recs[-1] 的 verdicts 经 _stats 复算并返回。
214
- def gate(x, batch=None) -> dict:
215
- """扩批闸门:读留痕复算通过率(不写盘)。"""
216
- cg = refine._as_cg(x)
217
- recs = []
218
- path = _log_path(cg)
219
- if os.path.exists(path):
220
- with open(path, encoding="utf-8", errors="replace") as f:
221
- for line in f:
222
- line = line.strip()
223
- if not line:
224
- continue
225
- try:
226
- recs.append(json.loads(line))
227
- except ValueError:
228
- continue
229
- if batch:
230
- recs = [r for r in recs if r.get("batch") == batch]
231
- if not recs:
232
- return {"ok": True, "action": "comment_gate_gate", "op": "maintain",
233
- "root": cg.root, "batch": batch, "batches": 0,
234
- "expand_allowed": False, "reason": "no_batch"}
235
- rec = recs[-1]
236
- stats = _stats(rec.get("verdicts"))
237
- return {"ok": True, "action": "comment_gate_gate", "op": "maintain",
238
- "root": cg.root, "batch": rec.get("batch"),
239
- "batches": len({r.get("batch") for r in recs}), **stats}
240
-
241
-
242
- # 生效条件:root 传入后调用 codeindex.index_dir 扫描(max_files 假值回落 500,max_items 假值回落 2000),对返回 items 的每条 comments(假值按空列表)逐条先 str(c).lstrip("#").strip() 再判断是否以 "生效条件" 开头,全部不以该串开头的项进入候选并返回含 items/errors/stats/examined/candidates 的字典。
243
- def candidates_from_sources(root, patterns=None, max_files=None, max_items=None,
244
- skip_dirs=None):
245
- """**源级**候选枚举(不依赖认知图):扫源码树,筛出注释里缺『生效条件』的符号。
246
-
247
- 为什么需要它(2026-09-17 实测):真实库 2934 条 code_ 节点的生效条件 **100% 是旧 render
248
- 的合成值**,故**图内候选池为 0**;而「源码里哪些符号缺条件注释」是**源侧事实**,
249
- 无须先重索引(重索引会让 2934 条同时失去条件、判 BLINDSPOT)。本入口绕开该一次性代价。
250
-
251
- 判据唯一且机械:符号的 **井号注释窗口**(leading + body,见 codeindex)中不存在以
252
- 『生效条件』开头的行;只认井号注释、不认 docstring——落点按 q-0 裁决。
253
- """
254
- items, errors, stats = codeindex.index_dir(
255
- root, patterns=patterns, max_files=int(max_files or 500),
256
- max_items=int(max_items or 2000), skip_dirs=skip_dirs)
257
- cands = []
258
- for it in items:
259
- has = any(str(c).lstrip("#").strip().startswith("生效条件")
260
- for c in (it.get("comments") or []))
261
- if not has:
262
- cands.append(it)
263
- return {"root": root, "items": cands, "errors": errors, "stats": stats,
264
- "examined": len(items), "candidates": len(cands),
265
- "note": ("源级枚举:判据=井号注释窗口内无『生效条件』行;"
266
- "不含图内节点状态,故不受存量渲染影响")}
267
-
268
-
269
- # 生效条件:it 传入后取 it.get("path")(假值按空串)按 "/" 分割首段作为 family(首段为空则 family="."),并返回含 id=codeindex.node_id(it)、name/kind、code_ref(path/lineno/end/lang/precise 各缺省 None)、comments(假值按空列表逐项 str)、以及固定 landing_rule 与 landing_note 的字典。
270
- def _landing_src(it) -> dict:
271
- return {"id": codeindex.node_id(it), "name": it.get("name"),
272
- "kind": it.get("kind"),
273
- "family": (it.get("path") or "").split("/")[0] or ".",
274
- "code_ref": {"path": it.get("path"), "lineno": it.get("lineno"),
275
- "end": it.get("end"), "lang": it.get("lang"),
276
- "precise": it.get("precise")},
277
- "comments": [str(c) for c in (it.get("comments") or [])],
278
- "landing_rule": ("定义行紧邻上方连续井号注释(leading)或定义行紧邻下方、"
279
- "体首语句之前(body)"),
280
- "landing_note": "两窗口按源码物理行序合并;靠前者胜出(契约 §三.2)"}
281
-
282
-
283
- # 生效条件:root 传入后调用 candidates_from_sources(root, patterns=patterns, skip_dirs=skip_dirs, max_files=max_files, max_items=max_items) 得候选,seed 假值回落 SAMPLE_SEED,n 为 None 时取 SAMPLE_N 否则 int(n)(0 保持 0),按 path 首段(空则 ".")分族与 sha(seed, node_id) 排序后做族间确定性轮转取至多 n 项,返回只读源级工单。
284
- def plan_sources(root, n=None, seed=None, patterns=None, skip_dirs=None,
285
- max_files=None, max_items=None) -> dict:
286
- """**源级**工单(只读):确定性抽样 + 源码落点;不依赖认知图、不改任何节点。
287
-
288
- 抽样口径:按大域(顶层目录)**确定性轮转**(族内按 sha(seed,id) 排序)。
289
- 刻意**不复制** refine 的浮点最大余数分配——那是第二份实现,会引入漂移;
290
- 源级候选列表是精确的(无「先抽样再过滤」的口径损失),轮转已给出跨族覆盖。
291
- """
292
- seed = seed or SAMPLE_SEED
293
- n = SAMPLE_N if n is None else int(n)
294
- got = candidates_from_sources(root, patterns=patterns, skip_dirs=skip_dirs,
295
- max_files=max_files, max_items=max_items)
296
- fams = {}
297
- for it in got["items"]:
298
- top = (it.get("path") or "").split("/")[0] or "."
299
- fams.setdefault(top, []).append(it)
300
- pools = {f: len(v) for f, v in fams.items()}
301
- names = sorted(fams)
302
- for f in names:
303
- fams[f].sort(key=lambda it: refine._sha(seed, codeindex.node_id(it)))
304
- picked = []
305
- while len(picked) < n and any(fams[f] for f in names):
306
- for f in names:
307
- if fams[f] and len(picked) < n:
308
- picked.append(fams[f].pop(0))
309
- work = [_landing_src(it) for it in picked]
310
- return {"root": root, "dry_run": True, "readonly": True, "mode": "source_level",
311
- "action": "comment_gate_sources", "op": "maintain",
312
- "seed": seed, "requested": n, "examined": got["examined"],
313
- "candidates": got["candidates"], "sampled": len(work),
314
- "families": len(pools), "strata": pools,
315
- "items": work, "worklist": work, "spec": SPEC,
316
- "scan_errors": list(got["errors"])[:10], "scan_stats": got["stats"],
317
- "gate_rule": SPEC["gate"],
318
- "note": ("源级工单(只读):不依赖认知图、不改任何节点;"
319
- "抽样为按大域的确定性轮转。")}
320
-
321
-
322
- # 生效条件:x 与 action 传入后,action=="comment_gate" 时若 kw.get("apply") 为真则转 apply(x, ids,n,seed,verdicts,actor,note,batch),否则转 plan(x, ids,n,seed);action=="comment_gate_verdict" 时转 gate(x, batch);action 为 "comment_gate_sources" 或 "comment_gate_source_plan" 时以 root=kw.get("root") or getattr(x,"root",None) or str(x) 转 plan_sources(...);其余 action 抛 ValueError。
323
- def run(x, action, **kw) -> dict:
324
- """maintain op 分派入口(与 backfill.run 同形,便于 mcp_server 侧并列分派)。"""
325
- if action == "comment_gate":
326
- if kw.get("apply"):
327
- return apply(x, ids=kw.get("ids"), n=kw.get("n"), seed=kw.get("seed"),
328
- verdicts=kw.get("verdicts"), actor=kw.get("actor"),
329
- note=kw.get("note"), batch=kw.get("batch"))
330
- return plan(x, ids=kw.get("ids"), n=kw.get("n"), seed=kw.get("seed"))
331
- if action == "comment_gate_verdict":
332
- return gate(x, batch=kw.get("batch"))
333
- if action in ("comment_gate_sources", "comment_gate_source_plan"):
334
- root = kw.get("root") or getattr(x, "root", None) or str(x)
335
- return plan_sources(root, n=kw.get("n"), seed=kw.get("seed"),
336
- patterns=kw.get("patterns"), skip_dirs=kw.get("skip_dirs"))
337
- raise ValueError("未知 comment_gate action:%s(允许 comment_gate / "
1
+ # -*- coding: utf-8 -*-
2
+ """comment_gate · 代码符号「条件化注释」抽样闸门(计划四环之环二入口)。
3
+
4
+ **换对象不换机制**:复用 refine.py 的闸门范式(分层抽样 → 只读工单 → 人工裁决留痕 →
5
+ 通过率放行),把处理对象从「node_ 前缀的记忆节点 CCG 字段缺口」换成
6
+ 「code_ 前缀的代码符号注释缺口」。
7
+
8
+ 候选判据(唯一、机械、不做语义猜测):**代码节点且正文缺『生效条件』**。
9
+ 依 Phase 0 契约,代码节点的生效条件只能来自源码人工声明——缺它即 BLINDSPOT
10
+ (缺证据),正是本闸门要治理的对象。落点按使用者裁决 q-0:写进源码、定义行紧邻的
11
+ 井号注释(**两个窗口**,见 docs/mdcg/代码评审与条件化注释_契约_v0.1.md §三.2)。
12
+
13
+ 本模块只做**候选池 / 工单 / 留痕 / 闸门**:不生成注释、不改任何节点。
14
+ 生成与评审方式按 q-2(LLM 生成 + 人工抽检,复用 0.90 闸门)。
15
+
16
+ 诚实边界(honest_limits 已随 SPEC 一并输出):
17
+ · 分层抽样的**分配**沿用 refine.sample_ids 对 code_ 节点的口径(家族=大域),
18
+ 而非对候选池重新分配——故 sample_adequacy 会如实报出样本里的候选产出率;
19
+ 若产出率不足,应先扩大 n 或改用候选池重分配(已知待办,不在本片)。
20
+ """
21
+ from __future__ import annotations
22
+
23
+ import json
24
+ import os
25
+ import time
26
+
27
+ from . import codeindex, nodefile, refine
28
+
29
+ #: 放行阈值**唯一真源在 refine**(不在此处再定义一份,防口径漂移)
30
+ GATE_MIN_PASS_RATE = refine.GATE_MIN_PASS_RATE
31
+ SAMPLE_N = refine.SAMPLE_N
32
+ #: 本闸门自己的抽样种子(与 refine 的 g6-sample-v1 分离,样本可各自复算)
33
+ SAMPLE_SEED = "comment-gate-v1"
34
+ #: 代码节点 id 前缀(见 codeindex.node_id = code_ + sha1 前 12 位)
35
+ PREFIX = "code_"
36
+ LOG_NAME = "_comment_gate.jsonl"
37
+
38
+ #: 人工核对清单(与工单逐项对应;对照 refine.SPEC.review_items 的同构位置)
39
+ REVIEW_ITEMS = (
40
+ "生效条件是否为**功能前置条件**(何种输入/状态下正确),而非索引元条件",
41
+ "条件可否被机械复核(有输入/状态判据;不是「常用条件默认省略」)",
42
+ "落点是否为源码定义行紧邻的井号注释(两窗口之一),且不覆盖既有实现说明",
43
+ "公开仓合规:过第 14 条「内容政策 + 隐私」双清单(补写内容随源码公开)",
44
+ )
45
+
46
+ SPEC = {
47
+ "goal": "为代码符号补写功能级生效条件注释,使其在检索侧可判(不再因缺证据恒 BLINDSPOT)",
48
+ "target": "code_ 前缀节点中正文缺『生效条件』者",
49
+ "landing": "源码定义行紧邻的井号注释(leading/body 两窗口,物理序合并)",
50
+ "review_items": list(REVIEW_ITEMS),
51
+ "gate": {"min_pass_rate": GATE_MIN_PASS_RATE, "basis": "人工核对忠实比例",
52
+ "rule": "低于阈值不得扩批"},
53
+ "honest_limits": [
54
+ "本闸门只覆盖已索引的代码节点;未索引的源码不在面内(先跑 index_code)",
55
+ "分层分配沿用 code_ 节点口径而非候选池,样本候选产出率由 sample_adequacy 如实上报",
56
+ "不生成注释、不改节点:生成与评审属另一环节(LLM 生成 + 人工抽检)",
57
+ ],
58
+ }
59
+
60
+
61
+ # 生效条件:cg 传入后返回 os.path.join(cg.root, LOG_NAME),即以 cg.root 与模块级常量 LOG_NAME 拼接的日志路径(cg 缺 root 属性时抛 AttributeError)。
62
+ def _log_path(cg) -> str:
63
+ return os.path.join(cg.root, LOG_NAME)
64
+
65
+
66
+ # 生效条件:cg 与 nid 传入后,先看 str(nid) 是否以模块级常量 PREFIX 开头(不以则返回 False);以 PREFIX 开头时取 cg.get(nid)(缺节点按空字典)的 content(假值按空串)经 nodefile.ccg_completeness 判断,若 "生效条件" 不在其 required_present 中则返回 True,否则 False。
67
+ def is_candidate(cg, nid) -> bool:
68
+ """候选判据:代码节点且正文缺『生效条件』(机械判据,唯一)。"""
69
+ if not str(nid).startswith(PREFIX):
70
+ return False
71
+ node = cg.get(nid) or {}
72
+ comp = nodefile.ccg_completeness(node.get("content") or "")
73
+ return "生效条件" not in comp["required_present"]
74
+
75
+
76
+ # 生效条件:cg 与 nid 传入后,从 cg.get(nid)(缺节点按空字典)的 frontmatter(假值按空字典)的 code_ref(假值按空字典)中按 path/name/kind/lineno/end/lang/precise 各键取 ref.get(k)(缺键为 None),返回含 code_ref 与固定 landing_rule、landing_note 字段的落点字典。
77
+ def _landing(cg, nid) -> dict:
78
+ """工单条目 → 源码落点(坐标 + 落点规则),供补写者直接定位。"""
79
+ node = cg.get(nid) or {}
80
+ fm = node.get("frontmatter") or {}
81
+ ref = fm.get("code_ref") or {}
82
+ return {
83
+ "code_ref": {k: ref.get(k) for k in
84
+ ("path", "name", "kind", "lineno", "end", "lang", "precise")},
85
+ "landing_rule": "定义行紧邻上方连续井号注释(leading)或定义行紧邻下方、体首语句之前(body)",
86
+ "landing_note": "两窗口按源码物理行序合并;靠前者胜出(契约 §三.2)",
87
+ }
88
+
89
+
90
+ # 生效条件:cg 与 nid 传入后,取 cg.get(nid)(缺节点按空字典)的 content(假值按空串)算长度与 refine._sha(content)[:16] 作为 source_sha,并结合 refine._entry(cg, nid) 的 layer/tags(tags 假值按空列表)与 nodefile.CCG_MARKS 得出 ccg_missing,最后合并 _landing(cg, nid) 的返回构成工单条目字典。
91
+ def _item(cg, nid) -> dict:
92
+ node = cg.get(nid) or {}
93
+ content = node.get("content") or ""
94
+ comp = nodefile.ccg_completeness(content)
95
+ e = refine._entry(cg, nid)
96
+ it = {
97
+ "id": nid, "family": refine._family(cg, nid),
98
+ "layer": e.get("layer"), "tags": list(e.get("tags") or []),
99
+ "ccg_present": comp["present"],
100
+ "ccg_missing": [m for m in nodefile.CCG_MARKS if m not in comp["present"]],
101
+ "body_len": len(content),
102
+ "source_sha": refine._sha(content)[:16],
103
+ }
104
+ it.update(_landing(cg, nid))
105
+ return it
106
+
107
+
108
+ # 生效条件:ids 非空时返回经 is_candidate(cg, i) 过滤后的显式候选与 meta.source='explicit_ids';ids 为空时经 refine._pool(cg, PREFIX) 扫描返回候选与 meta.source='scan'(含 skipped_protected)。
109
+ def candidates(cg, ids=None):
110
+ """候选池(只读)→ (ids, meta)。"""
111
+ if ids:
112
+ pool = sorted({str(i) for i in ids if is_candidate(cg, i)})
113
+ return pool, {"source": "explicit_ids", "pool": len(pool),
114
+ "requested": len(pool), "candidates": len(pool)}
115
+ all_ids, protected = refine._pool(cg, PREFIX)
116
+ cands = sorted(i for i in all_ids if is_candidate(cg, i))
117
+ return cands, {"source": "scan", "prefix": PREFIX, "pool": len(all_ids),
118
+ "skipped_protected": protected, "candidates": len(cands)}
119
+
120
+
121
+ # 生效条件:seed 为假值(None/空串)时回落模块常量 SAMPLE_SEED,n 仅当为 None 时取 SAMPLE_N、否则 int(n)(n=0 保留 0);ids 为真值时样本取全部候选,为假值(含空列表)时经 refine.sample_ids 抽样后按 is_candidate 过滤。
122
+ def plan(x, ids=None, n=None, seed=None) -> dict:
123
+ """抽检工单(只读):确定性样本 + 源码落点 + 口径声明 + 样本充分性。"""
124
+ cg = refine._as_cg(x)
125
+ seed = seed or SAMPLE_SEED
126
+ n = SAMPLE_N if n is None else int(n)
127
+ cands, cmeta = candidates(cg, ids=ids)
128
+ if ids:
129
+ sample = sorted(cands)
130
+ smeta = {"pool": len(cands), "sampled": len(cands), "families": 0, "strata": {}}
131
+ else:
132
+ picked, smeta = refine.sample_ids(cg, n=n, seed=seed, prefix=PREFIX)
133
+ sample = sorted(i for i in picked if is_candidate(cg, i))
134
+ items = [_item(cg, nid) for nid in sample]
135
+ strata = {}
136
+ for it in items:
137
+ s = strata.setdefault(it["family"], {"picked": 0, "missing_fields": {}})
138
+ s["picked"] += 1
139
+ for m in it["ccg_missing"]:
140
+ s["missing_fields"][m] = s["missing_fields"].get(m, 0) + 1
141
+ adequacy = {
142
+ "sample_of_code_nodes": smeta.get("sampled", len(sample)),
143
+ "candidates_in_sample": len(sample),
144
+ "candidate_yield": round(len(sample) / float(smeta.get("sampled") or 1), 4),
145
+ "note": "分配沿用 code_ 节点口径;产出率不足时应扩大 n 或改候选池重分配",
146
+ }
147
+ return {
148
+ "root": cg.root, "dry_run": True, "readonly": True,
149
+ "action": "comment_gate", "op": "maintain",
150
+ "prefix": PREFIX, "seed": seed, "requested": n,
151
+ "pool": cmeta, "sampled": len(items), "families": len(strata),
152
+ "sample": sample, "sample_sha": refine._sha(*sample)[:16] if sample else "",
153
+ "strata": strata, "items": items, "worklist": items,
154
+ "spec": SPEC, "gate_rule": SPEC["gate"], "sample_adequacy": adequacy,
155
+ "note": ("代码注释补写工单(只读):供人工核对补写口径;"
156
+ "核对通过率未达阈值前不得扩批。本动作不改任何节点。"),
157
+ }
158
+
159
+
160
+ # 生效条件:verdicts(None 按 [])中可哈希且属于 okv 字面集合(True/"1"/"true"/"True"/"pass"/"PASS"/"faithful"/"忠实"/"accept"/"ACCEPT")的项计 passed,dict 项在 `v in okv` 处不可哈希先抛 TypeError,故源码里 v.get("verdict") 的计数分支不可达;reviewed 为 0 时 rate=0.0、expand_allowed=False、reason="no_review",否则按 rate 与模块常量 GATE_MIN_PASS_RATE 比较给出 expand_allowed 与 reason。
161
+ def _stats(verdicts) -> dict:
162
+ """通过率(只认忠实/pass/True),阈值取 refine 唯一真源。"""
163
+ vs = list(verdicts or [])
164
+ okv = {True, "1", "true", "True", "pass", "PASS", "faithful", "忠实",
165
+ "accept", "ACCEPT"}
166
+ passed = 0
167
+ for v in vs:
168
+ if v in okv:
169
+ passed += 1
170
+ elif isinstance(v, dict) and v.get("verdict") in okv:
171
+ passed += 1
172
+ reviewed = len(vs)
173
+ rate = (passed / float(reviewed)) if reviewed else 0.0
174
+ allowed = reviewed > 0 and rate >= GATE_MIN_PASS_RATE
175
+ return {"reviewed": reviewed, "passed": passed, "pass_rate": round(rate, 4),
176
+ "min_pass_rate": GATE_MIN_PASS_RATE, "expand_allowed": allowed,
177
+ "reason": ("" if allowed else
178
+ ("no_review" if reviewed == 0 else
179
+ "rate %.4f < %.2f" % (rate, GATE_MIN_PASS_RATE)))}
180
+
181
+
182
+ # 生效条件:x 传入后经 refine._as_cg 得到 cg,若 cg.principal 非 None 则调用其 require_admin("maintain_comment_gate");随后调用 plan(cg, ids=ids, n=n, seed=seed) 取工单、调用 _stats(verdicts) 取闸门统计,batch 假值回落 time.strftime("%Y%m%d-%H%M%S"),os.makedirs(cg.root, exist_ok=True) 后把含 batch/actor/seed/pool/sample/verdicts/gate 等字段的记录以追加方式写入 _log_path(cg),并返回 ok=True 的留痕结果。
183
+ def apply(x, ids=None, n=None, seed=None, verdicts=None, actor=None, note=None,
184
+ batch=None) -> dict:
185
+ """落抽检批次 + 人工裁决到 _comment_gate.jsonl。**不改写任何节点**。
186
+
187
+ 权限**自持在模块内**(与 refine 同档):apply 虽只落留痕,但它决定后续是否放行
188
+ **扩批**,故按管理面处理。放在此处而非分发层,是为避免「分发面漏挂一道闸」
189
+ 这类易失同步的权限缺口。
190
+ """
191
+ cg = refine._as_cg(x)
192
+ _principal = getattr(cg, "principal", None)
193
+ if _principal is not None:
194
+ _principal.require_admin("maintain_comment_gate")
195
+ p = plan(cg, ids=ids, n=n, seed=seed)
196
+ batch = batch or time.strftime("%Y%m%d-%H%M%S")
197
+ stats = _stats(verdicts)
198
+ rec = {"t": time.time(), "action": "comment_gate", "batch": batch, "actor": actor,
199
+ "seed": p["seed"], "requested": p["requested"], "pool": p["pool"],
200
+ "sampled": p["sampled"], "sample": p["sample"], "sample_sha": p["sample_sha"],
201
+ "sample_adequacy": p["sample_adequacy"], "verdicts": list(verdicts or []),
202
+ "gate": stats, "note": note}
203
+ os.makedirs(cg.root, exist_ok=True)
204
+ with open(_log_path(cg), "a", encoding="utf-8") as f:
205
+ f.write(json.dumps(rec, ensure_ascii=False) + chr(10))
206
+ return {"ok": True, "action": "comment_gate", "op": "maintain", "batch": batch,
207
+ "root": cg.root, "sampled": p["sampled"], "gate": stats, "log": LOG_NAME,
208
+ "note": ("抽检留痕已落盘(未改任何节点);" +
209
+ ("闸门放行扩批" if stats["expand_allowed"] else
210
+ "闸门未放行:" + stats["reason"]))}
211
+
212
+
213
+ # 生效条件:x 传入后经 refine._as_cg 得到 cg,读取 _log_path(cg) 且仅当 os.path.exists 为真时逐行解析(空行跳过、json.loads 抛 ValueError 的行跳过),batch 为真时仅保留 batch 字段匹配的记录;recs 为空时返回 expand_allowed=False、reason="no_batch",否则取 recs[-1] 的 verdicts 经 _stats 复算并返回。
214
+ def gate(x, batch=None) -> dict:
215
+ """扩批闸门:读留痕复算通过率(不写盘)。"""
216
+ cg = refine._as_cg(x)
217
+ recs = []
218
+ path = _log_path(cg)
219
+ if os.path.exists(path):
220
+ with open(path, encoding="utf-8", errors="replace") as f:
221
+ for line in f:
222
+ line = line.strip()
223
+ if not line:
224
+ continue
225
+ try:
226
+ recs.append(json.loads(line))
227
+ except ValueError:
228
+ continue
229
+ if batch:
230
+ recs = [r for r in recs if r.get("batch") == batch]
231
+ if not recs:
232
+ return {"ok": True, "action": "comment_gate_gate", "op": "maintain",
233
+ "root": cg.root, "batch": batch, "batches": 0,
234
+ "expand_allowed": False, "reason": "no_batch"}
235
+ rec = recs[-1]
236
+ stats = _stats(rec.get("verdicts"))
237
+ return {"ok": True, "action": "comment_gate_gate", "op": "maintain",
238
+ "root": cg.root, "batch": rec.get("batch"),
239
+ "batches": len({r.get("batch") for r in recs}), **stats}
240
+
241
+
242
+ # 生效条件:root 传入后调用 codeindex.index_dir 扫描(max_files 假值回落 500,max_items 假值回落 2000),对返回 items 的每条 comments(假值按空列表)逐条先 str(c).lstrip("#").strip() 再判断是否以 "生效条件" 开头,全部不以该串开头的项进入候选并返回含 items/errors/stats/examined/candidates 的字典。
243
+ def candidates_from_sources(root, patterns=None, max_files=None, max_items=None,
244
+ skip_dirs=None):
245
+ """**源级**候选枚举(不依赖认知图):扫源码树,筛出注释里缺『生效条件』的符号。
246
+
247
+ 为什么需要它(2026-09-17 实测):真实库 2934 条 code_ 节点的生效条件 **100% 是旧 render
248
+ 的合成值**,故**图内候选池为 0**;而「源码里哪些符号缺条件注释」是**源侧事实**,
249
+ 无须先重索引(重索引会让 2934 条同时失去条件、判 BLINDSPOT)。本入口绕开该一次性代价。
250
+
251
+ 判据唯一且机械:符号的 **井号注释窗口**(leading + body,见 codeindex)中不存在以
252
+ 『生效条件』开头的行;只认井号注释、不认 docstring——落点按 q-0 裁决。
253
+ """
254
+ items, errors, stats = codeindex.index_dir(
255
+ root, patterns=patterns, max_files=int(max_files or 500),
256
+ max_items=int(max_items or 2000), skip_dirs=skip_dirs)
257
+ cands = []
258
+ for it in items:
259
+ has = any(str(c).lstrip("#").strip().startswith("生效条件")
260
+ for c in (it.get("comments") or []))
261
+ if not has:
262
+ cands.append(it)
263
+ return {"root": root, "items": cands, "errors": errors, "stats": stats,
264
+ "examined": len(items), "candidates": len(cands),
265
+ "note": ("源级枚举:判据=井号注释窗口内无『生效条件』行;"
266
+ "不含图内节点状态,故不受存量渲染影响")}
267
+
268
+
269
+ # 生效条件:it 传入后取 it.get("path")(假值按空串)按 "/" 分割首段作为 family(首段为空则 family="."),并返回含 id=codeindex.node_id(it)、name/kind、code_ref(path/lineno/end/lang/precise 各缺省 None)、comments(假值按空列表逐项 str)、以及固定 landing_rule 与 landing_note 的字典。
270
+ def _landing_src(it) -> dict:
271
+ return {"id": codeindex.node_id(it), "name": it.get("name"),
272
+ "kind": it.get("kind"),
273
+ "family": (it.get("path") or "").split("/")[0] or ".",
274
+ "code_ref": {"path": it.get("path"), "lineno": it.get("lineno"),
275
+ "end": it.get("end"), "lang": it.get("lang"),
276
+ "precise": it.get("precise")},
277
+ "comments": [str(c) for c in (it.get("comments") or [])],
278
+ "landing_rule": ("定义行紧邻上方连续井号注释(leading)或定义行紧邻下方、"
279
+ "体首语句之前(body)"),
280
+ "landing_note": "两窗口按源码物理行序合并;靠前者胜出(契约 §三.2)"}
281
+
282
+
283
+ # 生效条件:root 传入后调用 candidates_from_sources(root, patterns=patterns, skip_dirs=skip_dirs, max_files=max_files, max_items=max_items) 得候选,seed 假值回落 SAMPLE_SEED,n 为 None 时取 SAMPLE_N 否则 int(n)(0 保持 0),按 path 首段(空则 ".")分族与 sha(seed, node_id) 排序后做族间确定性轮转取至多 n 项,返回只读源级工单。
284
+ def plan_sources(root, n=None, seed=None, patterns=None, skip_dirs=None,
285
+ max_files=None, max_items=None) -> dict:
286
+ """**源级**工单(只读):确定性抽样 + 源码落点;不依赖认知图、不改任何节点。
287
+
288
+ 抽样口径:按大域(顶层目录)**确定性轮转**(族内按 sha(seed,id) 排序)。
289
+ 刻意**不复制** refine 的浮点最大余数分配——那是第二份实现,会引入漂移;
290
+ 源级候选列表是精确的(无「先抽样再过滤」的口径损失),轮转已给出跨族覆盖。
291
+ """
292
+ seed = seed or SAMPLE_SEED
293
+ n = SAMPLE_N if n is None else int(n)
294
+ got = candidates_from_sources(root, patterns=patterns, skip_dirs=skip_dirs,
295
+ max_files=max_files, max_items=max_items)
296
+ fams = {}
297
+ for it in got["items"]:
298
+ top = (it.get("path") or "").split("/")[0] or "."
299
+ fams.setdefault(top, []).append(it)
300
+ pools = {f: len(v) for f, v in fams.items()}
301
+ names = sorted(fams)
302
+ for f in names:
303
+ fams[f].sort(key=lambda it: refine._sha(seed, codeindex.node_id(it)))
304
+ picked = []
305
+ while len(picked) < n and any(fams[f] for f in names):
306
+ for f in names:
307
+ if fams[f] and len(picked) < n:
308
+ picked.append(fams[f].pop(0))
309
+ work = [_landing_src(it) for it in picked]
310
+ return {"root": root, "dry_run": True, "readonly": True, "mode": "source_level",
311
+ "action": "comment_gate_sources", "op": "maintain",
312
+ "seed": seed, "requested": n, "examined": got["examined"],
313
+ "candidates": got["candidates"], "sampled": len(work),
314
+ "families": len(pools), "strata": pools,
315
+ "items": work, "worklist": work, "spec": SPEC,
316
+ "scan_errors": list(got["errors"])[:10], "scan_stats": got["stats"],
317
+ "gate_rule": SPEC["gate"],
318
+ "note": ("源级工单(只读):不依赖认知图、不改任何节点;"
319
+ "抽样为按大域的确定性轮转。")}
320
+
321
+
322
+ # 生效条件:x 与 action 传入后,action=="comment_gate" 时若 kw.get("apply") 为真则转 apply(x, ids,n,seed,verdicts,actor,note,batch),否则转 plan(x, ids,n,seed);action=="comment_gate_verdict" 时转 gate(x, batch);action 为 "comment_gate_sources" 或 "comment_gate_source_plan" 时以 root=kw.get("root") or getattr(x,"root",None) or str(x) 转 plan_sources(...);其余 action 抛 ValueError。
323
+ def run(x, action, **kw) -> dict:
324
+ """maintain op 分派入口(与 backfill.run 同形,便于 mcp_server 侧并列分派)。"""
325
+ if action == "comment_gate":
326
+ if kw.get("apply"):
327
+ return apply(x, ids=kw.get("ids"), n=kw.get("n"), seed=kw.get("seed"),
328
+ verdicts=kw.get("verdicts"), actor=kw.get("actor"),
329
+ note=kw.get("note"), batch=kw.get("batch"))
330
+ return plan(x, ids=kw.get("ids"), n=kw.get("n"), seed=kw.get("seed"))
331
+ if action == "comment_gate_verdict":
332
+ return gate(x, batch=kw.get("batch"))
333
+ if action in ("comment_gate_sources", "comment_gate_source_plan"):
334
+ root = kw.get("root") or getattr(x, "root", None) or str(x)
335
+ return plan_sources(root, n=kw.get("n"), seed=kw.get("seed"),
336
+ patterns=kw.get("patterns"), skip_dirs=kw.get("skip_dirs"))
337
+ raise ValueError("未知 comment_gate action:%s(允许 comment_gate / "
338
338
  "comment_gate_verdict)" % action)