@furongjun1999/dsh-memory 0.4.7 → 0.4.9
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 +130 -47
- package/codebuddy/CODEBUDDY.md +21 -10
- package/codebuddy/README.md +13 -1
- package/codebuddy/mcp.json +9 -0
- 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 -0
- 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 -0
- package/docs/README.md +111 -0
- package/docs/discipline/harnesses.yaml +226 -152
- package/docs/discipline/templates/full.md.tmpl +61 -58
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.md +127 -0
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.png +0 -0
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_/347/201/265/346/236/242_vs_dejavu_/347/273/237/344/270/200/350/257/204/345/210/206_v7.md +202 -0
- package/docs/experiments/linkref_backfill/candidates_20260917.json +726 -0
- package/docs/experiments/linkref_backfill/candidates_internal_20260917.json +602 -0
- package/docs/experiments/linkref_backfill/candidates_internal_v2.json +603 -0
- package/docs/experiments/linkref_backfill/candidates_secret_20260917.json +884 -0
- package/docs/experiments/linkref_backfill/candidates_secret_v2.json +789 -0
- package/docs/experiments/m4-role-probe/census.py +86 -0
- package/docs/experiments/m4-role-probe/probe.py +89 -0
- package/docs/experiments/mapped_confidence/bench_mapped_conf.py +216 -0
- package/docs/experiments/mapped_confidence/post_check.py +75 -0
- package/docs/experiments/mapped_confidence/repro_thirdparty_tol.py +83 -0
- package/docs/experiments/mapped_confidence/result_mapped_conf.json +215 -0
- package/docs/hive//345/244/232/347/253/257harness/351/200/232/344/277/241/345/245/221/347/272/246_v0.1.md +42 -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 -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 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S1b/344/270/216/345/217/254/345/233/236/346/235/203/350/241/241_v0.1.md +57 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S7/345/200/222/346/216/222/345/200/231/351/200/211/345/261/202_v0.1.md +126 -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 +503 -0
- 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 +14 -2
- package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -0
- package/docs/{README → mdcg/README}/350/257/246/347/273/206/347/211/210_v0.4.5.md +631 -625
- package/docs/{ → mdcg/}/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 +1 -1
- package/docs/mdcg//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_/345/245/221/347/272/246_v0.1.md +82 -0
- 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 -0
- 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 +263 -0
- 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 +1 -1
- package/docs/mdcg//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 -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 +2 -2
- package/docs/{ → mdcg/}/347/201/265/346/236/242/344/270/211/345/261/202/346/213/206/345/210/206/350/247/204/345/210/222_v0.1.md +181 -181
- 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 -0
- package/docs/mdcg//347/216/257/344/272/214_/347/231/275/347/256/261/345/241/253/345/205/205/346/265/201/346/260/264/347/272/277_v0.1.md +31 -0
- package/docs/{ → mdcg/}/347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +2 -2
- 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 +1 -1
- 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 +4 -4
- package/docs/{ → mdcg/}/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_MdCGOS/344/270/216MCP/346/216/245/345/205/245_v0.1.md +2 -2
- package/docs/mdcg//350/267/250/347/253/257/351/252/214/350/257/201/344/270/216/345/220/214/346/255/245/345/215/217/350/256/256_v0.1.md +93 -0
- 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 -0
- package/docs/{ → swarm/}/350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +3 -3
- 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 -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 -0
- 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 -0
- 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 -0
- 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 +6 -6
- 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 +1 -1
- 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 -0
- 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 -0
- package/docs//345/255/230/347/256/227/344/270/200/344/275/223/346/236/266/346/236/204/345/255/246/344/271/240_/345/244/226/351/203/250/347/220/206/350/256/272/345/257/271/347/205/247/344/270/216/350/267/257/347/272/277/344/272/244/346/216/245_20260916.md +98 -0
- package/docs//345/255/230/347/256/227/344/270/200/344/275/223/347/245/236/347/273/217/347/275/221/347/273/234/346/236/266/346/236/204_/346/200/273/347/272/262/344/270/216/344/272/244/346/216/245_20260916.md +109 -0
- 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 +434 -405
- package/docs//347/201/265/346/236/242/350/207/252/346/210/221/346/224/271/350/277/233/345/267/245/344/275/234/350/256/241/345/210/222_/345/244/226/351/203/250/347/240/224/347/251/266/347/263/273/345/210/227/345/220/270/346/224/266_v1_20260919.md +286 -0
- package/docs//347/231/275/347/256/261/345/214/226/347/272/262/351/242/206_/344/270/211/351/241/271/347/233/256/345/255/246/344/271/240/346/200/273/346/236/266/346/236/204/344/270/216Ghidra/344/272/244/346/216/245_20260916.md +104 -0
- package/docs//350/256/260/345/277/206/350/257/204/345/256/241/347/263/273/347/273/237_/347/253/213/351/241/271/350/256/276/350/256/241/344/270/216/346/226/275/345/267/245/344/272/244/346/216/245_20260915.md +183 -0
- package/dsh/README.md +34 -1
- package/dsh/cordis.yml.example +13 -7
- package/dsh/hive-mcp-probe.mjs +94 -0
- package/dsh/hive-mcp.example.yml +62 -0
- package/dsh/update-lingshu.bat +11 -0
- package/dsh/update-lingshu.ps1 +337 -0
- package/lib/hooks.d.ts +8 -0
- package/lib/hooks.js +27 -24
- package/lib/index.d.ts +4 -2
- package/lib/index.js +29 -6
- package/lib/lib/datapath.d.ts +76 -1
- package/lib/lib/datapath.js +199 -13
- package/lib/lib/mdcg_client.d.ts +6 -3
- package/lib/lib/mdcg_client.js +6 -5
- package/lib/lib/mutual.js +4 -4
- package/lib/lib/prompt_safety.d.ts +48 -0
- package/lib/lib/prompt_safety.js +62 -0
- package/lib/lib/token_store.js +4 -5
- package/md_cg/audit.py +91 -2
- package/md_cg/autonomy.py +86 -15
- package/md_cg/backfill.py +36 -1
- package/md_cg/backfill_bigdomain.py +34 -0
- package/md_cg/bench6_arms.py +28 -1
- package/md_cg/bench6_common.py +10 -1
- package/md_cg/bench6_competitors.py +6 -1
- package/md_cg/bench_axis_domain.py +9 -1
- package/md_cg/bench_blind_comp.py +7 -1
- package/md_cg/bench_en_atoms_public.py +9 -0
- package/md_cg/bench_governance.py +348 -0
- package/md_cg/bench_lme_zh.py +16 -1
- package/md_cg/bench_locomo.py +2 -1
- package/md_cg/bench_locomo_zh.py +16 -1
- package/md_cg/bench_locomo_zh_public.py +4 -1
- package/md_cg/bench_longmem.py +2 -1
- package/md_cg/bench_membench.py +37 -6
- package/md_cg/bench_p0.py +4 -1
- package/md_cg/bench_progressive.py +61 -10
- package/md_cg/bench_role_views.py +238 -0
- package/md_cg/bench_task_ab.py +8 -1
- package/md_cg/bench_task_ab_llm.py +13 -1
- package/md_cg/bench_unified_en.py +6 -1
- package/md_cg/bench_zh_mad.py +20 -1
- package/md_cg/blindspot_tickets.py +123 -0
- package/md_cg/branches.py +286 -0
- package/md_cg/build_postings.py +73 -0
- package/md_cg/ccgc.py +949 -0
- package/md_cg/census.py +5 -1
- package/md_cg/chain.py +24 -3
- package/md_cg/codeindex.py +134 -17
- package/md_cg/coldverify.py +265 -0
- package/md_cg/comment_gate.py +338 -0
- package/md_cg/cond_compose.py +190 -0
- package/md_cg/cond_facts.py +155 -0
- package/md_cg/cond_template.json +107 -0
- package/md_cg/condition_anchor.py +143 -0
- package/md_cg/conformance.py +727 -0
- package/md_cg/consistency.py +25 -2
- package/md_cg/consolidate.py +53 -2
- package/md_cg/corpus.py +5 -1
- package/md_cg/crosscheck.py +42 -2
- package/md_cg/crypto.py +35 -1
- package/md_cg/d_meta.py +310 -0
- package/md_cg/datapath.py +201 -26
- package/md_cg/docindex.py +122 -1
- package/md_cg/eval_common.py +35 -6
- package/md_cg/evidence.py +27 -1
- package/md_cg/evolution.py +21 -1
- package/md_cg/export.py +11 -1
- package/md_cg/forgetting.py +34 -4
- package/md_cg/fsutil.py +81 -2
- package/md_cg/hotcache.py +214 -0
- package/md_cg/hyperedge.py +251 -0
- package/md_cg/identity.py +20 -3
- package/md_cg/insight.py +19 -3
- package/md_cg/lexicon/build_cedict_en_zh.py +9 -0
- package/md_cg/lexicon/build_standard_en.py +171 -168
- package/md_cg/lexicon/expand_en_zh.py +6 -0
- package/md_cg/lifecycle.py +273 -0
- package/md_cg/linkref.py +281 -0
- package/md_cg/links.py +29 -1
- package/md_cg/mcp_server.py +894 -168
- package/md_cg/md_whitebox.py +53 -1
- package/md_cg/mdcg.py +1205 -41
- package/md_cg/mdcos.py +1060 -76
- package/md_cg/metacognition.py +39 -4
- package/md_cg/migrate.py +4 -0
- package/md_cg/migrate_aeis.py +221 -213
- package/md_cg/migrate_roleplay.py +8 -0
- package/md_cg/migrate_wisdom_graph.py +14 -1
- package/md_cg/mreview/__init__.py +25 -0
- package/md_cg/mreview/__main__.py +110 -0
- package/md_cg/mreview/bundle.py +178 -0
- package/md_cg/mreview/candidates.py +262 -0
- package/md_cg/mreview/govern.py +694 -0
- package/md_cg/mreview/locate.py +939 -0
- package/md_cg/mreview/pipeline.py +729 -0
- package/md_cg/mreview/rules/duplication.json +21 -0
- package/md_cg/mreview/rules/field_coverage.json +54 -0
- package/md_cg/mreview/rules/source_license.json +21 -0
- package/md_cg/mreview/rules/template_flow.json +21 -0
- package/md_cg/mreview/ruleset.py +253 -0
- package/md_cg/nodefile.py +269 -1
- package/md_cg/pooling.py +23 -1
- package/md_cg/postings.py +298 -0
- package/md_cg/predict.py +113 -15
- package/md_cg/progressive.py +3 -0
- package/md_cg/protect.py +18 -5
- package/md_cg/protocol.py +372 -0
- package/md_cg/provenance.py +262 -0
- package/md_cg/reach.py +453 -0
- package/md_cg/refindex.py +88 -4
- package/md_cg/refine.py +20 -1
- package/md_cg/roleviews.py +89 -0
- package/md_cg/routing.py +76 -0
- package/md_cg/scrub.py +68 -3
- package/md_cg/security.py +26 -1
- package/md_cg/self_state.py +65 -2
- package/md_cg/selfreport.py +151 -0
- package/md_cg/semantic/canonical.py +5 -0
- package/md_cg/semantic/en_normalizer.py +364 -295
- package/md_cg/semantic/zh_en_atoms.py +139 -136
- package/md_cg/signer.py +41 -1
- package/md_cg/sources.py +583 -547
- package/md_cg/statushdr.py +179 -0
- package/md_cg/stg.py +59 -18
- package/md_cg/subgraph.py +23 -0
- package/md_cg/sustain.py +74 -1
- package/md_cg/tasks.py +471 -0
- package/md_cg/test_action_derive.py +203 -0
- package/md_cg/test_audit_rotate.py +270 -0
- package/md_cg/test_autonomy.py +26 -0
- package/md_cg/test_bench_governance.py +102 -0
- package/md_cg/test_blindspot_tickets.py +166 -0
- package/md_cg/test_branches.py +249 -0
- package/md_cg/test_ccg_perturb.py +1 -1
- package/md_cg/test_ccgc.py +433 -0
- package/md_cg/test_codeindex.py +338 -0
- package/md_cg/test_comment_gate.py +187 -0
- package/md_cg/test_cond_compose_anchors.py +76 -0
- package/md_cg/test_condition_anchor.py +82 -0
- package/md_cg/test_conformance.py +343 -0
- package/md_cg/test_d_meta.py +412 -0
- package/md_cg/test_datapath_root.py +188 -0
- package/md_cg/test_en_pipeline.py +24 -0
- package/md_cg/test_gain_gate.py +47 -1
- package/md_cg/test_health_scale.py +173 -0
- package/md_cg/test_hot_cold.py +187 -0
- package/md_cg/test_hyperedge.py +245 -0
- package/md_cg/test_identity_attribution.py +6 -0
- package/md_cg/test_index_durability.py +224 -0
- package/md_cg/test_lifecycle.py +309 -0
- package/md_cg/test_linkref.py +306 -0
- package/md_cg/test_md_access_parity.py +15 -3
- package/md_cg/test_mr_m1.py +769 -0
- package/md_cg/test_mr_m2.py +587 -0
- package/md_cg/test_mr_m3.py +710 -0
- package/md_cg/test_mr_m4.py +485 -0
- package/md_cg/test_p1.py +1 -1
- package/md_cg/test_p11_consistency.py +1 -1
- package/md_cg/test_p12_metacognition.py +2 -2
- package/md_cg/test_p16_self_state.py +1 -1
- package/md_cg/test_p26_refindex.py +50 -21
- package/md_cg/test_p27_docindex.py +258 -4
- package/md_cg/test_p28_refcheck.py +1 -1
- package/md_cg/test_p29_session_ingest_export.py +1 -1
- package/md_cg/test_p2_mcp.py +7 -1
- package/md_cg/test_p31_insight.py +24 -0
- package/md_cg/test_p38_contextualize.py +1 -1
- package/md_cg/test_p39_vision_evidence.py +1 -1
- package/md_cg/test_p40_refine_worklist.py +1 -1
- package/md_cg/test_p41_evolve_patrol.py +1 -1
- package/md_cg/test_p42_provenance.py +1 -1
- package/md_cg/test_p43_pooling.py +41 -13
- package/md_cg/test_p44_md_whitebox.py +14 -1
- package/md_cg/test_protocol.py +243 -0
- package/md_cg/test_reach.py +378 -0
- package/md_cg/test_reach_keys.py +201 -0
- package/md_cg/test_reach_meta_exits.py +145 -0
- package/md_cg/test_read_clip.py +141 -0
- package/md_cg/test_retr_s1.py +340 -0
- package/md_cg/test_retr_s1b.py +209 -0
- package/md_cg/test_retr_s3.py +194 -0
- package/md_cg/test_retr_s4.py +163 -0
- package/md_cg/test_retr_s5.py +200 -0
- package/md_cg/test_retr_s6.py +157 -0
- package/md_cg/test_retr_s7.py +385 -0
- package/md_cg/test_retr_s8_time.py +316 -0
- package/md_cg/test_retr_s9_edges.py +286 -0
- package/md_cg/test_retr_s9_entity_ctx.py +175 -0
- package/md_cg/test_review_conformance.py +367 -0
- package/md_cg/test_role_views.py +354 -0
- package/md_cg/test_tasks.py +409 -0
- package/md_cg/test_tool_face.py +189 -0
- package/md_cg/test_trust.py +361 -0
- package/md_cg/test_twophase.py +286 -0
- package/md_cg/test_units_poll.py +71 -0
- package/md_cg/test_v14_fixes.py +397 -0
- package/md_cg/test_validity_filter.py +280 -0
- package/md_cg/test_wisdom_md_store.py +7 -3
- package/md_cg/test_writepipe.py +214 -0
- package/md_cg/theory.py +17 -2
- package/md_cg/tokens.py +134 -12
- package/md_cg/tool_face.py +261 -0
- package/md_cg/trust.py +943 -0
- package/md_cg/twophase.py +232 -0
- package/md_cg/units.py +665 -0
- package/md_cg/vision_evidence.py +25 -2
- package/md_cg/weights.py +25 -2
- package/md_cg/whitebox.py +33 -2
- package/md_cg/whitebox_kb/data/verify_cache.json +21233 -360
- package/md_cg/whitebox_kb/data/verify_savings.jsonl +5124 -0
- package/md_cg/whitebox_kb/wisdom/audit_log/chain_heat.json +10 -10
- package/md_cg/whitebox_kb/wisdom/code_compose.py +113 -6
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +1 -1
- package/md_cg/whitebox_kb/wisdom/verifier.py +340 -55
- package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db +0 -0
- package/md_cg/writelimit.py +37 -7
- package/md_cg/writepipe.py +543 -0
- package/package.json +2 -2
- package/skills/skills/designer-perspective/scripts/__pycache__/designer.cpython-310.pyc +0 -0
- package/skills/skills/designer-perspective/scripts/designer.py +17 -1
- package/skills/skills/designer-perspective/tests/selftest.py +3 -1
- package/src/hooks.ts +27 -22
- package/src/index.ts +33 -6
- package/src/lib/datapath.ts +211 -13
- package/src/lib/mdcg_client.ts +12 -8
- package/src/lib/mutual.ts +411 -411
- package/src/lib/prompt_safety.ts +62 -0
- package/src/lib/token_store.ts +4 -5
- package/zcode/AGENTS.md +21 -10
- package/zcode/README.md +4 -0
- package/docs//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +0 -221
- /package/docs/{AGI → 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" +0 -0
- /package/docs/{AGI → 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" +0 -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" +0 -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" +0 -0
- /package/docs/{guardrail-charter.md → mdcg/guardrail-charter.md} +0 -0
- /package/docs/{lingshu_tutorial.html → mdcg/lingshu_tutorial.html} +0 -0
- /package/docs/{memory-assessment.html → mdcg/memory-assessment.html} +0 -0
- /package/docs/{memory_score.html → mdcg/memory_score.html} +0 -0
- /package/docs/{memory_score.png → mdcg/memory_score.png} +0 -0
- /package/docs/{release_v0.3.0.md → mdcg/release_v0.3.0.md} +0 -0
- /package/docs/{release_v0.4.5.md → mdcg/release_v0.4.5.md} +0 -0
- /package/docs/{tool_table_v0.3.0.md → mdcg/tool_table_v0.3.0.md} +0 -0
- /package/docs/{ → mdcg/}/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" +0 -0
- /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" +0 -0
- /package/docs/{ → mdcg/}/347/201/265/346/236/242MCP/345/267/245/345/205/267/346/200/273/350/241/250_v3.4.md" +0 -0
- /package/docs/{ → mdcg/}/347/201/265/346/236/242_/350/207/252/346/210/221/345/261/202/345/256/232/344/271/211.md" +0 -0
- /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_MD/347/233/256/345/275/225/346/226/271/346/241/210_v0.1.md" +0 -0
- /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" +0 -0
- /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276/344/275/234/344/270/272/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_/350/257/204/344/274/260/344/270/216/350/267/257/347/272/277_v0.1.md" +0 -0
- /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" +0 -0
- /package/docs/{ → plans/}/347/237/245/350/257/206/345/233/276/350/260/261/351/241/271/347/233/256_/344/272/244/346/216/245/346/226/207/346/241/243_20260914.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/344/275/277/347/224/250/346/212/245/345/221/212_20260913.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/345/212/237/350/203/275/350/257/264/346/230/216_v0.6.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/347/233/262/345/214/272/346/240/207/350/256/260_v1.0.md" +0 -0
- /package/docs/{ → theory/}/344/277/241/346/201/257/345/267/256/344/270/272/344/273/200/344/271/210/345/277/205/347/204/266/345/255/230/345/234/250/344/270/224/350/207/252/347/204/266/346/211/251/345/244/247.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/345/205/254/347/220/206/345/214/226/345/237/272/347/237/263.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/350/256/244/347/237/245/350/277/207/347/250/213.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/350/256/2723.4.md" +0 -0
- /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/346/230/257/344/273/200/344/271/210/357/274/237.md" +0 -0
- /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/347/263/273/345/210/227/302/267/347/254/254/344/272/224/347/257/207/357/274/232/350/256/251AI/347/234/237/346/255/243/350/243/205/344/270/212/350/256/260/345/277/206.md" +0 -0
package/md_cg/backfill.py
CHANGED
|
@@ -127,11 +127,13 @@ CAP_RULES = OrderedDict(
|
|
|
127
127
|
|
|
128
128
|
# ---- 通用工具 ------------------------------------------------------------
|
|
129
129
|
|
|
130
|
+
# 生效条件:x 为 str 时返回 MdCGOS(x),否则原样返回 x。
|
|
130
131
|
def _as_cg(x):
|
|
131
132
|
"""接受 root 路径或已构造的 cg 实例——保持密级隔离与密钥上下文。"""
|
|
132
133
|
return MdCGOS(x) if isinstance(x, str) else x
|
|
133
134
|
|
|
134
135
|
|
|
136
|
+
# 生效条件:v 为 list/tuple 时返回分号连接的非空元素文本;v 为 None 或空串时返回 "";否则返回 str(v).strip()(v 为 0 或 False 走此支返回 "0"/"False")。
|
|
135
137
|
def _as_text(v) -> str:
|
|
136
138
|
if isinstance(v, (list, tuple)):
|
|
137
139
|
return ";".join(str(x).strip() for x in v if str(x).strip())
|
|
@@ -140,12 +142,14 @@ def _as_text(v) -> str:
|
|
|
140
142
|
return str(v).strip()
|
|
141
143
|
|
|
142
144
|
|
|
145
|
+
# 生效条件:fm 为假值时按 {} 处理,state_attributes.comment 为 dict 时返回该 dict,否则返回 {}。
|
|
143
146
|
def _comment(fm: dict) -> dict:
|
|
144
147
|
st = (fm or {}).get("state_attributes")
|
|
145
148
|
c = st.get("comment") if isinstance(st, dict) else None
|
|
146
149
|
return c if isinstance(c, dict) else {}
|
|
147
150
|
|
|
148
151
|
|
|
152
|
+
# 生效条件:fm 的 state_attributes 为 dict 且其下 comment 为 dict 时原样返回该 comment;否则创建并返回空 comment dict(state_attributes 非 dict 时置 fm["state_attributes"]={},comment 非 dict 时置 st["comment"]={})。
|
|
149
153
|
def _ensure_comment(fm: dict) -> dict:
|
|
150
154
|
st = fm.get("state_attributes")
|
|
151
155
|
if not isinstance(st, dict):
|
|
@@ -158,10 +162,12 @@ def _ensure_comment(fm: dict) -> dict:
|
|
|
158
162
|
return c
|
|
159
163
|
|
|
160
164
|
|
|
165
|
+
# 生效条件:e 的 id 为真值时返回 id,否则返回 e 的 path 基名去掉最后 3 个字符(path 为假值时基名为空,结果空串)。
|
|
161
166
|
def _node_id(e: dict) -> str:
|
|
162
167
|
return e.get("id") or os.path.basename(e.get("path") or "")[:-3]
|
|
163
168
|
|
|
164
169
|
|
|
170
|
+
# 生效条件:fm 的 condition_space 四槽齐全时返回 nodefile.condition_space_text 合成文本,否则返回空串。
|
|
165
171
|
def _condition_text(fm: dict) -> str:
|
|
166
172
|
"""→ 条件空间四槽合成的生效条件声明;四槽不齐 → ""(不冒充)。
|
|
167
173
|
|
|
@@ -172,14 +178,17 @@ def _condition_text(fm: dict) -> str:
|
|
|
172
178
|
return nodefile.condition_space_text((fm or {}).get("condition_space"))
|
|
173
179
|
|
|
174
180
|
|
|
181
|
+
# 生效条件:s 为真值时返回其 sha1 前 12 位,s 为假值(None/空串等)时对空串取 sha1 前 12 位。
|
|
175
182
|
def _sha(s: str) -> str:
|
|
176
183
|
return hashlib.sha1((s or "").encode("utf-8")).hexdigest()[:12]
|
|
177
184
|
|
|
178
185
|
|
|
186
|
+
# 生效条件:batch 与 nid 经 f-string 拼接后取 sha1 前 12 位;两者为 None 会字符串化为 "None"。
|
|
179
187
|
def _entry_id(batch: str, nid: str) -> str:
|
|
180
188
|
return hashlib.sha1(f"{batch}|{nid}".encode("utf-8")).hexdigest()[:12]
|
|
181
189
|
|
|
182
190
|
|
|
191
|
+
# 生效条件:content 中 strip 后以 # 开头且去掉 # 与空白后、全角或半角冒号前首段等于 field 的整行被删除,其余行保留并 join。
|
|
183
192
|
def _remove_ccg_line(content: str, field: str) -> str:
|
|
184
193
|
"""删掉 `# <字段>:…` 整行(回滚用)。"""
|
|
185
194
|
keep = []
|
|
@@ -192,12 +201,14 @@ def _remove_ccg_line(content: str, field: str) -> str:
|
|
|
192
201
|
return "\n".join(keep)
|
|
193
202
|
|
|
194
203
|
|
|
204
|
+
# 生效条件:cg.root 与模块级常量 BACKFILL_LOG 拼接为返回路径。
|
|
195
205
|
def _log_path(cg) -> str:
|
|
196
206
|
return os.path.join(cg.root, BACKFILL_LOG)
|
|
197
207
|
|
|
198
208
|
|
|
199
209
|
# ---- 字段推导(唯一入口:只搬运已声明的证据) -----------------------------
|
|
200
210
|
|
|
211
|
+
# 生效条件:fm 与 content 给定时,仅对 content 中尚无对应 CCG 行的字段(功能名/生效条件/子功能/执行/验证方式/不适用条件)从 fm 的已有声明(state_attributes.comment、frontmatter、verification_basis、或形参 basis_text)取值,值非空且非占位文本才写入 out,假值不写、占位文本只把字段名追加进 placeholder_out(未传该形参时用临时列表)。
|
|
201
212
|
def derive_fields(fm: dict, content: str, basis_text: str = None,
|
|
202
213
|
placeholder_out: list = None) -> dict:
|
|
203
214
|
"""按**已有声明**推导可回填字段 → `{field: (value, basis)}`。
|
|
@@ -213,6 +224,7 @@ def derive_fields(fm: dict, content: str, basis_text: str = None,
|
|
|
213
224
|
ph = placeholder_out if placeholder_out is not None else []
|
|
214
225
|
out = {}
|
|
215
226
|
|
|
227
|
+
# 生效条件:field 与 basis 在 value 为真值且 nodefile.is_placeholder_text(value) 为假时写入 out;value 为假值不写入;value 为占位文本时仅把 field 记入 ph。
|
|
216
228
|
def _put(field, value, basis):
|
|
217
229
|
"""有值且非占位标记才写出;占位值只记名,绝不渲染成事实。"""
|
|
218
230
|
if not value:
|
|
@@ -267,6 +279,7 @@ def derive_fields(fm: dict, content: str, basis_text: str = None,
|
|
|
267
279
|
|
|
268
280
|
# ---- 节点筛选 ------------------------------------------------------------
|
|
269
281
|
|
|
282
|
+
# 生效条件:cg 无 _readable 可调用时返回 True;有可调用时返回 bool(fn(e)),fn(e) 抛异常时返回 False。
|
|
270
283
|
def _readable_guard(cg, e) -> bool:
|
|
271
284
|
fn = getattr(cg, "_readable", None)
|
|
272
285
|
if not callable(fn):
|
|
@@ -277,6 +290,7 @@ def _readable_guard(cg, e) -> bool:
|
|
|
277
290
|
return False
|
|
278
291
|
|
|
279
292
|
|
|
293
|
+
# 生效条件:仅当 cg 对 e 读出的 fm 非 None、content 未被 crypto.is_encrypted、e['layer'] 不在 SKIP_LAYERS 且 fm.get('tags') 无命中 SKIP_TAGS、ccg_completeness(content)['complete'] 为假时才继续——derive_fields(受 basis_text 影响)过滤掉 content 已有 CCG 行的可写字段为空时按 placeholder_out 是否非空返回 ('placeholder'/'unfillable', None),非空时返回 ('', item)(item 的 id 取 nid、class 依 undeducible 是否为空取 'backfillable' 或 'partial');上述四个前置不满足时依次返回 ('unreadable'/'locked'/'derived'/'present', None)。
|
|
280
294
|
def _classify(cg, e, nid, basis_text=None):
|
|
281
295
|
"""→ (skip_reason, item);skip_reason 非空表示不参与回填。"""
|
|
282
296
|
fm, content = cg._read(e)
|
|
@@ -317,6 +331,7 @@ def _classify(cg, e, nid, basis_text=None):
|
|
|
317
331
|
}
|
|
318
332
|
|
|
319
333
|
|
|
334
|
+
# 生效条件:x 经 _as_cg 后遍历 cg.index.nodes,按 ids/layer/prefix 过滤,内部层/不可读/locked/derived/present/unfillable/placeholder/partial 且 include_partial 为 False 分别计数跳过,其余标记 entry_id 并计入 targeted,items 受 limit 限制(limit 为 None 或 len(items) < limit 时追加),返回 dry_run rep。
|
|
320
335
|
def plan(x, layer=None, limit=None, ids=None, include_partial=False,
|
|
321
336
|
basis_text=None, prefix=None) -> dict:
|
|
322
337
|
"""预演:产出可回填清单,不写盘。
|
|
@@ -381,6 +396,7 @@ def plan(x, layer=None, limit=None, ids=None, include_partial=False,
|
|
|
381
396
|
|
|
382
397
|
# ---- 回填写入 / 回滚 / 留痕 ----------------------------------------------
|
|
383
398
|
|
|
399
|
+
# 生效条件:x 可被 _as_cg 解释为 CG 句柄时,按 layer/ids/prefix/entry_ids 选定条目做回填并返回含 written 等计数的 rep,其中 limit 非 None 时把写入数截断到该值。
|
|
384
400
|
def apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
385
401
|
batch=BATCH_DEFAULT, include_partial=False, basis_text=None,
|
|
386
402
|
actor=None, prefix=None) -> dict:
|
|
@@ -458,6 +474,7 @@ def apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
458
474
|
return rep
|
|
459
475
|
|
|
460
476
|
|
|
477
|
+
# 生效条件:x 经 _as_cg 定位后读留痕日志,仅对 action=='backfill' 且(batch 为假值则不过滤 batch,否则 rec['batch']==batch)、(entry_ids 为假值则不过滤,否则 rec['entry_id'] 属于该集合)、write_id 未出现在已完成 rollback 集合中、节点命中 cg.index['nodes'] 且 cg._read(e) 的 fm 可读、字段当前 _ccg_field(content, f) 等于留痕 after 的记录执行撤销写回(before 为 None 则删该 comment 键,否则还原原值),无字段可撤销只计 conflict 不写盘,reverted 非空时 rebuild_index,结果汇总进返回的 rep。
|
|
461
478
|
def rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
462
479
|
"""按留痕反向应用:撤销本批次回填(当前值 ≠ 写入值时跳过,防覆盖)。"""
|
|
463
480
|
cg = _as_cg(x)
|
|
@@ -528,6 +545,7 @@ def rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
528
545
|
return rep
|
|
529
546
|
|
|
530
547
|
|
|
548
|
+
# 生效条件:x 经 _as_cg,action/batch 为真值时过滤对应日志记录;limit 不为 None 且 >=0 时按 recs[-limit:] 截断(limit=0 时切片为全部记录),limit 为 None 或负数时不截断;返回 total/returned/records。
|
|
531
549
|
def history(x, limit=100, action=None, batch=None) -> dict:
|
|
532
550
|
cg = _as_cg(x)
|
|
533
551
|
recs = []
|
|
@@ -555,6 +573,7 @@ def history(x, limit=100, action=None, batch=None) -> dict:
|
|
|
555
573
|
_CAP_TEMPLATE_LINES = ("验证方式",)
|
|
556
574
|
|
|
557
575
|
|
|
576
|
+
# 生效条件:content 中去除 # 与空白后、全角或半角冒号前首段命中 _CAP_TEMPLATE_LINES 的行被剔除,其余行保留并 join。
|
|
558
577
|
def _cap_body(content: str) -> str:
|
|
559
578
|
"""正文(供关键词匹配)——剔除 CCG 模板行,防模板词污染候选。"""
|
|
560
579
|
keep = []
|
|
@@ -567,6 +586,7 @@ def _cap_body(content: str) -> str:
|
|
|
567
586
|
return "\n".join(keep)
|
|
568
587
|
|
|
569
588
|
|
|
589
|
+
# 生效条件:当 fm 为可 get 的 frontmatter、e 为带 id 的节点条目、content 为正文文本时,返回 title+e.id+功能名/生效条件/子功能字段+正文前 300 字合并后的小写串(不含 fm.tags)。
|
|
570
590
|
def _cap_text(e, fm, content) -> str:
|
|
571
591
|
"""候选匹配文本:节点标识 + CCG 字段 + 正文(**不含 `fm.tags`**)。"""
|
|
572
592
|
parts = [_as_text(fm.get("title")), e.get("id") or ""]
|
|
@@ -578,6 +598,7 @@ def _cap_text(e, fm, content) -> str:
|
|
|
578
598
|
return " ".join(parts).lower()
|
|
579
599
|
|
|
580
600
|
|
|
601
|
+
# 生效条件:text 包含 CAP_RULES 中某 cap 的至少一个关键词时,该 cap 以匹配关键词与置信度加入返回,按置信度降序、cap 升序排序;无匹配返回空 hits。
|
|
581
602
|
def cap_matches(text: str) -> list:
|
|
582
603
|
hits = []
|
|
583
604
|
for cap, kws in CAP_RULES.items():
|
|
@@ -589,6 +610,7 @@ def cap_matches(text: str) -> list:
|
|
|
589
610
|
return hits
|
|
590
611
|
|
|
591
612
|
|
|
613
|
+
# 生效条件:x 经 _as_cg,遍历 nodes 按 ids/layer 过滤,不可读计 denied,读取失败或加密计 locked,扫描后以 _cap_text 匹配并过滤 confidence >= min_conf 且标签未含 cap:,无命中计 present,有命中则 targeted 并受 limit 限制加入 items,返回 dry_run rep。
|
|
592
614
|
def cap_plan(x, layer=None, limit=None, ids=None, min_conf=0.5) -> dict:
|
|
593
615
|
"""预演:按关键词启发式给出 `cap:<op>` 标签建议(含依据与置信度),不写盘。"""
|
|
594
616
|
cg = _as_cg(x)
|
|
@@ -626,6 +648,7 @@ def cap_plan(x, layer=None, limit=None, ids=None, min_conf=0.5) -> dict:
|
|
|
626
648
|
return rep
|
|
627
649
|
|
|
628
650
|
|
|
651
|
+
# 生效条件:x 经 _as_cg,batch 假值回落 BATCH_DEFAULT;先 cap_plan 得 items,按 entry_ids 过滤;逐个检查节点存在、读取可读、无新增标签分别计 drift/locked/drift,成功写 tags 并记日志,limit 非 None 且 written >= limit 时 break;返回 rep。
|
|
629
652
|
def cap_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
630
653
|
batch=BATCH_DEFAULT, min_conf=0.5, actor=None) -> dict:
|
|
631
654
|
"""注入 `cap:<op>` 标签:只改 frontmatter.tags,不动正文。"""
|
|
@@ -676,6 +699,7 @@ def cap_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
676
699
|
return rep
|
|
677
700
|
|
|
678
701
|
|
|
702
|
+
# 生效条件:x 经 _as_cg,读取日志中 action=cap 且未回滚的记录,按 batch/entry_ids 过滤,节点存在且原加入标签仍在 tags 中时移除,否则计 conflict/missing,返回 rep。
|
|
679
703
|
def cap_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
680
704
|
"""撤销 cap 注入:仅移除**仍在 tags 里**的 `cap:` 标签(防覆盖后续修改)。"""
|
|
681
705
|
cg = _as_cg(x)
|
|
@@ -730,6 +754,7 @@ def cap_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
730
754
|
EXEMPT_FLAG = "ccg_exempt"
|
|
731
755
|
|
|
732
756
|
|
|
757
|
+
# 生效条件:fm 的 verification_basis 合法且 content 的 ccg_completeness 标记 complete 时返回 (True, []),否则把缺失项放入 miss 返回 ready=False。
|
|
733
758
|
def _exempt_ready(fm: dict, content: str):
|
|
734
759
|
"""摘豁免前置条件 → `(ready, missing)`。
|
|
735
760
|
|
|
@@ -745,6 +770,7 @@ def _exempt_ready(fm: dict, content: str):
|
|
|
745
770
|
return (not miss), miss
|
|
746
771
|
|
|
747
772
|
|
|
773
|
+
# 生效条件:x 经 _as_cg,遍历 nodes 按 ids/prefix/layer 过滤,内部层/不可读/读取失败或加密分别计数跳过,fm 无 EXEMPT_FLAG 计 not_exempt,require_ready 为真且不 ready 时计 unready 并在 want 为 None 时跳过,否则生成 item 受 limit 限制;sample 为真值时按 id 序等距抽取 sample 个。
|
|
748
774
|
def exempt_plan(x, layer=None, limit=None, ids=None, require_ready=True,
|
|
749
775
|
sample=0, prefix=None) -> dict:
|
|
750
776
|
"""预演:列出可摘 `ccg_exempt` 的节点(默认要求证据就绪),不写盘。
|
|
@@ -804,6 +830,7 @@ def exempt_plan(x, layer=None, limit=None, ids=None, require_ready=True,
|
|
|
804
830
|
return rep
|
|
805
831
|
|
|
806
832
|
|
|
833
|
+
# 生效条件:x 经 _as_cg,batch 假值回落 BATCH_DEFAULT;先 exempt_plan 得 items,按 entry_ids 过滤;逐个检查节点存在、可读、EXEMPT_FLAG 仍真、require_ready 为真时 _exempt_ready 再次通过;不通过计 skipped_unready 并记 exempt_skip;通过则置 EXEMPT_FLAG=False 写盘记日志;limit 限制 written;返回 rep。
|
|
807
834
|
def exempt_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
808
835
|
batch=BATCH_DEFAULT, require_ready=True, actor=None,
|
|
809
836
|
prefix=None) -> dict:
|
|
@@ -864,6 +891,7 @@ def exempt_apply(x, ids=None, entry_ids=None, layer=None, limit=None,
|
|
|
864
891
|
return rep
|
|
865
892
|
|
|
866
893
|
|
|
894
|
+
# 生效条件:当 x 可解析为 cg 时,日志中 action 为 exempt 的记录若其非空 write_id 已存在于既有 action 为 exempt_rollback 的记录 write_id 集合中,则跳过并计入 skipped_done,否则在通过 batch 与 entry_ids 过滤后,节点存在且可读、EXEMPT_FLAG 当前为假时,该记录才被还原并计入 reverted;。
|
|
867
895
|
def exempt_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
868
896
|
"""反向还原 `ccg_exempt`:仅当当前仍为「已摘」状态时还原,否则计 conflict。"""
|
|
869
897
|
cg = _as_cg(x)
|
|
@@ -920,6 +948,7 @@ def exempt_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
920
948
|
# ③ verify_conditions 只读复算:验收指标 legacy_position == 0
|
|
921
949
|
|
|
922
950
|
|
|
951
|
+
# 生效条件:x 经 _as_cg,遍历 nodes 按 prefix/layer 过滤,内部层/不可读/读取失败或加密/derived 层或 SKIP_TAGS 分别计数跳过;扫描后,正文已有生效条件计 declared,derive_fields 可推出计 derivable,否则按 condition_space 缺失槽计 pending 并受 limit 限制收集 items;返回 rep。
|
|
923
952
|
def conditions_pending(x, prefix=None, layer=None, limit=None) -> dict:
|
|
924
953
|
"""只读台账:列出「未声明生效条件、且四槽推不出」的节点及其缺失槽。
|
|
925
954
|
|
|
@@ -978,6 +1007,7 @@ def conditions_pending(x, prefix=None, layer=None, limit=None) -> dict:
|
|
|
978
1007
|
return rep
|
|
979
1008
|
|
|
980
1009
|
|
|
1010
|
+
# 生效条件:cg 的留痕日志中存在 basis 为 LEGACY_CONDITION_BASIS 且未被回滚的 backfill 生效条件写入时,按 node 记录最后一次的 after/original 返回;无匹配返回空。
|
|
981
1011
|
def _legacy_condition_records(cg) -> dict:
|
|
982
1012
|
"""→ {node: {after, original, …}}:我们**自己写下的**单槽冒充行(真源 = 留痕)。
|
|
983
1013
|
|
|
@@ -1005,6 +1035,7 @@ def _legacy_condition_records(cg) -> dict:
|
|
|
1005
1035
|
return out
|
|
1006
1036
|
|
|
1007
1037
|
|
|
1038
|
+
# 生效条件:x 经 _as_cg,从 _legacy_condition_records 取候选,按 prefix 过滤,节点不存在/不可读/读取失败或加密分别计 missing/denied/locked;当前生效条件等于留痕 after 时,四槽合成非空则 rewrite 否则 drop,不等则 conflict;items 受 limit 限制;返回 dry_run rep。
|
|
1008
1039
|
def fix_conditions_plan(x, prefix=None, limit=None) -> dict:
|
|
1009
1040
|
"""预演:清洗存量单槽冒充行。不写盘。
|
|
1010
1041
|
|
|
@@ -1054,6 +1085,7 @@ def fix_conditions_plan(x, prefix=None, limit=None) -> dict:
|
|
|
1054
1085
|
return rep
|
|
1055
1086
|
|
|
1056
1087
|
|
|
1088
|
+
# 生效条件:x 经 _as_cg,batch 假值回落 FIX_BATCH_DEFAULT;先 fix_conditions_plan 得 items,按 ids/entry_ids 过滤;逐个再验当前值仍等于 before 且 comment_before 一致,否则 skipped_drift;rewrite 时 upsert 生效条件行并写 comment,drop 时删行并还原 comment;写盘记 condition_fix,drop 另记 condition_pending;limit 限制 rewritten+dropped;返回 rep。
|
|
1057
1089
|
def fix_conditions_apply(x, ids=None, entry_ids=None, prefix=None, limit=None,
|
|
1058
1090
|
batch=FIX_BATCH_DEFAULT, actor=None) -> dict:
|
|
1059
1091
|
"""执行清洗:`rewrite` 改写为四槽合成声明;`drop` 删行并登记待补。
|
|
@@ -1144,6 +1176,7 @@ def fix_conditions_apply(x, ids=None, entry_ids=None, prefix=None, limit=None,
|
|
|
1144
1176
|
return rep
|
|
1145
1177
|
|
|
1146
1178
|
|
|
1179
|
+
# 生效条件:x 经 _as_cg,读取日志中 action=condition_fix 且未回滚的记录,按 batch/entry_ids 过滤,节点存在且当前生效条件等于 after 时,还原 before(空则删行)并还原 comment_before,否则计 conflict/missing;返回 rep。
|
|
1147
1180
|
def fix_conditions_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
1148
1181
|
"""按留痕反向应用:恢复被改写的旧值 / 重建被删除的冒充行。
|
|
1149
1182
|
|
|
@@ -1210,6 +1243,7 @@ def fix_conditions_rollback(x, batch=None, entry_ids=None, actor=None) -> dict:
|
|
|
1210
1243
|
return rep
|
|
1211
1244
|
|
|
1212
1245
|
|
|
1246
|
+
# 生效条件:x 经 _as_cg,遍历 nodes 按 prefix 过滤、内部层跳过,读取失败或加密跳过;对每个节点当前生效条件行,缺失计 absent,否则按 is_legacy_position_condition、等于 _condition_text 合成、等于 comment、其他分别计数,legacy_ids 受 limit 限制;返回 rep。
|
|
1213
1247
|
def verify_conditions(x, prefix=None, limit=None) -> dict:
|
|
1214
1248
|
"""复算核对(只读):生效条件行的来源分布 + 弱等价残留计数。
|
|
1215
1249
|
|
|
@@ -1264,6 +1298,7 @@ ACTIONS = ("backfill", "backfill_rollback", "backfill_history",
|
|
|
1264
1298
|
"exempt", "exempt_rollback", "exempt_history")
|
|
1265
1299
|
|
|
1266
1300
|
|
|
1301
|
+
# 生效条件:按其 action 分派——action=='backfill' 时 kw['apply'] 为真调 apply(x, 去掉 apply 的 kw)、否则调 plan 同参;action=='cap'/'exempt' 同理在 kw['apply'] 为真时调 cap_apply/exempt_apply、否则调 cap_plan/exempt_plan;action=='backfill_rollback'/'cap_rollback'/'exempt_rollback' 分别调 rollback/cap_rollback/exempt_rollback(x, **kw);action=='backfill_history' 调 history(x, **kw),'cap_history'/'exempt_history' 调 history(x, action='cap'/'exempt', **kw);其余 action 值抛 ValueError。
|
|
1267
1302
|
def run(x, action, **kw) -> dict:
|
|
1268
1303
|
"""`maintain` op 的分派入口:action ∈ ACTIONS。"""
|
|
1269
1304
|
if action == "backfill":
|
|
@@ -1290,4 +1325,4 @@ def run(x, action, **kw) -> dict:
|
|
|
1290
1325
|
return exempt_rollback(x, **kw)
|
|
1291
1326
|
if action == "exempt_history":
|
|
1292
1327
|
return history(x, action="exempt", **kw)
|
|
1293
|
-
raise ValueError(f"未知 backfill action:{action}(允许:{ACTIONS})")
|
|
1328
|
+
raise ValueError(f"未知 backfill action:{action}(允许:{ACTIONS})")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""big_domain 域标签回填(S1 大域收敛的前置元数据;幂等、支持 --dry-run)。
|
|
3
|
+
|
|
4
|
+
用法:
|
|
5
|
+
python -X utf8 -m md_cg.backfill_bigdomain --root <库根> [--dry-run] [--limit N]
|
|
6
|
+
|
|
7
|
+
为何需要单独的回填入口:域标签是**写入侧**新增的元数据,存量节点没有;
|
|
8
|
+
S1 要按域收敛,就必须先把存量补齐(契约 §8.1)。
|
|
9
|
+
"""
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
from .mdcg import MdCG
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# 生效条件:无条件解析参数(root 必填,dry_run/limit 可选)、以 MdCG(root) 打开库、调用 backfill_big_domain 并把统计 dict 以 JSON 打印,返回 0。
|
|
18
|
+
def main(argv=None):
|
|
19
|
+
ap = argparse.ArgumentParser()
|
|
20
|
+
ap.add_argument("--root", required=True, help="库根目录")
|
|
21
|
+
ap.add_argument("--dry-run", action="store_true", dest="dry_run",
|
|
22
|
+
help="只统计不改盘")
|
|
23
|
+
ap.add_argument("--limit", type=int, default=None, help="最多补写多少个节点")
|
|
24
|
+
a = ap.parse_args(argv)
|
|
25
|
+
cg = MdCG(a.root)
|
|
26
|
+
st = cg.backfill_big_domain(dry_run=a.dry_run, limit=a.limit)
|
|
27
|
+
print(json.dumps(st, ensure_ascii=False))
|
|
28
|
+
return 0
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
33
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
34
|
+
sys.exit(main())
|
package/md_cg/bench6_arms.py
CHANGED
|
@@ -54,6 +54,7 @@ QUERY_CONTEXT = {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
# 生效条件:形参 c 若提供映射接口,则取 c["zh_fields"](缺失或假值回落 {})再取其 "condition"(缺失或假值回落 {}),返回三槽 observation_position/observation_tool/existence_constraint,各自以 cond.get(中文键, "") 取值——中文键缺失时回落空串,键存在而值为 None 时结果即为 None(不回落)。
|
|
57
58
|
def cond_of(c):
|
|
58
59
|
"""zh_fields.condition(中文三槽)→ mdcos 期望的英文槽名。
|
|
59
60
|
|
|
@@ -65,6 +66,7 @@ def cond_of(c):
|
|
|
65
66
|
"existence_constraint": cond.get("存在约束", "")}
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
# 生效条件:形参 c 若提供映射接口,则 f = c["zh_fields"] 为假值(缺失/None/{})时当作 {},返回 [str(f["identity"] 或 "")] + [str(t) for t in (f["terms"] 或 [])]:identity 缺失或假值时首元素为空串(列表恒有 1 项),terms 缺失或假值时只有首元素。
|
|
68
70
|
def tags_of(c):
|
|
69
71
|
"""喂 entity 路的裸词 tags = identity + terms。
|
|
70
72
|
|
|
@@ -77,24 +79,30 @@ def tags_of(c):
|
|
|
77
79
|
return [str(f.get("identity") or "")] + [str(t) for t in (f.get("terms") or [])]
|
|
78
80
|
|
|
79
81
|
|
|
82
|
+
# 生效条件:类无 __init__,实例化无需任何形参;其 describe_ingest(nids) 对任意 nids(含空)恒返回 [],而 reset()、add(nid, text)、search(query, k=5) 对任意实参一律抛 NotImplementedError。
|
|
80
83
|
class Adapter:
|
|
81
84
|
"""统一适配接口。六家一律只回吐 id 列表,指标计算交回 bench6_common。"""
|
|
82
85
|
name = "adapter"
|
|
83
86
|
|
|
87
|
+
# 生效条件:无可选/必需形参,任何调用一律抛 NotImplementedError(基类接口桩)。
|
|
84
88
|
def reset(self):
|
|
85
89
|
raise NotImplementedError
|
|
86
90
|
|
|
91
|
+
# 生效条件:对任意 nid 与 text 一律抛 NotImplementedError(形参不参与任何判断)。
|
|
87
92
|
def add(self, nid, text):
|
|
88
93
|
raise NotImplementedError
|
|
89
94
|
|
|
95
|
+
# 生效条件:对任意 query 与任意 k(默认 5)一律抛 NotImplementedError,不返回结果。
|
|
90
96
|
def search(self, query, k=5):
|
|
91
97
|
raise NotImplementedError
|
|
92
98
|
|
|
99
|
+
# 生效条件:对任意 nids(包括空列表或 None)都直接返回空列表 [],不读取任何存储。
|
|
93
100
|
def describe_ingest(self, nids):
|
|
94
101
|
"""回读真实存储内容样本,用于取证「入库语言与入库形态」。"""
|
|
95
102
|
return []
|
|
96
103
|
|
|
97
104
|
|
|
105
|
+
# 生效条件:必须以 rows、variant、paths 三个必需形参构造(context 默认 None、with_meta 默认 False、rebuild 默认 False 可选),构造后 search(query, k=5) 是否向 search_rrf 传 context 由 context 是否为 None 决定,describe_ingest(nids)/bucket_health() 的取证内容取决于 variant 对应 root 库的索引状态。
|
|
98
106
|
class LingshuAdapter(Adapter):
|
|
99
107
|
"""灵枢臂:进程内 MdCGOS。
|
|
100
108
|
|
|
@@ -103,6 +111,7 @@ class LingshuAdapter(Adapter):
|
|
|
103
111
|
|
|
104
112
|
name = "lingshu"
|
|
105
113
|
|
|
114
|
+
# 生效条件:root 固定为 os.path.join(ROOT_BASE, variant);rebuild 为真且 os.path.isdir(root) 为真时先 rmtree,索引中已有节点数 ≥ len(rows) 时直接 return(幂等复用、不写库),否则按 rows 逐条 add(with_meta 为真时同时补 tags=tags_of(c)、condition_space=cond_of(c))后 flush。
|
|
106
115
|
def __init__(self, rows, variant, paths, context=None, with_meta=False,
|
|
107
116
|
rebuild=False):
|
|
108
117
|
from md_cg.bench_locomo_zh_public import body_of
|
|
@@ -132,12 +141,14 @@ class LingshuAdapter(Adapter):
|
|
|
132
141
|
print(" [lingshu/%s] 建库 %d 节点 %.1fs"
|
|
133
142
|
% (variant, len(self.cg.index["nodes"]), time.time() - t0))
|
|
134
143
|
|
|
144
|
+
# 生效条件:给定 query 与 k(默认 5)即调用 self.cg.search_rrf(k=k、paths=self.paths、judge=False、record=False),仅当 self.context 不为 None 时附加 context 参数,返回每个结果 r 的 r[0]["id"] 组成的列表。
|
|
135
145
|
def search(self, query, k=5):
|
|
136
146
|
kw = {"context": self.context} if self.context is not None else {}
|
|
137
147
|
res, _meta = self.cg.search_rrf(query, k=k, paths=self.paths,
|
|
138
148
|
judge=False, record=False, **kw)
|
|
139
149
|
return [r[0]["id"] for r in res]
|
|
140
150
|
|
|
151
|
+
# 生效条件:只遍历 nids[:2],节点索引中 .get(nid) 为假值(缺失)的 nid 被跳过,其余按 os.path.join(self.cg.root, e["path"]) 读文件头 300 字符,抛 OSError 时 file_head 保持空串,输出各字段用 e.get(缺键为 None)。
|
|
141
152
|
def describe_ingest(self, nids):
|
|
142
153
|
"""回读真实落盘内容(索引元数据 + 文件头),取证入库语言与形态。
|
|
143
154
|
|
|
@@ -161,6 +172,7 @@ class LingshuAdapter(Adapter):
|
|
|
161
172
|
"file_head": head})
|
|
162
173
|
return out
|
|
163
174
|
|
|
175
|
+
# 生效条件:无参数,遍历 self.cg.index["nodes"] 各节点的 e.get("bucket"),其缺失或为假值(None/空串等)时归入 "<none>" 计数,再把计数字典交 routing.bucket_health 并返回其结果。
|
|
164
176
|
def bucket_health(self):
|
|
165
177
|
"""桶健康度自检(routing.bucket_health):取证条件路由是否有区分力。"""
|
|
166
178
|
from md_cg import routing
|
|
@@ -171,6 +183,7 @@ class LingshuAdapter(Adapter):
|
|
|
171
183
|
return routing.bucket_health(counts)
|
|
172
184
|
|
|
173
185
|
|
|
186
|
+
# 生效条件:无必需构造形参,base 为假值(None/空串)时先回落 os.environ["BENCH6_EMBED_BASE"]、再回落 "http://127.0.0.1:1234/v1" 并 rstrip("/"),model 为假值时回落 os.environ["BENCH6_EMBED_MODEL"]、再回落空串 "",timeout 缺省为 30。
|
|
174
187
|
class VectorRagAdapter(Adapter):
|
|
175
188
|
"""纯向量 RAG 基线(零 LLM):英文原文直嵌入 + 余弦 Top-k。
|
|
176
189
|
|
|
@@ -180,6 +193,7 @@ class VectorRagAdapter(Adapter):
|
|
|
180
193
|
|
|
181
194
|
name = "vector_rag"
|
|
182
195
|
|
|
196
|
+
# 生效条件:base 依次按 base 形参 → os.environ.get("BENCH6_EMBED_BASE") → "http://127.0.0.1:1234/v1" 取值(每级为空串/None 均继续回落)再去掉尾部 "/",model 依次按 model 形参 → os.environ.get("BENCH6_EMBED_MODEL") → "" 取值(空串也回落),timeout 直接取形参(含 0),ids/vecs 置 []、_dim 置 0。
|
|
183
197
|
def __init__(self, base=None, model=None, timeout=30):
|
|
184
198
|
self.base = (base or os.environ.get("BENCH6_EMBED_BASE")
|
|
185
199
|
or "http://127.0.0.1:1234/v1").rstrip("/")
|
|
@@ -189,6 +203,7 @@ class VectorRagAdapter(Adapter):
|
|
|
189
203
|
self.vecs = []
|
|
190
204
|
self._dim = 0
|
|
191
205
|
|
|
206
|
+
# 生效条件:以 self.base + path 为 URL、method="POST"、JSON 编码的 payload 为 body、Content-Type: application/json、超时 self.timeout 发出请求,返回响应体按 UTF-8 解码后 json.loads 的对象。
|
|
192
207
|
def _post(self, path, payload):
|
|
193
208
|
req = urllib.request.Request(
|
|
194
209
|
self.base + path, method="POST",
|
|
@@ -197,6 +212,7 @@ class VectorRagAdapter(Adapter):
|
|
|
197
212
|
with urllib.request.urlopen(req, timeout=self.timeout) as r:
|
|
198
213
|
return json.loads(r.read().decode("utf-8"))
|
|
199
214
|
|
|
215
|
+
# 生效条件:self.model 为真值时直接返回;否则请求 self.base + "/models",从 data.get("data") 筛出 id 非空的模型名列表,该列表为空时抛 RuntimeError,否则优先取名字含 embed/bge/gte/m3 的第一个,无匹配则取 ids[0],写入 self.model 后返回。
|
|
200
216
|
def resolve_model(self):
|
|
201
217
|
"""未显式指定时,从 /models 取第一个 embedding 模型。"""
|
|
202
218
|
if self.model:
|
|
@@ -216,12 +232,14 @@ class VectorRagAdapter(Adapter):
|
|
|
216
232
|
self.model = ids[0]
|
|
217
233
|
return self.model
|
|
218
234
|
|
|
235
|
+
# 生效条件:对任意 text 以 self.model 调 _post("/embeddings", {"model":…, "input": text}),取 d["data"][0]["embedding"],令 self._dim 等于该向量长度并返回该向量。
|
|
219
236
|
def embed(self, text):
|
|
220
237
|
d = self._post("/embeddings", {"model": self.model, "input": text})
|
|
221
238
|
v = d["data"][0]["embedding"]
|
|
222
239
|
self._dim = len(v)
|
|
223
240
|
return v
|
|
224
241
|
|
|
242
|
+
# 生效条件:按 batch(默认 32)把 texts 切片,每片整批 POST /embeddings 成功时按 x.get("index", 0) 排序后依次收集 r["embedding"],该片抛任何异常时改为对片内每条调 self.embed 回退,self._dim 为 0 且有结果时置为最后一条向量长度,最后返回 out。
|
|
225
243
|
def embed_many(self, texts, batch=32):
|
|
226
244
|
"""批量嵌入(服务不支持 batch 时逐条回退)。"""
|
|
227
245
|
out = []
|
|
@@ -237,13 +255,16 @@ class VectorRagAdapter(Adapter):
|
|
|
237
255
|
self._dim = len(out[-1])
|
|
238
256
|
return out
|
|
239
257
|
|
|
258
|
+
# 生效条件:无前置;把 self.ids 与 self.vecs 同时清空(二者下标耦合,必须成对重置),self._dim 保留原值不动;
|
|
240
259
|
def reset(self):
|
|
241
260
|
self.ids, self.vecs = [], []
|
|
242
261
|
|
|
262
|
+
# 生效条件:对任意 nid 与 text,把 nid 追加到 self.ids、把 self.embed(text) 的向量追加到 self.vecs,二者按下标一一对应,不查重、不返回。
|
|
243
263
|
def add(self, nid, text):
|
|
244
264
|
self.ids.append(nid)
|
|
245
265
|
self.vecs.append(self.embed(text))
|
|
246
266
|
|
|
267
|
+
# 生效条件:self.vecs 为空时直接返回 [];否则嵌入 query 并对每条候选计算余弦相似度(qn 或 vn 为 0 时用 1.0 兜底),按相似度降序、同分按 id 升序排序后返回前 k 个 nid。
|
|
247
268
|
def search(self, query, k=5):
|
|
248
269
|
if not self.vecs:
|
|
249
270
|
return []
|
|
@@ -257,6 +278,7 @@ class VectorRagAdapter(Adapter):
|
|
|
257
278
|
scored.sort(key=lambda x: (-x[0], x[1]))
|
|
258
279
|
return [nid for _s, nid in scored[:k]]
|
|
259
280
|
|
|
281
|
+
# 生效条件:对任意 nids 都只取前 2 项(nids[:2]),各返回 {"id": nid, "form": "原样英文文本 → embedding", "lang": "en", "dim": self._dim},不读磁盘内容。
|
|
260
282
|
def describe_ingest(self, nids):
|
|
261
283
|
return [{"id": nid, "form": "原样英文文本 → embedding",
|
|
262
284
|
"lang": "en", "dim": self._dim} for nid in nids[:2]]
|
|
@@ -264,6 +286,7 @@ class VectorRagAdapter(Adapter):
|
|
|
264
286
|
|
|
265
287
|
# ------------------------------------------------------------------ 套件与评分
|
|
266
288
|
|
|
289
|
+
# 生效条件:lang 等于 "zh" 时逐题取 q["question_zh"],lang 为其它任何值(含 "en")时取 q["question_en"],对 questions 每项调 adapter.search(query, k=k),verbose 为真且序数能被 50 整除时打印进度,返回 {qid: 检索结果列表}。
|
|
267
290
|
def run_suite(adapter, questions, lang, k=5, verbose=True):
|
|
268
291
|
"""一套查询语言跑一遍 → {qid: [id...]}(顺序即相关性降序)。"""
|
|
269
292
|
key = "question_zh" if lang == "zh" else "question_en"
|
|
@@ -276,6 +299,7 @@ def run_suite(adapter, questions, lang, k=5, verbose=True):
|
|
|
276
299
|
return hits
|
|
277
300
|
|
|
278
301
|
|
|
302
|
+
# 生效条件:对 langs 中每个 lang 依次跑 run_suite(adapter, questions, lang, k=k)、bc.rows_from_hits 与 ec.summarize,结果写入 out["langs"][lang];最后取 questions 前 2 条的 qid 调 adapter.describe_ingest 存入 out["ingest_probe"] 并返回 out。
|
|
279
303
|
def evaluate(arm, adapter, questions, k=5, langs=("zh", "en")):
|
|
280
304
|
"""一套库 × 两种查询语言 → 指标 + per-question 明细 + 回读取证。"""
|
|
281
305
|
out = {"arm": arm, "k": k, "langs": {}}
|
|
@@ -290,6 +314,7 @@ def evaluate(arm, adapter, questions, k=5, langs=("zh", "en")):
|
|
|
290
314
|
return out
|
|
291
315
|
|
|
292
316
|
|
|
317
|
+
# 生效条件:model 依次按 model 形参 → os.environ.get("BENCH6_EMBED_MODEL") → "text-embedding-bge-m3" 取值(形参为空串/None、环境变量缺失或为空串都会继续回落),随后 resolve_model(),再把 pool 中每条的 t["id"]、t["ingest"] 分别装进 vec.ids 与批量嵌入结果 vec.vecs 后返回 vec。
|
|
293
318
|
def build_vector_rag(pool, model=None):
|
|
294
319
|
"""向量基线:池内英文原文批量嵌入(零 LLM、无结构化)。"""
|
|
295
320
|
vec = VectorRagAdapter(model=model or os.environ.get("BENCH6_EMBED_MODEL")
|
|
@@ -303,6 +328,7 @@ def build_vector_rag(pool, model=None):
|
|
|
303
328
|
return vec
|
|
304
329
|
|
|
305
330
|
|
|
331
|
+
# 生效条件:argv 为 None 时取 sys.argv[1:],其中出现 "--rebuild" 则各臂以 rebuild=True 建库,非 "-" 开头的项构成 only 白名单,仅当 only 为空或臂名在 only 中时执行对应臂(only 为空时额外执行 2×2 消融块),跑完返回含 manifest/results/elapsed_s 的 payload。
|
|
306
332
|
def main(argv=None):
|
|
307
333
|
argv = sys.argv[1:] if argv is None else argv
|
|
308
334
|
rebuild = "--rebuild" in argv
|
|
@@ -322,6 +348,7 @@ def main(argv=None):
|
|
|
322
348
|
rows = [corpus_by_id[t["id"]] for t in pool]
|
|
323
349
|
results, table = {}, {}
|
|
324
350
|
|
|
351
|
+
# 生效条件:形参 name 出现在外层 main 的 only 白名单中时返回 True;only 为空(假值)时对任何 name 都返回 True;only 非空且不含 name 时返回 False。
|
|
325
352
|
def _want(name):
|
|
326
353
|
return not only or name in only
|
|
327
354
|
|
|
@@ -381,4 +408,4 @@ def main(argv=None):
|
|
|
381
408
|
|
|
382
409
|
|
|
383
410
|
if __name__ == "__main__":
|
|
384
|
-
main()
|
|
411
|
+
main()
|
package/md_cg/bench6_common.py
CHANGED
|
@@ -53,6 +53,7 @@ BOUNDARIES = [
|
|
|
53
53
|
]
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
# 生效条件:rows 为含 qtype 的行列表、n 取默认 N_QUESTIONS、seed 取默认 SEED 时(rows 为空则分组与配额皆空、out 为空列表;n=0 时各型配额与 out 皆为空/0),按 int(n*组大小/总行数) 定配额并把余数按小数部分降序补足,逐型用 random.Random("%d:%s"%(seed,qt)) 抽 min(配额,组大小) 条,返回按 qid 排序的 (out, quota)
|
|
56
57
|
def stratified_sample(rows, n=N_QUESTIONS, seed=SEED):
|
|
57
58
|
"""按 qtype 比例分层抽样(最大余额法)。
|
|
58
59
|
|
|
@@ -78,6 +79,7 @@ def stratified_sample(rows, n=N_QUESTIONS, seed=SEED):
|
|
|
78
79
|
return out, quota
|
|
79
80
|
|
|
80
81
|
|
|
82
|
+
# 生效条件:sample 为含 qid 与 evidence_turns 的题列表、corpus_by_id 为 id→池行的映射时,把不在 corpus_by_id 中的 evidence_turns 逐题记为 {"qid":…,"missing":[…]} 收入 dangling,其余去重后返回 (按 id 排序的 corpus_by_id 行列表, dangling)
|
|
81
83
|
def build_pool(sample, corpus_by_id):
|
|
82
84
|
"""池 = 抽中题的 gold 引用 turn 去重。返回 (pool, dangling)。
|
|
83
85
|
|
|
@@ -94,6 +96,7 @@ def build_pool(sample, corpus_by_id):
|
|
|
94
96
|
return [corpus_by_id[i] for i in sorted(pool_ids)], dangling
|
|
95
97
|
|
|
96
98
|
|
|
99
|
+
# 生效条件:c 为含 text 键的映射时取其去空白文本,date 非空则返回 "文本 [date]",date 为空则只返回 text。
|
|
97
100
|
def ingest_text_en(c):
|
|
98
101
|
"""六家共用的英文写入文本:原始陈述 + 会话时间。
|
|
99
102
|
|
|
@@ -107,6 +110,7 @@ def ingest_text_en(c):
|
|
|
107
110
|
return "%s [%s]" % (text, date) if date else text
|
|
108
111
|
|
|
109
112
|
|
|
113
|
+
# 生效条件:c 含 "id" 键时返回 {'id': c["id"], 'speaker'/'date'/'text' 为 c.get(键) or ""(键缺失或值为 None/""/0/[] 等假值均落空串), 'ingest': ingest_text_en(c)};缺 "id" 键时 c["id"] 抛 KeyError
|
|
110
114
|
def turn_rec(c):
|
|
111
115
|
"""池行 → 落盘行(六家共用的英文侧视图)。"""
|
|
112
116
|
return {"id": c["id"], "speaker": c.get("speaker") or "",
|
|
@@ -114,6 +118,7 @@ def turn_rec(c):
|
|
|
114
118
|
"ingest": ingest_text_en(c)}
|
|
115
119
|
|
|
116
120
|
|
|
121
|
+
# 生效条件:sample 每题的 qid 在 en_by_qid 中且中英 evidence_turns 逐字相等时返回按 sample 顺序的 {qid, qtype, question_zh, question_en, evidence_turns} 列表;en_by_qid.get(qid) 为 None 抛 KeyError,两列表不等抛 AssertionError
|
|
117
122
|
def align_queries(sample, en_by_qid):
|
|
118
123
|
"""中英双查询词面按 qid join,断言 evidence_turns 逐字一致。
|
|
119
124
|
|
|
@@ -133,6 +138,7 @@ def align_queries(sample, en_by_qid):
|
|
|
133
138
|
return out
|
|
134
139
|
|
|
135
140
|
|
|
141
|
+
# 生效条件:ids 为 id 序列、evidence 为证据 id 集合时,把 ids 包装成 [({"id": x}, 0.0)] 后原样返回 ec.first_evidence_rank 的结果
|
|
136
142
|
def rank_of(ids, evidence):
|
|
137
143
|
"""首个证据 id 的排名(1-based;未命中 0)。
|
|
138
144
|
|
|
@@ -143,6 +149,7 @@ def rank_of(ids, evidence):
|
|
|
143
149
|
return ec.first_evidence_rank(res, set(evidence))
|
|
144
150
|
|
|
145
151
|
|
|
152
|
+
# 生效条件:questions 每题含 qid,hits_by_qid 缺该 qid 或其值为假值(含空列表)时按空 id 列表处理,取前 k=K 条后返回每题 {qid, qtype, rank, top1_score(ids 非空为 1.0 否则 0.0), n_res} 的行列表
|
|
146
153
|
def rows_from_hits(questions, hits_by_qid, k=K):
|
|
147
154
|
"""把任一家的 id 列表统一转成 ec.summarize 的明细行。
|
|
148
155
|
|
|
@@ -159,6 +166,7 @@ def rows_from_hits(questions, hits_by_qid, k=K):
|
|
|
159
166
|
return rows
|
|
160
167
|
|
|
161
168
|
|
|
169
|
+
# 生效条件:force 为假且 os.path.exists(MANIFEST) 与 os.path.exists(QUESTIONS_JSONL) 均为真时读回 MANIFEST 直接返回(verbose 为真时打印复用信息);否则重建口径、写 POOL_JSONL/QUESTIONS_JSONL/MANIFEST 后返回该 man
|
|
162
170
|
def prepare(force=False, verbose=True):
|
|
163
171
|
"""固化口径层产物(幂等)。返回 manifest。"""
|
|
164
172
|
if not force and os.path.exists(MANIFEST) and os.path.exists(QUESTIONS_JSONL):
|
|
@@ -211,6 +219,7 @@ def prepare(force=False, verbose=True):
|
|
|
211
219
|
return man
|
|
212
220
|
|
|
213
221
|
|
|
222
|
+
# 生效条件:无参调用时读 MANIFEST 常量并返回 {'questions': QUESTIONS_JSONL 行列表, 'pool': POOL_JSONL 行列表, 'manifest': 该 JSON 对象}
|
|
214
223
|
def load():
|
|
215
224
|
"""读回已固化的口径层产物。六家适配器只经此取题与池。"""
|
|
216
225
|
man = json.load(open(MANIFEST, encoding="utf-8"))
|
|
@@ -219,4 +228,4 @@ def load():
|
|
|
219
228
|
|
|
220
229
|
|
|
221
230
|
if __name__ == "__main__":
|
|
222
|
-
prepare(force="--force" in sys.argv)
|
|
231
|
+
prepare(force="--force" in sys.argv)
|
|
@@ -54,11 +54,13 @@ MAIN_ARMS = [
|
|
|
54
54
|
LANGS = ("zh", "en")
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
# 生效条件:questions、hits、k 三者给定即成立,以 hits 结合 k 经 bc.rows_from_hits 生成 rows,再返回 (ec.summarize(rows, k=k), rows)。
|
|
57
58
|
def _score_hits(questions, hits, k):
|
|
58
59
|
rows = bc.rows_from_hits(questions, hits, k=k)
|
|
59
60
|
return ec.summarize(rows, k=k), rows
|
|
60
61
|
|
|
61
62
|
|
|
63
|
+
# 生效条件:manifest_note 传入但源码未使用该形参,结果只取决于模块常量 ec.RESULTS 下 bench6_arms_result.json——该路径不存在时打印警告并返回 {},路径可读时返回 json.load 结果 .get('results') or {}(results 键缺失或该值为假值时同样得到 {})。
|
|
62
64
|
def load_main(manifest_note):
|
|
63
65
|
"""读主进程臂结果(含灵枢 5 口径 + 向量基线)。"""
|
|
64
66
|
path = os.path.join(ec.RESULTS, "bench6_arms_result.json")
|
|
@@ -69,6 +71,7 @@ def load_main(manifest_note):
|
|
|
69
71
|
return json.load(f).get("results") or {}
|
|
70
72
|
|
|
71
73
|
|
|
74
|
+
# 生效条件:由 arm 拼出模块常量 ARM_OUT 下 <arm>.json,该路径不存在时返回 (None, '缺文件 …(该臂未跑或跑失败)');路径可读时用 questions 与 k 对遍历模块常量 LANGS 各语言的 hits 评分(raw['langs']、某语言块、其 hits 缺失或为假值时按 {} 处理,errors 缺失或为假值时按 [] 处理),返回 (out, None)。
|
|
72
75
|
def load_competitor(arm, questions, k):
|
|
73
76
|
path = os.path.join(ARM_OUT, "%s.json" % arm)
|
|
74
77
|
if not os.path.exists(path):
|
|
@@ -94,6 +97,7 @@ def load_competitor(arm, questions, k):
|
|
|
94
97
|
return out, None
|
|
95
98
|
|
|
96
99
|
|
|
100
|
+
# 生效条件:遍历 rows 的每个 (label, r),仅当 r['langs'] 对模块常量 LANGS 每个语言都存在真值时,才用 k 读 s['hit@k'] 并打印 hit@1/hit@k/MRR 及未回收率(unmapped_rate 为 None 时显示 n/a);否则只打印 label 加「—」占位行,不打印数值。
|
|
97
101
|
def print_matrix(rows, k):
|
|
98
102
|
"""六家 × 两语言主表(hit@1 / hit@k / MRR)。"""
|
|
99
103
|
head = ("系统", "zh hit@1", "zh hit@%d" % k, "zh MRR",
|
|
@@ -119,6 +123,7 @@ def print_matrix(rows, k):
|
|
|
119
123
|
print(" ".join(c.ljust(wi) for c, wi in zip(cells, w)))
|
|
120
124
|
|
|
121
125
|
|
|
126
|
+
# 生效条件:argv 为 None 时改读 sys.argv[1:] 解析 --k,随后按 MAIN_ARMS 与 COMPETITOR_ARMS 各自装载结果,返回含 k、arms、missing 的 payload。
|
|
122
127
|
def main(argv=None):
|
|
123
128
|
argv = sys.argv[1:] if argv is None else argv
|
|
124
129
|
k = 5
|
|
@@ -205,4 +210,4 @@ def main(argv=None):
|
|
|
205
210
|
|
|
206
211
|
|
|
207
212
|
if __name__ == "__main__":
|
|
208
|
-
main()
|
|
213
|
+
main()
|