@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
package/md_cg/weights.py
CHANGED
|
@@ -1,625 +1,625 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""位置权重矩阵(序标定)——「不同身份,参数偏好不同」。
|
|
3
|
-
|
|
4
|
-
理论出处(本仓原文,非外部知识)
|
|
5
|
-
--------------------------------
|
|
6
|
-
`docs/theory/智能的公理化基石.md` §4.3:信任合成是
|
|
7
|
-
P_trust = f(一致性, 位置可预测性, 版本对齐度)
|
|
8
|
-
其中 `版本对齐度` 已由 `theory` + `links.version_alignment` 提供,
|
|
9
|
-
`位置可预测性` 见 `predict`,`一致性` 见 `consistency`。本模块只补一件
|
|
10
|
-
此前缺失的东西:**三个分量在不同位置下的偏好序**。
|
|
11
|
-
|
|
12
|
-
六个位置分为**两类**(由功能身份决定,非人为指定):
|
|
13
|
-
|
|
14
|
-
· 认知视角(viewpoint):设计者 / 反思 / 验证
|
|
15
|
-
——「思考的不同视角」,**三分量都涉及**,只标定主导,**不设零**。
|
|
16
|
-
· 功能单元(functional):记录 / 输出 / 维生
|
|
17
|
-
——功能需求决定,**身份即排除**:主导 + 明确排除一项(≈0)。
|
|
18
|
-
|
|
19
|
-
排除项可**推导**(派生律:功能身份 → 缺失分量),不是选出来的:
|
|
20
|
-
|
|
21
|
-
· 记录单元**不猜** → 不做预测 → 排除 位置可预测性
|
|
22
|
-
· 输出单元**不记** → 不复现对账 → 排除 一致性
|
|
23
|
-
· 维生系统**不对外** → 无外部协议 → 排除 版本对齐度
|
|
24
|
-
|
|
25
|
-
设计者定位(本轮裁决):
|
|
26
|
-
· **不参与日常评估**——它是元视角,思考总体规律;细节由反思/验证承担,
|
|
27
|
-
否则要做全局细节整理,耗时极长。
|
|
28
|
-
|
|
29
|
-
可推导不变量(`invariants()` 逐条自检)
|
|
30
|
-
--------------------------------------
|
|
31
|
-
1. **排除唯一**——每个分量恰被 **1** 个位置排除;因视角「3 项都涉及」,
|
|
32
|
-
故每个分量的参与度 = **5/6**(不是 3/6);
|
|
33
|
-
2. **排除项只属功能单元**,且 A/B/C 各被排除一次;
|
|
34
|
-
3. **视角主导 ↔ 功能单元排除**一一配对:
|
|
35
|
-
设计者(A)↔维生、反思(B)↔记录、验证(C)↔输出。
|
|
36
|
-
|
|
37
|
-
诚实边界
|
|
38
|
-
--------
|
|
39
|
-
· 本模块只声明**序**(谁能压过谁),**不宣称数值**——与 `links.py` 的
|
|
40
|
-
`UP_STEP`/`DECAY_DAYS` 同一纪律(文档 §4.3:「v0.1 只声明结构」)。
|
|
41
|
-
· `blend()` 里的权重是**占位值**(用序秩当量级),仅供仿真,标定属 v0.3。
|
|
42
|
-
|
|
43
|
-
零第三方依赖。
|
|
44
|
-
"""
|
|
45
|
-
from __future__ import annotations
|
|
46
|
-
|
|
47
|
-
import math
|
|
48
|
-
import os
|
|
49
|
-
import time
|
|
50
|
-
|
|
51
|
-
from .fsutil import append_jsonl, read_jsonl
|
|
52
|
-
|
|
53
|
-
# --------------------------------------------------------------------------
|
|
54
|
-
# 常量
|
|
55
|
-
# --------------------------------------------------------------------------
|
|
56
|
-
|
|
57
|
-
#: 三个分量(顺序即 A/B/C,稳定,供外部按位引用)
|
|
58
|
-
COMPONENTS = ("version_alignment", "predictability", "consistency")
|
|
59
|
-
|
|
60
|
-
#: 分量中文名(日志/自描述用)
|
|
61
|
-
COMPONENT_LABELS = {
|
|
62
|
-
"version_alignment": "版本对齐度",
|
|
63
|
-
"predictability": "位置可预测性",
|
|
64
|
-
"consistency": "一致性",
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
#: 位置类别
|
|
68
|
-
VIEWPOINT = "viewpoint" # 认知视角:3 项都涉及,只标主导,不设零
|
|
69
|
-
FUNCTIONAL = "functional" # 功能单元:主导 + 明确排除一项
|
|
70
|
-
|
|
71
|
-
#: 位置 → 权重序规格
|
|
72
|
-
#: primary 主导分量(权重最高)
|
|
73
|
-
#: secondary 次主导分量(功能单元的第二个偏好;视角为 None=另两项并列)
|
|
74
|
-
#: excluded 被排除分量(≈0;仅功能单元有;视角为 None=不设零)
|
|
75
|
-
SPEC = {
|
|
76
|
-
# ---- 认知视角(不参与日常评估者仅 designer)----
|
|
77
|
-
"designer": {"class": VIEWPOINT, "primary": "version_alignment",
|
|
78
|
-
"secondary": None, "excluded": None},
|
|
79
|
-
"reflect": {"class": VIEWPOINT, "primary": "predictability",
|
|
80
|
-
"secondary": None, "excluded": None},
|
|
81
|
-
"verify": {"class": VIEWPOINT, "primary": "consistency",
|
|
82
|
-
"secondary": None, "excluded": None},
|
|
83
|
-
# ---- 功能单元(身份即排除)----
|
|
84
|
-
"record": {"class": FUNCTIONAL, "primary": "consistency",
|
|
85
|
-
"secondary": "version_alignment", "excluded": "predictability"},
|
|
86
|
-
"output": {"class": FUNCTIONAL, "primary": "predictability",
|
|
87
|
-
"secondary": "version_alignment", "excluded": "consistency"},
|
|
88
|
-
"sustain": {"class": FUNCTIONAL, "primary": "consistency",
|
|
89
|
-
"secondary": "predictability", "excluded": "version_alignment"},
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
POSITION_ORDER = ("designer", "record", "reflect", "verify", "output", "sustain")
|
|
93
|
-
|
|
94
|
-
#: 参与**日常评估**的位置(设计者是元参照系,不入日常)
|
|
95
|
-
DAILY = ("record", "reflect", "verify", "output", "sustain")
|
|
96
|
-
|
|
97
|
-
#: 序秩(占位量级,仅仿真用):主导 2 / 次主导 1 / 排除 0;视角另两项 = 1
|
|
98
|
-
RANK_PRIMARY = 2.0
|
|
99
|
-
RANK_SECONDARY = 1.0
|
|
100
|
-
RANK_EXCLUDED = 0.0
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
class WeightError(Exception):
|
|
104
|
-
"""未知位置 / 未知分量。"""
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# --------------------------------------------------------------------------
|
|
108
|
-
# 基础查询
|
|
109
|
-
# --------------------------------------------------------------------------
|
|
110
|
-
|
|
111
|
-
# 生效条件:position 经 str(position or "").strip() 作为 SPEC 的键,命中时返回对应 spec dict,未命中(含 position 为 None/空串/未知)抛 WeightError;
|
|
112
|
-
def _spec(position: str) -> dict:
|
|
113
|
-
s = SPEC.get(str(position or "").strip())
|
|
114
|
-
if s is None:
|
|
115
|
-
raise WeightError(f"未知位置:{position!r}(允许:{POSITION_ORDER})")
|
|
116
|
-
return s
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# 生效条件:component 经 str(component or "").strip() 后若结果在 COMPONENTS 中返回该规范分量字符串,否则抛 WeightError;
|
|
120
|
-
def _comp(component: str) -> str:
|
|
121
|
-
c = str(component or "").strip()
|
|
122
|
-
if c not in COMPONENTS:
|
|
123
|
-
raise WeightError(f"未知分量:{component!r}(允许:{COMPONENTS})")
|
|
124
|
-
return c
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
# 生效条件:position 可被 _spec 解析且其结果 "class" 等于 VIEWPOINT 时返回 True,非 VIEWPOINT 返回 False,未知 position 抛 WeightError;
|
|
128
|
-
def is_viewpoint(position: str) -> bool:
|
|
129
|
-
"""是否认知视角(3 项都涉及,不设零)。"""
|
|
130
|
-
return _spec(position)["class"] == VIEWPOINT
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
# 生效条件:position 可被 _spec 解析且其结果 "class" 等于 FUNCTIONAL 时返回 True,非 FUNCTIONAL 返回 False,未知 position 抛 WeightError;
|
|
134
|
-
def is_functional(position: str) -> bool:
|
|
135
|
-
"""是否功能单元(身份即排除)。"""
|
|
136
|
-
return _spec(position)["class"] == FUNCTIONAL
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
# 生效条件:position 经 _spec(position) 验证可解析后,返回原始 position 是否在模块级 DAILY 中;带首尾空白等未 strip 的值会因不在 DAILY 返回 False,未知 position 抛 WeightError;
|
|
140
|
-
def in_daily_eval(position: str) -> bool:
|
|
141
|
-
"""是否参与日常评估(设计者=False,元参照系)。"""
|
|
142
|
-
_spec(position)
|
|
143
|
-
return position in DAILY
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
# 生效条件:position 可被 _spec 解析且其 spec 含 "primary" 键时返回该值,未知 position 抛 WeightError;
|
|
147
|
-
def dominant(position: str) -> str:
|
|
148
|
-
"""主导分量(权重最高者)。"""
|
|
149
|
-
return _spec(position)["primary"]
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
# 生效条件:position 可被 _spec 解析且其 spec 含 "secondary" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
|
|
153
|
-
def secondary(position: str):
|
|
154
|
-
"""次主导分量;视角返回 None(另两项并列、均 >0)。"""
|
|
155
|
-
return _spec(position)["secondary"]
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
# 生效条件:position 可被 _spec 解析且其 spec 含 "excluded" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
|
|
159
|
-
def excluded(position: str):
|
|
160
|
-
"""被排除分量(≈0);视角返回 None(不设零)。"""
|
|
161
|
-
return _spec(position)["excluded"]
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# --------------------------------------------------------------------------
|
|
165
|
-
# 序比较(本模块的权威结论:只有序,没有数值)
|
|
166
|
-
# --------------------------------------------------------------------------
|
|
167
|
-
|
|
168
|
-
# 生效条件:position 与 component 分别经 _spec 与 _comp 验证后,若 component 等于该位置 spec["excluded"] 返回 RANK_EXCLUDED,否则若等于 spec["primary"] 返回 RANK_PRIMARY,否则返回 RANK_SECONDARY;
|
|
169
|
-
def rank(position: str, component: str) -> float:
|
|
170
|
-
"""分量在该位置的序秩(占位量级):2 主导 / 1 参与 / 0 排除。"""
|
|
171
|
-
s = _spec(position)
|
|
172
|
-
c = _comp(component)
|
|
173
|
-
if s["excluded"] == c:
|
|
174
|
-
return RANK_EXCLUDED
|
|
175
|
-
if s["primary"] == c:
|
|
176
|
-
return RANK_PRIMARY
|
|
177
|
-
return RANK_SECONDARY
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# 生效条件:position、a、b 经 rank 可得序秩,若 rank(position,a)==rank(position,b) 返回 None,否则返回 ra>rb 的 bool;任一参数未知则抛 WeightError;
|
|
181
|
-
def prefers(position: str, a: str, b: str):
|
|
182
|
-
"""该位置是否**严格**偏好 a 胜过 b。
|
|
183
|
-
|
|
184
|
-
返回 True / False / None(None = 二者并列,无严格序)。
|
|
185
|
-
"""
|
|
186
|
-
ra, rb = rank(position, a), rank(position, b)
|
|
187
|
-
if ra == rb:
|
|
188
|
-
return None
|
|
189
|
-
return ra > rb
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,按 -rank(position,c) 与 COMPONENTS.index(c) 排序,返回 {"preferred":[rank>0], "excluded":[rank==0], "primary":dominant(position), "secondary":secondary(position)}(无 dominant 键);
|
|
193
|
-
def order(position: str):
|
|
194
|
-
"""从高到低排列的分量(并列者按 COMPONENTS 稳定序);排除项单独列出。"""
|
|
195
|
-
_spec(position)
|
|
196
|
-
ranked = sorted(COMPONENTS, key=lambda c: (-rank(position, c), COMPONENTS.index(c)))
|
|
197
|
-
kept = [c for c in ranked if rank(position, c) > 0]
|
|
198
|
-
exc = [c for c in ranked if rank(position, c) == 0]
|
|
199
|
-
return {"preferred": kept, "excluded": exc,
|
|
200
|
-
"primary": dominant(position), "secondary": secondary(position)}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
# 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,将各分量 rank 归一化到 4 位小数返回;若 total 为 0 则按 total=1.0 计算;
|
|
204
|
-
def weights(position: str) -> dict:
|
|
205
|
-
"""占位数值权重(序秩归一化);**未标定**,仅供仿真。"""
|
|
206
|
-
_spec(position)
|
|
207
|
-
raw = {c: rank(position, c) for c in COMPONENTS}
|
|
208
|
-
total = sum(raw.values()) or 1.0
|
|
209
|
-
return {c: round(raw[c] / total, 4) for c in COMPONENTS}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
# --------------------------------------------------------------------------
|
|
213
|
-
# 合成(占位:f(一致性, 位置可预测性, 版本对齐度))
|
|
214
|
-
# --------------------------------------------------------------------------
|
|
215
|
-
|
|
216
|
-
# 生效条件:position 经 _spec 可解析且 COMPONENTS 可用时,components 对每个分量经 .get(c,0.0) 取值并截到 [0,1];若 components 无 .get 或该值不能 float 则该分量值记 0.0,仍按 weights(position) 加权求和返回含 score/values/weights/dominant 的 dict;
|
|
217
|
-
def blend(position: str, components: dict) -> dict:
|
|
218
|
-
"""按位置的权重合成单一信任标量。
|
|
219
|
-
|
|
220
|
-
`components` 形如 {"version_alignment": 1.0, "predictability": 0.8,
|
|
221
|
-
"consistency": 0.6};缺省按 0 计。
|
|
222
|
-
|
|
223
|
-
**数值未标定**:这里用序秩当量级,只保证「主导分量对结果影响最大」这
|
|
224
|
-
一方向性事实。标定属路线图 v0.3。
|
|
225
|
-
"""
|
|
226
|
-
s = _spec(position)
|
|
227
|
-
w = weights(position)
|
|
228
|
-
vals = {}
|
|
229
|
-
for c in COMPONENTS:
|
|
230
|
-
try:
|
|
231
|
-
vals[c] = max(0.0, min(1.0, float(components.get(c, 0.0))))
|
|
232
|
-
except (AttributeError, TypeError, ValueError):
|
|
233
|
-
vals[c] = 0.0
|
|
234
|
-
score = sum(w[c] * vals[c] for c in COMPONENTS)
|
|
235
|
-
return {"position": position, "class": s["class"],
|
|
236
|
-
"weights": w, "values": vals, "score": round(score, 4),
|
|
237
|
-
"dominant": s["primary"],
|
|
238
|
-
"note": "权重为占位序秩(未标定);仅方向性结论可信"}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
# --------------------------------------------------------------------------
|
|
242
|
-
# 不变量自检(把上轮的三条结构约束落成可执行断言)
|
|
243
|
-
# --------------------------------------------------------------------------
|
|
244
|
-
|
|
245
|
-
# 生效条件:模块级 POSITION_ORDER、COMPONENTS、SPEC、VIEWPOINT、FUNCTIONAL 等常量齐备时,invariants() 逐条自检并返回 {"ok": all(checks[*].ok), "checks": ...};
|
|
246
|
-
def invariants() -> dict:
|
|
247
|
-
"""逐条自检结构约束,返回 {ok, checks{name: {ok, detail}}}。"""
|
|
248
|
-
checks = {}
|
|
249
|
-
|
|
250
|
-
# ① 排除唯一:每分量恰被 1 个位置排除 ⇒ 参与度 = 5/6
|
|
251
|
-
part = {c: [p for p in POSITION_ORDER if rank(p, c) > 0] for c in COMPONENTS}
|
|
252
|
-
exc_of = {c: [p for p in POSITION_ORDER if rank(p, c) == 0] for c in COMPONENTS}
|
|
253
|
-
checks["excluded_exactly_once"] = {
|
|
254
|
-
"ok": all(len(exc_of[c]) == 1 for c in COMPONENTS)
|
|
255
|
-
and all(len(part[c]) == len(POSITION_ORDER) - 1 for c in COMPONENTS),
|
|
256
|
-
"detail": {c: {"participants": len(part[c]), "excluded_by": exc_of[c]}
|
|
257
|
-
for c in COMPONENTS}}
|
|
258
|
-
|
|
259
|
-
# ② 排除项只属功能单元,且每分量各被排除一次
|
|
260
|
-
excs = {}
|
|
261
|
-
for p in POSITION_ORDER:
|
|
262
|
-
e = excluded(p)
|
|
263
|
-
if e is None:
|
|
264
|
-
continue
|
|
265
|
-
excs.setdefault(e, []).append(p)
|
|
266
|
-
only_functional = all(is_functional(p)
|
|
267
|
-
for vs in excs.values() for p in vs)
|
|
268
|
-
both = all(len(excs.get(c) or []) == 1 for c in COMPONENTS)
|
|
269
|
-
checks["exclusion_functional_only_once_each"] = {
|
|
270
|
-
"ok": bool(excs) and only_functional and both,
|
|
271
|
-
"detail": {c: excs.get(c, []) for c in COMPONENTS}}
|
|
272
|
-
|
|
273
|
-
# ③ 视角主导 ↔ 功能单元排除 一一配对
|
|
274
|
-
dom_pairs = {} # 分量 → 视角
|
|
275
|
-
for p in POSITION_ORDER:
|
|
276
|
-
if is_viewpoint(p):
|
|
277
|
-
dom_pairs.setdefault(dominant(p), []).append(p)
|
|
278
|
-
pairing = {}
|
|
279
|
-
for p in POSITION_ORDER:
|
|
280
|
-
if not is_functional(p):
|
|
281
|
-
continue
|
|
282
|
-
e = excluded(p)
|
|
283
|
-
if e and len(dom_pairs.get(e) or []) == 1:
|
|
284
|
-
pairing[dom_pairs[e][0]] = p
|
|
285
|
-
checks["viewpoint_dominant_pairs_unit_exclusion"] = {
|
|
286
|
-
"ok": len(pairing) == 3,
|
|
287
|
-
"detail": pairing}
|
|
288
|
-
|
|
289
|
-
# ④ 功能单元恰有一个排除项;视角一个都没有
|
|
290
|
-
checks["functional_excludes_exactly_one"] = {
|
|
291
|
-
"ok": all(excluded(p) is not None for p in POSITION_ORDER
|
|
292
|
-
if is_functional(p))
|
|
293
|
-
and all(excluded(p) is None for p in POSITION_ORDER
|
|
294
|
-
if is_viewpoint(p)),
|
|
295
|
-
"detail": {p: excluded(p) for p in POSITION_ORDER}}
|
|
296
|
-
|
|
297
|
-
# ⑤ 排除项序秩严格最低
|
|
298
|
-
checks["excluded_is_lowest"] = {
|
|
299
|
-
"ok": all(rank(p, excluded(p)) < rank(p, c)
|
|
300
|
-
for p in POSITION_ORDER if excluded(p)
|
|
301
|
-
for c in COMPONENTS if c != excluded(p)),
|
|
302
|
-
"detail": "排除分量序秩 0,严格低于其余分量"}
|
|
303
|
-
|
|
304
|
-
return {"ok": all(c["ok"] for c in checks.values()), "checks": checks}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
# --------------------------------------------------------------------------
|
|
308
|
-
# 自描述
|
|
309
|
-
# --------------------------------------------------------------------------
|
|
310
|
-
|
|
311
|
-
# 生效条件:模块级 COMPONENTS、COMPONENT_LABELS、VIEWPOINT、FUNCTIONAL、SPEC、POSITION_ORDER、DAILY 齐备时,返回位置权重矩阵自描述 dict,其中 components 按 COMPONENT_LABELS、positions 按 SPEC、daily_eval 按 DAILY 展开;
|
|
312
|
-
def catalog() -> dict:
|
|
313
|
-
"""位置权重矩阵自描述(供 MCP / 文档对照验证)。"""
|
|
314
|
-
return {
|
|
315
|
-
"question": "不同身份,参数偏好不同",
|
|
316
|
-
"components": {c: COMPONENT_LABELS[c] for c in COMPONENTS},
|
|
317
|
-
"classes": {
|
|
318
|
-
VIEWPOINT: "认知视角:3 项都涉及,只标主导,不设零",
|
|
319
|
-
FUNCTIONAL: "功能单元:身份即排除(不猜/不记/不对外)",
|
|
320
|
-
},
|
|
321
|
-
"positions": {p: dict(SPEC[p]) for p in POSITION_ORDER},
|
|
322
|
-
"daily_eval": list(DAILY),
|
|
323
|
-
"meta_reference": [p for p in POSITION_ORDER if p not in DAILY],
|
|
324
|
-
"derivation": {"record": "不猜 → 排除 位置可预测性",
|
|
325
|
-
"output": "不记 → 排除 一致性",
|
|
326
|
-
"sustain": "不对外 → 排除 版本对齐度"},
|
|
327
|
-
"formula": "P_trust = f(一致性, 位置可预测性, 版本对齐度)",
|
|
328
|
-
"honest_boundary": "只声明序,不宣称数值;blend() 权重为占位序秩",
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
# ==========================================================================
|
|
333
|
-
# 结构重要性重算(maintain.importance)
|
|
334
|
-
# ==========================================================================
|
|
335
|
-
#
|
|
336
|
-
# 与上面的「位置权重矩阵」是**两件事**,不要混:
|
|
337
|
-
# · 上面回答「不同身份偏好哪些信任分量」(序标定,作用于位置);
|
|
338
|
-
# · 下面回答「一个节点在认知图结构里该有多大重要性」(重算,作用于节点)。
|
|
339
|
-
#
|
|
340
|
-
# 三个**可测**分量(对齐计划:按覆盖度、冗余度、验证基底重排):
|
|
341
|
-
# coverage 覆盖度 —— 有多少节点指向/包含它(入度,结构中枢性)
|
|
342
|
-
# redundancy 冗余度 —— 与同层节点内容哈希撞车的比例(越冗余越该降权)
|
|
343
|
-
# basis 验证基底 —— 外部验证档位(formal_proof/compiler > test > measurement > data > other)
|
|
344
|
-
#
|
|
345
|
-
# 纪律:只改 `frontmatter.importance` 与索引快照,**不动正文**(减小 diff 与重写成本);
|
|
346
|
-
# 全流程可预演(apply=False)、可留痕(`_maintain.jsonl`)、可回滚(rollback)。
|
|
347
|
-
# 性能:dry-run 不读任何节点文件(只用索引快照);apply 只写「变动超阈值」的节点。
|
|
348
|
-
|
|
349
|
-
MAINTAIN_LOG = "_maintain.jsonl"
|
|
350
|
-
|
|
351
|
-
#: 验证基底 → 可信权重(枚举来自 nodefile.VERIFICATION_BASIS)
|
|
352
|
-
#: 文科来源一致性档(textbook/public_kb)低于可复现档、高于 other:
|
|
353
|
-
#: 教材/公开知识库是权威二手来源,但不是可复算证据。
|
|
354
|
-
BASIS_TRUST = {
|
|
355
|
-
"formal_proof": 1.00,
|
|
356
|
-
"compiler": 0.90,
|
|
357
|
-
"test": 0.80,
|
|
358
|
-
"measurement": 0.65,
|
|
359
|
-
"textbook": 0.60,
|
|
360
|
-
"data": 0.45,
|
|
361
|
-
"public_kb": 0.40,
|
|
362
|
-
"other": 0.25,
|
|
363
|
-
}
|
|
364
|
-
BASIS_TRUST_MISSING = 0.25
|
|
365
|
-
|
|
366
|
-
#: 三分量合成权重(占位量级,沿用「只声明序」纪律;分量序主导→次要)
|
|
367
|
-
IMPORTANCE_MIX = {"basis": 0.40, "coverage": 0.35, "redundancy": 0.25}
|
|
368
|
-
COV_SAT = 12.0 # 入度饱和点:约 12 条入边即视为覆盖满
|
|
369
|
-
IMPORTANCE_FLOOR = 0.10
|
|
370
|
-
IMPORTANCE_CEIL = 1.00
|
|
371
|
-
IMPORTANCE_PROTECT = 0.70 # ≥ 此值:保护下限(已保护/高危节点不被降破)
|
|
372
|
-
APPLY_DELTA = 0.05 # 变动小于此值不写盘(防 IO 放大)
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
# 生效条件:e 为可 .get 的映射时,遍历 e.get("edges")(假值视为空)逐项按 dict 的 to/target/node/id 或标量转 str 追加非假值,再取 e.get("subgraph"),若为 dict 取其 "nodes" 否则取 subgraph 本身,且当其为 list/tuple 时追加其中 dict 的 id 或标量转 str 的非假值,返回 out;
|
|
376
|
-
def _targets(e: dict):
|
|
377
|
-
"""索引快照里的「出边目标」:edges ∪ subgraph.nodes(兼容 dict/str)。"""
|
|
378
|
-
out = []
|
|
379
|
-
for x in (e.get("edges") or []):
|
|
380
|
-
if isinstance(x, dict):
|
|
381
|
-
t = x.get("to") or x.get("target") or x.get("node") or x.get("id")
|
|
382
|
-
else:
|
|
383
|
-
t = x
|
|
384
|
-
if t:
|
|
385
|
-
out.append(str(t))
|
|
386
|
-
sg = e.get("subgraph")
|
|
387
|
-
raw = sg.get("nodes") if isinstance(sg, dict) else sg
|
|
388
|
-
if isinstance(raw, (list, tuple)):
|
|
389
|
-
for n in raw:
|
|
390
|
-
nid = n.get("id") if isinstance(n, dict) else n
|
|
391
|
-
if nid:
|
|
392
|
-
out.append(str(nid))
|
|
393
|
-
return out
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
# 生效条件:basis 为 None 时返回 BASIS_TRUST_MISSING;否则把 str(basis).strip().lower() 作为 BASIS_TRUST 的键,命中返回对应权重,未命中(含空串)返回 BASIS_TRUST_MISSING;
|
|
397
|
-
def basis_trust(basis):
|
|
398
|
-
"""验证基底 → 可信权重;缺失/未知一律给最低档(不假装可信)。"""
|
|
399
|
-
if basis is None:
|
|
400
|
-
return BASIS_TRUST_MISSING
|
|
401
|
-
return BASIS_TRUST.get(str(basis).strip().lower(), BASIS_TRUST_MISSING)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
# 生效条件:cg 的 index(getattr(cg,"index",None) or {})与其 "nodes" 同为真值时,返回以这些节点 id 为键的入度表,仅当 _targets(e) 给出的目标 t 也在 nodes 且 t != nid 时计数 +1;index 或 "nodes" 为假值(None/{})时 nodes 回落 {},直接返回空 dict。
|
|
405
|
-
def coverage_index(cg) -> dict:
|
|
406
|
-
"""入度表:nid → 被多少节点指向(覆盖度,O(N) 免读文件)。"""
|
|
407
|
-
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
408
|
-
indeg = {nid: 0 for nid in nodes}
|
|
409
|
-
for nid, e in nodes.items():
|
|
410
|
-
for t in _targets(e):
|
|
411
|
-
if t in indeg and t != nid:
|
|
412
|
-
indeg[t] += 1
|
|
413
|
-
return indeg
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
# 生效条件:cg.index 的 "nodes" 为 dict 时,layer 真值仅处理 e.get("layer")==layer 的节点,layer 假值不过滤;content_hash 为假值(None/空串/0 等)的节点输出 0.0,同 (e.get("layer"), content_hash) 第二次撞车时当前与首次节点均输出 1.0,否则输出 0.0;
|
|
417
|
-
def redundancy_map(cg, layer=None) -> dict:
|
|
418
|
-
"""同层内容哈希撞车 → 冗余度 1.0,否则 0.0(精确冗余,O(N) 免读文件)。
|
|
419
|
-
|
|
420
|
-
诚实边界:这是**精确冗余**(同一层出现完全相同的正文),不是语义近似冗余。
|
|
421
|
-
语义近似由 `forgetting.redundancy`(bigram 覆盖)在写入侧单独负责。
|
|
422
|
-
"""
|
|
423
|
-
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
424
|
-
seen, out = {}, {}
|
|
425
|
-
for nid, e in nodes.items():
|
|
426
|
-
if layer and e.get("layer") != layer:
|
|
427
|
-
continue
|
|
428
|
-
h = e.get("content_hash") or ""
|
|
429
|
-
if not h:
|
|
430
|
-
out[nid] = 0.0
|
|
431
|
-
continue
|
|
432
|
-
key = (e.get("layer"), h)
|
|
433
|
-
if key in seen:
|
|
434
|
-
out[nid] = 1.0
|
|
435
|
-
out[seen[key]] = 1.0
|
|
436
|
-
else:
|
|
437
|
-
seen[key] = nid
|
|
438
|
-
out.setdefault(nid, 0.0)
|
|
439
|
-
return out
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
# 生效条件:cg.index 的 nodes 为 dict 且 entry 非 None 或 nodes.get(nid) 命中时,e 按 entry 优先否则 nodes.get(nid);indeg/red 分别仅在为 None 时回落 coverage_index(cg)/redundancy_map(cg, layer=e.get("layer"))(空容器不回落);按 IMPORTANCE_MIX、COV_SAT 及 e.get("verification_basis") 的 basis_trust 计算 coverage/redundancy/basis 分量,按 bool(e.get("protected")) 选择 IMPORTANCE_PROTECT 或 IMPORTANCE_FLOOR 作下限、IMPORTANCE_CEIL 作上限,返回含 before(e.get("importance",0.5) or 0.5)、after、components、protected 的 dict;entry 与 nodes.get(nid) 均为 None 返回 None;
|
|
443
|
-
def node_importance(cg, nid, indeg=None, red=None, entry=None):
|
|
444
|
-
"""单节点结构重要性分解(可审计:给出分量而非只给分)。"""
|
|
445
|
-
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
446
|
-
e = entry if entry is not None else nodes.get(nid)
|
|
447
|
-
if e is None:
|
|
448
|
-
return None
|
|
449
|
-
indeg = indeg if indeg is not None else coverage_index(cg)
|
|
450
|
-
red = red if red is not None else redundancy_map(cg, layer=e.get("layer"))
|
|
451
|
-
d = int(indeg.get(nid, 0) or 0)
|
|
452
|
-
cov = min(1.0, math.log1p(d) / math.log1p(COV_SAT))
|
|
453
|
-
rr = max(0.0, min(1.0, float(red.get(nid, 0.0) or 0.0)))
|
|
454
|
-
bt = basis_trust(e.get("verification_basis"))
|
|
455
|
-
score = (IMPORTANCE_MIX["basis"] * bt
|
|
456
|
-
+ IMPORTANCE_MIX["coverage"] * cov
|
|
457
|
-
+ IMPORTANCE_MIX["redundancy"] * (1.0 - rr))
|
|
458
|
-
protected = bool(e.get("protected"))
|
|
459
|
-
floor = IMPORTANCE_PROTECT if protected else IMPORTANCE_FLOOR
|
|
460
|
-
score = max(floor, min(IMPORTANCE_CEIL, score))
|
|
461
|
-
return {"node_id": nid,
|
|
462
|
-
"before": float(e.get("importance", 0.5) or 0.5),
|
|
463
|
-
"after": round(score, 4),
|
|
464
|
-
"components": {"coverage": round(cov, 4), "redundancy": round(rr, 4),
|
|
465
|
-
"basis_trust": round(bt, 4), "in_degree": d,
|
|
466
|
-
"verification_basis": e.get("verification_basis")},
|
|
467
|
-
"protected": protected,
|
|
468
|
-
"protected_floor": protected}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
# 生效条件:给定 cg 且 nodes = cg.index["nodes"] 时按 layer 过滤、limit 为真值才 ids = ids[:int(limit)] 逐节点重算,abs(after-before) < float(min_delta) 记 unchanged;仅 apply=True 才把 frontmatter.importance/importance_source/importance_components 写回(after >= IMPORTANCE_PROTECT 且未 protected 时补写 protected/protection_reason),并向 cg.root 下 append_jsonl(..., MAINTAIN_LOG) 记 batch 后 rebuild_index。
|
|
472
|
-
def recalc(cg, layer=None, limit=None, apply=False, min_delta=APPLY_DELTA,
|
|
473
|
-
actor="maintain", dry_run_samples=10):
|
|
474
|
-
"""结构重要性重算:覆盖度 + 冗余度 + 验证基底 → 重排节点重要性。
|
|
475
|
-
|
|
476
|
-
apply=False(默认)只出报表,不写盘(对应计划「可预演」)。
|
|
477
|
-
apply=True 逐节点改写 `frontmatter.importance`,每批写一条 `_maintain.jsonl`
|
|
478
|
-
(before/after/分量/actor),并提供 rollback 反向应用。
|
|
479
|
-
"""
|
|
480
|
-
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
481
|
-
indeg = coverage_index(cg)
|
|
482
|
-
red = redundancy_map(cg, layer=layer)
|
|
483
|
-
ids = [nid for nid, e in nodes.items()
|
|
484
|
-
if not layer or e.get("layer") == layer]
|
|
485
|
-
ids.sort()
|
|
486
|
-
if limit:
|
|
487
|
-
ids = ids[:int(limit)]
|
|
488
|
-
t0 = time.time()
|
|
489
|
-
planned, changed, unchanged, skipped = [], 0, 0, 0
|
|
490
|
-
before_sum = after_sum = 0.0
|
|
491
|
-
by_layer = {}
|
|
492
|
-
batch = time.strftime("%Y%m%d-%H%M%S")
|
|
493
|
-
samples = []
|
|
494
|
-
for nid in ids:
|
|
495
|
-
info = node_importance(cg, nid, indeg=indeg, red=red)
|
|
496
|
-
if info is None:
|
|
497
|
-
skipped += 1
|
|
498
|
-
continue
|
|
499
|
-
before, after = info["before"], info["after"]
|
|
500
|
-
before_sum += before
|
|
501
|
-
after_sum += after
|
|
502
|
-
lay = (nodes.get(nid) or {}).get("layer") or "?"
|
|
503
|
-
bl = by_layer.setdefault(lay, {"nodes": 0, "changed": 0,
|
|
504
|
-
"avg_before": 0.0, "avg_after": 0.0})
|
|
505
|
-
bl["nodes"] += 1
|
|
506
|
-
if abs(after - before) < float(min_delta):
|
|
507
|
-
unchanged += 1
|
|
508
|
-
continue
|
|
509
|
-
changed += 1
|
|
510
|
-
bl["changed"] += 1
|
|
511
|
-
plan = dict(info)
|
|
512
|
-
plan["batch"] = batch
|
|
513
|
-
plan["delta"] = round(after - before, 4)
|
|
514
|
-
planned.append(plan)
|
|
515
|
-
if len(samples) < int(dry_run_samples):
|
|
516
|
-
samples.append(plan)
|
|
517
|
-
for lay, bl in list(by_layer.items()):
|
|
518
|
-
bl["avg_before"] = 0.0
|
|
519
|
-
bl["avg_after"] = 0.0
|
|
520
|
-
written = 0
|
|
521
|
-
if apply:
|
|
522
|
-
for plan in planned:
|
|
523
|
-
nid = plan["node_id"]
|
|
524
|
-
node = cg.get(nid)
|
|
525
|
-
if not node:
|
|
526
|
-
continue
|
|
527
|
-
fm = node.get("frontmatter") or {}
|
|
528
|
-
fm["importance"] = plan["after"]
|
|
529
|
-
fm["importance_source"] = "recalc"
|
|
530
|
-
fm["importance_components"] = plan["components"]
|
|
531
|
-
if plan["after"] >= IMPORTANCE_PROTECT and not fm.get("protected"):
|
|
532
|
-
fm["protected"] = True
|
|
533
|
-
fm["protection_reason"] = (f"recalc importance={plan['after']:.2f}"
|
|
534
|
-
f"≥{IMPORTANCE_PROTECT}")
|
|
535
|
-
path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
|
|
536
|
-
or node.get("path") or f"{nid}.md")
|
|
537
|
-
cg._write_node(nid, path, fm, node.get("content") or "")
|
|
538
|
-
e = nodes.get(nid)
|
|
539
|
-
if e is not None:
|
|
540
|
-
e["importance"] = plan["after"]
|
|
541
|
-
if fm.get("protected"):
|
|
542
|
-
e["protected"] = True
|
|
543
|
-
e["protection_reason"] = fm["protection_reason"]
|
|
544
|
-
rec = {"t": time.time(), "action": "importance", "batch": batch,
|
|
545
|
-
"id": nid, "layer": (e or {}).get("layer"),
|
|
546
|
-
"before": plan["before"], "after": plan["after"],
|
|
547
|
-
"delta": plan["delta"], "components": plan["components"],
|
|
548
|
-
"actor": actor}
|
|
549
|
-
append_jsonl(os.path.join(cg.root, MAINTAIN_LOG), rec)
|
|
550
|
-
written += 1
|
|
551
|
-
if written and hasattr(cg, "rebuild_index"):
|
|
552
|
-
cg.rebuild_index() # 索引与盘面重新对齐,防内存/磁盘分叉
|
|
553
|
-
n = max(1, len(ids))
|
|
554
|
-
return {
|
|
555
|
-
"ok": True, "action": "importance", "dry_run": not apply,
|
|
556
|
-
"batch": batch, "nodes_scanned": len(ids), "changed": changed,
|
|
557
|
-
"unchanged": unchanged, "skipped": skipped, "written": written,
|
|
558
|
-
"min_delta": float(min_delta),
|
|
559
|
-
"avg_before": round(before_sum / n, 4),
|
|
560
|
-
"avg_after": round(after_sum / n, 4),
|
|
561
|
-
"by_layer": {k: {"nodes": v["nodes"], "changed": v["changed"]}
|
|
562
|
-
for k, v in by_layer.items()},
|
|
563
|
-
"samples": samples, "elapsed_ms": int((time.time() - t0) * 1000),
|
|
564
|
-
"log": MAINTAIN_LOG,
|
|
565
|
-
"note": ("dry-run:未写盘;apply=True 才改写 importance"
|
|
566
|
-
if not apply else
|
|
567
|
-
f"已改写 {written} 个节点;回滚见 rollback(batch={batch})"),
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
# 生效条件:cg.root/MAINTAIN_LOG 可读出 action=="importance" 记录后,entry_ids 为真值时按记录 id 是否在 {str(x) for x in entry_ids} 过滤;否则 batch 为真值时按 r.get("batch")==batch 过滤;否则取最后一条记录的 batch 再按其过滤;无 importance 记录返回 {"ok":False,"error":"no_records","reverted":0},过滤后无记录返回 {"ok":False,"error":"batch_not_found",...};对命中且 cg.get(nid) 为真的记录写回 rec.get("before") 并计数,若 reverted 且 cg 有 rebuild_index 则调用,最后 append_jsonl 写 actor 并返回 {"ok":True,"batch":batch,"reverted":reverted,"ids":ids};
|
|
572
|
-
def rollback(cg, batch=None, entry_ids=None, actor="maintain"):
|
|
573
|
-
"""把重要性重算反向应用(bulk 改写的可回滚兑现)。
|
|
574
|
-
|
|
575
|
-
batch 为空则回滚**最近一批**。返回 {ok, reverted, batch, ids}。
|
|
576
|
-
"""
|
|
577
|
-
log_path = os.path.join(cg.root, MAINTAIN_LOG)
|
|
578
|
-
records = [r for r in read_jsonl(log_path)
|
|
579
|
-
if r.get("action") == "importance"]
|
|
580
|
-
if not records:
|
|
581
|
-
return {"ok": False, "error": "no_records", "reverted": 0}
|
|
582
|
-
if entry_ids:
|
|
583
|
-
want = {str(x) for x in entry_ids}
|
|
584
|
-
records = [r for r in records if str(r.get("id")) in want]
|
|
585
|
-
elif batch:
|
|
586
|
-
records = [r for r in records if r.get("batch") == batch]
|
|
587
|
-
else:
|
|
588
|
-
batch = records[-1].get("batch")
|
|
589
|
-
records = [r for r in records if r.get("batch") == batch]
|
|
590
|
-
if not records:
|
|
591
|
-
return {"ok": False, "error": "batch_not_found", "batch": batch,
|
|
592
|
-
"reverted": 0}
|
|
593
|
-
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
594
|
-
reverted, ids = 0, []
|
|
595
|
-
# 同一节点多条记录时以最早一条的 before 为准
|
|
596
|
-
for rec in records:
|
|
597
|
-
nid = rec.get("id")
|
|
598
|
-
node = cg.get(nid)
|
|
599
|
-
if not node:
|
|
600
|
-
continue
|
|
601
|
-
fm = node.get("frontmatter") or {}
|
|
602
|
-
fm["importance"] = rec.get("before")
|
|
603
|
-
fm["importance_source"] = "recalc_rollback"
|
|
604
|
-
path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
|
|
605
|
-
or node.get("path") or f"{nid}.md")
|
|
606
|
-
cg._write_node(nid, path, fm, node.get("content") or "")
|
|
607
|
-
e = nodes.get(nid)
|
|
608
|
-
if e is not None:
|
|
609
|
-
e["importance"] = rec.get("before")
|
|
610
|
-
reverted += 1
|
|
611
|
-
ids.append(nid)
|
|
612
|
-
if reverted and hasattr(cg, "rebuild_index"):
|
|
613
|
-
cg.rebuild_index()
|
|
614
|
-
append_jsonl(log_path, {"t": time.time(), "action": "importance_rollback",
|
|
615
|
-
"batch": batch, "reverted": reverted, "actor": actor})
|
|
616
|
-
return {"ok": True, "batch": batch, "reverted": reverted, "ids": ids}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
# 生效条件:cg.root/MAINTAIN_LOG 可读出 JSONL 记录后,action 为真值时按 r.get("action")==action 过滤,假值不过滤;返回 recs[-int(limit):],其中 limit=0 时 int(0)=0 使切片为 recs[0:] 返回全部而非空;
|
|
620
|
-
def history(cg, limit=100, action=None):
|
|
621
|
-
"""维护留痕(最近 limit 条),可按 action 过滤。"""
|
|
622
|
-
recs = list(read_jsonl(os.path.join(cg.root, MAINTAIN_LOG)))
|
|
623
|
-
if action:
|
|
624
|
-
recs = [r for r in recs if r.get("action") == action]
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""位置权重矩阵(序标定)——「不同身份,参数偏好不同」。
|
|
3
|
+
|
|
4
|
+
理论出处(本仓原文,非外部知识)
|
|
5
|
+
--------------------------------
|
|
6
|
+
`docs/theory/智能的公理化基石.md` §4.3:信任合成是
|
|
7
|
+
P_trust = f(一致性, 位置可预测性, 版本对齐度)
|
|
8
|
+
其中 `版本对齐度` 已由 `theory` + `links.version_alignment` 提供,
|
|
9
|
+
`位置可预测性` 见 `predict`,`一致性` 见 `consistency`。本模块只补一件
|
|
10
|
+
此前缺失的东西:**三个分量在不同位置下的偏好序**。
|
|
11
|
+
|
|
12
|
+
六个位置分为**两类**(由功能身份决定,非人为指定):
|
|
13
|
+
|
|
14
|
+
· 认知视角(viewpoint):设计者 / 反思 / 验证
|
|
15
|
+
——「思考的不同视角」,**三分量都涉及**,只标定主导,**不设零**。
|
|
16
|
+
· 功能单元(functional):记录 / 输出 / 维生
|
|
17
|
+
——功能需求决定,**身份即排除**:主导 + 明确排除一项(≈0)。
|
|
18
|
+
|
|
19
|
+
排除项可**推导**(派生律:功能身份 → 缺失分量),不是选出来的:
|
|
20
|
+
|
|
21
|
+
· 记录单元**不猜** → 不做预测 → 排除 位置可预测性
|
|
22
|
+
· 输出单元**不记** → 不复现对账 → 排除 一致性
|
|
23
|
+
· 维生系统**不对外** → 无外部协议 → 排除 版本对齐度
|
|
24
|
+
|
|
25
|
+
设计者定位(本轮裁决):
|
|
26
|
+
· **不参与日常评估**——它是元视角,思考总体规律;细节由反思/验证承担,
|
|
27
|
+
否则要做全局细节整理,耗时极长。
|
|
28
|
+
|
|
29
|
+
可推导不变量(`invariants()` 逐条自检)
|
|
30
|
+
--------------------------------------
|
|
31
|
+
1. **排除唯一**——每个分量恰被 **1** 个位置排除;因视角「3 项都涉及」,
|
|
32
|
+
故每个分量的参与度 = **5/6**(不是 3/6);
|
|
33
|
+
2. **排除项只属功能单元**,且 A/B/C 各被排除一次;
|
|
34
|
+
3. **视角主导 ↔ 功能单元排除**一一配对:
|
|
35
|
+
设计者(A)↔维生、反思(B)↔记录、验证(C)↔输出。
|
|
36
|
+
|
|
37
|
+
诚实边界
|
|
38
|
+
--------
|
|
39
|
+
· 本模块只声明**序**(谁能压过谁),**不宣称数值**——与 `links.py` 的
|
|
40
|
+
`UP_STEP`/`DECAY_DAYS` 同一纪律(文档 §4.3:「v0.1 只声明结构」)。
|
|
41
|
+
· `blend()` 里的权重是**占位值**(用序秩当量级),仅供仿真,标定属 v0.3。
|
|
42
|
+
|
|
43
|
+
零第三方依赖。
|
|
44
|
+
"""
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import math
|
|
48
|
+
import os
|
|
49
|
+
import time
|
|
50
|
+
|
|
51
|
+
from .fsutil import append_jsonl, read_jsonl
|
|
52
|
+
|
|
53
|
+
# --------------------------------------------------------------------------
|
|
54
|
+
# 常量
|
|
55
|
+
# --------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
#: 三个分量(顺序即 A/B/C,稳定,供外部按位引用)
|
|
58
|
+
COMPONENTS = ("version_alignment", "predictability", "consistency")
|
|
59
|
+
|
|
60
|
+
#: 分量中文名(日志/自描述用)
|
|
61
|
+
COMPONENT_LABELS = {
|
|
62
|
+
"version_alignment": "版本对齐度",
|
|
63
|
+
"predictability": "位置可预测性",
|
|
64
|
+
"consistency": "一致性",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#: 位置类别
|
|
68
|
+
VIEWPOINT = "viewpoint" # 认知视角:3 项都涉及,只标主导,不设零
|
|
69
|
+
FUNCTIONAL = "functional" # 功能单元:主导 + 明确排除一项
|
|
70
|
+
|
|
71
|
+
#: 位置 → 权重序规格
|
|
72
|
+
#: primary 主导分量(权重最高)
|
|
73
|
+
#: secondary 次主导分量(功能单元的第二个偏好;视角为 None=另两项并列)
|
|
74
|
+
#: excluded 被排除分量(≈0;仅功能单元有;视角为 None=不设零)
|
|
75
|
+
SPEC = {
|
|
76
|
+
# ---- 认知视角(不参与日常评估者仅 designer)----
|
|
77
|
+
"designer": {"class": VIEWPOINT, "primary": "version_alignment",
|
|
78
|
+
"secondary": None, "excluded": None},
|
|
79
|
+
"reflect": {"class": VIEWPOINT, "primary": "predictability",
|
|
80
|
+
"secondary": None, "excluded": None},
|
|
81
|
+
"verify": {"class": VIEWPOINT, "primary": "consistency",
|
|
82
|
+
"secondary": None, "excluded": None},
|
|
83
|
+
# ---- 功能单元(身份即排除)----
|
|
84
|
+
"record": {"class": FUNCTIONAL, "primary": "consistency",
|
|
85
|
+
"secondary": "version_alignment", "excluded": "predictability"},
|
|
86
|
+
"output": {"class": FUNCTIONAL, "primary": "predictability",
|
|
87
|
+
"secondary": "version_alignment", "excluded": "consistency"},
|
|
88
|
+
"sustain": {"class": FUNCTIONAL, "primary": "consistency",
|
|
89
|
+
"secondary": "predictability", "excluded": "version_alignment"},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
POSITION_ORDER = ("designer", "record", "reflect", "verify", "output", "sustain")
|
|
93
|
+
|
|
94
|
+
#: 参与**日常评估**的位置(设计者是元参照系,不入日常)
|
|
95
|
+
DAILY = ("record", "reflect", "verify", "output", "sustain")
|
|
96
|
+
|
|
97
|
+
#: 序秩(占位量级,仅仿真用):主导 2 / 次主导 1 / 排除 0;视角另两项 = 1
|
|
98
|
+
RANK_PRIMARY = 2.0
|
|
99
|
+
RANK_SECONDARY = 1.0
|
|
100
|
+
RANK_EXCLUDED = 0.0
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class WeightError(Exception):
|
|
104
|
+
"""未知位置 / 未知分量。"""
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# --------------------------------------------------------------------------
|
|
108
|
+
# 基础查询
|
|
109
|
+
# --------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
# 生效条件:position 经 str(position or "").strip() 作为 SPEC 的键,命中时返回对应 spec dict,未命中(含 position 为 None/空串/未知)抛 WeightError;
|
|
112
|
+
def _spec(position: str) -> dict:
|
|
113
|
+
s = SPEC.get(str(position or "").strip())
|
|
114
|
+
if s is None:
|
|
115
|
+
raise WeightError(f"未知位置:{position!r}(允许:{POSITION_ORDER})")
|
|
116
|
+
return s
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# 生效条件:component 经 str(component or "").strip() 后若结果在 COMPONENTS 中返回该规范分量字符串,否则抛 WeightError;
|
|
120
|
+
def _comp(component: str) -> str:
|
|
121
|
+
c = str(component or "").strip()
|
|
122
|
+
if c not in COMPONENTS:
|
|
123
|
+
raise WeightError(f"未知分量:{component!r}(允许:{COMPONENTS})")
|
|
124
|
+
return c
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# 生效条件:position 可被 _spec 解析且其结果 "class" 等于 VIEWPOINT 时返回 True,非 VIEWPOINT 返回 False,未知 position 抛 WeightError;
|
|
128
|
+
def is_viewpoint(position: str) -> bool:
|
|
129
|
+
"""是否认知视角(3 项都涉及,不设零)。"""
|
|
130
|
+
return _spec(position)["class"] == VIEWPOINT
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# 生效条件:position 可被 _spec 解析且其结果 "class" 等于 FUNCTIONAL 时返回 True,非 FUNCTIONAL 返回 False,未知 position 抛 WeightError;
|
|
134
|
+
def is_functional(position: str) -> bool:
|
|
135
|
+
"""是否功能单元(身份即排除)。"""
|
|
136
|
+
return _spec(position)["class"] == FUNCTIONAL
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# 生效条件:position 经 _spec(position) 验证可解析后,返回原始 position 是否在模块级 DAILY 中;带首尾空白等未 strip 的值会因不在 DAILY 返回 False,未知 position 抛 WeightError;
|
|
140
|
+
def in_daily_eval(position: str) -> bool:
|
|
141
|
+
"""是否参与日常评估(设计者=False,元参照系)。"""
|
|
142
|
+
_spec(position)
|
|
143
|
+
return position in DAILY
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# 生效条件:position 可被 _spec 解析且其 spec 含 "primary" 键时返回该值,未知 position 抛 WeightError;
|
|
147
|
+
def dominant(position: str) -> str:
|
|
148
|
+
"""主导分量(权重最高者)。"""
|
|
149
|
+
return _spec(position)["primary"]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# 生效条件:position 可被 _spec 解析且其 spec 含 "secondary" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
|
|
153
|
+
def secondary(position: str):
|
|
154
|
+
"""次主导分量;视角返回 None(另两项并列、均 >0)。"""
|
|
155
|
+
return _spec(position)["secondary"]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# 生效条件:position 可被 _spec 解析且其 spec 含 "excluded" 键时返回该值(视角可为 None),未知 position 抛 WeightError;
|
|
159
|
+
def excluded(position: str):
|
|
160
|
+
"""被排除分量(≈0);视角返回 None(不设零)。"""
|
|
161
|
+
return _spec(position)["excluded"]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# --------------------------------------------------------------------------
|
|
165
|
+
# 序比较(本模块的权威结论:只有序,没有数值)
|
|
166
|
+
# --------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
# 生效条件:position 与 component 分别经 _spec 与 _comp 验证后,若 component 等于该位置 spec["excluded"] 返回 RANK_EXCLUDED,否则若等于 spec["primary"] 返回 RANK_PRIMARY,否则返回 RANK_SECONDARY;
|
|
169
|
+
def rank(position: str, component: str) -> float:
|
|
170
|
+
"""分量在该位置的序秩(占位量级):2 主导 / 1 参与 / 0 排除。"""
|
|
171
|
+
s = _spec(position)
|
|
172
|
+
c = _comp(component)
|
|
173
|
+
if s["excluded"] == c:
|
|
174
|
+
return RANK_EXCLUDED
|
|
175
|
+
if s["primary"] == c:
|
|
176
|
+
return RANK_PRIMARY
|
|
177
|
+
return RANK_SECONDARY
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# 生效条件:position、a、b 经 rank 可得序秩,若 rank(position,a)==rank(position,b) 返回 None,否则返回 ra>rb 的 bool;任一参数未知则抛 WeightError;
|
|
181
|
+
def prefers(position: str, a: str, b: str):
|
|
182
|
+
"""该位置是否**严格**偏好 a 胜过 b。
|
|
183
|
+
|
|
184
|
+
返回 True / False / None(None = 二者并列,无严格序)。
|
|
185
|
+
"""
|
|
186
|
+
ra, rb = rank(position, a), rank(position, b)
|
|
187
|
+
if ra == rb:
|
|
188
|
+
return None
|
|
189
|
+
return ra > rb
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,按 -rank(position,c) 与 COMPONENTS.index(c) 排序,返回 {"preferred":[rank>0], "excluded":[rank==0], "primary":dominant(position), "secondary":secondary(position)}(无 dominant 键);
|
|
193
|
+
def order(position: str):
|
|
194
|
+
"""从高到低排列的分量(并列者按 COMPONENTS 稳定序);排除项单独列出。"""
|
|
195
|
+
_spec(position)
|
|
196
|
+
ranked = sorted(COMPONENTS, key=lambda c: (-rank(position, c), COMPONENTS.index(c)))
|
|
197
|
+
kept = [c for c in ranked if rank(position, c) > 0]
|
|
198
|
+
exc = [c for c in ranked if rank(position, c) == 0]
|
|
199
|
+
return {"preferred": kept, "excluded": exc,
|
|
200
|
+
"primary": dominant(position), "secondary": secondary(position)}
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# 生效条件:position 经 _spec 验证且 COMPONENTS 可用时,将各分量 rank 归一化到 4 位小数返回;若 total 为 0 则按 total=1.0 计算;
|
|
204
|
+
def weights(position: str) -> dict:
|
|
205
|
+
"""占位数值权重(序秩归一化);**未标定**,仅供仿真。"""
|
|
206
|
+
_spec(position)
|
|
207
|
+
raw = {c: rank(position, c) for c in COMPONENTS}
|
|
208
|
+
total = sum(raw.values()) or 1.0
|
|
209
|
+
return {c: round(raw[c] / total, 4) for c in COMPONENTS}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# --------------------------------------------------------------------------
|
|
213
|
+
# 合成(占位:f(一致性, 位置可预测性, 版本对齐度))
|
|
214
|
+
# --------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
# 生效条件:position 经 _spec 可解析且 COMPONENTS 可用时,components 对每个分量经 .get(c,0.0) 取值并截到 [0,1];若 components 无 .get 或该值不能 float 则该分量值记 0.0,仍按 weights(position) 加权求和返回含 score/values/weights/dominant 的 dict;
|
|
217
|
+
def blend(position: str, components: dict) -> dict:
|
|
218
|
+
"""按位置的权重合成单一信任标量。
|
|
219
|
+
|
|
220
|
+
`components` 形如 {"version_alignment": 1.0, "predictability": 0.8,
|
|
221
|
+
"consistency": 0.6};缺省按 0 计。
|
|
222
|
+
|
|
223
|
+
**数值未标定**:这里用序秩当量级,只保证「主导分量对结果影响最大」这
|
|
224
|
+
一方向性事实。标定属路线图 v0.3。
|
|
225
|
+
"""
|
|
226
|
+
s = _spec(position)
|
|
227
|
+
w = weights(position)
|
|
228
|
+
vals = {}
|
|
229
|
+
for c in COMPONENTS:
|
|
230
|
+
try:
|
|
231
|
+
vals[c] = max(0.0, min(1.0, float(components.get(c, 0.0))))
|
|
232
|
+
except (AttributeError, TypeError, ValueError):
|
|
233
|
+
vals[c] = 0.0
|
|
234
|
+
score = sum(w[c] * vals[c] for c in COMPONENTS)
|
|
235
|
+
return {"position": position, "class": s["class"],
|
|
236
|
+
"weights": w, "values": vals, "score": round(score, 4),
|
|
237
|
+
"dominant": s["primary"],
|
|
238
|
+
"note": "权重为占位序秩(未标定);仅方向性结论可信"}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# --------------------------------------------------------------------------
|
|
242
|
+
# 不变量自检(把上轮的三条结构约束落成可执行断言)
|
|
243
|
+
# --------------------------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
# 生效条件:模块级 POSITION_ORDER、COMPONENTS、SPEC、VIEWPOINT、FUNCTIONAL 等常量齐备时,invariants() 逐条自检并返回 {"ok": all(checks[*].ok), "checks": ...};
|
|
246
|
+
def invariants() -> dict:
|
|
247
|
+
"""逐条自检结构约束,返回 {ok, checks{name: {ok, detail}}}。"""
|
|
248
|
+
checks = {}
|
|
249
|
+
|
|
250
|
+
# ① 排除唯一:每分量恰被 1 个位置排除 ⇒ 参与度 = 5/6
|
|
251
|
+
part = {c: [p for p in POSITION_ORDER if rank(p, c) > 0] for c in COMPONENTS}
|
|
252
|
+
exc_of = {c: [p for p in POSITION_ORDER if rank(p, c) == 0] for c in COMPONENTS}
|
|
253
|
+
checks["excluded_exactly_once"] = {
|
|
254
|
+
"ok": all(len(exc_of[c]) == 1 for c in COMPONENTS)
|
|
255
|
+
and all(len(part[c]) == len(POSITION_ORDER) - 1 for c in COMPONENTS),
|
|
256
|
+
"detail": {c: {"participants": len(part[c]), "excluded_by": exc_of[c]}
|
|
257
|
+
for c in COMPONENTS}}
|
|
258
|
+
|
|
259
|
+
# ② 排除项只属功能单元,且每分量各被排除一次
|
|
260
|
+
excs = {}
|
|
261
|
+
for p in POSITION_ORDER:
|
|
262
|
+
e = excluded(p)
|
|
263
|
+
if e is None:
|
|
264
|
+
continue
|
|
265
|
+
excs.setdefault(e, []).append(p)
|
|
266
|
+
only_functional = all(is_functional(p)
|
|
267
|
+
for vs in excs.values() for p in vs)
|
|
268
|
+
both = all(len(excs.get(c) or []) == 1 for c in COMPONENTS)
|
|
269
|
+
checks["exclusion_functional_only_once_each"] = {
|
|
270
|
+
"ok": bool(excs) and only_functional and both,
|
|
271
|
+
"detail": {c: excs.get(c, []) for c in COMPONENTS}}
|
|
272
|
+
|
|
273
|
+
# ③ 视角主导 ↔ 功能单元排除 一一配对
|
|
274
|
+
dom_pairs = {} # 分量 → 视角
|
|
275
|
+
for p in POSITION_ORDER:
|
|
276
|
+
if is_viewpoint(p):
|
|
277
|
+
dom_pairs.setdefault(dominant(p), []).append(p)
|
|
278
|
+
pairing = {}
|
|
279
|
+
for p in POSITION_ORDER:
|
|
280
|
+
if not is_functional(p):
|
|
281
|
+
continue
|
|
282
|
+
e = excluded(p)
|
|
283
|
+
if e and len(dom_pairs.get(e) or []) == 1:
|
|
284
|
+
pairing[dom_pairs[e][0]] = p
|
|
285
|
+
checks["viewpoint_dominant_pairs_unit_exclusion"] = {
|
|
286
|
+
"ok": len(pairing) == 3,
|
|
287
|
+
"detail": pairing}
|
|
288
|
+
|
|
289
|
+
# ④ 功能单元恰有一个排除项;视角一个都没有
|
|
290
|
+
checks["functional_excludes_exactly_one"] = {
|
|
291
|
+
"ok": all(excluded(p) is not None for p in POSITION_ORDER
|
|
292
|
+
if is_functional(p))
|
|
293
|
+
and all(excluded(p) is None for p in POSITION_ORDER
|
|
294
|
+
if is_viewpoint(p)),
|
|
295
|
+
"detail": {p: excluded(p) for p in POSITION_ORDER}}
|
|
296
|
+
|
|
297
|
+
# ⑤ 排除项序秩严格最低
|
|
298
|
+
checks["excluded_is_lowest"] = {
|
|
299
|
+
"ok": all(rank(p, excluded(p)) < rank(p, c)
|
|
300
|
+
for p in POSITION_ORDER if excluded(p)
|
|
301
|
+
for c in COMPONENTS if c != excluded(p)),
|
|
302
|
+
"detail": "排除分量序秩 0,严格低于其余分量"}
|
|
303
|
+
|
|
304
|
+
return {"ok": all(c["ok"] for c in checks.values()), "checks": checks}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
# --------------------------------------------------------------------------
|
|
308
|
+
# 自描述
|
|
309
|
+
# --------------------------------------------------------------------------
|
|
310
|
+
|
|
311
|
+
# 生效条件:模块级 COMPONENTS、COMPONENT_LABELS、VIEWPOINT、FUNCTIONAL、SPEC、POSITION_ORDER、DAILY 齐备时,返回位置权重矩阵自描述 dict,其中 components 按 COMPONENT_LABELS、positions 按 SPEC、daily_eval 按 DAILY 展开;
|
|
312
|
+
def catalog() -> dict:
|
|
313
|
+
"""位置权重矩阵自描述(供 MCP / 文档对照验证)。"""
|
|
314
|
+
return {
|
|
315
|
+
"question": "不同身份,参数偏好不同",
|
|
316
|
+
"components": {c: COMPONENT_LABELS[c] for c in COMPONENTS},
|
|
317
|
+
"classes": {
|
|
318
|
+
VIEWPOINT: "认知视角:3 项都涉及,只标主导,不设零",
|
|
319
|
+
FUNCTIONAL: "功能单元:身份即排除(不猜/不记/不对外)",
|
|
320
|
+
},
|
|
321
|
+
"positions": {p: dict(SPEC[p]) for p in POSITION_ORDER},
|
|
322
|
+
"daily_eval": list(DAILY),
|
|
323
|
+
"meta_reference": [p for p in POSITION_ORDER if p not in DAILY],
|
|
324
|
+
"derivation": {"record": "不猜 → 排除 位置可预测性",
|
|
325
|
+
"output": "不记 → 排除 一致性",
|
|
326
|
+
"sustain": "不对外 → 排除 版本对齐度"},
|
|
327
|
+
"formula": "P_trust = f(一致性, 位置可预测性, 版本对齐度)",
|
|
328
|
+
"honest_boundary": "只声明序,不宣称数值;blend() 权重为占位序秩",
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
# ==========================================================================
|
|
333
|
+
# 结构重要性重算(maintain.importance)
|
|
334
|
+
# ==========================================================================
|
|
335
|
+
#
|
|
336
|
+
# 与上面的「位置权重矩阵」是**两件事**,不要混:
|
|
337
|
+
# · 上面回答「不同身份偏好哪些信任分量」(序标定,作用于位置);
|
|
338
|
+
# · 下面回答「一个节点在认知图结构里该有多大重要性」(重算,作用于节点)。
|
|
339
|
+
#
|
|
340
|
+
# 三个**可测**分量(对齐计划:按覆盖度、冗余度、验证基底重排):
|
|
341
|
+
# coverage 覆盖度 —— 有多少节点指向/包含它(入度,结构中枢性)
|
|
342
|
+
# redundancy 冗余度 —— 与同层节点内容哈希撞车的比例(越冗余越该降权)
|
|
343
|
+
# basis 验证基底 —— 外部验证档位(formal_proof/compiler > test > measurement > data > other)
|
|
344
|
+
#
|
|
345
|
+
# 纪律:只改 `frontmatter.importance` 与索引快照,**不动正文**(减小 diff 与重写成本);
|
|
346
|
+
# 全流程可预演(apply=False)、可留痕(`_maintain.jsonl`)、可回滚(rollback)。
|
|
347
|
+
# 性能:dry-run 不读任何节点文件(只用索引快照);apply 只写「变动超阈值」的节点。
|
|
348
|
+
|
|
349
|
+
MAINTAIN_LOG = "_maintain.jsonl"
|
|
350
|
+
|
|
351
|
+
#: 验证基底 → 可信权重(枚举来自 nodefile.VERIFICATION_BASIS)
|
|
352
|
+
#: 文科来源一致性档(textbook/public_kb)低于可复现档、高于 other:
|
|
353
|
+
#: 教材/公开知识库是权威二手来源,但不是可复算证据。
|
|
354
|
+
BASIS_TRUST = {
|
|
355
|
+
"formal_proof": 1.00,
|
|
356
|
+
"compiler": 0.90,
|
|
357
|
+
"test": 0.80,
|
|
358
|
+
"measurement": 0.65,
|
|
359
|
+
"textbook": 0.60,
|
|
360
|
+
"data": 0.45,
|
|
361
|
+
"public_kb": 0.40,
|
|
362
|
+
"other": 0.25,
|
|
363
|
+
}
|
|
364
|
+
BASIS_TRUST_MISSING = 0.25
|
|
365
|
+
|
|
366
|
+
#: 三分量合成权重(占位量级,沿用「只声明序」纪律;分量序主导→次要)
|
|
367
|
+
IMPORTANCE_MIX = {"basis": 0.40, "coverage": 0.35, "redundancy": 0.25}
|
|
368
|
+
COV_SAT = 12.0 # 入度饱和点:约 12 条入边即视为覆盖满
|
|
369
|
+
IMPORTANCE_FLOOR = 0.10
|
|
370
|
+
IMPORTANCE_CEIL = 1.00
|
|
371
|
+
IMPORTANCE_PROTECT = 0.70 # ≥ 此值:保护下限(已保护/高危节点不被降破)
|
|
372
|
+
APPLY_DELTA = 0.05 # 变动小于此值不写盘(防 IO 放大)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
# 生效条件:e 为可 .get 的映射时,遍历 e.get("edges")(假值视为空)逐项按 dict 的 to/target/node/id 或标量转 str 追加非假值,再取 e.get("subgraph"),若为 dict 取其 "nodes" 否则取 subgraph 本身,且当其为 list/tuple 时追加其中 dict 的 id 或标量转 str 的非假值,返回 out;
|
|
376
|
+
def _targets(e: dict):
|
|
377
|
+
"""索引快照里的「出边目标」:edges ∪ subgraph.nodes(兼容 dict/str)。"""
|
|
378
|
+
out = []
|
|
379
|
+
for x in (e.get("edges") or []):
|
|
380
|
+
if isinstance(x, dict):
|
|
381
|
+
t = x.get("to") or x.get("target") or x.get("node") or x.get("id")
|
|
382
|
+
else:
|
|
383
|
+
t = x
|
|
384
|
+
if t:
|
|
385
|
+
out.append(str(t))
|
|
386
|
+
sg = e.get("subgraph")
|
|
387
|
+
raw = sg.get("nodes") if isinstance(sg, dict) else sg
|
|
388
|
+
if isinstance(raw, (list, tuple)):
|
|
389
|
+
for n in raw:
|
|
390
|
+
nid = n.get("id") if isinstance(n, dict) else n
|
|
391
|
+
if nid:
|
|
392
|
+
out.append(str(nid))
|
|
393
|
+
return out
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
# 生效条件:basis 为 None 时返回 BASIS_TRUST_MISSING;否则把 str(basis).strip().lower() 作为 BASIS_TRUST 的键,命中返回对应权重,未命中(含空串)返回 BASIS_TRUST_MISSING;
|
|
397
|
+
def basis_trust(basis):
|
|
398
|
+
"""验证基底 → 可信权重;缺失/未知一律给最低档(不假装可信)。"""
|
|
399
|
+
if basis is None:
|
|
400
|
+
return BASIS_TRUST_MISSING
|
|
401
|
+
return BASIS_TRUST.get(str(basis).strip().lower(), BASIS_TRUST_MISSING)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
# 生效条件:cg 的 index(getattr(cg,"index",None) or {})与其 "nodes" 同为真值时,返回以这些节点 id 为键的入度表,仅当 _targets(e) 给出的目标 t 也在 nodes 且 t != nid 时计数 +1;index 或 "nodes" 为假值(None/{})时 nodes 回落 {},直接返回空 dict。
|
|
405
|
+
def coverage_index(cg) -> dict:
|
|
406
|
+
"""入度表:nid → 被多少节点指向(覆盖度,O(N) 免读文件)。"""
|
|
407
|
+
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
408
|
+
indeg = {nid: 0 for nid in nodes}
|
|
409
|
+
for nid, e in nodes.items():
|
|
410
|
+
for t in _targets(e):
|
|
411
|
+
if t in indeg and t != nid:
|
|
412
|
+
indeg[t] += 1
|
|
413
|
+
return indeg
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
# 生效条件:cg.index 的 "nodes" 为 dict 时,layer 真值仅处理 e.get("layer")==layer 的节点,layer 假值不过滤;content_hash 为假值(None/空串/0 等)的节点输出 0.0,同 (e.get("layer"), content_hash) 第二次撞车时当前与首次节点均输出 1.0,否则输出 0.0;
|
|
417
|
+
def redundancy_map(cg, layer=None) -> dict:
|
|
418
|
+
"""同层内容哈希撞车 → 冗余度 1.0,否则 0.0(精确冗余,O(N) 免读文件)。
|
|
419
|
+
|
|
420
|
+
诚实边界:这是**精确冗余**(同一层出现完全相同的正文),不是语义近似冗余。
|
|
421
|
+
语义近似由 `forgetting.redundancy`(bigram 覆盖)在写入侧单独负责。
|
|
422
|
+
"""
|
|
423
|
+
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
424
|
+
seen, out = {}, {}
|
|
425
|
+
for nid, e in nodes.items():
|
|
426
|
+
if layer and e.get("layer") != layer:
|
|
427
|
+
continue
|
|
428
|
+
h = e.get("content_hash") or ""
|
|
429
|
+
if not h:
|
|
430
|
+
out[nid] = 0.0
|
|
431
|
+
continue
|
|
432
|
+
key = (e.get("layer"), h)
|
|
433
|
+
if key in seen:
|
|
434
|
+
out[nid] = 1.0
|
|
435
|
+
out[seen[key]] = 1.0
|
|
436
|
+
else:
|
|
437
|
+
seen[key] = nid
|
|
438
|
+
out.setdefault(nid, 0.0)
|
|
439
|
+
return out
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
# 生效条件:cg.index 的 nodes 为 dict 且 entry 非 None 或 nodes.get(nid) 命中时,e 按 entry 优先否则 nodes.get(nid);indeg/red 分别仅在为 None 时回落 coverage_index(cg)/redundancy_map(cg, layer=e.get("layer"))(空容器不回落);按 IMPORTANCE_MIX、COV_SAT 及 e.get("verification_basis") 的 basis_trust 计算 coverage/redundancy/basis 分量,按 bool(e.get("protected")) 选择 IMPORTANCE_PROTECT 或 IMPORTANCE_FLOOR 作下限、IMPORTANCE_CEIL 作上限,返回含 before(e.get("importance",0.5) or 0.5)、after、components、protected 的 dict;entry 与 nodes.get(nid) 均为 None 返回 None;
|
|
443
|
+
def node_importance(cg, nid, indeg=None, red=None, entry=None):
|
|
444
|
+
"""单节点结构重要性分解(可审计:给出分量而非只给分)。"""
|
|
445
|
+
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
446
|
+
e = entry if entry is not None else nodes.get(nid)
|
|
447
|
+
if e is None:
|
|
448
|
+
return None
|
|
449
|
+
indeg = indeg if indeg is not None else coverage_index(cg)
|
|
450
|
+
red = red if red is not None else redundancy_map(cg, layer=e.get("layer"))
|
|
451
|
+
d = int(indeg.get(nid, 0) or 0)
|
|
452
|
+
cov = min(1.0, math.log1p(d) / math.log1p(COV_SAT))
|
|
453
|
+
rr = max(0.0, min(1.0, float(red.get(nid, 0.0) or 0.0)))
|
|
454
|
+
bt = basis_trust(e.get("verification_basis"))
|
|
455
|
+
score = (IMPORTANCE_MIX["basis"] * bt
|
|
456
|
+
+ IMPORTANCE_MIX["coverage"] * cov
|
|
457
|
+
+ IMPORTANCE_MIX["redundancy"] * (1.0 - rr))
|
|
458
|
+
protected = bool(e.get("protected"))
|
|
459
|
+
floor = IMPORTANCE_PROTECT if protected else IMPORTANCE_FLOOR
|
|
460
|
+
score = max(floor, min(IMPORTANCE_CEIL, score))
|
|
461
|
+
return {"node_id": nid,
|
|
462
|
+
"before": float(e.get("importance", 0.5) or 0.5),
|
|
463
|
+
"after": round(score, 4),
|
|
464
|
+
"components": {"coverage": round(cov, 4), "redundancy": round(rr, 4),
|
|
465
|
+
"basis_trust": round(bt, 4), "in_degree": d,
|
|
466
|
+
"verification_basis": e.get("verification_basis")},
|
|
467
|
+
"protected": protected,
|
|
468
|
+
"protected_floor": protected}
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
# 生效条件:给定 cg 且 nodes = cg.index["nodes"] 时按 layer 过滤、limit 为真值才 ids = ids[:int(limit)] 逐节点重算,abs(after-before) < float(min_delta) 记 unchanged;仅 apply=True 才把 frontmatter.importance/importance_source/importance_components 写回(after >= IMPORTANCE_PROTECT 且未 protected 时补写 protected/protection_reason),并向 cg.root 下 append_jsonl(..., MAINTAIN_LOG) 记 batch 后 rebuild_index。
|
|
472
|
+
def recalc(cg, layer=None, limit=None, apply=False, min_delta=APPLY_DELTA,
|
|
473
|
+
actor="maintain", dry_run_samples=10):
|
|
474
|
+
"""结构重要性重算:覆盖度 + 冗余度 + 验证基底 → 重排节点重要性。
|
|
475
|
+
|
|
476
|
+
apply=False(默认)只出报表,不写盘(对应计划「可预演」)。
|
|
477
|
+
apply=True 逐节点改写 `frontmatter.importance`,每批写一条 `_maintain.jsonl`
|
|
478
|
+
(before/after/分量/actor),并提供 rollback 反向应用。
|
|
479
|
+
"""
|
|
480
|
+
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
481
|
+
indeg = coverage_index(cg)
|
|
482
|
+
red = redundancy_map(cg, layer=layer)
|
|
483
|
+
ids = [nid for nid, e in nodes.items()
|
|
484
|
+
if not layer or e.get("layer") == layer]
|
|
485
|
+
ids.sort()
|
|
486
|
+
if limit:
|
|
487
|
+
ids = ids[:int(limit)]
|
|
488
|
+
t0 = time.time()
|
|
489
|
+
planned, changed, unchanged, skipped = [], 0, 0, 0
|
|
490
|
+
before_sum = after_sum = 0.0
|
|
491
|
+
by_layer = {}
|
|
492
|
+
batch = time.strftime("%Y%m%d-%H%M%S")
|
|
493
|
+
samples = []
|
|
494
|
+
for nid in ids:
|
|
495
|
+
info = node_importance(cg, nid, indeg=indeg, red=red)
|
|
496
|
+
if info is None:
|
|
497
|
+
skipped += 1
|
|
498
|
+
continue
|
|
499
|
+
before, after = info["before"], info["after"]
|
|
500
|
+
before_sum += before
|
|
501
|
+
after_sum += after
|
|
502
|
+
lay = (nodes.get(nid) or {}).get("layer") or "?"
|
|
503
|
+
bl = by_layer.setdefault(lay, {"nodes": 0, "changed": 0,
|
|
504
|
+
"avg_before": 0.0, "avg_after": 0.0})
|
|
505
|
+
bl["nodes"] += 1
|
|
506
|
+
if abs(after - before) < float(min_delta):
|
|
507
|
+
unchanged += 1
|
|
508
|
+
continue
|
|
509
|
+
changed += 1
|
|
510
|
+
bl["changed"] += 1
|
|
511
|
+
plan = dict(info)
|
|
512
|
+
plan["batch"] = batch
|
|
513
|
+
plan["delta"] = round(after - before, 4)
|
|
514
|
+
planned.append(plan)
|
|
515
|
+
if len(samples) < int(dry_run_samples):
|
|
516
|
+
samples.append(plan)
|
|
517
|
+
for lay, bl in list(by_layer.items()):
|
|
518
|
+
bl["avg_before"] = 0.0
|
|
519
|
+
bl["avg_after"] = 0.0
|
|
520
|
+
written = 0
|
|
521
|
+
if apply:
|
|
522
|
+
for plan in planned:
|
|
523
|
+
nid = plan["node_id"]
|
|
524
|
+
node = cg.get(nid)
|
|
525
|
+
if not node:
|
|
526
|
+
continue
|
|
527
|
+
fm = node.get("frontmatter") or {}
|
|
528
|
+
fm["importance"] = plan["after"]
|
|
529
|
+
fm["importance_source"] = "recalc"
|
|
530
|
+
fm["importance_components"] = plan["components"]
|
|
531
|
+
if plan["after"] >= IMPORTANCE_PROTECT and not fm.get("protected"):
|
|
532
|
+
fm["protected"] = True
|
|
533
|
+
fm["protection_reason"] = (f"recalc importance={plan['after']:.2f}"
|
|
534
|
+
f"≥{IMPORTANCE_PROTECT}")
|
|
535
|
+
path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
|
|
536
|
+
or node.get("path") or f"{nid}.md")
|
|
537
|
+
cg._write_node(nid, path, fm, node.get("content") or "")
|
|
538
|
+
e = nodes.get(nid)
|
|
539
|
+
if e is not None:
|
|
540
|
+
e["importance"] = plan["after"]
|
|
541
|
+
if fm.get("protected"):
|
|
542
|
+
e["protected"] = True
|
|
543
|
+
e["protection_reason"] = fm["protection_reason"]
|
|
544
|
+
rec = {"t": time.time(), "action": "importance", "batch": batch,
|
|
545
|
+
"id": nid, "layer": (e or {}).get("layer"),
|
|
546
|
+
"before": plan["before"], "after": plan["after"],
|
|
547
|
+
"delta": plan["delta"], "components": plan["components"],
|
|
548
|
+
"actor": actor}
|
|
549
|
+
append_jsonl(os.path.join(cg.root, MAINTAIN_LOG), rec)
|
|
550
|
+
written += 1
|
|
551
|
+
if written and hasattr(cg, "rebuild_index"):
|
|
552
|
+
cg.rebuild_index() # 索引与盘面重新对齐,防内存/磁盘分叉
|
|
553
|
+
n = max(1, len(ids))
|
|
554
|
+
return {
|
|
555
|
+
"ok": True, "action": "importance", "dry_run": not apply,
|
|
556
|
+
"batch": batch, "nodes_scanned": len(ids), "changed": changed,
|
|
557
|
+
"unchanged": unchanged, "skipped": skipped, "written": written,
|
|
558
|
+
"min_delta": float(min_delta),
|
|
559
|
+
"avg_before": round(before_sum / n, 4),
|
|
560
|
+
"avg_after": round(after_sum / n, 4),
|
|
561
|
+
"by_layer": {k: {"nodes": v["nodes"], "changed": v["changed"]}
|
|
562
|
+
for k, v in by_layer.items()},
|
|
563
|
+
"samples": samples, "elapsed_ms": int((time.time() - t0) * 1000),
|
|
564
|
+
"log": MAINTAIN_LOG,
|
|
565
|
+
"note": ("dry-run:未写盘;apply=True 才改写 importance"
|
|
566
|
+
if not apply else
|
|
567
|
+
f"已改写 {written} 个节点;回滚见 rollback(batch={batch})"),
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
# 生效条件:cg.root/MAINTAIN_LOG 可读出 action=="importance" 记录后,entry_ids 为真值时按记录 id 是否在 {str(x) for x in entry_ids} 过滤;否则 batch 为真值时按 r.get("batch")==batch 过滤;否则取最后一条记录的 batch 再按其过滤;无 importance 记录返回 {"ok":False,"error":"no_records","reverted":0},过滤后无记录返回 {"ok":False,"error":"batch_not_found",...};对命中且 cg.get(nid) 为真的记录写回 rec.get("before") 并计数,若 reverted 且 cg 有 rebuild_index 则调用,最后 append_jsonl 写 actor 并返回 {"ok":True,"batch":batch,"reverted":reverted,"ids":ids};
|
|
572
|
+
def rollback(cg, batch=None, entry_ids=None, actor="maintain"):
|
|
573
|
+
"""把重要性重算反向应用(bulk 改写的可回滚兑现)。
|
|
574
|
+
|
|
575
|
+
batch 为空则回滚**最近一批**。返回 {ok, reverted, batch, ids}。
|
|
576
|
+
"""
|
|
577
|
+
log_path = os.path.join(cg.root, MAINTAIN_LOG)
|
|
578
|
+
records = [r for r in read_jsonl(log_path)
|
|
579
|
+
if r.get("action") == "importance"]
|
|
580
|
+
if not records:
|
|
581
|
+
return {"ok": False, "error": "no_records", "reverted": 0}
|
|
582
|
+
if entry_ids:
|
|
583
|
+
want = {str(x) for x in entry_ids}
|
|
584
|
+
records = [r for r in records if str(r.get("id")) in want]
|
|
585
|
+
elif batch:
|
|
586
|
+
records = [r for r in records if r.get("batch") == batch]
|
|
587
|
+
else:
|
|
588
|
+
batch = records[-1].get("batch")
|
|
589
|
+
records = [r for r in records if r.get("batch") == batch]
|
|
590
|
+
if not records:
|
|
591
|
+
return {"ok": False, "error": "batch_not_found", "batch": batch,
|
|
592
|
+
"reverted": 0}
|
|
593
|
+
nodes = (getattr(cg, "index", None) or {}).get("nodes") or {}
|
|
594
|
+
reverted, ids = 0, []
|
|
595
|
+
# 同一节点多条记录时以最早一条的 before 为准
|
|
596
|
+
for rec in records:
|
|
597
|
+
nid = rec.get("id")
|
|
598
|
+
node = cg.get(nid)
|
|
599
|
+
if not node:
|
|
600
|
+
continue
|
|
601
|
+
fm = node.get("frontmatter") or {}
|
|
602
|
+
fm["importance"] = rec.get("before")
|
|
603
|
+
fm["importance_source"] = "recalc_rollback"
|
|
604
|
+
path = os.path.join(cg.root, (nodes.get(nid) or {}).get("path")
|
|
605
|
+
or node.get("path") or f"{nid}.md")
|
|
606
|
+
cg._write_node(nid, path, fm, node.get("content") or "")
|
|
607
|
+
e = nodes.get(nid)
|
|
608
|
+
if e is not None:
|
|
609
|
+
e["importance"] = rec.get("before")
|
|
610
|
+
reverted += 1
|
|
611
|
+
ids.append(nid)
|
|
612
|
+
if reverted and hasattr(cg, "rebuild_index"):
|
|
613
|
+
cg.rebuild_index()
|
|
614
|
+
append_jsonl(log_path, {"t": time.time(), "action": "importance_rollback",
|
|
615
|
+
"batch": batch, "reverted": reverted, "actor": actor})
|
|
616
|
+
return {"ok": True, "batch": batch, "reverted": reverted, "ids": ids}
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
# 生效条件:cg.root/MAINTAIN_LOG 可读出 JSONL 记录后,action 为真值时按 r.get("action")==action 过滤,假值不过滤;返回 recs[-int(limit):],其中 limit=0 时 int(0)=0 使切片为 recs[0:] 返回全部而非空;
|
|
620
|
+
def history(cg, limit=100, action=None):
|
|
621
|
+
"""维护留痕(最近 limit 条),可按 action 过滤。"""
|
|
622
|
+
recs = list(read_jsonl(os.path.join(cg.root, MAINTAIN_LOG)))
|
|
623
|
+
if action:
|
|
624
|
+
recs = [r for r in recs if r.get("action") == action]
|
|
625
625
|
return recs[-int(limit):]
|