@furongjun1999/dsh-memory 0.4.11 → 0.5.0
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 +16 -16
- package/codebuddy/CODEBUDDY.md +11 -3
- package/codebuddy/README.md +92 -90
- package/codebuddy/mcp.json +27 -27
- package/docs/GBrain/345/217/257/345/200/237/351/211/264/347/202/271_/347/201/265/346/236/242/350/220/275/347/202/271/344/272/244/346/216/245_20260919.md +169 -169
- package/docs/Pi/345/217/257/345/255/246/344/271/240/344/274/230/347/202/271_/347/201/265/346/236/242/345/244/247/350/204/221/346/224/271/350/277/233/344/272/244/346/216/245_20260915.md +144 -144
- package/docs/README.md +142 -111
- package/docs/discipline/harnesses.yaml +244 -226
- package/docs/discipline/templates/full.md.tmpl +61 -61
- package/docs/discipline/templates/rules.mdc.tmpl +68 -0
- package/docs/discipline/templates/skill.md.tmpl +23 -23
- package/docs/eval/AGI/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v1.0.md +299 -299
- package/docs/eval/AGI/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v2.0.md +239 -239
- package/docs/eval//345/256/236/351/252/214/346/226/271/346/241/210_/345/255/246/344/271/240/351/227/255/347/216/257AB/344/270/216/346/250/252/350/257/204_v1.0.md +174 -174
- package/docs/eval//346/250/252/350/257/204_/345/205/255/345/256/266100/351/242/230/344/270/255/350/213/261/345/217/214/346/237/245_v1.0.md +223 -223
- package/docs/{mdcg → hive}//344/273/244/347/211/214/344/270/216/350/247/222/350/211/262/346/235/203/350/201/214/345/210/206/347/246/273_v0.1.md +165 -160
- package/docs/hive//344/273/244/347/211/214/350/257/255/344/271/211/344/277/256/346/255/243_/344/273/262/350/243/201/344/275/215_v0.1.md +76 -0
- package/docs/{mdcg → hive}//345/255/220/344/273/243/347/220/206/351/205/215/347/275/256/346/240/207/345/207/206_v0.5.md +236 -236
- package/docs/hive//346/243/200/347/264/242/346/224/266/346/225/233/345/256/236/346/265/213/344/270/216S1b/350/256/276/350/256/241_v0.1.md +43 -43
- package/docs/hive//346/243/200/347/264/242/347/256/227/346/263/225/345/217/243/345/276/204/345/257/271/347/205/247_v0.1.md +85 -0
- package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +102 -102
- package/docs/hive//350/234/202/345/267/242M6_ingest/345/256/236/346/226/275/350/256/241/345/210/222_v0.1.md +47 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +503 -503
- package/docs/hive//350/234/202/345/267/242/345/267/245/344/275/234/350/256/260/345/277/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +85 -85
- package/docs/hive//350/234/202/345/267/242/350/256/276/350/256/241_/347/220/206/350/256/272/345/257/271/351/275/220_v0.1.md +191 -0
- package/docs/hive//350/234/202/345/267/242/350/277/255/344/273/243_/345/256/217/350/247/202/344/270/216/347/276/244/344/275/223/350/260/203/345/272/246_v0.1.md +90 -0
- package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -216
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +646 -646
- package/docs/mdcg/lingshu_tutorial.html +14449 -14449
- package/docs/mdcg/release_v0.4.11.md +49 -0
- package/docs/mdcg/release_v0.4.5.md +55 -55
- package/docs/mdcg/tool_table_v0.3.0.md +117 -117
- package/docs/mdcg//345/205/250/345/272/223/344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/350/256/241/345/210/222_v0.1.md +600 -600
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
- package/docs/mdcg//345/215/225/345/205/203/350/207/252/346/210/221/351/224/232/347/202/271_/347/263/273/347/273/237/346/217/220/347/244/272/350/257/215/346/240/207/345/207/206_v0.3.md +275 -275
- package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +54 -0
- package/docs/mdcg//346/272/220/347/240/201/347/272/247/346/236/266/346/236/204/345/256/241/350/256/241_GPT/346/211/271/350/257/204/345/257/271/347/205/247_v1.0.md +130 -130
- package/docs/mdcg//347/201/265/346/236/24282/345/267/245/345/205/267_/345/212/237/350/203/275/346/225/264/347/220/206/344/270/216/350/277/201/347/247/273/346/230/240/345/260/204_v0.1.md +278 -278
- package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +172 -172
- package/docs/mdcg//347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +270 -270
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_G4-G8/347/274/272/345/217/243/350/243/201/345/256/232/345/215/225_v0.1.md +491 -491
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_/346/235/241/344/273/266/347/251/272/351/227/264/345/220/210/346/210/220/344/270/216/347/224/237/346/225/210/346/235/241/344/273/266/345/217/243/345/276/204_v0.1.md +340 -340
- package/docs/mdcg//350/256/244/347/237/245/345/233/276_/347/264/242/345/274/225/344/270/216/345/267/245/347/250/213/350/247/204/350/214/203/345/214/226_/350/256/241/345/210/222_v0.1.md +588 -588
- package/docs/plans/GridWorld/346/234/200/345/260/217/351/227/255/347/216/257/350/247/204/346/240/274_v0.1.md +176 -176
- package/docs/plans//345/221/275/345/220/215/346/262/273/347/220/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +81 -81
- package/docs/swarm//350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +704 -704
- package/docs/swarm//350/234/202/347/276/244/345/220/214/351/224/231/346/243/200/346/265/213/345/256/236/351/252/214/345/215/217/350/256/256_v0.1.md +242 -242
- package/docs/theory//345/215/225/347/272/277/347/250/213/344/270/216/346/263/250/346/204/217/345/212/233/351/233/206/344/270/255_/346/227/240/344/272/211/350/256/256/347/220/206/350/256/272/346/226/207/346/241/243_v1.0.md +129 -129
- package/docs/theory//345/271/266/345/217/221/345/277/205/347/204/266/346/200/247/347/220/206/350/256/272_v0.2.md +134 -134
- package/docs/theory//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- package/docs/theory//346/246/202/345/277/265/345/210/206/345/261/202/345/257/271/351/275/220/350/241/250_v0.1.md +145 -145
- package/docs/theory//347/220/206/350/256/272_/346/234/272/345/210/266_/344/273/243/347/240/201_/345/256/236/351/252/214_/347/274/272/345/217/243/347/237/251/351/230/265_v0.1.md +144 -144
- package/docs/theory//347/220/206/350/256/272/344/273/223/346/213/206/345/210/206/344/270/216/347/231/275/347/256/261/347/237/245/350/257/206/345/272/223/345/206/205/350/277/201_v0.1.md +198 -198
- package/docs/theory//350/256/244/347/237/245/344/273/243/347/220/206/344/270/216/346/224/266/346/225/233/347/273/223/346/236/204_/346/235/241/344/273/266/350/256/272/351/207/215/346/236/204_v0.1.md +221 -221
- package/docs/world_model//344/270/226/347/225/214/346/250/241/345/236/213_/347/245/236/347/273/217/347/275/221/347/273/234/345/272/225/345/261/202/346/236/266/346/236/204_v1.0.md +237 -237
- package/docs//345/217/221/345/270/203/344/273/266/345/233/236/346/272/257/350/257/264/346/230/216_v0.1.md +82 -82
- package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +28 -2
- package/dsh/README.md +82 -82
- package/dsh/cordis.yml.example +139 -139
- package/dsh/update-lingshu.bat +11 -11
- package/lib/hooks.js +36 -2
- package/lib/lib/roleplay_web.js +427 -427
- package/md_cg/__init__.py +7 -7
- package/md_cg/audit.py +368 -368
- package/md_cg/autonomy.py +287 -287
- package/md_cg/backfill.py +1327 -1327
- package/md_cg/backfill_bigdomain.py +34 -34
- package/md_cg/bench6_arms.py +410 -410
- package/md_cg/bench6_common.py +230 -230
- package/md_cg/bench6_competitors.py +212 -212
- package/md_cg/bench_axis_domain.py +257 -257
- package/md_cg/bench_blind_comp.py +308 -308
- package/md_cg/bench_en_atoms_public.py +230 -230
- package/md_cg/bench_governance.py +348 -348
- package/md_cg/bench_lme_zh.py +410 -410
- package/md_cg/bench_locomo.py +121 -121
- package/md_cg/bench_locomo_zh.py +450 -450
- package/md_cg/bench_locomo_zh_public.py +147 -147
- package/md_cg/bench_longmem.py +112 -112
- package/md_cg/bench_membench.py +632 -632
- package/md_cg/bench_p0.py +149 -149
- package/md_cg/bench_progressive.py +287 -287
- package/md_cg/bench_role_views.py +238 -238
- package/md_cg/bench_task_ab.py +243 -243
- package/md_cg/bench_task_ab_llm.py +408 -408
- package/md_cg/bench_unified_en.py +204 -204
- package/md_cg/bench_zh_mad.py +601 -601
- package/md_cg/blindspot_tickets.py +123 -123
- package/md_cg/branches.py +285 -285
- package/md_cg/build_postings.py +73 -73
- package/md_cg/ccgc.py +1005 -948
- package/md_cg/census.py +132 -132
- package/md_cg/chain.py +300 -300
- package/md_cg/codeindex.py +531 -531
- package/md_cg/coldverify.py +292 -292
- package/md_cg/comment_gate.py +337 -337
- package/md_cg/cond_compose.py +190 -190
- package/md_cg/cond_facts.py +154 -154
- package/md_cg/cond_template.json +106 -106
- package/md_cg/condition_anchor.py +142 -142
- package/md_cg/conformance.py +726 -726
- package/md_cg/consistency.py +717 -717
- package/md_cg/consolidate.py +1536 -1439
- package/md_cg/corpus.py +110 -110
- package/md_cg/crosscheck.py +1097 -1097
- package/md_cg/crypto.py +437 -437
- package/md_cg/d_meta.py +310 -310
- package/md_cg/datapath.py +334 -334
- package/md_cg/docindex.py +473 -473
- package/md_cg/eval_common.py +575 -575
- package/md_cg/evidence.py +580 -580
- package/md_cg/evolution.py +477 -477
- package/md_cg/export.py +220 -220
- package/md_cg/forgetting.py +581 -581
- package/md_cg/fsutil.py +329 -329
- package/md_cg/hotcache.py +238 -214
- package/md_cg/hyperedge.py +251 -251
- package/md_cg/identity.py +390 -390
- package/md_cg/insight.py +500 -500
- package/md_cg/interop.py +199 -0
- package/md_cg/lexicon/build_cedict_en_zh.py +329 -329
- package/md_cg/lexicon/build_standard_en.py +171 -171
- package/md_cg/lexicon/expand_en_zh.py +211 -211
- package/md_cg/lifecycle.py +272 -272
- package/md_cg/linkref.py +280 -280
- package/md_cg/links.py +622 -622
- package/md_cg/mcp_server.py +129 -32
- package/md_cg/md_whitebox.py +345 -345
- package/md_cg/mdcg.py +176 -117
- package/md_cg/mdcos.py +79 -13
- package/md_cg/metacognition.py +591 -591
- package/md_cg/migrate.py +119 -119
- package/md_cg/migrate_aeis.py +221 -221
- package/md_cg/migrate_roleplay.py +293 -293
- package/md_cg/migrate_wisdom_graph.py +360 -360
- package/md_cg/mreview/__init__.py +25 -25
- package/md_cg/mreview/__main__.py +110 -110
- package/md_cg/mreview/bundle.py +178 -178
- package/md_cg/mreview/candidates.py +262 -262
- package/md_cg/mreview/govern.py +693 -693
- package/md_cg/mreview/locate.py +939 -939
- package/md_cg/mreview/pipeline.py +728 -728
- package/md_cg/mreview/rules/duplication.json +21 -21
- package/md_cg/mreview/rules/field_coverage.json +54 -54
- package/md_cg/mreview/rules/source_license.json +21 -21
- package/md_cg/mreview/rules/template_flow.json +21 -21
- package/md_cg/mreview/ruleset.py +252 -252
- package/md_cg/nodefile.py +575 -575
- package/md_cg/pooling.py +484 -472
- package/md_cg/postings.py +298 -298
- package/md_cg/predict.py +1100 -1100
- package/md_cg/progressive.py +123 -123
- package/md_cg/protect.py +272 -272
- package/md_cg/protocol/md_cg_gate.proto +33 -33
- package/md_cg/protocol.py +372 -372
- package/md_cg/provenance.py +582 -582
- package/md_cg/reach.py +453 -453
- package/md_cg/readcache.py +85 -0
- package/md_cg/refindex.py +833 -833
- package/md_cg/refine.py +604 -604
- package/md_cg/roleviews.py +89 -89
- package/md_cg/routing.py +365 -365
- package/md_cg/scrub.py +852 -852
- package/md_cg/security.py +274 -274
- package/md_cg/self_state.py +1029 -1029
- package/md_cg/selfreport.py +151 -151
- package/md_cg/semantic/__init__.py +10 -10
- package/md_cg/semantic/canonical.py +122 -122
- package/md_cg/semantic/en_normalizer.py +364 -364
- package/md_cg/semantic/en_zh_map.json +28694 -0
- package/md_cg/semantic/export_en_zh_map.py +64 -0
- package/md_cg/semantic/unify.py +45 -0
- package/md_cg/semantic/zh_en_atoms.py +139 -139
- package/md_cg/signer.py +562 -562
- package/md_cg/sources.py +815 -582
- package/md_cg/statushdr.py +179 -179
- package/md_cg/stg.py +48 -37
- package/md_cg/subgraph.py +729 -729
- package/md_cg/sustain.py +1138 -1138
- package/md_cg/tasks.py +470 -470
- package/md_cg/test_action_derive.py +203 -203
- package/md_cg/test_audit_rotate.py +270 -270
- package/md_cg/test_autonomy.py +143 -143
- package/md_cg/test_bench_governance.py +102 -102
- package/md_cg/test_blindspot_tickets.py +166 -166
- package/md_cg/test_branches.py +249 -249
- package/md_cg/test_ccg_perturb.py +184 -184
- package/md_cg/test_ccgc.py +433 -433
- package/md_cg/test_census_prune.py +81 -81
- package/md_cg/test_cond_compose_anchors.py +76 -76
- package/md_cg/test_cond_match.py +165 -165
- package/md_cg/test_condition_anchor.py +81 -81
- package/md_cg/test_d_meta.py +412 -412
- package/md_cg/test_datapath_root.py +199 -199
- package/md_cg/test_en_pipeline.py +166 -166
- package/md_cg/test_gain_gate.py +212 -212
- package/md_cg/test_health_scale.py +173 -173
- package/md_cg/test_hive_ingest.py +285 -0
- package/md_cg/test_hot_cold.py +215 -215
- package/md_cg/test_hyperedge.py +245 -245
- package/md_cg/test_i26_empty_first_write.py +116 -0
- package/md_cg/test_i27_e041_identity.py +128 -0
- package/md_cg/test_i28_hotcache_prodpath.py +122 -0
- package/md_cg/test_identity_attribution.py +147 -147
- package/md_cg/test_index_durability.py +224 -224
- package/md_cg/test_interop.py +93 -0
- package/md_cg/test_lifecycle.py +309 -309
- package/md_cg/test_linkref.py +306 -306
- package/md_cg/test_lock.py +43 -43
- package/md_cg/test_md_access_parity.py +255 -255
- package/md_cg/test_md_writepath.py +345 -345
- package/md_cg/test_mdstore_search_parity.py +160 -0
- package/md_cg/test_mr_m2.py +587 -587
- package/md_cg/test_mr_m3.py +710 -710
- package/md_cg/test_mr_m4.py +485 -485
- package/md_cg/test_p0.py +250 -250
- package/md_cg/test_p1.py +316 -316
- package/md_cg/test_p10_identity.py +173 -173
- package/md_cg/test_p11_consistency.py +233 -233
- package/md_cg/test_p12_metacognition.py +212 -212
- package/md_cg/test_p13_encryption.py +241 -241
- package/md_cg/test_p14_sustain.py +249 -249
- package/md_cg/test_p15_scrub.py +280 -280
- package/md_cg/test_p16_self_state.py +301 -301
- package/md_cg/test_p17_predict.py +354 -354
- package/md_cg/test_p18_whitebox.py +171 -171
- package/md_cg/test_p19_migrate_roleplay.py +149 -149
- package/md_cg/test_p20_evolution.py +315 -315
- package/md_cg/test_p21_tokens.py +293 -270
- package/md_cg/test_p22_theory.py +175 -175
- package/md_cg/test_p23_links.py +311 -311
- package/md_cg/test_p24_evidence.py +227 -227
- package/md_cg/test_p25_weights.py +156 -156
- package/md_cg/test_p26_refindex.py +416 -416
- package/md_cg/test_p27_docindex.py +765 -765
- package/md_cg/test_p28_refcheck.py +305 -305
- package/md_cg/test_p29_session_ingest_export.py +354 -333
- package/md_cg/test_p3.py +11 -2
- package/md_cg/test_p30_maintain.py +330 -330
- package/md_cg/test_p31_insight.py +534 -534
- package/md_cg/test_p32_backfill.py +298 -298
- package/md_cg/test_p33_ccg_wiring.py +293 -293
- package/md_cg/test_p34_crosscheck.py +331 -331
- package/md_cg/test_p35_conditioned_claim.py +252 -252
- package/md_cg/test_p36_kp_align.py +230 -230
- package/md_cg/test_p37_condition_space.py +248 -248
- package/md_cg/test_p38_concurrent_flush.py +102 -0
- package/md_cg/test_p38_contextualize.py +273 -273
- package/md_cg/test_p39_verify_flow.py +113 -0
- package/md_cg/test_p39_vision_evidence.py +369 -369
- package/md_cg/test_p40_refine_worklist.py +241 -241
- package/md_cg/test_p41_evolve_patrol.py +224 -224
- package/md_cg/test_p42_provenance.py +269 -269
- package/md_cg/test_p43_pooling.py +412 -398
- package/md_cg/test_p44_md_whitebox.py +231 -231
- package/md_cg/test_p45_session_identity.py +219 -219
- package/md_cg/test_p46_unit_scope.py +272 -272
- package/md_cg/test_p47_session_view.py +281 -0
- package/md_cg/test_p4_fuzzy.py +223 -223
- package/md_cg/test_p5_semantic.py +226 -226
- package/md_cg/test_p6_consolidate.py +440 -387
- package/md_cg/test_p7_goals_recent.py +202 -202
- package/md_cg/test_p8_subgraph_chain.py +200 -200
- package/md_cg/test_p9_forget_protect.py +231 -231
- package/md_cg/test_predict_beta.py +135 -135
- package/md_cg/test_preflight_failclosed.py +100 -100
- package/md_cg/test_progressive.py +146 -146
- package/md_cg/test_protocol.py +243 -243
- package/md_cg/test_reach.py +378 -378
- package/md_cg/test_reach_keys.py +201 -201
- package/md_cg/test_read_clip.py +141 -141
- package/md_cg/test_readcache_prodpath.py +155 -0
- package/md_cg/test_retr_gates_prodpath.py +140 -0
- package/md_cg/test_retr_s1.py +340 -340
- package/md_cg/test_retr_s1b.py +209 -209
- package/md_cg/test_retr_s3.py +194 -194
- package/md_cg/test_retr_s4.py +163 -163
- package/md_cg/test_retr_s5.py +200 -200
- package/md_cg/test_retr_s6.py +157 -157
- package/md_cg/test_retr_s7.py +384 -384
- package/md_cg/test_retr_s8_time.py +369 -316
- package/md_cg/test_retr_s9_edges.py +286 -286
- package/md_cg/test_retr_s9_entity_ctx.py +175 -175
- package/md_cg/test_review_conformance.py +367 -367
- package/md_cg/test_role_views.py +354 -354
- package/md_cg/test_sem_noise.py +242 -242
- package/md_cg/test_semantic_canonical.py +241 -241
- package/md_cg/test_subproc_encoding.py +192 -192
- package/md_cg/test_sustain_mutual.py +153 -153
- package/md_cg/test_tasks.py +409 -409
- package/md_cg/test_tool_face.py +189 -189
- package/md_cg/test_transfer.py +180 -180
- package/md_cg/test_trust.py +361 -361
- package/md_cg/test_twophase.py +286 -286
- package/md_cg/test_v14_fixes.py +397 -397
- package/md_cg/test_validity_filter.py +280 -280
- package/md_cg/test_verify_answer.py +138 -138
- package/md_cg/test_wisdom_md_store.py +292 -292
- package/md_cg/test_writelimit.py +197 -197
- package/md_cg/test_writepipe.py +214 -214
- package/md_cg/theory.py +273 -273
- package/md_cg/tokens.py +677 -663
- package/md_cg/tool_face.py +260 -260
- package/md_cg/trust.py +986 -950
- package/md_cg/twophase.py +231 -231
- package/md_cg/units.py +667 -667
- package/md_cg/vision_evidence.py +666 -666
- package/md_cg/weights.py +624 -624
- package/md_cg/whitebox.py +527 -527
- package/md_cg/whitebox_kb/__init__.py +37 -37
- package/md_cg/whitebox_kb/aeis_core/__init__.py +42 -42
- package/md_cg/whitebox_kb/aeis_core/semantic.py +280 -280
- package/md_cg/whitebox_kb/aeis_core/textutil.py +13 -13
- package/md_cg/whitebox_kb/engine.py +310 -310
- package/md_cg/whitebox_kb/seed_knowledge//346/231/272/350/203/275/350/256/2723.4.md +5260 -5260
- package/md_cg/whitebox_kb/wisdom/browser_units.py +2631 -2631
- package/md_cg/whitebox_kb/wisdom/causal_discover.py +432 -432
- package/md_cg/whitebox_kb/wisdom/chat_engine.py +1506 -1506
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
- package/md_cg/whitebox_kb/wisdom/compiler_code_units.py +3033 -3033
- package/md_cg/whitebox_kb/wisdom/condition_algebra.py +112 -112
- package/md_cg/whitebox_kb/wisdom/condition_frame.py +315 -315
- package/md_cg/whitebox_kb/wisdom/condition_kb.py +108 -108
- package/md_cg/whitebox_kb/wisdom/conflict_map.json +4445 -4445
- package/md_cg/whitebox_kb/wisdom/core/lexer.py +512 -512
- package/md_cg/whitebox_kb/wisdom/core/name_checker.py +1023 -1023
- package/md_cg/whitebox_kb/wisdom/cspmn.py +258 -258
- package/md_cg/whitebox_kb/wisdom/csre.py +264 -264
- package/md_cg/whitebox_kb/wisdom/danmaku_audit.py +252 -252
- package/md_cg/whitebox_kb/wisdom/distilled_condition_units.json +6417 -6417
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902b.json +1950 -1950
- package/md_cg/whitebox_kb/wisdom/docs/WB-EVAL-20260902c.json +1296 -1296
- package/md_cg/whitebox_kb/wisdom/docs/whitebox_capability_graph_demo.json +59 -59
- package/md_cg/whitebox_kb/wisdom/graph_db_units.py +3089 -3089
- package/md_cg/whitebox_kb/wisdom/knowledge_points.py +318 -318
- package/md_cg/whitebox_kb/wisdom/md_access.py +470 -470
- package/md_cg/whitebox_kb/wisdom/md_store.py +276 -251
- package/md_cg/whitebox_kb/wisdom/migrate_wisdom.py +476 -476
- package/md_cg/whitebox_kb/wisdom/navigate.py +248 -248
- package/md_cg/whitebox_kb/wisdom/neural_retrieve.py +224 -224
- package/md_cg/whitebox_kb/wisdom/os_units.py +2735 -2735
- package/md_cg/whitebox_kb/wisdom/pattern_separation.py +376 -376
- package/md_cg/whitebox_kb/wisdom/prereq_map.json +364 -364
- package/md_cg/whitebox_kb/wisdom/python_code_units.py +2766 -2766
- package/md_cg/whitebox_kb/wisdom/role_solidified.json +7 -7
- package/md_cg/whitebox_kb/wisdom/route_memory.py +244 -244
- package/md_cg/whitebox_kb/wisdom/scene_reconstruction.py +148 -148
- package/md_cg/whitebox_kb/wisdom/snr_report.json +40 -40
- package/md_cg/whitebox_kb/wisdom/test_code_compose_domains.py +7541 -7541
- package/md_cg/whitebox_kb/wisdom/test_compiler_self_bootstrap.py +354 -354
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_assembly.py +158 -158
- package/md_cg/whitebox_kb/wisdom/test_ecosystem_demos.py +193 -193
- package/md_cg/whitebox_kb/wisdom/test_graph_db.py +292 -292
- package/md_cg/whitebox_kb/wisdom/test_python_self_bootstrap.py +160 -160
- package/md_cg/whitebox_kb/wisdom/trigger_words_index.json +4366 -4366
- package/md_cg/whitebox_kb/wisdom/verifier.py +1297 -1297
- package/md_cg/writelimit.py +356 -356
- package/md_cg/writepipe.py +550 -542
- package/package.json +97 -96
- package/skills/plugin.json +54 -54
- package/skills/skills/designer-perspective/SKILL.md +158 -158
- package/skills/skills/designer-perspective/references/01-observation-position.md +66 -66
- package/skills/skills/designer-perspective/references/02-structure-recognition.md +62 -62
- package/skills/skills/designer-perspective/references/03-direction-judgment.md +55 -55
- package/skills/skills/designer-perspective/references/04-qualification-verdict.md +72 -72
- package/skills/skills/designer-perspective/references/05-condition-attribution.md +74 -74
- package/skills/skills/designer-perspective/scripts/designer.py +545 -545
- package/skills/skills/designer-perspective/tests/cases.jsonl +17 -17
- package/skills/skills/designer-perspective/tests/selftest.py +61 -61
- package/skills/skills/lingshu-browser/SKILL.md +60 -60
- package/skills/skills/lingshu-compiler/SKILL.md +56 -56
- package/skills/skills/lingshu-compiler/units/analyze-type-infer/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/check-name-real/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-assign/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-expr-tree/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-full-pipeline/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-func-def/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-if-then/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-logic-expr/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-recursive/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-scope/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-type-check/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compile-while/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0010c4bf/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0355bffb/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0361708a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-054a0414/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05a1691a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-05eeed1e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0622a1f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-08b54217/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0a62b70c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ab24d00/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e093688/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0e82b966/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0ee9b9b9/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-0f3787e6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1028685f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-11897630/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-16661b9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-1f722303/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-25be1262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2a76ba07/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2dbea54a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2df52f16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2ec2c9d2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-2f8c8f39/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-38378ac7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39457d2e/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-39fb5926/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-47f4fbfa/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4a8cd1f1/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4b230b6b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4cbbda95/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-4d5a68ff/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-56dc9bdd/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-57e76ebe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-61ff016b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-63eae588/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-64c4224b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-66377955/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-674ab4f6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6af76fd6/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6d979db2/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6de326c0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-6f1c0eea/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-724d6c9b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7690177f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7b229a7d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-7f471b3a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-815cad08/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-83c61634/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8c798c81/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-8dd747ac/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-90324d0a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94b8d72d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-94f12231/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-95937c16/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98a5625b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98b4c42f/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-98e3894a/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9bdfe4b8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9d9b4e83/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-9f7be5ad/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a6daf076/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a7995a0c/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-a8399248/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-aabbd099/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-afe169d8/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b0678bda/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b09bd196/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b1396e23/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-b9b31ce0/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-c10264a7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cb1e8e4b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ccafd438/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cda9c262/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ce648068/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-cf5776a4/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-d974e5d3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-e3979fd3/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-eb1cf2b5/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-ecb30d5b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f8c8b24b/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-f99fedbe/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fa8ff5f7/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/compiler-fe1b058d/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-chinese-program/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-dao-de-jing/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/lex-nine-chapters/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-arithmetic/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-array-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-closure-create/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-compare/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-jump/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-cond-space/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-exception/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-func-call/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-loop-run/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-profiling/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-refcount/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-run-loop/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-short-circuit/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-guard/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-stack-ops/SKILL.md +45 -45
- package/skills/skills/lingshu-compiler/units/vm-trust-accum/SKILL.md +45 -45
- package/skills/skills/lingshu-graph/SKILL.md +63 -63
- package/skills/skills/lingshu-net/SKILL.md +48 -48
- package/skills/skills/lingshu-os/SKILL.md +64 -64
- package/skills/skills/lingshu-pylang/SKILL.md +71 -71
- package/src/bridge.ts +401 -401
- package/src/hooks.ts +38 -2
- package/src/lib/datapath.ts +326 -326
- package/src/lib/mdcg_client.ts +413 -413
- package/src/lib/mutual.ts +428 -428
- package/src/lib/prompt_safety.ts +62 -62
- package/src/lib/python_path.ts +71 -71
- package/src/lib/roleplay_web.ts +932 -932
- package/src/lib/token_store.ts +192 -192
- package/src/tools.ts +212 -212
- package/zcode/AGENTS.md +11 -3
- package/zcode/README.md +41 -41
- /package/docs/{mdcg → hive}//344/270/273/344/273/243/347/220/206/345/255/220/344/273/243/347/220/206/350/256/260/345/277/206/346/236/266/346/236/204/350/256/276/350/256/241.md" +0 -0
package/md_cg/test_ccgc.py
CHANGED
|
@@ -1,433 +1,433 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""ccgc 验收:对话记录 → CCG 六要素编译器(V1-V20)。
|
|
3
|
-
|
|
4
|
-
运行:python -m md_cg.test_ccgc
|
|
5
|
-
|
|
6
|
-
三条判据在实现层为何是**机械可判定**的(不依赖自觉):
|
|
7
|
-
① 「LLM 不得自己验证自己」——候选结构里没有签章字段,且 attest 机械比对
|
|
8
|
-
`verifier != compiled_by`(E041);link 再挡一次(双闸)。
|
|
9
|
-
② 「幻觉」——名实门 E010/E011:每个写入值必须是源文本字面子串,零灰区。
|
|
10
|
-
③ 「缺参数」——是编译错误(E001-E004)而非 DEFER,`success = (errors == [])`。
|
|
11
|
-
|
|
12
|
-
V16-V20 覆盖**跨调用形态**(三次独立 MCP 调用传不动对象,只能落盘):
|
|
13
|
-
候选与签章绑定在 `_ccgc_pending/`(hash 防篡改)+ 复核通道三态 + 蜂巢契约
|
|
14
|
-
端到端(假执行器模拟 serve,无网络无密钥也能确定性验收「通道与签章」)。
|
|
15
|
-
"""
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
import json
|
|
19
|
-
import os
|
|
20
|
-
import shutil
|
|
21
|
-
import sys
|
|
22
|
-
import tempfile
|
|
23
|
-
import threading
|
|
24
|
-
import time
|
|
25
|
-
|
|
26
|
-
from . import audit, backfill, ccgc, nodefile, units
|
|
27
|
-
from .mdcos import MdCGOS
|
|
28
|
-
|
|
29
|
-
PASS = FAIL = 0
|
|
30
|
-
FAILS = []
|
|
31
|
-
|
|
32
|
-
DIALOG = ("文件摄取分派:按扩展名把文件路由到对应摄取器"
|
|
33
|
-
"。该方法使用扩展名映射表进行路由"
|
|
34
|
-
"。此功能在本地文件系统中生效"
|
|
35
|
-
"。仅对本地可读文件生效"
|
|
36
|
-
"。2026-09-16"
|
|
37
|
-
"。通过回放测试验证"
|
|
38
|
-
"。二进制文件不适用")
|
|
39
|
-
|
|
40
|
-
SLOTS = {
|
|
41
|
-
"observation_position": {"value": "此功能在本地文件系统中生效"},
|
|
42
|
-
"observation_tool": {"value": "该方法使用扩展名映射表进行路由"},
|
|
43
|
-
"time_window": {"value": [0.0, 9999999999.0]},
|
|
44
|
-
"existence_constraint": {"value": "仅对本地可读文件生效"},
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
MARKS = {
|
|
48
|
-
"功能名": {"value": "文件摄取分派:按扩展名把文件路由到对应摄取器"},
|
|
49
|
-
"子功能": {"value": "按扩展名把文件路由到对应摄取器"},
|
|
50
|
-
"执行": {"value": "使用扩展名映射表进行路由"},
|
|
51
|
-
"验证方式": {"value": "回放测试", "basis": "test"},
|
|
52
|
-
"不适用条件": {"value": "二进制文件不适用"},
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def ok(cond, label):
|
|
57
|
-
global PASS, FAIL
|
|
58
|
-
if cond:
|
|
59
|
-
PASS += 1
|
|
60
|
-
else:
|
|
61
|
-
FAIL += 1
|
|
62
|
-
FAILS.append(label)
|
|
63
|
-
print(" FAIL " + label)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def _has(errs, code):
|
|
67
|
-
return any(str(e).startswith(code) for e in (errs or []))
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _seed(root):
|
|
71
|
-
cg = MdCGOS(root)
|
|
72
|
-
cg.add("tgt", "# 功能名:待编译节点\n\n占位正文。\n", layer="knowledge")
|
|
73
|
-
cg.flush()
|
|
74
|
-
cg.rebuild_index()
|
|
75
|
-
return cg
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def _fake_serve(jobs, stop, seen):
|
|
79
|
-
"""假蜂巢执行器:读 spec.json 写 result.json(契约与 hive 的 LLM 委托型一致)。
|
|
80
|
-
|
|
81
|
-
用线程模拟 serve 侧的单元执行,使**复核通道与签章搬运**在无网络无密钥下
|
|
82
|
-
可确定性验收——被测的是通道契约,不是模型质量。seen 记录 spec 形态供断言。
|
|
83
|
-
"""
|
|
84
|
-
while not stop.is_set():
|
|
85
|
-
try:
|
|
86
|
-
names = sorted(os.listdir(jobs))
|
|
87
|
-
except OSError:
|
|
88
|
-
names = []
|
|
89
|
-
for jid in names:
|
|
90
|
-
d = os.path.join(jobs, jid)
|
|
91
|
-
sp = os.path.join(d, units.SPEC_FILE)
|
|
92
|
-
rp = os.path.join(d, units.RESULT_FILE)
|
|
93
|
-
if not jid.startswith("h") or not os.path.isfile(sp) or os.path.exists(rp):
|
|
94
|
-
continue
|
|
95
|
-
try:
|
|
96
|
-
with open(sp, encoding="utf-8") as f:
|
|
97
|
-
spec = json.load(f)
|
|
98
|
-
except (OSError, ValueError):
|
|
99
|
-
continue
|
|
100
|
-
prompt = str(spec.get("user_prompt") or spec.get("prompt") or "")
|
|
101
|
-
seen.update({"role": spec.get("role"), "model": spec.get("model"),
|
|
102
|
-
"prompt_len": len(prompt),
|
|
103
|
-
"prompt_has_dialog": "文件摄取分派" in prompt})
|
|
104
|
-
payload = {"verdict": seen.get("verdict") or "accept",
|
|
105
|
-
"reason": "假单元复核:候选与对话原文一致",
|
|
106
|
-
"slot_corrections": {}}
|
|
107
|
-
try:
|
|
108
|
-
with open(rp, "w", encoding="utf-8") as f:
|
|
109
|
-
json.dump({"ok": True, "model": spec.get("model"),
|
|
110
|
-
"content": json.dumps(payload, ensure_ascii=False)},
|
|
111
|
-
f, ensure_ascii=False)
|
|
112
|
-
except OSError:
|
|
113
|
-
continue
|
|
114
|
-
time.sleep(0.05)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def _import_mcp():
|
|
118
|
-
"""延迟导入工具面(避免测试顶部把 server 依赖一并拉起)。"""
|
|
119
|
-
try:
|
|
120
|
-
from . import mcp_server
|
|
121
|
-
return mcp_server
|
|
122
|
-
except Exception: # noqa: BLE001
|
|
123
|
-
return None
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def main():
|
|
127
|
-
global PASS, FAIL
|
|
128
|
-
tmp = tempfile.mkdtemp(prefix="mdcg_ccgc_")
|
|
129
|
-
try:
|
|
130
|
-
root = os.path.join(tmp, "root")
|
|
131
|
-
os.makedirs(root, exist_ok=True)
|
|
132
|
-
cg = _seed(root)
|
|
133
|
-
|
|
134
|
-
# ---------- V1 缺参即编译错误(裁定 B) ----------
|
|
135
|
-
r = ccgc.compile_dialog("", "tgt", "agent:a1")
|
|
136
|
-
ok((not r.success) and _has(r.errors, "E001"), "V1a 缺 dialog → E001")
|
|
137
|
-
r = ccgc.compile_dialog(DIALOG, "", "agent:a1")
|
|
138
|
-
ok((not r.success) and _has(r.errors, "E002"), "V1b 缺 node_id → E002")
|
|
139
|
-
r = ccgc.compile_dialog(DIALOG, "tgt", "")
|
|
140
|
-
ok((not r.success) and _has(r.errors, "E003"), "V1c 缺 actor → E003")
|
|
141
|
-
r = ccgc.compile_dialog(DIALOG, "nope", "agent:a1", cg=cg)
|
|
142
|
-
ok((not r.success) and _has(r.errors, "E002"), "V1d 节点不存在 → E002")
|
|
143
|
-
ok(bool(r.verdict) and r.verdict.get("authority") == "VERIFICATION_UNIT",
|
|
144
|
-
"V1e 终裁 authority=VERIFICATION_UNIT")
|
|
145
|
-
|
|
146
|
-
# ---------- V2 名实门:幻觉在编译期被机械检出 ----------
|
|
147
|
-
bad_slots = dict(SLOTS)
|
|
148
|
-
bad_slots["observation_tool"] = {"value": "该方法使用神经网络进行路由",
|
|
149
|
-
"span": "该方法使用神经网络进行路由"}
|
|
150
|
-
r_bad = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
151
|
-
slots=bad_slots, marks=MARKS, cg=cg)
|
|
152
|
-
ok((not r_bad.success) and _has(r_bad.errors, "E011"), "V2a 捏造值 → E011")
|
|
153
|
-
ok(len(r_bad.ungrounded) >= 1, "V2b 未过门项进入 ungrounded 台账")
|
|
154
|
-
|
|
155
|
-
bad2 = dict(SLOTS)
|
|
156
|
-
bad2["observation_position"] = {"value": "此功能在本地文件系统中生效",
|
|
157
|
-
"span": "不存在的引用文本"}
|
|
158
|
-
r2 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
159
|
-
slots=bad2, marks=MARKS, cg=cg)
|
|
160
|
-
ok((not r2.success) and _has(r2.errors, "E010"), "V2c 引用定位失败 → E010")
|
|
161
|
-
|
|
162
|
-
class EvilParser(object):
|
|
163
|
-
"""冒充 LLM 通道:给出看起来合理但源文本里没有的值。"""
|
|
164
|
-
|
|
165
|
-
def candidates(self, dialog, ctx):
|
|
166
|
-
return {"marks": dict(MARKS), "slots": dict(bad_slots)}
|
|
167
|
-
|
|
168
|
-
r3 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
169
|
-
parser=EvilParser(), cg=cg)
|
|
170
|
-
ok((not r3.success) and _has(r3.errors, "E011"),
|
|
171
|
-
"V2d 外部 parser 幻觉同样被 E011 拦截(结构级阻断)")
|
|
172
|
-
|
|
173
|
-
# ---------- V3 四槽强制 ----------
|
|
174
|
-
r4 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
175
|
-
slots={"observation_position": SLOTS["observation_position"]},
|
|
176
|
-
marks=MARKS, cg=cg)
|
|
177
|
-
ok((not r4.success) and _has(r4.errors, "E020"), "V3a 四槽不全 → E020")
|
|
178
|
-
|
|
179
|
-
# ---------- V4/V5 唯一合成入口 + 六要素齐备 ----------
|
|
180
|
-
plain_slots = {k: v.get("value") for k, v in SLOTS.items()}
|
|
181
|
-
r = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
182
|
-
slots=SLOTS, marks=MARKS, cg=cg)
|
|
183
|
-
ok(r.success, "V4a 完整入参编译成功")
|
|
184
|
-
ok(r.lines.get("生效条件") == nodefile.condition_space_text(plain_slots),
|
|
185
|
-
"V4b 生效条件 == nodefile.condition_space_text(唯一入口)")
|
|
186
|
-
ok(set(r.lines) == set(nodefile.CCG_MARKS), "V5a 六要素齐备")
|
|
187
|
-
ok(r.sources.get("verification_basis") == "test", "V5b 验证基底 test")
|
|
188
|
-
|
|
189
|
-
# ---------- V7 自证拒绝(裁定 A 核心) ----------
|
|
190
|
-
a_self = ccgc.attest("tgt", ccgc.ACCEPT, "agent:a1", "agent:a1", cg=cg)
|
|
191
|
-
ok((not a_self.ok) and "E041" in a_self.error, "V7a 验证方==编译方 → E041")
|
|
192
|
-
a_defer = ccgc.attest("tgt", ccgc.DEFER, "designer", "agent:a1", cg=cg)
|
|
193
|
-
ok((not a_defer.ok) and "E042" in a_defer.error, "V7b DEFER 不构成签章")
|
|
194
|
-
a_ok = ccgc.attest("tgt", ccgc.ACCEPT, "designer", "agent:a1",
|
|
195
|
-
evidence="设计者核对原文一致", cg=cg)
|
|
196
|
-
ok(a_ok.ok and bool(a_ok.token), "V7c 编外验证方 ACCEPT → 有效签章")
|
|
197
|
-
|
|
198
|
-
# ---------- V8 无章不写 ----------
|
|
199
|
-
l0 = ccgc.link(r, None, cg=cg, apply=True)
|
|
200
|
-
ok((not l0.ok) and any("E040" in e for e in l0.errors), "V8a 无签章 → E040 拒绝")
|
|
201
|
-
l1 = ccgc.link(r, a_self, cg=cg, apply=True)
|
|
202
|
-
ok(not l1.ok, "V8b 自证签章 → link 拒绝")
|
|
203
|
-
l2 = ccgc.link(r, a_ok, cg=cg, apply=False)
|
|
204
|
-
ok(l2.ok and l2.dry_run and l2.written == 0, "V8c dry-run 不写入")
|
|
205
|
-
_fm_b, c_before = cg._read(cg.index["nodes"]["tgt"])
|
|
206
|
-
ok(not nodefile.ccg_completeness(c_before)["complete"], "V5c link 前六要素不全")
|
|
207
|
-
|
|
208
|
-
# ---------- link 落库 ----------
|
|
209
|
-
l3 = ccgc.link(r, a_ok, cg=cg, apply=True)
|
|
210
|
-
ok(l3.ok and l3.written == 6, "V8d 签章通过 → 写入六行")
|
|
211
|
-
fm_after, c_after = cg._read(cg.index["nodes"]["tgt"])
|
|
212
|
-
ok(nodefile.ccg_completeness(c_after)["complete"],
|
|
213
|
-
"V5d link 后六要素齐备(可判定性提升)")
|
|
214
|
-
ok(fm_after.get("condition_space") == plain_slots, "V4c condition_space 落 frontmatter")
|
|
215
|
-
ok(fm_after.get("verification_basis") == "test", "V5e verification_basis 落盘")
|
|
216
|
-
|
|
217
|
-
# ---------- V6 未制造条件污染 ----------
|
|
218
|
-
rep = backfill.verify_conditions(cg)
|
|
219
|
-
ok(rep.get("legacy_position") == 0, "V6a 弱等价残留 legacy_position == 0")
|
|
220
|
-
ok(rep.get("from_synthesis", 0) >= 1, "V6b 生效条件来源=合成")
|
|
221
|
-
|
|
222
|
-
# ---------- V9 缺验证器恒 DEFER(能力外置) ----------
|
|
223
|
-
v = audit.audit("ccg_marks", {"node": "tgt"}, {})
|
|
224
|
-
ok(v.get("state") == "DEFER", "V9a 未注入验证器 → DEFER(不假装通过)")
|
|
225
|
-
ok(audit.kinds()["ccg_marks"]["basis"] == "test", "V9b ccg_marks 基底建议=test")
|
|
226
|
-
|
|
227
|
-
# ---------- V11 用后续验证修正生效条件 ----------
|
|
228
|
-
rc = ccgc.recalibrate("tgt", {"existence_constraint": "仅对本地可读文件生效"},
|
|
229
|
-
"agent:a1", "agent:a1", cg=cg, apply=False)
|
|
230
|
-
ok(any("E041" in e for e in rc.errors), "V11a 修正方==编译方 → E041")
|
|
231
|
-
rc = ccgc.recalibrate("tgt", {"生效条件": "手写条件"}, "designer", "agent:a1",
|
|
232
|
-
cg=cg, apply=False)
|
|
233
|
-
ok(any("E043" in e for e in rc.errors), "V11b 非四槽键 → E043(无第二通路)")
|
|
234
|
-
rc = ccgc.recalibrate("tgt", {"observation_tool": "该方法使用扩展名映射表进行路由"},
|
|
235
|
-
"designer", "agent:a1", evidence="实测复核:方法槽无误",
|
|
236
|
-
cg=cg, apply=True)
|
|
237
|
-
ok(rc.ok, "V11c 编外验证方修正获准")
|
|
238
|
-
_fm_r, c_r = cg._read(cg.index["nodes"]["tgt"])
|
|
239
|
-
ok(nodefile.ccg_completeness(c_r)["complete"], "V11d 修正后仍齐备")
|
|
240
|
-
logs = ccgc._read_jsonl(ccgc._log_path(cg))
|
|
241
|
-
ok(any(x.get("action") == "ccgc_recalibrate" and x.get("slots_before") is not None
|
|
242
|
-
and x.get("slots_after") is not None for x in logs),
|
|
243
|
-
"V11e 修正留痕含 before/after(可溯源)")
|
|
244
|
-
ok(any(x.get("action") == "ccgc_attest" for x in logs), "V11f 签章留痕可查")
|
|
245
|
-
|
|
246
|
-
# ---------- V13 内生规则解析器:诚实下界 ----------
|
|
247
|
-
r_rule = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1", cg=cg)
|
|
248
|
-
ok(any("下界能力" in w for w in r_rule.warnings), "V13a 未注入解析器时如实声明下界")
|
|
249
|
-
bad_spans = [s for arr in r_rule.spans.values() for s in arr
|
|
250
|
-
if s and s not in DIALOG]
|
|
251
|
-
ok(not bad_spans, "V13b 内生解析器引用全部 grounded")
|
|
252
|
-
|
|
253
|
-
# ---------- V14 产物无占位残留 ----------
|
|
254
|
-
ok(not any(nodefile.is_placeholder_text(x) for x in r.lines.values()),
|
|
255
|
-
"V14 产物无占位残留")
|
|
256
|
-
|
|
257
|
-
# ---------- V15 裁定 B 术语落地:单一真源 + 六要素一一对应 ----------
|
|
258
|
-
ok(ccgc.CONTRACT_ROLES is nodefile.CCG_CONTRACT_ROLES,
|
|
259
|
-
"V15a 术语真源唯一(ccgc 引用 nodefile,不另定义一份)")
|
|
260
|
-
ok(tuple(nodefile.CCG_CONTRACT_ROLES) == tuple(nodefile.CCG_MARKS),
|
|
261
|
-
"V15b 契约角色与六要素一一对应(顺序一致)")
|
|
262
|
-
ok(nodefile.CCG_CONTRACT_ROLES["生效条件"] == "前置条件 precondition",
|
|
263
|
-
"V15c 生效条件角色 = precondition(裁定 B)")
|
|
264
|
-
|
|
265
|
-
# ---------- V16 pending:候选与签章绑定(跨 MCP 三次独立调用形态) ----------
|
|
266
|
-
p_path = ccgc.pending_path(cg, "tgt")
|
|
267
|
-
ok(bool(p_path) and ccgc.PENDING_DIR in p_path, "V16a pending 落 LAYERS 之外的冷区")
|
|
268
|
-
sv = ccgc.save_pending(cg, r)
|
|
269
|
-
ok(bool(sv.get("ok")) and os.path.isfile(sv["path"]) and bool(sv.get("hash")),
|
|
270
|
-
"V16b 候选落盘并留内容摘要")
|
|
271
|
-
got = ccgc.load_pending(cg, "tgt")
|
|
272
|
-
ok(bool(got.get("ok")) and bool(got.get("hash_ok")), "V16c 读回摘要一致(原件未被改写)")
|
|
273
|
-
ok(got["compiled"].lines == r.lines, "V16d 读回六行 == 编译产物(无损搬运)")
|
|
274
|
-
with open(sv["path"], encoding="utf-8") as f:
|
|
275
|
-
rec = json.load(f)
|
|
276
|
-
rec["compiled"]["lines"]["功能名"] = "被篡改的功能名"
|
|
277
|
-
with open(sv["path"], "w", encoding="utf-8") as f:
|
|
278
|
-
json.dump(rec, f, ensure_ascii=False)
|
|
279
|
-
lx = ccgc.link_pending(cg, "tgt", apply=True)
|
|
280
|
-
ok((not lx.ok) and any("hash" in e for e in lx.errors),
|
|
281
|
-
"V16e 候选被改写 → hash 不符,拒绝写入(签章只忠于原件)")
|
|
282
|
-
sv = ccgc.save_pending(cg, r, a_ok)
|
|
283
|
-
lz = ccgc.link_pending(cg, "tgt", apply=True, actor="agent:a1")
|
|
284
|
-
ok(lz.ok and lz.written == 6, "V16f 读回原件+签章 → 落库成功")
|
|
285
|
-
ok(not os.path.isfile(sv["path"]), "V16g 落库成功即清 pending(暂存非存档)")
|
|
286
|
-
ok(not any(ccgc.PENDING_DIR in str(k) for k in (cg.index.get("nodes") or {})),
|
|
287
|
-
"V16h pending 不进索引(冷区对检索隐身)")
|
|
288
|
-
|
|
289
|
-
# ---------- V17 闸门:只认编外裁决,绝不假装通过 ----------
|
|
290
|
-
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
291
|
-
"verifier": "hive:reflect:h1",
|
|
292
|
-
"evidence": "假单元复核:与原文一致"}, {})
|
|
293
|
-
ok(v.get("state") == "ACCEPT", "V17a 编外裁决+依据 → ACCEPT")
|
|
294
|
-
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
295
|
-
"verifier": "hive:reflect:h1"}, {})
|
|
296
|
-
ok(v.get("state") == "DEFER", "V17b ACCEPT 但无依据 → DEFER(无依据不通过)")
|
|
297
|
-
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
298
|
-
"verifier": "agent:a1", "evidence": "我自己验的"},
|
|
299
|
-
{"compiled_by": "agent:a1"})
|
|
300
|
-
ok(v.get("state") == "REJECT", "V17c 自证 → REJECT(E041 在闸门层再挡一次)")
|
|
301
|
-
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
302
|
-
"evidence": "无验证方"}, {})
|
|
303
|
-
ok(v.get("state") == "DEFER", "V17d 有裁决缺验证方标识 → DEFER")
|
|
304
|
-
v = audit.audit("ccg_marks", {"node_id": "tgt"}, {})
|
|
305
|
-
d = v.get("detail") or {}
|
|
306
|
-
ok(v.get("state") == "DEFER" and bool(d.get("next")) and d.get("channel_state") in units.STATES,
|
|
307
|
-
"V17e 无裁决 → DEFER 且给出下一步通道(不阻塞写路径)")
|
|
308
|
-
v = audit.audit("ccg_marks", {}, {})
|
|
309
|
-
ok(v.get("state") == "DEFER", "V17f 缺 node_id → DEFER")
|
|
310
|
-
|
|
311
|
-
# ---------- V18 复核通道:三态如实 + 来源标识结构上非编译者 ----------
|
|
312
|
-
ok(units.transport_name(units.HIVE, units.REFLECT, "h1") == "hive:reflect:h1",
|
|
313
|
-
"V18a 蜂巢来源标识 = hive:<role>:<job>")
|
|
314
|
-
ok(units.transport_name(units.HIVE, units.REFLECT, "h1") != "agent:a1",
|
|
315
|
-
"V18b 来源标识结构上不可能等于编译者(裁定 A 不被误伤)")
|
|
316
|
-
u = units.verdict_of('前置说明\n```json\n{"verdict":"accept","reason":"一致"}\n```')
|
|
317
|
-
ok(u["verdict"] == units.ACCEPT and bool(u["parsed"]), "V18c 围栏 JSON 可解析 → ACCEPT")
|
|
318
|
-
u = units.verdict_of("我无法判断这件事")
|
|
319
|
-
ok(u["verdict"] == units.DEFER and not u["parsed"], "V18d 解析不出 → DEFER(不猜测)")
|
|
320
|
-
u = units.verdict_of({"verdict": "drop", "reason": "与原文不符",
|
|
321
|
-
"slot_corrections": {"observation_tool": "x"}})
|
|
322
|
-
ok(u["verdict"] == units.REJECT and bool(u["slot_corrections"]),
|
|
323
|
-
"V18e drop → REJECT(四槽修正随裁决带回)")
|
|
324
|
-
aa = units.to_attest_args({"verdict": units.ACCEPT, "reason": "一致"}, state=units.HIVE,
|
|
325
|
-
role=units.REFLECT, job_id="h1",
|
|
326
|
-
compiled_by=units.transport_name(units.HIVE, units.REFLECT, "h1"))
|
|
327
|
-
ok(aa.get("self_verify") is True, "V18f 万一自证 → 显式标记(供上层拒绝)")
|
|
328
|
-
aa = units.to_attest_args({"verdict": units.ACCEPT, "reason": "一致"}, state=units.HIVE,
|
|
329
|
-
role=units.REFLECT, job_id="h1", compiled_by="agent:a1")
|
|
330
|
-
ok(not aa.get("self_verify") and aa["verifier"].startswith("hive:reflect:"),
|
|
331
|
-
"V18g 非自证:verifier 取蜂巢来源标识(不设自证标记)")
|
|
332
|
-
pr = units.probe(jobs=os.path.join(tmp, "nojobs"))
|
|
333
|
-
ok(pr["state"] == units.CONFIGURE and units.ENV_MODEL in pr["hint"],
|
|
334
|
-
"V18h 蜂巢不可用 → 返回配置指引(不自动拉起、不假装可用)")
|
|
335
|
-
pr = units.probe(jobs=os.path.join(tmp, "nojobs"), allow_degrade=True)
|
|
336
|
-
ok(pr["state"] == units.SUBAGENT, "V18i 显式 allow_degrade → 子代理降级(不冒充 hive)")
|
|
337
|
-
|
|
338
|
-
# ---------- V19/V20 端到端:假蜂巢 → 编外裁决 → 签章 → 落库 ----------
|
|
339
|
-
jobs = os.path.join(tmp, "jobs")
|
|
340
|
-
os.makedirs(jobs, exist_ok=True)
|
|
341
|
-
# 假 serve 是**本进程内的线程**,故「该 pid 是本程序」如实为真——把本程序
|
|
342
|
-
# 口径指向本进程映像名即可(v14 缺陷 E 修复后 units 判活含**身份层**:
|
|
343
|
-
# 旧写法心跳 pid=本进程却让 EXE 口径指向 hive.exe,身份层判假 → 通道不可用,
|
|
344
|
-
# 那不是被测缺陷而是测试自身要与新口径对齐)。
|
|
345
|
-
_old_exe = os.environ.get(units.ENV_EXE)
|
|
346
|
-
os.environ[units.ENV_EXE] = sys.executable
|
|
347
|
-
with open(os.path.join(jobs, units.SERVE_FILE), "w", encoding="utf-8") as f:
|
|
348
|
-
json.dump({"ts": int(time.time() * 1000), "pid": os.getpid()}, f)
|
|
349
|
-
seen = {}
|
|
350
|
-
stop = threading.Event()
|
|
351
|
-
th = threading.Thread(target=_fake_serve, args=(jobs, stop, seen), daemon=True)
|
|
352
|
-
th.start()
|
|
353
|
-
_old_model = os.environ.get(units.ENV_MODEL)
|
|
354
|
-
os.environ[units.ENV_MODEL] = "fake-unit-model"
|
|
355
|
-
try:
|
|
356
|
-
pr = units.probe(jobs=jobs)
|
|
357
|
-
ok(pr["state"] == units.HIVE, "V19a 心跳新鲜+模型已配 → HIVE 可派发")
|
|
358
|
-
rv = units.review(digest=r, dialog=DIALOG, role=units.REFLECT, node_id="tgt",
|
|
359
|
-
jobs=jobs, blocking=True, wait_s=30, cg=cg, actor="agent:a1")
|
|
360
|
-
ok(rv["state"] == units.HIVE and bool(rv.get("unit")), "V19b 派发并取回编外裁决")
|
|
361
|
-
ok((rv["unit"] or {}).get("verdict") == units.ACCEPT, "V19c 单元裁决解析为 ACCEPT")
|
|
362
|
-
ok(seen.get("role") == units.REFLECT and seen.get("model") == "fake-unit-model"
|
|
363
|
-
and seen.get("prompt_has_dialog"),
|
|
364
|
-
"V19d spec 形态合蜂巢契约(role/model/复核包正文)")
|
|
365
|
-
ok(str((rv.get("attest") or {}).get("verifier") or "").startswith("hive:reflect:"),
|
|
366
|
-
"V19e 签章方 = 蜂巢单元标识(结构上非编译者)")
|
|
367
|
-
at = ccgc.attest("tgt", rv["attest"]["verdict"], rv["attest"]["verifier"],
|
|
368
|
-
"agent:a1", evidence=rv["attest"]["evidence"] or "单元复核",
|
|
369
|
-
cg=cg)
|
|
370
|
-
ok(at.ok, "V19f 蜂巢裁决可直接签章(E041 不被误伤)")
|
|
371
|
-
logs = ccgc._read_jsonl(os.path.join(str(cg.root), units.LOG_NAME))
|
|
372
|
-
ok(any(x.get("action") == "review" and x.get("job_id") for x in logs),
|
|
373
|
-
"V19g 派发留痕(job_id 可追溯)")
|
|
374
|
-
|
|
375
|
-
# --- V20 MCP 工具面:compile → review → attest/link 三段式 ---
|
|
376
|
-
mcp = _import_mcp()
|
|
377
|
-
ok(mcp is not None, "V20a 工具面可加载")
|
|
378
|
-
c1 = mcp._ccg_call(cg, {"ccg": {"action": "catalog"}})
|
|
379
|
-
ok(c1["ok"] and "compile" in c1["actions"] and "E041" in c1["errors"],
|
|
380
|
-
"V20b catalog 自描述(动作清单 + 错误码)")
|
|
381
|
-
c2 = mcp._ccg_call(cg, {"ccg": {"action": "compile", "node_id": "tgt",
|
|
382
|
-
"dialog": DIALOG, "marks": MARKS, "slots": SLOTS}})
|
|
383
|
-
ok(c2["ok"] and c2["compiled"]["success"] and c2["pending"]["ok"],
|
|
384
|
-
"V20c compile 成功并落 pending(不当场写库)")
|
|
385
|
-
ok("E041" in c2["hint"], "V20d hint 指向编外复核(裁定 A 对调用方可见)")
|
|
386
|
-
c3 = mcp._ccg_call(cg, {"ccg": {"action": "attest", "node_id": "tgt",
|
|
387
|
-
"verdict": "ACCEPT", "verifier": c2["compiled_by"],
|
|
388
|
-
"compiled_by": c2["compiled_by"],
|
|
389
|
-
"evidence": "我自己验的"}})
|
|
390
|
-
ok((not c3["ok"]) and "E041" in str(c3["attest"]["error"]),
|
|
391
|
-
"V20e MCP 面自证 → E041(机械拒绝,不靠自觉)")
|
|
392
|
-
c4 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
393
|
-
ok(not c4["ok"], "V20f 自证章不构成准入 → link 拒绝")
|
|
394
|
-
c5 = mcp._ccg_call(cg, {"ccg": {"action": "review", "node_id": "tgt",
|
|
395
|
-
"jobs": jobs, "blocking": True, "wait_s": 30}})
|
|
396
|
-
ok(c5["state"] == units.HIVE and c5["verdict"] == "ACCEPT" and c5["passed"] is True,
|
|
397
|
-
"V20g review 取回裁决:ok/verdict/passed 三者分离")
|
|
398
|
-
ok(bool((c5.get("attest") or {}).get("ok")), "V20h 拿到裁决即自动签章")
|
|
399
|
-
c7 = mcp._ccg_call(cg, {"ccg": {"action": "review", "node_id": "tgt",
|
|
400
|
-
"jobs": jobs, "blocking": False}})
|
|
401
|
-
ok(c7["state"] == units.HIVE and c7["verdict"] is None and c7["passed"] is False,
|
|
402
|
-
"V20j 非阻塞:派发成功但裁决未回(verdict=None,不冒充通过)")
|
|
403
|
-
c6 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
404
|
-
ok(c6["ok"] and c6["link"]["written"] == 6, "V20i link 落库(三段式闭环)")
|
|
405
|
-
c10 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
406
|
-
ok(not c10["ok"], "V20m 落库后 pending 已清 → 再 link 明确报错(暂存非存档)")
|
|
407
|
-
c8 = mcp._ccg_call(cg, {"ccg": {"action": "units", "jobs": jobs, "doctor": True}})
|
|
408
|
-
ok(c8["ok"] and c8["action"] == "units", "V20k units/doctor 走三级链体检")
|
|
409
|
-
c9 = mcp._ccg_call(cg, {"ccg": {"action": "nope"}})
|
|
410
|
-
ok(not c9["ok"], "V20l 未知 action → 明确报错(不静默降级)")
|
|
411
|
-
finally:
|
|
412
|
-
stop.set()
|
|
413
|
-
th.join(timeout=3)
|
|
414
|
-
if _old_model is None:
|
|
415
|
-
os.environ.pop(units.ENV_MODEL, None)
|
|
416
|
-
else:
|
|
417
|
-
os.environ[units.ENV_MODEL] = _old_model
|
|
418
|
-
if _old_exe is None:
|
|
419
|
-
os.environ.pop(units.ENV_EXE, None)
|
|
420
|
-
else:
|
|
421
|
-
os.environ[units.ENV_EXE] = _old_exe
|
|
422
|
-
|
|
423
|
-
finally:
|
|
424
|
-
print()
|
|
425
|
-
print("ccgc: PASS=%d FAIL=%d" % (PASS, FAIL))
|
|
426
|
-
if FAILS:
|
|
427
|
-
print("FAILS: " + "; ".join(FAILS))
|
|
428
|
-
shutil.rmtree(tmp, ignore_errors=True)
|
|
429
|
-
return 1 if FAIL else 0
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if __name__ == "__main__":
|
|
433
|
-
sys.exit(main())
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""ccgc 验收:对话记录 → CCG 六要素编译器(V1-V20)。
|
|
3
|
+
|
|
4
|
+
运行:python -m md_cg.test_ccgc
|
|
5
|
+
|
|
6
|
+
三条判据在实现层为何是**机械可判定**的(不依赖自觉):
|
|
7
|
+
① 「LLM 不得自己验证自己」——候选结构里没有签章字段,且 attest 机械比对
|
|
8
|
+
`verifier != compiled_by`(E041);link 再挡一次(双闸)。
|
|
9
|
+
② 「幻觉」——名实门 E010/E011:每个写入值必须是源文本字面子串,零灰区。
|
|
10
|
+
③ 「缺参数」——是编译错误(E001-E004)而非 DEFER,`success = (errors == [])`。
|
|
11
|
+
|
|
12
|
+
V16-V20 覆盖**跨调用形态**(三次独立 MCP 调用传不动对象,只能落盘):
|
|
13
|
+
候选与签章绑定在 `_ccgc_pending/`(hash 防篡改)+ 复核通道三态 + 蜂巢契约
|
|
14
|
+
端到端(假执行器模拟 serve,无网络无密钥也能确定性验收「通道与签章」)。
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import shutil
|
|
21
|
+
import sys
|
|
22
|
+
import tempfile
|
|
23
|
+
import threading
|
|
24
|
+
import time
|
|
25
|
+
|
|
26
|
+
from . import audit, backfill, ccgc, nodefile, units
|
|
27
|
+
from .mdcos import MdCGOS
|
|
28
|
+
|
|
29
|
+
PASS = FAIL = 0
|
|
30
|
+
FAILS = []
|
|
31
|
+
|
|
32
|
+
DIALOG = ("文件摄取分派:按扩展名把文件路由到对应摄取器"
|
|
33
|
+
"。该方法使用扩展名映射表进行路由"
|
|
34
|
+
"。此功能在本地文件系统中生效"
|
|
35
|
+
"。仅对本地可读文件生效"
|
|
36
|
+
"。2026-09-16"
|
|
37
|
+
"。通过回放测试验证"
|
|
38
|
+
"。二进制文件不适用")
|
|
39
|
+
|
|
40
|
+
SLOTS = {
|
|
41
|
+
"observation_position": {"value": "此功能在本地文件系统中生效"},
|
|
42
|
+
"observation_tool": {"value": "该方法使用扩展名映射表进行路由"},
|
|
43
|
+
"time_window": {"value": [0.0, 9999999999.0]},
|
|
44
|
+
"existence_constraint": {"value": "仅对本地可读文件生效"},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
MARKS = {
|
|
48
|
+
"功能名": {"value": "文件摄取分派:按扩展名把文件路由到对应摄取器"},
|
|
49
|
+
"子功能": {"value": "按扩展名把文件路由到对应摄取器"},
|
|
50
|
+
"执行": {"value": "使用扩展名映射表进行路由"},
|
|
51
|
+
"验证方式": {"value": "回放测试", "basis": "test"},
|
|
52
|
+
"不适用条件": {"value": "二进制文件不适用"},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def ok(cond, label):
|
|
57
|
+
global PASS, FAIL
|
|
58
|
+
if cond:
|
|
59
|
+
PASS += 1
|
|
60
|
+
else:
|
|
61
|
+
FAIL += 1
|
|
62
|
+
FAILS.append(label)
|
|
63
|
+
print(" FAIL " + label)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _has(errs, code):
|
|
67
|
+
return any(str(e).startswith(code) for e in (errs or []))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _seed(root):
|
|
71
|
+
cg = MdCGOS(root)
|
|
72
|
+
cg.add("tgt", "# 功能名:待编译节点\n\n占位正文。\n", layer="knowledge")
|
|
73
|
+
cg.flush()
|
|
74
|
+
cg.rebuild_index()
|
|
75
|
+
return cg
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _fake_serve(jobs, stop, seen):
|
|
79
|
+
"""假蜂巢执行器:读 spec.json 写 result.json(契约与 hive 的 LLM 委托型一致)。
|
|
80
|
+
|
|
81
|
+
用线程模拟 serve 侧的单元执行,使**复核通道与签章搬运**在无网络无密钥下
|
|
82
|
+
可确定性验收——被测的是通道契约,不是模型质量。seen 记录 spec 形态供断言。
|
|
83
|
+
"""
|
|
84
|
+
while not stop.is_set():
|
|
85
|
+
try:
|
|
86
|
+
names = sorted(os.listdir(jobs))
|
|
87
|
+
except OSError:
|
|
88
|
+
names = []
|
|
89
|
+
for jid in names:
|
|
90
|
+
d = os.path.join(jobs, jid)
|
|
91
|
+
sp = os.path.join(d, units.SPEC_FILE)
|
|
92
|
+
rp = os.path.join(d, units.RESULT_FILE)
|
|
93
|
+
if not jid.startswith("h") or not os.path.isfile(sp) or os.path.exists(rp):
|
|
94
|
+
continue
|
|
95
|
+
try:
|
|
96
|
+
with open(sp, encoding="utf-8") as f:
|
|
97
|
+
spec = json.load(f)
|
|
98
|
+
except (OSError, ValueError):
|
|
99
|
+
continue
|
|
100
|
+
prompt = str(spec.get("user_prompt") or spec.get("prompt") or "")
|
|
101
|
+
seen.update({"role": spec.get("role"), "model": spec.get("model"),
|
|
102
|
+
"prompt_len": len(prompt),
|
|
103
|
+
"prompt_has_dialog": "文件摄取分派" in prompt})
|
|
104
|
+
payload = {"verdict": seen.get("verdict") or "accept",
|
|
105
|
+
"reason": "假单元复核:候选与对话原文一致",
|
|
106
|
+
"slot_corrections": {}}
|
|
107
|
+
try:
|
|
108
|
+
with open(rp, "w", encoding="utf-8") as f:
|
|
109
|
+
json.dump({"ok": True, "model": spec.get("model"),
|
|
110
|
+
"content": json.dumps(payload, ensure_ascii=False)},
|
|
111
|
+
f, ensure_ascii=False)
|
|
112
|
+
except OSError:
|
|
113
|
+
continue
|
|
114
|
+
time.sleep(0.05)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _import_mcp():
|
|
118
|
+
"""延迟导入工具面(避免测试顶部把 server 依赖一并拉起)。"""
|
|
119
|
+
try:
|
|
120
|
+
from . import mcp_server
|
|
121
|
+
return mcp_server
|
|
122
|
+
except Exception: # noqa: BLE001
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def main():
|
|
127
|
+
global PASS, FAIL
|
|
128
|
+
tmp = tempfile.mkdtemp(prefix="mdcg_ccgc_")
|
|
129
|
+
try:
|
|
130
|
+
root = os.path.join(tmp, "root")
|
|
131
|
+
os.makedirs(root, exist_ok=True)
|
|
132
|
+
cg = _seed(root)
|
|
133
|
+
|
|
134
|
+
# ---------- V1 缺参即编译错误(裁定 B) ----------
|
|
135
|
+
r = ccgc.compile_dialog("", "tgt", "agent:a1")
|
|
136
|
+
ok((not r.success) and _has(r.errors, "E001"), "V1a 缺 dialog → E001")
|
|
137
|
+
r = ccgc.compile_dialog(DIALOG, "", "agent:a1")
|
|
138
|
+
ok((not r.success) and _has(r.errors, "E002"), "V1b 缺 node_id → E002")
|
|
139
|
+
r = ccgc.compile_dialog(DIALOG, "tgt", "")
|
|
140
|
+
ok((not r.success) and _has(r.errors, "E003"), "V1c 缺 actor → E003")
|
|
141
|
+
r = ccgc.compile_dialog(DIALOG, "nope", "agent:a1", cg=cg)
|
|
142
|
+
ok((not r.success) and _has(r.errors, "E002"), "V1d 节点不存在 → E002")
|
|
143
|
+
ok(bool(r.verdict) and r.verdict.get("authority") == "VERIFICATION_UNIT",
|
|
144
|
+
"V1e 终裁 authority=VERIFICATION_UNIT")
|
|
145
|
+
|
|
146
|
+
# ---------- V2 名实门:幻觉在编译期被机械检出 ----------
|
|
147
|
+
bad_slots = dict(SLOTS)
|
|
148
|
+
bad_slots["observation_tool"] = {"value": "该方法使用神经网络进行路由",
|
|
149
|
+
"span": "该方法使用神经网络进行路由"}
|
|
150
|
+
r_bad = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
151
|
+
slots=bad_slots, marks=MARKS, cg=cg)
|
|
152
|
+
ok((not r_bad.success) and _has(r_bad.errors, "E011"), "V2a 捏造值 → E011")
|
|
153
|
+
ok(len(r_bad.ungrounded) >= 1, "V2b 未过门项进入 ungrounded 台账")
|
|
154
|
+
|
|
155
|
+
bad2 = dict(SLOTS)
|
|
156
|
+
bad2["observation_position"] = {"value": "此功能在本地文件系统中生效",
|
|
157
|
+
"span": "不存在的引用文本"}
|
|
158
|
+
r2 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
159
|
+
slots=bad2, marks=MARKS, cg=cg)
|
|
160
|
+
ok((not r2.success) and _has(r2.errors, "E010"), "V2c 引用定位失败 → E010")
|
|
161
|
+
|
|
162
|
+
class EvilParser(object):
|
|
163
|
+
"""冒充 LLM 通道:给出看起来合理但源文本里没有的值。"""
|
|
164
|
+
|
|
165
|
+
def candidates(self, dialog, ctx):
|
|
166
|
+
return {"marks": dict(MARKS), "slots": dict(bad_slots)}
|
|
167
|
+
|
|
168
|
+
r3 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
169
|
+
parser=EvilParser(), cg=cg)
|
|
170
|
+
ok((not r3.success) and _has(r3.errors, "E011"),
|
|
171
|
+
"V2d 外部 parser 幻觉同样被 E011 拦截(结构级阻断)")
|
|
172
|
+
|
|
173
|
+
# ---------- V3 四槽强制 ----------
|
|
174
|
+
r4 = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
175
|
+
slots={"observation_position": SLOTS["observation_position"]},
|
|
176
|
+
marks=MARKS, cg=cg)
|
|
177
|
+
ok((not r4.success) and _has(r4.errors, "E020"), "V3a 四槽不全 → E020")
|
|
178
|
+
|
|
179
|
+
# ---------- V4/V5 唯一合成入口 + 六要素齐备 ----------
|
|
180
|
+
plain_slots = {k: v.get("value") for k, v in SLOTS.items()}
|
|
181
|
+
r = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1",
|
|
182
|
+
slots=SLOTS, marks=MARKS, cg=cg)
|
|
183
|
+
ok(r.success, "V4a 完整入参编译成功")
|
|
184
|
+
ok(r.lines.get("生效条件") == nodefile.condition_space_text(plain_slots),
|
|
185
|
+
"V4b 生效条件 == nodefile.condition_space_text(唯一入口)")
|
|
186
|
+
ok(set(r.lines) == set(nodefile.CCG_MARKS), "V5a 六要素齐备")
|
|
187
|
+
ok(r.sources.get("verification_basis") == "test", "V5b 验证基底 test")
|
|
188
|
+
|
|
189
|
+
# ---------- V7 自证拒绝(裁定 A 核心) ----------
|
|
190
|
+
a_self = ccgc.attest("tgt", ccgc.ACCEPT, "agent:a1", "agent:a1", cg=cg)
|
|
191
|
+
ok((not a_self.ok) and "E041" in a_self.error, "V7a 验证方==编译方 → E041")
|
|
192
|
+
a_defer = ccgc.attest("tgt", ccgc.DEFER, "designer", "agent:a1", cg=cg)
|
|
193
|
+
ok((not a_defer.ok) and "E042" in a_defer.error, "V7b DEFER 不构成签章")
|
|
194
|
+
a_ok = ccgc.attest("tgt", ccgc.ACCEPT, "designer", "agent:a1",
|
|
195
|
+
evidence="设计者核对原文一致", cg=cg)
|
|
196
|
+
ok(a_ok.ok and bool(a_ok.token), "V7c 编外验证方 ACCEPT → 有效签章")
|
|
197
|
+
|
|
198
|
+
# ---------- V8 无章不写 ----------
|
|
199
|
+
l0 = ccgc.link(r, None, cg=cg, apply=True)
|
|
200
|
+
ok((not l0.ok) and any("E040" in e for e in l0.errors), "V8a 无签章 → E040 拒绝")
|
|
201
|
+
l1 = ccgc.link(r, a_self, cg=cg, apply=True)
|
|
202
|
+
ok(not l1.ok, "V8b 自证签章 → link 拒绝")
|
|
203
|
+
l2 = ccgc.link(r, a_ok, cg=cg, apply=False)
|
|
204
|
+
ok(l2.ok and l2.dry_run and l2.written == 0, "V8c dry-run 不写入")
|
|
205
|
+
_fm_b, c_before = cg._read(cg.index["nodes"]["tgt"])
|
|
206
|
+
ok(not nodefile.ccg_completeness(c_before)["complete"], "V5c link 前六要素不全")
|
|
207
|
+
|
|
208
|
+
# ---------- link 落库 ----------
|
|
209
|
+
l3 = ccgc.link(r, a_ok, cg=cg, apply=True)
|
|
210
|
+
ok(l3.ok and l3.written == 6, "V8d 签章通过 → 写入六行")
|
|
211
|
+
fm_after, c_after = cg._read(cg.index["nodes"]["tgt"])
|
|
212
|
+
ok(nodefile.ccg_completeness(c_after)["complete"],
|
|
213
|
+
"V5d link 后六要素齐备(可判定性提升)")
|
|
214
|
+
ok(fm_after.get("condition_space") == plain_slots, "V4c condition_space 落 frontmatter")
|
|
215
|
+
ok(fm_after.get("verification_basis") == "test", "V5e verification_basis 落盘")
|
|
216
|
+
|
|
217
|
+
# ---------- V6 未制造条件污染 ----------
|
|
218
|
+
rep = backfill.verify_conditions(cg)
|
|
219
|
+
ok(rep.get("legacy_position") == 0, "V6a 弱等价残留 legacy_position == 0")
|
|
220
|
+
ok(rep.get("from_synthesis", 0) >= 1, "V6b 生效条件来源=合成")
|
|
221
|
+
|
|
222
|
+
# ---------- V9 缺验证器恒 DEFER(能力外置) ----------
|
|
223
|
+
v = audit.audit("ccg_marks", {"node": "tgt"}, {})
|
|
224
|
+
ok(v.get("state") == "DEFER", "V9a 未注入验证器 → DEFER(不假装通过)")
|
|
225
|
+
ok(audit.kinds()["ccg_marks"]["basis"] == "test", "V9b ccg_marks 基底建议=test")
|
|
226
|
+
|
|
227
|
+
# ---------- V11 用后续验证修正生效条件 ----------
|
|
228
|
+
rc = ccgc.recalibrate("tgt", {"existence_constraint": "仅对本地可读文件生效"},
|
|
229
|
+
"agent:a1", "agent:a1", cg=cg, apply=False)
|
|
230
|
+
ok(any("E041" in e for e in rc.errors), "V11a 修正方==编译方 → E041")
|
|
231
|
+
rc = ccgc.recalibrate("tgt", {"生效条件": "手写条件"}, "designer", "agent:a1",
|
|
232
|
+
cg=cg, apply=False)
|
|
233
|
+
ok(any("E043" in e for e in rc.errors), "V11b 非四槽键 → E043(无第二通路)")
|
|
234
|
+
rc = ccgc.recalibrate("tgt", {"observation_tool": "该方法使用扩展名映射表进行路由"},
|
|
235
|
+
"designer", "agent:a1", evidence="实测复核:方法槽无误",
|
|
236
|
+
cg=cg, apply=True)
|
|
237
|
+
ok(rc.ok, "V11c 编外验证方修正获准")
|
|
238
|
+
_fm_r, c_r = cg._read(cg.index["nodes"]["tgt"])
|
|
239
|
+
ok(nodefile.ccg_completeness(c_r)["complete"], "V11d 修正后仍齐备")
|
|
240
|
+
logs = ccgc._read_jsonl(ccgc._log_path(cg))
|
|
241
|
+
ok(any(x.get("action") == "ccgc_recalibrate" and x.get("slots_before") is not None
|
|
242
|
+
and x.get("slots_after") is not None for x in logs),
|
|
243
|
+
"V11e 修正留痕含 before/after(可溯源)")
|
|
244
|
+
ok(any(x.get("action") == "ccgc_attest" for x in logs), "V11f 签章留痕可查")
|
|
245
|
+
|
|
246
|
+
# ---------- V13 内生规则解析器:诚实下界 ----------
|
|
247
|
+
r_rule = ccgc.compile_dialog(DIALOG, "tgt", "agent:a1", cg=cg)
|
|
248
|
+
ok(any("下界能力" in w for w in r_rule.warnings), "V13a 未注入解析器时如实声明下界")
|
|
249
|
+
bad_spans = [s for arr in r_rule.spans.values() for s in arr
|
|
250
|
+
if s and s not in DIALOG]
|
|
251
|
+
ok(not bad_spans, "V13b 内生解析器引用全部 grounded")
|
|
252
|
+
|
|
253
|
+
# ---------- V14 产物无占位残留 ----------
|
|
254
|
+
ok(not any(nodefile.is_placeholder_text(x) for x in r.lines.values()),
|
|
255
|
+
"V14 产物无占位残留")
|
|
256
|
+
|
|
257
|
+
# ---------- V15 裁定 B 术语落地:单一真源 + 六要素一一对应 ----------
|
|
258
|
+
ok(ccgc.CONTRACT_ROLES is nodefile.CCG_CONTRACT_ROLES,
|
|
259
|
+
"V15a 术语真源唯一(ccgc 引用 nodefile,不另定义一份)")
|
|
260
|
+
ok(tuple(nodefile.CCG_CONTRACT_ROLES) == tuple(nodefile.CCG_MARKS),
|
|
261
|
+
"V15b 契约角色与六要素一一对应(顺序一致)")
|
|
262
|
+
ok(nodefile.CCG_CONTRACT_ROLES["生效条件"] == "前置条件 precondition",
|
|
263
|
+
"V15c 生效条件角色 = precondition(裁定 B)")
|
|
264
|
+
|
|
265
|
+
# ---------- V16 pending:候选与签章绑定(跨 MCP 三次独立调用形态) ----------
|
|
266
|
+
p_path = ccgc.pending_path(cg, "tgt")
|
|
267
|
+
ok(bool(p_path) and ccgc.PENDING_DIR in p_path, "V16a pending 落 LAYERS 之外的冷区")
|
|
268
|
+
sv = ccgc.save_pending(cg, r)
|
|
269
|
+
ok(bool(sv.get("ok")) and os.path.isfile(sv["path"]) and bool(sv.get("hash")),
|
|
270
|
+
"V16b 候选落盘并留内容摘要")
|
|
271
|
+
got = ccgc.load_pending(cg, "tgt")
|
|
272
|
+
ok(bool(got.get("ok")) and bool(got.get("hash_ok")), "V16c 读回摘要一致(原件未被改写)")
|
|
273
|
+
ok(got["compiled"].lines == r.lines, "V16d 读回六行 == 编译产物(无损搬运)")
|
|
274
|
+
with open(sv["path"], encoding="utf-8") as f:
|
|
275
|
+
rec = json.load(f)
|
|
276
|
+
rec["compiled"]["lines"]["功能名"] = "被篡改的功能名"
|
|
277
|
+
with open(sv["path"], "w", encoding="utf-8") as f:
|
|
278
|
+
json.dump(rec, f, ensure_ascii=False)
|
|
279
|
+
lx = ccgc.link_pending(cg, "tgt", apply=True)
|
|
280
|
+
ok((not lx.ok) and any("hash" in e for e in lx.errors),
|
|
281
|
+
"V16e 候选被改写 → hash 不符,拒绝写入(签章只忠于原件)")
|
|
282
|
+
sv = ccgc.save_pending(cg, r, a_ok)
|
|
283
|
+
lz = ccgc.link_pending(cg, "tgt", apply=True, actor="agent:a1")
|
|
284
|
+
ok(lz.ok and lz.written == 6, "V16f 读回原件+签章 → 落库成功")
|
|
285
|
+
ok(not os.path.isfile(sv["path"]), "V16g 落库成功即清 pending(暂存非存档)")
|
|
286
|
+
ok(not any(ccgc.PENDING_DIR in str(k) for k in (cg.index.get("nodes") or {})),
|
|
287
|
+
"V16h pending 不进索引(冷区对检索隐身)")
|
|
288
|
+
|
|
289
|
+
# ---------- V17 闸门:只认编外裁决,绝不假装通过 ----------
|
|
290
|
+
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
291
|
+
"verifier": "hive:reflect:h1",
|
|
292
|
+
"evidence": "假单元复核:与原文一致"}, {})
|
|
293
|
+
ok(v.get("state") == "ACCEPT", "V17a 编外裁决+依据 → ACCEPT")
|
|
294
|
+
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
295
|
+
"verifier": "hive:reflect:h1"}, {})
|
|
296
|
+
ok(v.get("state") == "DEFER", "V17b ACCEPT 但无依据 → DEFER(无依据不通过)")
|
|
297
|
+
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
298
|
+
"verifier": "agent:a1", "evidence": "我自己验的"},
|
|
299
|
+
{"compiled_by": "agent:a1"})
|
|
300
|
+
ok(v.get("state") == "REJECT", "V17c 自证 → REJECT(E041 在闸门层再挡一次)")
|
|
301
|
+
v = audit.audit("ccg_marks", {"node_id": "tgt", "unit_verdict": "ACCEPT",
|
|
302
|
+
"evidence": "无验证方"}, {})
|
|
303
|
+
ok(v.get("state") == "DEFER", "V17d 有裁决缺验证方标识 → DEFER")
|
|
304
|
+
v = audit.audit("ccg_marks", {"node_id": "tgt"}, {})
|
|
305
|
+
d = v.get("detail") or {}
|
|
306
|
+
ok(v.get("state") == "DEFER" and bool(d.get("next")) and d.get("channel_state") in units.STATES,
|
|
307
|
+
"V17e 无裁决 → DEFER 且给出下一步通道(不阻塞写路径)")
|
|
308
|
+
v = audit.audit("ccg_marks", {}, {})
|
|
309
|
+
ok(v.get("state") == "DEFER", "V17f 缺 node_id → DEFER")
|
|
310
|
+
|
|
311
|
+
# ---------- V18 复核通道:三态如实 + 来源标识结构上非编译者 ----------
|
|
312
|
+
ok(units.transport_name(units.HIVE, units.REFLECT, "h1") == "hive:reflect:h1",
|
|
313
|
+
"V18a 蜂巢来源标识 = hive:<role>:<job>")
|
|
314
|
+
ok(units.transport_name(units.HIVE, units.REFLECT, "h1") != "agent:a1",
|
|
315
|
+
"V18b 来源标识结构上不可能等于编译者(裁定 A 不被误伤)")
|
|
316
|
+
u = units.verdict_of('前置说明\n```json\n{"verdict":"accept","reason":"一致"}\n```')
|
|
317
|
+
ok(u["verdict"] == units.ACCEPT and bool(u["parsed"]), "V18c 围栏 JSON 可解析 → ACCEPT")
|
|
318
|
+
u = units.verdict_of("我无法判断这件事")
|
|
319
|
+
ok(u["verdict"] == units.DEFER and not u["parsed"], "V18d 解析不出 → DEFER(不猜测)")
|
|
320
|
+
u = units.verdict_of({"verdict": "drop", "reason": "与原文不符",
|
|
321
|
+
"slot_corrections": {"observation_tool": "x"}})
|
|
322
|
+
ok(u["verdict"] == units.REJECT and bool(u["slot_corrections"]),
|
|
323
|
+
"V18e drop → REJECT(四槽修正随裁决带回)")
|
|
324
|
+
aa = units.to_attest_args({"verdict": units.ACCEPT, "reason": "一致"}, state=units.HIVE,
|
|
325
|
+
role=units.REFLECT, job_id="h1",
|
|
326
|
+
compiled_by=units.transport_name(units.HIVE, units.REFLECT, "h1"))
|
|
327
|
+
ok(aa.get("self_verify") is True, "V18f 万一自证 → 显式标记(供上层拒绝)")
|
|
328
|
+
aa = units.to_attest_args({"verdict": units.ACCEPT, "reason": "一致"}, state=units.HIVE,
|
|
329
|
+
role=units.REFLECT, job_id="h1", compiled_by="agent:a1")
|
|
330
|
+
ok(not aa.get("self_verify") and aa["verifier"].startswith("hive:reflect:"),
|
|
331
|
+
"V18g 非自证:verifier 取蜂巢来源标识(不设自证标记)")
|
|
332
|
+
pr = units.probe(jobs=os.path.join(tmp, "nojobs"))
|
|
333
|
+
ok(pr["state"] == units.CONFIGURE and units.ENV_MODEL in pr["hint"],
|
|
334
|
+
"V18h 蜂巢不可用 → 返回配置指引(不自动拉起、不假装可用)")
|
|
335
|
+
pr = units.probe(jobs=os.path.join(tmp, "nojobs"), allow_degrade=True)
|
|
336
|
+
ok(pr["state"] == units.SUBAGENT, "V18i 显式 allow_degrade → 子代理降级(不冒充 hive)")
|
|
337
|
+
|
|
338
|
+
# ---------- V19/V20 端到端:假蜂巢 → 编外裁决 → 签章 → 落库 ----------
|
|
339
|
+
jobs = os.path.join(tmp, "jobs")
|
|
340
|
+
os.makedirs(jobs, exist_ok=True)
|
|
341
|
+
# 假 serve 是**本进程内的线程**,故「该 pid 是本程序」如实为真——把本程序
|
|
342
|
+
# 口径指向本进程映像名即可(v14 缺陷 E 修复后 units 判活含**身份层**:
|
|
343
|
+
# 旧写法心跳 pid=本进程却让 EXE 口径指向 hive.exe,身份层判假 → 通道不可用,
|
|
344
|
+
# 那不是被测缺陷而是测试自身要与新口径对齐)。
|
|
345
|
+
_old_exe = os.environ.get(units.ENV_EXE)
|
|
346
|
+
os.environ[units.ENV_EXE] = sys.executable
|
|
347
|
+
with open(os.path.join(jobs, units.SERVE_FILE), "w", encoding="utf-8") as f:
|
|
348
|
+
json.dump({"ts": int(time.time() * 1000), "pid": os.getpid()}, f)
|
|
349
|
+
seen = {}
|
|
350
|
+
stop = threading.Event()
|
|
351
|
+
th = threading.Thread(target=_fake_serve, args=(jobs, stop, seen), daemon=True)
|
|
352
|
+
th.start()
|
|
353
|
+
_old_model = os.environ.get(units.ENV_MODEL)
|
|
354
|
+
os.environ[units.ENV_MODEL] = "fake-unit-model"
|
|
355
|
+
try:
|
|
356
|
+
pr = units.probe(jobs=jobs)
|
|
357
|
+
ok(pr["state"] == units.HIVE, "V19a 心跳新鲜+模型已配 → HIVE 可派发")
|
|
358
|
+
rv = units.review(digest=r, dialog=DIALOG, role=units.REFLECT, node_id="tgt",
|
|
359
|
+
jobs=jobs, blocking=True, wait_s=30, cg=cg, actor="agent:a1")
|
|
360
|
+
ok(rv["state"] == units.HIVE and bool(rv.get("unit")), "V19b 派发并取回编外裁决")
|
|
361
|
+
ok((rv["unit"] or {}).get("verdict") == units.ACCEPT, "V19c 单元裁决解析为 ACCEPT")
|
|
362
|
+
ok(seen.get("role") == units.REFLECT and seen.get("model") == "fake-unit-model"
|
|
363
|
+
and seen.get("prompt_has_dialog"),
|
|
364
|
+
"V19d spec 形态合蜂巢契约(role/model/复核包正文)")
|
|
365
|
+
ok(str((rv.get("attest") or {}).get("verifier") or "").startswith("hive:reflect:"),
|
|
366
|
+
"V19e 签章方 = 蜂巢单元标识(结构上非编译者)")
|
|
367
|
+
at = ccgc.attest("tgt", rv["attest"]["verdict"], rv["attest"]["verifier"],
|
|
368
|
+
"agent:a1", evidence=rv["attest"]["evidence"] or "单元复核",
|
|
369
|
+
cg=cg)
|
|
370
|
+
ok(at.ok, "V19f 蜂巢裁决可直接签章(E041 不被误伤)")
|
|
371
|
+
logs = ccgc._read_jsonl(os.path.join(str(cg.root), units.LOG_NAME))
|
|
372
|
+
ok(any(x.get("action") == "review" and x.get("job_id") for x in logs),
|
|
373
|
+
"V19g 派发留痕(job_id 可追溯)")
|
|
374
|
+
|
|
375
|
+
# --- V20 MCP 工具面:compile → review → attest/link 三段式 ---
|
|
376
|
+
mcp = _import_mcp()
|
|
377
|
+
ok(mcp is not None, "V20a 工具面可加载")
|
|
378
|
+
c1 = mcp._ccg_call(cg, {"ccg": {"action": "catalog"}})
|
|
379
|
+
ok(c1["ok"] and "compile" in c1["actions"] and "E041" in c1["errors"],
|
|
380
|
+
"V20b catalog 自描述(动作清单 + 错误码)")
|
|
381
|
+
c2 = mcp._ccg_call(cg, {"ccg": {"action": "compile", "node_id": "tgt",
|
|
382
|
+
"dialog": DIALOG, "marks": MARKS, "slots": SLOTS}})
|
|
383
|
+
ok(c2["ok"] and c2["compiled"]["success"] and c2["pending"]["ok"],
|
|
384
|
+
"V20c compile 成功并落 pending(不当场写库)")
|
|
385
|
+
ok("E041" in c2["hint"], "V20d hint 指向编外复核(裁定 A 对调用方可见)")
|
|
386
|
+
c3 = mcp._ccg_call(cg, {"ccg": {"action": "attest", "node_id": "tgt",
|
|
387
|
+
"verdict": "ACCEPT", "verifier": c2["compiled_by"],
|
|
388
|
+
"compiled_by": c2["compiled_by"],
|
|
389
|
+
"evidence": "我自己验的"}})
|
|
390
|
+
ok((not c3["ok"]) and "E041" in str(c3["attest"]["error"]),
|
|
391
|
+
"V20e MCP 面自证 → E041(机械拒绝,不靠自觉)")
|
|
392
|
+
c4 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
393
|
+
ok(not c4["ok"], "V20f 自证章不构成准入 → link 拒绝")
|
|
394
|
+
c5 = mcp._ccg_call(cg, {"ccg": {"action": "review", "node_id": "tgt",
|
|
395
|
+
"jobs": jobs, "blocking": True, "wait_s": 30}})
|
|
396
|
+
ok(c5["state"] == units.HIVE and c5["verdict"] == "ACCEPT" and c5["passed"] is True,
|
|
397
|
+
"V20g review 取回裁决:ok/verdict/passed 三者分离")
|
|
398
|
+
ok(bool((c5.get("attest") or {}).get("ok")), "V20h 拿到裁决即自动签章")
|
|
399
|
+
c7 = mcp._ccg_call(cg, {"ccg": {"action": "review", "node_id": "tgt",
|
|
400
|
+
"jobs": jobs, "blocking": False}})
|
|
401
|
+
ok(c7["state"] == units.HIVE and c7["verdict"] is None and c7["passed"] is False,
|
|
402
|
+
"V20j 非阻塞:派发成功但裁决未回(verdict=None,不冒充通过)")
|
|
403
|
+
c6 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
404
|
+
ok(c6["ok"] and c6["link"]["written"] == 6, "V20i link 落库(三段式闭环)")
|
|
405
|
+
c10 = mcp._ccg_call(cg, {"ccg": {"action": "link", "node_id": "tgt", "apply": True}})
|
|
406
|
+
ok(not c10["ok"], "V20m 落库后 pending 已清 → 再 link 明确报错(暂存非存档)")
|
|
407
|
+
c8 = mcp._ccg_call(cg, {"ccg": {"action": "units", "jobs": jobs, "doctor": True}})
|
|
408
|
+
ok(c8["ok"] and c8["action"] == "units", "V20k units/doctor 走三级链体检")
|
|
409
|
+
c9 = mcp._ccg_call(cg, {"ccg": {"action": "nope"}})
|
|
410
|
+
ok(not c9["ok"], "V20l 未知 action → 明确报错(不静默降级)")
|
|
411
|
+
finally:
|
|
412
|
+
stop.set()
|
|
413
|
+
th.join(timeout=3)
|
|
414
|
+
if _old_model is None:
|
|
415
|
+
os.environ.pop(units.ENV_MODEL, None)
|
|
416
|
+
else:
|
|
417
|
+
os.environ[units.ENV_MODEL] = _old_model
|
|
418
|
+
if _old_exe is None:
|
|
419
|
+
os.environ.pop(units.ENV_EXE, None)
|
|
420
|
+
else:
|
|
421
|
+
os.environ[units.ENV_EXE] = _old_exe
|
|
422
|
+
|
|
423
|
+
finally:
|
|
424
|
+
print()
|
|
425
|
+
print("ccgc: PASS=%d FAIL=%d" % (PASS, FAIL))
|
|
426
|
+
if FAILS:
|
|
427
|
+
print("FAILS: " + "; ".join(FAILS))
|
|
428
|
+
shutil.rmtree(tmp, ignore_errors=True)
|
|
429
|
+
return 1 if FAIL else 0
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
if __name__ == "__main__":
|
|
433
|
+
sys.exit(main())
|