@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
package/md_cg/security.py CHANGED
@@ -1,275 +1,275 @@
1
- # -*- coding: utf-8 -*-
2
- """md_cg · 进程/权限模型(记忆 OS #2)
3
-
4
- 关键动机:**灵枢是开源仓库,而记忆很大一部分是私有内容**。因此权限模型必须
5
- 支持「公开知识」与「私有记忆」的物理与逻辑隔离:
6
-
7
- ① 物理隔离:租户(tenant)各自一个根目录。public 租户的根可落在开源仓库内,
8
- private 租户的根必须落在仓库外(如 ~/.mdcg/private/)。
9
- ② 逻辑隔离:每个节点带 sensitivity(public < internal < private < secret);
10
- 每个调用方(Principal)带 clearance,只能读写 ≤ clearance 的节点。
11
- ③ 硬规则:secret 节点对 clearance < secret 的调用方**写入即拒**(对齐 noema
12
- 「secret 候选自动拒绝」);写入高于自身 clearance 的敏感度 → 拒绝。
13
-
14
- 零第三方依赖。
15
- """
16
- from __future__ import annotations
17
-
18
- import json
19
- import os
20
- import time
21
- import uuid
22
-
23
- SENSITIVITY_ORDER = ("public", "internal", "private", "secret")
24
- DEFAULT_SENSITIVITY = "internal"
25
-
26
-
27
- class AccessDenied(Exception):
28
- """权限拒绝(读/写/管理)。"""
29
-
30
-
31
- # 生效条件:形参 level 为模块级常量 SENSITIVITY_ORDER 中的元素时返回其下标,否则抛 AccessDenied。
32
- def _rank(level: str) -> int:
33
- try:
34
- return SENSITIVITY_ORDER.index(level)
35
- except ValueError:
36
- raise AccessDenied(f"未知敏感度/密级:{level}") from None
37
-
38
-
39
- # 生效条件:全部形参均可省略、clearance 默认取模块常量 DEFAULT_SENSITIVITY,构造时先经 _rank(clearance) 校验,随后 session 为假值(含空串)回落为 sess_+uuid 十二位、role 假值回落 "system"、expires_at 为假值(含 0)置 None、layers_allow/ops_allow 为 None 时保持 None 否则转 tuple、theory_ok 经 bool() 转换。
40
- class Principal:
41
- """调用方身份(一次会话一个)。
42
-
43
- tenant —— 租户(决定根目录)
44
- actor —— 调用者标识(写入审计)
45
- clearance —— 最高可读/可写敏感度
46
- can_write —— 是否允许写
47
- can_admin —— 是否允许管理操作(forget/restore/review_decide)
48
- session —— 会话 id(进程/会话模型:每次连接一个)
49
- harness —— 承载端标识(dsh/zcode/codebuddy…;仅归因,不参与授权)
50
- unit —— 单元分工(record/reflect/verify/output/sustain;仅归因)
51
- 注:MCP 请求级参数 `as_unit` 会经 `tokens.narrowed_principal`
52
- 产出一次性 Principal——其 role/layers/ops 取自该单元 spec、unit
53
- 记为执行单元。那是**单次调用的临时身份**,不改变本字段的归因
54
- 定位(见 `mcp_server.call_tool`)。
55
-
56
- 令牌扩展(由 `tokens.verify_token` 填充;直接构造时为 None = 不限制):
57
- role —— 角色(designer/reflection/verifier/recorder/output/sustain/guest)
58
- token_id —— 令牌 id(可追溯到签发记录)
59
- parent —— 派生来源令牌 id(权职分离的委派链)
60
- expires_at —— 过期时间戳(None = 不过期)
61
- layers_allow —— 可写层白名单(None = 不限制;"*" = 全部)
62
- ops_allow —— 可执行 op 白名单(同上)
63
- auth_mode —— direct(直接构造)/ token / legacy_env / anonymous
64
-
65
- 版本层扩展(蜂群互联层0,由 `theory.check` 填充):
66
- theory_ok —— 版本声明是否合法;False 时**全部写/管理操作被拒**(只读降级)
67
- theory_version —— 当前声明的协议版本(审计与 whoami 用)
68
- """
69
-
70
- # 生效条件:clearance 须为模块级常量 SENSITIVITY_ORDER 成员(否则 _rank 抛 AccessDenied),session 为假值(含 None/空串)时生成 sess_ 随机串,expires_at 为假值(含 None/0)时存 None 否则 float(expires_at),layers_allow/ops_allow 为 None 时存 None 否则 tuple 化。
71
- def __init__(self, tenant: str = "default", actor: str = "system",
72
- clearance: str = DEFAULT_SENSITIVITY, can_write: bool = True,
73
- can_admin: bool = False, session: str = None,
74
- harness: str = None, unit: str = None,
75
- role: str = None, token_id: str = None, parent: str = None,
76
- expires_at: float = None, layers_allow=None, ops_allow=None,
77
- auth_mode: str = "direct", theory_ok: bool = True,
78
- theory_version: str = None):
79
- _rank(clearance) # 校验
80
- self.tenant = tenant
81
- self.actor = actor
82
- self.clearance = clearance
83
- self.can_write = can_write
84
- self.can_admin = can_admin
85
- self.session = session or ("sess_" + uuid.uuid4().hex[:12])
86
- # 归因维度(嵌套身份):只入审计(_audit/_recent),不参与权限判定。
87
- # 权限域仍由令牌记录决定(tokens.ROLE_SPECS),与 harness/unit 无关。
88
- # 受控例外:MCP 请求级 `as_unit` 收窄(tokens.narrowed_principal)产出的是
89
- # 一次性 Principal,其 role/allow 取自单元 spec——**只做减法**(与 owner
90
- # 求交 + 管理权恒 False),故不构成本字段「参与授权」的先例。
91
- self.harness = harness
92
- self.unit = unit
93
- self.role = (role or "system")
94
- self.token_id = token_id
95
- self.parent = parent
96
- self.expires_at = float(expires_at) if expires_at else None
97
- self.layers_allow = None if layers_allow is None else tuple(layers_allow)
98
- self.ops_allow = None if ops_allow is None else tuple(ops_allow)
99
- self.auth_mode = auth_mode
100
- self.theory_ok = bool(theory_ok)
101
- self.theory_version = theory_version
102
-
103
- # ---------- 基础判定 ----------
104
-
105
- # 生效条件:形参 sensitivity 与 self.clearance 均可被 _rank 映射到模块级常量 SENSITIVITY_ORDER 中时,返回前者排名是否不高于后者;任一不在其中则 _rank 抛 AccessDenied。
106
- def allows(self, sensitivity: str) -> bool:
107
- """clearance 是否覆盖该敏感度(可读/可写)。"""
108
- return _rank(sensitivity) <= _rank(self.clearance)
109
-
110
- # 生效条件:无 required 形参或模块级常量前置,仅当 self.expires_at(来自 __init__ 的 expires_at)不为 None 且 time.time() 大于它时返回 True,否则返回 False。
111
- def expired(self) -> bool:
112
- return self.expires_at is not None and time.time() > self.expires_at
113
-
114
- @staticmethod
115
- # 生效条件:allow 为 None 时返回 True(未声明=不限制),allow 非 None 时返回 "'*' in allow 或 name in allow" 的布尔结果。
116
- def _in_scope(allow, name: str) -> bool:
117
- if allow is None: # 未声明 = 不限制(兼容直接构造)
118
- return True
119
- return "*" in allow or name in allow
120
-
121
- # 生效条件:layer 为假值(None/空串)时以 "knowledge" 参与判定,返回 self._in_scope(self.layers_allow, layer or "knowledge") 的结果。
122
- def allows_layer(self, layer: str) -> bool:
123
- return self._in_scope(self.layers_allow, layer or "knowledge")
124
-
125
- # 生效条件:op 为假值(None/空串)时以 "" 参与,先经 strip().lower() 归一化,返回 self._in_scope(self.ops_allow, (op or "").strip().lower()) 的结果。
126
- def allows_op(self, op: str) -> bool:
127
- return self._in_scope(self.ops_allow, (op or "").strip().lower())
128
-
129
- # ---------- 强制校验(越权即 AccessDenied) ----------
130
-
131
- # 生效条件:无 required 形参或模块级常量前置,当 self.expired()(来自 __init__ 的 expires_at 与当前时间比较)为 True 时抛 AccessDenied,否则无操作返回 None。
132
- def _require_live(self):
133
- if self.expired():
134
- raise AccessDenied(f"actor={self.actor} 令牌已过期")
135
-
136
- # 生效条件:先调用 self._require_live()(过期则抛 AccessDenied);再要求 self.allows_op(op) 为 True,否则抛 AccessDenied。
137
- def require_op(self, op: str):
138
- self._require_live()
139
- if not self.allows_op(op):
140
- raise AccessDenied(
141
- f"角色 {self.role} 无权执行 op={op}(作用域 "
142
- f"{list(self.ops_allow) if self.ops_allow is not None else '不限'})")
143
-
144
- # 生效条件:依次要求 self._require_live() 未抛异常、self.theory_ok 为 True、self.can_write 为 True、self.allows(sensitivity) 为 True;任一不满足则抛 AccessDenied。
145
- def require_write(self, sensitivity: str):
146
- self._require_live()
147
- if not self.theory_ok:
148
- raise AccessDenied(
149
- "版本层校验未通过(theory_ok=False):全部写操作被拒,"
150
- "仅保留 theory 修复入口")
151
- if not self.can_write:
152
- raise AccessDenied(f"actor={self.actor} 无写权限")
153
- if not self.allows(sensitivity):
154
- raise AccessDenied(
155
- f"写入敏感度 {sensitivity} 超出 clearance {self.clearance}")
156
-
157
- # 生效条件:先要求 self.require_write(sensitivity) 未抛异常;随后将形参 layer 为假值(None/空串)时按 "knowledge" 处理,并要求 self.allows_layer(layer) 为 True,否则抛 AccessDenied。
158
- def require_layer_write(self, layer: str, sensitivity: str):
159
- """写层校验:密级 + 层白名单双闸门(核心私有内容不可越权修改)。"""
160
- self.require_write(sensitivity)
161
- layer = layer or "knowledge"
162
- if not self.allows_layer(layer):
163
- raise AccessDenied(
164
- f"角色 {self.role} 无权写入 {layer} 层"
165
- f"(可写层 {list(self.layers_allow) if self.layers_allow is not None else '不限'})")
166
-
167
- # 生效条件:要求 self._require_live() 未抛异常、self.theory_ok 为 True、self.can_admin 为 True 时通过;否则抛 AccessDenied(消息用形参 op 标记操作)。
168
- def require_admin(self, op: str):
169
- self._require_live()
170
- if not self.theory_ok:
171
- raise AccessDenied(
172
- f"版本层校验未通过(theory_ok=False):管理操作 {op} 被拒")
173
- if not self.can_admin:
174
- raise AccessDenied(f"actor={self.actor} 无管理权限({op})")
175
-
176
- # 生效条件:无 required 形参或模块级常量前置,返回包含 self 各属性(tenant/actor/clearance/can_write/can_admin/session/harness/unit/role/token_id/parent/auth_mode/expires_at/theory_ok/theory_version 及 layers_allow/ops_allow)的 dict;其中 layers_allow/ops_allow 为 None 时值为 None,否则 list 化。
177
- def as_dict(self):
178
- return {"tenant": self.tenant, "actor": self.actor,
179
- "clearance": self.clearance, "can_write": self.can_write,
180
- "can_admin": self.can_admin, "session": self.session,
181
- "harness": self.harness, "unit": self.unit,
182
- "role": self.role, "token_id": self.token_id,
183
- "parent": self.parent, "auth_mode": self.auth_mode,
184
- "expires_at": self.expires_at,
185
- "theory_ok": self.theory_ok,
186
- "theory_version": self.theory_version,
187
- "layers_allow": (None if self.layers_allow is None
188
- else list(self.layers_allow)),
189
- "ops_allow": (None if self.ops_allow is None
190
- else list(self.ops_allow))}
191
-
192
- # 生效条件:无前置;仅返回 tenant/actor/role/clearance/write/admin 的短摘要用于日志与排障,不含 token、密钥材料与能力白名单明细;
193
- def __repr__(self):
194
- return (f"Principal(tenant={self.tenant!r}, actor={self.actor!r}, "
195
- f"role={self.role!r}, clearance={self.clearance!r}, "
196
- f"write={self.can_write}, admin={self.can_admin})")
197
-
198
-
199
- # 生效条件:path 为 None 时落至 os.path.expanduser("~") 下的 .mdcg/_tenants.json,path 非 None(含空串)时按传入值使用,并在构造内以 self._load() 的返回填充 self.data。
200
- class TenantRegistry:
201
- """租户注册表:tenant → {root, clearance_cap, description}。
202
-
203
- 默认位置:<registry_dir>/_tenants.json(默认 ~/.mdcg/)。
204
- 设计意图:私有租户的 root 指向仓库外目录,开源仓库里只放 public 租户的根。
205
- """
206
-
207
- # 生效条件:形参 path 为 None 时取 ~/.mdcg/_tenants.json,否则取 path;self.data 初始化为 _load() 结果(self.path 经 os.path.exists 为真且 JSON 解析为 dict 时取该 dict,否则回落 {"schema":1,"tenants":{}})。
208
- def __init__(self, path: str = None):
209
- if path is None:
210
- path = os.path.join(os.path.expanduser("~"), ".mdcg", "_tenants.json")
211
- self.path = path
212
- self.data = self._load()
213
-
214
- # 生效条件:当 self.path 经 os.path.exists 为真且内容可解析为 dict 时返回该 dict;否则(os.path.exists 为假、非 dict、JSON 解析失败或 OSError)返回 {"schema":1,"tenants":{}}。
215
- def _load(self):
216
- if os.path.exists(self.path):
217
- try:
218
- with open(self.path, encoding="utf-8") as f:
219
- d = json.load(f)
220
- if isinstance(d, dict):
221
- return d
222
- except (ValueError, OSError):
223
- pass
224
- return {"schema": 1, "tenants": {}}
225
-
226
- # 生效条件:无 required 形参或模块级常量前置,将 self.data 以 JSON 写入 self.path + ".tmp",随后 os.replace 到 self.path;目录名称为空时用 "." 创建。
227
- def _save(self):
228
- os.makedirs(os.path.dirname(self.path) or ".", exist_ok=True)
229
- tmp = self.path + ".tmp"
230
- with open(tmp, "w", encoding="utf-8") as f:
231
- json.dump(self.data, f, ensure_ascii=False, indent=1)
232
- os.replace(tmp, self.path)
233
-
234
- # 生效条件:形参 clearance_cap 须为模块级常量 SENSITIVITY_ORDER 成员(否则 _rank 抛 AccessDenied);形参 tenant/root 提供后写入 self.data["tenants"](要求 self.data 含 "tenants" 键,否则 KeyError),_save 成功则返回新登记项。
235
- def register(self, tenant: str, root: str, clearance_cap: str = DEFAULT_SENSITIVITY,
236
- description: str = ""):
237
- _rank(clearance_cap)
238
- self.data["tenants"][tenant] = {
239
- "root": os.path.abspath(root),
240
- "clearance_cap": clearance_cap,
241
- "description": description,
242
- "registered_at": time.time(),
243
- }
244
- self._save()
245
- return self.data["tenants"][tenant]
246
-
247
- # 生效条件:self.data 含 "tenants" 键(否则 KeyError),且该映射中存在形参 tenant 时返回其值,否则返回 None(.get 缺键回落 None,键存在值为 None 也返回 None)。
248
- def get(self, tenant: str):
249
- return self.data["tenants"].get(tenant)
250
-
251
- # 生效条件:self.get(tenant) 返回真值(非 None/空 dict 等)时返回 t["root"](若 t 无 "root" 键则 KeyError);返回假值时返回 None。
252
- def root_of(self, tenant: str):
253
- t = self.get(tenant)
254
- return t["root"] if t else None
255
-
256
- # 生效条件:self.get(tenant) 返回真值时返回 t["clearance_cap"](缺键则 KeyError);返回假值时返回模块级常量 DEFAULT_SENSITIVITY。
257
- def cap_of(self, tenant: str):
258
- t = self.get(tenant)
259
- return t["clearance_cap"] if t else DEFAULT_SENSITIVITY
260
-
261
- # 生效条件:self.data 含 "tenants" 键时返回其浅拷贝 dict(self.data["tenants"]);该键缺失时按 self.data["tenants"] 取值会 KeyError,无默认回落。
262
- def all(self):
263
- return dict(self.data["tenants"])
264
-
265
- # 生效条件:cap 由 cap_of(tenant) 决定(形参 tenant 未注册时取模块级常量 DEFAULT_SENSITIVITY);clearance 为假值(含 None/空串)时 want 取 cap,否则先取 clearance,再在 _rank(want) > _rank(cap) 时夹紧为 cap;actor 为假值时取 tenant;返回 Principal(...)。
266
- def principal_for(self, tenant: str, actor: str = None, clearance: str = None,
267
- can_write: bool = True, can_admin: bool = False,
268
- session: str = None) -> Principal:
269
- """按租户上限夹紧 clearance(调用方不能超过租户上限)。"""
270
- cap = self.cap_of(tenant)
271
- want = clearance or cap
272
- if _rank(want) > _rank(cap):
273
- want = cap
274
- return Principal(tenant=tenant, actor=actor or tenant, clearance=want,
1
+ # -*- coding: utf-8 -*-
2
+ """md_cg · 进程/权限模型(记忆 OS #2)
3
+
4
+ 关键动机:**灵枢是开源仓库,而记忆很大一部分是私有内容**。因此权限模型必须
5
+ 支持「公开知识」与「私有记忆」的物理与逻辑隔离:
6
+
7
+ ① 物理隔离:租户(tenant)各自一个根目录。public 租户的根可落在开源仓库内,
8
+ private 租户的根必须落在仓库外(如 ~/.mdcg/private/)。
9
+ ② 逻辑隔离:每个节点带 sensitivity(public < internal < private < secret);
10
+ 每个调用方(Principal)带 clearance,只能读写 ≤ clearance 的节点。
11
+ ③ 硬规则:secret 节点对 clearance < secret 的调用方**写入即拒**(对齐 noema
12
+ 「secret 候选自动拒绝」);写入高于自身 clearance 的敏感度 → 拒绝。
13
+
14
+ 零第三方依赖。
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import os
20
+ import time
21
+ import uuid
22
+
23
+ SENSITIVITY_ORDER = ("public", "internal", "private", "secret")
24
+ DEFAULT_SENSITIVITY = "internal"
25
+
26
+
27
+ class AccessDenied(Exception):
28
+ """权限拒绝(读/写/管理)。"""
29
+
30
+
31
+ # 生效条件:形参 level 为模块级常量 SENSITIVITY_ORDER 中的元素时返回其下标,否则抛 AccessDenied。
32
+ def _rank(level: str) -> int:
33
+ try:
34
+ return SENSITIVITY_ORDER.index(level)
35
+ except ValueError:
36
+ raise AccessDenied(f"未知敏感度/密级:{level}") from None
37
+
38
+
39
+ # 生效条件:全部形参均可省略、clearance 默认取模块常量 DEFAULT_SENSITIVITY,构造时先经 _rank(clearance) 校验,随后 session 为假值(含空串)回落为 sess_+uuid 十二位、role 假值回落 "system"、expires_at 为假值(含 0)置 None、layers_allow/ops_allow 为 None 时保持 None 否则转 tuple、theory_ok 经 bool() 转换。
40
+ class Principal:
41
+ """调用方身份(一次会话一个)。
42
+
43
+ tenant —— 租户(决定根目录)
44
+ actor —— 调用者标识(写入审计)
45
+ clearance —— 最高可读/可写敏感度
46
+ can_write —— 是否允许写
47
+ can_admin —— 是否允许管理操作(forget/restore/review_decide)
48
+ session —— 会话 id(进程/会话模型:每次连接一个)
49
+ harness —— 承载端标识(dsh/zcode/codebuddy…;仅归因,不参与授权)
50
+ unit —— 单元分工(record/reflect/verify/output/sustain;仅归因)
51
+ 注:MCP 请求级参数 `as_unit` 会经 `tokens.narrowed_principal`
52
+ 产出一次性 Principal——其 role/layers/ops 取自该单元 spec、unit
53
+ 记为执行单元。那是**单次调用的临时身份**,不改变本字段的归因
54
+ 定位(见 `mcp_server.call_tool`)。
55
+
56
+ 令牌扩展(由 `tokens.verify_token` 填充;直接构造时为 None = 不限制):
57
+ role —— 角色(designer/reflection/verifier/recorder/output/sustain/guest)
58
+ token_id —— 令牌 id(可追溯到签发记录)
59
+ parent —— 派生来源令牌 id(权职分离的委派链)
60
+ expires_at —— 过期时间戳(None = 不过期)
61
+ layers_allow —— 可写层白名单(None = 不限制;"*" = 全部)
62
+ ops_allow —— 可执行 op 白名单(同上)
63
+ auth_mode —— direct(直接构造)/ token / legacy_env / anonymous
64
+
65
+ 版本层扩展(蜂群互联层0,由 `theory.check` 填充):
66
+ theory_ok —— 版本声明是否合法;False 时**全部写/管理操作被拒**(只读降级)
67
+ theory_version —— 当前声明的协议版本(审计与 whoami 用)
68
+ """
69
+
70
+ # 生效条件:clearance 须为模块级常量 SENSITIVITY_ORDER 成员(否则 _rank 抛 AccessDenied),session 为假值(含 None/空串)时生成 sess_ 随机串,expires_at 为假值(含 None/0)时存 None 否则 float(expires_at),layers_allow/ops_allow 为 None 时存 None 否则 tuple 化。
71
+ def __init__(self, tenant: str = "default", actor: str = "system",
72
+ clearance: str = DEFAULT_SENSITIVITY, can_write: bool = True,
73
+ can_admin: bool = False, session: str = None,
74
+ harness: str = None, unit: str = None,
75
+ role: str = None, token_id: str = None, parent: str = None,
76
+ expires_at: float = None, layers_allow=None, ops_allow=None,
77
+ auth_mode: str = "direct", theory_ok: bool = True,
78
+ theory_version: str = None):
79
+ _rank(clearance) # 校验
80
+ self.tenant = tenant
81
+ self.actor = actor
82
+ self.clearance = clearance
83
+ self.can_write = can_write
84
+ self.can_admin = can_admin
85
+ self.session = session or ("sess_" + uuid.uuid4().hex[:12])
86
+ # 归因维度(嵌套身份):只入审计(_audit/_recent),不参与权限判定。
87
+ # 权限域仍由令牌记录决定(tokens.ROLE_SPECS),与 harness/unit 无关。
88
+ # 受控例外:MCP 请求级 `as_unit` 收窄(tokens.narrowed_principal)产出的是
89
+ # 一次性 Principal,其 role/allow 取自单元 spec——**只做减法**(与 owner
90
+ # 求交 + 管理权恒 False),故不构成本字段「参与授权」的先例。
91
+ self.harness = harness
92
+ self.unit = unit
93
+ self.role = (role or "system")
94
+ self.token_id = token_id
95
+ self.parent = parent
96
+ self.expires_at = float(expires_at) if expires_at else None
97
+ self.layers_allow = None if layers_allow is None else tuple(layers_allow)
98
+ self.ops_allow = None if ops_allow is None else tuple(ops_allow)
99
+ self.auth_mode = auth_mode
100
+ self.theory_ok = bool(theory_ok)
101
+ self.theory_version = theory_version
102
+
103
+ # ---------- 基础判定 ----------
104
+
105
+ # 生效条件:形参 sensitivity 与 self.clearance 均可被 _rank 映射到模块级常量 SENSITIVITY_ORDER 中时,返回前者排名是否不高于后者;任一不在其中则 _rank 抛 AccessDenied。
106
+ def allows(self, sensitivity: str) -> bool:
107
+ """clearance 是否覆盖该敏感度(可读/可写)。"""
108
+ return _rank(sensitivity) <= _rank(self.clearance)
109
+
110
+ # 生效条件:无 required 形参或模块级常量前置,仅当 self.expires_at(来自 __init__ 的 expires_at)不为 None 且 time.time() 大于它时返回 True,否则返回 False。
111
+ def expired(self) -> bool:
112
+ return self.expires_at is not None and time.time() > self.expires_at
113
+
114
+ @staticmethod
115
+ # 生效条件:allow 为 None 时返回 True(未声明=不限制),allow 非 None 时返回 "'*' in allow 或 name in allow" 的布尔结果。
116
+ def _in_scope(allow, name: str) -> bool:
117
+ if allow is None: # 未声明 = 不限制(兼容直接构造)
118
+ return True
119
+ return "*" in allow or name in allow
120
+
121
+ # 生效条件:layer 为假值(None/空串)时以 "knowledge" 参与判定,返回 self._in_scope(self.layers_allow, layer or "knowledge") 的结果。
122
+ def allows_layer(self, layer: str) -> bool:
123
+ return self._in_scope(self.layers_allow, layer or "knowledge")
124
+
125
+ # 生效条件:op 为假值(None/空串)时以 "" 参与,先经 strip().lower() 归一化,返回 self._in_scope(self.ops_allow, (op or "").strip().lower()) 的结果。
126
+ def allows_op(self, op: str) -> bool:
127
+ return self._in_scope(self.ops_allow, (op or "").strip().lower())
128
+
129
+ # ---------- 强制校验(越权即 AccessDenied) ----------
130
+
131
+ # 生效条件:无 required 形参或模块级常量前置,当 self.expired()(来自 __init__ 的 expires_at 与当前时间比较)为 True 时抛 AccessDenied,否则无操作返回 None。
132
+ def _require_live(self):
133
+ if self.expired():
134
+ raise AccessDenied(f"actor={self.actor} 令牌已过期")
135
+
136
+ # 生效条件:先调用 self._require_live()(过期则抛 AccessDenied);再要求 self.allows_op(op) 为 True,否则抛 AccessDenied。
137
+ def require_op(self, op: str):
138
+ self._require_live()
139
+ if not self.allows_op(op):
140
+ raise AccessDenied(
141
+ f"角色 {self.role} 无权执行 op={op}(作用域 "
142
+ f"{list(self.ops_allow) if self.ops_allow is not None else '不限'})")
143
+
144
+ # 生效条件:依次要求 self._require_live() 未抛异常、self.theory_ok 为 True、self.can_write 为 True、self.allows(sensitivity) 为 True;任一不满足则抛 AccessDenied。
145
+ def require_write(self, sensitivity: str):
146
+ self._require_live()
147
+ if not self.theory_ok:
148
+ raise AccessDenied(
149
+ "版本层校验未通过(theory_ok=False):全部写操作被拒,"
150
+ "仅保留 theory 修复入口")
151
+ if not self.can_write:
152
+ raise AccessDenied(f"actor={self.actor} 无写权限")
153
+ if not self.allows(sensitivity):
154
+ raise AccessDenied(
155
+ f"写入敏感度 {sensitivity} 超出 clearance {self.clearance}")
156
+
157
+ # 生效条件:先要求 self.require_write(sensitivity) 未抛异常;随后将形参 layer 为假值(None/空串)时按 "knowledge" 处理,并要求 self.allows_layer(layer) 为 True,否则抛 AccessDenied。
158
+ def require_layer_write(self, layer: str, sensitivity: str):
159
+ """写层校验:密级 + 层白名单双闸门(核心私有内容不可越权修改)。"""
160
+ self.require_write(sensitivity)
161
+ layer = layer or "knowledge"
162
+ if not self.allows_layer(layer):
163
+ raise AccessDenied(
164
+ f"角色 {self.role} 无权写入 {layer} 层"
165
+ f"(可写层 {list(self.layers_allow) if self.layers_allow is not None else '不限'})")
166
+
167
+ # 生效条件:要求 self._require_live() 未抛异常、self.theory_ok 为 True、self.can_admin 为 True 时通过;否则抛 AccessDenied(消息用形参 op 标记操作)。
168
+ def require_admin(self, op: str):
169
+ self._require_live()
170
+ if not self.theory_ok:
171
+ raise AccessDenied(
172
+ f"版本层校验未通过(theory_ok=False):管理操作 {op} 被拒")
173
+ if not self.can_admin:
174
+ raise AccessDenied(f"actor={self.actor} 无管理权限({op})")
175
+
176
+ # 生效条件:无 required 形参或模块级常量前置,返回包含 self 各属性(tenant/actor/clearance/can_write/can_admin/session/harness/unit/role/token_id/parent/auth_mode/expires_at/theory_ok/theory_version 及 layers_allow/ops_allow)的 dict;其中 layers_allow/ops_allow 为 None 时值为 None,否则 list 化。
177
+ def as_dict(self):
178
+ return {"tenant": self.tenant, "actor": self.actor,
179
+ "clearance": self.clearance, "can_write": self.can_write,
180
+ "can_admin": self.can_admin, "session": self.session,
181
+ "harness": self.harness, "unit": self.unit,
182
+ "role": self.role, "token_id": self.token_id,
183
+ "parent": self.parent, "auth_mode": self.auth_mode,
184
+ "expires_at": self.expires_at,
185
+ "theory_ok": self.theory_ok,
186
+ "theory_version": self.theory_version,
187
+ "layers_allow": (None if self.layers_allow is None
188
+ else list(self.layers_allow)),
189
+ "ops_allow": (None if self.ops_allow is None
190
+ else list(self.ops_allow))}
191
+
192
+ # 生效条件:无前置;仅返回 tenant/actor/role/clearance/write/admin 的短摘要用于日志与排障,不含 token、密钥材料与能力白名单明细;
193
+ def __repr__(self):
194
+ return (f"Principal(tenant={self.tenant!r}, actor={self.actor!r}, "
195
+ f"role={self.role!r}, clearance={self.clearance!r}, "
196
+ f"write={self.can_write}, admin={self.can_admin})")
197
+
198
+
199
+ # 生效条件:path 为 None 时落至 os.path.expanduser("~") 下的 .mdcg/_tenants.json,path 非 None(含空串)时按传入值使用,并在构造内以 self._load() 的返回填充 self.data。
200
+ class TenantRegistry:
201
+ """租户注册表:tenant → {root, clearance_cap, description}。
202
+
203
+ 默认位置:<registry_dir>/_tenants.json(默认 ~/.mdcg/)。
204
+ 设计意图:私有租户的 root 指向仓库外目录,开源仓库里只放 public 租户的根。
205
+ """
206
+
207
+ # 生效条件:形参 path 为 None 时取 ~/.mdcg/_tenants.json,否则取 path;self.data 初始化为 _load() 结果(self.path 经 os.path.exists 为真且 JSON 解析为 dict 时取该 dict,否则回落 {"schema":1,"tenants":{}})。
208
+ def __init__(self, path: str = None):
209
+ if path is None:
210
+ path = os.path.join(os.path.expanduser("~"), ".mdcg", "_tenants.json")
211
+ self.path = path
212
+ self.data = self._load()
213
+
214
+ # 生效条件:当 self.path 经 os.path.exists 为真且内容可解析为 dict 时返回该 dict;否则(os.path.exists 为假、非 dict、JSON 解析失败或 OSError)返回 {"schema":1,"tenants":{}}。
215
+ def _load(self):
216
+ if os.path.exists(self.path):
217
+ try:
218
+ with open(self.path, encoding="utf-8") as f:
219
+ d = json.load(f)
220
+ if isinstance(d, dict):
221
+ return d
222
+ except (ValueError, OSError):
223
+ pass
224
+ return {"schema": 1, "tenants": {}}
225
+
226
+ # 生效条件:无 required 形参或模块级常量前置,将 self.data 以 JSON 写入 self.path + ".tmp",随后 os.replace 到 self.path;目录名称为空时用 "." 创建。
227
+ def _save(self):
228
+ os.makedirs(os.path.dirname(self.path) or ".", exist_ok=True)
229
+ tmp = self.path + ".tmp"
230
+ with open(tmp, "w", encoding="utf-8") as f:
231
+ json.dump(self.data, f, ensure_ascii=False, indent=1)
232
+ os.replace(tmp, self.path)
233
+
234
+ # 生效条件:形参 clearance_cap 须为模块级常量 SENSITIVITY_ORDER 成员(否则 _rank 抛 AccessDenied);形参 tenant/root 提供后写入 self.data["tenants"](要求 self.data 含 "tenants" 键,否则 KeyError),_save 成功则返回新登记项。
235
+ def register(self, tenant: str, root: str, clearance_cap: str = DEFAULT_SENSITIVITY,
236
+ description: str = ""):
237
+ _rank(clearance_cap)
238
+ self.data["tenants"][tenant] = {
239
+ "root": os.path.abspath(root),
240
+ "clearance_cap": clearance_cap,
241
+ "description": description,
242
+ "registered_at": time.time(),
243
+ }
244
+ self._save()
245
+ return self.data["tenants"][tenant]
246
+
247
+ # 生效条件:self.data 含 "tenants" 键(否则 KeyError),且该映射中存在形参 tenant 时返回其值,否则返回 None(.get 缺键回落 None,键存在值为 None 也返回 None)。
248
+ def get(self, tenant: str):
249
+ return self.data["tenants"].get(tenant)
250
+
251
+ # 生效条件:self.get(tenant) 返回真值(非 None/空 dict 等)时返回 t["root"](若 t 无 "root" 键则 KeyError);返回假值时返回 None。
252
+ def root_of(self, tenant: str):
253
+ t = self.get(tenant)
254
+ return t["root"] if t else None
255
+
256
+ # 生效条件:self.get(tenant) 返回真值时返回 t["clearance_cap"](缺键则 KeyError);返回假值时返回模块级常量 DEFAULT_SENSITIVITY。
257
+ def cap_of(self, tenant: str):
258
+ t = self.get(tenant)
259
+ return t["clearance_cap"] if t else DEFAULT_SENSITIVITY
260
+
261
+ # 生效条件:self.data 含 "tenants" 键时返回其浅拷贝 dict(self.data["tenants"]);该键缺失时按 self.data["tenants"] 取值会 KeyError,无默认回落。
262
+ def all(self):
263
+ return dict(self.data["tenants"])
264
+
265
+ # 生效条件:cap 由 cap_of(tenant) 决定(形参 tenant 未注册时取模块级常量 DEFAULT_SENSITIVITY);clearance 为假值(含 None/空串)时 want 取 cap,否则先取 clearance,再在 _rank(want) > _rank(cap) 时夹紧为 cap;actor 为假值时取 tenant;返回 Principal(...)。
266
+ def principal_for(self, tenant: str, actor: str = None, clearance: str = None,
267
+ can_write: bool = True, can_admin: bool = False,
268
+ session: str = None) -> Principal:
269
+ """按租户上限夹紧 clearance(调用方不能超过租户上限)。"""
270
+ cap = self.cap_of(tenant)
271
+ want = clearance or cap
272
+ if _rank(want) > _rank(cap):
273
+ want = cap
274
+ return Principal(tenant=tenant, actor=actor or tenant, clearance=want,
275
275
  can_write=can_write, can_admin=can_admin, session=session)