@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/sustain.py
CHANGED
|
@@ -80,16 +80,19 @@ _POLL = 0.2 # 循环轮询步长(常驻进程 CPU 可忽
|
|
|
80
80
|
# 心跳
|
|
81
81
|
# --------------------------------------------------------------------------
|
|
82
82
|
|
|
83
|
+
# 生效条件:d 为真值时返回 d,d 为 None/空串时回落 MDCG_SUSTAIN_DIR,该环境变量也未设或为空串时返回 os.path.join(os.path.expanduser("~"), ".mdcg", "sustain");
|
|
83
84
|
def net_dir(d: str = None) -> str:
|
|
84
85
|
"""心跳戳目录:显式 → MDCG_SUSTAIN_DIR → ~/.mdcg/sustain(仓库外)。"""
|
|
85
86
|
return (d or os.environ.get("MDCG_SUSTAIN_DIR")
|
|
86
87
|
or os.path.join(os.path.expanduser("~"), ".mdcg", "sustain"))
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
# 生效条件:给定必填 name,返回 net_dir(d) 下 heartbeat.<name>.stamp 的拼接路径。
|
|
89
91
|
def stamp_path(name: str, d: str = None) -> str:
|
|
90
92
|
return os.path.join(net_dir(d), f"heartbeat.{name}.stamp")
|
|
91
93
|
|
|
92
94
|
|
|
95
|
+
# 生效条件:name 必填,组装含模块常量 STAMP_VERSION 与 task_running 的戳记录、原子写入 stamp_path(name,d) 后返回该 rec。
|
|
93
96
|
def write_stamp(name: str, d: str = None, **extra) -> dict:
|
|
94
97
|
"""写一次心跳(原子替换)。extra 会并入戳内容(None 值丢弃)。"""
|
|
95
98
|
rec = {"v": STAMP_VERSION, "name": name, "ts": time.time(),
|
|
@@ -104,6 +107,7 @@ def write_stamp(name: str, d: str = None, **extra) -> dict:
|
|
|
104
107
|
return rec
|
|
105
108
|
|
|
106
109
|
|
|
110
|
+
# 生效条件:stamp_path(name, d) 所得路径上 os.path.exists 为真且 json.load 结果为 dict 时,返回该 rec 并附加 age=max(0.0, time.time() - float(rec.get("ts") or 0));该路径不可读、json.load 抛 ValueError/OSError 或 rec 非 dict 时返回 None;
|
|
107
111
|
def read_stamp(name: str, d: str = None):
|
|
108
112
|
"""读心跳戳并附 age(秒);不存在 / 损坏 → None。"""
|
|
109
113
|
p = stamp_path(name, d)
|
|
@@ -120,6 +124,7 @@ def read_stamp(name: str, d: str = None):
|
|
|
120
124
|
return rec
|
|
121
125
|
|
|
122
126
|
|
|
127
|
+
# 生效条件:对 stamp_path(name,d) 执行 os.remove,OSError 被静默忽略,无返回值。
|
|
123
128
|
def clear_stamp(name: str, d: str = None):
|
|
124
129
|
try:
|
|
125
130
|
os.remove(stamp_path(name, d))
|
|
@@ -127,6 +132,7 @@ def clear_stamp(name: str, d: str = None):
|
|
|
127
132
|
pass
|
|
128
133
|
|
|
129
134
|
|
|
135
|
+
# 生效条件:age 为 None 返回 'absent';否则以 factor=working if task_running else 1.0 比较 age 与 interval*warn*factor、interval*dead*factor,分别返回 'ok'/'warning'/'dead'。
|
|
130
136
|
def judge(age, *, interval: float = DEFAULT_BEAT_INTERVAL,
|
|
131
137
|
task_running: bool = False, warn: float = DEFAULT_WARN_FACTOR,
|
|
132
138
|
dead: float = DEFAULT_DEAD_FACTOR,
|
|
@@ -146,6 +152,7 @@ def judge(age, *, interval: float = DEFAULT_BEAT_INTERVAL,
|
|
|
146
152
|
return "dead"
|
|
147
153
|
|
|
148
154
|
|
|
155
|
+
# 生效条件:net_dir(d) 可列为目录时遍历 heartbeat.*.stamp 并返回含 age 与 state 的记录列表,否则返回 []。
|
|
149
156
|
def peers(d: str = None):
|
|
150
157
|
"""列出本机所有心跳戳(含状态)。"""
|
|
151
158
|
base = net_dir(d)
|
|
@@ -171,6 +178,7 @@ DEFAULT_RESTART_COOLDOWN = 300.0 # 同一对端两次拉起的最小间隔(
|
|
|
171
178
|
DEFAULT_FRESH_TIMEOUT = 60.0 # 拉起后等待对端戳变新鲜的窗口
|
|
172
179
|
|
|
173
180
|
|
|
181
|
+
# 生效条件:pid 可转 int 且 >0 时按探活(os.name=='nt' 用 OpenProcess+WaitForSingleObject,否则 os.kill(pid,0))返回 True,转 int 失败或 pid<=0 或探活失败返回 False。
|
|
174
182
|
def pid_alive(pid) -> bool:
|
|
175
183
|
"""进程探活(零第三方依赖):Windows=OpenProcess+WaitForSingleObject;
|
|
176
184
|
posix=os.kill(pid,0)。pid 无效 / 已退出 / 权限外 → False(诚实)。"""
|
|
@@ -199,6 +207,7 @@ def pid_alive(pid) -> bool:
|
|
|
199
207
|
return False
|
|
200
208
|
|
|
201
209
|
|
|
210
|
+
# 生效条件:cmd 为 argv 列表时以 stdout/stderr=DEVNULL、不经 shell 的 subprocess.Popen 拉起(nt 附加 DETACHED|NEW_GROUP creationflags),返回该 Popen 对象。
|
|
202
211
|
def _default_spawner(cmd):
|
|
203
212
|
"""分离式拉起:argv 列表、不经 shell、输出弃置(Windows 完全脱离父控制台)。"""
|
|
204
213
|
import subprocess
|
|
@@ -209,6 +218,7 @@ def _default_spawner(cmd):
|
|
|
209
218
|
stderr=subprocess.DEVNULL, **kw)
|
|
210
219
|
|
|
211
220
|
|
|
221
|
+
# 生效条件:root 与 peer 必填,扫描 root/SUSTAIN_LOG(模块常量)返回 op='mutual'、action='restart' 且 detail 以 peer 开头的记录中最大 t,无匹配返回 0.0。
|
|
212
222
|
def _last_mutual_restart(root: str, peer: str) -> float:
|
|
213
223
|
"""_sustain.jsonl 里该对端最近一次互维拉起时间(无 → 0.0,审计即状态)。"""
|
|
214
224
|
last = 0.0
|
|
@@ -227,6 +237,7 @@ def _last_mutual_restart(root: str, peer: str) -> float:
|
|
|
227
237
|
return last
|
|
228
238
|
|
|
229
239
|
|
|
240
|
+
# 生效条件:cg 与 peer 必填,读对端戳判状态:ok/warning 直接返回 action='none';dead/absent 时依次按 pid_alive、restart_cooldown、restart_cmd 有无走 alive_but_stale/restart_cooldown/dead_unhandled/拉起并验戳,返回 out。
|
|
230
241
|
def mutual_watch(cg, peer: str, *, restart_cmd=None, d: str = None,
|
|
231
242
|
interval: float = DEFAULT_BEAT_INTERVAL,
|
|
232
243
|
restart_cooldown: float = DEFAULT_RESTART_COOLDOWN,
|
|
@@ -294,6 +305,7 @@ def mutual_watch(cg, peer: str, *, restart_cmd=None, d: str = None,
|
|
|
294
305
|
return out
|
|
295
306
|
|
|
296
307
|
|
|
308
|
+
# 生效条件:cg 与 peer 必填,分别按 name 与 peer 读戳判状态,仅当自身与对端状态均属 ('dead','absent') 时返回 ok=False、both_dead=True。
|
|
297
309
|
def mutual_status(cg, peer: str, *, d: str = None, name: str = "md_cg",
|
|
298
310
|
interval: float = DEFAULT_BEAT_INTERVAL) -> dict:
|
|
299
311
|
"""互维状态 + 双亡检测:自己也失联时互维不可信 → 显式外部告警语义。"""
|
|
@@ -316,6 +328,7 @@ def mutual_status(cg, peer: str, *, d: str = None, name: str = "md_cg",
|
|
|
316
328
|
# 诊断(只读)
|
|
317
329
|
# --------------------------------------------------------------------------
|
|
318
330
|
|
|
331
|
+
# 生效条件:root 必填,对模块常量 LAYERS 各层 os.walk 统计以 .md 结尾的文件名个数并返回 n(不解析正文)。
|
|
319
332
|
def _count_node_files(root: str) -> int:
|
|
320
333
|
"""轻量统计磁盘节点数(只数文件名,不解析正文)。"""
|
|
321
334
|
n = 0
|
|
@@ -325,6 +338,7 @@ def _count_node_files(root: str) -> int:
|
|
|
325
338
|
return n
|
|
326
339
|
|
|
327
340
|
|
|
341
|
+
# 生效条件:root 与 older_than 必填,返回 root 及其 LAYERS 各层下以 '.' 开头、名含 '.tmp-' 且 mtime 早于 now-older_than 的路径列表。
|
|
328
342
|
def _list_stale_temps(root: str, older_than: float):
|
|
329
343
|
now, out = time.time(), []
|
|
330
344
|
bases = [root] + [os.path.join(root, l) for l in LAYERS]
|
|
@@ -343,6 +357,7 @@ def _list_stale_temps(root: str, older_than: float):
|
|
|
343
357
|
return out
|
|
344
358
|
|
|
345
359
|
|
|
360
|
+
# 生效条件:root 必填,返回 root 顶层以 .jsonl/.log 结尾且 ends_mid_line 为真的路径列表;root 非目录返回 []。
|
|
346
361
|
def _half_line_logs(root: str):
|
|
347
362
|
"""顶层行式日志里末尾不是换行的(写者被杀留下的半截记录)。"""
|
|
348
363
|
out = []
|
|
@@ -357,6 +372,7 @@ def _half_line_logs(root: str):
|
|
|
357
372
|
return out
|
|
358
373
|
|
|
359
374
|
|
|
375
|
+
# 生效条件:root/_index_log 可列为目录时返回其中 .log 结尾的文件名列表,否则返回 []。
|
|
360
376
|
def _index_log_shards(root: str):
|
|
361
377
|
d = os.path.join(root, "_index_log")
|
|
362
378
|
if not os.path.isdir(d):
|
|
@@ -364,6 +380,7 @@ def _index_log_shards(root: str):
|
|
|
364
380
|
return [f for f in os.listdir(d) if f.endswith(".log")]
|
|
365
381
|
|
|
366
382
|
|
|
383
|
+
# 生效条件:cg 具备 crypto_status 且其返回 unlocked 为假时,返回 cg.index['nodes'] 中 sensitivity 属 crypto.ENCRYPTED_LEVELS 的条目数;属性缺失、调用异常或已解锁时返回 0。
|
|
367
384
|
def _locked_nodes(cg) -> int:
|
|
368
385
|
"""加密引擎在「未解锁」状态下被隔离的私有节点数(缺密钥 = 权限事实)。"""
|
|
369
386
|
if not hasattr(cg, "crypto_status"):
|
|
@@ -388,6 +405,7 @@ EVOLVE_FIXES = {"ccg_backlog": "consolidate_run",
|
|
|
388
405
|
"importance_drift": "importance"}
|
|
389
406
|
|
|
390
407
|
|
|
408
|
+
# 生效条件:nodes 与 top 必填,遍历索引条目统计缺 verification_basis 或 has_neg_conditions 的候补数 n、no_basis、no_neg 并取最多 top 个 sample,返回含 proxy=True 与 EVOLVE_FIXES['ccg_backlog'] 的字典。
|
|
391
409
|
def _ccg_backlog(nodes: dict, top: int) -> dict:
|
|
392
410
|
"""固化候补量(**索引代理指标**:零读节点文件、确定性、O(N))。
|
|
393
411
|
|
|
@@ -412,6 +430,7 @@ def _ccg_backlog(nodes: dict, top: int) -> dict:
|
|
|
412
430
|
"proxy": True, "fix": EVOLVE_FIXES["ccg_backlog"]}
|
|
413
431
|
|
|
414
432
|
|
|
433
|
+
# 生效条件:cg 必填,取 cg.index['nodes'](layer 非空时按 layer 过滤),经 weights.recalc(apply=False) 与 _ccg_backlog 汇总,返回 ok=True、readonly=True、dry_run=True 的候选盘点字典。
|
|
415
434
|
def evolution_candidates(cg, *, layer: str = None, top: int = 8,
|
|
416
435
|
min_delta: float = None) -> dict:
|
|
417
436
|
"""演化候选盘点(G7):**只读、零读节点文件、确定性、不写盘**。
|
|
@@ -446,6 +465,7 @@ def evolution_candidates(cg, *, layer: str = None, top: int = 8,
|
|
|
446
465
|
"重要性重算为确定性动作(有 rollback)")}
|
|
447
466
|
|
|
448
467
|
|
|
468
|
+
# 生效条件:给定 cg 后只读汇总(nodes 取自 cg.index、disk 计数、refindex.check_refs),stale_temp_age 传入 _list_stale_temps;check_heartbeat / check_evolution(evolve_top) / check_provenance(provenance_top) 为真时分别追加对应 issue,返回 ok = 无 severity=="warning" 的 issue 连同 stats。
|
|
449
469
|
def diagnose(cg, *, name: str = "md_cg", stale_temp_age: float = STALE_TEMP_AGE,
|
|
450
470
|
check_heartbeat: bool = True, check_evolution: bool = True,
|
|
451
471
|
evolve_top: int = 5, check_provenance: bool = True,
|
|
@@ -575,17 +595,20 @@ def diagnose(cg, *, name: str = "md_cg", stale_temp_age: float = STALE_TEMP_AGE,
|
|
|
575
595
|
# 自愈
|
|
576
596
|
# --------------------------------------------------------------------------
|
|
577
597
|
|
|
598
|
+
# 生效条件:path 必填,以 'ab' 模式向该路径追加写入单个换行 b'\n',无返回值。
|
|
578
599
|
def _seal_half_line(path: str):
|
|
579
600
|
with open(path, "ab") as f:
|
|
580
601
|
f.write(b"\n")
|
|
581
602
|
|
|
582
603
|
|
|
604
|
+
# 生效条件:root/op/action 必填,向 root/SUSTAIN_LOG(模块常量)追加一行含 t/op/action/detail(截断 200)/pid 的 JSONL,无返回值。
|
|
583
605
|
def _audit(root: str, op: str, action: str, detail: str = ""):
|
|
584
606
|
append_jsonl(os.path.join(root, SUSTAIN_LOG),
|
|
585
607
|
{"t": time.time(), "op": op, "action": action,
|
|
586
608
|
"detail": str(detail)[:200], "pid": os.getpid()})
|
|
587
609
|
|
|
588
610
|
|
|
611
|
+
# 生效条件:按 diagnose(cg, name=name, stale_temp_age=stale_temp_age) 的 issues code 集合分派——命中 index_drift/index_orphan 重建索引、ref_stale/ref_dangling 按 ref 重建源索引、index_log_backlog 合并索引分片、stale_temps 清理陈旧临时文件、half_line_logs 修补半截日志;ccg_backlog 仅 allow_evolve=True 且 reflect_fn 非 None 时才 consolidate(否则记 needs_llm),importance_drift 仅 allow_evolve=True 时才重算重要性(否则记 evolve_disabled);dry_run=True 时各动作只记入 actions 不落盘,返回含 after["ok"]、dry_run、actions、before/after 的 stats 与 t 的 dict;
|
|
589
612
|
def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
590
613
|
stale_temp_age: float = STALE_TEMP_AGE,
|
|
591
614
|
allow_evolve: bool = False, reflect_fn=None, verify_fn=None) -> dict:
|
|
@@ -599,6 +622,7 @@ def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
|
599
622
|
root = cg.root
|
|
600
623
|
actions = []
|
|
601
624
|
|
|
625
|
+
# 生效条件:闭包 dry_run 为真时向 actions 追加 {"code": code, "detail": detail, "applied": False} 并返回;否则调用 fn(),成功追加 applied=True/ok=True,抛异常时追加 applied=True/ok=False 与 error,最后执行 _audit(root, "heal", code, detail);
|
|
602
626
|
def act(code: str, detail: str, fn):
|
|
603
627
|
if dry_run:
|
|
604
628
|
actions.append({"code": code, "detail": detail, "applied": False})
|
|
@@ -624,6 +648,7 @@ def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
|
624
648
|
if "stale_temps" in codes:
|
|
625
649
|
paths = _list_stale_temps(root, stale_temp_age)
|
|
626
650
|
|
|
651
|
+
# 生效条件:对闭包变量 paths 中每个路径尝试 os.remove(p),单个路径的 OSError 被吞掉后继续处理后续路径;
|
|
627
652
|
def _sweep():
|
|
628
653
|
for p in paths:
|
|
629
654
|
try:
|
|
@@ -643,6 +668,7 @@ def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
|
643
668
|
if allow_evolve and reflect_fn is not None:
|
|
644
669
|
from . import consolidate as _cd
|
|
645
670
|
|
|
671
|
+
# 生效条件:调用时返回 _cd.consolidate(cg.root, apply=True, reflect_fn=reflect_fn, verify_fn=verify_fn);
|
|
646
672
|
def _consolidate():
|
|
647
673
|
return _cd.consolidate(cg.root, apply=True,
|
|
648
674
|
reflect_fn=reflect_fn,
|
|
@@ -655,6 +681,7 @@ def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
|
655
681
|
if allow_evolve:
|
|
656
682
|
from . import weights
|
|
657
683
|
|
|
684
|
+
# 生效条件:调用时返回 weights.recalc(cg, apply=True, actor="sustain_evolve");
|
|
658
685
|
def _importance():
|
|
659
686
|
return weights.recalc(cg, apply=True, actor="sustain_evolve")
|
|
660
687
|
act("importance", "重算结构重要性(确定性;可 rollback)", _importance)
|
|
@@ -674,6 +701,7 @@ def heal(cg, *, name: str = "md_cg", dry_run: bool = False,
|
|
|
674
701
|
# 会话水位(重启续接)
|
|
675
702
|
# --------------------------------------------------------------------------
|
|
676
703
|
|
|
704
|
+
# 生效条件:以 root 实例化后账本固定指向 os.path.join(root, LEDGER_FILE),其 _load/_save/note/resume_point/sessions/summary 均以该路径为唯一读写对象;
|
|
677
705
|
class SessionLedger:
|
|
678
706
|
"""会话水位账本:<root>/_sessions.json。
|
|
679
707
|
|
|
@@ -681,10 +709,12 @@ class SessionLedger:
|
|
|
681
709
|
这里记「某个会话发生过什么」——重启后按会话给出续接点。
|
|
682
710
|
"""
|
|
683
711
|
|
|
712
|
+
# 生效条件:传入 root 时置 self.root=root 且 self.path=os.path.join(root, LEDGER_FILE),不做其他校验;
|
|
684
713
|
def __init__(self, root: str):
|
|
685
714
|
self.root = root
|
|
686
715
|
self.path = os.path.join(root, LEDGER_FILE)
|
|
687
716
|
|
|
717
|
+
# 生效条件:self.path(root/LEDGER_FILE)可读且 json 结果为 dict、且 d.get("sessions") 也是 dict 时返回该 d;self.path 不可读、json.load 抛 ValueError/OSError、或 d 非 dict / sessions 非 dict 时返回 {"schema": 1, "sessions": {}};
|
|
688
718
|
def _load(self):
|
|
689
719
|
if os.path.exists(self.path):
|
|
690
720
|
try:
|
|
@@ -696,9 +726,11 @@ class SessionLedger:
|
|
|
696
726
|
pass
|
|
697
727
|
return {"schema": 1, "sessions": {}}
|
|
698
728
|
|
|
729
|
+
# 生效条件:传入 d 时执行 atomic_write(self.path, json.dumps(d, ensure_ascii=False, indent=1)),自身无返回值;
|
|
699
730
|
def _save(self, d):
|
|
700
731
|
atomic_write(self.path, json.dumps(d, ensure_ascii=False, indent=1))
|
|
701
732
|
|
|
733
|
+
# 生效条件:以 session 为键 setdefault 会话记录后写 events=int(s.get("events") or 0)+int(n)(n 默认 1,n=0 时计数不变),t 非 None 时写 last_t 且 first_t 为空时一并写入,seq 非 None 时写 last_seq,actor 为真值时写 actor,最后写 updated_at 并 _save,返回 dict(s, session=session);
|
|
702
734
|
def note(self, session: str, *, t=None, seq=None, n: int = 1,
|
|
703
735
|
actor: str = None) -> dict:
|
|
704
736
|
"""记一笔会话活动(事件计数 + 最后 (t, seq) 水位)。"""
|
|
@@ -718,6 +750,7 @@ class SessionLedger:
|
|
|
718
750
|
self._save(d)
|
|
719
751
|
return dict(s, session=session)
|
|
720
752
|
|
|
753
|
+
# 生效条件:_load()["sessions"].get(session) 为假值(键缺失或值为空 dict)时返回 {"session": session, "resume": None, "events": 0};否则返回 {"session": session, "events": s.get("events", 0), "resume": {"t": s.get("last_t"), "seq": s.get("last_seq")}, "last_t": s.get("last_t"), "actor": s.get("actor")};
|
|
721
754
|
def resume_point(self, session: str) -> dict:
|
|
722
755
|
"""重启续接点:(t, seq) 之后的事件才是新的。"""
|
|
723
756
|
s = self._load()["sessions"].get(session)
|
|
@@ -727,9 +760,11 @@ class SessionLedger:
|
|
|
727
760
|
"resume": {"t": s.get("last_t"), "seq": s.get("last_seq")},
|
|
728
761
|
"last_t": s.get("last_t"), "actor": s.get("actor")}
|
|
729
762
|
|
|
763
|
+
# 生效条件:无参调用时返回 dict(self._load()["sessions"]) 的浅拷贝,账本缺失/损坏时 _load 回落默认值故此处为 {};
|
|
730
764
|
def sessions(self) -> dict:
|
|
731
765
|
return dict(self._load()["sessions"])
|
|
732
766
|
|
|
767
|
+
# 生效条件:取 d=_load()["sessions"] 后返回 {"sessions": len(d), "events": sum(int(v.get("events") or 0)), "latest": max(v.get("last_t") or 0) if d else None},d 为空时 latest 为 None;
|
|
733
768
|
def summary(self) -> dict:
|
|
734
769
|
d = self._load()["sessions"]
|
|
735
770
|
return {"sessions": len(d),
|
|
@@ -738,6 +773,7 @@ class SessionLedger:
|
|
|
738
773
|
if d else None}
|
|
739
774
|
|
|
740
775
|
|
|
776
|
+
# 生效条件:os.path.exists(os.path.join(cg.root, "_sources.json")) 为真且 json.load 成功时返回 dict((d or {}).get("sources") or {})(d 或 sources 为假值即回落 {});该路径不可读或 json.load 抛 ValueError/OSError 时返回 {};
|
|
741
777
|
def watermarks(cg) -> dict:
|
|
742
778
|
"""源视角水位快照(读 sources.Ingestor 的 _sources.json)。"""
|
|
743
779
|
p = os.path.join(cg.root, "_sources.json")
|
|
@@ -755,6 +791,7 @@ def watermarks(cg) -> dict:
|
|
|
755
791
|
# 常驻循环
|
|
756
792
|
# --------------------------------------------------------------------------
|
|
757
793
|
|
|
794
|
+
# 生效条件:传入 cg 即构造实例并把 self.cg 指向它,name/beat_interval/heal_interval/auto_heal/scrub_interval/auto_scrub/evolve_interval/auto_evolve/tidy_interval/auto_tidy 用各默认值(DEFAULT_* 与 False/True)经 float()/bool() 落为 self 属性,ledger 为假值(默认 None)时回落 SessionLedger(cg.root),d 经 net_dir(d) 赋值,其余运行态字段初始化为 False/None/空列表/空 Event/Lock
|
|
758
795
|
class SustainLoop:
|
|
759
796
|
"""常驻自维持循环:后台线程周期心跳 + 周期巡检 + 必要时自愈。
|
|
760
797
|
|
|
@@ -762,6 +799,7 @@ class SustainLoop:
|
|
|
762
799
|
让对端立刻看到「正常下线」而不是「失联」。
|
|
763
800
|
"""
|
|
764
801
|
|
|
802
|
+
# 生效条件:传入 cg 时按 name 与各 DEFAULT_* 默认值初始化——self.d=net_dir(d)(d 假值时回落 MDCG_SUSTAIN_DIR/~/ .mdcg/sustain)、self.ledger=ledger or SessionLedger(cg.root)(ledger 假值时新建),beat/heal/scrub/evolve/tidy 间隔 float() 化、auto_heal/auto_scrub/auto_evolve/auto_tidy bool() 化后存为实例属性;
|
|
765
803
|
def __init__(self, cg, name: str = "md_cg", *,
|
|
766
804
|
beat_interval: float = DEFAULT_BEAT_INTERVAL,
|
|
767
805
|
heal_interval: float = DEFAULT_HEAL_INTERVAL,
|
|
@@ -797,6 +835,8 @@ class SustainLoop:
|
|
|
797
835
|
self.evolves = []
|
|
798
836
|
self.last_tidy = None
|
|
799
837
|
self.tidys = []
|
|
838
|
+
# 数据健康不变量断言集结论(Pi⑤):与 tidy 同节奏,只取结论不落盘
|
|
839
|
+
self.last_conformance = None
|
|
800
840
|
self._started_at = None
|
|
801
841
|
self._th = None
|
|
802
842
|
self._stop = threading.Event()
|
|
@@ -804,6 +844,7 @@ class SustainLoop:
|
|
|
804
844
|
|
|
805
845
|
# ---- 心跳 ----
|
|
806
846
|
|
|
847
|
+
# 生效条件:task_running 非 None 时先置 self.task_running=bool(task_running),再 write_stamp(self.name, self.d, task_running=self.task_running, root=self.cg.root, uptime=... if self._started_at else 0.0),beats 自增并记 last_beat=rec["ts"],返回该 rec;
|
|
807
848
|
def beat(self, task_running: bool = None) -> dict:
|
|
808
849
|
if task_running is not None:
|
|
809
850
|
self.task_running = bool(task_running)
|
|
@@ -817,6 +858,7 @@ class SustainLoop:
|
|
|
817
858
|
|
|
818
859
|
# ---- 生命周期 ----
|
|
819
860
|
|
|
861
|
+
# 生效条件:不适用(无必需形参与模块级常量)
|
|
820
862
|
def start(self):
|
|
821
863
|
if self._th is not None and self._th.is_alive():
|
|
822
864
|
return self
|
|
@@ -828,6 +870,7 @@ class SustainLoop:
|
|
|
828
870
|
self._th.start()
|
|
829
871
|
return self
|
|
830
872
|
|
|
873
|
+
# 生效条件:调用时置 _stop 事件,self._th 非 None 时 join(timeout)(默认 3.0)后置为 None,随后 clear_stamp(self.name, self.d),返回 self;
|
|
831
874
|
def stop(self, timeout: float = 3.0):
|
|
832
875
|
self._stop.set()
|
|
833
876
|
if self._th is not None:
|
|
@@ -836,6 +879,7 @@ class SustainLoop:
|
|
|
836
879
|
clear_stamp(self.name, self.d)
|
|
837
880
|
return self
|
|
838
881
|
|
|
882
|
+
# 生效条件:self._stop 未置位期间轮询,按 beat_interval/heal_interval/scrub_interval/evolve_interval/tidy_interval 到期分别执行 beat 与 _tick_heal/_tick_scrub/_tick_evolve/_tick_tidy,各 tick 抛出的异常被吞掉不中断循环,末尾以 _stop.wait(_POLL) 休眠;
|
|
839
883
|
def _run(self):
|
|
840
884
|
next_beat = time.time() + self.beat_interval
|
|
841
885
|
next_heal = time.time() + self.heal_interval
|
|
@@ -876,6 +920,7 @@ class SustainLoop:
|
|
|
876
920
|
next_tidy = now + self.tidy_interval
|
|
877
921
|
self._stop.wait(_POLL)
|
|
878
922
|
|
|
923
|
+
# 生效条件:以 apply=self.auto_tidy 调 writelimit.tidy_contextual(self.cg, actor="sustain_tidy"),把 t/scanned/groups/members/applied_count/auto_tidy 记入 self.last_tidy 与 tidys(仅保留最近 20 条),随后调 _tick_conformance();auto_tidy=False(默认)时只盘点不落盘;
|
|
879
924
|
def _tick_tidy(self):
|
|
880
925
|
"""整理巡检(contextual 流水治理·读侧):同构组聚合 + 成员降权。
|
|
881
926
|
|
|
@@ -894,7 +939,24 @@ class SustainLoop:
|
|
|
894
939
|
with self._lock:
|
|
895
940
|
self.tidys.append(rec)
|
|
896
941
|
self.tidys = self.tidys[-20:]
|
|
942
|
+
self._tick_conformance()
|
|
897
943
|
|
|
944
|
+
# 生效条件:把 conformance.report_summary(self.cg) 的结论写入 self.last_conformance;该调用抛异常时写入 {"ok": False, "verdict": "BLINDSPOT", "error": "<类型名>: <消息>"};
|
|
945
|
+
def _tick_conformance(self):
|
|
946
|
+
"""数据健康不变量断言集(Pi⑤)——与 tidy 同节奏,**只取结论**。
|
|
947
|
+
|
|
948
|
+
复用 tidy 的 6h 节奏而不新开周期:两者都是「存量数据体检」,且都是
|
|
949
|
+
只读巡检。纪律:本断言集**只告警不改数据**,故 `auto_*` 在此无意义;
|
|
950
|
+
`check_paths=False` 跳过 1.1 万次 stat,`_audit.jsonl` 只读尾窗。
|
|
951
|
+
"""
|
|
952
|
+
from . import conformance
|
|
953
|
+
try:
|
|
954
|
+
self.last_conformance = conformance.report_summary(self.cg)
|
|
955
|
+
except Exception as e: # noqa: BLE001
|
|
956
|
+
self.last_conformance = {"ok": False, "verdict": "BLINDSPOT",
|
|
957
|
+
"error": f"{type(e).__name__}: {e}"}
|
|
958
|
+
|
|
959
|
+
# 生效条件:恒以 evolution_candidates(self.cg) 只读盘点并记入 last_evolve 与 evolves(保留最近 20 条);仅当 self.auto_evolve 为真且 ev["importance_drift"]["n"] 为真时才额外执行 weights.recalc(self.cg, apply=True, actor="sustain_evolve"),其异常写入 rec["applied"];
|
|
898
960
|
def _tick_evolve(self):
|
|
899
961
|
"""演化巡检(G7):盘点固化/重要性候选 —— 让「有能力」变成「有驱动」。
|
|
900
962
|
|
|
@@ -921,6 +983,7 @@ class SustainLoop:
|
|
|
921
983
|
self.evolves.append(rec)
|
|
922
984
|
self.evolves = self.evolves[-20:]
|
|
923
985
|
|
|
986
|
+
# 生效条件:以 dry_run=not self.auto_scrub 调 scrub.sweep(self.cg),把 t/ok/n_issues/n_high_medium/applied/dry_run 记入 last_scrub 与 scrubs(保留最近 20 条);auto_scrub=False(默认)时 dry_run=True 只读巡检;
|
|
924
987
|
def _tick_scrub(self):
|
|
925
988
|
"""记忆自净:抽查 → 联想 → 去污染 → 校准偏差。
|
|
926
989
|
|
|
@@ -939,6 +1002,7 @@ class SustainLoop:
|
|
|
939
1002
|
self.scrubs.append(rec)
|
|
940
1003
|
self.scrubs = self.scrubs[-20:]
|
|
941
1004
|
|
|
1005
|
+
# 生效条件:先 diagnose(self.cg, name=self.name) 并将 ok 与 issues code 记入 last_diagnose;仅当 self.auto_heal 为真且 rep["ok"] 为假时才调 heal(self.cg, name=self.name),其 actions 非空时把各 action 的 code 记入 heals(保留最近 20 条);
|
|
942
1006
|
def _tick_heal(self):
|
|
943
1007
|
rep = diagnose(self.cg, name=self.name)
|
|
944
1008
|
self.last_diagnose = {"t": time.time(), "ok": rep["ok"],
|
|
@@ -954,6 +1018,7 @@ class SustainLoop:
|
|
|
954
1018
|
|
|
955
1019
|
# ---- 状态 ----
|
|
956
1020
|
|
|
1021
|
+
# 生效条件:以 read_stamp(self.name, self.d) 判定 state(有戳走 judge(age, interval=self.beat_interval, task_running=...),无戳为 "stopped"),返回含 name/running/pid/uptime(无 _started_at 时为 0.0)/beats/last_beat/各 interval 与 auto_* 开关/heals[-5:]/evolves[-5:]/tidys[-5:]/peers(self.d)/ledger.summary() 的 dict;
|
|
957
1022
|
def status(self) -> dict:
|
|
958
1023
|
st = read_stamp(self.name, self.d)
|
|
959
1024
|
state = (judge(st["age"], interval=self.beat_interval,
|
|
@@ -980,6 +1045,7 @@ class SustainLoop:
|
|
|
980
1045
|
"evolves": self.evolves[-5:],
|
|
981
1046
|
"last_tidy": self.last_tidy,
|
|
982
1047
|
"tidys": self.tidys[-5:],
|
|
1048
|
+
"last_conformance": self.last_conformance,
|
|
983
1049
|
"peers": peers(self.d),
|
|
984
1050
|
"sessions": self.ledger.summary()}
|
|
985
1051
|
|
|
@@ -988,6 +1054,7 @@ _LOOPS = {}
|
|
|
988
1054
|
_LOOPS_LOCK = threading.Lock()
|
|
989
1055
|
|
|
990
1056
|
|
|
1057
|
+
# 生效条件:cg 必填,以 (os.path.abspath(cg.root), name) 为键在模块级 _LOOPS 中复用已有实例或新建 SustainLoop 并返回该实例。
|
|
991
1058
|
def ensure_loop(cg, name: str = "md_cg", **kw) -> SustainLoop:
|
|
992
1059
|
"""按 (root, name) 复用同一个常驻循环(避免重复线程 / 重复戳)。"""
|
|
993
1060
|
key = (os.path.abspath(cg.root), name)
|
|
@@ -999,10 +1066,12 @@ def ensure_loop(cg, name: str = "md_cg", **kw) -> SustainLoop:
|
|
|
999
1066
|
return lp
|
|
1000
1067
|
|
|
1001
1068
|
|
|
1069
|
+
# 生效条件:cg 必填,返回 _LOOPS[(os.path.abspath(cg.root), name)],该键未登记时返回 None。
|
|
1002
1070
|
def get_loop(cg, name: str = "md_cg"):
|
|
1003
1071
|
return _LOOPS.get((os.path.abspath(cg.root), name))
|
|
1004
1072
|
|
|
1005
1073
|
|
|
1074
|
+
# 生效条件:模块级 _LOOPS 非空时清空该表并对每个循环调用 stop()(异常被吞),无返回值。
|
|
1006
1075
|
def stop_all():
|
|
1007
1076
|
"""测试 / 进程退出用:停掉本进程创建的所有常驻循环。"""
|
|
1008
1077
|
with _LOOPS_LOCK:
|
|
@@ -1015,6 +1084,7 @@ def stop_all():
|
|
|
1015
1084
|
pass
|
|
1016
1085
|
|
|
1017
1086
|
|
|
1087
|
+
# 生效条件:以 read_stamp(name) 有戳时返回 heartbeat={'age': round(st["age"],1), 'state': judge(...), 'pid', 'task_running'}、无戳时 {'state':'absent'},loop 取 get_loop(cg, name) 有值时给 running/beats/state、无值时 {'running': False},并附带 SessionLedger(cg.root).summary()、scrub_summary(cg)、evolve_summary(cg)、provenance_summary(cg);
|
|
1018
1088
|
def summary(cg, name: str = "md_cg") -> dict:
|
|
1019
1089
|
"""并入 health_os 的轻量摘要(只读戳与计数,不做巡检)。"""
|
|
1020
1090
|
st = read_stamp(name)
|
|
@@ -1036,6 +1106,7 @@ def summary(cg, name: str = "md_cg") -> dict:
|
|
|
1036
1106
|
}
|
|
1037
1107
|
|
|
1038
1108
|
|
|
1109
|
+
# 生效条件:cg 必填,可导入 provenance 且其 summary(cg) 调用成功时返回该摘要,异常时返回 {}。
|
|
1039
1110
|
def provenance_summary(cg) -> dict:
|
|
1040
1111
|
"""派生溯源摘要(G8,只读;失败不抛,避免拖垮 health_os)。"""
|
|
1041
1112
|
try:
|
|
@@ -1045,6 +1116,7 @@ def provenance_summary(cg) -> dict:
|
|
|
1045
1116
|
return {}
|
|
1046
1117
|
|
|
1047
1118
|
|
|
1119
|
+
# 生效条件:cg 必填,evolution_candidates(cg, top=3) 成功时返回 candidates/ccg_backlog/importance_drift 计数摘要,异常时返回 {}。
|
|
1048
1120
|
def evolve_summary(cg) -> dict:
|
|
1049
1121
|
"""演化巡检摘要(只读;失败不抛,避免拖垮 health_os)。"""
|
|
1050
1122
|
try:
|
|
@@ -1057,10 +1129,11 @@ def evolve_summary(cg) -> dict:
|
|
|
1057
1129
|
return {}
|
|
1058
1130
|
|
|
1059
1131
|
|
|
1132
|
+
# 生效条件:cg 必填,可导入 scrub 且其 summary(cg) 调用成功时返回该摘要,异常时返回 {}。
|
|
1060
1133
|
def scrub_summary(cg) -> dict:
|
|
1061
1134
|
"""记忆自净摘要(惰性导入,避免模块加载顺序耦合)。"""
|
|
1062
1135
|
try:
|
|
1063
1136
|
from . import scrub
|
|
1064
1137
|
return scrub.summary(cg)
|
|
1065
1138
|
except Exception: # noqa: BLE001
|
|
1066
|
-
return {}
|
|
1139
|
+
return {}
|