@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""条件文档图端到端测试(P27 · 认知图的文档面)。
|
|
3
3
|
|
|
4
|
-
R2 改造的验收(对照 docs/认知图_索引与工程规范化_计划_v0.1.md §六 R2、§七):
|
|
4
|
+
R2 改造的验收(对照 docs/mdcg/认知图_索引与工程规范化_计划_v0.1.md §六 R2、§七):
|
|
5
5
|
|
|
6
6
|
① 切块纪律:只切 level<=3;直接正文 <200 字且无子节的小节**合并进父节**
|
|
7
7
|
(不单独建节点,其文字进父节摘要)。既不过细,也不丢内容。
|
|
@@ -20,20 +20,31 @@ R2 改造的验收(对照 docs/认知图_索引与工程规范化_计划_v0.1.
|
|
|
20
20
|
⑦ 不静默:truncated / skipped_suffixes / skipped_dirs 显式上报;排除为**追加**
|
|
21
21
|
(只增不减,内置 .git/.venv/node_modules 不可被关闭);只读契约(源 mtime 不变);
|
|
22
22
|
幂等(重跑节点数不变);`index_doc` 进 ALL_OPS 且与工具 schema 一致。
|
|
23
|
+
⑧ fence 往返列六件套的形状与边界:BINDING_FIELDS / binding_of / binding_key
|
|
24
|
+
(**不含行位**)/ binding_slug / validate_binding / binding_drift / locate。
|
|
25
|
+
为什么必须钉死:列形状漂移会让对账器把坏列当好消息(漏报);键若悄悄带上
|
|
26
|
+
行位,真源上方插一行就会让整库失配——两者都是静默退化,只有断言看得见。
|
|
27
|
+
⑨ 逐字节回放回归:对**真实索引出的卡**断言 `render(条目) + "\n" == 卡片正文`。
|
|
28
|
+
⑧ 只证「列可定位」;只有逐字节相等才证明卡片是真源条目的**派生物**而非另一份
|
|
29
|
+
副本(渲染漂移或人工改写时列全然不变,对账器看不出来)。外部历史库另段抽样
|
|
30
|
+
(设 MDCG_ROOT 则跑,未设如实 SKIP 不虚报通过)。
|
|
23
31
|
|
|
24
32
|
运行:python -m md_cg.test_p27_docindex
|
|
33
|
+
设 MDCG_ROOT=<认知图库根> 追加跑【12b】外部历史库逐字节回放抽样
|
|
25
34
|
"""
|
|
26
35
|
from __future__ import annotations
|
|
27
36
|
|
|
28
37
|
import os
|
|
38
|
+
import random
|
|
29
39
|
import shutil
|
|
30
40
|
import sys
|
|
31
41
|
import tempfile
|
|
32
42
|
|
|
33
|
-
from . import codeindex, corpus, docindex, nodefile, routing, tokens
|
|
43
|
+
from . import codeindex, corpus, docindex, nodefile, refindex, routing, tokens
|
|
34
44
|
from . import mcp_server
|
|
35
|
-
from .mdcos import MdCGOS
|
|
45
|
+
from .mdcos import MdCGOS, MdCGSecure # 生产路径:forget 属 OS 层,基础层 MdCG 无删除原语
|
|
36
46
|
from .mcp_server import call_tool
|
|
47
|
+
from .security import Principal
|
|
37
48
|
|
|
38
49
|
PASS = FAIL = 0
|
|
39
50
|
FAILS = []
|
|
@@ -41,7 +52,7 @@ FAILS = []
|
|
|
41
52
|
_BASE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
42
53
|
ROOT = os.path.join(_BASE, "_md_cg_p27")
|
|
43
54
|
DOCS = os.path.join(_BASE, "docs")
|
|
44
|
-
PLAN_DOC = "
|
|
55
|
+
PLAN_DOC = "mdcg/认知图_MD目录方案_v0.1.md"
|
|
45
56
|
|
|
46
57
|
|
|
47
58
|
def check(name, cond, detail=""):
|
|
@@ -55,6 +66,79 @@ def check(name, cond, detail=""):
|
|
|
55
66
|
print(f" [FAIL] {name} · {detail}")
|
|
56
67
|
|
|
57
68
|
|
|
69
|
+
def _norm(p):
|
|
70
|
+
"""路径归一(大小写 + 分隔符):root 归属比对用,避免同一目录被判成两个。"""
|
|
71
|
+
return os.path.normcase(os.path.normpath(str(p or "")))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# 逐字节回放:把「往返列」从「形状可校验」推进到「内容可无损重建」。
|
|
75
|
+
# 生效条件:cg 已索引完成的库;索引条目 tags 含 "doc" 且 frontmatter 有非空 doc_ref。
|
|
76
|
+
# 判据:真源同键条目 `render(条目)` 补一个换行 == 卡片正文——`nodefile.dumps` 对不以
|
|
77
|
+
# 换行结尾的正文补 '\n',故卡片正文恒比 render 多 1 字节(是常态,不是缺陷;判等
|
|
78
|
+
# 一律按 `render + "\n"`,避免把口径差当回归)。
|
|
79
|
+
# 为什么非此不可:列形状对(validate_binding)只保证「可定位」;只有逐字节相等才
|
|
80
|
+
# 证明卡片是真源条目的**派生物**而非另一份副本。渲染漂移或人工改写卡片正文时,
|
|
81
|
+
# 列全都不变(路径/行位/hash 都是真源侧的值),对账器看不出来——本函数才看得见。
|
|
82
|
+
# 悬空(真源已移出)/ 未解析如实计数:那是数据面事实,不冒充渲染失败。
|
|
83
|
+
def _replay_cards(cg, roots=None, sample=0, seed=7):
|
|
84
|
+
nodes = (getattr(cg, "index", {}) or {}).get("nodes") or {}
|
|
85
|
+
picks = []
|
|
86
|
+
for nid in sorted(nodes):
|
|
87
|
+
if "doc" not in ((nodes.get(nid) or {}).get("tags") or []):
|
|
88
|
+
continue
|
|
89
|
+
kind, ref = refindex.ref_of(cg.get(nid))
|
|
90
|
+
if kind != "doc_ref" or not ref:
|
|
91
|
+
continue
|
|
92
|
+
if roots is not None and _norm(ref.get("root")) not in roots:
|
|
93
|
+
continue
|
|
94
|
+
picks.append((nid, ref))
|
|
95
|
+
if sample and len(picks) > sample:
|
|
96
|
+
picks = sorted(random.Random(seed).sample(picks, sample))
|
|
97
|
+
out = {"sampled": len(picks), "ok": 0, "dangling": 0, "gone": 0,
|
|
98
|
+
"unreadable": 0, "mismatch": []}
|
|
99
|
+
cache = {}
|
|
100
|
+
for nid, ref in picks:
|
|
101
|
+
fp = (str(ref.get("root") or ""), str(ref.get("path") or ""))
|
|
102
|
+
ckey = (_norm(fp[0]), fp[1])
|
|
103
|
+
if ckey not in cache:
|
|
104
|
+
# 把「源文件已移出」(数据面事实,非缺陷)与其它 IO/抽取异常(可能是真
|
|
105
|
+
# 问题:权限、编码、源被改成无标题文档)分开计数——混为一谈会把真实
|
|
106
|
+
# 故障伪装成历史遗留,静默吞掉回归。三态:True 读得 / False 不存在 /
|
|
107
|
+
# None 读不了。
|
|
108
|
+
try:
|
|
109
|
+
with open(os.path.join(fp[0], fp[1]), "r", encoding="utf-8",
|
|
110
|
+
errors="replace") as f:
|
|
111
|
+
cache[ckey] = (True, docindex.extract(f.read(), fp[1]))
|
|
112
|
+
except FileNotFoundError:
|
|
113
|
+
cache[ckey] = (False, None)
|
|
114
|
+
except (OSError, ValueError):
|
|
115
|
+
cache[ckey] = (None, None)
|
|
116
|
+
hit, items = cache[ckey]
|
|
117
|
+
if hit is not True:
|
|
118
|
+
out["gone" if hit is False else "unreadable"] += 1
|
|
119
|
+
continue
|
|
120
|
+
node = cg.get(nid) or {}
|
|
121
|
+
want = docindex.binding_key(docindex.binding_of(node))
|
|
122
|
+
# 键(path#heading_path)在同名标题重复时可能命中多条:先按行位锁定同名代,
|
|
123
|
+
# 行位也漂了才回落首条(此时本来就判「不符」,不掩盖结论)。
|
|
124
|
+
cands = [i for i in items if docindex.binding_key(i) == want]
|
|
125
|
+
if not cands:
|
|
126
|
+
out["dangling"] += 1
|
|
127
|
+
continue
|
|
128
|
+
item = next((i for i in cands if i.get("lineno") == ref.get("lineno")),
|
|
129
|
+
cands[0])
|
|
130
|
+
got = docindex.render(item) + "\n"
|
|
131
|
+
content = node.get("content") or ""
|
|
132
|
+
if got == content:
|
|
133
|
+
out["ok"] += 1
|
|
134
|
+
continue
|
|
135
|
+
k = next((i for i in range(min(len(got), len(content)))
|
|
136
|
+
if got[i] != content[i]), min(len(got), len(content)))
|
|
137
|
+
out["mismatch"].append(
|
|
138
|
+
f"{nid}@{k} 回放={got[k:k + 24]!r} 卡片={content[k:k + 24]!r}")
|
|
139
|
+
return out
|
|
140
|
+
|
|
141
|
+
|
|
58
142
|
LONG = "这是总览段落," + "用以验证章节切块在长正文下的表现," * 12 + "结束。"
|
|
59
143
|
|
|
60
144
|
GUIDE_LINES = [
|
|
@@ -494,6 +578,176 @@ def main():
|
|
|
494
578
|
check("清退后悬空归零", not (ck3.get("dangling") or []),
|
|
495
579
|
str(ck3.get("dangling"))[:130])
|
|
496
580
|
|
|
581
|
+
# 跨进程一致性:新实例重放 _index_log 后,已清退节点不得复活成幽灵条目
|
|
582
|
+
# (索引有条目、文件不存在)——只有把「删除」也写进增量日志才成立。
|
|
583
|
+
cg2 = MdCGOS(ROOT)
|
|
584
|
+
revived = sorted(n for n in ids4 if n in (cg2.index.get("nodes") or {}))
|
|
585
|
+
check("清退后重开不复活幽灵条目", not revived, f"复活={revived}")
|
|
586
|
+
|
|
587
|
+
# 存量幽灵(历史「删除只摘内存索引」遗留):索引有条目、节点文件不存在
|
|
588
|
+
# 也必须清得掉,否则 dangling 永远够不着零。
|
|
589
|
+
gid = "doc_ghost_probe0001"
|
|
590
|
+
cg.index["nodes"][gid] = {"path": "knowledge/ghost_probe.md",
|
|
591
|
+
"layer": "knowledge", "tags": ["doc"],
|
|
592
|
+
"bucket": None, "importance": 0.5}
|
|
593
|
+
g1 = call_tool(cg, "cg", {"op": "ref", "action": "prune"})
|
|
594
|
+
check("幽灵条目被清退(索引有、文件无)",
|
|
595
|
+
len(g1.get("ghost_pruned") or []) >= 1
|
|
596
|
+
and gid not in (cg.index.get("nodes") or {}), str(g1)[:130])
|
|
597
|
+
ck4 = call_tool(cg, "cg", {"op": "ref", "action": "check", "max_nodes": 5000})
|
|
598
|
+
check("清幽灵后悬空仍为零", not (ck4.get("dangling") or []),
|
|
599
|
+
str(ck4.get("dangling"))[:130])
|
|
600
|
+
|
|
601
|
+
# ============================================ ⑪ fence 往返列(binding)
|
|
602
|
+
# 缺口:往返列(取列 / 造键 / 校验 / 漂移 / 反查)是「条件卡 ↔ Markdown 真源」
|
|
603
|
+
# 的可校验面,此前零测试。列形状一旦漂移,对账器会把坏列当好消息(漏报);
|
|
604
|
+
# 键若悄悄带上行位,真源上方插一行就会让整库失配——故两者都要钉死。
|
|
605
|
+
print("\n【11】fence 往返列:形状 / 键不含行位 / 校验 / 漂移 / 反查")
|
|
606
|
+
li = docindex.extract(GUIDE, "guide.md")
|
|
607
|
+
s9b = next(i for i in li if i["heading"] == "9. 分阶段实施")
|
|
608
|
+
rendered = docindex.render(s9b)
|
|
609
|
+
gnode = cg.get(g_id) or {}
|
|
610
|
+
g_ref = (gnode.get("frontmatter") or {}).get("doc_ref") or {}
|
|
611
|
+
b0 = docindex.binding_of(gnode)
|
|
612
|
+
check("必需列齐全且无空值",
|
|
613
|
+
isinstance(b0, dict)
|
|
614
|
+
and all(b0.get(k) not in (None, "") for k in docindex.BINDING_FIELDS),
|
|
615
|
+
str(sorted(docindex.BINDING_FIELDS)))
|
|
616
|
+
check("列面 = 必需列 + 附加列(无第二份列口径)",
|
|
617
|
+
set(b0 or {}) == set(docindex.BINDING_FIELDS)
|
|
618
|
+
| set(docindex.BINDING_OPTIONAL),
|
|
619
|
+
str(sorted(set(b0 or {}) ^ (set(docindex.BINDING_FIELDS)
|
|
620
|
+
| set(docindex.BINDING_OPTIONAL)))))
|
|
621
|
+
check("必需列/附加列 ⊆ 写侧 doc_ref 列(读写同一列面)",
|
|
622
|
+
(set(docindex.BINDING_FIELDS) | set(docindex.BINDING_OPTIONAL))
|
|
623
|
+
<= set(g_ref),
|
|
624
|
+
str(sorted(set(docindex.BINDING_FIELDS) - set(g_ref))))
|
|
625
|
+
check("binding_of 与直接读 frontmatter 同源(同一投影)",
|
|
626
|
+
b0 == docindex.binding_of({"frontmatter": {"doc_ref": g_ref}}))
|
|
627
|
+
check("binding_of 对非索引节点返回 None(不猜、不补默认值)",
|
|
628
|
+
docindex.binding_of(None) is None
|
|
629
|
+
and docindex.binding_of([]) is None
|
|
630
|
+
and docindex.binding_of({}) is None
|
|
631
|
+
and docindex.binding_of({"frontmatter": {"tags": ["doc"]}}) is None)
|
|
632
|
+
check("validate_binding:本仓卡片列形状合法(ok + 零 issue)",
|
|
633
|
+
docindex.validate_binding(b0) == {"ok": True, "issues": []},
|
|
634
|
+
str(docindex.validate_binding(b0)))
|
|
635
|
+
check("validate_binding:非 dict 如实报错且不抛",
|
|
636
|
+
docindex.validate_binding(None)
|
|
637
|
+
== {"ok": False, "issues": ["绑定不是字典(该节点无 doc_ref)"]})
|
|
638
|
+
lo0 = b0["lineno"]
|
|
639
|
+
bad_detail = []
|
|
640
|
+
for _nm, _b, _want in (
|
|
641
|
+
("缺列", {k: v for k, v in b0.items() if k != "anchor"},
|
|
642
|
+
"缺列 anchor"),
|
|
643
|
+
("类型错 root", {**b0, "root": 123},
|
|
644
|
+
"root 应为字符串,实为 int"),
|
|
645
|
+
("类型错 lineno", {**b0, "lineno": "十"}, "行位不是整数"),
|
|
646
|
+
("行位越界", {**b0, "lineno": 0}, "lineno 越界(0 < 1)"),
|
|
647
|
+
("区间倒置", {**b0, "end": lo0 - 1},
|
|
648
|
+
f"end 早于 lineno({lo0}-{lo0 - 1})")):
|
|
649
|
+
_v = docindex.validate_binding(_b)
|
|
650
|
+
if _v["ok"] or _want not in _v["issues"]:
|
|
651
|
+
bad_detail.append(f"{_nm}→{_v['issues']}")
|
|
652
|
+
check("validate_binding 逐类坏列均被点出(缺列/类型错/越界/区间倒置)",
|
|
653
|
+
not bad_detail, "; ".join(bad_detail)[:170])
|
|
654
|
+
b_shift = docindex.binding_of({"frontmatter": {"doc_ref": {
|
|
655
|
+
**g_ref, "lineno": lo0 + 40, "end": g_ref["end"] + 40}}})
|
|
656
|
+
check("键不含行位:行位位移不改键(重排后仍是同一章节)",
|
|
657
|
+
docindex.binding_key(b0) == docindex.binding_key(b_shift)
|
|
658
|
+
== "guide.md#总览/9. 分阶段实施",
|
|
659
|
+
docindex.binding_key(b0))
|
|
660
|
+
check("漂移按固定列序报出变化项(lineno → end → hash)",
|
|
661
|
+
docindex.binding_drift(b0, b_shift) == ["lineno", "end"]
|
|
662
|
+
and docindex.binding_drift(b0, {**b0, "hash": "zz"}) == ["hash"]
|
|
663
|
+
and docindex.binding_drift(
|
|
664
|
+
b0, {**b0, "hash": "zz", "lineno": lo0 + 1})
|
|
665
|
+
== ["lineno", "hash"],
|
|
666
|
+
str(docindex.binding_drift(b0, b_shift)))
|
|
667
|
+
check("同列零漂移(无变化不报 / 空值不炸)",
|
|
668
|
+
docindex.binding_drift(b0, dict(b0)) == []
|
|
669
|
+
and docindex.binding_drift(None, None) == [])
|
|
670
|
+
check("binding_key 缺 heading_path 回落 path#anchor · 非 dict 返空串",
|
|
671
|
+
docindex.binding_key({"path": "a.md", "anchor": "s1"}) == "a.md#s1"
|
|
672
|
+
and docindex.binding_key({"path": "a.md"}) == "a.md#"
|
|
673
|
+
and docindex.binding_key(None) == "")
|
|
674
|
+
check("binding_slug 与 render 正文「本条目属于」逐字同源",
|
|
675
|
+
docindex.binding_slug(b0) == "guide.md#9-分阶段实施"
|
|
676
|
+
and f"本条目属于 {docindex.binding_slug(b0)}" in rendered,
|
|
677
|
+
docindex.binding_slug(b0))
|
|
678
|
+
check("反查取最内层(父节区间内的子节优先,不回落父节)",
|
|
679
|
+
docindex.locate(li, 12)["heading"] == "9. 分阶段实施"
|
|
680
|
+
and docindex.locate(li, 30)["heading"] == "代码示例",
|
|
681
|
+
str((docindex.locate(li, 12) or {}).get("heading")))
|
|
682
|
+
check("反查区间闭合(标题行与末行都算本节)",
|
|
683
|
+
docindex.locate(li, s9b["lineno"])["heading"] == "9. 分阶段实施"
|
|
684
|
+
and docindex.locate(li, s9b["end"])["heading"] == "9. 分阶段实施")
|
|
685
|
+
check("反查越界/非整数/空表 → None(fail-closed 不猜)",
|
|
686
|
+
docindex.locate(li, 10 ** 6) is None
|
|
687
|
+
and docindex.locate(li, 0) is None
|
|
688
|
+
and docindex.locate(li, "x") is None
|
|
689
|
+
and docindex.locate(li, None) is None
|
|
690
|
+
and docindex.locate([], 10) is None)
|
|
691
|
+
|
|
692
|
+
# ================================ ⑫ 逐字节回放回归(往返列无损)
|
|
693
|
+
# ⑪ 只证「列可校验」;本段把口径推到内容无损:卡片必须是真源条目的派生物
|
|
694
|
+
# (render 补一个换行 == 卡片正文)。root 限定为本次真正索引过的两个真源,
|
|
695
|
+
# 断言只落在本轮写入的卡上——历史残留不参与,避免把脏数据当回归。
|
|
696
|
+
print("\n【12】逐字节回放回归:render(条目) + 换行 == 卡片正文")
|
|
697
|
+
cg.flush()
|
|
698
|
+
rp = _replay_cards(cg, roots={_norm(fx), _norm(DOCS)})
|
|
699
|
+
print(f" 取样 {rp['sampled']} 卡:一致 {rp['ok']} · 键未命中 "
|
|
700
|
+
f"{rp['dangling']} · 源已移出 {rp['gone']} · 读不了 "
|
|
701
|
+
f"{rp['unreadable']}")
|
|
702
|
+
check("回放取样命中卡片(root 限定=本次索引的两个真源)",
|
|
703
|
+
rp["sampled"] > 0, str(rp["sampled"]))
|
|
704
|
+
check("可读卡 100% 逐字节回放一致(写侧 render 与读侧同源)",
|
|
705
|
+
not rp["mismatch"],
|
|
706
|
+
f"一致 {rp['ok']}/{rp['sampled']};" + ";".join(rp["mismatch"][:2]))
|
|
707
|
+
check("零键未命中 / 零源已移出 / 零读不了(源在库则必可重定位并读回)",
|
|
708
|
+
rp["dangling"] == 0 and rp["gone"] == 0
|
|
709
|
+
and rp["unreadable"] == 0,
|
|
710
|
+
f"键未命中={rp['dangling']} 源已移出={rp['gone']} "
|
|
711
|
+
f"读不了={rp['unreadable']}")
|
|
712
|
+
check("回放账目闭合(一致 + 键未命中 + 源已移出 + 读不了 = 取样数)",
|
|
713
|
+
(rp["ok"] + rp["dangling"] + rp["gone"] + rp["unreadable"])
|
|
714
|
+
== rp["sampled"],
|
|
715
|
+
f"{rp['ok']}+{rp['dangling']}+{rp['gone']}+{rp['unreadable']}"
|
|
716
|
+
f" vs {rp['sampled']}")
|
|
717
|
+
|
|
718
|
+
# 历史抽样:真实认知图库(仓外数据面,历史卡最多)。以 MDCG_ROOT 显式声明;
|
|
719
|
+
# 裸 clone / CI 无此数据面 → 如实报 SKIP(不虚报通过、也不 FAIL)。
|
|
720
|
+
ext_root = os.environ.get("MDCG_ROOT") or ""
|
|
721
|
+
if not (ext_root and os.path.isdir(ext_root)):
|
|
722
|
+
print("\n【12b】历史抽样:跳过(未设 MDCG_ROOT 或目录不存在)"
|
|
723
|
+
"—— 本仓语料回放见【12】")
|
|
724
|
+
else:
|
|
725
|
+
print(f"\n【12b】历史抽样:外部认知图库 {ext_root}(只读身份)")
|
|
726
|
+
ext = MdCGSecure(ext_root, principal=Principal(
|
|
727
|
+
actor="p27-replay", clearance="secret", can_write=False,
|
|
728
|
+
can_admin=False, role="designer", auth_mode="local-cli"))
|
|
729
|
+
try:
|
|
730
|
+
hp = _replay_cards(ext, sample=120)
|
|
731
|
+
finally:
|
|
732
|
+
ext.close()
|
|
733
|
+
print(f" 抽样 {hp['sampled']} 卡:一致 {hp['ok']} · 键未命中 "
|
|
734
|
+
f"{hp['dangling']} · 源已移出 {hp['gone']} · 读不了 "
|
|
735
|
+
f"{hp['unreadable']}")
|
|
736
|
+
check("【12b】历史库抽样命中卡片(数据面可达)",
|
|
737
|
+
hp["sampled"] > 0, str(hp["sampled"]))
|
|
738
|
+
check("【12b】可读历史卡零回放不符(未被渲染漂移/人工改写腐化)",
|
|
739
|
+
not hp["mismatch"],
|
|
740
|
+
f"一致 {hp['ok']}/{hp['sampled']};"
|
|
741
|
+
+ ";".join(hp["mismatch"][:2]))
|
|
742
|
+
check("【12b】未读回的全部是「源已移出」(非 IO/抽取故障)",
|
|
743
|
+
hp["unreadable"] == 0,
|
|
744
|
+
f"源已移出={hp['gone']} 读不了={hp['unreadable']}")
|
|
745
|
+
check("【12b】抽样账目闭合(无静默丢弃)",
|
|
746
|
+
(hp["ok"] + hp["dangling"] + hp["gone"] + hp["unreadable"])
|
|
747
|
+
== hp["sampled"],
|
|
748
|
+
f"{hp['ok']}+{hp['dangling']}+{hp['gone']}+{hp['unreadable']}"
|
|
749
|
+
f" vs {hp['sampled']}")
|
|
750
|
+
|
|
497
751
|
finally:
|
|
498
752
|
shutil.rmtree(tmp, ignore_errors=True)
|
|
499
753
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""会话层 + 摄取分派 + 全库导出(P29 · P0 工程缺口验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/灵枢82工具_功能整理与迁移映射_v0.1.md` §五:P0 新增三个 op。
|
|
4
|
+
对照 `docs/mdcg/灵枢82工具_功能整理与迁移映射_v0.1.md` §五:P0 新增三个 op。
|
|
5
5
|
|
|
6
6
|
① op 三处同步:`tokens.ALL_OPS` == `cg` 工具 op 描述 == `_cg_call` 分支
|
|
7
7
|
② session:note 幂等写入;recall 一次返回可续接上下文包;compact 启发式压缩
|
package/md_cg/test_p2_mcp.py
CHANGED
|
@@ -262,12 +262,18 @@ def main():
|
|
|
262
262
|
kn = [t["name"] for t in kt]
|
|
263
263
|
check("kernel 只暴露 2 个基元", kn == ["cg", "stg"], str(kn))
|
|
264
264
|
info = kc.call("cg", {"op": "info"})
|
|
265
|
+
# 注:新增 content_kind(如 ccg_marks)须同步本清单——工具面自描述
|
|
266
|
+
# 与 audit.CONTENT_KINDS 真源逐类对齐,防「真源扩了、自描述没跟」。
|
|
265
267
|
check("cg info 自描述审核体系",
|
|
266
268
|
info.get("surface") == "kernel"
|
|
267
269
|
and set(info.get("audit_kinds", {})) == {
|
|
268
270
|
"code", "image_desc", "text", "permission",
|
|
269
|
-
"work_done", "work_wip"},
|
|
271
|
+
"work_done", "work_wip", "ccg_marks", "hyperedge"},
|
|
270
272
|
str(list(info.get("audit_kinds", {})))[:120])
|
|
273
|
+
check("cg info 自描述 CCG 契约角色(裁定 B)",
|
|
274
|
+
info.get("ccg_contract", {}).get("生效条件") == "前置条件 precondition"
|
|
275
|
+
and len(info.get("ccg_contract", {})) == 6,
|
|
276
|
+
str(info.get("ccg_contract"))[:120])
|
|
271
277
|
w = kc.call("cg", {"op": "write", "content_kind": "text",
|
|
272
278
|
"content": "hello", "node_id": "kw1"})
|
|
273
279
|
check("未验证的写入进审核队列",
|
|
@@ -201,6 +201,30 @@ def main():
|
|
|
201
201
|
mfm.get("induced_concept") == cid
|
|
202
202
|
and cid in {e.get("target") for e in (mfm.get("edges") or [])},
|
|
203
203
|
str(mfm.get("induced_concept")))
|
|
204
|
+
# ---- 2026-09-19 阶段一:巩固留痕字段一等公民 ----
|
|
205
|
+
check("成员侧记 consolidated_into(规范名·巩固进哪一条)",
|
|
206
|
+
mfm.get("consolidated_into") == cid
|
|
207
|
+
and mfm.get("induced_concept") == cid,
|
|
208
|
+
str(mfm.get("consolidated_into")))
|
|
209
|
+
check("成员侧记 consolidated_at(何时巩固)",
|
|
210
|
+
bool(mfm.get("consolidated_at")), str(mfm.get("consolidated_at")))
|
|
211
|
+
check("概念侧记 consolidated_at(概念形成即巩固时刻)",
|
|
212
|
+
bool(cfm.get("consolidated_at"))
|
|
213
|
+
and cfm.get("induced_at") == cfm.get("consolidated_at"),
|
|
214
|
+
f"{cfm.get('consolidated_at')} / {cfm.get('induced_at')}")
|
|
215
|
+
check("前身可定位:概念侧 induced_from 与成员侧列互查一致",
|
|
216
|
+
set(cfm.get("induced_from") or []) == {"ind_1", "ind_2", "ind_3"}
|
|
217
|
+
and all(((cg.get(m) or {}).get("frontmatter") or {}
|
|
218
|
+
).get("consolidated_into") == cid
|
|
219
|
+
for m in ("ind_1", "ind_2", "ind_3")))
|
|
220
|
+
# add() 是**全量重建 fm**——覆写后留痕必须仍在(回读节点继承,非索引快照)
|
|
221
|
+
cg.add("ind_1", IND_A, layer="contextual", importance=0.4,
|
|
222
|
+
verification_basis="other", actor="p31")
|
|
223
|
+
mfm2 = (cg.get("ind_1") or {}).get("frontmatter") or {}
|
|
224
|
+
check("覆写后成员侧巩固留痕继承(consolidated_into/at 不丢)",
|
|
225
|
+
mfm2.get("consolidated_into") == cid
|
|
226
|
+
and bool(mfm2.get("consolidated_at")),
|
|
227
|
+
str(mfm2.get("consolidated_into")))
|
|
204
228
|
check("induce 留痕 _maintain.jsonl",
|
|
205
229
|
any(r.get("action") == "induce"
|
|
206
230
|
for r in consolidate._read_maintain(ROOT)))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""层归位(P38 · G4 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §二:批次流水账(`note_`/`milestone_`/
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §二:批次流水账(`note_`/`milestone_`/
|
|
5
5
|
`retest6_`)与感知产物(`imgpart_`/`vpipe_`)混在 knowledge 层,语义上属**情境**,
|
|
6
6
|
需归位到 `contextual` 且**保留可召回**。
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""视觉证据回填(P39 · G5 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §三:视觉节点证据面恒为 `{}`,
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §三:视觉节点证据面恒为 `{}`,
|
|
5
5
|
根因是产出侧只取 `model_evidence`(白箱部件不带该键)——即**证据口径未定义**。
|
|
6
6
|
本轮以**库外只读归档**(逐部件结构化结果)为证据源,按三档映射回填,脱敏、
|
|
7
7
|
不读图像、不重跑视觉。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""G6 · node_ 结构提炼抽检工单与扩批闸门(P40 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §四 G6:`node_*`(P37 派生记忆)
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §四 G6:`node_*`(P37 派生记忆)
|
|
5
5
|
自带 `ccg_exempt=true`,只声明「功能名 / 生效条件」,`子功能/执行/不适用条件` 全缺。
|
|
6
6
|
条件 A 要求**先抽 20 条做提炼预演、人工核对提炼口径,绝不盲跑全量**。
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""G7 · 自主演化巡检(把「有能力」变成「有驱动」)(P41 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §五 G7:固化 / 重要性 / 去污染三类自我
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §五 G7:固化 / 重要性 / 去污染三类自我
|
|
5
5
|
演化动作早已具备,但**没有任何驱动源**周期性问「现在有多少该固化 / 该重算的候选」,
|
|
6
6
|
于是能力被饿死。本项给常驻循环挂上**只读**演化巡检 + **受控**自愈。
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""G8 · 派生溯源(新增即建链 + 失败不阻断 + 悬空可检出)(P42 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §六 G8:节点拆并/派生后**血缘丢失**,
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §六 G8:节点拆并/派生后**血缘丢失**,
|
|
5
5
|
库根无 `_link.jsonl`、frontmatter 的派生字段全空,事后无从回答「这个节点从哪来」。
|
|
6
6
|
本项只对**新增**节点常态化建链(历史不回填),且立三条硬约束。
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""§七 · 召回分池与降权(P43 设计态验收)。
|
|
3
3
|
|
|
4
|
-
对照 `docs/认知图_G4-G8缺口裁定单_v0.1.md` §七:索引/产物类节点(`code_`/`doc_`)
|
|
4
|
+
对照 `docs/mdcg/认知图_G4-G8缺口裁定单_v0.1.md` §七:索引/产物类节点(`code_`/`doc_`)
|
|
5
5
|
词面更易命中,在 `GLOBAL_CAP` 单条截断点**先把知识节点挤掉**。本项把截断额度
|
|
6
6
|
**显式分池**(不是抬高额度),并立四条纪律。
|
|
7
7
|
|
|
@@ -41,7 +41,11 @@ PASS = FAIL = 0
|
|
|
41
41
|
FAILS = []
|
|
42
42
|
|
|
43
43
|
BODY = "召回截断 索引 分池 内容"
|
|
44
|
-
|
|
44
|
+
# 多词查询:索引类含全部查询词、知识类缺「分池」→ 相关度有**区分度**。
|
|
45
|
+
# 原语料下 16 条分数全等(覆盖度口径),截断谁入榜只能由传入序决定——而传入序
|
|
46
|
+
# 本身不确定(目录枚举 + 并行 prefetch),断言 `off=6` 实为顺序抽签的产物。
|
|
47
|
+
QUERY = "召回截断 分池"
|
|
48
|
+
KBODY = "召回截断 索引 内容"
|
|
45
49
|
|
|
46
50
|
|
|
47
51
|
def ok(cond, label):
|
|
@@ -71,7 +75,12 @@ def _snapshot(root):
|
|
|
71
75
|
|
|
72
76
|
|
|
73
77
|
def _mk(root):
|
|
74
|
-
"""6 个索引类(code_/doc_)+ 10
|
|
78
|
+
"""6 个索引类(code_/doc_)+ 10 个知识类。
|
|
79
|
+
|
|
80
|
+
§七 的真实机制是「索引/产物类节点**词面命中率更高**」(正文短、查询词占比大),
|
|
81
|
+
故索引类正文短、知识类正文长(含背景说明),使索引类相似度**确实**高于知识类
|
|
82
|
+
——挤占由相关度驱动,不依赖写入顺序(截断依据已改为相关度,见 `cut_by_relevance`)。
|
|
83
|
+
"""
|
|
75
84
|
cg = MdCGOS(root, actor="test")
|
|
76
85
|
for i in range(4):
|
|
77
86
|
cg.add(f"code_{i}", f"# 功能名:索引条目 {i}\n# 生效条件:条件 I\n\n{BODY} {i}\n",
|
|
@@ -80,7 +89,10 @@ def _mk(root):
|
|
|
80
89
|
cg.add(f"doc_{i}", f"# 功能名:文档索引 {i}\n# 生效条件:条件 D\n\n{BODY} {i}\n",
|
|
81
90
|
layer="knowledge", tags=["index"])
|
|
82
91
|
for i in range(10):
|
|
83
|
-
cg.add(f"kp_{i}",
|
|
92
|
+
cg.add(f"kp_{i}",
|
|
93
|
+
f"# 功能名:知识 {i}\n# 生效条件:条件 K\n\n{KBODY} {i}\n"
|
|
94
|
+
f"备注:本条为知识类条目,含背景说明、推理链与引用出处,正文较长,"
|
|
95
|
+
f"查询词在全文中的占比因此显著低于索引类条目。\n",
|
|
84
96
|
layer="knowledge")
|
|
85
97
|
cg.add("n_rej", f"# 功能名:被否决\n# 生效条件:条件 R\n\n{BODY} 否\n",
|
|
86
98
|
layer="rejected")
|
|
@@ -238,12 +250,27 @@ def main():
|
|
|
238
250
|
# 但「乘数可复算」这一被测语义不变。
|
|
239
251
|
base = {r[0]["id"]: r[1] for r in off}
|
|
240
252
|
sc = {r[0]["id"]: r[1] for r in on}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
253
|
+
|
|
254
|
+
def _pick_idx(d):
|
|
255
|
+
"""挑一条「关闭态也有基础分」的索引类入榜条目。
|
|
256
|
+
|
|
257
|
+
截断依据改为相关度后,具体哪条索引入榜由分数序决定(不再是固定的
|
|
258
|
+
`code_0`——那正是按传入序截断时代的产物),故动态取。
|
|
259
|
+
"""
|
|
260
|
+
return next((i for i in d if PL.pool_of(i) == "index" and i in base), None)
|
|
261
|
+
|
|
262
|
+
iid = _pick_idx(sc)
|
|
263
|
+
ok(iid is not None, "(8) 分池态含索引类条目(额度保底生效)")
|
|
264
|
+
ok(iid is not None and abs(sc[iid] - base[iid] * 0.6) < 1e-9,
|
|
265
|
+
f"(8) 索引类命中分 == 基础分 × 0.6({iid}: base={base.get(iid, 0.0):.6f} → "
|
|
266
|
+
f"{sc.get(iid, float('nan')):.6f})")
|
|
267
|
+
# 知识类权重 1.0 → 命中分应与关闭态同源分一致。不硬编码编号:关闭态额度
|
|
268
|
+
# 被索引类占满,只余 2 条知识类入榜,与分池态取的 6 条未必有同编号交集
|
|
269
|
+
# (全同分下由稳定序决定),故按「关闭态知识分基准」比对。
|
|
270
|
+
base_kp = [v for k, v in base.items() if k.startswith("kp_")]
|
|
271
|
+
sc_kp = [v for k, v in sc.items() if k.startswith("kp_")]
|
|
272
|
+
ok(base_kp and sc_kp and all(abs(v - base_kp[0]) < 1e-9 for v in sc_kp),
|
|
273
|
+
f"(8) 知识类命中分不被削(权重 1.0;base={base_kp[:1]} → on={sc_kp[:2]})")
|
|
247
274
|
ok(PL.weight_of("code_x", {}, True) == PL.WEIGHTS["index"]["weight"],
|
|
248
275
|
"(8) weight_of 与表内系数一致")
|
|
249
276
|
alt = {"knowledge": {"cap_ratio": 0.5, "weight": 1.0},
|
|
@@ -251,9 +278,10 @@ def main():
|
|
|
251
278
|
"negative": {"cap_ratio": 0.1, "weight": 0.5}}
|
|
252
279
|
on2, _m2 = cg.search(QUERY, k=20, record=False, pools=alt)
|
|
253
280
|
sc2 = {r[0]["id"]: r[1] for r in on2}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
f"{
|
|
281
|
+
iid2 = _pick_idx(sc2)
|
|
282
|
+
ok(iid2 is not None and abs(sc2[iid2] - base[iid2] * 0.3) < 1e-9,
|
|
283
|
+
f"(8) 换表即换行为({iid2}: base×0.3={base.get(iid2, 0.0) * 0.3:.6f} → "
|
|
284
|
+
f"{sc2.get(iid2, float('nan')):.6f})")
|
|
257
285
|
ok(PL.caps(10, PL.resolve(alt)) == {"knowledge": 4, "index": 4, "negative": 2},
|
|
258
286
|
f"(8) 换表额度同步可复算(实得 {PL.caps(10, PL.resolve(alt))})")
|
|
259
287
|
|
|
@@ -28,7 +28,7 @@ import tempfile
|
|
|
28
28
|
|
|
29
29
|
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
30
30
|
|
|
31
|
-
from .md_whitebox import build_db_from_md # noqa: E402
|
|
31
|
+
from .md_whitebox import build_db_from_md, corpus_gap # noqa: E402
|
|
32
32
|
|
|
33
33
|
SOURCE_DB = os.path.join(_HERE, "whitebox_kb", "wisdom", "wisdom-book-cloud.db")
|
|
34
34
|
|
|
@@ -129,6 +129,19 @@ def _report(rows):
|
|
|
129
129
|
def main():
|
|
130
130
|
ok = True
|
|
131
131
|
|
|
132
|
+
# 依赖自辩(2026-09-20 v14 缺陷 F):源库与 md 语料均为 gitignored 本地
|
|
133
|
+
# 数据面——缺失时本模块自己打 SKIP 返回 0。旧形态下缺库会以未捕获的
|
|
134
|
+
# `sqlite3.OperationalError: unable to open database file` traceback 示人,
|
|
135
|
+
# 与兄弟目标「自建库后断言失败」构成同一根因的第三副面孔。
|
|
136
|
+
if not os.path.exists(SOURCE_DB):
|
|
137
|
+
print("SKIP test_p44_md_whitebox:依赖源库 %s(.gitignore 忽略,"
|
|
138
|
+
"需本地生成)" % SOURCE_DB)
|
|
139
|
+
return 0
|
|
140
|
+
_gap = corpus_gap()
|
|
141
|
+
if _gap:
|
|
142
|
+
print("SKIP test_p44_md_whitebox:%s" % _gap)
|
|
143
|
+
return 0
|
|
144
|
+
|
|
132
145
|
# ---- 1) 结构等价 ----
|
|
133
146
|
# force:从 md 语料**重新**还原,保证 access_count 等可变字段与源库快照
|
|
134
147
|
# 同起点(复用旧库会带上此前问答累积的 access,造成假差异)。
|