@furongjun1999/dsh-memory 0.4.11 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +552 -465
- package/codebuddy/CODEBUDDY.md +11 -3
- package/codebuddy/README.md +92 -90
- package/codebuddy/mcp.json +27 -27
- 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
- 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
- package/docs/README.md +143 -111
- package/docs/discipline/harnesses.yaml +244 -226
- package/docs/discipline/templates/full.md.tmpl +61 -61
- package/docs/discipline/templates/rules.mdc.tmpl +68 -0
- package/docs/discipline/templates/skill.md.tmpl +23 -23
- 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
- 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
- package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
- package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
- package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
- package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
- 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
- package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
- 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
- package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
- 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
- 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
- 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
- package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
- 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
- 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
- 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
- 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
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +519 -503
- 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
- 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
- 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
- package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
- package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
- 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
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +646 -646
- package/docs/mdcg/lingshu_tutorial.html +14449 -14449
- package/docs/mdcg/release_v0.4.11.md +49 -0
- package/docs/mdcg/release_v0.4.5.md +55 -55
- package/docs/mdcg/tool_table_v0.3.0.md +117 -117
- 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
- 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
- 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
- package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +54 -0
- 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
- 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
- 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
- package/docs/mdcg//347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +270 -270
- 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
- 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
- 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
- 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
- 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
- package/docs/swarm//350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +704 -704
- 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
- package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
- 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
- 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
- package/docs/theory//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- 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
- 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
- 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
- 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
- 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
- package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
- 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
- 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
- package/dsh/README.md +82 -82
- package/dsh/cordis.yml.example +139 -139
- package/dsh/update-lingshu.bat +11 -11
- package/lib/bridge.d.ts +9 -0
- package/lib/bridge.js +35 -0
- package/lib/hooks.js +36 -2
- package/lib/index.js +7 -1
- package/lib/lib/roleplay_web.js +116 -29
- package/lib/lib/token_store.d.ts +7 -1
- package/lib/lib/token_store.js +12 -3
- package/md_cg/__init__.py +7 -7
- package/md_cg/audit.py +379 -368
- package/md_cg/autonomy.py +287 -287
- package/md_cg/backfill.py +1328 -1327
- package/md_cg/backfill_bigdomain.py +34 -34
- package/md_cg/backfill_bucket_zh.py +35 -0
- package/md_cg/bench6_arms.py +410 -410
- package/md_cg/bench6_common.py +230 -230
- package/md_cg/bench6_competitors.py +212 -212
- package/md_cg/bench_axis_domain.py +257 -257
- package/md_cg/bench_blind_comp.py +308 -308
- package/md_cg/bench_e2e_judge.py +532 -0
- package/md_cg/bench_e2e_locomo_qa.py +368 -0
- package/md_cg/bench_e2e_qa.py +256 -0
- package/md_cg/bench_en_atoms_public.py +230 -230
- package/md_cg/bench_governance.py +348 -348
- package/md_cg/bench_lme_zh.py +410 -410
- package/md_cg/bench_locomo.py +121 -121
- package/md_cg/bench_locomo_zh.py +450 -450
- package/md_cg/bench_locomo_zh_public.py +147 -147
- package/md_cg/bench_longmem.py +112 -112
- package/md_cg/bench_membench.py +632 -632
- package/md_cg/bench_p0.py +149 -149
- package/md_cg/bench_progressive.py +287 -287
- package/md_cg/bench_role_views.py +238 -238
- package/md_cg/bench_task_ab.py +243 -243
- package/md_cg/bench_task_ab_llm.py +408 -408
- package/md_cg/bench_unified_en.py +204 -204
- package/md_cg/bench_zh_mad.py +601 -601
- package/md_cg/blindspot_tickets.py +123 -123
- package/md_cg/branches.py +301 -285
- package/md_cg/build_postings.py +73 -73
- package/md_cg/ccgc.py +1006 -948
- package/md_cg/census.py +132 -132
- package/md_cg/chain.py +315 -300
- package/md_cg/codeindex.py +531 -531
- package/md_cg/coldverify.py +292 -292
- package/md_cg/comment_gate.py +337 -337
- package/md_cg/cond_compose.py +190 -190
- package/md_cg/cond_facts.py +154 -154
- package/md_cg/cond_template.json +106 -106
- package/md_cg/condition_anchor.py +142 -142
- package/md_cg/conformance.py +726 -726
- package/md_cg/consistency.py +717 -717
- package/md_cg/consolidate.py +1537 -1439
- package/md_cg/corpus.py +110 -110
- package/md_cg/crosscheck.py +1098 -1097
- package/md_cg/crypto.py +3 -1
- package/md_cg/d_meta.py +310 -310
- package/md_cg/datapath.py +78 -18
- package/md_cg/docindex.py +473 -473
- package/md_cg/eval_common.py +575 -575
- package/md_cg/evidence.py +4 -2
- package/md_cg/evolution.py +477 -477
- package/md_cg/export.py +222 -220
- package/md_cg/forgetting.py +581 -581
- package/md_cg/fsutil.py +377 -329
- package/md_cg/hotcache.py +48 -7
- package/md_cg/hyperedge.py +251 -251
- package/md_cg/identity.py +390 -390
- package/md_cg/insight.py +500 -500
- package/md_cg/interop.py +338 -0
- package/md_cg/judgment_manifest.py +177 -0
- package/md_cg/lexicon/build_cedict_en_zh.py +329 -329
- package/md_cg/lexicon/build_standard_en.py +171 -171
- package/md_cg/lexicon/expand_en_zh.py +211 -211
- package/md_cg/lifecycle.py +272 -272
- package/md_cg/linkref.py +280 -280
- package/md_cg/links.py +140 -107
- package/md_cg/mcp_server.py +403 -55
- package/md_cg/md_whitebox.py +345 -345
- package/md_cg/mdcg.py +783 -233
- package/md_cg/mdcos.py +500 -70
- package/md_cg/metacognition.py +591 -591
- package/md_cg/migrate.py +119 -119
- package/md_cg/migrate_aeis.py +221 -221
- package/md_cg/migrate_roleplay.py +293 -293
- package/md_cg/migrate_wisdom_graph.py +360 -360
- package/md_cg/mreview/__init__.py +25 -25
- package/md_cg/mreview/__main__.py +110 -110
- package/md_cg/mreview/bundle.py +178 -178
- package/md_cg/mreview/candidates.py +262 -262
- package/md_cg/mreview/govern.py +694 -693
- package/md_cg/mreview/locate.py +939 -939
- package/md_cg/mreview/pipeline.py +728 -728
- package/md_cg/mreview/rules/duplication.json +21 -21
- package/md_cg/mreview/rules/field_coverage.json +54 -54
- package/md_cg/mreview/rules/source_license.json +21 -21
- package/md_cg/mreview/rules/template_flow.json +21 -21
- package/md_cg/mreview/ruleset.py +252 -252
- package/md_cg/nodefile.py +575 -575
- package/md_cg/pooling.py +484 -472
- package/md_cg/postings.py +300 -298
- package/md_cg/predict.py +1100 -1100
- package/md_cg/progressive.py +123 -123
- package/md_cg/protect.py +272 -272
- package/md_cg/protocol/md_cg_gate.proto +33 -33
- package/md_cg/protocol.py +372 -372
- package/md_cg/provenance.py +582 -582
- package/md_cg/reach.py +453 -453
- package/md_cg/readcache.py +143 -0
- package/md_cg/reconcile.py +228 -0
- package/md_cg/refindex.py +833 -833
- package/md_cg/refine.py +604 -604
- package/md_cg/review_cli.py +170 -0
- package/md_cg/roleviews.py +89 -89
- package/md_cg/routing.py +393 -365
- package/md_cg/run_tests.py +211 -0
- package/md_cg/scrub.py +13 -3
- package/md_cg/security.py +128 -18
- package/md_cg/self_state.py +1029 -1029
- package/md_cg/selfreport.py +152 -151
- package/md_cg/semantic/__init__.py +10 -10
- package/md_cg/semantic/canonical.py +122 -122
- package/md_cg/semantic/en_normalizer.py +364 -364
- package/md_cg/semantic/en_zh_map.json +28694 -0
- package/md_cg/semantic/export_en_zh_map.py +64 -0
- package/md_cg/semantic/unify.py +45 -0
- package/md_cg/semantic/zh_en_atoms.py +139 -139
- package/md_cg/signer.py +7 -4
- package/md_cg/sources.py +816 -582
- package/md_cg/statushdr.py +179 -179
- package/md_cg/stg.py +54 -37
- package/md_cg/subgraph.py +729 -729
- package/md_cg/sustain.py +35 -5
- package/md_cg/tasks.py +470 -470
- package/md_cg/test_access_hints.py +147 -0
- package/md_cg/test_action_derive.py +203 -203
- package/md_cg/test_audit_rotate.py +270 -270
- package/md_cg/test_autonomy.py +143 -143
- package/md_cg/test_bench_governance.py +102 -102
- package/md_cg/test_blindspot_tickets.py +166 -166
- package/md_cg/test_branch_discard_tombstone.py +136 -0
- package/md_cg/test_branches.py +13 -3
- package/md_cg/test_ccg_perturb.py +184 -184
- package/md_cg/test_ccgc.py +433 -433
- package/md_cg/test_census_prune.py +81 -81
- package/md_cg/test_chain_read_isolate.py +168 -0
- package/md_cg/test_cond_compose_anchors.py +76 -76
- package/md_cg/test_cond_match.py +165 -165
- package/md_cg/test_condition_anchor.py +81 -81
- package/md_cg/test_d_meta.py +412 -412
- package/md_cg/test_datapath_device_name.py +203 -0
- package/md_cg/test_datapath_root.py +199 -199
- package/md_cg/test_emit_negtail_cache.py +156 -0
- package/md_cg/test_en_pipeline.py +22 -2
- package/md_cg/test_gain_gate.py +212 -212
- package/md_cg/test_govern_directread.py +421 -0
- package/md_cg/test_health_scale.py +173 -173
- package/md_cg/test_hive_ingest.py +285 -0
- package/md_cg/test_hot_cold.py +215 -215
- package/md_cg/test_hyperedge.py +245 -245
- package/md_cg/test_i26_empty_first_write.py +116 -0
- package/md_cg/test_i27_e041_identity.py +128 -0
- package/md_cg/test_i28_hotcache_prodpath.py +122 -0
- package/md_cg/test_i32_hotcache_env_key.py +218 -0
- package/md_cg/test_identity_attribution.py +96 -15
- package/md_cg/test_index_durability.py +17 -3
- package/md_cg/test_interop.py +95 -0
- package/md_cg/test_interop_judgment.py +228 -0
- package/md_cg/test_issue39_utf8_stdio.py +273 -0
- package/md_cg/test_lifecycle.py +309 -309
- package/md_cg/test_linkref.py +306 -306
- package/md_cg/test_links_concurrent_write.py +188 -0
- package/md_cg/test_lock.py +43 -43
- package/md_cg/test_md_access_parity.py +255 -255
- package/md_cg/test_md_writepath.py +345 -345
- package/md_cg/test_mdstore_search_parity.py +160 -0
- package/md_cg/test_merge_upsert.py +168 -0
- package/md_cg/test_mr_m2.py +587 -587
- package/md_cg/test_mr_m3.py +710 -710
- package/md_cg/test_mr_m4.py +485 -485
- package/md_cg/test_n123_derive_expiry_chain.py +205 -0
- package/md_cg/test_n130_verify_falsified_protect.py +185 -0
- package/md_cg/test_n131_merge_gate.py +205 -0
- package/md_cg/test_p0.py +250 -250
- package/md_cg/test_p1.py +316 -316
- package/md_cg/test_p10_identity.py +173 -173
- package/md_cg/test_p11_consistency.py +233 -233
- package/md_cg/test_p12_metacognition.py +212 -212
- package/md_cg/test_p13_encryption.py +241 -241
- package/md_cg/test_p14_sustain.py +249 -249
- package/md_cg/test_p15_scrub.py +280 -280
- package/md_cg/test_p16_self_state.py +301 -301
- package/md_cg/test_p17_predict.py +354 -354
- package/md_cg/test_p18_whitebox.py +171 -171
- package/md_cg/test_p19_migrate_roleplay.py +149 -149
- package/md_cg/test_p1x_ref_root.py +160 -0
- package/md_cg/test_p20_evolution.py +315 -315
- package/md_cg/test_p21_tokens.py +293 -270
- package/md_cg/test_p22_theory.py +175 -175
- package/md_cg/test_p23_links.py +311 -311
- package/md_cg/test_p24_evidence.py +227 -227
- package/md_cg/test_p25_weights.py +156 -156
- package/md_cg/test_p26_refindex.py +416 -416
- package/md_cg/test_p27_docindex.py +16 -7
- package/md_cg/test_p28_refcheck.py +305 -305
- package/md_cg/test_p29_session_ingest_export.py +354 -333
- package/md_cg/test_p2_mcp.py +3 -0
- package/md_cg/test_p3.py +11 -2
- package/md_cg/test_p30_maintain.py +330 -330
- package/md_cg/test_p31_insight.py +534 -534
- package/md_cg/test_p32_backfill.py +7 -1
- package/md_cg/test_p33_ccg_wiring.py +293 -293
- package/md_cg/test_p34_crosscheck.py +331 -331
- package/md_cg/test_p35_conditioned_claim.py +252 -252
- package/md_cg/test_p36_kp_align.py +230 -230
- package/md_cg/test_p37_condition_space.py +248 -248
- package/md_cg/test_p38_concurrent_flush.py +102 -0
- package/md_cg/test_p38_contextualize.py +273 -273
- package/md_cg/test_p39_verify_flow.py +153 -0
- package/md_cg/test_p39_vision_evidence.py +369 -369
- package/md_cg/test_p40_refine_worklist.py +241 -241
- package/md_cg/test_p41_evolve_patrol.py +224 -224
- package/md_cg/test_p42_provenance.py +269 -269
- package/md_cg/test_p43_pooling.py +412 -398
- package/md_cg/test_p44_md_whitebox.py +231 -231
- package/md_cg/test_p45_session_identity.py +219 -219
- package/md_cg/test_p46_unit_scope.py +272 -272
- package/md_cg/test_p47_session_view.py +316 -0
- package/md_cg/test_p4_fuzzy.py +223 -223
- package/md_cg/test_p5_semantic.py +226 -226
- package/md_cg/test_p6_consolidate.py +440 -387
- package/md_cg/test_p7_goals_recent.py +202 -202
- package/md_cg/test_p8_subgraph_chain.py +200 -200
- package/md_cg/test_p9_forget_protect.py +231 -231
- package/md_cg/test_predict_beta.py +135 -135
- package/md_cg/test_preflight_failclosed.py +100 -100
- package/md_cg/test_progressive.py +146 -146
- package/md_cg/test_propose_tail_index.py +157 -0
- package/md_cg/test_protocol.py +243 -243
- package/md_cg/test_reach.py +378 -378
- package/md_cg/test_reach_keys.py +201 -201
- package/md_cg/test_read_clip.py +141 -141
- package/md_cg/test_read_scope_b27.py +277 -0
- package/md_cg/test_readcache_default_on.py +168 -0
- package/md_cg/test_readcache_precise_inval.py +270 -0
- package/md_cg/test_readcache_prodpath.py +203 -0
- package/md_cg/test_reconcile_v0.py +294 -0
- package/md_cg/test_retr_gates_prodpath.py +140 -0
- package/md_cg/test_retr_s1.py +344 -340
- package/md_cg/test_retr_s1b.py +276 -209
- package/md_cg/test_retr_s3.py +194 -194
- package/md_cg/test_retr_s4.py +163 -163
- package/md_cg/test_retr_s5.py +200 -200
- package/md_cg/test_retr_s6.py +157 -157
- package/md_cg/test_retr_s7.py +392 -384
- package/md_cg/test_retr_s8_time.py +369 -316
- package/md_cg/test_retr_s9_edges.py +286 -286
- package/md_cg/test_retr_s9_entity_ctx.py +9 -3
- package/md_cg/test_retr_score_once.py +208 -0
- package/md_cg/test_review_conformance.py +367 -367
- package/md_cg/test_review_onepass.py +170 -0
- package/md_cg/test_role_views.py +354 -354
- package/md_cg/test_rrf_graph_seed_cache.py +154 -0
- package/md_cg/test_security_audit.py +155 -0
- package/md_cg/test_security_audit_b26.py +161 -0
- package/md_cg/test_security_audit_v21.py +250 -0
- package/md_cg/test_sem_noise.py +242 -242
- package/md_cg/test_semantic_canonical.py +16 -2
- package/md_cg/test_session_isolation.py +168 -0
- package/md_cg/test_snapshot_autoclose.py +187 -0
- package/md_cg/test_subproc_encoding.py +192 -192
- package/md_cg/test_sustain_mutual.py +153 -153
- package/md_cg/test_tail_watermark_race.py +208 -0
- package/md_cg/test_tasks.py +409 -409
- package/md_cg/test_tenant_env_override_warn.py +139 -0
- package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
- package/md_cg/test_tool_face.py +189 -189
- package/md_cg/test_transfer.py +180 -180
- package/md_cg/test_trust.py +361 -361
- package/md_cg/test_twophase.py +286 -286
- package/md_cg/test_v14_fixes.py +38 -20
- package/md_cg/test_validity_filter.py +280 -280
- package/md_cg/test_verify_answer.py +138 -138
- package/md_cg/test_verify_dirty_reconcile.py +157 -0
- package/md_cg/test_wisdom_md_store.py +292 -292
- package/md_cg/test_writelimit.py +197 -197
- package/md_cg/test_writepipe.py +214 -214
- package/md_cg/theory.py +6 -3
- package/md_cg/tokens.py +85 -14
- package/md_cg/tool_face.py +260 -260
- package/md_cg/trust.py +986 -950
- package/md_cg/twophase.py +231 -231
- package/md_cg/units.py +668 -667
- package/md_cg/vision_evidence.py +667 -666
- package/md_cg/weights.py +624 -624
- package/md_cg/whitebox.py +527 -527
- package/md_cg/whitebox_kb/__init__.py +37 -37
- package/md_cg/whitebox_kb/aeis_core/__init__.py +42 -42
- package/md_cg/whitebox_kb/aeis_core/semantic.py +280 -280
- package/md_cg/whitebox_kb/aeis_core/textutil.py +13 -13
- package/md_cg/whitebox_kb/engine.py +310 -310
- package/md_cg/whitebox_kb/seed_knowledge//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- package/md_cg/whitebox_kb/wisdom/browser_units.py +2631 -2631
- package/md_cg/whitebox_kb/wisdom/causal_discover.py +432 -432
- package/md_cg/whitebox_kb/wisdom/chat_engine.py +1506 -1506
- package/md_cg/whitebox_kb/wisdom/compiler_code_units.py +3033 -3033
- package/md_cg/whitebox_kb/wisdom/condition_algebra.py +112 -112
- package/md_cg/whitebox_kb/wisdom/condition_frame.py +315 -315
- package/md_cg/whitebox_kb/wisdom/condition_kb.py +108 -108
- package/md_cg/whitebox_kb/wisdom/conflict_map.json +4445 -4445
- package/md_cg/whitebox_kb/wisdom/core/lexer.py +512 -512
- package/md_cg/whitebox_kb/wisdom/core/name_checker.py +1023 -1023
- package/md_cg/whitebox_kb/wisdom/cspmn.py +258 -258
- package/md_cg/whitebox_kb/wisdom/csre.py +264 -264
- package/md_cg/whitebox_kb/wisdom/danmaku_audit.py +252 -252
- package/md_cg/whitebox_kb/wisdom/distilled_condition_units.json +6417 -6417
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902b.json +1950 -1950
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902c.json +1296 -1296
- package/md_cg/whitebox_kb/wisdom/docs/whitebox_capability_graph_demo.json +59 -59
- package/md_cg/whitebox_kb/wisdom/graph_db_units.py +3089 -3089
- package/md_cg/whitebox_kb/wisdom/knowledge_points.py +318 -318
- package/md_cg/whitebox_kb/wisdom/md_access.py +470 -470
- package/md_cg/whitebox_kb/wisdom/md_store.py +276 -251
- package/md_cg/whitebox_kb/wisdom/migrate_wisdom.py +476 -476
- package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
- package/md_cg/whitebox_kb/wisdom/navigate.py +248 -248
- package/md_cg/whitebox_kb/wisdom/neural_retrieve.py +224 -224
- package/md_cg/whitebox_kb/wisdom/os_units.py +2735 -2735
- package/md_cg/whitebox_kb/wisdom/pattern_separation.py +376 -376
- package/md_cg/whitebox_kb/wisdom/prereq_map.json +364 -364
- package/md_cg/whitebox_kb/wisdom/python_code_units.py +2766 -2766
- package/md_cg/whitebox_kb/wisdom/role_solidified.json +7 -7
- package/md_cg/whitebox_kb/wisdom/route_memory.py +244 -244
- package/md_cg/whitebox_kb/wisdom/scene_reconstruction.py +148 -148
- package/md_cg/whitebox_kb/wisdom/snr_report.json +40 -40
- package/md_cg/whitebox_kb/wisdom/test_code_compose_domains.py +7541 -7541
- package/md_cg/whitebox_kb/wisdom/test_compiler_self_bootstrap.py +354 -354
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_assembly.py +158 -158
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_demos.py +193 -193
- package/md_cg/whitebox_kb/wisdom/test_graph_db.py +292 -292
- package/md_cg/whitebox_kb/wisdom/test_python_self_bootstrap.py +160 -160
- package/md_cg/whitebox_kb/wisdom/trigger_words_index.json +4366 -4366
- package/md_cg/whitebox_kb/wisdom/verifier.py +1297 -1297
- package/md_cg/writelimit.py +356 -356
- package/md_cg/writepipe.py +20 -8
- package/package.json +101 -96
- package/skills/plugin.json +54 -54
- package/skills/skills/designer-perspective/SKILL.md +158 -158
- package/skills/skills/designer-perspective/references/01-observation-position.md +66 -66
- package/skills/skills/designer-perspective/references/02-structure-recognition.md +62 -62
- package/skills/skills/designer-perspective/references/03-direction-judgment.md +55 -55
- package/skills/skills/designer-perspective/references/04-qualification-verdict.md +72 -72
- package/skills/skills/designer-perspective/references/05-condition-attribution.md +74 -74
- package/skills/skills/designer-perspective/scripts/designer.py +545 -545
- package/skills/skills/designer-perspective/tests/cases.jsonl +17 -17
- package/skills/skills/designer-perspective/tests/selftest.py +61 -61
- package/skills/skills/lingshu-browser/SKILL.md +60 -60
- package/skills/skills/lingshu-compiler/SKILL.md +56 -56
- package/skills/skills/lingshu-compiler/units/analyze-type-infer/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/check-name-real/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-assign/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-expr-tree/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-full-pipeline/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-func-def/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-if-then/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-logic-expr/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-recursive/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-scope/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-type-check/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-while/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0010c4bf/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0355bffb/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0361708a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-054a0414/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05a1691a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05eeed1e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0622a1f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-08b54217/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0a62b70c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ab24d00/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e093688/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e82b966/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ee9b9b9/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0f3787e6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1028685f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-11897630/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-16661b9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1f722303/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-25be1262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2a76ba07/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2dbea54a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2df52f16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2ec2c9d2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2f8c8f39/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-38378ac7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39457d2e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39fb5926/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-47f4fbfa/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4a8cd1f1/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4b230b6b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4cbbda95/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4d5a68ff/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-56dc9bdd/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-57e76ebe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-61ff016b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-63eae588/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-64c4224b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-66377955/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-674ab4f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6af76fd6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6d979db2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6de326c0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6f1c0eea/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-724d6c9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7690177f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7b229a7d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7f471b3a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-815cad08/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-83c61634/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8c798c81/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8dd747ac/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-90324d0a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94b8d72d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94f12231/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-95937c16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98a5625b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98b4c42f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98e3894a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9bdfe4b8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9d9b4e83/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9f7be5ad/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a6daf076/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a7995a0c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a8399248/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-aabbd099/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-afe169d8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b0678bda/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b09bd196/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b1396e23/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b9b31ce0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-c10264a7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cb1e8e4b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ccafd438/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cda9c262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ce648068/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cf5776a4/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-d974e5d3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-e3979fd3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-eb1cf2b5/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ecb30d5b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f8c8b24b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f99fedbe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fa8ff5f7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fe1b058d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-chinese-program/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-dao-de-jing/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-nine-chapters/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-arithmetic/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-array-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-create/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-compare/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-jump/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-space/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-exception/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-func-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-loop-run/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-profiling/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-refcount/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-run-loop/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-short-circuit/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-guard/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-trust-accum/SKILL.md +45 -45
- package/skills/skills/lingshu-graph/SKILL.md +63 -63
- package/skills/skills/lingshu-net/SKILL.md +48 -48
- package/skills/skills/lingshu-os/SKILL.md +64 -64
- package/skills/skills/lingshu-pylang/SKILL.md +71 -71
- package/src/bridge.ts +33 -0
- package/src/hooks.ts +38 -2
- package/src/index.ts +526 -518
- package/src/lib/datapath.ts +326 -326
- package/src/lib/mdcg_client.ts +413 -413
- package/src/lib/mutual.ts +428 -428
- package/src/lib/prompt_safety.ts +62 -62
- package/src/lib/python_path.ts +71 -71
- package/src/lib/roleplay_web.ts +116 -29
- package/src/lib/token_store.ts +13 -3
- package/src/tools.ts +212 -212
- package/zcode/AGENTS.md +11 -3
- package/zcode/README.md +41 -41
- /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
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""run_tests.py · 测试一键入口(固化 `python -m` 运行约定)。
|
|
3
|
+
|
|
4
|
+
背景(2026-09-13 全面分析报告建议 #3):md_cg 包内测试普遍使用**相对导入**,
|
|
5
|
+
必须以模块方式从仓库根运行——`python -m md_cg.test_xxx`;直接
|
|
6
|
+
`python md_cg/test_xxx.py` 会因相对导入 ImportError(59/61 踩坑实测)。
|
|
7
|
+
本脚本把该约定固化为唯一入口,杜绝逐文件手敲与跑法漂移。
|
|
8
|
+
|
|
9
|
+
**本模块是包内入口**(2026-09-24 修复):原入口只在 `scripts/run_tests.py`,
|
|
10
|
+
而出货包 `files` 不含 `scripts/` —— README 写的门禁命令在安装态不存在。
|
|
11
|
+
现在 `python -m md_cg.run_tests` 恒可用;源码树里 `scripts/run_tests.py`
|
|
12
|
+
可继续作为薄封装(同一约定)。
|
|
13
|
+
|
|
14
|
+
与 scripts/ 版的两点差异(都是为了在受限宿主里可跑):
|
|
15
|
+
① 子进程输出**重定向到文件**,不用 capture_output(管道):DSH 文件沙箱
|
|
16
|
+
禁 CreatePipe(WinError 5),旧写法在受限环境里每个用例都 PermissionError
|
|
17
|
+
——表现为「全部失败」,与代码无关。日志落在 `<testlogs>/` 便于事后查。
|
|
18
|
+
② 组集合按**存在性**发现:compiler / swarm / scripts / hive 不在(安装态)
|
|
19
|
+
就自然没有目标,不报错。
|
|
20
|
+
|
|
21
|
+
用法(任意 cwd 均可,内部以本包所在仓根为 subprocess cwd):
|
|
22
|
+
python -m md_cg.run_tests # 全量(存在的组)
|
|
23
|
+
python -m md_cg.run_tests md_cg # 只跑一组:md_cg | compiler | swarm | scripts | hive
|
|
24
|
+
python -m md_cg.run_tests -k p44 # 按关键字过滤模块名
|
|
25
|
+
python -m md_cg.run_tests --jobs 1 # 串行(默认并发 4)
|
|
26
|
+
python -m md_cg.run_tests --list # 只列出目标不执行
|
|
27
|
+
|
|
28
|
+
退出码:全部通过 0,存在失败 1(可直接接 CI / 提交前门禁)。
|
|
29
|
+
"""
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import argparse
|
|
33
|
+
import concurrent.futures
|
|
34
|
+
import glob
|
|
35
|
+
import os
|
|
36
|
+
import subprocess
|
|
37
|
+
import sys
|
|
38
|
+
import tempfile
|
|
39
|
+
import time
|
|
40
|
+
|
|
41
|
+
_REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
42
|
+
#: 逐用例日志目录(重定向目标;默认临时目录,避免污染仓)
|
|
43
|
+
_LOG_DIR = os.environ.get("MDCG_TESTLOG_DIR") or os.path.join(
|
|
44
|
+
tempfile.gettempdir(), "md_cg_testlogs")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _discover():
|
|
48
|
+
"""返回 [(组名, 显示名, argv 候选列表)];argv 依次尝试直到成功启动。"""
|
|
49
|
+
out = []
|
|
50
|
+
for f in sorted(glob.glob(os.path.join(_REPO, "md_cg", "test_*.py"))):
|
|
51
|
+
stem = os.path.splitext(os.path.basename(f))[0]
|
|
52
|
+
out.append(("md_cg", f"md_cg.{stem}",
|
|
53
|
+
[[sys.executable, "-X", "utf8", "-m", f"md_cg.{stem}"]]))
|
|
54
|
+
for pkg in ("compiler", "swarm"):
|
|
55
|
+
for f in sorted(glob.glob(os.path.join(_REPO, pkg, "tests", "*.py"))):
|
|
56
|
+
if os.path.basename(f).startswith("_"):
|
|
57
|
+
continue
|
|
58
|
+
stem = os.path.splitext(os.path.basename(f))[0]
|
|
59
|
+
out.append((pkg, f"{pkg}.tests.{stem}",
|
|
60
|
+
[[sys.executable, "-X", "utf8", "-m",
|
|
61
|
+
f"{pkg}.tests.{stem}"],
|
|
62
|
+
[sys.executable, "-X", "utf8", f]]))
|
|
63
|
+
# scripts/ 不是包(无 __init__.py)→ 只能直跑;脚本内自带 sys.path 注入
|
|
64
|
+
for f in sorted(glob.glob(os.path.join(_REPO, "scripts", "test_*.py"))):
|
|
65
|
+
stem = os.path.splitext(os.path.basename(f))[0]
|
|
66
|
+
out.append(("scripts", f"scripts.{stem}",
|
|
67
|
+
[[sys.executable, "-X", "utf8", f]]))
|
|
68
|
+
# hive/ 是包 → -m 优先;测试内用 importlib 直载,故回退直跑同样可用。
|
|
69
|
+
for f in sorted(glob.glob(os.path.join(_REPO, "hive", "test_*.py"))):
|
|
70
|
+
stem = os.path.splitext(os.path.basename(f))[0]
|
|
71
|
+
out.append(("hive", f"hive.{stem}",
|
|
72
|
+
[[sys.executable, "-X", "utf8", "-m", f"hive.{stem}"],
|
|
73
|
+
[sys.executable, "-X", "utf8", f]]))
|
|
74
|
+
return out
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# 生效条件:name/argvs/timeout 就绪时逐个 argv 尝试运行(cwd=_REPO,stdout+stderr 重定向到 _LOG_DIR/<name>.log,无管道),返回 (name, 是否通过, 日志尾部最多 800 字符);超时返回 (name, False, "超时(>Ns)");首个成功启动(非「No module named」回退)的尝试决定结果。
|
|
78
|
+
def _run_one(name, argvs, timeout):
|
|
79
|
+
"""跑一个用例;输出**重定向到文件**(不用管道——沙箱禁 CreatePipe)。"""
|
|
80
|
+
os.makedirs(_LOG_DIR, exist_ok=True)
|
|
81
|
+
env = dict(os.environ, PYTHONUTF8="1", PYTHONIOENCODING="utf-8")
|
|
82
|
+
last = ""
|
|
83
|
+
for argv in argvs: # -m 优先;No module named 时回退直跑
|
|
84
|
+
log = os.path.join(_LOG_DIR, name.replace(".", "_") + ".log")
|
|
85
|
+
t0 = time.time()
|
|
86
|
+
try:
|
|
87
|
+
with open(log, "wb") as fh:
|
|
88
|
+
p = subprocess.run(argv, cwd=_REPO, stdout=fh,
|
|
89
|
+
stderr=subprocess.STDOUT,
|
|
90
|
+
stdin=subprocess.DEVNULL, env=env,
|
|
91
|
+
shell=False, timeout=timeout)
|
|
92
|
+
rc = p.returncode
|
|
93
|
+
except subprocess.TimeoutExpired:
|
|
94
|
+
return name, False, f"超时(>{timeout}s)—— 日志 {log}"
|
|
95
|
+
except OSError as exc:
|
|
96
|
+
return name, False, f"无法启动子进程:{exc!r}(日志 {log})"
|
|
97
|
+
try:
|
|
98
|
+
with open(log, encoding="utf-8", errors="replace") as fh:
|
|
99
|
+
text = fh.read()
|
|
100
|
+
except OSError:
|
|
101
|
+
text = ""
|
|
102
|
+
if rc != 0 and "No module named" in text and len(argvs) > 1:
|
|
103
|
+
last = text[-300:]
|
|
104
|
+
continue
|
|
105
|
+
tail = text[-800:]
|
|
106
|
+
return name, rc == 0, f"[{time.time() - t0:.1f}s] " + tail
|
|
107
|
+
return name, False, last
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _dep_db():
|
|
111
|
+
p = os.path.join(_REPO, "md_cg", "whitebox_kb", "wisdom",
|
|
112
|
+
"wisdom-book-cloud.db")
|
|
113
|
+
return (None if os.path.exists(p)
|
|
114
|
+
else "依赖白箱库 whitebox_kb/wisdom/wisdom-book-cloud.db"
|
|
115
|
+
"(.gitignore 忽略,需本地生成)")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _dep_mdroot():
|
|
119
|
+
"""md 语料真源依赖:目录存在**且含 .md** 才算就绪。
|
|
120
|
+
|
|
121
|
+
空壳目录不算(v14 缺陷 F:旁路执行造出的空 `_md_cg_wisdom_graph/` 曾把
|
|
122
|
+
runner 从 SKIP 翻成 FAIL)——判据必须与 test_md_access_parity 同口径。
|
|
123
|
+
"""
|
|
124
|
+
p = os.path.join(_REPO, "_md_cg_wisdom_graph")
|
|
125
|
+
if not os.path.isdir(p):
|
|
126
|
+
return ("依赖 md 语料真源 _md_cg_wisdom_graph/(.gitignore 忽略,"
|
|
127
|
+
"组 D 需本地真源)")
|
|
128
|
+
for _dirpath, _dirs, names in os.walk(p):
|
|
129
|
+
if any(n.endswith(".md") for n in names):
|
|
130
|
+
return None
|
|
131
|
+
return ("依赖 md 语料真源 _md_cg_wisdom_graph/(目录在但零 .md:"
|
|
132
|
+
"空壳目录不算依赖就绪)")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# 裸 clone 环境 SKIP 探测(2026-09-14 外部复核建议 #3):
|
|
136
|
+
# 依赖 gitignored 本地数据或特定平台的测试,依赖缺失时标 SKIP(附原因)
|
|
137
|
+
# 不计入失败——避免裸 clone 用户第一眼看到虚假 FAIL(复核实测 83/87 根因)。
|
|
138
|
+
_SKIPS = {
|
|
139
|
+
"md_cg.test_p44_md_whitebox": _dep_db,
|
|
140
|
+
"md_cg.test_md_access_parity": _dep_db,
|
|
141
|
+
"md_cg.test_wisdom_md_store": _dep_mdroot,
|
|
142
|
+
"swarm.tests.test_swarm_fault": (
|
|
143
|
+
lambda: None if os.name == "nt"
|
|
144
|
+
else "Windows 专用(powershell/taskkill)"),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# 生效条件:argv 就绪时解析组/-k/--jobs/--timeout/--list 参数,按 _discover() 与 _SKIPS 过滤后并发执行,打印 PASS/FAIL/SKIP 与汇总;全部通过返回 0、有失败返回 1、--list 恒返回 0。
|
|
149
|
+
def main(argv=None):
|
|
150
|
+
ap = argparse.ArgumentParser(
|
|
151
|
+
prog="python -m md_cg.run_tests",
|
|
152
|
+
description="灵枢测试入口(python -m 约定;输出重定向,沙箱安全)")
|
|
153
|
+
# 注:不用 argparse choices——部分 Python 版本对 nargs="*" 无值时
|
|
154
|
+
# 以空列表过 choices 校验会误报 invalid choice(bpo-27227 老行为)。
|
|
155
|
+
ap.add_argument("group", nargs="*", default=None,
|
|
156
|
+
help="只跑指定组,可多选:md_cg compiler swarm scripts hive"
|
|
157
|
+
"(缺省全量)")
|
|
158
|
+
ap.add_argument("-k", default="", help="按关键字过滤模块名")
|
|
159
|
+
ap.add_argument("--jobs", type=int, default=4, help="并发数(默认 4)")
|
|
160
|
+
ap.add_argument("--timeout", type=int, default=900, help="单测超时秒数")
|
|
161
|
+
ap.add_argument("--list", action="store_true", help="只列出目标不执行")
|
|
162
|
+
args = ap.parse_args(argv)
|
|
163
|
+
|
|
164
|
+
_known = ("md_cg", "compiler", "swarm", "scripts", "hive")
|
|
165
|
+
_bad = [g for g in (args.group or ()) if g not in _known]
|
|
166
|
+
if _bad:
|
|
167
|
+
ap.error(f"invalid group: {', '.join(_bad)}(可选:{'/'.join(_known)})")
|
|
168
|
+
groups = set(args.group or ()) or set(_known)
|
|
169
|
+
targets = [(g, n, a) for g, n, a in _discover()
|
|
170
|
+
if g in groups and (not args.k or args.k in n)]
|
|
171
|
+
if args.list:
|
|
172
|
+
for g, n, _a in targets:
|
|
173
|
+
print(f"{g:<9}{n}")
|
|
174
|
+
print(f"共 {len(targets)} 个")
|
|
175
|
+
return 0
|
|
176
|
+
|
|
177
|
+
# SKIP 探测:依赖缺失/平台不符的测试不执行(外部复核建议 #3,裸 clone 友好)
|
|
178
|
+
skipped, runnable = [], []
|
|
179
|
+
for g, n, a in targets:
|
|
180
|
+
probe = _SKIPS.get(n)
|
|
181
|
+
reason = probe() if probe else None
|
|
182
|
+
if reason:
|
|
183
|
+
skipped.append((n, reason))
|
|
184
|
+
print(f"SKIP {n} ({reason})", flush=True)
|
|
185
|
+
else:
|
|
186
|
+
runnable.append((g, n, a))
|
|
187
|
+
|
|
188
|
+
bad = []
|
|
189
|
+
with concurrent.futures.ThreadPoolExecutor(
|
|
190
|
+
max_workers=max(1, args.jobs)) as ex:
|
|
191
|
+
futs = {ex.submit(_run_one, n, a, args.timeout): (g, n)
|
|
192
|
+
for g, n, a in runnable}
|
|
193
|
+
for fu in concurrent.futures.as_completed(futs):
|
|
194
|
+
name, ok, tail = fu.result()
|
|
195
|
+
print(("PASS " if ok else "FAIL ") + name, flush=True)
|
|
196
|
+
if not ok:
|
|
197
|
+
bad.append(name)
|
|
198
|
+
for ln in tail.splitlines()[-6:]:
|
|
199
|
+
print(" " + ln, flush=True)
|
|
200
|
+
|
|
201
|
+
print(f"\n===== SUMMARY {len(runnable) - len(bad)}/{len(runnable)} 通过,"
|
|
202
|
+
f"{len(skipped)} 跳过(依赖缺失/平台不符) =====")
|
|
203
|
+
print(f"逐用例日志:{_LOG_DIR}")
|
|
204
|
+
if bad:
|
|
205
|
+
print("失败:" + ", ".join(bad))
|
|
206
|
+
return 1
|
|
207
|
+
return 0
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
sys.exit(main())
|
package/md_cg/scrub.py
CHANGED
|
@@ -45,7 +45,7 @@ import os
|
|
|
45
45
|
import random
|
|
46
46
|
import time
|
|
47
47
|
|
|
48
|
-
from . import forgetting, protect
|
|
48
|
+
from . import forgetting, nodefile, protect
|
|
49
49
|
from .fsutil import append_jsonl, read_jsonl
|
|
50
50
|
from .mdcg import bigrams
|
|
51
51
|
|
|
@@ -450,7 +450,12 @@ def _kv_pairs(content) -> dict:
|
|
|
450
450
|
if sep in line:
|
|
451
451
|
k, _, v = line.partition(sep)
|
|
452
452
|
k, v = k.strip(), v.strip()
|
|
453
|
-
|
|
453
|
+
# CCG 六要素行(`# 功能名:` / `# 不适用条件:` …)是**逐节点声明**,
|
|
454
|
+
# 不是可跨节点比对的断言值。把「不适用条件」当键会让语义无关的节点
|
|
455
|
+
# 互为「同键不同值」矛盾(实测 12 抽样里 9 条 high 全是这类误报,
|
|
456
|
+
# 且 apply 会把好节点 weaken+demote 并跨层移动文件)。
|
|
457
|
+
if (2 <= len(k) <= 12 and v and k not in _SKIP_KEYS
|
|
458
|
+
and not nodefile.is_ccg_mark(k)):
|
|
454
459
|
out.setdefault(k, v)
|
|
455
460
|
break
|
|
456
461
|
return out
|
|
@@ -642,7 +647,12 @@ def decontaminate(cg, node_ids=None, *, kinds=None, dry_run: bool = True,
|
|
|
642
647
|
nid, kind = issue["node_id"], issue["kind"]
|
|
643
648
|
if kinds and kind not in kinds:
|
|
644
649
|
continue
|
|
645
|
-
|
|
650
|
+
# 只给建议的动作必须按 CONTAMINATION 的**声明**判定,不能靠 kind 白名单:
|
|
651
|
+
# `not_yet` 声明 fix=("hint",),原实现只排除 duplicate/unverified,
|
|
652
|
+
# 于是它会落到 _weaken 分支(实测 min_severity="info" 时 confidence
|
|
653
|
+
# 0.6→0.45、negative_evidence 0→1),声明与实修不一致。
|
|
654
|
+
_declared = CONTAMINATION.get(kind, (None, ()))[1]
|
|
655
|
+
if kind in ("duplicate", "unverified") or _declared == ("hint",):
|
|
646
656
|
n_hint += 1
|
|
647
657
|
actions.append({"node_id": nid, "kind": kind, "action": "hint",
|
|
648
658
|
"detail": issue["detail"], "applied": False})
|
package/md_cg/security.py
CHANGED
|
@@ -20,12 +20,44 @@ import os
|
|
|
20
20
|
import time
|
|
21
21
|
import uuid
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
from .datapath import aux_root
|
|
24
|
+
from .fsutil import publish
|
|
25
|
+
|
|
26
|
+
# 密级阶梯的体系语义(批次 27 表述正名,使用者 2026-09-24 澄清):
|
|
27
|
+
# private ≠ 个人隐私保密,而是**错误处置标记**——工作区内容因错误相关、
|
|
28
|
+
# 验证未过、待排查而被标记私有,目的是**限制向平级/下级扩散**(防止未
|
|
29
|
+
# 证实或已知有误的内容被下游消费),不是对错误处置链路保密。
|
|
30
|
+
# 可见性是**故意的冲突设计**:平级/下级限读,但错误处置链路必须可读——
|
|
31
|
+
# 设计者(designer,secret 上限)、上级节点、验证单元(verify)三者
|
|
32
|
+
# 必读。当前令牌矩阵中 record/reflect/verify/sustain/orchestr 的
|
|
33
|
+
# clearance_cap 均为 internal(forbidden 含 private)——验证单元读错误
|
|
34
|
+
# 标记节点是本职却受限于 cap,属**已登记的分级缺口**(见安全审计实锚
|
|
35
|
+
# 文档「读权限分级」节),未来专项:verify 面提 cap 或走设计者代查通道。
|
|
36
|
+
# 密级阶梯的体系语义(批次 27 正名 / 批次 28 分型落地,使用者 2026-09-24):
|
|
37
|
+
# **restricted = 错误处置标记(新增档)**——内容因错误相关、验证未过、
|
|
38
|
+
# 待排查被标记,目的是限制向平级/下级扩散;可见性按**错误处置链路角色**
|
|
39
|
+
# 判定(designer/orchestr/verify 必读,record/worker/output/guest 限读),
|
|
40
|
+
# 不走纯密级 rank(链路角色与平级同为 internal,rank 无法区分);
|
|
41
|
+
# **不加密**(不在 crypto.ENCRYPTED_LEVELS——链路要明文读)。
|
|
42
|
+
# private = 隐私/会话绑定档(语义不变:仅归属会话 + 设计者豁免可见,
|
|
43
|
+
# 落盘加密);secret = 最高密级。
|
|
44
|
+
# 可见性的故意冲突设计就此消解:错误标记限扩散但处置链路必读,
|
|
45
|
+
# 隐私内容写者私有——两种语义不再共用一个密级档。
|
|
46
|
+
SENSITIVITY_ORDER = ("public", "internal", "restricted", "private", "secret")
|
|
24
47
|
DEFAULT_SENSITIVITY = "internal"
|
|
25
48
|
|
|
26
49
|
|
|
27
50
|
class AccessDenied(Exception):
|
|
28
|
-
"""权限拒绝(读/写/管理)。
|
|
51
|
+
"""权限拒绝(读/写/管理)。
|
|
52
|
+
|
|
53
|
+
hint(可选):与本仓 70 处失败路径 hint 同口径的「为什么 + 怎么办」可操作
|
|
54
|
+
指引(issue #34:新用户首个错误无可操作指引——guest 只读写入被拒恰是
|
|
55
|
+
三步接入后必然撞上的第一条失败,不得只说「不行」不说「怎么办」)。
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, msg: str, hint: str = None):
|
|
59
|
+
super().__init__(msg)
|
|
60
|
+
self.hint = hint
|
|
29
61
|
|
|
30
62
|
|
|
31
63
|
# 生效条件:形参 level 为模块级常量 SENSITIVITY_ORDER 中的元素时返回其下标,否则抛 AccessDenied。
|
|
@@ -128,18 +160,40 @@ class Principal:
|
|
|
128
160
|
|
|
129
161
|
# ---------- 强制校验(越权即 AccessDenied) ----------
|
|
130
162
|
|
|
131
|
-
# 生效条件:无 required 形参或模块级常量前置,当 self.expired()(来自 __init__ 的 expires_at 与当前时间比较)为 True 时抛 AccessDenied
|
|
163
|
+
# 生效条件:无 required 形参或模块级常量前置,当 self.expired()(来自 __init__ 的 expires_at 与当前时间比较)为 True 时抛 AccessDenied(带重新签发 hint),否则无操作返回 None。
|
|
132
164
|
def _require_live(self):
|
|
133
165
|
if self.expired():
|
|
134
|
-
raise AccessDenied(
|
|
135
|
-
|
|
136
|
-
|
|
166
|
+
raise AccessDenied(
|
|
167
|
+
f"actor={self.actor} 令牌已过期",
|
|
168
|
+
hint="令牌过期不是故障:重新签发并更新 MDCG_TOKEN 后重启宿主"
|
|
169
|
+
"(python -m md_cg.tokens issue …,README「写入凭据」一节)。")
|
|
170
|
+
|
|
171
|
+
# issue #34:op 拒绝按成因分指引——guest(无令牌只读访客)引导配凭据;
|
|
172
|
+
# 有令牌但白名单不含该 op 引导换角色/补授权。「不是故障」安抚语气与
|
|
173
|
+
# 本仓其它 70 处 hint 同口径。
|
|
174
|
+
_GUEST_OP_HINT = (
|
|
175
|
+
"当前为只读访客模式(未检测到写入凭据 MDCG_TOKEN):读/召回/时间线可用,"
|
|
176
|
+
"写入与管理操作不落盘。这不是故障,配置凭据后即恢复。"
|
|
177
|
+
"要真正落盘请签发并配置写入凭据(README「写入凭据」一节):\n"
|
|
178
|
+
" python -m md_cg.tokens issue --role recorder --actor <名> "
|
|
179
|
+
"--clearance internal\n"
|
|
180
|
+
" setx MDCG_TOKEN \"<token>\" # 然后重启宿主(DSH/IDE)\n"
|
|
181
|
+
"最小权限可用 --role recorder;op 用法可查 cg(op=\"help\", query=\"write\")。")
|
|
182
|
+
|
|
183
|
+
# 生效条件:先调用 self._require_live()(过期则抛 AccessDenied);再要求 self.allows_op(op) 为 True,否则抛 AccessDenied(role=guest 带配凭据 hint,其它角色带补授权 hint)。
|
|
137
184
|
def require_op(self, op: str):
|
|
138
185
|
self._require_live()
|
|
139
186
|
if not self.allows_op(op):
|
|
187
|
+
msg = (f"角色 {self.role} 无权执行 op={op}(作用域 "
|
|
188
|
+
f"{list(self.ops_allow) if self.ops_allow is not None else '不限'})")
|
|
189
|
+
if self.role == "guest":
|
|
190
|
+
raise AccessDenied(msg, hint=self._GUEST_OP_HINT)
|
|
140
191
|
raise AccessDenied(
|
|
141
|
-
|
|
142
|
-
f"{
|
|
192
|
+
msg,
|
|
193
|
+
hint=f"当前令牌(actor={self.actor},角色 {self.role})的 ops "
|
|
194
|
+
f"白名单不含 {op},属正常闸门不是故障。可:①换用含该 op "
|
|
195
|
+
f"的角色令牌;②由签发者以 --ops-allow 补授权后重新签发"
|
|
196
|
+
f"(python -m md_cg.tokens issue …,README「写入凭据」一节)。")
|
|
143
197
|
|
|
144
198
|
# 生效条件:依次要求 self._require_live() 未抛异常、self.theory_ok 为 True、self.can_write 为 True、self.allows(sensitivity) 为 True;任一不满足则抛 AccessDenied。
|
|
145
199
|
def require_write(self, sensitivity: str):
|
|
@@ -149,7 +203,12 @@ class Principal:
|
|
|
149
203
|
"版本层校验未通过(theory_ok=False):全部写操作被拒,"
|
|
150
204
|
"仅保留 theory 修复入口")
|
|
151
205
|
if not self.can_write:
|
|
152
|
-
raise AccessDenied(
|
|
206
|
+
raise AccessDenied(
|
|
207
|
+
f"actor={self.actor} 无写权限",
|
|
208
|
+
hint=(self._GUEST_OP_HINT if self.role == "guest" else
|
|
209
|
+
f"当前令牌(角色 {self.role})未授予写权限(can_write="
|
|
210
|
+
f"False),属正常闸门不是故障。请换用可写角色令牌或由"
|
|
211
|
+
f"签发者重新签发(README「写入凭据」一节)。"))
|
|
153
212
|
if not self.allows(sensitivity):
|
|
154
213
|
raise AccessDenied(
|
|
155
214
|
f"写入敏感度 {sensitivity} 超出 clearance {self.clearance}")
|
|
@@ -196,40 +255,47 @@ class Principal:
|
|
|
196
255
|
f"write={self.can_write}, admin={self.can_admin})")
|
|
197
256
|
|
|
198
257
|
|
|
199
|
-
# 生效条件:path 为 None 时落至
|
|
258
|
+
# 生效条件:path 为 None 时落至 datapath.aux_root()(默认 ~/.mdcg,可经 MDCG_AUX_ROOT 改)下的 _tenants.json,path 非 None(含空串)时按传入值使用,并在构造内以 self._load() 的返回填充 self.data、以 self.load_error 留存加载期损坏留痕(N124,2026-09-25:登记表损坏/不可读必须可被调用方感知,缺文件不算损坏)。
|
|
200
259
|
class TenantRegistry:
|
|
201
260
|
"""租户注册表:tenant → {root, clearance_cap, description}。
|
|
202
261
|
|
|
203
262
|
默认位置:<registry_dir>/_tenants.json(默认 ~/.mdcg/)。
|
|
204
263
|
设计意图:私有租户的 root 指向仓库外目录,开源仓库里只放 public 租户的根。
|
|
264
|
+
|
|
265
|
+
load_error(N124,2026-09-25):_load 遇「文件在但损坏/不可读」(JSON
|
|
266
|
+
解析失败、OSError、顶层非对象)时留存原因字符串,完好/缺文件为 None——
|
|
267
|
+
供 _resolve_root 等调用方把「静默回落空表」开口成 stderr 告警。
|
|
205
268
|
"""
|
|
206
269
|
|
|
207
|
-
# 生效条件:形参 path 为 None 时取 ~/.mdcg/_tenants.json,否则取 path;self.data 初始化为 _load() 结果(self.path 经 os.path.exists 为真且 JSON 解析为 dict 时取该 dict,否则回落 {"schema":1,"tenants":{}}
|
|
270
|
+
# 生效条件:形参 path 为 None 时取 ~/.mdcg/_tenants.json,否则取 path;self.load_error 置 None 后 self.data 初始化为 _load() 结果(self.path 经 os.path.exists 为真且 JSON 解析为 dict 时取该 dict,否则回落 {"schema":1,"tenants":{}};文件在但解析失败/OSError/顶层非对象时先置 self.load_error 为原因串,缺文件不置)。
|
|
208
271
|
def __init__(self, path: str = None):
|
|
209
272
|
if path is None:
|
|
210
|
-
path = os.path.join(
|
|
273
|
+
path = os.path.join(aux_root(), "_tenants.json")
|
|
211
274
|
self.path = path
|
|
275
|
+
self.load_error = None
|
|
212
276
|
self.data = self._load()
|
|
213
277
|
|
|
214
|
-
#
|
|
278
|
+
# 生效条件:先置 self.load_error=None;当 self.path 经 os.path.exists 为真且内容可解析为 dict 时返回该 dict;解析失败或 OSError 时置 self.load_error=f"{类型名}: {e}"、顶层 JSON 非对象时置 self.load_error="登记表 JSON 顶层不是对象";否则(os.path.exists 为假)不留痕;各回落分支均返回 {"schema":1,"tenants":{}}。
|
|
215
279
|
def _load(self):
|
|
280
|
+
self.load_error = None
|
|
216
281
|
if os.path.exists(self.path):
|
|
217
282
|
try:
|
|
218
283
|
with open(self.path, encoding="utf-8") as f:
|
|
219
284
|
d = json.load(f)
|
|
220
285
|
if isinstance(d, dict):
|
|
221
286
|
return d
|
|
222
|
-
|
|
223
|
-
|
|
287
|
+
self.load_error = "登记表 JSON 顶层不是对象"
|
|
288
|
+
except (ValueError, OSError) as e:
|
|
289
|
+
self.load_error = f"{type(e).__name__}: {e}"
|
|
224
290
|
return {"schema": 1, "tenants": {}}
|
|
225
291
|
|
|
226
|
-
# 生效条件:无 required 形参或模块级常量前置,将 self.data 以 JSON 写入 self.path + ".tmp",随后 os.replace
|
|
292
|
+
# 生效条件:无 required 形参或模块级常量前置,将 self.data 以 JSON 写入 self.path + ".tmp",随后 publish(带 Windows 短重试的 os.replace)到 self.path;目录名称为空时用 "." 创建。
|
|
227
293
|
def _save(self):
|
|
228
294
|
os.makedirs(os.path.dirname(self.path) or ".", exist_ok=True)
|
|
229
295
|
tmp = self.path + ".tmp"
|
|
230
296
|
with open(tmp, "w", encoding="utf-8") as f:
|
|
231
297
|
json.dump(self.data, f, ensure_ascii=False, indent=1)
|
|
232
|
-
|
|
298
|
+
publish(tmp, self.path)
|
|
233
299
|
|
|
234
300
|
# 生效条件:形参 clearance_cap 须为模块级常量 SENSITIVITY_ORDER 成员(否则 _rank 抛 AccessDenied);形参 tenant/root 提供后写入 self.data["tenants"](要求 self.data 含 "tenants" 键,否则 KeyError),_save 成功则返回新登记项。
|
|
235
301
|
def register(self, tenant: str, root: str, clearance_cap: str = DEFAULT_SENSITIVITY,
|
|
@@ -272,4 +338,48 @@ class TenantRegistry:
|
|
|
272
338
|
if _rank(want) > _rank(cap):
|
|
273
339
|
want = cap
|
|
274
340
|
return Principal(tenant=tenant, actor=actor or tenant, clearance=want,
|
|
275
|
-
can_write=can_write, can_admin=can_admin, session=session)
|
|
341
|
+
can_write=can_write, can_admin=can_admin, session=session)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
# P1-4(批次 26,外部审查报告):工具路径参数的根白名单——ingest/export/link
|
|
345
|
+
# 的 path/out 是模型可控输入,原样透传 = 任意文件读(/etc/passwd 进图)与
|
|
346
|
+
# 任意文件写(evidence export 的 out)。校验语义与 HIVE_READ_ROOTS 同构:
|
|
347
|
+
# **env 未设置 = 放开**(默认部署零行为变更,与 2026-09-19 的读放开裁定
|
|
348
|
+
# 精神一致);**设置了 = realpath 落根内否则拒**(fail-closed),`..` 与
|
|
349
|
+
# 绝对路径穿越在 realpath 归一后自然被涵盖。支持 os.pathsep 分隔多根。
|
|
350
|
+
# 生效条件:env_var 环境变量去空白后为空、或 path 为 None/空串时直接返回(不约束);否则取 realpath(expanduser(path)),与 env 值按 os.pathsep 切分的每个根做「相等或以根+os.sep 为前缀」判定,任一命中即返回;全部未命中抛 PermissionError(含 what/原 path/realpath/roots 的拒绝说明)。
|
|
351
|
+
def check_path_root(path, env_var: str, what: str) -> None:
|
|
352
|
+
raw = (os.environ.get(env_var) or "").strip()
|
|
353
|
+
if not raw:
|
|
354
|
+
return # 未配置 = 放开(部署开关)
|
|
355
|
+
if path is None or str(path).strip() == "":
|
|
356
|
+
return # 无路径参数(如 stat/action)
|
|
357
|
+
roots = []
|
|
358
|
+
for p in raw.split(os.pathsep):
|
|
359
|
+
p = p.strip()
|
|
360
|
+
if p:
|
|
361
|
+
roots.append(os.path.realpath(os.path.expanduser(p)))
|
|
362
|
+
real = os.path.realpath(os.path.expanduser(str(path)))
|
|
363
|
+
for r in roots:
|
|
364
|
+
if real == r or real.startswith(r.rstrip(os.sep) + os.sep):
|
|
365
|
+
return
|
|
366
|
+
raise PermissionError(
|
|
367
|
+
f"{what} 路径超出 {env_var} 白名单,拒绝访问:{path} "
|
|
368
|
+
f"(realpath={real}, roots={roots})——路径类工具参数的根约束"
|
|
369
|
+
"(P1-4),部署用该环境变量声明可读写的根目录")
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
# 错误处置链路角色集(批次 28 分型):restricted(错误处置标记)的可见性
|
|
373
|
+
# 不走密级 rank——链路角色与平级同为 internal,rank 无法区分「处置者」与
|
|
374
|
+
# 「扩散面」。designer=全局观测本职;orchestr=上级节点(拆解派发/裁决
|
|
375
|
+
# 收口);verify=验证本职(错误标记节点是验证的对象)。
|
|
376
|
+
_RESTRICTED_READER_ROLES = ("designer", "orchestr", "verify")
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
# 生效条件:p 为 Principal 或 None;p 为 None 返回 False;p.can_admin 为真(设计者)或 p.role 属 _RESTRICTED_READER_ROLES 时返回 True,否则返回 False。
|
|
380
|
+
def can_read_restricted(p) -> bool:
|
|
381
|
+
if p is None:
|
|
382
|
+
return False
|
|
383
|
+
if getattr(p, "can_admin", False):
|
|
384
|
+
return True
|
|
385
|
+
return getattr(p, "role", "") in _RESTRICTED_READER_ROLES
|