@furongjun1999/dsh-memory 0.4.11 → 0.5.0

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 (504) hide show
  1. package/README.md +16 -16
  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 +142 -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//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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +503 -503
  24. 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
  25. 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
  26. 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
  27. 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
  28. package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +646 -646
  29. package/docs/mdcg/lingshu_tutorial.html +14449 -14449
  30. package/docs/mdcg/release_v0.4.11.md +49 -0
  31. package/docs/mdcg/release_v0.4.5.md +55 -55
  32. package/docs/mdcg/tool_table_v0.3.0.md +117 -117
  33. 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
  34. 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
  35. 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
  36. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +54 -0
  37. 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
  38. 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
  39. 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
  40. package/docs/mdcg//347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +270 -270
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. package/docs/swarm//350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +704 -704
  47. 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
  48. 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
  49. 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
  50. package/docs/theory//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. package/dsh/README.md +82 -82
  59. package/dsh/cordis.yml.example +139 -139
  60. package/dsh/update-lingshu.bat +11 -11
  61. package/lib/hooks.js +36 -2
  62. package/lib/lib/roleplay_web.js +427 -427
  63. package/md_cg/__init__.py +7 -7
  64. package/md_cg/audit.py +368 -368
  65. package/md_cg/autonomy.py +287 -287
  66. package/md_cg/backfill.py +1327 -1327
  67. package/md_cg/backfill_bigdomain.py +34 -34
  68. package/md_cg/bench6_arms.py +410 -410
  69. package/md_cg/bench6_common.py +230 -230
  70. package/md_cg/bench6_competitors.py +212 -212
  71. package/md_cg/bench_axis_domain.py +257 -257
  72. package/md_cg/bench_blind_comp.py +308 -308
  73. package/md_cg/bench_en_atoms_public.py +230 -230
  74. package/md_cg/bench_governance.py +348 -348
  75. package/md_cg/bench_lme_zh.py +410 -410
  76. package/md_cg/bench_locomo.py +121 -121
  77. package/md_cg/bench_locomo_zh.py +450 -450
  78. package/md_cg/bench_locomo_zh_public.py +147 -147
  79. package/md_cg/bench_longmem.py +112 -112
  80. package/md_cg/bench_membench.py +632 -632
  81. package/md_cg/bench_p0.py +149 -149
  82. package/md_cg/bench_progressive.py +287 -287
  83. package/md_cg/bench_role_views.py +238 -238
  84. package/md_cg/bench_task_ab.py +243 -243
  85. package/md_cg/bench_task_ab_llm.py +408 -408
  86. package/md_cg/bench_unified_en.py +204 -204
  87. package/md_cg/bench_zh_mad.py +601 -601
  88. package/md_cg/blindspot_tickets.py +123 -123
  89. package/md_cg/branches.py +285 -285
  90. package/md_cg/build_postings.py +73 -73
  91. package/md_cg/ccgc.py +1005 -948
  92. package/md_cg/census.py +132 -132
  93. package/md_cg/chain.py +300 -300
  94. package/md_cg/codeindex.py +531 -531
  95. package/md_cg/coldverify.py +292 -292
  96. package/md_cg/comment_gate.py +337 -337
  97. package/md_cg/cond_compose.py +190 -190
  98. package/md_cg/cond_facts.py +154 -154
  99. package/md_cg/cond_template.json +106 -106
  100. package/md_cg/condition_anchor.py +142 -142
  101. package/md_cg/conformance.py +726 -726
  102. package/md_cg/consistency.py +717 -717
  103. package/md_cg/consolidate.py +1536 -1439
  104. package/md_cg/corpus.py +110 -110
  105. package/md_cg/crosscheck.py +1097 -1097
  106. package/md_cg/crypto.py +437 -437
  107. package/md_cg/d_meta.py +310 -310
  108. package/md_cg/datapath.py +334 -334
  109. package/md_cg/docindex.py +473 -473
  110. package/md_cg/eval_common.py +575 -575
  111. package/md_cg/evidence.py +580 -580
  112. package/md_cg/evolution.py +477 -477
  113. package/md_cg/export.py +220 -220
  114. package/md_cg/forgetting.py +581 -581
  115. package/md_cg/fsutil.py +329 -329
  116. package/md_cg/hotcache.py +238 -214
  117. package/md_cg/hyperedge.py +251 -251
  118. package/md_cg/identity.py +390 -390
  119. package/md_cg/insight.py +500 -500
  120. package/md_cg/interop.py +199 -0
  121. package/md_cg/lexicon/build_cedict_en_zh.py +329 -329
  122. package/md_cg/lexicon/build_standard_en.py +171 -171
  123. package/md_cg/lexicon/expand_en_zh.py +211 -211
  124. package/md_cg/lifecycle.py +272 -272
  125. package/md_cg/linkref.py +280 -280
  126. package/md_cg/links.py +622 -622
  127. package/md_cg/mcp_server.py +129 -32
  128. package/md_cg/md_whitebox.py +345 -345
  129. package/md_cg/mdcg.py +176 -117
  130. package/md_cg/mdcos.py +79 -13
  131. package/md_cg/metacognition.py +591 -591
  132. package/md_cg/migrate.py +119 -119
  133. package/md_cg/migrate_aeis.py +221 -221
  134. package/md_cg/migrate_roleplay.py +293 -293
  135. package/md_cg/migrate_wisdom_graph.py +360 -360
  136. package/md_cg/mreview/__init__.py +25 -25
  137. package/md_cg/mreview/__main__.py +110 -110
  138. package/md_cg/mreview/bundle.py +178 -178
  139. package/md_cg/mreview/candidates.py +262 -262
  140. package/md_cg/mreview/govern.py +693 -693
  141. package/md_cg/mreview/locate.py +939 -939
  142. package/md_cg/mreview/pipeline.py +728 -728
  143. package/md_cg/mreview/rules/duplication.json +21 -21
  144. package/md_cg/mreview/rules/field_coverage.json +54 -54
  145. package/md_cg/mreview/rules/source_license.json +21 -21
  146. package/md_cg/mreview/rules/template_flow.json +21 -21
  147. package/md_cg/mreview/ruleset.py +252 -252
  148. package/md_cg/nodefile.py +575 -575
  149. package/md_cg/pooling.py +484 -472
  150. package/md_cg/postings.py +298 -298
  151. package/md_cg/predict.py +1100 -1100
  152. package/md_cg/progressive.py +123 -123
  153. package/md_cg/protect.py +272 -272
  154. package/md_cg/protocol/md_cg_gate.proto +33 -33
  155. package/md_cg/protocol.py +372 -372
  156. package/md_cg/provenance.py +582 -582
  157. package/md_cg/reach.py +453 -453
  158. package/md_cg/readcache.py +85 -0
  159. package/md_cg/refindex.py +833 -833
  160. package/md_cg/refine.py +604 -604
  161. package/md_cg/roleviews.py +89 -89
  162. package/md_cg/routing.py +365 -365
  163. package/md_cg/scrub.py +852 -852
  164. package/md_cg/security.py +274 -274
  165. package/md_cg/self_state.py +1029 -1029
  166. package/md_cg/selfreport.py +151 -151
  167. package/md_cg/semantic/__init__.py +10 -10
  168. package/md_cg/semantic/canonical.py +122 -122
  169. package/md_cg/semantic/en_normalizer.py +364 -364
  170. package/md_cg/semantic/en_zh_map.json +28694 -0
  171. package/md_cg/semantic/export_en_zh_map.py +64 -0
  172. package/md_cg/semantic/unify.py +45 -0
  173. package/md_cg/semantic/zh_en_atoms.py +139 -139
  174. package/md_cg/signer.py +562 -562
  175. package/md_cg/sources.py +815 -582
  176. package/md_cg/statushdr.py +179 -179
  177. package/md_cg/stg.py +48 -37
  178. package/md_cg/subgraph.py +729 -729
  179. package/md_cg/sustain.py +1138 -1138
  180. package/md_cg/tasks.py +470 -470
  181. package/md_cg/test_action_derive.py +203 -203
  182. package/md_cg/test_audit_rotate.py +270 -270
  183. package/md_cg/test_autonomy.py +143 -143
  184. package/md_cg/test_bench_governance.py +102 -102
  185. package/md_cg/test_blindspot_tickets.py +166 -166
  186. package/md_cg/test_branches.py +249 -249
  187. package/md_cg/test_ccg_perturb.py +184 -184
  188. package/md_cg/test_ccgc.py +433 -433
  189. package/md_cg/test_census_prune.py +81 -81
  190. package/md_cg/test_cond_compose_anchors.py +76 -76
  191. package/md_cg/test_cond_match.py +165 -165
  192. package/md_cg/test_condition_anchor.py +81 -81
  193. package/md_cg/test_d_meta.py +412 -412
  194. package/md_cg/test_datapath_root.py +199 -199
  195. package/md_cg/test_en_pipeline.py +166 -166
  196. package/md_cg/test_gain_gate.py +212 -212
  197. package/md_cg/test_health_scale.py +173 -173
  198. package/md_cg/test_hive_ingest.py +285 -0
  199. package/md_cg/test_hot_cold.py +215 -215
  200. package/md_cg/test_hyperedge.py +245 -245
  201. package/md_cg/test_i26_empty_first_write.py +116 -0
  202. package/md_cg/test_i27_e041_identity.py +128 -0
  203. package/md_cg/test_i28_hotcache_prodpath.py +122 -0
  204. package/md_cg/test_identity_attribution.py +147 -147
  205. package/md_cg/test_index_durability.py +224 -224
  206. package/md_cg/test_interop.py +93 -0
  207. package/md_cg/test_lifecycle.py +309 -309
  208. package/md_cg/test_linkref.py +306 -306
  209. package/md_cg/test_lock.py +43 -43
  210. package/md_cg/test_md_access_parity.py +255 -255
  211. package/md_cg/test_md_writepath.py +345 -345
  212. package/md_cg/test_mdstore_search_parity.py +160 -0
  213. package/md_cg/test_mr_m2.py +587 -587
  214. package/md_cg/test_mr_m3.py +710 -710
  215. package/md_cg/test_mr_m4.py +485 -485
  216. package/md_cg/test_p0.py +250 -250
  217. package/md_cg/test_p1.py +316 -316
  218. package/md_cg/test_p10_identity.py +173 -173
  219. package/md_cg/test_p11_consistency.py +233 -233
  220. package/md_cg/test_p12_metacognition.py +212 -212
  221. package/md_cg/test_p13_encryption.py +241 -241
  222. package/md_cg/test_p14_sustain.py +249 -249
  223. package/md_cg/test_p15_scrub.py +280 -280
  224. package/md_cg/test_p16_self_state.py +301 -301
  225. package/md_cg/test_p17_predict.py +354 -354
  226. package/md_cg/test_p18_whitebox.py +171 -171
  227. package/md_cg/test_p19_migrate_roleplay.py +149 -149
  228. package/md_cg/test_p20_evolution.py +315 -315
  229. package/md_cg/test_p21_tokens.py +293 -270
  230. package/md_cg/test_p22_theory.py +175 -175
  231. package/md_cg/test_p23_links.py +311 -311
  232. package/md_cg/test_p24_evidence.py +227 -227
  233. package/md_cg/test_p25_weights.py +156 -156
  234. package/md_cg/test_p26_refindex.py +416 -416
  235. package/md_cg/test_p27_docindex.py +765 -765
  236. package/md_cg/test_p28_refcheck.py +305 -305
  237. package/md_cg/test_p29_session_ingest_export.py +354 -333
  238. package/md_cg/test_p3.py +11 -2
  239. package/md_cg/test_p30_maintain.py +330 -330
  240. package/md_cg/test_p31_insight.py +534 -534
  241. package/md_cg/test_p32_backfill.py +298 -298
  242. package/md_cg/test_p33_ccg_wiring.py +293 -293
  243. package/md_cg/test_p34_crosscheck.py +331 -331
  244. package/md_cg/test_p35_conditioned_claim.py +252 -252
  245. package/md_cg/test_p36_kp_align.py +230 -230
  246. package/md_cg/test_p37_condition_space.py +248 -248
  247. package/md_cg/test_p38_concurrent_flush.py +102 -0
  248. package/md_cg/test_p38_contextualize.py +273 -273
  249. package/md_cg/test_p39_verify_flow.py +113 -0
  250. package/md_cg/test_p39_vision_evidence.py +369 -369
  251. package/md_cg/test_p40_refine_worklist.py +241 -241
  252. package/md_cg/test_p41_evolve_patrol.py +224 -224
  253. package/md_cg/test_p42_provenance.py +269 -269
  254. package/md_cg/test_p43_pooling.py +412 -398
  255. package/md_cg/test_p44_md_whitebox.py +231 -231
  256. package/md_cg/test_p45_session_identity.py +219 -219
  257. package/md_cg/test_p46_unit_scope.py +272 -272
  258. package/md_cg/test_p47_session_view.py +281 -0
  259. package/md_cg/test_p4_fuzzy.py +223 -223
  260. package/md_cg/test_p5_semantic.py +226 -226
  261. package/md_cg/test_p6_consolidate.py +440 -387
  262. package/md_cg/test_p7_goals_recent.py +202 -202
  263. package/md_cg/test_p8_subgraph_chain.py +200 -200
  264. package/md_cg/test_p9_forget_protect.py +231 -231
  265. package/md_cg/test_predict_beta.py +135 -135
  266. package/md_cg/test_preflight_failclosed.py +100 -100
  267. package/md_cg/test_progressive.py +146 -146
  268. package/md_cg/test_protocol.py +243 -243
  269. package/md_cg/test_reach.py +378 -378
  270. package/md_cg/test_reach_keys.py +201 -201
  271. package/md_cg/test_read_clip.py +141 -141
  272. package/md_cg/test_readcache_prodpath.py +155 -0
  273. package/md_cg/test_retr_gates_prodpath.py +140 -0
  274. package/md_cg/test_retr_s1.py +340 -340
  275. package/md_cg/test_retr_s1b.py +209 -209
  276. package/md_cg/test_retr_s3.py +194 -194
  277. package/md_cg/test_retr_s4.py +163 -163
  278. package/md_cg/test_retr_s5.py +200 -200
  279. package/md_cg/test_retr_s6.py +157 -157
  280. package/md_cg/test_retr_s7.py +384 -384
  281. package/md_cg/test_retr_s8_time.py +369 -316
  282. package/md_cg/test_retr_s9_edges.py +286 -286
  283. package/md_cg/test_retr_s9_entity_ctx.py +175 -175
  284. package/md_cg/test_review_conformance.py +367 -367
  285. package/md_cg/test_role_views.py +354 -354
  286. package/md_cg/test_sem_noise.py +242 -242
  287. package/md_cg/test_semantic_canonical.py +241 -241
  288. package/md_cg/test_subproc_encoding.py +192 -192
  289. package/md_cg/test_sustain_mutual.py +153 -153
  290. package/md_cg/test_tasks.py +409 -409
  291. package/md_cg/test_tool_face.py +189 -189
  292. package/md_cg/test_transfer.py +180 -180
  293. package/md_cg/test_trust.py +361 -361
  294. package/md_cg/test_twophase.py +286 -286
  295. package/md_cg/test_v14_fixes.py +397 -397
  296. package/md_cg/test_validity_filter.py +280 -280
  297. package/md_cg/test_verify_answer.py +138 -138
  298. package/md_cg/test_wisdom_md_store.py +292 -292
  299. package/md_cg/test_writelimit.py +197 -197
  300. package/md_cg/test_writepipe.py +214 -214
  301. package/md_cg/theory.py +273 -273
  302. package/md_cg/tokens.py +677 -663
  303. package/md_cg/tool_face.py +260 -260
  304. package/md_cg/trust.py +986 -950
  305. package/md_cg/twophase.py +231 -231
  306. package/md_cg/units.py +667 -667
  307. package/md_cg/vision_evidence.py +666 -666
  308. package/md_cg/weights.py +624 -624
  309. package/md_cg/whitebox.py +527 -527
  310. package/md_cg/whitebox_kb/__init__.py +37 -37
  311. package/md_cg/whitebox_kb/aeis_core/__init__.py +42 -42
  312. package/md_cg/whitebox_kb/aeis_core/semantic.py +280 -280
  313. package/md_cg/whitebox_kb/aeis_core/textutil.py +13 -13
  314. package/md_cg/whitebox_kb/engine.py +310 -310
  315. package/md_cg/whitebox_kb/seed_knowledge//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
  316. package/md_cg/whitebox_kb/wisdom/browser_units.py +2631 -2631
  317. package/md_cg/whitebox_kb/wisdom/causal_discover.py +432 -432
  318. package/md_cg/whitebox_kb/wisdom/chat_engine.py +1506 -1506
  319. package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
  320. package/md_cg/whitebox_kb/wisdom/compiler_code_units.py +3033 -3033
  321. package/md_cg/whitebox_kb/wisdom/condition_algebra.py +112 -112
  322. package/md_cg/whitebox_kb/wisdom/condition_frame.py +315 -315
  323. package/md_cg/whitebox_kb/wisdom/condition_kb.py +108 -108
  324. package/md_cg/whitebox_kb/wisdom/conflict_map.json +4445 -4445
  325. package/md_cg/whitebox_kb/wisdom/core/lexer.py +512 -512
  326. package/md_cg/whitebox_kb/wisdom/core/name_checker.py +1023 -1023
  327. package/md_cg/whitebox_kb/wisdom/cspmn.py +258 -258
  328. package/md_cg/whitebox_kb/wisdom/csre.py +264 -264
  329. package/md_cg/whitebox_kb/wisdom/danmaku_audit.py +252 -252
  330. package/md_cg/whitebox_kb/wisdom/distilled_condition_units.json +6417 -6417
  331. package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902b.json +1950 -1950
  332. package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902c.json +1296 -1296
  333. package/md_cg/whitebox_kb/wisdom/docs/whitebox_capability_graph_demo.json +59 -59
  334. package/md_cg/whitebox_kb/wisdom/graph_db_units.py +3089 -3089
  335. package/md_cg/whitebox_kb/wisdom/knowledge_points.py +318 -318
  336. package/md_cg/whitebox_kb/wisdom/md_access.py +470 -470
  337. package/md_cg/whitebox_kb/wisdom/md_store.py +276 -251
  338. package/md_cg/whitebox_kb/wisdom/migrate_wisdom.py +476 -476
  339. package/md_cg/whitebox_kb/wisdom/navigate.py +248 -248
  340. package/md_cg/whitebox_kb/wisdom/neural_retrieve.py +224 -224
  341. package/md_cg/whitebox_kb/wisdom/os_units.py +2735 -2735
  342. package/md_cg/whitebox_kb/wisdom/pattern_separation.py +376 -376
  343. package/md_cg/whitebox_kb/wisdom/prereq_map.json +364 -364
  344. package/md_cg/whitebox_kb/wisdom/python_code_units.py +2766 -2766
  345. package/md_cg/whitebox_kb/wisdom/role_solidified.json +7 -7
  346. package/md_cg/whitebox_kb/wisdom/route_memory.py +244 -244
  347. package/md_cg/whitebox_kb/wisdom/scene_reconstruction.py +148 -148
  348. package/md_cg/whitebox_kb/wisdom/snr_report.json +40 -40
  349. package/md_cg/whitebox_kb/wisdom/test_code_compose_domains.py +7541 -7541
  350. package/md_cg/whitebox_kb/wisdom/test_compiler_self_bootstrap.py +354 -354
  351. package/md_cg/whitebox_kb/wisdom/test_ecosystem_assembly.py +158 -158
  352. package/md_cg/whitebox_kb/wisdom/test_ecosystem_demos.py +193 -193
  353. package/md_cg/whitebox_kb/wisdom/test_graph_db.py +292 -292
  354. package/md_cg/whitebox_kb/wisdom/test_python_self_bootstrap.py +160 -160
  355. package/md_cg/whitebox_kb/wisdom/trigger_words_index.json +4366 -4366
  356. package/md_cg/whitebox_kb/wisdom/verifier.py +1297 -1297
  357. package/md_cg/writelimit.py +356 -356
  358. package/md_cg/writepipe.py +550 -542
  359. package/package.json +97 -96
  360. package/skills/plugin.json +54 -54
  361. package/skills/skills/designer-perspective/SKILL.md +158 -158
  362. package/skills/skills/designer-perspective/references/01-observation-position.md +66 -66
  363. package/skills/skills/designer-perspective/references/02-structure-recognition.md +62 -62
  364. package/skills/skills/designer-perspective/references/03-direction-judgment.md +55 -55
  365. package/skills/skills/designer-perspective/references/04-qualification-verdict.md +72 -72
  366. package/skills/skills/designer-perspective/references/05-condition-attribution.md +74 -74
  367. package/skills/skills/designer-perspective/scripts/designer.py +545 -545
  368. package/skills/skills/designer-perspective/tests/cases.jsonl +17 -17
  369. package/skills/skills/designer-perspective/tests/selftest.py +61 -61
  370. package/skills/skills/lingshu-browser/SKILL.md +60 -60
  371. package/skills/skills/lingshu-compiler/SKILL.md +56 -56
  372. package/skills/skills/lingshu-compiler/units/analyze-type-infer/SKILL.md +45 -45
  373. package/skills/skills/lingshu-compiler/units/check-name-real/SKILL.md +45 -45
  374. package/skills/skills/lingshu-compiler/units/compile-assign/SKILL.md +45 -45
  375. package/skills/skills/lingshu-compiler/units/compile-expr-tree/SKILL.md +45 -45
  376. package/skills/skills/lingshu-compiler/units/compile-full-pipeline/SKILL.md +45 -45
  377. package/skills/skills/lingshu-compiler/units/compile-func-def/SKILL.md +45 -45
  378. package/skills/skills/lingshu-compiler/units/compile-if-then/SKILL.md +45 -45
  379. package/skills/skills/lingshu-compiler/units/compile-logic-expr/SKILL.md +45 -45
  380. package/skills/skills/lingshu-compiler/units/compile-recursive/SKILL.md +45 -45
  381. package/skills/skills/lingshu-compiler/units/compile-scope/SKILL.md +45 -45
  382. package/skills/skills/lingshu-compiler/units/compile-type-check/SKILL.md +45 -45
  383. package/skills/skills/lingshu-compiler/units/compile-while/SKILL.md +45 -45
  384. package/skills/skills/lingshu-compiler/units/compiler-0010c4bf/SKILL.md +45 -45
  385. package/skills/skills/lingshu-compiler/units/compiler-0355bffb/SKILL.md +45 -45
  386. package/skills/skills/lingshu-compiler/units/compiler-0361708a/SKILL.md +45 -45
  387. package/skills/skills/lingshu-compiler/units/compiler-054a0414/SKILL.md +45 -45
  388. package/skills/skills/lingshu-compiler/units/compiler-05a1691a/SKILL.md +45 -45
  389. package/skills/skills/lingshu-compiler/units/compiler-05eeed1e/SKILL.md +45 -45
  390. package/skills/skills/lingshu-compiler/units/compiler-0622a1f6/SKILL.md +45 -45
  391. package/skills/skills/lingshu-compiler/units/compiler-08b54217/SKILL.md +45 -45
  392. package/skills/skills/lingshu-compiler/units/compiler-0a62b70c/SKILL.md +45 -45
  393. package/skills/skills/lingshu-compiler/units/compiler-0ab24d00/SKILL.md +45 -45
  394. package/skills/skills/lingshu-compiler/units/compiler-0e093688/SKILL.md +45 -45
  395. package/skills/skills/lingshu-compiler/units/compiler-0e82b966/SKILL.md +45 -45
  396. package/skills/skills/lingshu-compiler/units/compiler-0ee9b9b9/SKILL.md +45 -45
  397. package/skills/skills/lingshu-compiler/units/compiler-0f3787e6/SKILL.md +45 -45
  398. package/skills/skills/lingshu-compiler/units/compiler-1028685f/SKILL.md +45 -45
  399. package/skills/skills/lingshu-compiler/units/compiler-11897630/SKILL.md +45 -45
  400. package/skills/skills/lingshu-compiler/units/compiler-16661b9b/SKILL.md +45 -45
  401. package/skills/skills/lingshu-compiler/units/compiler-1f722303/SKILL.md +45 -45
  402. package/skills/skills/lingshu-compiler/units/compiler-25be1262/SKILL.md +45 -45
  403. package/skills/skills/lingshu-compiler/units/compiler-2a76ba07/SKILL.md +45 -45
  404. package/skills/skills/lingshu-compiler/units/compiler-2dbea54a/SKILL.md +45 -45
  405. package/skills/skills/lingshu-compiler/units/compiler-2df52f16/SKILL.md +45 -45
  406. package/skills/skills/lingshu-compiler/units/compiler-2ec2c9d2/SKILL.md +45 -45
  407. package/skills/skills/lingshu-compiler/units/compiler-2f8c8f39/SKILL.md +45 -45
  408. package/skills/skills/lingshu-compiler/units/compiler-38378ac7/SKILL.md +45 -45
  409. package/skills/skills/lingshu-compiler/units/compiler-39457d2e/SKILL.md +45 -45
  410. package/skills/skills/lingshu-compiler/units/compiler-39fb5926/SKILL.md +45 -45
  411. package/skills/skills/lingshu-compiler/units/compiler-47f4fbfa/SKILL.md +45 -45
  412. package/skills/skills/lingshu-compiler/units/compiler-4a8cd1f1/SKILL.md +45 -45
  413. package/skills/skills/lingshu-compiler/units/compiler-4b230b6b/SKILL.md +45 -45
  414. package/skills/skills/lingshu-compiler/units/compiler-4cbbda95/SKILL.md +45 -45
  415. package/skills/skills/lingshu-compiler/units/compiler-4d5a68ff/SKILL.md +45 -45
  416. package/skills/skills/lingshu-compiler/units/compiler-56dc9bdd/SKILL.md +45 -45
  417. package/skills/skills/lingshu-compiler/units/compiler-57e76ebe/SKILL.md +45 -45
  418. package/skills/skills/lingshu-compiler/units/compiler-61ff016b/SKILL.md +45 -45
  419. package/skills/skills/lingshu-compiler/units/compiler-63eae588/SKILL.md +45 -45
  420. package/skills/skills/lingshu-compiler/units/compiler-64c4224b/SKILL.md +45 -45
  421. package/skills/skills/lingshu-compiler/units/compiler-66377955/SKILL.md +45 -45
  422. package/skills/skills/lingshu-compiler/units/compiler-674ab4f6/SKILL.md +45 -45
  423. package/skills/skills/lingshu-compiler/units/compiler-6af76fd6/SKILL.md +45 -45
  424. package/skills/skills/lingshu-compiler/units/compiler-6d979db2/SKILL.md +45 -45
  425. package/skills/skills/lingshu-compiler/units/compiler-6de326c0/SKILL.md +45 -45
  426. package/skills/skills/lingshu-compiler/units/compiler-6f1c0eea/SKILL.md +45 -45
  427. package/skills/skills/lingshu-compiler/units/compiler-724d6c9b/SKILL.md +45 -45
  428. package/skills/skills/lingshu-compiler/units/compiler-7690177f/SKILL.md +45 -45
  429. package/skills/skills/lingshu-compiler/units/compiler-7b229a7d/SKILL.md +45 -45
  430. package/skills/skills/lingshu-compiler/units/compiler-7f471b3a/SKILL.md +45 -45
  431. package/skills/skills/lingshu-compiler/units/compiler-815cad08/SKILL.md +45 -45
  432. package/skills/skills/lingshu-compiler/units/compiler-83c61634/SKILL.md +45 -45
  433. package/skills/skills/lingshu-compiler/units/compiler-8c798c81/SKILL.md +45 -45
  434. package/skills/skills/lingshu-compiler/units/compiler-8dd747ac/SKILL.md +45 -45
  435. package/skills/skills/lingshu-compiler/units/compiler-90324d0a/SKILL.md +45 -45
  436. package/skills/skills/lingshu-compiler/units/compiler-94b8d72d/SKILL.md +45 -45
  437. package/skills/skills/lingshu-compiler/units/compiler-94f12231/SKILL.md +45 -45
  438. package/skills/skills/lingshu-compiler/units/compiler-95937c16/SKILL.md +45 -45
  439. package/skills/skills/lingshu-compiler/units/compiler-98a5625b/SKILL.md +45 -45
  440. package/skills/skills/lingshu-compiler/units/compiler-98b4c42f/SKILL.md +45 -45
  441. package/skills/skills/lingshu-compiler/units/compiler-98e3894a/SKILL.md +45 -45
  442. package/skills/skills/lingshu-compiler/units/compiler-9bdfe4b8/SKILL.md +45 -45
  443. package/skills/skills/lingshu-compiler/units/compiler-9d9b4e83/SKILL.md +45 -45
  444. package/skills/skills/lingshu-compiler/units/compiler-9f7be5ad/SKILL.md +45 -45
  445. package/skills/skills/lingshu-compiler/units/compiler-a6daf076/SKILL.md +45 -45
  446. package/skills/skills/lingshu-compiler/units/compiler-a7995a0c/SKILL.md +45 -45
  447. package/skills/skills/lingshu-compiler/units/compiler-a8399248/SKILL.md +45 -45
  448. package/skills/skills/lingshu-compiler/units/compiler-aabbd099/SKILL.md +45 -45
  449. package/skills/skills/lingshu-compiler/units/compiler-afe169d8/SKILL.md +45 -45
  450. package/skills/skills/lingshu-compiler/units/compiler-b0678bda/SKILL.md +45 -45
  451. package/skills/skills/lingshu-compiler/units/compiler-b09bd196/SKILL.md +45 -45
  452. package/skills/skills/lingshu-compiler/units/compiler-b1396e23/SKILL.md +45 -45
  453. package/skills/skills/lingshu-compiler/units/compiler-b9b31ce0/SKILL.md +45 -45
  454. package/skills/skills/lingshu-compiler/units/compiler-c10264a7/SKILL.md +45 -45
  455. package/skills/skills/lingshu-compiler/units/compiler-cb1e8e4b/SKILL.md +45 -45
  456. package/skills/skills/lingshu-compiler/units/compiler-ccafd438/SKILL.md +45 -45
  457. package/skills/skills/lingshu-compiler/units/compiler-cda9c262/SKILL.md +45 -45
  458. package/skills/skills/lingshu-compiler/units/compiler-ce648068/SKILL.md +45 -45
  459. package/skills/skills/lingshu-compiler/units/compiler-cf5776a4/SKILL.md +45 -45
  460. package/skills/skills/lingshu-compiler/units/compiler-d974e5d3/SKILL.md +45 -45
  461. package/skills/skills/lingshu-compiler/units/compiler-e3979fd3/SKILL.md +45 -45
  462. package/skills/skills/lingshu-compiler/units/compiler-eb1cf2b5/SKILL.md +45 -45
  463. package/skills/skills/lingshu-compiler/units/compiler-ecb30d5b/SKILL.md +45 -45
  464. package/skills/skills/lingshu-compiler/units/compiler-f8c8b24b/SKILL.md +45 -45
  465. package/skills/skills/lingshu-compiler/units/compiler-f99fedbe/SKILL.md +45 -45
  466. package/skills/skills/lingshu-compiler/units/compiler-fa8ff5f7/SKILL.md +45 -45
  467. package/skills/skills/lingshu-compiler/units/compiler-fe1b058d/SKILL.md +45 -45
  468. package/skills/skills/lingshu-compiler/units/lex-chinese-program/SKILL.md +45 -45
  469. package/skills/skills/lingshu-compiler/units/lex-dao-de-jing/SKILL.md +45 -45
  470. package/skills/skills/lingshu-compiler/units/lex-nine-chapters/SKILL.md +45 -45
  471. package/skills/skills/lingshu-compiler/units/vm-arithmetic/SKILL.md +45 -45
  472. package/skills/skills/lingshu-compiler/units/vm-array-ops/SKILL.md +45 -45
  473. package/skills/skills/lingshu-compiler/units/vm-closure-call/SKILL.md +45 -45
  474. package/skills/skills/lingshu-compiler/units/vm-closure-create/SKILL.md +45 -45
  475. package/skills/skills/lingshu-compiler/units/vm-compare/SKILL.md +45 -45
  476. package/skills/skills/lingshu-compiler/units/vm-cond-jump/SKILL.md +45 -45
  477. package/skills/skills/lingshu-compiler/units/vm-cond-space/SKILL.md +45 -45
  478. package/skills/skills/lingshu-compiler/units/vm-exception/SKILL.md +45 -45
  479. package/skills/skills/lingshu-compiler/units/vm-func-call/SKILL.md +45 -45
  480. package/skills/skills/lingshu-compiler/units/vm-loop-run/SKILL.md +45 -45
  481. package/skills/skills/lingshu-compiler/units/vm-profiling/SKILL.md +45 -45
  482. package/skills/skills/lingshu-compiler/units/vm-refcount/SKILL.md +45 -45
  483. package/skills/skills/lingshu-compiler/units/vm-run-loop/SKILL.md +45 -45
  484. package/skills/skills/lingshu-compiler/units/vm-short-circuit/SKILL.md +45 -45
  485. package/skills/skills/lingshu-compiler/units/vm-stack-guard/SKILL.md +45 -45
  486. package/skills/skills/lingshu-compiler/units/vm-stack-ops/SKILL.md +45 -45
  487. package/skills/skills/lingshu-compiler/units/vm-trust-accum/SKILL.md +45 -45
  488. package/skills/skills/lingshu-graph/SKILL.md +63 -63
  489. package/skills/skills/lingshu-net/SKILL.md +48 -48
  490. package/skills/skills/lingshu-os/SKILL.md +64 -64
  491. package/skills/skills/lingshu-pylang/SKILL.md +71 -71
  492. package/src/bridge.ts +401 -401
  493. package/src/hooks.ts +38 -2
  494. package/src/lib/datapath.ts +326 -326
  495. package/src/lib/mdcg_client.ts +413 -413
  496. package/src/lib/mutual.ts +428 -428
  497. package/src/lib/prompt_safety.ts +62 -62
  498. package/src/lib/python_path.ts +71 -71
  499. package/src/lib/roleplay_web.ts +932 -932
  500. package/src/lib/token_store.ts +192 -192
  501. package/src/tools.ts +212 -212
  502. package/zcode/AGENTS.md +11 -3
  503. package/zcode/README.md +41 -41
  504. /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,409 +1,409 @@
1
- # -*- coding: utf-8 -*-
2
- """结构层任务实体(md_cg/tasks.py)验收矩阵(2026-09-16)。
3
-
4
- 蓝图=消除 AI 失忆四症状,断言按症状逐条对位:
5
-
6
- ① 忘记已实现的工程 → H 组:session_tasks / session_recall 任务段,
7
- 且**不按 session 过滤**(工程台账跨会话可见,这正是失忆的解)
8
- ② 计划与实际不符 → F 组:计划每轮覆盖更新 + 「计划变更」节逐轮累积
9
- ③ 缺核验 → E 组:done 时结果必填闸(缺一不收),拒收后**盘上内容逐字节不变**
10
- ④ 换表述即新任务 → A/C/I 组:身份=语义 slug(非内容哈希);同 slug 幂等更新
11
- 不新增节点;同族只提示、不自动合并
12
-
13
- 另含 MCP 面对位(L 组:action 推导不吞写意图 / schema 参数声明 / 缺省 list 冒烟 /
14
- 未知 action fail-closed)与边界(J 组:串号防护、检索面、反向关联;M 组:权限闸)。
15
- 脚本式 assert + 退出码,风格与 test_branches.py / test_action_derive.py 一致。
16
- """
17
-
18
- import os
19
- import re
20
- import sys
21
- import shutil
22
- import inspect
23
- import tempfile
24
- import hashlib
25
-
26
- _HERE = os.path.dirname(os.path.abspath(__file__))
27
- _REPO = os.path.dirname(_HERE)
28
- if _REPO not in sys.path:
29
- sys.path.insert(0, _REPO)
30
-
31
- try:
32
- sys.stdout.reconfigure(encoding="utf-8", errors="replace")
33
- except Exception:
34
- pass
35
-
36
- from md_cg import mcp_server as M
37
- from md_cg import tasks as T
38
- from md_cg import tokens as TK
39
- from md_cg.mdcos import MdCGSecure
40
- from md_cg.security import Principal, AccessDenied
41
-
42
- # 语料命名(互不串扰,各症状用独立任务名)
43
- NAME = "记忆失忆修复-工程"
44
- NAME2 = "任务实体-done闸探针"
45
- NAME3 = "mcp面-任务探针"
46
- NAME4 = "任务-未开先done"
47
- NAME5 = "越权任务"
48
-
49
- _fails = []
50
- _n = [0]
51
-
52
-
53
- def check(name, cond, detail=None):
54
- _n[0] += 1
55
- if cond:
56
- print(" ok %s" % name)
57
- else:
58
- print("FAIL %s %r" % (name, detail))
59
- _fails.append(name)
60
-
61
-
62
- def _raises(fn):
63
- try:
64
- fn()
65
- except Exception as e: # noqa: BLE001 —— 测试需拿到任何异常作证据
66
- return e
67
- return None
68
-
69
-
70
- def _mk_cg(root, **kw):
71
- p = Principal(actor="task_test", role="designer", can_write=True, can_admin=True,
72
- ops_allow=["*"], layers_allow=["*"], **kw)
73
- return MdCGSecure(root, principal=p)
74
-
75
-
76
- def _task_nodes(cg):
77
- return sorted(n for n in cg.index["nodes"] if n.startswith(T.TASK_PREFIX))
78
-
79
-
80
- def _hits(cg, q, **kw):
81
- res, _meta = cg.search(q, **kw)
82
- return [h[0].get("id") for h in res]
83
-
84
-
85
- def main():
86
- tmp = tempfile.mkdtemp(prefix="mdcg_tasks_")
87
- try:
88
- _root = os.path.join(tmp, "root")
89
- cg = _mk_cg(_root)
90
- nid = T.task_node_id(NAME)
91
-
92
- # ---------------- A. 身份判据=语义 slug(症状④ 的根) ----------------
93
- print("\n[A] 身份判据:语义 slug,非内容哈希")
94
- check("A1 中文名原样保留(语义身份可读)",
95
- T.slugify(NAME) == NAME, T.slugify(NAME))
96
- check("A2 路径分隔符折叠(防目录穿越)",
97
- T.slugify("a/b\\c") == "a-b-c", T.slugify("a/b\\c"))
98
- _trav = T.slugify("../../etc/passwd")
99
- check("A3 `..` 与 `/` 全部折叠,不留穿越形态",
100
- ".." not in _trav and "/" not in _trav and "\\" not in _trav, _trav)
101
- check("A4 空白/纯符号名拒收(无身份不建卡)",
102
- T.task_node_id(" ") is None or T.slugify(" ") == "", T.slugify(" "))
103
- check("A4b 纯符号名 slug 为空", T.slugify("!!!") == "", T.slugify("!!!"))
104
- check("A5 已带前缀不重复叠(task_x → task_x)",
105
- T.task_node_id("task_x") == "task_x" == T.task_node_id("x"),
106
- (T.task_node_id("task_x"), T.task_node_id("x")))
107
- check("A6 超长名截断(≥64 上限护栏)",
108
- len(T.task_node_id("a" * 200)) <= len(T.TASK_PREFIX) + 64,
109
- len(T.task_node_id("a" * 200)))
110
- _o = T.upsert(cg, "任务 名(一)", plan="探针")
111
- check("A7 归一化透明(原名与 slug 同返,不静默改名)",
112
- _o.get("ok") and _o.get("slug_normalized") == "任务-名-一"
113
- and _o.get("node_id") == "task_任务-名-一", _o)
114
-
115
- # ---------------- B. 创建与读回(结构层定位) ----------------
116
- print("\n[B] 创建与读回:structural 层一等节点")
117
- r = T.upsert(cg, NAME, goal="消除 AI 四症状失忆",
118
- plan="1) 建 tasks.py 2) 接 MCP 3) 会话段 4) 测试",
119
- acceptance="四症状逐条有对位断言", boundary="不动 LAYERS",
120
- condition="有跨会话任务台账需求")
121
- check("B1 首次登记建卡成功", r.get("ok") is True and r.get("created") is True, r)
122
- g = T.get_task(cg, nid)
123
- _idx = cg.index["nodes"].get(nid) or {} # 层/权重以索引真源为准
124
- check("B2 读回六要素齐备(CCG 骨架)",
125
- g.get("goal") and g.get("plan") and g.get("acceptance")
126
- and g.get("boundary") and g.get("condition"), g)
127
- check("B3 落盘层=structural(使用者指定位置,不新增层)",
128
- _idx.get("layer") == "structural", _idx.get("layer"))
129
- check("B4 标签含 task 与 task:<slug>(可反向关联)",
130
- T.TASK_TAG in g.get("tags", []) and ("task:" + NAME) in g.get("tags", []),
131
- g.get("tags"))
132
- check("B5 重要性 0.8(进入写保护域,不可被随意覆写)",
133
- abs(float(_idx.get("importance") or 0) - T.DEFAULT_IMPORTANCE) < 1e-9,
134
- _idx.get("importance"))
135
- check("B6 状态缺省 active", g.get("status") == "active", g.get("status"))
136
-
137
- # ---------------- C. 幂等:同 slug 即同任务(症状④ 的机制解) ----------------
138
- print("\n[C] 幂等:同 slug 走同一节点更新,不新建卡")
139
- _before = len(_task_nodes(cg))
140
- r2 = T.upsert(cg, NAME, plan="1) 建 tasks.py 2) 接 MCP 3) 会话段 4) 测试(已更新)")
141
- check("C1 重复登记不新建卡(created=False)",
142
- r2.get("ok") is True and r2.get("created") is False, r2)
143
- check("C2 节点数不变(换表述不产生新任务)",
144
- len(_task_nodes(cg)) == _before, _task_nodes(cg))
145
- g2 = T.get_task(cg, nid)
146
- check("C3 未提供字段沿用旧值(goal 未被清空)",
147
- g2.get("goal") == "消除 AI 四症状失忆", g2.get("goal"))
148
- check("C4 已提供字段被覆盖(plan 更新生效)",
149
- "(已更新)" in (g2.get("plan") or ""), g2.get("plan"))
150
- check("C5 与 goals 不双写(任务走自有状态机,不依赖 goal_ 节点)",
151
- not [n for n in cg.index["nodes"] if n.startswith("goal_")],
152
- [n for n in cg.index["nodes"] if n.startswith("goal_")])
153
-
154
- # ---------------- D. 结果不可被静默清空 ----------------
155
- print("\n[D] 结果维护:不可静默清空")
156
- T.upsert(cg, NAME, result="首版结果:tasks.py 骨架落地")
157
- check("D1 结果可写入",
158
- "首版结果" in (T.get_task(cg, nid).get("result") or ""),
159
- T.get_task(cg, nid).get("result"))
160
- T.upsert(cg, NAME, note="仅改进度,不碰结果")
161
- check("D2 本次不带 result → 旧结果保留(非清空)",
162
- "首版结果" in (T.get_task(cg, nid).get("result") or ""),
163
- T.get_task(cg, nid).get("result"))
164
- T.upsert(cg, NAME, result="")
165
- check("D3 空串视为未提供 → 仍保留旧结果",
166
- "首版结果" in (T.get_task(cg, nid).get("result") or ""),
167
- T.get_task(cg, nid).get("result"))
168
-
169
- # ---------------- E. done 结果必填闸(症状③ 缺核验) ----------------
170
- print("\n[E] 完成闸:done 无结果拒收,缺一不收")
171
- e1 = T.upsert(cg, NAME4, status="done")
172
- check("E1 新任务直接 done 且无结果 → 拒收",
173
- bool(e1) and e1.get("ok") is False and "结果" in (e1.get("error") or ""), e1)
174
- check("E1b 拒收不留半成品节点(盘上无残留)",
175
- T.task_node_id(NAME4) not in cg.index["nodes"])
176
- T.upsert(cg, NAME2, goal="验证完成闸", plan="1) 造 active 卡 2) 裸转 done")
177
- n2 = T.task_node_id(NAME2)
178
- _c_before = (cg.get(n2) or {}).get("content") or ""
179
- e2 = T.set_status(cg, n2, "done")
180
- check("E2 已有任务裸转 done(无结果)→ 拒收",
181
- bool(e2) and e2.get("ok") is False, e2)
182
- _c_after = (cg.get(n2) or {}).get("content") or ""
183
- check("E2b 拒收后盘上内容逐字节不变(拒绝不是软提示)",
184
- hashlib.md5(_c_before.encode("utf-8")).hexdigest()
185
- == hashlib.md5(_c_after.encode("utf-8")).hexdigest())
186
- check("E2c 状态未被偷偷推进(仍 active)",
187
- T.get_task(cg, n2).get("status") == "active",
188
- T.get_task(cg, n2).get("status"))
189
- e3 = T.set_status(cg, n2, "done", result="已交付:完成闸 41 断言全绿")
190
- check("E3 带结果转 done → 通过",
191
- bool(e3) and e3.get("ok") is True, e3)
192
- check("E3b 状态落盘 done 且结果可检索",
193
- T.get_task(cg, n2).get("status") == "done"
194
- and "已交付" in (T.get_task(cg, n2).get("result") or ""),
195
- T.get_task(cg, n2).get("status"))
196
-
197
- # ---------------- F. 计划覆盖 + 计划变更累积(症状②) ----------------
198
- print("\n[F] 计划与变更:计划覆盖、变更累积")
199
- T.upsert(cg, NAME, plan="1) 建模块 2) 接 MCP 3) 会话段 4) 测试 5) 归档")
200
- check("F1 计划每轮覆盖更新(当前态唯一)",
201
- "5) 归档" in (T.get_task(cg, nid).get("plan") or ""),
202
- T.get_task(cg, nid).get("plan"))
203
- f2 = T.plan_add(cg, nid, "发现 add 是全量重建 fm,需先读旧 fm 再合并")
204
- check("F2 计划变更可追加(变更记入独立节)",
205
- bool(f2) and f2.get("ok") is True, f2)
206
- T.plan_add(cg, nid, "MCP 面 action 推导顺序调整:写意图优先于读意图")
207
- ch = T.get_task(cg, nid).get("changes") or ""
208
- check("F3 变更逐轮累积(两轮 = 两行,差异可追溯)",
209
- ch.count("- [") == 2, ch)
210
- check("F4 变更不覆盖计划(两节独立)",
211
- "5) 归档" in (T.get_task(cg, nid).get("plan") or ""), ch)
212
- _empty = T.plan_add(cg, nid, " ")
213
- check("F5 空变更拒收(不写空行噪声)",
214
- bool(_empty) and _empty.get("ok") is False, _empty)
215
-
216
- # ---------------- G. 状态机 ----------------
217
- print("\n[G] 状态机:四态可切换,未知态拒收")
218
- T.upsert(cg, NAME3, goal="MCP 面探针", plan="1) 推导 2) 冒烟")
219
- n3 = T.task_node_id(NAME3)
220
- check("G1 blocked 可切换",
221
- T.set_status(cg, n3, "blocked").get("ok") is True
222
- and T.get_task(cg, n3).get("status") == "blocked")
223
- T.set_status(cg, n3, "active")
224
- _bad = T.set_status(cg, n3, "moving")
225
- check("G2 未知状态拒收(状态机封闭)",
226
- bool(_bad) and _bad.get("ok") is False, _bad)
227
-
228
- # ---------------- H. 会话装配(症状① 的机制解) ----------------
229
- print("\n[H] 会话召回:带出进行中与近期完成,跨会话可见")
230
- st = T.session_tasks(cg)
231
- check("H1 进行中任务被带出(忘记已实现的解)",
232
- any(t["name"] == NAME for t in st["active"]), [t["name"] for t in st["active"]])
233
- check("H2 近期完成单列且带结果摘要",
234
- any(t["name"] == NAME2 and t.get("result") for t in st["done"]),
235
- st["done"])
236
- _other = MdCGSecure(_root, principal=Principal(
237
- actor="task_test_other", role="designer", can_write=True, can_admin=True,
238
- ops_allow=["*"], layers_allow=["*"], session="sess_other"))
239
- check("H3 换会话(新 Principal 同 root)仍带出任务(工程台账跨会话)",
240
- any(t["name"] == NAME
241
- for t in _other.session_recall()["tasks"]["active"]))
242
- check("H3b session_tasks 无 session 形参(设计:台账不按会话切分)",
243
- "session" not in inspect.signature(T.session_tasks).parameters,
244
- list(inspect.signature(T.session_tasks).parameters))
245
- pack = cg.session_recall()
246
- check("H4 session_recall 含 tasks 段(上下文装配面已接)",
247
- "tasks" in pack and any(t["name"] == NAME for t in pack["tasks"]["active"]),
248
- list(pack.get("tasks", {}).get("active", []))[:2])
249
- check("H5 预算裁剪上报字段在位(任务段最后让位)",
250
- "tasks_truncated" in pack, sorted(pack.keys()))
251
- check("H6 done 任务不进进行中段(不冒充未完成)",
252
- all(t["name"] != NAME2 for t in st["active"]),
253
- [t["name"] for t in st["active"]])
254
-
255
- # ---------------- I. 同族提示(只提示,不合并) ----------------
256
- print("\n[I] 同族提示:由人裁决,不自动合并")
257
- s_exact = T.find_similar(cg, NAME)
258
- check("I1 完全同名可判别(exists=True,防重复开工)",
259
- s_exact.get("exists") is True, s_exact)
260
- _cnt_before = len(_task_nodes(cg))
261
- s_near = T.find_similar(cg, NAME + "-续")
262
- check("I2 近名给出疑似同族(提示面可用)",
263
- isinstance(s_near.get("similar"), list), s_near)
264
- check("I3 提示不改盘(同族绝不自动合并)",
265
- len(_task_nodes(cg)) == _cnt_before, _task_nodes(cg))
266
- s_new = T.find_similar(cg, "完全无关的新任务-xyz")
267
- check("I4 全新名不误报同族(exists=False)",
268
- s_new.get("exists") is False, s_new)
269
-
270
- # ---------------- J. 边界:串号 / 检索 / 反向关联 ----------------
271
- print("\n[J] 边界:串号防护、检索面、知识反向关联")
272
- cg.add("trait_probe", "非任务的结构层节点(探针)", layer="structural",
273
- verification_basis="other", consistency=False, tags=["trait"])
274
- check("J1 非任务 structural 节点不混入清单(层内串号防护)",
275
- all(t["id"] != "trait_probe" for t in T.list_tasks(cg)["tasks"]),
276
- [t["id"] for t in T.list_tasks(cg)["tasks"]])
277
- _ids = _hits(cg, NAME, layer="structural")
278
- check("J2 任务节点在 structural 层可被检索(按需调用面)",
279
- nid in _ids, _ids)
280
- cg.add("kp_task_rel", "任务相关知识:四症状的机制解与验收判据",
281
- layer="knowledge", verification_basis="test", consistency=False,
282
- tags=["task:" + NAME])
283
- _kp = cg.get("kp_task_rel")
284
- check("J3 任务知识挂 knowledge 层并以 tags 反向关联",
285
- _kp.get("frontmatter", {}).get("layer") == "knowledge"
286
- and ("task:" + NAME) in (_kp.get("frontmatter", {}).get("tags") or []),
287
- _kp.get("frontmatter", {}).get("tags"))
288
- check("J4 任务清单按 layer 过滤(知识节点不入台账)",
289
- all(t["id"] != "kp_task_rel" for t in T.list_tasks(cg)["tasks"]))
290
-
291
- # ---------------- K. 留痕:复用既有审计面 ----------------
292
- print("\n[K] 生命周期留痕:复用 _audit,不新造日志格式")
293
- _seen = []
294
- _orig = cg._audit
295
-
296
- def _spy(op, nid_, **kw):
297
- _seen.append(op)
298
- return _orig(op, nid_, **kw)
299
-
300
- cg._audit = _spy
301
- try:
302
- T.upsert(cg, "审计探针-任务", plan="x")
303
- T.plan_add(cg, T.task_node_id("审计探针-任务"), "变更一行")
304
- finally:
305
- cg._audit = _orig
306
- check("K1 建卡留痕 task_open", "task_open" in _seen, _seen)
307
- check("K2 更新留痕 task_update", "task_update" in _seen, _seen)
308
-
309
- # ---------------- L. MCP 面对位 ----------------
310
- print("\n[L] MCP 面:action 推导不吞写意图 / schema 可传 / 缺省 list")
311
- SIG = M._action_sig
312
- check("L1 task+name → open", SIG({"name": "X"}, "task") == ("open", "name"),
313
- SIG({"name": "X"}, "task"))
314
- check("L2 task+change → plan_add",
315
- SIG({"change": "c"}, "task") == ("plan_add", "change"),
316
- SIG({"change": "c"}, "task"))
317
- check("L3 task+name+change → open(open 兼容 change,写意图不丢)",
318
- SIG({"name": "X", "change": "c"}, "task") == ("open", "name"),
319
- SIG({"name": "X", "change": "c"}, "task"))
320
- check("L4 task+node_id → get",
321
- SIG({"node_id": "task_x"}, "task") == ("get", "node_id"),
322
- SIG({"node_id": "task_x"}, "task"))
323
- check("L5 task+node_id+change → plan_add(写优先于读,不静默当只读)",
324
- SIG({"node_id": "task_x", "change": "c"}, "task") == ("plan_add", "change"),
325
- SIG({"node_id": "task_x", "change": "c"}, "task"))
326
- check("L6 task+task_status → status",
327
- SIG({"task_status": "done"}, "task") == ("status", "task_status"),
328
- SIG({"task_status": "done"}, "task"))
329
- check("L7 task 无签名不猜(交 _ACTION_DEFAULT 承接)",
330
- SIG({}, "task") == (None, None), SIG({}, "task"))
331
- check("L8 _ACTION_DEFAULT['task'] == 'list'",
332
- M._ACTION_DEFAULT.get("task") == "list", M._ACTION_DEFAULT.get("task"))
333
- _src = open(os.path.join(_HERE, "mcp_server.py"), encoding="utf-8").read()
334
- _vals = set(re.findall(r'a\.get\("action"\)\s*or\s*"([a-z_]+)"', _src))
335
- check("L9 缺省字面量在源码真实存在(防幻影表)", "list" in _vals, sorted(_vals))
336
-
337
- out = M._cg_call(cg, {"op": "task", "name": NAME3, "plan": "1) 推导 2) 冒烟"})
338
- check("L10 op=task 缺 action → 推导 open 且透出(不静默)",
339
- out.get("ok") is True and out.get("action_derived") is True
340
- and out.get("action") == "open", out)
341
-
342
- def _chg():
343
- _g = M._cg_call(cg, {"op": "task", "action": "get", "node_id": n3})
344
- return _g.get("changes") or ""
345
-
346
- _c_before = _chg()
347
- out2 = M._cg_call(cg, {"op": "task", "node_id": n3, "change": "MCP 面追加一行"})
348
- check("L11 node_id+change 真实落盘(写意图未被吞)",
349
- out2.get("ok") is True and _chg().count("- [") == _c_before.count("- [") + 1,
350
- out2)
351
-
352
- out3 = M._cg_call(cg, {"op": "task"})
353
- check("L12 无签名 → 缺省 list 且透出 action_derived",
354
- out3.get("action_derived") is True and out3.get("action") == "list"
355
- and bool(out3.get("tasks")) is True, out3)
356
- out4 = M._cg_call(cg, {"op": "task", "action": "nope", "name": NAME})
357
- check("L13 未知 action fail-closed(返回 error,不静默降级)",
358
- out4.get("ok") is False and bool(out4.get("error")), out4)
359
- out5 = M._cg_call(cg, {"op": "task", "action": "session"})
360
- check("L14 action=session 会话装配面可经 MCP 取用",
361
- out5.get("ok") is True and bool(out5.get("active")), out5)
362
- out6 = M._cg_call(cg, {"op": "task", "action": "find", "name": NAME})
363
- check("L15 action=find 同族提示可经 MCP 取用",
364
- out6.get("ok") is True, out6)
365
-
366
- _tool = [t for t in M.KERNEL_TOOLS if t.get("name") == "cg"][0]
367
- _props = _tool["inputSchema"]["properties"]
368
- check("L16 op 枚举含 task(客户端可见面同步)",
369
- "task" in [x.strip() for x in _props["op"]["description"].split("|")])
370
- _miss = [k for k in ("plan", "result", "task_status", "acceptance", "boundary",
371
- "active_limit", "done_limit") if k not in _props]
372
- check("L17 cg schema 已声明 task 参数(客户端传得进来)", not _miss, _miss)
373
- check("L18 tokens.ALL_OPS 含 task(跨面真源同步)",
374
- "task" in TK.ALL_OPS, [o for o in TK.ALL_OPS if o == "task"])
375
-
376
- # ---------------- M. 权限闸 ----------------
377
- print("\n[M] 权限闸:写权限不够则拒,角色白名单同步")
378
- _guest = MdCGSecure(os.path.join(tmp, "guest_root"),
379
- principal=Principal(actor="guest1", role="guest",
380
- can_write=False, can_admin=False))
381
- _ge = _raises(lambda: T.upsert(_guest, NAME5, plan="x"))
382
- check("M1 无写权限角色写任务被拒(权限闸不可绕)",
383
- isinstance(_ge, AccessDenied), _ge)
384
- _rec = TK.ROLE_SPECS["record"]
385
- check("M2 record 角色 ops 白名单含 task 且可写 structural 层",
386
- "task" in _rec["ops_allow"] and "structural" in _rec["layers_allow"],
387
- (_rec["ops_allow"], _rec["layers_allow"]))
388
- _owner = Principal(actor="owner", role="designer", can_write=True,
389
- can_admin=True, ops_allow=["*"], layers_allow=["*"])
390
- _narrow = TK.narrowed_principal(_owner, "record")
391
- check("M3 收窄身份(记录单元)可执行 task(本职:保存过程与结果)",
392
- _narrow.allows_op("task") is True, _narrow.ops_allow)
393
- _rcg = MdCGSecure(os.path.join(tmp, "record_root"), principal=_narrow)
394
- _ro = T.upsert(_rcg, "记录单元-任务探针", plan="x")
395
- check("M4 收窄身份真实落盘成功(端到端)", _ro.get("ok") is True, _ro)
396
- finally:
397
- shutil.rmtree(tmp, ignore_errors=True)
398
-
399
- print("\n%s %d 项断言,%d 失败" % ("ALL GREEN" if not _fails else "FAILED",
400
- _n[0], len(_fails)))
401
- if _fails:
402
- for f in _fails:
403
- print(" - %s" % f)
404
- return 1
405
- return 0
406
-
407
-
408
- if __name__ == "__main__":
409
- sys.exit(main())
1
+ # -*- coding: utf-8 -*-
2
+ """结构层任务实体(md_cg/tasks.py)验收矩阵(2026-09-16)。
3
+
4
+ 蓝图=消除 AI 失忆四症状,断言按症状逐条对位:
5
+
6
+ ① 忘记已实现的工程 → H 组:session_tasks / session_recall 任务段,
7
+ 且**不按 session 过滤**(工程台账跨会话可见,这正是失忆的解)
8
+ ② 计划与实际不符 → F 组:计划每轮覆盖更新 + 「计划变更」节逐轮累积
9
+ ③ 缺核验 → E 组:done 时结果必填闸(缺一不收),拒收后**盘上内容逐字节不变**
10
+ ④ 换表述即新任务 → A/C/I 组:身份=语义 slug(非内容哈希);同 slug 幂等更新
11
+ 不新增节点;同族只提示、不自动合并
12
+
13
+ 另含 MCP 面对位(L 组:action 推导不吞写意图 / schema 参数声明 / 缺省 list 冒烟 /
14
+ 未知 action fail-closed)与边界(J 组:串号防护、检索面、反向关联;M 组:权限闸)。
15
+ 脚本式 assert + 退出码,风格与 test_branches.py / test_action_derive.py 一致。
16
+ """
17
+
18
+ import os
19
+ import re
20
+ import sys
21
+ import shutil
22
+ import inspect
23
+ import tempfile
24
+ import hashlib
25
+
26
+ _HERE = os.path.dirname(os.path.abspath(__file__))
27
+ _REPO = os.path.dirname(_HERE)
28
+ if _REPO not in sys.path:
29
+ sys.path.insert(0, _REPO)
30
+
31
+ try:
32
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
33
+ except Exception:
34
+ pass
35
+
36
+ from md_cg import mcp_server as M
37
+ from md_cg import tasks as T
38
+ from md_cg import tokens as TK
39
+ from md_cg.mdcos import MdCGSecure
40
+ from md_cg.security import Principal, AccessDenied
41
+
42
+ # 语料命名(互不串扰,各症状用独立任务名)
43
+ NAME = "记忆失忆修复-工程"
44
+ NAME2 = "任务实体-done闸探针"
45
+ NAME3 = "mcp面-任务探针"
46
+ NAME4 = "任务-未开先done"
47
+ NAME5 = "越权任务"
48
+
49
+ _fails = []
50
+ _n = [0]
51
+
52
+
53
+ def check(name, cond, detail=None):
54
+ _n[0] += 1
55
+ if cond:
56
+ print(" ok %s" % name)
57
+ else:
58
+ print("FAIL %s %r" % (name, detail))
59
+ _fails.append(name)
60
+
61
+
62
+ def _raises(fn):
63
+ try:
64
+ fn()
65
+ except Exception as e: # noqa: BLE001 —— 测试需拿到任何异常作证据
66
+ return e
67
+ return None
68
+
69
+
70
+ def _mk_cg(root, **kw):
71
+ p = Principal(actor="task_test", role="designer", can_write=True, can_admin=True,
72
+ ops_allow=["*"], layers_allow=["*"], **kw)
73
+ return MdCGSecure(root, principal=p)
74
+
75
+
76
+ def _task_nodes(cg):
77
+ return sorted(n for n in cg.index["nodes"] if n.startswith(T.TASK_PREFIX))
78
+
79
+
80
+ def _hits(cg, q, **kw):
81
+ res, _meta = cg.search(q, **kw)
82
+ return [h[0].get("id") for h in res]
83
+
84
+
85
+ def main():
86
+ tmp = tempfile.mkdtemp(prefix="mdcg_tasks_")
87
+ try:
88
+ _root = os.path.join(tmp, "root")
89
+ cg = _mk_cg(_root)
90
+ nid = T.task_node_id(NAME)
91
+
92
+ # ---------------- A. 身份判据=语义 slug(症状④ 的根) ----------------
93
+ print("\n[A] 身份判据:语义 slug,非内容哈希")
94
+ check("A1 中文名原样保留(语义身份可读)",
95
+ T.slugify(NAME) == NAME, T.slugify(NAME))
96
+ check("A2 路径分隔符折叠(防目录穿越)",
97
+ T.slugify("a/b\\c") == "a-b-c", T.slugify("a/b\\c"))
98
+ _trav = T.slugify("../../etc/passwd")
99
+ check("A3 `..` 与 `/` 全部折叠,不留穿越形态",
100
+ ".." not in _trav and "/" not in _trav and "\\" not in _trav, _trav)
101
+ check("A4 空白/纯符号名拒收(无身份不建卡)",
102
+ T.task_node_id(" ") is None or T.slugify(" ") == "", T.slugify(" "))
103
+ check("A4b 纯符号名 slug 为空", T.slugify("!!!") == "", T.slugify("!!!"))
104
+ check("A5 已带前缀不重复叠(task_x → task_x)",
105
+ T.task_node_id("task_x") == "task_x" == T.task_node_id("x"),
106
+ (T.task_node_id("task_x"), T.task_node_id("x")))
107
+ check("A6 超长名截断(≥64 上限护栏)",
108
+ len(T.task_node_id("a" * 200)) <= len(T.TASK_PREFIX) + 64,
109
+ len(T.task_node_id("a" * 200)))
110
+ _o = T.upsert(cg, "任务 名(一)", plan="探针")
111
+ check("A7 归一化透明(原名与 slug 同返,不静默改名)",
112
+ _o.get("ok") and _o.get("slug_normalized") == "任务-名-一"
113
+ and _o.get("node_id") == "task_任务-名-一", _o)
114
+
115
+ # ---------------- B. 创建与读回(结构层定位) ----------------
116
+ print("\n[B] 创建与读回:structural 层一等节点")
117
+ r = T.upsert(cg, NAME, goal="消除 AI 四症状失忆",
118
+ plan="1) 建 tasks.py 2) 接 MCP 3) 会话段 4) 测试",
119
+ acceptance="四症状逐条有对位断言", boundary="不动 LAYERS",
120
+ condition="有跨会话任务台账需求")
121
+ check("B1 首次登记建卡成功", r.get("ok") is True and r.get("created") is True, r)
122
+ g = T.get_task(cg, nid)
123
+ _idx = cg.index["nodes"].get(nid) or {} # 层/权重以索引真源为准
124
+ check("B2 读回六要素齐备(CCG 骨架)",
125
+ g.get("goal") and g.get("plan") and g.get("acceptance")
126
+ and g.get("boundary") and g.get("condition"), g)
127
+ check("B3 落盘层=structural(使用者指定位置,不新增层)",
128
+ _idx.get("layer") == "structural", _idx.get("layer"))
129
+ check("B4 标签含 task 与 task:<slug>(可反向关联)",
130
+ T.TASK_TAG in g.get("tags", []) and ("task:" + NAME) in g.get("tags", []),
131
+ g.get("tags"))
132
+ check("B5 重要性 0.8(进入写保护域,不可被随意覆写)",
133
+ abs(float(_idx.get("importance") or 0) - T.DEFAULT_IMPORTANCE) < 1e-9,
134
+ _idx.get("importance"))
135
+ check("B6 状态缺省 active", g.get("status") == "active", g.get("status"))
136
+
137
+ # ---------------- C. 幂等:同 slug 即同任务(症状④ 的机制解) ----------------
138
+ print("\n[C] 幂等:同 slug 走同一节点更新,不新建卡")
139
+ _before = len(_task_nodes(cg))
140
+ r2 = T.upsert(cg, NAME, plan="1) 建 tasks.py 2) 接 MCP 3) 会话段 4) 测试(已更新)")
141
+ check("C1 重复登记不新建卡(created=False)",
142
+ r2.get("ok") is True and r2.get("created") is False, r2)
143
+ check("C2 节点数不变(换表述不产生新任务)",
144
+ len(_task_nodes(cg)) == _before, _task_nodes(cg))
145
+ g2 = T.get_task(cg, nid)
146
+ check("C3 未提供字段沿用旧值(goal 未被清空)",
147
+ g2.get("goal") == "消除 AI 四症状失忆", g2.get("goal"))
148
+ check("C4 已提供字段被覆盖(plan 更新生效)",
149
+ "(已更新)" in (g2.get("plan") or ""), g2.get("plan"))
150
+ check("C5 与 goals 不双写(任务走自有状态机,不依赖 goal_ 节点)",
151
+ not [n for n in cg.index["nodes"] if n.startswith("goal_")],
152
+ [n for n in cg.index["nodes"] if n.startswith("goal_")])
153
+
154
+ # ---------------- D. 结果不可被静默清空 ----------------
155
+ print("\n[D] 结果维护:不可静默清空")
156
+ T.upsert(cg, NAME, result="首版结果:tasks.py 骨架落地")
157
+ check("D1 结果可写入",
158
+ "首版结果" in (T.get_task(cg, nid).get("result") or ""),
159
+ T.get_task(cg, nid).get("result"))
160
+ T.upsert(cg, NAME, note="仅改进度,不碰结果")
161
+ check("D2 本次不带 result → 旧结果保留(非清空)",
162
+ "首版结果" in (T.get_task(cg, nid).get("result") or ""),
163
+ T.get_task(cg, nid).get("result"))
164
+ T.upsert(cg, NAME, result="")
165
+ check("D3 空串视为未提供 → 仍保留旧结果",
166
+ "首版结果" in (T.get_task(cg, nid).get("result") or ""),
167
+ T.get_task(cg, nid).get("result"))
168
+
169
+ # ---------------- E. done 结果必填闸(症状③ 缺核验) ----------------
170
+ print("\n[E] 完成闸:done 无结果拒收,缺一不收")
171
+ e1 = T.upsert(cg, NAME4, status="done")
172
+ check("E1 新任务直接 done 且无结果 → 拒收",
173
+ bool(e1) and e1.get("ok") is False and "结果" in (e1.get("error") or ""), e1)
174
+ check("E1b 拒收不留半成品节点(盘上无残留)",
175
+ T.task_node_id(NAME4) not in cg.index["nodes"])
176
+ T.upsert(cg, NAME2, goal="验证完成闸", plan="1) 造 active 卡 2) 裸转 done")
177
+ n2 = T.task_node_id(NAME2)
178
+ _c_before = (cg.get(n2) or {}).get("content") or ""
179
+ e2 = T.set_status(cg, n2, "done")
180
+ check("E2 已有任务裸转 done(无结果)→ 拒收",
181
+ bool(e2) and e2.get("ok") is False, e2)
182
+ _c_after = (cg.get(n2) or {}).get("content") or ""
183
+ check("E2b 拒收后盘上内容逐字节不变(拒绝不是软提示)",
184
+ hashlib.md5(_c_before.encode("utf-8")).hexdigest()
185
+ == hashlib.md5(_c_after.encode("utf-8")).hexdigest())
186
+ check("E2c 状态未被偷偷推进(仍 active)",
187
+ T.get_task(cg, n2).get("status") == "active",
188
+ T.get_task(cg, n2).get("status"))
189
+ e3 = T.set_status(cg, n2, "done", result="已交付:完成闸 41 断言全绿")
190
+ check("E3 带结果转 done → 通过",
191
+ bool(e3) and e3.get("ok") is True, e3)
192
+ check("E3b 状态落盘 done 且结果可检索",
193
+ T.get_task(cg, n2).get("status") == "done"
194
+ and "已交付" in (T.get_task(cg, n2).get("result") or ""),
195
+ T.get_task(cg, n2).get("status"))
196
+
197
+ # ---------------- F. 计划覆盖 + 计划变更累积(症状②) ----------------
198
+ print("\n[F] 计划与变更:计划覆盖、变更累积")
199
+ T.upsert(cg, NAME, plan="1) 建模块 2) 接 MCP 3) 会话段 4) 测试 5) 归档")
200
+ check("F1 计划每轮覆盖更新(当前态唯一)",
201
+ "5) 归档" in (T.get_task(cg, nid).get("plan") or ""),
202
+ T.get_task(cg, nid).get("plan"))
203
+ f2 = T.plan_add(cg, nid, "发现 add 是全量重建 fm,需先读旧 fm 再合并")
204
+ check("F2 计划变更可追加(变更记入独立节)",
205
+ bool(f2) and f2.get("ok") is True, f2)
206
+ T.plan_add(cg, nid, "MCP 面 action 推导顺序调整:写意图优先于读意图")
207
+ ch = T.get_task(cg, nid).get("changes") or ""
208
+ check("F3 变更逐轮累积(两轮 = 两行,差异可追溯)",
209
+ ch.count("- [") == 2, ch)
210
+ check("F4 变更不覆盖计划(两节独立)",
211
+ "5) 归档" in (T.get_task(cg, nid).get("plan") or ""), ch)
212
+ _empty = T.plan_add(cg, nid, " ")
213
+ check("F5 空变更拒收(不写空行噪声)",
214
+ bool(_empty) and _empty.get("ok") is False, _empty)
215
+
216
+ # ---------------- G. 状态机 ----------------
217
+ print("\n[G] 状态机:四态可切换,未知态拒收")
218
+ T.upsert(cg, NAME3, goal="MCP 面探针", plan="1) 推导 2) 冒烟")
219
+ n3 = T.task_node_id(NAME3)
220
+ check("G1 blocked 可切换",
221
+ T.set_status(cg, n3, "blocked").get("ok") is True
222
+ and T.get_task(cg, n3).get("status") == "blocked")
223
+ T.set_status(cg, n3, "active")
224
+ _bad = T.set_status(cg, n3, "moving")
225
+ check("G2 未知状态拒收(状态机封闭)",
226
+ bool(_bad) and _bad.get("ok") is False, _bad)
227
+
228
+ # ---------------- H. 会话装配(症状① 的机制解) ----------------
229
+ print("\n[H] 会话召回:带出进行中与近期完成,跨会话可见")
230
+ st = T.session_tasks(cg)
231
+ check("H1 进行中任务被带出(忘记已实现的解)",
232
+ any(t["name"] == NAME for t in st["active"]), [t["name"] for t in st["active"]])
233
+ check("H2 近期完成单列且带结果摘要",
234
+ any(t["name"] == NAME2 and t.get("result") for t in st["done"]),
235
+ st["done"])
236
+ _other = MdCGSecure(_root, principal=Principal(
237
+ actor="task_test_other", role="designer", can_write=True, can_admin=True,
238
+ ops_allow=["*"], layers_allow=["*"], session="sess_other"))
239
+ check("H3 换会话(新 Principal 同 root)仍带出任务(工程台账跨会话)",
240
+ any(t["name"] == NAME
241
+ for t in _other.session_recall()["tasks"]["active"]))
242
+ check("H3b session_tasks 无 session 形参(设计:台账不按会话切分)",
243
+ "session" not in inspect.signature(T.session_tasks).parameters,
244
+ list(inspect.signature(T.session_tasks).parameters))
245
+ pack = cg.session_recall()
246
+ check("H4 session_recall 含 tasks 段(上下文装配面已接)",
247
+ "tasks" in pack and any(t["name"] == NAME for t in pack["tasks"]["active"]),
248
+ list(pack.get("tasks", {}).get("active", []))[:2])
249
+ check("H5 预算裁剪上报字段在位(任务段最后让位)",
250
+ "tasks_truncated" in pack, sorted(pack.keys()))
251
+ check("H6 done 任务不进进行中段(不冒充未完成)",
252
+ all(t["name"] != NAME2 for t in st["active"]),
253
+ [t["name"] for t in st["active"]])
254
+
255
+ # ---------------- I. 同族提示(只提示,不合并) ----------------
256
+ print("\n[I] 同族提示:由人裁决,不自动合并")
257
+ s_exact = T.find_similar(cg, NAME)
258
+ check("I1 完全同名可判别(exists=True,防重复开工)",
259
+ s_exact.get("exists") is True, s_exact)
260
+ _cnt_before = len(_task_nodes(cg))
261
+ s_near = T.find_similar(cg, NAME + "-续")
262
+ check("I2 近名给出疑似同族(提示面可用)",
263
+ isinstance(s_near.get("similar"), list), s_near)
264
+ check("I3 提示不改盘(同族绝不自动合并)",
265
+ len(_task_nodes(cg)) == _cnt_before, _task_nodes(cg))
266
+ s_new = T.find_similar(cg, "完全无关的新任务-xyz")
267
+ check("I4 全新名不误报同族(exists=False)",
268
+ s_new.get("exists") is False, s_new)
269
+
270
+ # ---------------- J. 边界:串号 / 检索 / 反向关联 ----------------
271
+ print("\n[J] 边界:串号防护、检索面、知识反向关联")
272
+ cg.add("trait_probe", "非任务的结构层节点(探针)", layer="structural",
273
+ verification_basis="other", consistency=False, tags=["trait"])
274
+ check("J1 非任务 structural 节点不混入清单(层内串号防护)",
275
+ all(t["id"] != "trait_probe" for t in T.list_tasks(cg)["tasks"]),
276
+ [t["id"] for t in T.list_tasks(cg)["tasks"]])
277
+ _ids = _hits(cg, NAME, layer="structural")
278
+ check("J2 任务节点在 structural 层可被检索(按需调用面)",
279
+ nid in _ids, _ids)
280
+ cg.add("kp_task_rel", "任务相关知识:四症状的机制解与验收判据",
281
+ layer="knowledge", verification_basis="test", consistency=False,
282
+ tags=["task:" + NAME])
283
+ _kp = cg.get("kp_task_rel")
284
+ check("J3 任务知识挂 knowledge 层并以 tags 反向关联",
285
+ _kp.get("frontmatter", {}).get("layer") == "knowledge"
286
+ and ("task:" + NAME) in (_kp.get("frontmatter", {}).get("tags") or []),
287
+ _kp.get("frontmatter", {}).get("tags"))
288
+ check("J4 任务清单按 layer 过滤(知识节点不入台账)",
289
+ all(t["id"] != "kp_task_rel" for t in T.list_tasks(cg)["tasks"]))
290
+
291
+ # ---------------- K. 留痕:复用既有审计面 ----------------
292
+ print("\n[K] 生命周期留痕:复用 _audit,不新造日志格式")
293
+ _seen = []
294
+ _orig = cg._audit
295
+
296
+ def _spy(op, nid_, **kw):
297
+ _seen.append(op)
298
+ return _orig(op, nid_, **kw)
299
+
300
+ cg._audit = _spy
301
+ try:
302
+ T.upsert(cg, "审计探针-任务", plan="x")
303
+ T.plan_add(cg, T.task_node_id("审计探针-任务"), "变更一行")
304
+ finally:
305
+ cg._audit = _orig
306
+ check("K1 建卡留痕 task_open", "task_open" in _seen, _seen)
307
+ check("K2 更新留痕 task_update", "task_update" in _seen, _seen)
308
+
309
+ # ---------------- L. MCP 面对位 ----------------
310
+ print("\n[L] MCP 面:action 推导不吞写意图 / schema 可传 / 缺省 list")
311
+ SIG = M._action_sig
312
+ check("L1 task+name → open", SIG({"name": "X"}, "task") == ("open", "name"),
313
+ SIG({"name": "X"}, "task"))
314
+ check("L2 task+change → plan_add",
315
+ SIG({"change": "c"}, "task") == ("plan_add", "change"),
316
+ SIG({"change": "c"}, "task"))
317
+ check("L3 task+name+change → open(open 兼容 change,写意图不丢)",
318
+ SIG({"name": "X", "change": "c"}, "task") == ("open", "name"),
319
+ SIG({"name": "X", "change": "c"}, "task"))
320
+ check("L4 task+node_id → get",
321
+ SIG({"node_id": "task_x"}, "task") == ("get", "node_id"),
322
+ SIG({"node_id": "task_x"}, "task"))
323
+ check("L5 task+node_id+change → plan_add(写优先于读,不静默当只读)",
324
+ SIG({"node_id": "task_x", "change": "c"}, "task") == ("plan_add", "change"),
325
+ SIG({"node_id": "task_x", "change": "c"}, "task"))
326
+ check("L6 task+task_status → status",
327
+ SIG({"task_status": "done"}, "task") == ("status", "task_status"),
328
+ SIG({"task_status": "done"}, "task"))
329
+ check("L7 task 无签名不猜(交 _ACTION_DEFAULT 承接)",
330
+ SIG({}, "task") == (None, None), SIG({}, "task"))
331
+ check("L8 _ACTION_DEFAULT['task'] == 'list'",
332
+ M._ACTION_DEFAULT.get("task") == "list", M._ACTION_DEFAULT.get("task"))
333
+ _src = open(os.path.join(_HERE, "mcp_server.py"), encoding="utf-8").read()
334
+ _vals = set(re.findall(r'a\.get\("action"\)\s*or\s*"([a-z_]+)"', _src))
335
+ check("L9 缺省字面量在源码真实存在(防幻影表)", "list" in _vals, sorted(_vals))
336
+
337
+ out = M._cg_call(cg, {"op": "task", "name": NAME3, "plan": "1) 推导 2) 冒烟"})
338
+ check("L10 op=task 缺 action → 推导 open 且透出(不静默)",
339
+ out.get("ok") is True and out.get("action_derived") is True
340
+ and out.get("action") == "open", out)
341
+
342
+ def _chg():
343
+ _g = M._cg_call(cg, {"op": "task", "action": "get", "node_id": n3})
344
+ return _g.get("changes") or ""
345
+
346
+ _c_before = _chg()
347
+ out2 = M._cg_call(cg, {"op": "task", "node_id": n3, "change": "MCP 面追加一行"})
348
+ check("L11 node_id+change 真实落盘(写意图未被吞)",
349
+ out2.get("ok") is True and _chg().count("- [") == _c_before.count("- [") + 1,
350
+ out2)
351
+
352
+ out3 = M._cg_call(cg, {"op": "task"})
353
+ check("L12 无签名 → 缺省 list 且透出 action_derived",
354
+ out3.get("action_derived") is True and out3.get("action") == "list"
355
+ and bool(out3.get("tasks")) is True, out3)
356
+ out4 = M._cg_call(cg, {"op": "task", "action": "nope", "name": NAME})
357
+ check("L13 未知 action fail-closed(返回 error,不静默降级)",
358
+ out4.get("ok") is False and bool(out4.get("error")), out4)
359
+ out5 = M._cg_call(cg, {"op": "task", "action": "session"})
360
+ check("L14 action=session 会话装配面可经 MCP 取用",
361
+ out5.get("ok") is True and bool(out5.get("active")), out5)
362
+ out6 = M._cg_call(cg, {"op": "task", "action": "find", "name": NAME})
363
+ check("L15 action=find 同族提示可经 MCP 取用",
364
+ out6.get("ok") is True, out6)
365
+
366
+ _tool = [t for t in M.KERNEL_TOOLS if t.get("name") == "cg"][0]
367
+ _props = _tool["inputSchema"]["properties"]
368
+ check("L16 op 枚举含 task(客户端可见面同步)",
369
+ "task" in [x.strip() for x in _props["op"]["description"].split("|")])
370
+ _miss = [k for k in ("plan", "result", "task_status", "acceptance", "boundary",
371
+ "active_limit", "done_limit") if k not in _props]
372
+ check("L17 cg schema 已声明 task 参数(客户端传得进来)", not _miss, _miss)
373
+ check("L18 tokens.ALL_OPS 含 task(跨面真源同步)",
374
+ "task" in TK.ALL_OPS, [o for o in TK.ALL_OPS if o == "task"])
375
+
376
+ # ---------------- M. 权限闸 ----------------
377
+ print("\n[M] 权限闸:写权限不够则拒,角色白名单同步")
378
+ _guest = MdCGSecure(os.path.join(tmp, "guest_root"),
379
+ principal=Principal(actor="guest1", role="guest",
380
+ can_write=False, can_admin=False))
381
+ _ge = _raises(lambda: T.upsert(_guest, NAME5, plan="x"))
382
+ check("M1 无写权限角色写任务被拒(权限闸不可绕)",
383
+ isinstance(_ge, AccessDenied), _ge)
384
+ _rec = TK.ROLE_SPECS["record"]
385
+ check("M2 record 角色 ops 白名单含 task 且可写 structural 层",
386
+ "task" in _rec["ops_allow"] and "structural" in _rec["layers_allow"],
387
+ (_rec["ops_allow"], _rec["layers_allow"]))
388
+ _owner = Principal(actor="owner", role="designer", can_write=True,
389
+ can_admin=True, ops_allow=["*"], layers_allow=["*"])
390
+ _narrow = TK.narrowed_principal(_owner, "record")
391
+ check("M3 收窄身份(记录单元)可执行 task(本职:保存过程与结果)",
392
+ _narrow.allows_op("task") is True, _narrow.ops_allow)
393
+ _rcg = MdCGSecure(os.path.join(tmp, "record_root"), principal=_narrow)
394
+ _ro = T.upsert(_rcg, "记录单元-任务探针", plan="x")
395
+ check("M4 收窄身份真实落盘成功(端到端)", _ro.get("ok") is True, _ro)
396
+ finally:
397
+ shutil.rmtree(tmp, ignore_errors=True)
398
+
399
+ print("\n%s %d 项断言,%d 失败" % ("ALL GREEN" if not _fails else "FAILED",
400
+ _n[0], len(_fails)))
401
+ if _fails:
402
+ for f in _fails:
403
+ print(" - %s" % f)
404
+ return 1
405
+ return 0
406
+
407
+
408
+ if __name__ == "__main__":
409
+ sys.exit(main())