@furongjun1999/dsh-memory 0.6.1 → 0.7.1
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 +49 -18
- package/docs/README.md +1 -0
- package/docs/eval/cons200_/345/206/262/347/252/201/346/243/200/346/265/213/351/200/211/351/235/242_/345/256/236/346/226/275/350/256/260/345/275/225_v1.0.md +223 -0
- package/docs/eval/cons200_/345/206/262/347/252/201/346/243/200/346/265/213/351/200/211/351/235/242_/345/256/236/346/226/275/350/256/260/345/275/225_v1.1.md +340 -0
- package/docs/eval/issue50_/345/205/203/346/225/260/346/215/256/351/200/217/344/274/240/344/270/216/345/205/234/345/272/225_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +437 -0
- package/docs/eval/issue50_/345/215/212/351/207/215/345/244/215/345/276/205/345/256/232/345/244/215/346/240/270_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +488 -0
- package/docs/eval/issue50_/345/276/205/345/256/232/345/244/215/346/240/270/345/205/245/351/230/237_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +428 -0
- package/docs/eval/issue50_/350/257/273/351/235/242/344/277/235/346/212/244/345/217/252/350/256/244/346/230/276/345/274/217/346/235/245/346/272/220_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +271 -0
- package/docs/eval/issue50_/351/207/215/350/246/201/345/272/246/345/220/214/346/272/220/344/270/216/344/277/235/346/212/244/350/257/255/344/271/211_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +306 -0
- package/docs/eval/issue51_/344/270/200/351/224/256/345/256/211/350/243/205/345/244/261/350/264/245_/345/275/222/345/261/236/345/210/244/345/256/232_v1.0.md +58 -0
- package/docs/eval/issue52_/346/235/241/344/273/266/345/205/210/350/241/214/344/270/216/346/210/252/346/226/255/345/217/257/350/247/202/346/265/213_/344/277/256/345/244/215/350/256/260/345/275/225_v1.0.md +360 -0
- package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/241/346/241/243/344/275/215/345/215/225/344/270/200/345/205/245/345/217/243_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +651 -0
- package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/242/345/217/230/346/233/264/345/215/225/344/270/216/345/233/236/346/273/232/345/216/237/350/257/255_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +439 -0
- package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/243/345/207/206/345/205/245/350/257/273/346/225/260_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +1337 -0
- package/docs/eval//344/270/211/346/241/243/350/207/252/346/262/273_/346/255/245/351/252/244/342/221/244/346/224/266/345/256/230/344/270/216/345/205/250/351/223/276/351/252/214/346/224/266_/350/220/275/347/240/201/350/256/260/345/275/225_v1.0.md +1817 -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/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/217/221/345/270/20309_/346/243/200/347/264/242/351/235/242/344/270/211/346/211/271/346/224/266/345/217/243_v1.0.md +66 -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//347/254/2543/345/261/202stg/347/273/223/346/236/204/347/264/242/345/274/225_/345/256/236/346/226/275/350/256/260/345/275/225_v1.0.md +250 -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 +32 -2
- package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +88 -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 +47 -11
- 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/plans/stg/346/235/241/344/273/266/345/214/226/344/270/216/347/273/223/346/236/204/347/264/242/345/274/225_/350/256/276/350/256/241_v0.1.md +124 -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/256/260/345/277/206/350/207/252/345/244/204/347/220/206/344/270/211/346/241/243/350/207/252/346/262/273_/350/256/276/350/256/241_v0.2.md +207 -0
- package/md_cg/admission.py +718 -0
- package/md_cg/autonomy_modes.py +642 -0
- package/md_cg/bench_e2e_locomo_qa.py +11 -4
- package/md_cg/chain.py +47 -0
- package/md_cg/consistency.py +133 -8
- package/md_cg/forgetting.py +38 -6
- package/md_cg/freshness.py +527 -0
- package/md_cg/generation.py +409 -0
- package/md_cg/hotcache.py +4 -1
- package/md_cg/lifecycle.py +30 -2
- package/md_cg/mcp_server.py +191 -26
- package/md_cg/mdcg.py +594 -39
- package/md_cg/mdcos.py +869 -38
- package/md_cg/nodefile.py +74 -1
- package/md_cg/protect.py +79 -4
- package/md_cg/provenance.py +1 -1
- package/md_cg/review_cli.py +31 -2
- package/md_cg/rollback.py +411 -0
- package/md_cg/rollback_cli.py +104 -0
- 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/stg.py +400 -50
- package/md_cg/stgidx.py +281 -0
- package/md_cg/sustain.py +146 -9
- package/md_cg/test_auto_defaults.py +424 -0
- package/md_cg/test_autonomy_admission.py +1098 -0
- package/md_cg/test_autonomy_modes.py +1972 -0
- package/md_cg/test_b1_auto_id_multiproc.py +7 -0
- package/md_cg/test_b1b2_write_face.py +7 -0
- package/md_cg/test_b3_merge_keeps_content.py +7 -0
- package/md_cg/test_boundary_hit.py +410 -0
- package/md_cg/test_cons200_scan_selection.py +791 -0
- package/md_cg/test_en_pipeline.py +22 -13
- package/md_cg/test_generation_guard.py +352 -0
- package/md_cg/test_h4_sustain_snapshot.py +14 -4
- package/md_cg/test_i50a_half_dup_defer.py +408 -0
- package/md_cg/test_i50b_defer_to_review_queue.py +545 -0
- package/md_cg/test_i50c_meta_passthrough.py +608 -0
- package/md_cg/test_i50d_importance_source.py +531 -0
- package/md_cg/test_i50e_readside_protection.py +656 -0
- package/md_cg/test_issue39_utf8_stdio.py +9 -1
- package/md_cg/test_issue52_scan_condition_first.py +677 -0
- package/md_cg/test_linkref.py +7 -0
- package/md_cg/test_mode_parity.py +1393 -0
- package/md_cg/test_mutation_rollback.py +805 -0
- package/md_cg/test_n204_n205_n226_n227_n228_n229_exit_gates.py +1 -1
- package/md_cg/test_n212_n213_n224_generation_gates.py +14 -8
- package/md_cg/test_n214_n215_n221_n222_write_face_gates.py +7 -0
- package/md_cg/test_n230_dirty_replay.py +375 -0
- package/md_cg/test_p2_mcp.py +8 -0
- package/md_cg/test_p2_six_elements.py +463 -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_p9_forget_protect.py +7 -0
- package/md_cg/test_p9c_dedup_hints.py +7 -0
- package/md_cg/test_policy_required_ccg.py +5 -1
- package/md_cg/test_protocol.py +7 -0
- package/md_cg/test_rank_parity_score_mode.py +6 -0
- package/md_cg/test_semantic_canonical.py +5 -3
- package/md_cg/test_sleep.py +611 -0
- package/md_cg/test_sleep_p1.py +784 -0
- package/md_cg/test_stgidx_index_parity.py +1020 -0
- package/md_cg/test_time_core_lint.py +968 -0
- package/md_cg/test_unify_default_off.py +701 -0
- package/md_cg/test_unify_scope.py +182 -0
- package/md_cg/test_writelimit.py +36 -9
- package/md_cg/test_writepipe.py +5 -2
- package/md_cg/weights.py +15 -1
- package/md_cg/whitebox_kb/aeis_core/time_core.py +8 -0
- package/md_cg/writepipe.py +101 -2
- package/package.json +3 -2
- package/skills/plugin.json +1 -1
- package/utf8_boot.py +237 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 发布 09 · 0.7.1:检索面三批同族收口(条件先行与截断可观测 + stg 结构索引 + consistency 选面)
|
|
2
|
+
|
|
3
|
+
> 发版线:v0.7.0(`bfbdcb92`)→ v0.7.1
|
|
4
|
+
> 设计真源:`docs/plans/stg条件化与结构索引_设计_v0.1.md`(§八 签收记录,2026-10-03 五条均同意)· `docs/hive/检索路径与认知结构契约_v0.1.md`(六阶段逐级收敛)
|
|
5
|
+
> 发布三关:`npm run gate`(九条腿)· Linux 容器双栈 · E 盘空文件夹沙箱模拟新用户安装
|
|
6
|
+
> 起源:issue #52(外部报告)+ 使用者裁定——「遇到更多的检索节点,应该要建立索引,明确检索条件,和不适用条件,而不是扩大节点数」
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 一、一批起源、三批落地(同族:索引序切片 + 静默截断)
|
|
11
|
+
|
|
12
|
+
| 批 | 提交 | 内容 |
|
|
13
|
+
|:--|:--|:--|
|
|
14
|
+
| 第 1/2 层 | `0d3a0ab2` | **issue #52**:`stg._scan` 索引序切片退场——条件(session/layer/time_window/bbox)先于限额、`truncated/scanned/kept` 可观测+近期优先兜底+可操作 hint;`max_scan=5000` 数值不动 |
|
|
15
|
+
| 第 3 层 | `9a1150dd` | **stg 结构索引**(`md_cg/stgidx.py`):by_session/by_layer/by_time 内存倒排+条件资格首验(`MDCG_STG_INDEX`/`MDCG_STG_QUALIFY` 双 flag 默认关);路径等价为唯一准入 |
|
|
16
|
+
| 第二实现批 | `50bb291c` | **consistency 选面**(设计稿签收点 5):`MAX_SCAN=200` 索引序静默 break 退场——相关性预筛(快照级零读盘)+精比面=相关面∪保底面+面内例外+`truncated/kept/hint` 可观测;数值一字未动 |
|
|
17
|
+
|
|
18
|
+
共同主线:**索引序选面 + 静默截断**——检索/写入面三处同族缺陷一次性收口。
|
|
19
|
+
|
|
20
|
+
## 二、逐批读数(每批都经「修前独立复现 → 契约实施+守卫 → 定点变异自证 → 独立复核」)
|
|
21
|
+
|
|
22
|
+
### 第 1/2 层(`0d3a0ab2`)
|
|
23
|
+
|
|
24
|
+
- 修前在役复现:timeline 默认 `count=25`(全 `code_*`)对全量 `count=229`(被切 204 条含 15 条 `mem_*`,今天归档的亦全不可见)。
|
|
25
|
+
- 修后对照:`count` 25 → **7607**;今日 `mem_*` 全可见;截断显形(`truncated`/`kept` 读数)。
|
|
26
|
+
- 守卫 36 断言+8 处定点变异;python 309/309;容器 41/0 与 96/0/3。
|
|
27
|
+
|
|
28
|
+
### 第 3 层(`9a1150dd`)
|
|
29
|
+
|
|
30
|
+
- 在役实测:timeline **44.84ms → 0.86ms(52.07×)**;两臂(flag 开/关)逐位等价。
|
|
31
|
+
- 守卫 51 断言+17 处定点变异;独立复核 ACCEPT;python 310/310;容器 43/0 与 96/0/3。
|
|
32
|
+
- 容器 2 fail 定因=issue52 守卫 ANCHOR-MISS 按设计工作(fail-closed)——五组锚同步+容器清单补登后全绿。
|
|
33
|
+
|
|
34
|
+
### 第二实现批(`50bb291c`)
|
|
35
|
+
|
|
36
|
+
- 修前复现(13 腿,独立复现员在改动前的树上取得):222 节点合成库、冲突对落索引位 220 ⇒ **静默 ACCEPT 漏检**(`scanned=200` 恰在 MAX_SCAN 处 break);REJECT 级(纪律违反)同被吞;写面带同载荷 `on_conflict=reject` 静默落盘;返回体与 `_consistency.jsonl` 均无截断标记。
|
|
37
|
+
- 修前在役采样(17883 节点,只读):非 gated 写链 knowledge 层 16935 节点、前 200 里 `code_*` 占 **93%** ⇒ 真记忆几乎从不进比对面。
|
|
38
|
+
- 守卫 27 断言+6 处定点变异(8/11/19/10/4/5 各自恰好命中、零空转);python 311/311;容器 43/0 与 96/0/3。
|
|
39
|
+
- **两轮独立复核:第一轮 DEFER(F1 判据同源缝+无词面口径)→ 缺口补齐(面内例外)→ 第二轮 ACCEPT**;F1 闭合由编排侧独立探针复验(非同源形态·面内 ⇒ 仍 REJECT)。
|
|
40
|
+
|
|
41
|
+
## 三、必须连着读的披露
|
|
42
|
+
|
|
43
|
+
1. **双 flag 默认关**:`MDCG_STG_INDEX`/`MDCG_STG_QUALIFY` 缺省关闭——第 3 层索引的路径等价已机械验证(两臂逐位一致),但默认开关待单独讨论(先 flag 化、逐项验证、再讨论默认开启——检索契约 §7 口径)。
|
|
44
|
+
2. **面外残余(cons200 诚实边界)**:非同源形态(非合作写者直改 `.md` 不重建索引)下、落修前扫描面**之外**的纪律节点可能不被相关面捡到——修前亦检不出,不构成回归;已由 `truncated` 可观测+docstring 边界声明覆盖。
|
|
45
|
+
3. **升级须重启的长驻进程**:在役 MCP 进程仍持旧字节码——cons200 的写链检测面与 stg 层改动须重启 MCP 后生效(既有运维前提,发布 08 已登记)。
|
|
46
|
+
4. **选面只影响超限分支**:cons200 的相关性排序只决定「候选超限时谁进精比面」;正常库(候选 ≤ limit)行为逐位不变(对拍含递归/exclude/哨兵等 11 个场景逐位一致)。
|
|
47
|
+
|
|
48
|
+
## 四、已知边界(如实登记)
|
|
49
|
+
|
|
50
|
+
1. cons200 在役规模成本取证未做(硬边界:未触在役数据根)——真实规模的成本构成与 F4 纪律投影词形(`work-discipline` 不被 `_is_discipline` 认)的实效待后续取证。
|
|
51
|
+
2. F2 诚实边界另一支(面外、无 `rejection_terms` 的旧节点、仅声明生效条件的 pos 面冲突)未独立构造复现(守卫 docstring 有声明)。
|
|
52
|
+
3. `MdCG.add` 直连面 `extra["consistency"]` 仍只投影五旧键(`mdcg.py:2181-2185`,设计裁定)——该面看不到 `kept/truncated`;`writepipe`/`mdcos`/`mcp_server` 面完整透传。
|
|
53
|
+
4. 留池(不属本版):会话水印面(MCP 重启后 auto-recall 本会话视图断链)· 双 flag 默认开关讨论 · 公开检索基准重跑。
|
|
54
|
+
|
|
55
|
+
## 五、发布面与回验
|
|
56
|
+
|
|
57
|
+
- 版本号 8 处:`package.json` · `package-lock.json`(×2)· `.claude-plugin/marketplace.json` · `claude/lingshu-memory/.claude-plugin/plugin.json` · `codex/lingshu-memory/.codex-plugin/plugin.json` · `skills/plugin.json` · `README.md` 正文版本行与版本表。**`SERVER_VERSION` 不动**(它动态读 `package.json`,正是 issue #42 的修法)。
|
|
58
|
+
- 回验:`python scripts/check_publish_artifact.py` · `python scripts/check_publish_smoke.py`(真装真握手)· `python -X utf8 scripts/check_registry_tarball.py`(发布后)· `npx @furongjun1999/dsh-memory init`(清缓存后终验)。
|
|
59
|
+
|
|
60
|
+
## 六、证据面(守卫星座)
|
|
61
|
+
|
|
62
|
+
| 批 | 修复报告 | 守卫 |
|
|
63
|
+
|:--|:--|:--|
|
|
64
|
+
| 第 1/2 层 | `docs/eval/issue52_条件先行与截断可观测_修复记录_v1.0.md` | `md_cg/test_issue52_scan_condition_first.py` |
|
|
65
|
+
| 第 3 层 | `docs/eval/第3层stg结构索引_实施记录_v1.0.md` | `md_cg/test_stgidx_index_parity.py` |
|
|
66
|
+
| 第二实现批 | `docs/eval/cons200_冲突检测选面_实施记录_v1.0.md` / `_v1.1.md`(收口轮) | `md_cg/test_cons200_scan_selection.py` |
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# 归一层缺省翻关(UNIFY-DEFAULT-OFF)修复记录 v1.0
|
|
2
|
+
|
|
3
|
+
> **日期**:2026-09-30 | **缺陷号**:UNIFY-DEFAULT-OFF | **契约**:动态工作流 `dwfrun-e8eabeba-…` 的 `args.contract`(`defect=UNIFY-DEFAULT-OFF`)——**验收条款原文见 §七.1**
|
|
4
|
+
> **被测面**:`D:\program\dsh-memory-main` **工作树(未提交)**——12 个已修改跟踪件(`README.md`、`docs/hive/检索算法口径对照_v0.1.md`、`md_cg/bench_e2e_locomo_qa.py`、`md_cg/mdcg.py`、`md_cg/mdcos.py`、`md_cg/semantic/unify.py`、`md_cg/test_en_pipeline.py`、`md_cg/test_rank_parity_score_mode.py`、`md_cg/test_semantic_canonical.py`、`md_cg/test_unify_scope.py`、`rust/src/atoms.rs`、`scripts/rank_parity.py`)+ 2 个未跟踪项(`.zcode/`、新守卫 `md_cg/test_unify_default_off.py`)
|
|
5
|
+
> **证据分级**(本报告不越界陈述):
|
|
6
|
+
> - **§一、§三**=本次读码实读(行号以本次读码为准,**每处同时标明 `git HEAD`(修前)与工作树(修后)两个行号**);§一.2 与 §三.1 各附实跑命令原文。
|
|
7
|
+
> - **§二**=工作流复现腿采集的修前现场(11 条腿,逐条标出「谁跑的」);**本报告未重跑修前态**。其中「HEAD 判据字面量」「HEAD↔现行逐位等价」「修前非 `"0"/"1"` 取值」「修前断言判别力」四点由本报告直接复核,见 §一.2、§四.6、§四.13、§四.11。
|
|
8
|
+
> - **§四**=**每条命令均由本报告在本次会话实跑**,逐条给出确切命令与读数;凡非本次实跑者一律显式标注出处。
|
|
9
|
+
> - **§五**=独立复核(不同执行体)的判定与其自列 uncovered,转述并标注本报告能否复现。
|
|
10
|
+
> - **§六**=边界、未覆盖、未查明项。
|
|
11
|
+
> - 报告撰写任务的硬边界:只写本文件;不改源码;不 `git add/commit/push`;本报告**未跑**「写活库」类归档(工作纪律第 16 条)——显式声明,非静默跳过。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 一、缺陷定义与真实站点
|
|
16
|
+
|
|
17
|
+
### 1.1 缺陷(契约原文见 §七.1)
|
|
18
|
+
|
|
19
|
+
`MDCG_UNIFY_QUERY` 的**缺省语义是「开」**:环境变量**未设**时归一层生效——检索入口把 query 送进「英文归一 → 中文原子序列」链路。契约判定该层对中文检索池是纯开销,使用者 2026-09-30 裁定把缺省翻为「关」。
|
|
20
|
+
|
|
21
|
+
### 1.2 判据本体(两侧各一处单点;两个行号都给出)
|
|
22
|
+
|
|
23
|
+
| 侧 | 修前(`git HEAD`) | 修后(工作树) | 位移原因 |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| Python | `md_cg/semantic/unify.py:43` `return os.environ.get("MDCG_UNIFY_QUERY", "1") == "1"`(`def unify_on` 在 `:41`,头注 `:24`,CCG 注 `:40`/`:64`) | `md_cg/semantic/unify.py:54` `... get("MDCG_UNIFY_QUERY", "0") == "1"`(`def unify_on` 在 `:52`,头注 `:24–34`,CCG 注 `:51`,`unify_query` 的 CCG 注 `:75`) | 头注开关段由 3 行扩为 12 行(`+11`) |
|
|
26
|
+
| Rust | `rust/src/atoms.rs:98` `if std::env::var("MDCG_UNIFY_QUERY").map(\|v\| v == "0").unwrap_or(false) {`(`pub fn from_env` 在 `:97`,旧注释 `:29`/`:84`) | `rust/src/atoms.rs:118` `if std::env::var("MDCG_UNIFY_QUERY").as_deref() != Ok("1") {`(`pub fn from_env` 在 `:113`,生效条件注 `:99–100`,头注三态表 `:31–43`) | 头注新增三态表(`+14`) |
|
|
27
|
+
|
|
28
|
+
复核命令与读数(本报告实跑,原文照录):
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
$ git show HEAD:md_cg/semantic/unify.py | grep -n MDCG_UNIFY_QUERY
|
|
32
|
+
24:开关:MDCG_UNIFY_QUERY 默认 "1"(2026-09-23 使用者拍板口径转正);
|
|
33
|
+
40:# 生效条件:… 当 os.environ.get("MDCG_UNIFY_QUERY", "1") == "1" 时返回 True …
|
|
34
|
+
43: return os.environ.get("MDCG_UNIFY_QUERY", "1") == "1"
|
|
35
|
+
|
|
36
|
+
$ git show HEAD:rust/src/atoms.rs | grep -n "MDCG_UNIFY_QUERY\|unwrap_or(false)\|pub fn from_env"
|
|
37
|
+
84: /// 生效条件:`MDCG_UNIFY_QUERY=0` 时无条件返回 None(显式关优先);
|
|
38
|
+
97: pub fn from_env() -> Option<Self> {
|
|
39
|
+
98: if std::env::var("MDCG_UNIFY_QUERY").map(|v| v == "0").unwrap_or(false) {
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**站点纠正(采集腿给出,本报告读码复核成立)**:env 读取**不在** `Atoms::unify`(纯函数,`rust/src/atoms.rs:162` 起为 `unify`/`segment` 一类纯逻辑),而在 `Atoms::from_env`(HEAD `:97` / 工作树 `:113`)。⚠ 契约的【缺陷定义】一段把该站点写成 `atoms.rs::Atoms::unify`——**契约自身的站点提示亦不精确**,与采集腿的纠正一致(§七.1 原文可核)。引擎侧接线单点:`rust/src/engine.rs:140`(`atoms: crate::atoms::Atoms::from_env()`)→ `engine.rs:181` → `engine.rs:235` `prepare_query` → `engine.rs:262`。
|
|
43
|
+
|
|
44
|
+
**接线面(三处 search 入口)——修前/修后行号成对给出**:
|
|
45
|
+
|
|
46
|
+
| 接线点 | 修前(HEAD) | 修后(工作树) | 位移原因 |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| `MdCG.search`(`md_cg/mdcg.py`) | `:3075-3076`(`from .semantic.unify import unify_query` / `q = unify_query(q)`) | `:3077-3078` | 同文件 ⚠ 注释块由 12 行扩为 14 行(`git diff` hunk `@@ -280,12 +280,14 @@`,`+2`)⇒ 其后整段下移 2 行 |
|
|
49
|
+
| `MdCGOS.search`(`md_cg/mdcos.py`) | `:852-853` | `:852-853` | 该文件该处**无净行数变化** |
|
|
50
|
+
| `MdCGOS.search_rrf`(`md_cg/mdcos.py`) | `:1406-1407` | `:1406-1407` | 同上 |
|
|
51
|
+
|
|
52
|
+
> 契约的 sites 提示与 §二 采集腿引用的是**修前行号** `md_cg/mdcg.py:3075-3076`(与 `git show HEAD:md_cg/mdcg.py | grep -n unify_query` 实测一致);§一.2 表格右列是**修后**行号。**两者都对,差 +2,原因即上表的注释扩行**——接线代码本身本轮未动(只动其上方注释)。
|
|
53
|
+
|
|
54
|
+
**开关登记面**:`md_cg/hotcache.py:63-64` `_ENV_SWITCHES` 含 `"MDCG_UNIFY_QUERY"`(跨口径 query 缓存键),本轮确认只登记开关名、无缺省语义,无需改(守卫 G4i 钉住)。
|
|
55
|
+
|
|
56
|
+
### 1.3 定因(为何要翻)——**结论的适用面**
|
|
57
|
+
|
|
58
|
+
本层本职是**英文 query → 中文节点**。在**唯一被本次实测的公开中文池**(locomo-zh-500,池 567 / 题 500)上(§四.4):**缺省关态** lexical hit@1 96.4% / lexical+fuzzy 97.2%;**开态** 95.8% / 96.6% ⇒ 缺省开该池 **−0.6pp**。
|
|
59
|
+
|
|
60
|
+
**本报告不把它外推为「对所有中文池都亏」的全称判断**:依据只有**单池单配置**取样,且幅度随作用域大幅变动——同一池在 v0.6.1 的旧「整条归一」口径下差 **10.0pp**(§二.5,采集腿读数)。契约的判定(「对中文检索池是纯开销」)是**裁定方向**,不是本报告可支撑的定量全称命题。
|
|
61
|
+
|
|
62
|
+
### 1.4 连带缺陷:翻缺省才暴露的静默失效(同一根因的第二处)
|
|
63
|
+
|
|
64
|
+
`scripts/rank_parity.py:299-306` 的 A/B 对拍里,「开」这一臂原以 `os.environ.pop("MDCG_UNIFY_QUERY")` 吃「默认开」(HEAD `:301`)。缺省一旦翻关,`pop` 让**两臂都成关态** ⇒ A/B 恒零差异——对拍仍然"绿",但什么都没比(**静默失效**:不是红,是失去判别力)。修法=「开」臂显式 `os.environ["MDCG_UNIFY_QUERY"] = "1"`(工作树 `:304`),并同步 `:222` 注释与 `:362` 显示串(`'1(默认开)'` → `'0(默认关)'`)。修后该臂恢复判别,**本报告实跑 `--ab` 得 top-1 变化 5/10**(§四.12)。
|
|
65
|
+
|
|
66
|
+
### 1.5 修前两侧对「非 `"0"/"1"` 取值」并不同判(本报告实测,见 §四.13)
|
|
67
|
+
|
|
68
|
+
修前两侧对**第三个取值**(如 `"TRUE"`)判定相反:Rust `v == "0"` ⇒ 非 `"0"` 即**开**;Python `== "1"` ⇒ 非 `"1"` 即**关**。⇒ 契约「两侧三态判定必须一致」在修前对**三态之外**的取值不成立;修后两侧统一到「唯一开态 = `"1"`」(同为关)。新守卫只钉「未设 / `"0"` / `"1"`」三态,**未把该取值写成断言**(§六.E)。
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 二、修前现场(修前读数逐条)
|
|
73
|
+
|
|
74
|
+
> 「谁跑的」一列:**采集**=本工作流 ask#1「缺陷复现员」在**改动前**的树上采集(本报告未重跑该条);**本报告复核**=我在本次会话直接复跑或复核过。
|
|
75
|
+
|
|
76
|
+
| # | 腿 | payload(确切命令/输入) | 观察(修前) | 站点 | 谁跑的 |
|
|
77
|
+
|---|---|---|---|---|---|
|
|
78
|
+
| 1 | 构造期判据 · Python 三态 | 进程 env 三态(未设 / `"0"` / `"1"`);探针 `self acceptance`(另含纯中文、中夹英) | 未设 → `unify_on=True`、`unify_query("self acceptance")="self 包 容 心"`;`"0"` → False、原样;`"1"` → True、同未设。**未设 ≡ `"1"` ⇒ 缺省即开**。三态在字节保真/CRLF/LF 三棵临时树上结果相同 | `semantic/unify.py` 修前 `:43`(判据)、`:41`(`def unify_on`)、`:24`/`:40`/`:64` | 采集 |
|
|
79
|
+
| 2 | 构造期装载 · Rust 三态 | `cargo test --offline --test repro_unify_env_tristate`(临时树,同一 env 三态) | 未设 → `is_some=true`,`a.unify("I eat beef yesterday")="我 吃 牛肉 昨天"`;`"0"` → false;`"1"` → true。**未设=开** | 修前 `rust/src/atoms.rs:98`(`from_env`)→ `engine.rs:140` → `prepare_query` `engine.rs:235-238` → `search` `engine.rs:262` | 采集 |
|
|
80
|
+
| 3 | 检索代价 · 缺省态 vs 显式关 | `python -X utf8 -m md_cg.bench_locomo_zh_public`(池 567/题 500,jaccard + GLOBAL_CAP 解除,k=5),未设 vs `=0`,各两遍 | 未设:95.8 / 96.6(两遍逐位相同,MRR 0.9755/0.9821);`=0`:96.4 / 97.2(两遍相同) | `semantic/unify.py` 修前 `:43` + 三处接线 | 采集 |
|
|
81
|
+
| 4 | 检索代价 · 显式 `=1` ≡ 未设 | 同 bench,`MDCG_UNIFY_QUERY=1`,×2 | 95.8 / 96.6(两遍逐位相同),与未设态**逐位相同** ⇒ 缺省字面量 `"1"` 的实际语义就是开 | `semantic/unify.py` 修前 `:43` | 采集 |
|
|
82
|
+
| 5 | 发布版 v0.6.1 对照(更严重) | `git archive v0.6.1` → 临时树;同 bench,未设 vs `=0`,各两遍 | 未设:94.4 / 87.2(MRR 0.9600/0.9064);`=0`:96.4 / 97.2。lexical,fuzzy 差 **10.0pp** | v0.6.1 临时树 `semantic/unify.py`(缺省同为 `"1"`,作用域为旧「整条归一」口径) | 采集 |
|
|
83
|
+
| 6 | 定点变异 · 缺省字面量是单点因(两侧) | 副本内改 (a) Python 缺省 `"1"`→`"0"`;(b) Rust `map(\|v\| v=="0").unwrap_or(false)`→`unwrap_or(true)` | (a) 未设态读数翻成 96.4/97.2(与显式 0 逐位相同);作用域守卫 `test_unify_scope` 由「100 断言全绿」转 `FAILED 17/100`,首项点名「MDCG_UNIFY_QUERY 默认开(口径转正)」,另含 3 条纯英文归一与 13 条 fixture 逐位不符。(b) Rust 未设态 `is_some=false`,断言 panic:`tests\repro_unify_env_tristate.rs:36`「未设 env 时归一层应生效」 | `semantic/unify.py` 修前 `:43` / `rust/src/atoms.rs` 修前 `:98` | 采集 |
|
|
84
|
+
| 7 | 接线腿 · 缺省态 search 确实调用 `unify_query` | 临时池上 spy 包裹 `md_cg.semantic.unify.unify_query`,调 `MdCGOS.search` 与 `search_rrf`,未设 vs `=0` | 未设:2 次调用,`in="I eat beef yesterday"` → `out="我 吃 牛肉 昨天"`(changed=true),命中 3 条;`=0`:2 次调用但恒等,命中仍 3 条 | `md_cg/mdcos.py:852-853` / `:1406-1407` / `md_cg/mdcg.py` 修前 `:3075-3076` | 采集 |
|
|
85
|
+
| 8 | 受影响面 · `test_en_pipeline` 断言**不判别** | 复刻 `md_cg/test_en_pipeline.py:150-153` 场景(`n_beef`+`n_unrel`,`query="I ate beef yesterday"`),缺省开 vs 缺省翻 0 | 缺省开:`ids=["n_beef"]` `scores=[0.4]`,行 152 断言真;翻 0:`ids=["n_beef","n_unrel"]` `scores=[0.0,0.0]`,行 152 断言**仍真**(0 分候选仍返回且 `n_beef` 居首 = vacuous)。两态下整件均 rc=0、48 断言全绿 ⇒ **翻缺省不会让它红** ⇒ 文案 `:17-18`/`:146-149` 须改,若要真钉缺省须加 `score>0` | `md_cg/test_en_pipeline.py:150-153`(文案 `:17-18`、`:146-149`) | 采集;**本报告复核**(§四.11:实测为**三态皆真**,比该腿更强) |
|
|
86
|
+
| 9 | 受影响面 · `test_rank_parity_score_mode` 缺省态读数不变 | `python -X utf8 -m md_cg.test_rank_parity_score_mode`,在缺省开树与缺省翻 0 树各一次(先 `cargo build --release`) | 两态均 rc=0:40 通过 / 0 失败 / 0 跳过(G1c 逐位 10/10、G1b-2 缺省调用 10/10/10)。未建 release 二进制时恒 fail-closed 红(「rust release 二进制缺失 → 退出 1」)=环境前置 ⇒ 期望值无需更新 | `md_cg/test_rank_parity_score_mode.py:90-91`、`:232` | 采集 |
|
|
87
|
+
| 10 | 全量 python 测试套件(字节保真**修前树**副本) | `python -X utf8 scripts/run_tests.py` | **287/288 通过、5 跳过、1 红**(口径见 §四.7.0):红 = `hive.test_job_id_segment_dot` 的 C0「在役池可枚举且非空」(副本恒红的 fail-closed 前置;工作区 `hive/jobs` 有 15 个 `h*` 目录 ⇒ 该处应绿)。副本内补建 hive release 后其余 4 项先前 hive 红转绿 | 非本缺陷(环境/设计前置) | 采集 |
|
|
88
|
+
| 11 | `npm run gate` 八条腿(字节保真**修前树**副本) | 副本 + `git init` + `origin=git@github.com:FuRongJun-1999/dsh-memory.git`;`cmd /c npm run gate` | rc=0 全绿:`check_unreachable` 510 文件 0 命中;`check_publish_artifact` VERDICT=PASS(R1–R6 全 PASS);`cogmap_sync check` 10/10;`link_check` 全相对链接可达;`workspace_index --check` [OK] 顶层 20·追踪 2109;`verify_discipline --allow-missing` 10/10;`gate_rust_crate_test` cargo test 28 passed/0 failed;`gate_rust_parity` rc=0 逐位 10/10。★用 `git archive` 取副本则此腿**假红**(行尾致真源指纹漂移) | `package.json` `scripts.gate` | 采集 |
|
|
89
|
+
|
|
90
|
+
**两条修前读数不在上表,出处如下**:
|
|
91
|
+
- **修前 `--dataset` 对拍读数 8/10 · 8/10 · 9/10(rc=1)**:出自 `docs/hive/检索算法口径对照_v0.1.md:126-140`(§五.2 表,含逐位/集合/top-1 与两条 DIFF 名)——该表由上一批复核与本批工作树实跑共同留存,**不在本工作流的 11 条采集腿内**,本报告也未重跑修前态;修后三腿见 §四.3。
|
|
92
|
+
- **修前 `--ab` 的 A/B 判别失效**:见 §一.4(机制)+ §四.12(修后实跑 5/10)。
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 三、修法契约与落点
|
|
97
|
+
|
|
98
|
+
### 3.1 契约(两侧同语义,唯一开态 = 显式 `"1"`)
|
|
99
|
+
|
|
100
|
+
| `MDCG_UNIFY_QUERY` | Python `unify_on()` | Rust `Atoms::from_env()` |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| 未设 | `False`(缺省 `"0"`) | `None`(不载入) |
|
|
103
|
+
| `"0"` | `False` | `None`(不载入) |
|
|
104
|
+
| `"1"` | `True` | `Some(Atoms)`(载入) |
|
|
105
|
+
| 其它取值(如 `"TRUE"`) | `False` | `None`(不载入)——修前两侧在此**不同判**,见 §一.5 / §四.13 |
|
|
106
|
+
|
|
107
|
+
**算法本体与作用域收窄逻辑一行未动**——`git diff HEAD -- md_cg/semantic/unify.py` 原文(本报告实跑,照录):
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
$ git diff HEAD --stat -- md_cg/semantic/unify.py
|
|
111
|
+
md_cg/semantic/unify.py | 25 ++++++++++++++++++-------
|
|
112
|
+
1 file changed, 18 insertions(+), 7 deletions(-)
|
|
113
|
+
|
|
114
|
+
$ git diff HEAD -- md_cg/semantic/unify.py | grep -E "^@@"
|
|
115
|
+
@@ -21,9 +21,20 @@ ← 模块头注「开关」段(3 行 → 12 行:缺省翻关 + 三态表 + 定因读数)
|
|
116
|
+
@@ -37,10 +48,10 @@ ← unify_on 的 CCG 生效条件注释 + docstring + 判据行(缺省 "1"→"0")
|
|
117
|
+
@@ -61,7 +72,7 @@ ← unify_query 上方的 CCG 生效条件注释
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`unify_query` 本体(工作树 `:76-96`)不在任何 hunk 的变更行内(第三个 hunk 只改其上方 1 行注释,函数体为上下文)⇒ 「只改缺省与注释、不动算法本体」可核。
|
|
121
|
+
|
|
122
|
+
### 3.2 落点(按改动性质分三类)
|
|
123
|
+
|
|
124
|
+
| 类 | 落点 | 性质 |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| **判据(行为)** | `md_cg/semantic/unify.py:51,54`(缺省 `"1"`→`"0"`、docstring 同步);`rust/src/atoms.rs:118`(`map(\|v\| v=="0").unwrap_or(false)` → `.as_deref() != Ok("1")`) | 唯一改行为的落点,两侧各一处 |
|
|
127
|
+
| **连带缺陷** | `scripts/rank_parity.py:301-306`(A/B「开」臂由 `pop` 改**显式 `="1"`**);`:222` 注释;`:362` 显示串 | 改行为(恢复 A/B 判别力) |
|
|
128
|
+
| **文案/锚点/守卫(不改行为)** | `unify.py:23-36`、`:75`;`atoms.rs:31-43`、`:99-100`;`md_cg/mdcg.py:283-291`、`:3072-3076`;`md_cg/mdcos.py:849-851`;`md_cg/test_unify_scope.py:9-12,59-74,175`(第 1 节改三态、余下各节**显式 `=1`** 下跑、片尾归还 env);`md_cg/test_en_pipeline.py:16-23,146-169`(缺省态断言改为**归零**、新增显式 `"1"` 态断言);`md_cg/test_semantic_canonical.py:209-213,225-231`;`md_cg/test_rank_parity_score_mode.py:11-16`;`md_cg/bench_e2e_locomo_qa.py:28-35,278-281,361`;`README.md:363,555-568`;`docs/hive/检索算法口径对照_v0.1.md:3-9,11,65-68,88-92,119-138,144-152,171-183` | 口径面同步;**不改变任何检索行为** |
|
|
129
|
+
| **新守卫** | `md_cg/test_unify_default_off.py`(701 行,新建、未跟踪) | 三态 + 同一池检索读数 + 两侧一致 + 定点变异自证 + ANCHOR-MISS 退码 2 |
|
|
130
|
+
|
|
131
|
+
### 3.3 新守卫的判据结构(读码所见)
|
|
132
|
+
|
|
133
|
+
隔离前置(`:86-97`,辅助根/库根全落 `tempfile.mkdtemp`,口径类 env 在验证前被 pop)、被测面**可替换表** `U/R/RS`(`:122-124`)、三态环境上下文 `env_state`(`:187-202`)、读数夹具(`build_pool` `:224-236`、`py_reading` `:240-251`、`rust_reading` `:255-293` 走真 release 二进制的 `--serve` 协议)、断言组 G0–G4(`:307-501`)、变异表(`:520-537`)、`_mutate_mode`(`:592-675`,ANCHOR-MISS → 退出码 2)、`main`(`:678-697`,二进制缺失即 fail-closed 返回 1,不静默 SKIP)。
|
|
134
|
+
|
|
135
|
+
### 3.4 运维前提:缺省翻关对**长驻进程**何时生效(读码定位,未做端到端翻转实验)
|
|
136
|
+
|
|
137
|
+
| 侧 | 读取时机 | 结论 |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| Python | `unify_on()` **每次调用**读 env(`md_cg/semantic/unify.py:54`) | 无需重启即对**新调用**生效;且 query 缓存键含 `env_switch_key()` 快照(`md_cg/hotcache.py:63-71`,登记在 `_KEYED_EXTRA`)⇒ 同一进程内跨口径**不串缓存** |
|
|
140
|
+
| Rust | `Atoms::from_env()` 在**引擎构造时**读一次(`rust/src/engine.rs:140`;评测二进制 `rust/src/main.rs:112`) | **长驻 serve 进程必须重启**才切到新缺省(进程内已载入的 `Atoms` 不会自更新)。该「升级须重启」运维前提本仓已定案并写在 `README.md:112-…`「♻️ 升级后须重启长驻 MCP 进程(代校验)」 |
|
|
141
|
+
|
|
142
|
+
⚠ **未验证**:本报告**未**在真实长驻 serve 进程上做「翻 env → 观察是否需重启」的端到端实验;上表是读码结论(读取点 + README 既有前提),不是实测。
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 四、验证数字(本次会话实跑)
|
|
147
|
+
|
|
148
|
+
> 全部命令在 `D:\program\dsh-memory-main`(工作树)执行;标【副本】者在一个**字节保真临时副本**执行——副本 = `git ls-files` 2109 件逐文件字节拷贝 + 未跟踪的新守卫 1 件,位于 `%TEMP%\unifyoff_report`。副本内建库/建 target 均落临时目录,**工作区在全部实验前后 `git status --short` 逐行相同**(12 M + `.zcode/` + `md_cg/test_unify_default_off.py`)。
|
|
149
|
+
|
|
150
|
+
### 4.1 新守卫正向
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
$ python -X utf8 -m md_cg.test_unify_default_off
|
|
154
|
+
→ UNIFY-DEFAULT-OFF 守卫:43 通过,0 失败,0 跳过 退出码 0
|
|
155
|
+
```
|
|
156
|
+
断言总计 **43**(本次计数:输出中 `PASS` 行 43 行;分组 = G0 5 条 / G1 11 条 / G2 7 条 / G3 11 条 / G4 9 条)。**0 跳过**意味着 G3 的「两侧一致性(真 release 二进制 `--serve`)」本次确实跑了,未走 SKIP 分支(依赖缺失时守卫会逐条 `SKIP(未跑)` 并补一条 fail-closed 红项,见 `:405-409`)。
|
|
157
|
+
|
|
158
|
+
### 4.2 定点变异自证(每处变异红项数)
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
$ python -X utf8 -m md_cg.test_unify_default_off --mutate 退出码 0
|
|
162
|
+
未变异基线:失败=0(必须为 0)
|
|
163
|
+
M1 Python 缺省改回 "1"(缺陷形态:未设=开) 红项=13 预期=13 红(恰好命中预期)
|
|
164
|
+
M2 Rust 三态改回「未设=开」(缺陷形态) 红项=8 预期=8 红(恰好命中预期)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**M1 的 13 个红项**(逐条点名):`G1a`、`G1d`、`G1g`、`G1h`、`G2b`、`G2c`、`G2e`、`G2f`、`G2g`、`G3g[未设]`、`G3h`、`G4a`、`G4b`。
|
|
168
|
+
**M2 的 8 个红项**(逐条点名):`G3b`、`G3c`、`G3e`、`G3f`、`G3g[未设]`、`G3i`、`G4d`、`G4e`。
|
|
169
|
+
(同一次输出里的**环境旁白**,不计入红项:M2 走「源码定点变异 + 临时 `CARGO_TARGET_DIR` 重建真二进制」,本次重建 rc=0;M1 的 `G0d/G0e` 是**工作区**前置,设计上刻意不被变异弄红。)
|
|
170
|
+
红项数「恰好等于预期」本身就是判据:多红=判据越界、少红=判据空转,两者都判失败(守卫 `:659-667`)。
|
|
171
|
+
|
|
172
|
+
### 4.3 rank_parity 三腿(工作区实跑,`--exe rust/target/release/mdcg-eval.exe`)
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
$ python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe
|
|
176
|
+
→ unify=0(默认关) · 逐位一致 10/10 · 集合一致 10/10 · top-1 一致 10/10 rc=0
|
|
177
|
+
$ ... + --dataset scripts/retrieval_dataset.json
|
|
178
|
+
→ unify=0(默认关) · 逐位一致 10/10 · 集合一致 10/10 · top-1 一致 10/10 rc=0
|
|
179
|
+
$ MDCG_UNIFY_QUERY=1 ... + --dataset scripts/retrieval_dataset.json
|
|
180
|
+
→ unify=1 · 逐位一致 8/10 · 集合一致 8/10 · top-1 一致 9/10 rc=1
|
|
181
|
+
[DIFF] soul hub hot cache | [DIFF] token verification fail closed
|
|
182
|
+
```
|
|
183
|
+
与 `docs/hive/检索算法口径对照_v0.1.md:126-139` 逐项相符:两条 DIFF 只在显式开时重现;缺省态由修前的 8/10 变 10/10 rc=0(修前读数出处见 §二 末注)。
|
|
184
|
+
|
|
185
|
+
### 4.4 locomo-zh-500 验收读数【副本,各两遍】
|
|
186
|
+
|
|
187
|
+
`python -X utf8 -m md_cg.bench_locomo_zh_public`(池 567 / 题 500,脚本自报一致)
|
|
188
|
+
|
|
189
|
+
| 归一层态 | lexical hit@1 | hit@5 | MRR | lexical,fuzzy hit@1 | hit@5 | MRR |
|
|
190
|
+
|---|---|---|---|---|---|---|
|
|
191
|
+
| **缺省**(未设) | **96.4%** | 99.8% | 0.9785 | **97.2%** | 100.0% | 0.9851 |
|
|
192
|
+
| 显式 `=1` | **95.8%** | 99.8% | 0.9755 | **96.6%** | 100.0% | 0.9821 |
|
|
193
|
+
|
|
194
|
+
两遍逐位相同(缺省两遍 MRR 0.9785/0.9851;`=1` 两遍 0.9755/0.9821;第一遍的 `=1` 读数另从产物读出 `configs.lexical = {hit@1 0.958, hit@5 0.998, mrr 0.9755}` 与第二遍 stdout 互证)。
|
|
195
|
+
**读数归属**:修后**缺省 = 修前关态**(96.4/97.2)、修后**显式 `=1` = 修前缺省**(95.8/96.6)——翻缺省是一次**开关面的等价搬迁**,未引入新的检索行为。
|
|
196
|
+
**产物路径说明**:产物写在**副本内**(本次输出行显示 `<副本>\data\external\eval_results\public_locomo_zh_replay.json`),不在工作区;且该前缀被 `.gitignore:73 /data/external/` 覆盖(实测 `git check-ignore -v data/external/eval_results/public_locomo_zh_replay.json` → 命中 `.gitignore:73`)——这正是它与 §四 抬头「工作区逐行相同」并列成立的条件。
|
|
197
|
+
|
|
198
|
+
### 4.5 定向守卫(工作区,rc 为真实退出码)
|
|
199
|
+
|
|
200
|
+
| 命令 | 读数 | rc |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| `-m md_cg.test_unify_scope` | 101 断言全绿(fixture 19 例,两侧同源) | 0 |
|
|
203
|
+
| `-m md_cg.test_en_pipeline` | 49 assertions all green | 0 |
|
|
204
|
+
| `-m md_cg.test_semantic_canonical` | 33 断言全绿 | 0 |
|
|
205
|
+
| `-m md_cg.test_rank_parity_score_mode` | CH-1 守卫 40 通过 / 0 失败 / 0 跳过 | 0 |
|
|
206
|
+
| `-m md_cg.test_retr_score_once` | PASS 20 / FAIL 0 | 0 |
|
|
207
|
+
| `-m md_cg.test_unify_default_off` | 43 通过 / 0 失败 / 0 跳过 | 0 |
|
|
208
|
+
|
|
209
|
+
### 4.6 HEAD(修前实现)↔ 现行 逐位 oracle
|
|
210
|
+
|
|
211
|
+
做法:`git show HEAD:md_cg/semantic/unify.py` 导出到临时目录,用与守卫同款 `install_unify`(把文件装成进程内唯一 `md_cg.semantic.unify`)加载后比较 `unify_query` 产物。**query 集合与来源(可复算)**:`43` 条 = **14 条手工探针**(英文/中夹英/纯中文/含前后空白/全大写英文等)+ **10 条** `scripts/retrieval_dataset.json` 的 `q`(`"cross-lingual"/"en-direct"/"en-life"/"zh-direct"/"zh-life"` 五类 tag 共 10 条)+ **19 条** `md_cg/semantic/unify_fixture.json` 的用例(字段 `in/out`);三源之间存在 7 处重复串,**去重后 36 条唯一串**。(三项来源合计即 43 条,无第四来源。)
|
|
212
|
+
|
|
213
|
+
| 对照 | 逐位相同 |
|
|
214
|
+
|---|---|
|
|
215
|
+
| 修前**未设**(=缺省开) vs 现行**显式 `"1"`** | **True**(43/43 条) |
|
|
216
|
+
| 修前**显式 `"0"`** vs 现行**未设** | **True**(43/43 条) |
|
|
217
|
+
| 正对照:现行 开 vs 关 | 有差异(26/43 条),判据非空转 |
|
|
218
|
+
| 非 `"1"` 取值 `"TRUE"` vs 现行未设 | **Python 侧**同判(同为关)= True;Rust 侧见 §四.13 |
|
|
219
|
+
|
|
220
|
+
### 4.7 python 全量套件【副本】
|
|
221
|
+
|
|
222
|
+
#### 4.7.0 计数口径(先定死)
|
|
223
|
+
|
|
224
|
+
`scripts/run_tests.py:239-240` 的汇总行是
|
|
225
|
+
`===== SUMMARY {len(runnable)-len(bad)}/{len(runnable)} 通过,{len(skipped)} 跳过 =====`,
|
|
226
|
+
即:**分母 M = 可运行目标数(= 目标总数 − 跳过数),分子 N = 通过数;跳过数单列,不进分母**。目标总数由 `_discover()` 决定,可实测:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
$ python -X utf8 scripts/run_tests.py --list | tail -1
|
|
230
|
+
共 294 个 ← 工作区与副本(含新守卫)实测同值
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
⇒ 「289」=294 − 5(跳过);「282+7 = 289」(通过+失败 = 分母)自洽;**不存在 294/293 与分母打架**。§二.10 的读数(287/288 通过、5 跳过、1 红)对应**修前树**:288 + 5 = **293 目标** = 294 − 1——差的那 1 个目标就是**当时尚未创建的新守卫**(`md_cg/test_unify_default_off.py`);287 + 1 = 288 亦自洽。
|
|
234
|
+
|
|
235
|
+
#### 4.7.1 三遍读数(同一副本,逐步补前置)
|
|
236
|
+
|
|
237
|
+
| 遍 | 副本状态 | 读数 | rc | 红项 |
|
|
238
|
+
|---|---|---|---|---|
|
|
239
|
+
| 1 | 仅 `git ls-files` 拷贝 + 新守卫(**无任何 release 构建、无在役池**) | **282/289 通过、5 跳过** | 1 | 7 红,全部是缺构建产物/在役池的**前置**:`md_cg.test_rank_parity_score_mode`、`md_cg.test_unify_default_off`(两件的 fail-closed 二进制前置)、`hive.test_h6_mcp_depends_on`、`hive.test_id_contract_v2`、`hive.test_job_id_segment_dot`、`hive.test_orch`、`hive.test_result_anchor_chain` |
|
|
240
|
+
| 2 | 补 `cargo build --release --offline` @ `rust/`、`hive/` | **288/289 通过、5 跳过** | 1 | 唯一红 `hive.test_job_id_segment_dot`(C0 缺在役池) |
|
|
241
|
+
| 3 | **再补 `hive/jobs` 在役池**(工作区拷入) | **289/289 通过、5 跳过** | **0** | 无 |
|
|
242
|
+
|
|
243
|
+
第 3 遍的完整前置命令(可复现独立复核的读数):
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
副本 = git ls-files(2109) 逐文件字节拷贝 + 未跟踪新守卫 1 件 # 工具:shutil.copyfile,逐条
|
|
247
|
+
(cd rust && cargo build --release --offline) # → rust/target/release/mdcg-eval[.exe]
|
|
248
|
+
(cd hive && cargo build --release --offline) # → hive/target/release/hive
|
|
249
|
+
cp -r <工作区>/hive/jobs <副本>/hive/jobs # 在役池(18 条目 = 15 个 h* 目录 + 3 个非 h* 文件)
|
|
250
|
+
python -X utf8 scripts/run_tests.py # → SUMMARY 289/289 通过,5 跳过;rc=0
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
⇒ 第 2 遍与第 3 遍之差**完全由在役池补齐解释**,与独立复核的 `289/289`(§五)同值可复现。
|
|
254
|
+
第 2 遍唯一红的点名红项(副本内单跑):
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
$ python -X utf8 -m hive.test_job_id_segment_dot
|
|
258
|
+
[FAIL] C0 前置:在役池可枚举且非空(防空池假绿) ← 池=<副本>\hive\jobs 实得 0 个 h* 目录
|
|
259
|
+
```
|
|
260
|
+
⇒ **副本环境前置**,非本缺陷:工作区 `hive/jobs` 实读 **18 个条目,其中 `h*` 目录 15 个、非 `h*` 文件 3 个**(`_serve.json`、`_serve.log`、`_serve.tmp20528`)——所以 §二.10 的「15 个 `h*` 目录」与本节「18 个条目」是**同一目录的两种计数**(`ls -d hive/jobs/*/ | wc -l` = 15;`ls hive/jobs | wc -l` = 18;`ls hive/jobs | grep -c '^h'` = 15),`h*` 是 **15**。
|
|
261
|
+
`hive` 分组单跑:27/28 通过、rc=1(同唯一红)。⚠ 与采集腿(§二.10,287/288)与独立复核(§五,289/289)的差异**同源**:三者跑在各自副本上,在役池/构建产物是否补齐不同 ⇒ 红项集合不同。**本报告读数以本节为准。**
|
|
262
|
+
|
|
263
|
+
### 4.8 `npm run gate` 八条腿
|
|
264
|
+
|
|
265
|
+
**逐腿判定(8/8 rc=0)**:
|
|
266
|
+
|
|
267
|
+
| # | 腿 | 读数 | rc | 跑在哪 |
|
|
268
|
+
|---|---|---|---|---|
|
|
269
|
+
| 1 | `check_unreachable.py` | 511 文件 / 命中 0 / 语法失败 0 | 0 | 工作区 |
|
|
270
|
+
| 2 | `check_publish_artifact.py` | `VERDICT=PASS`(R1–R6 全 PASS) | 0 | 副本 |
|
|
271
|
+
| 3 | `cogmap_sync.py check` | 通过(cg 36 op / stg 4 op / whitebox 6 action / mdcg_* 31) | 0 | 工作区 |
|
|
272
|
+
| 4 | `link_check.py` | `OK=235 ALLOWED=0 BROKEN=0 UNTRACKED=0` | 0 | 工作区 |
|
|
273
|
+
| 5 | `workspace_index.py --check` | `[OK] 顶层目录 20 · 追踪 2109 件` | 0 | **工作区** |
|
|
274
|
+
| 6 | `verify_discipline.py --allow-missing` | 结论:10/10 目标一致 | 0 | 工作区 |
|
|
275
|
+
| 7 | `gate_rust_crate_test.py` | `cargo test rc=0:28 passed / 0 failed` | 0 | 副本 |
|
|
276
|
+
| 8 | `gate_rust_parity.py` | `rank_parity rc=0` 逐位 10/10(`unify=0(默认关)`) | 0 | 副本 |
|
|
277
|
+
|
|
278
|
+
**串联 `npm run gate` 未取得全绿**,其真因不是「副本里多了一件被追踪的新守卫」,而是**副本没有提交**:副本内 `npm run gate` 卡在 leg 5,报 `[DRIFT] 正文陈化`;追因实验证明——`workspace_index.py:153-157` 的 `_norm` 只把**十六进制 HEAD 指纹**归一化(正则要求 `HEAD` 后跟 4–40 位十六进制字符),而副本 `git rev-parse --short HEAD` 返回 `unknown`,故归一化后仍不同。对照实验(本次实跑):
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
# 副本内做一次提交后(HEAD=4e11b91,追踪 2110 件、索引文件仍是工作区的 2109 件版本)
|
|
282
|
+
$ python -X utf8 scripts/workspace_index.py --check
|
|
283
|
+
[OK ] 工作区索引与仓库一致(顶层目录 20 · 追踪 2110 件) rc=0
|
|
284
|
+
# 反向对照:把索引里某行计数改成 999(表格计数列)
|
|
285
|
+
$ python -X utf8 scripts/workspace_index.py --check
|
|
286
|
+
[OK ] 工作区索引与仓库一致 → 计数列被 _norm 掩掉,不参与判定 rc=0
|
|
287
|
+
```
|
|
288
|
+
⇒ ①DRIFT 与「新守卫是否被追踪/计数多少」**无关**(计数列本就被掩掉);②**串联 gate 未在工作区跑**(本报告任务硬边界:只改报告文件、不 `git add`),因此契约「`npm run gate` 八条腿全绿」这一条**本报告只给到逐腿 rc=0,未给到串联一次跑通**——如实标注为**未满足/未验证**(见 §七.1 对照表)。
|
|
289
|
+
|
|
290
|
+
### 4.9 容器两栈
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
$ docker run --rm -v <副本>:/work -w /work rust:bookworm bash scripts/linux_verify.sh full
|
|
294
|
+
→ === 汇总: 38 pass / 0 fail === (docker 退出码 0)
|
|
295
|
+
含 cargo test、20 套 python、hive 四件、断言判别力自证、smoke_test (linux)
|
|
296
|
+
$ docker run --rm -v <副本>:/work -w /work node:22-bookworm bash scripts/verify_linux_node.sh
|
|
297
|
+
→ node v22.23.3 / ci=0 build=0 test=0 / # pass 96 / # fail 0 / # cancelled 0 / # skipped 3
|
|
298
|
+
(docker 退出码 0)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 4.10 暴露面复核(独立复核列出的 uncovered,本报告复跑)
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
MDCG_UNIFY_QUERY=1 python -X utf8 -m md_cg.test_unify_scope → FAILED 1/101,rc=1
|
|
305
|
+
(点名:MDCG_UNIFY_QUERY 未设即关(缺省关,2026-09-30 翻))
|
|
306
|
+
MDCG_UNIFY_QUERY=1 python -X utf8 -m md_cg.test_en_pipeline → 48 passed, 1 FAILED,rc=1
|
|
307
|
+
(点名:缺省(unify 缺省关 + EN_ATOMS 关):词面零重叠召回归零)
|
|
308
|
+
MDCG_UNIFY_QUERY=1 python -X utf8 -m md_cg.test_unify_default_off → 43 通过 / 0 失败 / 0 跳过,rc=0
|
|
309
|
+
```
|
|
310
|
+
⇒ 与该 uncovered 逐条一致(§五)。**这是环境敏感性,不是缺陷**:两件判据的前提是「缺省态 = 关」,调用方进程已把开态钉死时其前置断言不成立。
|
|
311
|
+
|
|
312
|
+
### 4.11 受影响面 · 断言判别力(本报告独立复刻)
|
|
313
|
+
|
|
314
|
+
复刻 `test_en_pipeline.py:133-146` 的两节点池(`n_beef` / `n_unrel`,`query="I ate beef yesterday"`),三态读数:
|
|
315
|
+
|
|
316
|
+
| env | 返回 | 修前断言 `len(res)>=1 and ids[0]=="n_beef"` | 修后断言 `not res or all(score<=0)` |
|
|
317
|
+
|---|---|---|---|
|
|
318
|
+
| 未设 | `[('n_beef',0.0), ('n_unrel',0.0)]` | **真** | 真 |
|
|
319
|
+
| `"0"` | `[('n_beef',0.0), ('n_unrel',0.0)]` | **真** | 真 |
|
|
320
|
+
| `"1"` | `[('n_beef',0.4)]` | **真** | **假** |
|
|
321
|
+
|
|
322
|
+
⇒ 修前断言在**三态下恒真**(零判别力,比 §二.8 记录的「两态都过」更强);修后断言在开态转假 ⇒ 有判别力。
|
|
323
|
+
|
|
324
|
+
### 4.12 `--ab` 是什么腿、5/10 怎么复现
|
|
325
|
+
|
|
326
|
+
`--ab` 是 `scripts/rank_parity.py` 的**独立子模式**(帮助文本 `:274-276`:「统一归一层 A/B:unify on/off 各跑 **Python 侧**,按 tag 汇总 top-1 变化」;必须与 `--dataset` 同用,实现 `:296-320`,库根走 `tempfile.mkdtemp`)。它**不是** §四.3 那三腿(那是 **Python↔Rust 两侧逐位对拍**)。本报告实跑:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
$ python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe \
|
|
330
|
+
--dataset scripts/retrieval_dataset.json --ab
|
|
331
|
+
A/B(30 节点,top-1 变化;口径 jaccard(本 harness 钉住)):
|
|
332
|
+
[cross-lingual] beef noodles lunch off -> ds_en_03 on -> ds_zh_00
|
|
333
|
+
[cross-lingual] soul hub hot cache off -> ds_en_02 on -> ds_zh_02
|
|
334
|
+
[en-direct] token verification fail closed off -> ds_en_04 on -> ds_zh_05
|
|
335
|
+
[en-direct] database migration backup off -> ds_en_08 on -> ds_zh_08
|
|
336
|
+
[en-life] piano practice thirty minutes off -> ds_en_09 on -> ds_zh_07
|
|
337
|
+
top-1 变化 5/10 退出码 0
|
|
338
|
+
```
|
|
339
|
+
**「5/10 变化」与 §四.3 的「top-1 一致 9/10」是两个不同的量,不冲突**:前者=**同一个 Python 侧**在 开/关 两态之间 top-1 不同的题数;后者=**显式开态下 Python 与 Rust 两侧**top-1 相同的题数(其余 1 条即两条 DIFF 之一在 top-1 上也分叉,另一条只是集合不同 ⇒ 集合一致 8/10)。
|
|
340
|
+
|
|
341
|
+
### 4.13 修前非 `"0"/"1"` 取值的两侧不对称(本报告实跑)
|
|
342
|
+
|
|
343
|
+
做法:用与守卫 M2 **逐字相同**的替换文本把工作树 `rust/src/atoms.rs` 的判据改回修前形态(`git show HEAD:rust/src/atoms.rs` 的判据行与 M2 的新文本**实测为同一字符串**),以临时 `CARGO_TARGET_DIR` 重建 release 二进制;两侧在同一 4 节点池上按 `--serve` 协议跑四态:
|
|
344
|
+
|
|
345
|
+
| 二进制 | 未设 | `"0"` | `"1"` | `"TRUE"` |
|
|
346
|
+
|---|---|---|---|---|
|
|
347
|
+
| 现行工作树(`.as_deref() != Ok("1")`) | `n_a`(关) | `n_a`(关) | `n_gold`(开) | `n_a`(**关**) |
|
|
348
|
+
| 修前形态(`map(\|v\| v=="0").unwrap_or(false)`,M2 重建 rc=0) | `n_gold`(开) | `n_a`(关) | `n_gold`(开) | `n_gold`(**开**) |
|
|
349
|
+
|
|
350
|
+
(`n_gold` = 只能被归一层命中的中文节点;`n_a` = 噪声节点,即未命中。)
|
|
351
|
+
⇒ 修前 **Rust 侧 `"TRUE"` = 开、Python 侧 `"TRUE"` = 关**(Python 侧由 §四.6 的 oracle 实测);修后两侧同为关。该不对称是本缺陷的**同一两行**的自然结果(不是新缺陷),修法把两侧统一到「唯一开态 = `"1"`」。**新守卫未对它写断言**(§六.E)。
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 五、独立复核判定与它列出的 uncovered
|
|
356
|
+
|
|
357
|
+
**判定:ACCEPT。**
|
|
358
|
+
|
|
359
|
+
独立复核方(不同执行体)自述依据要点(转述):被测面 = 本工作树(未提交);契约取自工作流脚本 `args.contract`(`defect=UNIFY-DEFAULT-OFF`);**未编辑任何工作区文件**(复核前后 `git status --short` 逐行相同);全部实验库根走 `tempfile.mkdtemp` 并在跑完后清理。其四组核查为:
|
|
360
|
+
|
|
361
|
+
1. **各腿(现行树,只读,均自建临时库)**:`test_unify_scope` 101 全绿 rc=0;`test_en_pipeline` 49/49 rc=0;`test_semantic_canonical` 33/33 rc=0;`test_rank_parity_score_mode` 40/0 rc=0;`test_retr_score_once` PASS 20/FAIL 0 rc=0;`rank_parity --exe …` 逐位 10/10 rc=0;加 `--dataset` 逐位 10/10 rc=0;`MDCG_UNIFY_QUERY=1` + `--dataset` 逐位 8/10·集合 8/10·top-1 9/10 rc=1(两条 DIFF 与 §五.2 表逐项相符);题池腿一池四跑(未设→`1`→未设→`1`):未设 96.4/97.2、`=1` 95.8/96.6,交错序列不串态。
|
|
362
|
+
2. **逐位 oracle**:HEAD 实现导出后同款装载——「改前缺省(开) vs 现行显式 `=1`」`unify_query` 逐位相同=True、`topk` 逐位相同=True、题池 hit@1/hit@5/MRR 全等(0.958/0.998/0.9755 与 0.966/1.0/0.98206…);「改前显式 `"0"` vs 现行未设」同样逐位相同=True;正对照有差异;非 `"1"` 取值 `"TRUE"` 与未设同判。另以 `git diff HEAD -- md_cg/semantic/unify.py` 确认该文件相对 HEAD 只改注释与那一处缺省字面量。
|
|
363
|
+
3. **守卫本体**:正向 43/0/0 rc=0(断言总数 43,另在进程内数得 `_PASS=43`);`--mutate` 基线失败=0、M1 红 13/预期 13、M2 红 8/预期 8、rc=0;删断言探针(内存内把 `g1`/`g2` 换 no-op,文件未动)→ `_mutate_mode()` 返回 **1**、M1 红 4≠13;把 `g3` 换 no-op → 返回 **1**、M1 红 11≠13、M2 红 2≠8(即「守卫能被证明在数东西」)。
|
|
364
|
+
4. **不得静默面可观测**:把 `_EXE` 与 `R["exe"]` 指向不存在路径 → `main()` 返回 **1** 并打印 fail-closed 文案(不静默返回 0);单跑 `g3`(二进制缺失)→ 通过 0/失败 1/跳过 1(SKIP 不计入通过数,且补一条 fail-closed 红项);把 `_MUTATIONS` 锚点改成不存在的行 → `_mutate_mode()` 返回 **2**(ANCHOR-MISS fail-closed)。
|
|
365
|
+
|
|
366
|
+
**它列出的 uncovered(该节只有这一条,无编号表)**:外部 env 已导出 `MDCG_UNIFY_QUERY=1` 时,`python -m md_cg.test_unify_scope` 红 1/101、`python -m md_cg.test_en_pipeline` 红 1/49(新守卫自身 `pop` env,43/0/0 不受影响)。——本报告在 §四.10 复跑,逐条一致。
|
|
367
|
+
|
|
368
|
+
**它给出的全量/容器读数**:python 全量 = 0(`===== SUMMARY 289/289 通过,5 跳过 ====`);容器栈一 = 0(`=== 汇总: 38 pass / 0 fail ===`);容器栈二 = 0(`# skipped 3 / # todo 0`)。**本报告已复现其 289/289**(§四.7.1 第 3 遍,配方同节),故该差异不再是悬案;容器两栈读数与 §四.9 一致。
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 六、边界与未覆盖
|
|
373
|
+
|
|
374
|
+
**A. 本报告未重跑的面(如实披露)**
|
|
375
|
+
- §二 的 11 条修前腿**整体未重跑**(需重建 HEAD 临时树、v0.6.1 archive 树、Rust 复现测试等)。只对其中**四点**做了直接复核:HEAD 判据字面量(§一.2)、HEAD↔现行逐位等价(§四.6)、修前断言判别力(§四.11)、修前非 `"0"/"1"` 取值的两侧不对称(§四.13)。
|
|
376
|
+
- 采集腿里的 v0.6.1 对照(§二.5)、构造期 Rust `cargo test --test repro_unify_env_tristate`(§二.2)、接线 spy(§二.7)——**本报告均未重跑**。
|
|
377
|
+
- 独立复核的四组核查(§五)为**其自述读数**,本报告未逐条重跑;独立复跑的只有 §四.10(暴露面三条)、§四.11(判别力复刻)、§四.13(非 `"0"/"1"` 取值)。
|
|
378
|
+
- **退化/容错路径(空池负对照、故障注入 `canonical.query_atoms` 抛异常、Rust `MDCG_EN_ZH_MAP` 指向不存在路径时的 stderr 退化提示)**:出自**独立复核**的「退化/容错路径」核查(其依据全文里紧接第①组之后的那段;本报告 §五 只转述了四组核查,未逐字抄录该段),**不在 §二 的 11 条采集腿里**;本报告未重跑。
|
|
379
|
+
- **长驻进程的运维前提**(§三.4)为读码结论,**未做端到端翻转实验**。
|
|
380
|
+
|
|
381
|
+
**B. 明确不修而留池的面(本轮边界)**
|
|
382
|
+
- **对外参考数字不一致**:`README.md:324`/`:328` 的 93.6 / 97.6 按契约**保留不动**,但公开复现脚本的**缺省输出已变为 96.4 / 97.2**(§四.4 的 stdout 里仍打印「(VERSION.json 参考 93.6%)/(… 97.6%)」对照行,本次实跑可见)。**出处查明情况**:这两个数来自 `data/benchmarks/locomo-zh-500/VERSION.json` 的 `reference_scale.self_reported`(`{lexical: hit@1 0.936, hit@5 0.992, mrr 0.96}`、`{lexical+fuzzy: 0.976/0.998/0.986}`,文件 `written_at` 2026-09-11)与脚本常量 `md_cg/bench_locomo_zh_public.py:55` `REFERENCE = {"lexical": 0.936, "lexical,fuzzy": 0.976}`;**该记录未标注所对应的开关态与作用域**。本报告实跑与采集腿合计掌握的**四种状态**(修后缺省 96.4/97.2【本报告实跑】、修后显式开 95.8/96.6【本报告实跑】、修前缺省 95.8/96.6【采集腿】、v0.6.1 缺省 94.4/87.2【采集腿】)**均不等于 93.6/97.6** ⇒ 「93.6/97.6 出自哪支口径」**本报告未能查明**,需由 VERSION.json 补记或编排侧裁定,修复方不自行改数(`docs/hive/检索算法口径对照_v0.1.md:50` 已注明「README 数字不因本任务变动,数字回流由编排侧另行核」)。
|
|
383
|
+
- **`--dataset` 口径是否并入门禁腿**:`docs/hive/检索算法口径对照_v0.1.md:139-140`(§七 待裁定项 1)保留待裁定——缺省已绿,但显式开归一层时恒 8/10,并入前须先裁定差分归属。本报告不代裁。
|
|
384
|
+
- **历史留档刻意不改写**:`docs/eval/` 下既往评测报告、`scripts/retrieval_dataset.json` 的 design 说明、`_md_cg_p27` 留档条目——改写即伪造历史。
|
|
385
|
+
- **文书/接线类锚点不由变异证明**:守卫 `G4c`/`G4f`/`G4g`/`G4h`/`G4i` 不被 M1/M2 弄红——效力由「实现漂移即红」保证(守卫 `:48-49`、`:516-519` 已如实标注)。
|
|
386
|
+
- **Rust 侧未新增 `cargo test` 单测**:三态覆盖走「真 release 二进制 `--serve` 行为断言 + 源码锚点」(守卫 G3/G4d/G4e)。
|
|
387
|
+
- **本任务硬边界「不写活库」** ⇒ 工作纪律第 16 条归档**未执行**——显式声明。
|
|
388
|
+
- ⚠ **`npm run gate` 串联未在工作区跑通**(逐腿 8/8 rc=0,见 §四.8)⇒ 契约「八条腿全绿」这一条**未取得串联证据**(§七.1 逐条对照)。
|
|
389
|
+
|
|
390
|
+
**C. 环境性红项的归属(不指向本缺陷)**
|
|
391
|
+
- §四.7 第 2 遍的唯一红(`hive.test_job_id_segment_dot` C0)=副本缺 `hive/jobs` 在役池;第 3 遍补池后 **289/289 rc=0**(§四.7.1);
|
|
392
|
+
- §四.8 副本 leg 5 DRIFT =副本**无提交**(副本的 `HEAD` 显示为 `unknown`,不被 `_norm` 归一化;`workspace_index.py:153-157`),与守卫是否入库无关(对照实验见 §四.8);
|
|
393
|
+
- §四.10 的 2 条红 ⇐ 调用方进程已导出 `MDCG_UNIFY_QUERY=1`(环境敏感,非缺陷)。
|
|
394
|
+
|
|
395
|
+
**D. 本次实验的工作区洁净性**:全部实验前后 `git status --short` 逐行相同(12 `M` + `.zcode/` + `md_cg/test_unify_default_off.py`);本报告只新增 `docs/eval/归一层缺省翻关_修复记录_v1.0.md` 一个文件;副本、容器挂载树、临时库根均在 `%TEMP%` 下。§四.4 的题池产物写在副本内且被 `.gitignore:73` 覆盖。
|
|
396
|
+
|
|
397
|
+
**E. 本轮未覆盖的判据缺口**:修前两侧对**非 `"0"/"1"` 取值**不同判(§一.5、§四.13 实测);新守卫只钉「未设 / `"0"` / `"1"`」三态,**未把 `"TRUE"` 一类取值写成断言**。若要钉住「唯一开态」的完整语义,须在守卫里补一条(本轮硬边界只改报告文件,未改守卫)。
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## 七、附录
|
|
402
|
+
|
|
403
|
+
### 7.1 契约原文(`args.contract` 的关键段,逐字)
|
|
404
|
+
|
|
405
|
+
来源:`.zcode/workflow-runs/dwfrun-e8eabeba-f3b8-45a5-8b59-3af9088a8a46.mjs` 的 `payload.args.contract`(本报告实读该文件)。
|
|
406
|
+
|
|
407
|
+
**【缺陷定义】** 统一归一层当前缺省为「开」。Python 判据单点 `md_cg/semantic/unify.py::unify_on` 读 `os.environ.get("MDCG_UNIFY_QUERY", "1") == "1"`(缺省 `"1"`);Rust 侧 `rust/src/atoms.rs::Atoms::unify` 读 `env::var("MDCG_UNIFY_QUERY").map(|v| v == "0").unwrap_or(false)`(未设 = 启用)。接线:Python 三处 search 入口(`md_cg/mdcg.py:3075-3076`、`md_cg/mdcos.py:852-853`、`md_cg/mdcos.py:1406-1407`),Rust 在 `engine.search` 单点。
|
|
408
|
+
**【使用者 2026-09-30 裁定】** 设 `MDCG_UNIFY_QUERY=0`——即把该开关的缺省改为「关」。
|
|
409
|
+
**【必须怎么修】**(1)缺省翻为关,两侧同一 env 语义;显式 `=1` 必须仍能开回;两侧对「未设 / `"0"` / `"1"`」三态判定必须一致。(2)同步全部受影响处(逐处给改动前后读数):`unify.py` 头注与 CCG 注释、`test_unify_scope.py:56`、`test_en_pipeline.py:17-18,146-158`、`test_semantic_canonical.py:209-235`、`test_rank_parity_score_mode.py`(**必须实测后据实更新;若变化无法解释,如实报告并停下,不许为了门禁变绿而改期望值**)、`rank_parity.py:359`、`bench_e2e_locomo_qa.py:279/:361`、`README.md:363,555-562`、`docs/hive/检索算法口径对照_v0.1.md:11,140`。(3)新增守卫 `md_cg/test_unify_default_off.py`:(a) 三态断言;(b) 缺省态与显式 `"0"` 态检索读数逐位相同(同一池);(c) 两侧一致性(Rust 侧若可在容器内跑则跑,不可跑则如实标注未覆盖);(d) 定点变异自证(红项数点名)。
|
|
410
|
+
**【不许动什么】** 不改 `unify_query` 算法本体与作用域收窄逻辑;不动 `atoms.rs` 的 CJK 判据与 `unify_fixture.json`;不改 `MDCG_EN_ATOMS`/`MDCG_SEMANTIC` 缺省、不删开关;不改 forbidden 规则、不写活库、不动在役 hive serve、不动 DSH 路径与 `hive/inbox.jsonl`;外部评审报告与转写本体不入库。
|
|
411
|
+
**【验收判据(逐条给读数,缺一不可)】**
|
|
412
|
+
|
|
413
|
+
| 契约条款 | 本报告读数 | 状态 |
|
|
414
|
+
|---|---|---|
|
|
415
|
+
| 修前独立复现:改动前树上跑 bench,记缺省态与 `=0` 态两行(各两遍) | §二.3(采集腿:95.8/96.6 对 96.4/97.2,各两遍逐位相同) | 采集取得,本报告未重跑 |
|
|
416
|
+
| 修后同一命令缺省态必须 = 修前关态(96.4/97.2),两遍逐位相同 | §四.4(96.4/97.2,两遍 MRR 逐位相同) | ✅ 实跑 |
|
|
417
|
+
| `MDCG_UNIFY_QUERY=1` 跑同一命令 = 修前开态(95.8/96.6) | §四.4(95.8/96.6,两遍逐位相同) | ✅ 实跑 |
|
|
418
|
+
| python 全量测试套件全绿 | §四.7.1 第 3 遍 **289/289 通过、5 跳过、rc=0**(副本补齐前置后) | ✅ 实跑(副本) |
|
|
419
|
+
| `npm run gate` 八条腿全绿(容器内 npm 不可 spawn,须用 `cmd /c npm …`) | §四.8:**逐腿 8/8 rc=0**;**串联未取得**(副本卡在 leg 5 的「无提交」环境面;工作区串联未跑——本任务硬边界) | ⚠ **部分**(未取得串联绿) |
|
|
420
|
+
| 容器双栈(`rust:bookworm scripts/linux_verify.sh full` 与 `node:22-bookworm` TS) | §四.9:38 pass/0 fail rc=0;node pass 96/fail 0/skipped 3 rc=0 | ✅ 实跑 |
|
|
421
|
+
| 守卫定点变异自证(红项数点名) | §四.1/§四.2(43/0/0 rc=0;M1 红 13、M2 红 8、基线 0) | ✅ 实跑 |
|
|
422
|
+
| 凡未能覆盖的,写进报告的未覆盖节,不许静默 | §六 A/B/C/E + 本节 ⚠ 一处(gate 串联) | ✅ |
|
|
423
|
+
|
|
424
|
+
### 7.2 复现命令一览(本报告 §四 用到的全部命令)
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# 守卫(工作区)
|
|
428
|
+
python -X utf8 -m md_cg.test_unify_default_off # 43/0/0 rc=0
|
|
429
|
+
python -X utf8 -m md_cg.test_unify_default_off --mutate # M1 红13 / M2 红8 rc=0
|
|
430
|
+
# 定向守卫(工作区)
|
|
431
|
+
python -X utf8 -m md_cg.test_unify_scope # 101 全绿 rc=0
|
|
432
|
+
python -X utf8 -m md_cg.test_en_pipeline # 49 全绿 rc=0
|
|
433
|
+
python -X utf8 -m md_cg.test_semantic_canonical # 33 全绿 rc=0
|
|
434
|
+
python -X utf8 -m md_cg.test_rank_parity_score_mode # 40/0/0 rc=0
|
|
435
|
+
python -X utf8 -m md_cg.test_retr_score_once # PASS 20 rc=0
|
|
436
|
+
# 两侧对拍与 A/B(工作区)
|
|
437
|
+
python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe # 10/10 rc=0
|
|
438
|
+
python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe --dataset scripts/retrieval_dataset.json # 10/10 rc=0
|
|
439
|
+
MDCG_UNIFY_QUERY=1 python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe --dataset scripts/retrieval_dataset.json # 8/10·8/10·9/10 rc=1
|
|
440
|
+
python -X utf8 scripts/rank_parity.py --exe rust/target/release/mdcg-eval.exe --dataset scripts/retrieval_dataset.json --ab # top-1 变化 5/10 rc=0
|
|
441
|
+
# 题池验收(副本)
|
|
442
|
+
python -X utf8 -m md_cg.bench_locomo_zh_public # 缺省 96.4/97.2
|
|
443
|
+
MDCG_UNIFY_QUERY=1 python -X utf8 -m md_cg.bench_locomo_zh_public # =1 95.8/96.6
|
|
444
|
+
# 全量(副本,需先建 rust/hive release 并拷入 hive/jobs 在役池)
|
|
445
|
+
python -X utf8 scripts/run_tests.py # 289/289 通过 5 跳过 rc=0
|
|
446
|
+
python -X utf8 scripts/run_tests.py --list # 共 294 个(= 289 + 5)
|
|
447
|
+
# 门禁逐腿(工作区)
|
|
448
|
+
python -X utf8 scripts/check_unreachable.py && python -X utf8 scripts/cogmap_sync.py check && \
|
|
449
|
+
python -X utf8 scripts/link_check.py && python -X utf8 scripts/workspace_index.py --check && \
|
|
450
|
+
python -X utf8 scripts/verify_discipline.py --allow-missing # 各 rc=0
|
|
451
|
+
# 门禁逐腿(副本)
|
|
452
|
+
python -X utf8 scripts/check_publish_artifact.py # VERDICT=PASS
|
|
453
|
+
python -X utf8 scripts/gate_rust_crate_test.py # cargo test 28 passed rc=0
|
|
454
|
+
python -X utf8 scripts/gate_rust_parity.py # 逐位 10/10 rc=0
|
|
455
|
+
# 容器双栈(挂副本)
|
|
456
|
+
docker run --rm -v <副本>:/work -w /work rust:bookworm bash scripts/linux_verify.sh full # 38 pass/0 fail
|
|
457
|
+
docker run --rm -v <副本>:/work -w /work node:22-bookworm bash scripts/verify_linux_node.sh # pass 96/fail 0
|
|
458
|
+
```
|