@furongjun1999/dsh-memory 0.6.0 → 0.7.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 +618 -572
- package/codebuddy/CODEBUDDY.md +10 -10
- package/data/policy.json +27 -0
- package/docs/README.md +1 -0
- package/docs/discipline/harnesses.yaml +31 -0
- package/docs/discipline/templates/full.md.tmpl +1 -1
- package/docs/discipline/templates/rules.mdc.tmpl +1 -1
- package/docs/eval/N225_/347/264/242/345/274/225/346/227/245/345/277/227/351/235/236/345/257/271/350/261/241/350/243/205/350/275/275/351/235/242/347/261/273/345/236/213/351/227/270_v1.0.md +418 -0
- package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/344/270/216/351/224/256/347/261/273/345/236/213/351/227/270_v1.1.md +441 -0
- package/docs/eval/issue43_/351/273/230/350/256/244/347/255/226/347/225/245/345/212/240/350/275/275/344/270/216/345/207/255/346/215/256/346/230/216/346/226/207/351/230/237/345/210/227_v1.0.md +398 -0
- package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/200/346/211/271_/346/216/245/347/272/277/344/270/216/347/255/211/344/273/267/345/217/230/346/215/242_v1.0.md +498 -0
- package/docs/eval//344/274/230/345/214/226/347/254/254/344/270/211/346/211/271_/351/227/250/347/246/201/350/275/254/346/255/243/344/270/216/350/260/203/345/272/246/346/255/242/350/241/200/344/270/216/351/227/250/346/216/247/346/224/266/345/217/243_v1.0.md +669 -0
- package/docs/eval//344/274/230/345/214/226/347/254/254/344/272/214/346/211/271_/344/276/235/350/265/226/351/200/217/344/274/240/344/270/216/345/257/271/346/213/215/345/217/243/345/276/204/344/270/216/350/264/237/347/274/223/345/255/230_v1.0.md +683 -0
- package/docs/eval//345/207/272/350/264/247/351/235/242/345/206/222/347/203/237_/350/277/233/350/264/247/351/227/250/347/246/201_v1.0.md +460 -0
- package/docs/eval//345/217/221/345/270/20307_/345/244/226/351/203/250/346/212/245/345/221/212/345/233/233/346/211/271/344/277/256/345/244/215/344/270/216/346/217/222/344/273/266/351/235/242/345/212/240/345/233/272_v1.0.md +205 -0
- package/docs/eval//345/217/221/345/270/20308_/350/207/252/350/277/255/344/273/243/344/270/216/347/235/241/347/234/240_/345/233/276/346/243/200/347/264/242/350/267/257/344/270/216/346/235/203/351/207/215_v1.0.md +97 -0
- package/docs/eval//345/275/222/344/270/200/345/261/202/347/274/272/347/234/201/347/277/273/345/205/263_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +458 -0
- package/docs/eval//346/200/247/350/203/275/344/270/223/351/241/271_/345/206/267/346/237/245/350/257/242/344/270/216/345/206/205/345/255/230_v1.0.md +218 -0
- package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +10 -0
- package/docs/eval//347/274/226/347/240/201/351/235/242/345/211/215/347/275/256_/345/205/245/345/217/243/350/207/252/344/277/235/350/257/201UTF8/344/270/216/346/226/207/346/234/254open/345/256/210/345/215/253_v1.0.md +646 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v20.md +283 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v21.md +224 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v22.md +223 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v23.md +293 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v24.md +303 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v25.md +230 -0
- 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 +136 -11
- 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 +52 -2
- 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 +1 -1
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +100 -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 +40 -40
- package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +57 -9
- 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 +7 -2
- package/docs/mdcg//347/235/241/347/234/240/345/221/250/346/234/237_/350/277/220/347/273/264/345/211/215/346/217/220/344/270/216/347/273/264/346/212/244/346/214/207/345/215/227_v1.0.md +183 -0
- 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 +39 -3
- package/docs/plans//345/205/250/344/270/255/346/226/207/347/274/226/347/240/201/344/270/216/350/234/202/345/267/242/344/273/273/345/212/241/346/240/207/350/257/206/345/245/221/347/272/246_v2.0.md +220 -0
- package/docs/plans//347/234/237/346/272/220/347/264/242/345/274/225_/351/200/232/347/224/250/346/234/272/345/210/266_v0.3.md +227 -0
- package/docs/plans//347/235/241/347/234/240/344/270/216/350/207/252/350/277/255/344/273/243_/345/212/237/350/203/275/344/274/230/345/214/226/350/256/276/350/256/241_v0.4.md +547 -0
- package/docs/plans//350/234/202/345/267/242/346/250/241/345/236/213/345/257/206/351/222/245/351/205/215/347/275/256/351/235/242_v1.0.md +385 -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 +460 -460
- package/lib/bridge.js +24 -2
- package/lib/hooks.d.ts +31 -2
- package/lib/hooks.js +219 -16
- package/lib/init.js +16 -1
- package/lib/lib/prompt_safety.d.ts +52 -1
- package/lib/lib/prompt_safety.js +76 -1
- package/md_cg/audit.py +652 -379
- package/md_cg/bench6_arms.py +1 -1
- package/md_cg/bench_e2e_locomo_qa.py +11 -4
- package/md_cg/bench_p0.py +1 -1
- package/md_cg/branches.py +2 -2
- package/md_cg/ccgc.py +1071 -1006
- package/md_cg/chain.py +48 -1
- package/md_cg/consistency.py +97 -9
- package/md_cg/consolidate.py +34 -9
- package/md_cg/crypto.py +59 -26
- package/md_cg/docindex.py +16 -1
- package/md_cg/evolution.py +17 -1
- package/md_cg/export.py +1 -1
- package/md_cg/forgetting.py +309 -13
- package/md_cg/freshness.py +511 -0
- package/md_cg/fsutil.py +454 -8
- package/md_cg/generation.py +409 -0
- package/md_cg/hotcache.py +4 -1
- package/md_cg/identity.py +3 -3
- package/md_cg/insight.py +24 -3
- package/md_cg/linkref.py +1 -1
- package/md_cg/logref.py +327 -0
- package/md_cg/mcp_server.py +4261 -3818
- package/md_cg/mdcg.py +4695 -3547
- package/md_cg/mdcos.py +4672 -4159
- package/md_cg/mreview/pipeline.py +15 -1
- package/md_cg/nodefile.py +713 -576
- package/md_cg/protect.py +158 -11
- package/md_cg/protocol.py +41 -2
- package/md_cg/provenance.py +22 -4
- package/md_cg/reach.py +4 -4
- package/md_cg/readcache.py +76 -15
- package/md_cg/reconcile.py +1 -1
- package/md_cg/refindex.py +246 -37
- package/md_cg/refine.py +1 -1
- package/md_cg/routing.py +32 -5
- package/md_cg/run_tests.py +17 -0
- package/md_cg/scrub.py +30 -3
- package/md_cg/security.py +47 -1
- package/md_cg/self_state.py +5 -5
- package/md_cg/semantic/canonical.py +22 -0
- package/md_cg/semantic/unify.py +73 -22
- package/md_cg/semantic/unify_fixture.json +25 -0
- package/md_cg/sleep.py +1297 -0
- package/md_cg/sources.py +23 -6
- package/md_cg/srcindex.py +352 -0
- package/md_cg/stg.py +47 -3
- package/md_cg/subgraph.py +2 -2
- package/md_cg/sustain.py +1436 -1168
- package/md_cg/tasks.py +469 -470
- package/md_cg/test_auto_defaults.py +424 -0
- package/md_cg/test_b1_auto_id_multiproc.py +277 -0
- package/md_cg/test_b1b2_write_face.py +417 -0
- package/md_cg/test_b2_sensitivity_landing.py +223 -0
- package/md_cg/test_b3_merge_keeps_content.py +576 -0
- package/md_cg/test_b4_shard_dir_selfheal.py +843 -0
- package/md_cg/test_b4_shard_dir_selfheal_guard.py +238 -0
- package/md_cg/test_boundary_hit.py +410 -0
- package/md_cg/test_c3_transient_read_negative.py +793 -0
- package/md_cg/test_c8_search_rrf_gates.py +502 -0
- package/md_cg/test_ccg_form_parity.py +188 -0
- package/md_cg/test_ccgc.py +28 -3
- package/md_cg/test_en_pipeline.py +22 -13
- package/md_cg/test_generation_guard.py +352 -0
- package/md_cg/test_govern_directread.py +17 -4
- package/md_cg/test_h2_session_view_norm.py +233 -0
- package/md_cg/test_h4_sustain_snapshot.py +1387 -0
- package/md_cg/test_hive_ingest.py +285 -285
- package/md_cg/test_issue39_utf8_stdio.py +307 -16
- package/md_cg/test_issue43_default_policy.py +865 -0
- package/md_cg/test_legacy_p3_node_id_type.py +375 -0
- package/md_cg/test_linkref.py +10 -3
- package/md_cg/test_lock.py +2 -2
- package/md_cg/test_logref.py +1109 -0
- package/md_cg/test_m3_h9_bucket_health_protect_mark.py +301 -0
- package/md_cg/test_m3_h9_semantic_guard.py +525 -0
- package/md_cg/test_mr_m2.py +15 -3
- package/md_cg/test_n130_verify_falsified_protect.py +1 -1
- package/md_cg/test_n139_dek_provision_failclosed.py +185 -0
- package/md_cg/test_n176_link_trust.py +221 -0
- package/md_cg/test_n178_units_jobid_gate.py +212 -0
- package/md_cg/test_n184_keys_concurrent_provision.py +307 -0
- package/md_cg/test_n195_writepath_reload.py +283 -0
- package/md_cg/test_n196_stale_gate_skip.py +169 -0
- package/md_cg/test_n197_n208_write_face_gates.py +471 -0
- package/md_cg/test_n198_tokens_corrupt_failclosed.py +225 -0
- package/md_cg/test_n199_tokens_concurrent_write.py +378 -0
- package/md_cg/test_n201_proposal_visibility.py +382 -0
- package/md_cg/test_n202_session_notes_visibility.py +461 -0
- package/md_cg/test_n204_n205_n226_n227_n228_n229_exit_gates.py +542 -0
- package/md_cg/test_n206_stdio_jsonrpc_type.py +403 -0
- package/md_cg/test_n209_verify_write_face_gates.py +461 -0
- package/md_cg/test_n212_n213_n224_generation_gates.py +519 -0
- package/md_cg/test_n214_n215_n221_n222_write_face_gates.py +563 -0
- package/md_cg/test_n225_nonobject_load.py +1110 -0
- package/md_cg/test_n230_dirty_replay.py +375 -0
- package/md_cg/test_n62_tenant_bind_failclosed.py +200 -0
- package/md_cg/test_neg_condition_hits.py +333 -0
- package/md_cg/test_neg_tail_honesty.py +663 -0
- package/md_cg/test_none_id_write_guard.py +4 -3
- package/md_cg/test_opt_batch1_md_cg.py +451 -0
- package/md_cg/test_p1.py +5 -5
- package/md_cg/test_p11_consistency.py +161 -12
- package/md_cg/test_p26_refindex.py +2 -2
- package/md_cg/test_p27_docindex.py +777 -774
- package/md_cg/test_p28_refcheck.py +740 -13
- package/md_cg/test_p29_session_ingest_export.py +2 -2
- package/md_cg/test_p2_mcp.py +12 -1
- package/md_cg/test_p2_six_elements.py +463 -0
- package/md_cg/test_p30_maintain.py +33 -2
- package/md_cg/test_p31_insight.py +1 -0
- package/md_cg/test_p3_legacy_closure.py +433 -0
- package/md_cg/test_p4_freshness.py +680 -0
- package/md_cg/test_p8_subgraph_chain.py +14 -1
- package/md_cg/test_p9c_dedup_hints.py +276 -0
- package/md_cg/test_policy_required_ccg.py +426 -0
- package/md_cg/test_protocol.py +22 -0
- package/md_cg/test_rank_parity_score_mode.py +522 -0
- package/md_cg/test_read_face_input_gates.py +363 -0
- package/md_cg/test_read_face_semantics.py +489 -0
- package/md_cg/test_recall_face_guards.py +812 -0
- package/md_cg/test_rejected_credential_forms.py +188 -0
- package/md_cg/test_rejected_redact.py +146 -0
- package/md_cg/test_retr_s1b.py +2 -2
- package/md_cg/test_retr_s5.py +20 -7
- package/md_cg/test_review_conformance.py +21 -3
- package/md_cg/test_security_audit_v21.py +2 -2
- package/md_cg/test_semantic_canonical.py +5 -3
- package/md_cg/test_server_version.py +67 -0
- package/md_cg/test_sleep.py +611 -0
- package/md_cg/test_sleep_p1.py +784 -0
- package/md_cg/test_srcindex.py +171 -0
- package/md_cg/test_tenant_env_override_warn.py +63 -50
- package/md_cg/test_time_core_lint.py +968 -0
- package/md_cg/test_token_lowercase_form.py +315 -0
- package/md_cg/test_unify_default_off.py +701 -0
- package/md_cg/test_unify_scope.py +182 -0
- package/md_cg/test_v21r1_package_version.py +310 -0
- package/md_cg/test_writepipe.py +10 -4
- package/md_cg/tokens.py +225 -95
- package/md_cg/tool_face.py +4 -4
- package/md_cg/trust.py +49 -5
- package/md_cg/units.py +204 -6
- package/md_cg/weights.py +4 -4
- package/md_cg/whitebox_kb/aeis_core/time_core.py +8 -0
- package/md_cg/whitebox_kb/wisdom/knowledge_points.py +1 -1
- package/md_cg/writelimit.py +42 -8
- package/md_cg/writepipe.py +651 -554
- package/package.json +4 -2
- package/skills/plugin.json +1 -1
- package/src/bridge.ts +25 -2
- package/src/hooks.ts +229 -16
- package/src/init.ts +15 -1
- package/src/lib/prompt_safety.ts +88 -1
- package/utf8_boot.py +237 -0
- package/zcode/AGENTS.md +10 -10
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# 缺陷挖掘·自主迭代 第 26 轮报告(md_cg 核心面收尾·第四圈第二站)
|
|
2
|
+
|
|
3
|
+
**材料与口径声明**:本报告由本轮 ask 给定的三份材料(四区复核结果 / 修复结果 / 留档未修清单)编译而成,凡属材料所给的第一手探针输出,条目内一律标注「材料所给」;凡属**本报告会话实跑**的结果,集中在第四节并标注命令与输出。材料中的旧行号已因修复偏移,本报告一律改用**现工作区行号**(本会话逐处 `grep -n` / 读取核实),与材料行号不一致处以现码为准并在条目内注明。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 一、执行摘要
|
|
8
|
+
|
|
9
|
+
- **轮次定位**:md_cg 核心面收尾·第四圈第二站。上一批(批次 66/67,HEAD `ca09872e`)已修 N195/N196/N198/P3/N178/v21-R1/N191/N206/N202/N211/N199/N210/N197/N208/N209,本轮**不复报**这些号,只处理其**次生面与同族未接线写点**。
|
|
10
|
+
- **四区复核**:`gatefamily` / `generation` / `visibility` / `scripts_ts`。**在册 25 条**=四区 confirmed 条目 24 条(gatefamily 5 / generation 6 / visibility 7 / scripts_ts 6)+ 修复期新发现残留 1 条(N230)。材料门禁结果记「四区确认 25 个」,本席按材料逐条点数为 24 条、加修复期残留 1 条后与材料口径一致(计数方法已在此声明)。**证伪·剔除 3 条 + 1 半条**(§3.2)。
|
|
11
|
+
- **编号**:自 N221 续编、全局唯一。**树内实占扫描**(本会话 `git ls-files` + `git grep -ohE 'N[0-9]{3,4}'`)实占最大值为 **N229**(`N802` 为 `hive/test_exec_empty_response.py:137` 的 flake8 noqa 码,非缺陷号),故新号 N221–N229 共 9 个落地给 9 条新发现,修复期残留续编 **N230**(§3.0 裁定表)。材料内四区各自自编的 N221–N224 **相互碰撞**,已按「树内实占·守卫文件名优先」归一。
|
|
12
|
+
- **修复**:**5 个修复批次**、覆盖 12 个缺陷号(N201/N204/N205/N212/N213/N214/N215/N216/N217/N218/N219/N220)+ 新号 N221/N222/N224/N226/N227/N228/N229(§2)。
|
|
13
|
+
- **留档未修 3 项**:N223(tidy 巡检 keep 写点)、N225(索引/日志非对象 JSON)、N207(`isMainEntry` 无 realpath 归一)(§5);另 N230 为修复期残留。
|
|
14
|
+
- **本报告会话实跑(第一手,详见 §4)**:全量回归 `245/245 通过,5 跳过`(rc=0);四条新 md_cg 守卫直跑 `31/42/22/45 passed, 0 failed`(rc=0);四处红基线独立复现(`10 passed/21 failed`、`PASS=12 FAIL=30`、`PASS=13 FAIL=9`、`PASS=16 FAIL=29`,与修复席自报**逐字一致**);scripts 侧四件守卫 `28/17/12/14`(rc=0);TS 守卫 `3 pass / 0 fail`(rc=0);`npm run gate` **退出码 0 且 `VERDICT=PASS`(一致)**。
|
|
15
|
+
- **未运行**:cargo(本轮零 Rust 改动)、真实 CI(ubuntu runner)与真实 registry 下载腿、`npm test` 全量 TS 套件(本席只跑 N219 单件)。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 二、修复清单(5 个修复批次;落工作区未 commit)
|
|
20
|
+
|
|
21
|
+
### 修复① 写面绕闸族四写点(N214 + N215 + N221 + N222;2 legacy + 2 新)
|
|
22
|
+
|
|
23
|
+
- **where(现码行号,本会话核实)**:
|
|
24
|
+
- **N214** `md_cg/forgetting.py:248`(`reinforce` 签名已加 `override/actor`)、`:273-275`(**写盘前** `protect.guard_overwrite`,层/敏感度取节点 fm 真值)、`:290`(其后才是裸 `cg._write_node`);两个调用点 `md_cg/mdcos.py:3393-3395`(`remember_gated` 的 MERGE 分支,透传 `override` + `actor`)与 `md_cg/mdcos.py:2790-2792`(`maintain action="prefeed" write=true` 的 reinforce 分支,**只透传 `actor`**,见下方「如实说明」)。
|
|
25
|
+
- **N215** `md_cg/writelimit.py:211`(`converge_into` 签名)、`:230-232`(写盘前同一闸)、`:237-239`(其后才是裸写);调用点 `md_cg/mdcos.py:3348-3350`(CONVERGE 分支,透传 `override` + `actor`)。
|
|
26
|
+
- **N221** `md_cg/mdcg.py:1690-1701`(缺陷与口径注释)、`:1702-1709`(**新增跨层闸**:既有节点跨层覆写=搬迁语义 ⇒ 源层 `protect.require_layer` 在先、`protect.guard_move` 在后,次序对齐 N131/N209);相关旧路径清理 `md_cg/mdcg.py:1870`(`os.remove(_old_real)`);工具面出口 `md_cg/mcp_server.py:3130-3131`。
|
|
27
|
+
- **N222** `md_cg/scrub.py:719`(`_apply_offset` 签名加 `actor`)、`:739-749`(缺陷注释)、`:750-752`(写盘前 `guard_overwrite`,**在 `is_protected` 跳过分支与 `cg._write_node` 的 try 之外** ⇒ 越权即 `AccessDenied` 整批中止)、`:793-795`(`calibrate` 透传 `actor`);工具面 `md_cg/mcp_server.py:1634`(`_scrub_call`,未加 `require_admin`)。
|
|
28
|
+
- **缺陷面**(材料所给):`remember_gated` 的 MERGE / CONVERGE 两条**替代落盘分支**与 `add` 的**跨层覆写**、`scrub.calibrate apply` 四处写点,写盘时**既不查 principal 层白名单、也不过 `protect.guard_overwrite`**,同身份的 `add` 被 `AccessDenied`、此路照样落盘;无 `_protected_history` 快照、无 `_protected_audit.jsonl`。N221 的语义等同 `_move_layer` 搬迁(旧层文件被删、索引改指新层)却绕过 N209 为搬迁建的双闸。
|
|
29
|
+
- **修复**:四处全部复用**既有单点** `protect.guard_overwrite` / `protect.require_layer`,不另造第二份口径;`override=True` 走同一闸的显式放行分支(快照 + 审计)。
|
|
30
|
+
- **攻防前后对比**(材料所给第一手;本席仅复现红基线守门,见 §4):
|
|
31
|
+
- 修前:reflect(`layers_allow=('contextual',)`)`remember_gated(layer='self')` → `{"verdict":"MERGE","merged_into":"self214","reinforced":{"importance":0.95,"merge_count":1,"protected":true}}`,`_protected_history` / `_protected_audit.jsonl` 均不存在;CONVERGE 腿先经 `ProtectionError` 落 `sig→anchor id` 预占位再换正文 → anchor 层节点被追加聚合行、`merge_count` 递增;`mdcg_remember(gated=false)` 跨层覆写返回 `{"ok":true,"id":"kn221"}`、旧层文件消失;sustain `op=scrub action=calibrate apply=true` → `n_adjusted=5`(含 `override=true` 腿动 importance 0.9 的不可遗忘节点)。
|
|
32
|
+
- 修后:上述四腿全部 `AccessDenied: 角色 <reflect|sustain> 无权写入 <self|anchor|knowledge|goals> 层(可写层 [...])`,盘面**零改写、零搬迁**,审计/快照仍为空(因为写入未发生);**反向腿全绿**(reflect 对自己层 contextual 的 MERGE/同构聚合仍成功、designer 同层覆写与 calibrate 仍生效、`override=True` 正路落快照 + 审计)。
|
|
33
|
+
- **守卫**:`md_cg/test_n214_n215_n221_n222_write_face_gates.py`(六组,**31 passed / 0 failed,live=22**,本席实跑 rc=0);红基线(本席实跑,HEAD 覆盖临时副本)**10 passed / 21 failed(live=22)**。
|
|
34
|
+
- **如实说明(与材料的差异,本会话读码核实)**:材料记「三处调用点透传 override/actor」,实测 `md_cg/mdcos.py:2790-2792`(prefeed 路)**只传 `actor`**,该路无 `override` 形参 ⇒ `guard_overwrite` 走默认 `override=False`,行为是 **fail-closed**(保护节点被拒),**不构成绕过**;措辞差异已在此更正。
|
|
35
|
+
|
|
36
|
+
### 修复② 索引代际签名 / 陈旧条目可见性 / 重载派生缓存(N212 + N213 + N224;含两条次生面)
|
|
37
|
+
|
|
38
|
+
- **where(现码行号)**:`md_cg/mdcg.py:1027`(`_index_signature` 计入口径)、`:1073-1124`(`_maybe_reload_index`:重载成功后 `subgraph/chain/trust.invalidate_cache` 三连,`:1115-1120` 为 N224 缺陷注释)、`:1225`(`flush` 登记本进程分片 `_own_shard`);`md_cg/mdcos.py:4132`(`MdCGSecure.get` 以**本次读取的 frontmatter** 复核可见性)、`:3842`(`_open_content`:所有密文解密出口**前置**读可见性闸);`md_cg/protect.py:53`(`_GATE_UNKNOWN_KEYS` 单点键集)、`:63`(`_entry` 判定前代际探活)、`:86/:116`(`_fm` 的 `need_fallback` 增「受保护层且门控键值为 None」判据)、`:358/:372-381`(`mark` 改动进索引写日志:`_dirty[nid]=e` + `flush`)。
|
|
39
|
+
- **缺陷面**(材料所给):①代际签名只取 `_index.json` 的 `(mtime_ns,size)`,而 `flush()` 只追加分片、从不重写快照 ⇒ **存活且未 compact 的他进程写方对本进程永不可见**:N195 写保护闸静默失活(anchor 节点被无痕覆写)、存在性假阴(`get→None`、`forget→not_found`)、文档承诺的 `maintain action=reload` 逃逸口实测无效(`reloaded=false`)。②同根次生:`prev_entry=None` ⇒ 旧路径清理整段跳过,同 id 落成两个文件、重开后版本漂移 + 永久孤儿。③陈旧条目可见性用**旧快照**的 sensitivity/session,而正文由盘上当前文件解出 ⇒ 同 actor 异 session 的 private 正文跨会话明文解出(N196 的修补只在 `e is None` 分支探活)。④同根 `protect._fm` 在 `_node_entry`/`_stage` 恒落三键下 `need_fallback` 恒假 ⇒ `_fm` 100% 信任索引、永不回读文件。⑤N224:重载**不失效** `chain/subgraph/trust` 派生拓扑缓存 ⇒ 已不可见节点与其跳条件继续从 `walk/explain/causal_path/expand_from_seeds` 泄出,新快照的新节点与新边永不进拓扑(陈旧读取长期常驻 serve)。
|
|
40
|
+
- **修复**:①签名口径改 `(快照签名, 他进程分片签名元组)`,本进程分片按绝对路径精确排除(自身写入不触发自重载);②重载路径补齐三连 `invalidate_cache`(与本地写路径同源同序);③`get` 命中条目后以**与正文同一次读取**所得 frontmatter 复核可见性(无 TOCTOU、无额外 IO),`_open_content` 出口前置同一闸(关死「判据陈旧、正文新鲜」的全部读面);④`_entry` 判定前代际探活、`_fm` 的 `need_fallback` 增「受保护层门控键值为 None」判据;⑤`protect.mark` 改门控字段后标脏 + `flush`,使保护位进跨进程代际载体。
|
|
41
|
+
- **攻防前后对比**(材料所给):修前常驻 A 对「B 只 flush 不 close」的写入 `_maybe_reload_index()=False`、`is_immutable=(False,'')`、`A.add` 覆写 anchor 节点**成功且无痕**、`maintain('reload')={"reloaded":False}`;同 id 跨桶写落两文件、重开索引内容为旧版;同 actor 异 session `get` 返回 private 明文;重载后 `walk(Y)` 仍返回已不可见节点 X。修后逐项反转(`ProtectionError` / 恰一份文件 / `get=None` / 邻接表整体消失),并有**阳性对照**防过度收口(共享档仍可见、可见节点验证态照常)。**代价(材料所给,同机 300 节点池)**:`_index_signature` 14.3→32.6 µs/次、`get` +3.5%、`protect.stats(300)` 0.3→20.1 ms(管理/诊断面)。
|
|
42
|
+
- **守卫**:`md_cg/test_n212_n213_n224_generation_gates.py`(六组,**PASS=42 / FAIL=0 / LIVE=26**,本席实跑 rc=0);红基线(本席实跑)**PASS=12 / FAIL=30**。
|
|
43
|
+
- **同批新发现残留**:**N230**(`_dirty` 重放遮蔽,见 §3.1-25 与 §5),材料记该席自编「N226」、因与树内实占 N226 撞号而改判。
|
|
44
|
+
|
|
45
|
+
### 修复③ 提案队列可见性(N201 = legacy 第 24 轮首编号 + 同批次生计数面)
|
|
46
|
+
|
|
47
|
+
- **where(现码行号)**:写面 `md_cg/mdcos.py:1736`(`MdCGOS.propose`)与 `:3949`(`MdCGSecure.propose`)——rec 顶层补 `sensitivity`(与节点 frontmatter/索引条目同形状,`extra` 内原键原样保留);读面 `md_cg/mdcos.py:4250-4263`(**新增** `_review_list_visible`:逐条取顶层 sensitivity、缺键回退 `extra.sensitivity`、仍缺按 `"secret"` fail-closed,判定走 `_readable` 单点);`:4246-4247`(`MdCGSecure.review_list` = `require_op("review")` + 该过滤);`:3238`(`health_os` 的 `review_pending` 改走可见性计数面);出口面 `md_cg/mcp_server.py:3089-3096`(`"mdcg_review_list": "read" → "review"`,移入裁决面组);职责行 `md_cg/tool_face.py:55`。
|
|
48
|
+
- **缺陷面**(材料所给):提案正文以明文写进 `hippocampus/inbox.jsonl`,`review_list` 全函数体零 `_readable`/零身份判定 ⇒ 任何持 `read` op 的身份(含无令牌 guest)经工具 `mdcg_review_list` 明文读走全部待审提案正文与 actor/session 归属,而**同库** `cg(op=review)` 被 `AccessDenied`(两条出口口径矛盾)。前提成立:`mdcg_*` 细粒度工具属 **full** 工具面(DSH 插件强制 full,`src/lib/mdcg_client.ts:121`)。
|
|
49
|
+
- **修复**:写面留档 + 读面可见性收口 + 出口 op 对齐「规范出口」;次生面(只读体检面会被 op 闸打死)拆出 `_review_list_visible`(基类=全量、隔离层=按可见性收窄、**不设 op 闸**)供 `health_os` 使用。
|
|
50
|
+
- **攻防前后对比**(材料所给):修前 guest 经细粒度工具**未被拒**、返回体含 designer `sensitivity='private'` 候选的**明文标记**与归属;`mdcg_health` 的 `review_pending=2`=可见 2=全体 2(计数面直接暴露不可见提案存在性);修后 guest 两出口均 `AccessDenied`,orchestr(internal / 高密级异会话)只见共享档、**同会话达标者见该候选**(未过度封禁)、设计者全见,健康面位审计数=该身份**可见**待审数。
|
|
51
|
+
- **守卫**:`md_cg/test_n201_proposal_visibility.py`(六组,**PASS=22 / FAIL=0 / LIVE=13**,本席实跑 rc=0);红基线(本席实跑)**PASS=13 / FAIL=9**。
|
|
52
|
+
- **刻意不改(材料所给,含实测支撑)**:`inbox.jsonl` 的 content 仍明文落盘——DEK 按身份签发,若按提案者密钥封套入队,**复核者读不开自己必须裁决的候选**且 `accept` 会把该密文原样落进节点(此后对所有其他身份永久不可读);故本轮补偿控制 = 读面身份闸 + 落盘密级留档,静态明文面(能读 root 文件系统者=运维权限)标注为**本轮残留**,不冒充已修。
|
|
53
|
+
- **编号更正**:该席上一批自报的「N227(只读体检面暴露不可见提案计数)」与材料本批 N227(演化台账)撞号,**以材料为准**,该计数面按 **N201 次生面**归并、原占用作废(材料自陈,本席据实登记)。
|
|
54
|
+
|
|
55
|
+
### 修复④ 脚本与 TS 面五件门禁(N216 + N217 + N218 + N220 + N219;全 legacy)
|
|
56
|
+
|
|
57
|
+
- **where(现码行号)**:`scripts/check_publish_artifact.py`:`:152`(`unsafe_rel_reason` 拒 `..`/绝对/盘符/UNC)、`:175`(`_within_root`)、`:278-279`(越根条目一律不读)、`:351`(**新增** `extract_pack_manifest`:逐段 `raw_decode` 全部候选、优先全形态、同档取**末段**)、`:610`(新规则 R5 清单路径安全)、`:615`(新规则 R6 清单来源可信——再跑 `npm pack --dry-run --json --ignore-scripts` 作基线,要求基线 ⊆ 所选清单,漏列即坐实);`.github/workflows/publish-artifact-check.yml:3-15`(仅补契约注释,**触发面未改**);`scripts/check_registry_tarball.py:40-53`(顶层对象闸)、`scripts/interop_gate.py:26-53`(顶层 dict 闸 + `_REQUIRED` 补 `failed` + 计数类型口径对齐);`scripts/dsh_log_index.py:249`(`_as_dict` 单点)+ 逐会话 `skipped` 与 TOTAL 双出口 + stderr WARNING;`src/bridge.ts:233-249`(行处理器对 `JSON.parse` 结果加类型闸,运行件随 `npm run build` 同步);`scripts/migrate_restricted.py:69-99`(`--ids` 逐目标复查)、`:101-106`(写保护预检)、`:140`(`override` 条件)、`:146`(ProtectionError/AccessDenied 收口)、新参数 `--force`。
|
|
58
|
+
- **缺陷面**(材料所给):①**N216(high)** 发布清单取自被测树自身生命周期脚本 stdout ⇒ `prepare` 打印的诱饵 JSON 排在 npm 真清单之前、旧解析器取「首个可解析 JSON 值」⇒ 真发布件里的凭据文件不再被检查、门禁打印 `VERDICT=PASS` / exit 0;同路径还允许清单条目带 `..` 越根读任意可读文件并回显命中片段。②**N217** 三件门禁脚本对「合法 JSON 但顶层非对象」无类型闸 ⇒ `TypeError/AttributeError` 逃出 main、退出码落到与脚本自陈契约**相反**的一侧(承诺 2/3 实得 1)。③**N218** `dsh_log_index` 非对象 JSON 行未按同函数既有 fail-closed 纪律记账 ⇒ `AttributeError` 逃出 main、**整轮摄取中断**(stdout 空、无 TOTAL、后续会话全不处理)。④**N219** `src/bridge.ts` 行处理器只挡「非 JSON」、未校验 parse 结果类型 ⇒ 一行 `null` 在流回调内抛 `TypeError`、**未捕获异常终结宿主(DSH)进程**。⑤**N220** `--ids` 命名的任何可读节点都被改写为 `restricted` 且恒定 `override=True`(破 anchor 层保护闸),dry-run 还回显正文前 40 字。
|
|
59
|
+
- **攻防前后对比**(材料所给):N216 修前「文件数=1」+ R1/R2/R3/R4 全 PASS + `VERDICT=PASS` / exit 0(去诱饵对照 → 文件数=3 + `[FAIL] R1 .env` + exit 1,证明漏检由诱饵直接导致),修后同仓 `[FAIL] R6 清单来源可信 命中=1` + exit 1、越根腿 R1 内容面=0(根外文件不再被读),CI 形态(纯文本 prepare)不误伤;N217 修后四种非对象形态全 exit 2、interop_gate 字符串腿 exit 3 且合法 pass→0/fail→1 不被吞掉;N218 修后 exit 0、stdout 含 TOTAL、坏行之后会话仍摄取、`skipped={not_object:5, bad_shape:7}`;N219 修后 `3/3 通过`、null 之后 initialize 响应仍正常结算;N220 修后 `--ids` 3 个 → dry-run「清单: 1 跳过: 2」且**无正文回显**、apply「迁移: 1 跳过: 4」、`--force` 才动 immutable 目标。
|
|
60
|
+
- **守卫**(本席全部实跑,详见 §4):`scripts/test_check_publish_artifact_manifest.py` **28 passed**、`scripts/test_gate_json_shape.py` **17 passed**、`scripts/test_dsh_log_index_shape.py` **12 passed**、`scripts/test_migrate_restricted_ids.py` **14 passed**,各 rc=0;`test/bridge_nonobject_line.test.ts` **tests 3 / pass 3 / fail 0**。既有守卫未回归:`scripts/test_check_publish_artifact_scan.py`(9)、`scripts/test_registry_tarball.py`、`scripts/test_migrate_restricted.py`(15)、`scripts/test_dsh_log_index_token.py`(23)。
|
|
61
|
+
- **编号**:该席**未新增编号**——同函数/同写点的次生腿(`interop_gate` 缺 `failed` 键、`dsh_log_index` 的 `type` 非字符串与内层形态、`migrate_restricted` 的 dry-run 回显与 immutable 预检)按「次生腿」口径并入 N217/N218/N220 同号。
|
|
62
|
+
- **未做(材料声明)**:`publish-artifact-check.yml` 触发面未改(缺陷在**清单来源**,改 `paths` 不闭合该洞);`migrate_restricted` 的 passthrough 排除表(`tags`/`session`)未动(该腿本轮回合已判未证成,见 §3.2)。
|
|
63
|
+
|
|
64
|
+
### 修复⑤ 读出口零闸同批六件(N204 + N205 + N226 + N227 + N228 + N229;3 legacy + 4 新)
|
|
65
|
+
|
|
66
|
+
- **where(现码行号)**:跨层可见性**单点**(新增)`md_cg/security.py:403`(`visible_to`)/`:415`(`node_visible`,口径=子类 `_readable`;无钩子=不限制、判据异常=不可见、`can_admin` 豁免);接线点:`md_cg/trust.py:938/:953`(`describe` 的「`get` 被拒即不可见」早返回)、`:987`(`load_ledger` 逐行过滤);`md_cg/docindex.py:199-213`(摘要**预算预分配**:合并段预算 `min(len, MAX_SUMMARY//2)`、父段让位);`md_cg/provenance.py:439`(`_node_digest` 接单点,端点不可见即 `{present:False}`)、`:513-514`(`find_edges` 在谓词过滤**之前**按「两端都可见」过滤边);`md_cg/evolution.py:267/:282`(`entries` 逐行过滤,`summary/patterns/show/health_os` 全部经此入口);`md_cg/forgetting.py:305/:331`(`history` 逐行过滤);`md_cg/protect.py:193/:218`(`snapshot` 成功即 `_audit(action="snapshot")`);`md_cg/mcp_server.py:3076`(N228 `mdcg_protect` write→protect)、`:3081`(N227 `mdcg_evolution` read→evolution)、`:3084`(N229 `mdcg_forgetting_history` read→protect);职责行 `md_cg/tool_face.py:59/61/65`。
|
|
67
|
+
- **缺陷面**(材料所给):六条出口**零可见性闸**:`status/describe/load_ledger` 在 `cg.get` 被拒后回落索引条目、仍报 `ok=True` 并回带验证态与含明文证据串的裁决行;`docindex` 父摘要占满 200 字后**被合并子节的文字一个字都进不去**(合并的唯一目的正是让它们可检索);`edges` 的端点摘要直读索引、边拓扑零过滤;演化台账与遗忘留痕出口对 guest 可达(粗粒度 op 映射);`mdcg_protect` 被映射到粗粒度 `write` ⇒ 任何 `can_write` 角色可经 `action=snapshot` 真落盘且(修前)零审计。
|
|
68
|
+
- **修复**:统一范式——**新增跨层可见性单点**(`security.visible_to` / `node_visible`),6 处出口全部接线同一实现,不新写第二份密级/会话口径;工具面 op 对齐到规范出口(`protect`/`evolution`/`protect`)。
|
|
69
|
+
- **攻防前后对比**(材料所给):修前 guest `cg(op=status,node_id=私密)` → `ok=True` + `verification_state="verified"` + 状态头,`action=ledger` 明文回带「外部裁决 confirmed:…证据串」;`op=edges,expand_nodes=true` 返回指向私密节点的边与端点半截摘要、聚合 sample 回 `child->priv(derived_from)`;`mdcg_evolution` / `cg(op=info)` / `mdcg_health` **三处**命中演化台账自由文本与被引用私密节点 id;record 经 `mdcg_protect(action=snapshot)` 真落盘且 `_audit` 条数 8→8 不变。修后同一守卫逐条反转(guest 全部零命中、`AccessDenied`),且**阳性对照全绿**(可见节点验证态照常、设计者仍见私密节点与证据串、三档父长下子节文字均进摘要、两端可见的边照常、`stats` 照常且快照留痕)。
|
|
70
|
+
- **守卫**:`md_cg/test_n204_n205_n226_n227_n228_n229_exit_gates.py`(八组,**PASS=45 / FAIL=0 / LIVE=30**,本席实跑 rc=0);红基线(本席实跑)**PASS=16 / FAIL=29**。
|
|
71
|
+
- **残留(材料如实申报)**:留痕/台账内**自由文本跨节点引用**不做机械脱敏(只能按行所属 `node_id` 判定);同族 `search/get/recall` 仍会返回**可见节点自身** frontmatter 的 `derived_from`;`trust.load_ledger` 对「索引无条目」的行在有身份模型时 **fail-closed 丢弃**(设计者豁免)=行为变更;`docindex` 合并段超预算时只保前 `min(len, 200//2)` 字;工具面收紧带来的可达性变化(`mdcg_protect`/`mdcg_forgetting_history`/`mdcg_evolution` 对低权身份不再可达,库层路径仍按行过滤可用)。
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 三、发现明细
|
|
76
|
+
|
|
77
|
+
### 3.0 编号裁定表(本轮;并号归一的唯一依据)
|
|
78
|
+
|
|
79
|
+
**裁定规则**:① **树内实占·守卫文件名优先**(v22 §3.0-② 先例);② 无树内实占时保留修复席已声明编号;③ 残余按「已修新发现 → 留档新发现 → 留档 legacy」顺延;④ 新号自**实际最大值 +1** 续编且全局唯一。
|
|
80
|
+
|
|
81
|
+
**树内实占扫描(本会话实跑)**:`git ls-files` 得守卫文件名实占 `N201 / N204 / N205 / N212 / N213 / N214 / N215 / N221 / N222 / N224 / N226 / N227 / N228 / N229`;`git grep -ohE 'N[0-9]{3,4}'` 全树最大 **N229**(`N802` 为 `hive/test_exec_empty_response.py:137` 的 flake8 noqa 码);代码注释实占与守卫文件名**一致**(`md_cg/mdcg.py:1115`=N224、`:1690`=N221、`md_cg/scrub.py:739`=N222、`md_cg/forgetting.py:254`=N214、`:308`=N229、`md_cg/writelimit.py:217`=N215、`md_cg/provenance.py:431`=N226、`md_cg/evolution.py:267`=N227、`md_cg/protect.py:193`=N228、`md_cg/mcp_server.py:3076/3081/3084/3089`)。`N223` / `N225` / `N230` 树内**零命中**(本会话 `git grep` 实跑)。
|
|
82
|
+
|
|
83
|
+
| 材料中的自编号(区) | 冲突对象 | where 锚(现码) | sev | 状态 | **裁定编号** | 裁定依据 |
|
|
84
|
+
|---|---|---|---|---|---|---|
|
|
85
|
+
| N214(gatefamily) | — | `md_cg/forgetting.py:248/:273` | high | 已修 | **N214**(原号) | legacy 原号,材料与守卫文件名一致 |
|
|
86
|
+
| N215(gatefamily) | — | `md_cg/writelimit.py:211/:230` | high | 已修 | **N215**(原号) | 同上 |
|
|
87
|
+
| N221(gatefamily:`add` 跨层覆写) | generation「N221」、visibility「N221」 | `md_cg/mdcg.py:1690/:1702-1709` | high | 已修 | **N221** | 守卫文件名 `test_n214_n215_n221_n222_write_face_gates.py` 实占 + 代码注释 `mdcg.py:1690` |
|
|
88
|
+
| N222(gatefamily:`scrub.calibrate`) | generation「N222」、visibility「N222」 | `md_cg/scrub.py:739/:750` | high | 已修 | **N222** | 同上(守卫文件名 + `scrub.py:739`) |
|
|
89
|
+
| N223(gatefamily:tidy keep 写点) | visibility「N223」 | `md_cg/writelimit.py:296-318` | medium | 留档 | **N223** | 树内零实占;visibility 的台账缺陷改判 N227(`evolution.py:267` 实占) |
|
|
90
|
+
| N221(generation:派生缓存不失效) | 写面 N221 | `md_cg/mdcg.py:1115-1123` | medium | 已修 | **N224**(改判) | 守卫文件名 `test_n212_n213_n224_generation_gates.py` + 代码注释 `mdcg.py:1115` |
|
|
91
|
+
| N222(generation:索引/日志非对象) | 写面 N222 | `md_cg/mdcg.py:992/:994/:1010` | medium | 留档 | **N225**(改判) | 树内零实占;该席自留「N225 给 index/log JSON 注入旁路腿」 |
|
|
92
|
+
| N221(visibility:派生边摘要) | 写面 N221 | `md_cg/provenance.py:431/:439` | medium | 已修 | **N226**(改判) | 守卫文件名 + 代码注释 `provenance.py:431` |
|
|
93
|
+
| N223(visibility:演化台账) | 留档 N223 | `md_cg/evolution.py:267` | medium | 已修 | **N227**(改判) | 守卫文件名 + 代码注释 `evolution.py:267`、`mcp_server.py:3081` |
|
|
94
|
+
| N224(visibility:protect 面 op 映射) | generation N224 | `md_cg/mcp_server.py:3076`、`md_cg/protect.py:193` | medium | 已修 | **N228**(改判) | 守卫文件名 + 代码注释 `protect.py:193`、`mcp_server.py:3076` |
|
|
95
|
+
| N222(visibility:遗忘留痕) | 写面 N222 | `md_cg/forgetting.py:308/:331` | medium | 已修 | **N229**(改判) | 守卫文件名 + 代码注释 `forgetting.py:308`、`mcp_server.py:3084` |
|
|
96
|
+
| N226(generation 修复期残留:`_dirty` 重放遮蔽) | 实占 N226(派生边) | `md_cg/mdcg.py:1073`(重放语义) | medium | 留档 | **N230**(改判) | 树内实占·守卫文件名优先;N226 已由出处守卫与 `provenance.py:431` 实占 ⇒ 取实际最大值 N229 + 1 |
|
|
97
|
+
| N227(visibility 席上一批自报:health 计数面) | 材料 N227 | `md_cg/mdcos.py:3238` | medium | 已修 | **并入 N201 次生面** | 该席自陈「以材料为准」;计数面已随 N201 同批收口 |
|
|
98
|
+
| N218 次生腿(scripts:内层形态) | — | `scripts/dsh_log_index.py:291/:302/:318/:333/:356` | medium | 已修 | **并入 N218** | 该席自陈「同函数次生腿并入同号」 |
|
|
99
|
+
|
|
100
|
+
**编号残留声明**:`md_cg/mdcg.py:1073-1078` 一带的 `_dirty` 重放语义**树内未落 `N230` 字样**(该残留仅存于修复席的文字申报),故无一字串需要代改;报告员**未代改任何源码注释或守卫文件名**。
|
|
101
|
+
|
|
102
|
+
### 3.1 confirmed 明细(25 条;已修 22 / 留档 3=N223、N225、N230)
|
|
103
|
+
|
|
104
|
+
> origin 口径:**legacy** = 该号在早前报告首编号、本轮为复测(原轮次与复测次数按 `docs/eval/缺陷挖掘_自主迭代_v*.md` 各版本 `grep` 实得:`N201/N204/N205/N207` 首见 v23=第 24 轮,v24=第 25 轮复测,本轮=第 2 次复测;`N212–N220` 首见 v24=第 25 轮,本轮=第 1 次复测);**new** = 本轮新发现。
|
|
105
|
+
|
|
106
|
+
| # | 号 | 区 | where(现码) | sev | origin(原轮次/复测) | 状态 |
|
|
107
|
+
|---|---|---|---|---|---|---|
|
|
108
|
+
| 1 | N214 | gatefamily | `md_cg/forgetting.py:248/:273/:290` × `md_cg/mdcos.py:2790/3393` | high | legacy·第 25 轮首编号/第 1 次复测 | 已修 |
|
|
109
|
+
| 2 | N215 | gatefamily | `md_cg/writelimit.py:211/:230/:237` × `md_cg/mdcos.py:3348` | high | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
110
|
+
| 3 | N221 | gatefamily | `md_cg/mdcg.py:1690-1709/:1870` × `md_cg/mcp_server.py:3130` | high | **new** | 已修 |
|
|
111
|
+
| 4 | N222 | gatefamily | `md_cg/scrub.py:719/:739/:750/:793` | high | **new** | 已修 |
|
|
112
|
+
| 5 | N223 | gatefamily | `md_cg/writelimit.py:296-318` × `md_cg/sustain.py:953-962` × `md_cg/mcp_server.py:1587-1600` | medium | **new** | **留档** |
|
|
113
|
+
| 6 | N212 | generation | `md_cg/mdcg.py:1027/:1073/:1225` | high | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
114
|
+
| 7 | N212 次生(同 id 双文件/孤儿) | generation | `md_cg/mdcg.py:1689/:1870` | medium | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
115
|
+
| 8 | N213 | generation | `md_cg/mdcos.py:4018`(`_readable` 单点)`:4132`(`get` 盘上复核)`:3842`(`_open_content` 出口闸) | high | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
116
|
+
| 9 | N213 同根(`protect._fm` 回读判据) | generation | `md_cg/protect.py:53/:63/:86/:116` | medium | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
117
|
+
| 10 | N224 | generation | `md_cg/mdcg.py:1115-1123` | medium | **new**(材料自编 N221) | 已修 |
|
|
118
|
+
| 11 | N225 | generation | `md_cg/mdcg.py:992/:994/:1010/:1169` × `md_cg/fsutil.py:212-223/:386` | medium | **new**(材料自编 N222) | **留档** |
|
|
119
|
+
| 12 | N201 | visibility | `md_cg/mdcos.py:1736`/`:3949`/`:4250-4263` × `md_cg/mcp_server.py:3089-3096` | high | legacy·第 24 轮/第 2 次复测 | 已修 |
|
|
120
|
+
| 13 | N205 | visibility | `md_cg/trust.py:938/:987` × `md_cg/mcp_server.py:1814` | medium | legacy·第 24 轮/第 2 次复测 | 已修 |
|
|
121
|
+
| 14 | N204 | visibility | `md_cg/docindex.py:186/:199-213` | medium | legacy·第 24 轮/第 2 次复测 | 已修 |
|
|
122
|
+
| 15 | N226 | visibility | `md_cg/provenance.py:431/:439/:513-514` | medium | **new**(材料自编 N221) | 已修 |
|
|
123
|
+
| 16 | N227 | visibility | `md_cg/evolution.py:267/:282` × `md_cg/mcp_server.py:3081` | medium | **new**(材料自编 N223) | 已修 |
|
|
124
|
+
| 17 | N228 | visibility | `md_cg/mcp_server.py:3076` × `md_cg/protect.py:193/:218` | medium | **new**(材料自编 N224) | 已修 |
|
|
125
|
+
| 18 | N229 | visibility | `md_cg/forgetting.py:308/:331` × `md_cg/mcp_server.py:3084` | medium | **new**(材料自编 N222) | 已修 |
|
|
126
|
+
| 19 | N216 | scripts_ts | `scripts/check_publish_artifact.py:152/175/278/351/610/615` | high | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
127
|
+
| 20 | N217 | scripts_ts | `check_registry_tarball.py:40-53`、`check_publish_artifact.py:297/312/646/658`、`interop_gate.py:26-53` | medium | legacy·第 24 轮未编号登记 → 第 25 轮编号/第 1 次复测 | 已修 |
|
|
128
|
+
| 21 | N218 | scripts_ts | `scripts/dsh_log_index.py:249/:313/:319/:349-357/:731/:771-791` | medium | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
129
|
+
| 22 | N219 | scripts_ts | `src/bridge.ts:233-249` | medium→**high** | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
130
|
+
| 23 | N220 | scripts_ts | `scripts/migrate_restricted.py:69-99/101-106/140/146` | medium | legacy·第 25 轮/第 1 次复测 | 已修 |
|
|
131
|
+
| 24 | N218 次生腿(内层非对象) | scripts_ts | `scripts/dsh_log_index.py:291/:302/:318/:333/:356` | medium | **new**(并入 N218) | 已修 |
|
|
132
|
+
| 25 | N230 | generation(修复期残留) | `md_cg/mdcg.py:1073-1078`(`_dirty` 重放遮蔽) | medium | **new**(材料自编 N226,并号改判) | **留档** |
|
|
133
|
+
|
|
134
|
+
**要点补记**:
|
|
135
|
+
- **N219 严重度上抬**(材料自陈):按「崩溃」类别与同族先例(批次 67 修的 N206「一行非对象 JSON 致 MCP 进程死亡」定 high)取 **high**;触发值窄(JSON 标量中仅 `null` 确定),但后果是宿主进程死亡 ⇒ 记忆面随宿主一起不可用。
|
|
136
|
+
- **N212 附带读码更正**(材料所给,供避免照抄失效陈述):`docs/eval/P1b2_读面代际修复_v1.0.md:72` 括注「日志记录仍须快照重写才并入」与实现相反——真重载走 `_load_index` 会重放分片日志,真正的门槛是**签名**而非「日志需快照」。同 tick mtime 碰撞面在 v23 §3.3 已判加固项,本轮不复报。
|
|
137
|
+
- **反向清点(材料所给,支持「同族已清完」的判断)**:full 面同批横扫(guest/record)显示只读出口命中仅 `mdcg_evolution`/`mdcg_health`/`cg:info`(=N227)与 `cg:edges`(=N226,需 `expand_nodes`);`mdcg_recall/search/get/identity/metacognition/self_state/predict/causal/whitebox/whoami/watermarks/service_info/review_list/review_records/review_rounds` 与 `stg` 全 op **零命中**(designer 正控命中=True)。
|
|
138
|
+
- **N225 的严重度界定依据**(材料所给):工具层调用被 `md_cg/mcp_server.py:3706-3709` 的入口兜底转成 `-32603`(不杀进程),但**构造期无兜底** ⇒ 启动失败即记忆面全不可用。
|
|
139
|
+
|
|
140
|
+
### 3.2 证伪与剔除(3 条 + 1 半条)
|
|
141
|
+
|
|
142
|
+
| # | 出处 | 原陈述 | 裁定 | 依据 |
|
|
143
|
+
|---|---|---|---|---|
|
|
144
|
+
| 1 | gatefamily 区 · N214 的 evidence ④**子claim** | 「`_forgetting.jsonl` 的 MERGE 行不含被改目标 id,被改节点在留痕中完全不可见」 | **证伪(不推翻 N214 主体)** | 材料实测该行 `reason` 为「重复度 1.00≥0.85(并入 `n26_self`,强化既有)」——目标 id **明文在 reason 文本里**(`forgetting.py:217` 把 `red["with"]` 拼进 `why`),只是**结构化 `node_id` 字段**记的是新 id;「留痕不含目标」**仅对 CONVERGE 路成立**(该路实测 anchor 路 `_forgetting.jsonl` 末行确无 anchor id)。N214 缺陷仍成立(无快照、无审计、无层闸与保护闸)。 |
|
|
145
|
+
| 2 | visibility 区 · 自设同族探针(**非候选清单项**) | `mdcg_watermarks` 直出 `sources` 键(源名/会话目录名/入池根路径)疑为同族未接线读点 | **不计缺陷、不给编号** | 读码上形式像同族出口,但临时库实测:用 `DSHSessionSource` 摄取合成会话(目录名带 `SECRET` 标记、`Ingestor.ingest` 返回 `new_events=0`)→ 水位表为空 → `guest mdcg_watermarks = {'watermarks': {}}`、`cg:info` 含会话 id=False,**无实测泄漏证据**;仅登记为「同族出口待观察」。 |
|
|
146
|
+
| 3 | scripts_ts 区 · `migrate_restricted` 排除表 | 「排除表九键不含 `tags`/`session` → 影响 restricted 可见性的腿」 | **未证成、剔除** | 读码核实:`md_cg/mdcos.py:4047-4050`(`_readable` 的 restricted 分支)只判 `principal.allows("internal") ∧ can_read_restricted(principal)`,**不读 `session`、`tags` 亦无闸作用**,故「缺键」本身不构成危害;本次仅按「`--ids` 未复查目标密级与层 + 恒定 `override=True` 破层保护闸」定级。 |
|
|
147
|
+
| 4 | scripts_ts 区 · 同条**半条** | 「异 actor 的绑定档节点在 `cg.get` 即被 SKIP ⇒ secret/private 密级下调腿」 | **半条不予确认** | 材料自陈**未能复现 SKIP 形态**(同 actor 场景下 private 目标同样被改写成功),故该半条不主张。 |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 四、验证(门禁)
|
|
152
|
+
|
|
153
|
+
以下全部为**本报告会话第一手实跑**(命令与结果原样;除第 8 项外均在本机仓库根运行,临时副本/临时库均在系统临时目录内、测毕删除):
|
|
154
|
+
|
|
155
|
+
1. **全量回归**:`python -X utf8 scripts/run_tests.py --jobs 4` → `===== SUMMARY 245/245 通过,5 跳过(依赖缺失/平台不符) =====`、**退出码 0**(连跑两次一致)。日志逐行核实:四条新 md_cg 守卫与五件 scripts 守卫**均在收集面内**(`PASS md_cg.test_n201_proposal_visibility` / `test_n204_n205_n226_n227_n228_n229_exit_gates` / `test_n212_n213_n224_generation_gates` / `test_n214_n215_n221_n222_write_face_gates`、`PASS scripts.test_check_publish_artifact_manifest` / `test_gate_json_shape` / `test_dsh_log_index_shape` / `test_migrate_restricted_ids` 等),PASS 行计数 245 条。
|
|
156
|
+
2. **四条新 md_cg 守卫直跑**(`python -X utf8 -m <module>`):`test_n214_n215_n221_n222_write_face_gates` → **31 passed, 0 failed (live=22)**;`test_n212_n213_n224_generation_gates` → **PASS=42 FAIL=0 LIVE=26**;`test_n201_proposal_visibility` → **PASS=22 FAIL=0 LIVE=13**;`test_n204_n205_n226_n227_n228_n229_exit_gates` → **PASS=45 FAIL=0 LIVE=30**;各 rc=0(合计 140 断言全绿)。
|
|
157
|
+
3. **红基线独立复现**(把 `md_cg` 整包复制到系统临时目录,用 `git show HEAD:md_cg/<file>` 覆盖本轮改动的文件后跑同一守卫;临时副本已删):
|
|
158
|
+
- 写面四写点(覆盖 `forgetting/writelimit/mdcg/scrub/mdcos.py`)→ `10 passed, 21 failed (live=22)`;
|
|
159
|
+
- 代际批(覆盖 `mdcg/mdcos/protect.py`)→ `PASS=12 FAIL=30 LIVE=26`;
|
|
160
|
+
- 提案可见性(覆盖 `mdcos/mcp_server/tool_face.py`)→ `PASS=13 FAIL=9 LIVE=13`;
|
|
161
|
+
- 读出口批(覆盖 `security/mdcos/trust/docindex/provenance/evolution/forgetting/protect/mcp_server.py`)→ `PASS=16 FAIL=29 LIVE=30`。
|
|
162
|
+
**四处数字与各修复席自报逐字一致**,红项条目名(如 `1a`/`2a`/`3a`/`4a`/`5a-5d`/`6a-6h`/`7a`/`8a-8i`)逐一核对无误 ⇒ 「红转绿」不是单方声明。
|
|
163
|
+
4. **scripts 侧四件守卫直跑**:`python -X utf8 scripts/test_check_publish_artifact_manifest.py` → **28 passed, 0 failed, 0 skipped**;`test_gate_json_shape.py` → **17 passed**;`test_dsh_log_index_shape.py` → **12 passed**;`test_migrate_restricted_ids.py` → **14 passed**;各 rc=0。**scripts 子集**:`python -X utf8 scripts/run_tests.py scripts` → `SUMMARY 13/13 通过,0 跳过`、rc=0。
|
|
164
|
+
5. **TS 守卫**:`node --import tsx --test test/bridge_nonobject_line.test.ts` → `tests 3 / pass 3 / fail 0 / cancelled 0 / skipped 0`、rc=0(宿主无 `uncaughtException`,null 之后协议面仍结算)。
|
|
165
|
+
6. **`npm run gate`**:**退出码 0、`VERDICT=PASS`——两者一致**。「结论」段 `FAIL 规则数=0`;六规则全 PASS(`R1 凭据/密钥面 文件面=0 内容面=0`、`R2`、`R3`、`R4 非追踪件面 非追踪=28 允许=28`、`R5 清单路径安全`、`R6 清单来源可信 json 候选=1 清单候选=1`);发布清单 `文件数=1442`;链上其余检查:`check_unreachable` 458 文件/命中 0/语法失败 0、`cogmap check` 通过(cg 36 op / stg 4 op / whitebox 6 action / mdcg_* 31 个)、`link_check` `OK=228 BROKEN=0`、`workspace_index --check` `[OK](顶层目录 20 · 追踪 2031 件)`、`verify_discipline` `结论:9/9 目标一致`。
|
|
166
|
+
7. **cargo:未运行**。本轮零 Rust 改动(`git status` 改动集为 `md_cg/*.py`、`scripts/*.py`、`src/bridge.ts` 与新增守卫,无 `.rs`/`hive/` 条目),材料亦记「未运行(Rust 面无改动)」——**本席未实跑,如实标注**。
|
|
167
|
+
8. **隔离与清理**:全部守卫/复现均使用系统临时目录(含哑主密钥与临时令牌库),未触真实令牌库、在役数据目录、真实 serve 与 DSH 探针节点 `prop_*`;本席创建的红基线临时副本已 `rm -rf` 删除;开工时 `git status --porcelain` 为 30 项,收尾复核为 **31 项=原 30 项逐条一致 + 本报告自身**(`docs/eval/缺陷挖掘_自主迭代_v25.md`,本报告落点)⇒ **本席未修改任何产品文件**。
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 五、遗留清单(含未修项的建议去向)
|
|
172
|
+
|
|
173
|
+
| # | 号 | where(现码) | sev | 原轮次/复测 | 状态与建议去向 |
|
|
174
|
+
|---|---|---|---|---|---|
|
|
175
|
+
| 1 | **N223** | `md_cg/writelimit.py:296-318`(keep 侧写盘,对照成员侧 `:306` 有 protected/immutable 跳过)× `md_cg/sustain.py:953-962` × `md_cg/mcp_server.py:1587-1600` | medium | 本轮首报 | **留档,交编排裁定**:材料自陈「是否接线由编排裁定(若判『由设计豁免』可剔除)」;危害低于 N214/N215/N221/N222(不删原文、不改 importance)。**建议**:下轮低危批次按 `guard_overwrite` 单点接线(keep 侧补成员侧同款判据 + 层闸),并保留「同组保留最早节点」的既有语义反向腿 |
|
|
176
|
+
| 2 | **N225** | `md_cg/mdcg.py:992/:994/:1010/:1169` × `md_cg/fsutil.py:212-223/:386` | medium | 本轮首报(材料自编 N222) | **建议列为下轮 md_cg 面首选**:具「构造期 fail → 记忆面全不可用」的崩溃色彩(启动 `rc=1`),且与已修 N206/N217/N218 同族、是 N212/N213 修复批的**外围旁路入口**;修法=装载面 `isinstance(d, dict)` 类型闸 + 分片行非对象跳过(`_load_index` / `compact_index` / `_maybe_reload_index` 三处同口径) |
|
|
177
|
+
| 3 | **N207** | `src/cli.ts:46-58`(`:50` `pathToFileURL(resolve(entry)).href`)、`src/init.ts:342-354`(`:346` 同款) | medium | 第 24 轮首编号/第 2 次复测(v24 留档) | **留档**:脚本面排序末位(本轮 5 席已满);**建议**下轮 TS/CLI 面 `realpathSync` 双向归一 + 一条 junction/软链形态守卫(POSIX 实链路本机不可执行,属未实测腿) |
|
|
178
|
+
| 4 | **N230** | `md_cg/mdcg.py:1073-1078`(`_dirty` 重放遮蔽) | medium | 本轮修复期新发现(并号改判) | **留档**:候选/元数据面仍按陈旧密级归属列出该 id 的存在与 `path/tags`(**正文面已被 `_open_content` 闸关死**);修它需给 `_dirty` 引入时序/代际排序,会动「未落盘写入不因重载从检索侧消失」的既有不变量,超出本批最小改动 ⇒ 建议单列一批,并先补一条「陈旧 `_dirty` 遮蔽」的红守卫 |
|
|
179
|
+
| 5 | N201 残留(静态明文面) | `md_cg/mdcos.py:1736/:3949`(`hippocampus/inbox.jsonl` 的 `content` 仍明文) | — | 本轮刻意不改 | **交「提案落地策略」一并定**:若走静态封套,须先解决「跨身份复核者读不开候选 / accept 落库后永久不可读」这一语义冲突(材料已实测 DEK 跨身份解封失败) |
|
|
180
|
+
| 6 | 各席自陈残留(不入册、仅登记) | ①非受保护层的**出带外(不经 API、不走写日志)**文件改写仍不被 `_fm` 判据采纳(代价不成比例);②演化台账 / 遗忘留痕内**自由文本跨节点引用**不做机械脱敏;③`search/get/recall` 仍返回**可见节点自身** frontmatter 的 `derived_from`(可能含不可见节点 id);④`trust.load_ledger` 对「索引无条目」的行 fail-closed 丢弃=行为变更;⑤`docindex` 合并段超预算时只保前 `min(len, 200//2)` 字;⑥工具面收紧(`mdcg_protect`/`mdcg_forgetting_history`/`mdcg_evolution` 对低权身份不再可达);⑦`publish-artifact-check.yml` 触发面未改;⑧`migrate_restricted` 排除表 `tags/session` 未动 | — | — | 建议按「下轮低危批次顺手清」原则登记,不单独立号;其中 ②③ 属**已知可接受边界**(行级/节点级判定无法覆盖自由文本语义),建议在纪律文档中留一句口径 |
|
|
181
|
+
| 7 | 测试卫生(非缺陷、未编号) | `md_cg/test_review_cli_visibility.py` 在 Windows 上每次运行残留一个 `clivis_1_*` 临时目录(`finally` 的 `rmtree(ignore_errors=True)` 被残留句柄挡住) | low | 材料附注 | 建议后续批次顺手修(测试卫生,非产品缺陷) |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 六、纪律合规声明
|
|
186
|
+
|
|
187
|
+
1. **未 commit**:本轮全部修复席**仅 `git add` 暂存**新增守卫(用于通过发布门 R4 的非追踪件面),**无任何 commit**;本席**未改任何产品文件**(开工 `git status --porcelain`=30 项,收尾=31 项=原 30 项逐条一致 + 本报告自身文件)。
|
|
188
|
+
2. **攻击复现环境**:所有攻击/红基线复现均在**系统临时目录 + 哑主密钥 + 临时令牌库**内进行(`MDCG_ROOT`/`MDCG_AUX_ROOT`/`MDCG_TOKEN_FILE` 全指临时目录),未触**真实令牌库、在役数据目录、真实 serve、DSH 探针节点 `prop_*`**;本席创建的红基线副本与临时库**测后已删**。
|
|
189
|
+
3. **结论引证**:本报告每条结论均引 `path:line`(现工作区行号,逐处 `grep -n`/读取核实)或本会话实跑输出;凡「材料所给」的探针输出(含各修复批的攻防前后对比、各席红基线数字、其它守卫的断言数)均已标注来源,**未冒充为本席实跑**。
|
|
190
|
+
4. **编号纪律**:新号自 N221 续编、全局唯一(N221–N229 九条新发现 + N230 残留);并号已按「树内实占·守卫文件名优先」裁定并给出裁定表(§3.0);**报告员未代改任何源码注释或守卫文件名**。
|
|
191
|
+
5. **本报告自身门禁**:不含真实凭据/PII 形态串,不写本机绝对路径(工作区路径以仓库相对路径书写;系统临时目录一律写「系统临时目录」)。
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 七、跳过项及原因
|
|
196
|
+
|
|
197
|
+
| # | 跳过项 | 原因 |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| 1 | **cargo 套件** | 本轮零 Rust 改动(改动集无 `.rs`/`hive/` 条目),材料亦记未运行;**本席未实跑** |
|
|
200
|
+
| 2 | **真实 CI(ubuntu runner)与真实 registry 下载腿** | 不接触在役面/网络面;N216/N217 的 registry 模式仅以进程内桩 `http_get_json` 与合成 tarball 覆盖(材料所给) |
|
|
201
|
+
| 3 | **`npm test` 全量 TS 套件** | 本席只跑了 ask 相关单件 `test/bridge_nonobject_line.test.ts`(3/3);全量 `npm test` 未跑(材料记 64 tests / pass 63 / fail 0 / skipped 1,属材料所给,本席不复述为已跑)。`npm run gate` 内的 `npm pack` 已实际触发构建路径 |
|
|
202
|
+
| 4 | **POSIX 真实符号链接链路(N207)** | 本机 win32 不可执行;材料以 NTFS 目录联接(junction,与 POSIX 符号链接同一 realpath 机制)建模并如实标注 |
|
|
203
|
+
| 5 | **各修复席红基线的第 5 处(scripts/TS 面)** | 本席复现了四处 md_cg 面红基线(§4-3),**scripts/TS 面红基线未复现**(仅跑了修后绿态);该项数字属材料所给 |
|
|
204
|
+
| 6 | **N207 修复** | 属留档项(脚本面排序末位、本轮 5 席已满),本轮不做 |
|
|
205
|
+
| 7 | **`inbox.jsonl` 静态封套** | 刻意不做(跨身份复核语义冲突,材料给出 DEK 跨身份解封失败实测支撑),见 §2-修复③ |
|
|
206
|
+
| 8 | **hive / swarm / compiler 面深挖** | 本轮定位为 md_cg 核心面收尾 + 脚本/TS 门禁面,其余区未列入本轮范围 |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 附录:双清单自查
|
|
211
|
+
|
|
212
|
+
**清单 A(材料条目逐条落表核对)**
|
|
213
|
+
- 四区 confirmed 24 条 → §3.1 表 1–24 行逐条落位(gatefamily 1–5 / generation 6–11 / visibility 12–18 / scripts_ts 19–24);修复期残留 1 条 → §3.1 第 25 行(N230)。
|
|
214
|
+
- 三区 rejected 共 3 条 → §3.2 表 1–3 行;另 scripts 区同条「半条」→ §3.2 第 4 行。
|
|
215
|
+
- 修复结果 5 批 → §2 修复①–⑤逐批落位;每批含 where / 缺陷面 / 修复 / 攻防前后对比 / 守卫五项。
|
|
216
|
+
- 留档未修 3 项(N223/N225/N207)→ §5 第 1–3 行;本轮修复期残留 N230 → §5 第 4 行。
|
|
217
|
+
- 材料门禁结果「四区确认 25 个、修复 5 项、留档 3 项」→ 25=24+1(§3.1 表 25 行)、修复 5 项=§2 五批、留档 3 项=§5 前三行,口径一致(计数方法已在 §1 声明)。
|
|
218
|
+
|
|
219
|
+
**清单 B(本席实跑命令与结果,逐条可复现)**
|
|
220
|
+
1. `python -X utf8 scripts/run_tests.py --jobs 4` → `SUMMARY 245/245 通过,5 跳过`、rc=0(跑两次一致)。
|
|
221
|
+
2. `python -X utf8 -m md_cg.test_n214_n215_n221_n222_write_face_gates` → `31 passed, 0 failed (live=22)`、rc=0。
|
|
222
|
+
3. `python -X utf8 -m md_cg.test_n212_n213_n224_generation_gates` → `PASS=42 FAIL=0 LIVE=26`、rc=0。
|
|
223
|
+
4. `python -X utf8 -m md_cg.test_n201_proposal_visibility` → `PASS=22 FAIL=0 LIVE=13`、rc=0。
|
|
224
|
+
5. `python -X utf8 -m md_cg.test_n204_n205_n226_n227_n228_n229_exit_gates` → `PASS=45 FAIL=0 LIVE=30`、rc=0。
|
|
225
|
+
6. 红基线四处(`mktemp -d` + `cp -r md_cg` + `git show HEAD:md_cg/<file>` 覆盖 + `PYTHONPATH=<tmp> python -X utf8 -m <guard>`)→ `10 passed/21 failed (live=22)`、`PASS=12 FAIL=30`、`PASS=13 FAIL=9`、`PASS=16 FAIL=29`;临时副本已删。
|
|
226
|
+
7. `python -X utf8 scripts/test_check_publish_artifact_manifest.py|test_gate_json_shape.py|test_dsh_log_index_shape.py|test_migrate_restricted_ids.py` → `28/17/12/14 passed`,各 rc=0;`python -X utf8 scripts/run_tests.py scripts` → `13/13`、rc=0。
|
|
227
|
+
8. `node --import tsx --test test/bridge_nonobject_line.test.ts` → `tests 3 / pass 3 / fail 0`、rc=0。
|
|
228
|
+
9. `npm run gate` → 退出码 0、`VERDICT=PASS`(一致)、`FAIL 规则数=0`、R1–R6 全 PASS。
|
|
229
|
+
10. 编号核对:`git ls-files`(守卫文件名实占表)、`git grep -ohE 'N[0-9]{3,4}'`(最大 N229;`N802`=hive noqa 码)、`git grep -n "N223|N225|N230"`(零命中)。
|
|
230
|
+
11. 读码核实(现码行号):`md_cg/mdcg.py:992/994/1010/1027/1073/1115-1123/1225/1557-1558/1689/1690-1709/1870`;`md_cg/mdcos.py:1736/1955/2790/3238/3348/3393/3842/3949/4018/4132/4246-4263`;`md_cg/forgetting.py:248/254/273/290/305/308/331`;`md_cg/writelimit.py:211/217/230/237/296-318`;`md_cg/scrub.py:719/739/750/793`;`md_cg/protect.py:53/63/86/116/193/218/358`;`md_cg/security.py:403/415`;`md_cg/trust.py:938/953/987`;`md_cg/docindex.py:186/199-213`;`md_cg/provenance.py:431/439/513-514`;`md_cg/evolution.py:267/282`;`md_cg/mcp_server.py:1634/3076/3081/3084/3089-3096/3130-3131`;`scripts/check_publish_artifact.py:152/175/278/351/610/615`;`src/cli.ts:46-50`、`src/init.ts:342-346`。
|
|
@@ -1,27 +1,76 @@
|
|
|
1
1
|
# 检索算法口径对照 v0.1(批次 15)
|
|
2
2
|
|
|
3
3
|
> 2026-09-23 使用者口径定案:**统一翻译为中文 → 中文归一化到标准中文集(atoms 词表)→ 检索**。
|
|
4
|
+
> **2026-09-30 使用者裁定收窄作用域**:归一层**只对英文内容做翻译归一,中文内容原样不动**。
|
|
5
|
+
> **2026-09-30 使用者裁定翻缺省**:`MDCG_UNIFY_QUERY` 由「默认开」翻为「**未设即关**、
|
|
6
|
+
> 显式 `=1` 才开」——本层本职是让英文 query 命中中文节点,对中文检索池是纯开销
|
|
7
|
+
> (locomo-zh-500 实测缺省关态 lexical hit@1 96.4% / lexical+fuzzy 97.2%,
|
|
8
|
+
> 开态 95.8% / 96.6%);两侧三态判据同语义。
|
|
4
9
|
> 本文是该口径的两侧实现对照与残留差距真源——两侧实现以本文为准,改动检索口径先改本文。
|
|
5
10
|
|
|
6
11
|
## 一、统一管线(两侧同构)
|
|
7
12
|
|
|
8
13
|
```
|
|
9
14
|
query(任意语言)
|
|
10
|
-
│ MDCG_UNIFY_QUERY=
|
|
15
|
+
│ MDCG_UNIFY_QUERY=1 可整体开(**默认关**——2026-09-30 裁定:本层只服务英文 query)
|
|
11
16
|
▼
|
|
12
|
-
[统一归一层 unify]
|
|
13
|
-
├─
|
|
14
|
-
|
|
17
|
+
[统一归一层 unify] —— 作用域(2026-09-30 收窄):**只译英文内容,中文原样不动**
|
|
18
|
+
├─ 分段判据单点:中文 = CJK 统一表意文字基本区 U+4E00–U+9FFF
|
|
19
|
+
│ Python `semantic/canonical.py::is_zh_char` / Rust `text.rs::is_zh` 同判据
|
|
20
|
+
├─ query 无 ASCII 字母 → 原样返回(纯中文零变更纪律,不 strip)
|
|
21
|
+
├─ 中文段 → **逐字保留、绝不切分、绝不送 segment**
|
|
22
|
+
├─ 含 ASCII 字母的非中文段 → en 形态归一(小写/停用词/时态归零)
|
|
15
23
|
│ → en→zh 词表映射(en_zh_map.json,28478 词,CEDICT 全链派生)
|
|
16
24
|
│ → 未登录词原样保留(unknown_keep = 词表边界,非错误)
|
|
17
|
-
|
|
25
|
+
│ → 映射产物经 segment 贪心最长匹配(zh_keys 204 标准原子,键长降序)
|
|
26
|
+
├─ 不含 ASCII 字母的非中文段(数字/标点)→ 原样保留
|
|
27
|
+
├─ 各段按原顺序单空格 join;空白(段内/段间)一律折叠为单空格
|
|
28
|
+
├─ 归一产物为空(折空白后)→ **回退原入参本身(含首尾空白,不 trim)**——
|
|
29
|
+
│ 两侧同语义:Python `return text` / Rust `query.to_string()`(见 §六)
|
|
18
30
|
▼
|
|
19
|
-
标准原子序列(空格 join,如 "我 吃 牛肉 昨天"
|
|
31
|
+
标准原子序列(空格 join,如 "我 吃 牛肉 昨天";
|
|
32
|
+
中夹英 "领养 LGBTQ 群体" → **Python 侧**原样,旧口径会切成
|
|
33
|
+
"领 养 LGBTQ 群 体";Rust 侧对未登录大写词的产物是
|
|
34
|
+
"领养 lgbtq 群体"——**两侧既有非对称**见下「一之补」表第 ① 条)
|
|
20
35
|
▼
|
|
21
36
|
检索各路(lexical / bucket / entity / graph,RRF 融合)
|
|
22
37
|
—— doc 侧正文不动(真源+原始双保留纪律),只有 query 侧归一
|
|
23
38
|
```
|
|
24
39
|
|
|
40
|
+
**为何收窄(2026-09-30 定因,实测)**:旧口径「query 含任一 ASCII 字母即整条
|
|
41
|
+
归一」会把**中夹英** query 的中文部分逐字切开(「自我接纳」→「自 我 接 纳」、
|
|
42
|
+
「慈善跑」→「慈 善 跑」)。locomo-zh-500 公开题池(567 池 / 500 题,
|
|
43
|
+
`eval_common` jaccard + GLOBAL_CAP 解除,k=5):现状 lexical hit@1 = 94.4% /
|
|
44
|
+
lexical,fuzzy = 87.2%;收窄后 **95.8% / 96.6%**;归一层全关 96.4% / 97.2%。
|
|
45
|
+
500 题里含 ASCII 字母的 145 条**全部**也含中文(题池无纯英文 query)。
|
|
46
|
+
复现:`python -X utf8 -m md_cg.bench_locomo_zh_public`。
|
|
47
|
+
**2026-09-30 翻缺省后**:缺省态(= 归一层关)即取 **96.4% / 97.2%** 这一行,
|
|
48
|
+
显式 `MDCG_UNIFY_QUERY=1` 才回到 95.8% / 96.6%。
|
|
49
|
+
(以上为本次收窄的定点实测读数,仅作口径变更的证据——仓库对外参考值/
|
|
50
|
+
README 数字不因本任务变动,数字回流由编排侧另行核。)
|
|
51
|
+
|
|
52
|
+
### 一之补 · 两侧既有非对称(非本次收窄引入,2026-09-30 实测)
|
|
53
|
+
|
|
54
|
+
下表三条是两侧实现的**既有分歧**,非 2026-09-30 收窄引入、也非本清理批次引入——
|
|
55
|
+
**收窄前对照实测同分歧**(收窄前 = `HEAD~1`:Python 侧按
|
|
56
|
+
`git show HEAD~1:md_cg/semantic/unify.py` 的整条归一路径
|
|
57
|
+
`" ".join(query_atoms(t))` 实跑;Rust 侧用 `git archive HEAD~1 rust` 导出到临时目录、以临时
|
|
58
|
+
cargo 工程(独立构建目录,不碰仓库 `rust/target/`)重建后实跑 `Atoms::unify`);该提交亦**未触碰**
|
|
59
|
+
`en_normalizer.py`(`git show --stat HEAD` 可见)。读数取法:Python 走
|
|
60
|
+
`md_cg.semantic.unify.unify_query`,Rust 走 `atoms.rs::Atoms::unify`
|
|
61
|
+
(两侧消费同一份 `en_zh_map.json`)。
|
|
62
|
+
|
|
63
|
+
| # | 形态 | Python 产物 | Rust 产物 | 根因(各自实现内) |
|
|
64
|
+
|---|---|---|---|---|
|
|
65
|
+
| ① | 未登录**大写**英文词 | `领养 LGBTQ 群体` → `领养 LGBTQ 群体`;`AI 记忆 系统` → `AI 记忆 系统`(保留原 case) | `领养 lgbtq 群体`;`ai 记忆 系统` | Python:未登录词 unknown_keep 原样;Rust:先经 `normalize_en`(一律 lower)再查表,未命中以 lower 形占位 |
|
|
66
|
+
| ② | 命中词表的**专名** | `Paris 报告` → `Paris 巴 黎 报告`(原词 + 译词**双原子**) | `巴 黎 报告`(只出译词) | Python `en_normalizer` 的 `is_proper` + 词表命中 → `proper_mapped_both` 双原子;Rust 无该分支 |
|
|
67
|
+
| ③ | 字母与数字**同段** | `beef 2024 报告` → `牛肉 报告`(**丢数字**) | `牛肉 2024 报告`(**保数字**) | Python `normalize_en_query` 分词类 `[A-Za-z\u4e00-\u9fff]+` 不含数字;Rust 侧 ASCII 数字词元保留、未登录则原样占位 |
|
|
68
|
+
|
|
69
|
+
**为何 fixture 避开这三类形态**:`md_cg/semantic/unify_fixture.json` 是**两侧钉同一期望值**的
|
|
70
|
+
逐位对拍件(Rust 侧 `include_str!` 编译期嵌入),上表三条两侧产物不同 ⇒ 钉不出同一期望值,
|
|
71
|
+
故该文件只登记「两侧同构」形态,`_caveat` 亦指向本节(正文为真源)。**是否把某一侧改成另一侧
|
|
72
|
+
口径,见 §七 待裁定项——本文不自行定方向。**
|
|
73
|
+
|
|
25
74
|
## 二、词表真源单侧化(架构决策)
|
|
26
75
|
|
|
27
76
|
| 资产 | 真源 | 产物 | Rust 消费 |
|
|
@@ -41,7 +90,9 @@ query(任意语言)
|
|
|
41
90
|
|
|
42
91
|
| 环节 | Python | Rust | 对齐守卫 |
|
|
43
92
|
|---|---|---|---|
|
|
44
|
-
| 统一归一入口 | `semantic/unify.py::unify_query`(三处 search
|
|
93
|
+
| 统一归一入口 | `semantic/unify.py::unify_query`(三处 search 入口接线;`unify_on()` 缺省关,显式 `"1"` 才开) | `atoms.rs::Atoms::unify`(`engine.search` 单点接线;`from_env()` 未设/`"0"`→`None`,显式 `"1"`→`Some`) | rank_parity 逐位对拍——**两个口径,读数不同**:内建合成语料 **10/10 绿**(rc=0,**门禁腿跑的就是这个口径**);`--dataset` 口径**缺省 10/10 绿**(2026-09-30 翻缺省后),**显式 `MDCG_UNIFY_QUERY=1` 时 8/10(既有差分,差在归一层)**,见 §五.2。三态一致性另由 `md_cg/test_unify_default_off.py` 钉住 |
|
|
94
|
+
| 中文段分段判据(单点) | `semantic/canonical.py::is_zh_char`(U+4E00–U+9FFF;边界=**长度恰为 1**,空串/多字符串一律假) | `text.rs::is_zh`(同区间;收 `char`,天然无空/多字符二态) | `semantic/unify_fixture.json` 两侧逐位对拍(19 例) |
|
|
95
|
+
| 归一层作用域(只译英文) | `md_cg/test_unify_scope.py` | `atoms::tests::unify_mixed_fixture_matches_python` | 同一 fixture 两侧钉同一期望值;Python 侧另有**对产物**的结构判据(第 6 节:中文段逐字保留、不得送 segment) |
|
|
45
96
|
| en 形态归一 | `en_normalizer.strip_tense` | `text.rs::strip_tense_en`(golden 对齐测试) | golden_python_alignment |
|
|
46
97
|
| en→zh 查表 | normalize_en_query 查链(extra→EN_ZH→CEDICT) | en2zh 查表(键=strip 后原形,lower) | 同一 en_zh_map.json |
|
|
47
98
|
| segment | `zh_en_atoms.segment` | `atoms.rs::segment`(键长降序贪心) | atoms 三测 + rank_parity |
|
|
@@ -68,9 +119,25 @@ path_weights 调优消化。
|
|
|
68
119
|
`swarm-dispatch`)时,中文 query 经 `bucket_key_readable`+`domain_similarity`
|
|
69
120
|
恒 no_key_match → 不收敛。恰击中 S1b 设计目标场景(真实库 91.1% 中文节点)。
|
|
70
121
|
方向:桶键双语化 / domain_similarity 中文面。
|
|
71
|
-
2.
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
2. **对拍逐位残留——两个口径,读数不同(门禁绿 ≠ dataset 对拍绿)**
|
|
123
|
+
(issue #29 未清项的精确化;2026-09-30 实测,两侧实际口径均 jaccard):
|
|
124
|
+
|
|
125
|
+
| 口径 | 命令 | 逐位 | 集合 | top-1 | rc |
|
|
126
|
+
|---|---|---|---|---|---|
|
|
127
|
+
| **内建合成语料**(**门禁腿跑的就是这个口径**) | `python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe` | **10/10** | 10/10 | 10/10 | **0(绿)** |
|
|
128
|
+
| `--dataset` 口径(**缺省**:归一层缺省关) | 同命令 + `--dataset scripts/retrieval_dataset.json` | **10/10** | 10/10 | 10/10 | **0(绿)**(2026-09-30 翻缺省后实测) |
|
|
129
|
+
| 同上 + 归一层**显式开** | 再加 `MDCG_UNIFY_QUERY=1` | **8/10** | 8/10 | 9/10 | **1(差分)** |
|
|
130
|
+
|
|
131
|
+
两条 DIFF = `soul hub hot cache` 与 `token verification fail closed`。差分出在
|
|
132
|
+
**归一层**(关 unify 即 10/10),但**不是本次收窄引入**:上一批复核员把 HEAD
|
|
133
|
+
(=收窄产物,`git archive HEAD` 导出 + 独立 `CARGO_TARGET_DIR` 重建)同口径实跑
|
|
134
|
+
同为 8/10 ⇒ **既有状态**(三项读数出自上一批复核;本批复跑的是工作树同三口径,
|
|
135
|
+
读数逐位一致)。机制是两侧 terms 展开对英文保留词的处理与 graph 路种子。
|
|
136
|
+
**2026-09-30 缺省翻关的连带效应**:`--dataset` 口径的**缺省态**读数由 8/10 变为
|
|
137
|
+
**10/10 rc=0**(缺省 = 归一层关 = 原来的「全关」行);两条 DIFF 只在**显式
|
|
138
|
+
`MDCG_UNIFY_QUERY=1`** 时重现,逐位重现(8/10 · 8/10 · 9/10,DIFF 两条同名前缀)。
|
|
139
|
+
**是否把 `--dataset` 口径并入门禁腿:见 §七 待裁定项 1**——本文不自行决定
|
|
140
|
+
(该口径缺省已绿,但显式开归一层时恒 8/10,并入前须先裁定该差分归属)。
|
|
74
141
|
3. **CEDICT 低置信错译**:dispatch→「结果」类第一义项直译(LoCoMo 报告发现 5
|
|
75
142
|
同模式)。en_zh_map 保留 CEDICT 层(覆盖面)+ low_confidence 观测,错译随
|
|
76
143
|
用随修进 EN_ZH 人工层。
|
|
@@ -79,7 +146,65 @@ path_weights 调优消化。
|
|
|
79
146
|
|
|
80
147
|
## 六、变更纪律
|
|
81
148
|
|
|
82
|
-
- `MDCG_UNIFY_QUERY`
|
|
149
|
+
- `MDCG_UNIFY_QUERY` **默认关**(2026-09-30 使用者裁定,由「默认 "1"」翻为「未设即关」);
|
|
150
|
+
两侧三态判据同语义,**唯一开态 = 显式 "1"**:
|
|
151
|
+
未设 → Python `unify_on()` `False` / Rust `Atoms::from_env()` `None`;
|
|
152
|
+
`"0"` → 同上(关);`"1"` → `True` / `Some(Atoms)`(开)。
|
|
153
|
+
两侧同一 env,判据落点:Python `md_cg/semantic/unify.py::unify_on`
|
|
154
|
+
`os.environ.get("MDCG_UNIFY_QUERY", "0") == "1"`;
|
|
155
|
+
Rust `rust/src/atoms.rs::Atoms::from_env`
|
|
156
|
+
`std::env::var("MDCG_UNIFY_QUERY").as_deref() != Ok("1") → None`。
|
|
157
|
+
三态守卫 `md_cg/test_unify_default_off.py`(含两侧一致性与定点变异自证)。
|
|
158
|
+
- **归一层作用域(2026-09-30 收窄)**:只对英文内容做翻译归一,中文段逐字保留
|
|
159
|
+
——中文判据单点两侧同区间(`canonical.is_zh_char` / `text.rs::is_zh`);
|
|
160
|
+
逐位对拍 fixture `md_cg/semantic/unify_fixture.json`(两侧钉同一份期望值),
|
|
161
|
+
改任一侧实现必先同步另一侧并跑两份守卫。
|
|
162
|
+
- **中文判据边界**:Python `is_zh_char` **仅长度恰为 1 的串可为真**(空串/多字符串
|
|
163
|
+
一律 False);Rust `is_zh` 收 `char` 天然同语义。两侧边界约定写在各函数 docstring。
|
|
164
|
+
- **空产物回退**:归一产物为空时两侧**原样返回原入参(含首尾空白,不 trim)**
|
|
165
|
+
——Python `unify_query` 尾行 `return text`,Rust `Atoms::unify` 的
|
|
166
|
+
`query.to_string()`(2026-09-30 清理批次乙1 修正:此前 Rust 误为 `query.trim()`);
|
|
167
|
+
fixture「空产物回退·原样返回原入参(不 trim)」例钉住。
|
|
168
|
+
- **两侧既有非对称三条**(§一之补)**尚未统一**——改任一条都属**改语义**,须先由
|
|
169
|
+
使用者裁定方向(§七 待裁定项 2),再两侧同改 + 更新本节与 fixture。
|
|
83
170
|
- 词表再生成:`python -m md_cg.semantic.export_en_zh_map` → 两侧自动同源。
|
|
84
171
|
- 对拍命令:`python scripts/rank_parity.py --dataset scripts/retrieval_dataset.json --ab`
|
|
85
172
|
(A/B 证据)+ 同命令去 `--ab`(逐位对拍)。
|
|
173
|
+
|
|
174
|
+
## 七、待裁定项(2026-09-30 清理批次登记;本文不自行定方向)
|
|
175
|
+
|
|
176
|
+
### 1. `--dataset` 对拍口径是否并入门禁腿?
|
|
177
|
+
|
|
178
|
+
现状(§五.2 表):门禁腿跑**内建合成语料**口径(10/10 绿,rc=0);`--dataset` 口径
|
|
179
|
+
在 **2026-09-30 缺省翻关后缺省态已绿(10/10 rc=0)**,只在**显式
|
|
180
|
+
`MDCG_UNIFY_QUERY=1`** 时回到 8/10 rc=1(既有差分,非本次收窄引入)。**本批未并入**
|
|
181
|
+
——该腿对归一层开关敏感(开关一开即 8/10),并入前若不清因,等于给门禁留一条
|
|
182
|
+
「看 env 的脸色」的腿,失去门禁信号价值。
|
|
183
|
+
待裁定:①先清掉那两条 DIFF 再并入;②或把 `--dataset` 永久留在证据面(`--ab` 路径)
|
|
184
|
+
不进门禁。**在裁定前不得并入。**
|
|
185
|
+
|
|
186
|
+
### 2. §一之补 的三条两侧既有非对称统一到哪一侧?
|
|
187
|
+
|
|
188
|
+
**后果读数**(2026-09-30 实测):locomo-zh-500 公开题池(池 567 / 题 500,
|
|
189
|
+
`eval_common` jaccard + GLOBAL_CAP 解除,k=5),Python 侧用**进程内 monkeypatch**
|
|
190
|
+
量(不改仓库文件;patch 包在 `en_normalizer.normalize_en_query` 外层,随后跑与
|
|
191
|
+
`python -X utf8 -m md_cg.bench_locomo_zh_public` 同一口径;池与结果均落临时目录):
|
|
192
|
+
|
|
193
|
+
| 态 | lexical hit@1 | lexical,fuzzy hit@1 | MRR(lexical / lex,fuzzy) |
|
|
194
|
+
|---|---|---|---|
|
|
195
|
+
| 现状(Python 保留原 case、字母数字同段丢数字) | **95.8%** | **96.6%** | 0.9755 / 0.9821 |
|
|
196
|
+
| 把 Python 的未登录大写词改 lower(= 向 Rust ①侧靠) | 95.8% | 96.4%(−0.2pp) | 0.9755 / 0.9811 |
|
|
197
|
+
| 把 Python 的字母数字同段改为保数字(= 向 Rust ③侧靠) | 96.2%(+0.4pp) | 96.6%(持平) | 0.9775 / 0.9821 |
|
|
198
|
+
|
|
199
|
+
读数边界(如实声明,勿外推):
|
|
200
|
+
- 「大写 lower」patch 的判据是「term 含 ASCII 字母即 lower」⇒ 它同时覆盖第 ① 条
|
|
201
|
+
**与第 ② 条的原文原子大小写面**(`Paris`→`paris`),但**未动** ② 的双原子结构;
|
|
202
|
+
- 「保数字」patch 把数字串**追加在该段原子序列末尾**(段内原位插入会略改 bigram
|
|
203
|
+
组合),属近似实现;
|
|
204
|
+
- **第 ② 条「专名双原子」未单独量**(需改 `is_proper` + 词表命中分支,patch 面更大)
|
|
205
|
+
——缺读数即声明缺,不填猜测值。
|
|
206
|
+
|
|
207
|
+
⇒ 结论:两条可量项都**未达「明确该改」的强度**(①向 Rust 靠在这两路不增益甚至
|
|
208
|
+
fuzzy −0.2pp;③向 Rust 靠 lexical +0.4pp、fuzzy 持平),且两条都动两侧共享语义面
|
|
209
|
+
(Rust 侧改需同步改 `normalize_en` 的 lower 语义或新增双原子分支)。**故本批只披露
|
|
210
|
+
读数,统一到哪一侧由使用者裁定;裁定后两侧同改 + 更新 §一之补 / fixture / 守卫。**
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
情境输入(query, context)
|
|
23
23
|
↓ S1 大域先验收敛 terms → big_domain_classify → 域集合;候选 = 该域节点 ∪ ORPHAN 兜底
|
|
24
24
|
↓ S2 条件空间前置门控 condition_space 硬槽(time_window/observation_position/存在约束)不匹配 → 不进候选
|
|
25
|
-
↓ S3 图扩散激活 以 (S1∩S2) 命中为种子,沿 edges 双向扩散 N
|
|
25
|
+
↓ S3 图扩散激活 以 (S1∩S2) 命中为种子,沿 edges 双向扩散 N 跳、按跳数衰减;不读正文
|
|
26
|
+
(邻接构建为 O(N) 索引条目级——见 §3 S3 的代价口径)
|
|
26
27
|
↓ S4 层级激活优先级 anchor/self 初始激活值加成(认知优先级,不是过滤)
|
|
27
28
|
↓ S5 负记忆抑制 rejected/unresolved 命中 → 对相关正候选乘性降权(抑制信号)
|
|
28
29
|
↓ S6 一致性交叉验证 对最终 top-k 做 crosscheck(复用 md_cg/crosscheck.py)
|
|
@@ -49,7 +50,17 @@
|
|
|
49
50
|
### S3 图扩散激活
|
|
50
51
|
- 输入:种子集合、`edges`(出边在 `fm.edges`;白箱 KB 的 `edges` 表按 source/target 双索引)
|
|
51
52
|
- 输出:激活集合 + 激活值(种子 1.0,第 n 跳 × 衰减^n)
|
|
52
|
-
- 不变量:扩散**不得引入未通过 S2
|
|
53
|
+
- 不变量:扩散**不得引入未通过 S2 门控**的节点;边方向/关系类型权重**部分可配**
|
|
54
|
+
(2026-10-01 勘误,**P3 遗留 ④ 如实降级**:实测只有「关系类型**集合**」可配
|
|
55
|
+
——`MDCG_CHAIN_TYPES`(`md_cg/chain.py`,缺省 `CHAIN_TYPES_DEFAULT`);边权数值
|
|
56
|
+
**沿用唯一表** `EDGE_WEIGHTS`(真源唯一,不提供第二处可配口径);方向**固定为
|
|
57
|
+
依赖方向(出边)**(`walk(direction="out")` 缺省)。⇒ 本不变量属**部分满足**)
|
|
58
|
+
- 代价口径(2026-10-01 勘误,**P3 遗留 ⑥ 如实降级**):原文「**不走全表**」与实测
|
|
59
|
+
不符——`chain.adjacency`(`md_cg/chain.py:152`)遍历**全部索引节点**建出邻接,
|
|
60
|
+
只是**不读正文**(`subgraph._fm` 优先走索引快照)。正确表述:**不读正文;
|
|
61
|
+
邻接构建为 O(N) 索引条目级**。代价读数(`scripts/p2p4_probe.py` R7,400 条目
|
|
62
|
+
确定性小库):冷建 ~0.24ms、缓存命中 ~1µs。可选硬化路径:在索引快照的**边集合**
|
|
63
|
+
上增量构建邻接(本轮未做)
|
|
53
64
|
- 失败模式:图稀疏(实测 142 节点 / 87 边)→ 覆盖不足,必须保留域内 LIKE 兜底
|
|
54
65
|
|
|
55
66
|
### S4 层级激活优先级
|
|
@@ -76,6 +87,45 @@
|
|
|
76
87
|
|
|
77
88
|
规则:**默认关**;每阶段可单独开,便于逐项验证与归因;总开关关时 `search()` 走原路径。
|
|
78
89
|
|
|
90
|
+
### 4.1 读入口 × 门控状态(C-8,2026-09-29 固化)
|
|
91
|
+
|
|
92
|
+
S1/S1b/S2/S4 由 `md_cg/mdcg.py::apply_retrieval_gates` **唯一实现**;三条读入口原地调用
|
|
93
|
+
(插入点同构:`_candidates` 之后、候选生成之前)。本表是「哪条读路径吃了门控」的判据面,
|
|
94
|
+
由 `md_cg/test_c8_search_rrf_gates.py` 逐路机械断言:
|
|
95
|
+
|
|
96
|
+
| 读入口 | 生产链 | 门控状态 |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| `MdCG.search` | 基类(专项测试面) | 生效(issue #25 起) |
|
|
99
|
+
| `MdCGOS.search` | `mdcg_search` / `cg(op=read, query)` | 生效(issue #25 起) |
|
|
100
|
+
| `MdCGOS.search_rrf`(→ `MdCGSecure.search_rrf`) | `mdcg_recall` / `cg(op=read, budget_tokens=…)` | 生效(C-8 起;此前**整段不过门控**——无 gates 键、scanned 恒全表,与 `search` 候选面分裂) |
|
|
101
|
+
|
|
102
|
+
**有意保留的差异**(不是缺陷,也不是门控缺口):S3 spread 与 S7 postings 是 `search` 的
|
|
103
|
+
**候选生成段**(引入新 tier / 新候选,非收敛);RRF 入口的对应物是 `reach`
|
|
104
|
+
(`MDCG_REACH=1`,同为候选生成器,见 `md_cg/reach.py`)。二者语义上都不是
|
|
105
|
+
「收敛」,故不共用 `apply_retrieval_gates`。
|
|
106
|
+
|
|
107
|
+
读入口新增或覆写时:**必须**在表中登记并给出门控状态;未登记的读入口按「缺口」处理
|
|
108
|
+
(issue #25 与 C-8 是同一病灶的两次复发:新增入口时漏接共享门控)。
|
|
109
|
+
|
|
110
|
+
### 4.2 读侧**语言面**分叉(2026-10-01 登记 · P3 遗留 ③)
|
|
111
|
+
|
|
112
|
+
**Python 与 Rust 两侧的缺省路集本就不同**,本表必须显式登记,**不得**被读成
|
|
113
|
+
「对拍通过」:
|
|
114
|
+
|
|
115
|
+
| 侧 | 缺省路集 | 出处 |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| Python | **6 路**:lexical / bucket / entity / graph / chain / temporal | `md_cg/mdcos.py::search_rrf` 的 `paths` 缺省值 |
|
|
118
|
+
| Rust | **4 路**:lexical / bucket / entity / graph | `rust/src/engine.rs::SearchEngine::open`(`EngineConfig.paths == None` 时的字面量) |
|
|
119
|
+
|
|
120
|
+
Rust 读侧尚未实现 `chain` / `temporal`(以及本批新增的**六要素后两行索引键**)、
|
|
121
|
+
未实现 `freshness` 之外的 Python 侧多路。⇒ `scripts/rank_parity.py` 现在仍报
|
|
122
|
+
10/10,**只因其语料无边、无时间参数、无六要素后两行声明**(缺省差异在这类语料上
|
|
123
|
+
不产出可观测差),**不是**「两侧已对齐」的证据。
|
|
124
|
+
|
|
125
|
+
事实钉住面:`md_cg/test_p3_legacy_closure.py`(`--mutate` 自证)逐条断言
|
|
126
|
+
「Rust 缺省四路」字面量与「Python 缺省六路」并存且**不相等**——防止有人把
|
|
127
|
+
rank_parity 的 10/10 误读成对拍通过。
|
|
128
|
+
|
|
79
129
|
## 5. 验收判据(每阶段都要过)
|
|
80
130
|
|
|
81
131
|
1. **等价性**:开关关 → `scripts/run_tests.py md_cg` 全绿,且返回与现状一致(快照对比);
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
### T1 HiveJobsSource(sources.py 注册蜂巢事件源)
|
|
18
18
|
|
|
19
|
-
- **依据**:§5.1 事件源注册表(source_id=hive_jobs;progress.jsonl 五类条目 + result.json 终态权威确认;job_id
|
|
19
|
+
- **依据**:§5.1 事件源注册表(source_id=hive_jobs;progress.jsonl 五类条目 + result.json 终态权威确认;job_id 名升序=时间序)。〔2026-09-30 订正(C2):末句「名升序=时间序」在 id 契约 v2 下**失实**——新形态 `h_<身份>_<任务>_<单元>_<编号>` 不含时间,名序 = 提交时序只是旧形态 `h<毫秒>_<hex>` 的巧合代理(`hive/src/job.rs::list_jobs` 头注已同改)。本源的 `_jobs()` 实按名升序枚举、**代码未改**(去重键 `(session, seq)` 仍确定),docstring 已据实订正;若要真时间序须改走 `created_ts` 真值。见 `docs/plans/全中文编码与蜂巢任务标识契约_v2.0.md` §五.1「C 论证订正」行与 §五.2 第 2 条〕
|
|
20
20
|
- **条件**:复用 `Source` 基类协议(events() → {t, seq, role, text, session, cwd},t=epoch 秒);session=`hive:<job_id>`(ingest 去重键)。
|
|
21
21
|
- **错后**:progress 解析失败跳过该行并计入 skipped(不终杀批次);result.json 缺失任务按 progress 现状处理(不伪造终态)。
|
|
22
22
|
- **裁决**:ACCEPT。
|