@furongjun1999/dsh-memory 0.6.1 → 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.
Files changed (48) hide show
  1. package/README.md +48 -18
  2. package/docs/README.md +1 -0
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. package/docs/mdcg/README/350/257/246/347/273/206/347/211/210_v0.4.10.md +88 -0
  9. 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
  10. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +47 -11
  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
  12. 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
  13. package/md_cg/bench_e2e_locomo_qa.py +11 -4
  14. package/md_cg/chain.py +47 -0
  15. package/md_cg/freshness.py +511 -0
  16. package/md_cg/generation.py +409 -0
  17. package/md_cg/hotcache.py +4 -1
  18. package/md_cg/mcp_server.py +128 -19
  19. package/md_cg/mdcg.py +509 -22
  20. package/md_cg/mdcos.py +203 -22
  21. package/md_cg/nodefile.py +74 -1
  22. package/md_cg/semantic/canonical.py +22 -0
  23. package/md_cg/semantic/unify.py +73 -22
  24. package/md_cg/semantic/unify_fixture.json +25 -0
  25. package/md_cg/sleep.py +1297 -0
  26. package/md_cg/sustain.py +146 -9
  27. package/md_cg/test_auto_defaults.py +424 -0
  28. package/md_cg/test_boundary_hit.py +410 -0
  29. package/md_cg/test_en_pipeline.py +22 -13
  30. package/md_cg/test_generation_guard.py +352 -0
  31. package/md_cg/test_h4_sustain_snapshot.py +14 -4
  32. package/md_cg/test_n212_n213_n224_generation_gates.py +14 -8
  33. package/md_cg/test_n230_dirty_replay.py +375 -0
  34. package/md_cg/test_p2_six_elements.py +463 -0
  35. package/md_cg/test_p3_legacy_closure.py +433 -0
  36. package/md_cg/test_p4_freshness.py +680 -0
  37. package/md_cg/test_p8_subgraph_chain.py +14 -1
  38. package/md_cg/test_rank_parity_score_mode.py +6 -0
  39. package/md_cg/test_semantic_canonical.py +5 -3
  40. package/md_cg/test_sleep.py +611 -0
  41. package/md_cg/test_sleep_p1.py +784 -0
  42. package/md_cg/test_time_core_lint.py +968 -0
  43. package/md_cg/test_unify_default_off.py +701 -0
  44. package/md_cg/test_unify_scope.py +182 -0
  45. package/md_cg/whitebox_kb/aeis_core/time_core.py +8 -0
  46. package/package.json +3 -2
  47. package/skills/plugin.json +1 -1
  48. package/utf8_boot.py +237 -0
@@ -0,0 +1,183 @@
1
+ # 睡眠周期 · 运维前提与维护指南(v1.0)
2
+
3
+ > **这一页回答一件事:开了睡眠周期之后,你的记忆库多了什么、在哪里、怎么维护、怎么关、怎么退。**
4
+ > 依据:`docs/plans/睡眠与自迭代_功能优化设计_v0.4.md`(规格冻结版)§四 / §4.7。
5
+ > 使用者裁定(2026-10-01,第三轮):「进行登记,让用户知道怎么维护记忆」。
6
+
7
+ ---
8
+
9
+ ## 一、睡眠周期是什么(一句话)
10
+
11
+ 灵枢的**自迭代**(八步闭环的第 5 固化 / 6 记录 / 8 方向性自检)与**睡眠整理**合成一条周期引擎:在**睡眠时段**内,用**一个副本**做归纳 / 升层 / 巩固 / 权重与索引重建,完成后**周期性合并**回主库,并**留下修改历史**。
12
+
13
+ **为什么用副本**:整理期间主库的**真源面**(八个层目录下的 `.md`)逐字节不变——长驻进程(serve / 蜂巢 / 会话)继续正常读写,整理结果只在合并那一刻以**受闸门约束**的方式落回。
14
+
15
+ ---
16
+
17
+ ## 二、版本库在哪里(唯一的"新增物")
18
+
19
+ | 项 | 位置 | 说明 |
20
+ |---|---|---|
21
+ | **版本库(git 目录)** | `<state_root>/sleep/lib.git` | **在数据根之外**。用 `git --git-dir` 显式指定,**不在你的记忆库里放 `.git`** |
22
+ | **影子工作树** | `<state_root>/sleep/shadow` | 整理实际发生的地方;每轮以 `git worktree` 建在分支 `sleep/<时间戳>` 上 |
23
+ | **台账** | `<state_root>/sleep/` 下的轮次记录 | 每轮九步的逐步读数、语义差异集 Δ、冲突清单 |
24
+
25
+ **版本库只覆盖真源面**:那八个层目录下的 `.md`。以下**结构性进不去**(用显式路径白名单而非 ignore 面保证):
26
+ `_keys.json`(密钥信封)· `_access.log` · `_index.json` · `_index_log/` · `*.tmp`(临时件)· `*.lock`(锁件)。
27
+ ⇒ **密钥与运行态从设计上就不可达**,不是"记得排除"。
28
+
29
+ ---
30
+
31
+ ## 三、维护动作(你要知道的四条)
32
+
33
+ ### 1. 看历史
34
+
35
+ ```bash
36
+ git --git-dir=<state_root>/sleep/lib.git --work-tree=<root> log --oneline
37
+ ```
38
+
39
+ 一条睡眠周期 = **两个提交**:先是**内容提交**(语义重放落主库的那一刻,台账里记作 `round_commit`),随后是 `--no-ff` 的**合并提交**(只记拓扑,其树与内容提交同)。
40
+
41
+ ### 2. 看某一轮改了什么
42
+
43
+ ```bash
44
+ git --git-dir=<state_root>/sleep/lib.git --work-tree=<root> show <round_commit>
45
+ ```
46
+
47
+ 逐节点的 before/after 另有 `_maintain.jsonl` 同族留痕(与权重重算共用一套)。
48
+
49
+ ### 3. 回退(**只提供 `revert`**)
50
+
51
+ ```bash
52
+ git --git-dir=<state_root>/sleep/lib.git --work-tree=<root> revert <round_commit>
53
+ ```
54
+
55
+ **要 revert 的是该轮的「内容提交」**(台账 `phases.merge.round_commit`)——合并提交只是拓扑记录,对它 `revert -m 1` 对内容零影响(git 会报 nothing added to commit)。
56
+
57
+ **裁定(第三轮):只给 `revert`,不提供 `reset --hard`。** 理由:`revert` 出一个**新提交**——历史不丢、可追、可再次审计;`reset --hard` 会抹掉历史,与「留下修改历史」的裁定相反。
58
+ 回退是**显式发起**的动作,睡眠周期**永不自动回退**。
59
+
60
+ ### 4. 冲突怎么处理
61
+
62
+ 合并阶段若发现**主库与影子改了同一个 id**(或命中保护闸 / tombstone 闸 / 生命周期闸),该项**挂起**:**不自动解决**、**不写入主库**,出一个冲突清单等人处理(与蜂巢工作记忆 `hive/wm.py` 的既有裁决同款:冲突手交人工)。
63
+
64
+ > 一句话:**git 只做记录者,准入由仓内既有闸门裁决**。所以「合并成功」不等于"git 没冲突",而是"过了语义四闸"。
65
+
66
+ ---
67
+
68
+ ## 四、开关与可调项(全部可调)
69
+
70
+ | env | 缺省 | 语义 |
71
+ |---|---|---|
72
+ | `MDCG_SLEEP` | `1`(开) | 睡眠周期总开关;设 `0` 即整条周期不再启动 |
73
+ | `MDCG_SLEEP_INTERVAL` | `3600` | 周期(秒),缺省一小时一次 |
74
+ | `MDCG_SLEEP_WINDOW` | `23:00-07:00` | **睡眠时段**(本地时间);**支持跨午夜**;留空 = 全时段;**窗口外只记账、不迭代** |
75
+ | `MDCG_SLEEP_MERGE` | `auto` | 合并策略:`auto`(自动执行四阶段)/ `ask`(合并前询问)/ `never`(只留副本不合并)。**`auto` 下冲突仍挂起** |
76
+ | `MDCG_SLEEP_GITDIR` | 空 | 覆盖版本库位置(缺省 `state_root()/sleep/lib.git`) |
77
+ | `MDCG_SLEEP_SHADOW` | 空 | 覆盖影子工作树位置(缺省 `state_root()/sleep/shadow`) |
78
+ | `MDCG_SLEEP_SCRUB_APPLY` | `0` | 第④步「去污染实改」的闸门;**缺省只盘点不落盘** |
79
+ | `MDCG_TEMPORAL_GAMMA` | `ln2/30天` | 时间邻近度的衰减率(半衰期 30 天,与既有 `links.py` 同刻度);可调 |
80
+ | `MDCG_CHAIN_TYPES` | 空 | **因果路沿哪些边类型扩散**(逗号分隔,大小写不敏感)。留空 = 缺省集 `causal,sequential,applies_to`。**这一项决定因果路在语料库上有没有东西可走**:从文档/叙事语料切出来的节点只有 `reference` 与父章节结构边,**没有 causal 边**,所以对这种库要显式设成 `MDCG_CHAIN_TYPES=reference,part_of`(或含 `sequential`)——否则因果路恒空。只接受 `chain.EDGE_WEIGHTS` 里已登记的类型,未登记形态会被剔除并回落缺省集 |
81
+ | `MDCG_SUSTAIN` | `1` | 常驻自维持循环总开关(睡眠周期挂在它上面) |
82
+
83
+ > **整条关掉**:`MDCG_SLEEP=0`;**连常驻循环一起关**:`MDCG_SUSTAIN=0`。
84
+
85
+ ---
86
+
87
+ ## 五、自动的边界(哪些永不自动)
88
+
89
+ | 动作 | 可自动 | 依据 |
90
+ |---|---|---|
91
+ | 归纳 / 升层 / 权重重算 / 索引重建 | ✅ | 确定性、可预演、可回滚;索引是派生物 |
92
+ | 去污染**实改** | ⚠ 缺省关(`MDCG_SLEEP_SCRUB_APPLY=0`) | 在副本上可放行,合并前可复核 |
93
+ | **任何依赖 LLM 的固化** | ❌ **永不自动** | 依赖 LLM 的动作交人工另批 |
94
+ | **任何不可回滚的删除** | ❌ **永不自动** | 五环承诺:遗忘只能由显式 `cg(op=forget)` 发起 |
95
+ | 方向性自检 | ✅ 只产**记录** | 理论纪律:自检结果**不自动触发修改** |
96
+
97
+ **「合并前可复核」在缺省配置下由什么保证**:缺省 `MDCG_SLEEP_MERGE=auto` 会在**同一轮**内把已过闸的改动一并落主库,所以严格的「合并前人工看一眼」窗口只由 `MDCG_SLEEP_MERGE=ask` 提供。另外**去污染实改缺省就是关的**(`MDCG_SLEEP_SCRUB_APPLY=0`),所以缺省配置下最具侵入性的那一档根本不会落盘——要用它,请显式开启并配 `ask` 档。
98
+
99
+ **窗口值写错了会怎样**:`MDCG_SLEEP_WINDOW` **留空**=全时段(这是唯一的显式全时段入口);**非法形态**(例如 `23:00-99:99`)按同表 `INTERVAL`/`MERGE` 的既有回落口径**回落缺省 `23:00-07:00`**——不会因为打错字而变成全天迭代。
100
+
101
+ ---
102
+
103
+ ## 六、健康读数(每轮都留)
104
+
105
+ 每轮睡眠在台账里留:①盘点候选数 ②本轮语义差异集 Δ 的大小 ③过了四闸多少、挂起多少 ④是否空轮(候选 0 ⇒ 只记账不动手)⑤九步逐步读数(未接线的步骤显式标 `skipped`)。
106
+
107
+ `cg(op=sustain, action=status)` 可看到最近几轮。
108
+
109
+ ---
110
+
111
+ ## 七、前提一句话总结
112
+
113
+ > 睡眠周期会在 `<state_root>/sleep/lib.git` 建一个**只覆盖真源面**的版本库,用它做**副本迭代 + 周期合并**,合并准入走仓内既有语义闸门(不是 git 的文本合并),回退只给 `revert`,冲突挂起等人处理。**密钥与运行态结构性进不去这个版本库。**
114
+
115
+ ---
116
+
117
+ ## 八、P2 / P4 落地后的检索与权重变化(2026-10-01 · 发版披露)
118
+
119
+ > 依据:`docs/plans/睡眠与自迭代_功能优化设计_v0.4.md` §5.1–§5.4 / §七。
120
+ > **这一节是「默认检索读数变了」的对外说明**——改动前基线与改动后读数见
121
+ > `scripts/p2p4_probe.py`(同一命令在改前 worktree 与改后工作区各跑一次)。
122
+
123
+ ### 1. 六要素后两行进默认检索(§5.4)
124
+
125
+ `# 验证方式`(后置条件词)与 `# 不适用条件`(拒绝域词)现在进**索引条目**
126
+ (`postcondition_terms` / `rejection_terms`,与 `time_window` 同款「免读文件」扁指标量),
127
+ 并进**默认检索路径**:
128
+
129
+ - 问「**怎么验证的 / 用什么方法证明**」或查询词命中验证手段 ⇒ 召回声明了该手段的节点;
130
+ - 问「**什么条件下不适用 / 何时不适用**」⇒ 召回**声明了拒绝域**的节点,结果卡带
131
+ `boundary_hit` 标记(`meta.boundary` 里有独立计数);
132
+ - **普通问句下拒绝域仍不作召回键**(反例命中只由资格判定处置)——灵敏度一字不动。
133
+
134
+ **拒绝域双语义**:边界命中(`boundary_hit`)与资格 `REJECT` 是**两件事**,
135
+ 分开计数、分开呈现;「问它什么时候不适用」不会把节点自己打成 REJECT。
136
+
137
+ **口径提醒(务必知道)**:`mdcg_recall` 的缺省**融合口径是 `max`**(因因果路缺省进路),
138
+ 这影响**所有**默认召回调用,**与库里有没有边无关**;要 `sum`(经典 RRF 求和)请显式传
139
+ `fusion="sum"`。(这是设计稿 §6.2 的既定口径,本批**补披露**,行为未变。)
140
+
141
+ ### 2. 权重刷新与衰减进主分数(§七)
142
+
143
+ 检索分数现在是:`score ← score × cred_factor(γ, Δt) × refresh(访问计数)`。
144
+
145
+ | env | 缺省 | 语义 |
146
+ |---|---|---|
147
+ | `MDCG_FRESHNESS` | `1`(开) | 刷新/衰减乘子总开关;**设 `0` 即回到改动前口径**(与既有部署逐位一致,是「可回退」的第一道闸) |
148
+ | `MDCG_FRESHNESS_NOW` | 空 | 参照时刻(unix 秒)。**只为守卫/探针的确定性**;留空 = 系统时钟 |
149
+ | `MDCG_TEMPORAL_GAMMA` | `ln2/30天` | 衰减率(与时间路同一读取点) |
150
+
151
+ 三条必须知道的语义:
152
+
153
+ 1. **老记忆会被降权**(这正是「召回被旧的历史记忆干扰」的处置):未被调用的记忆按
154
+ `ln2/30 天` 半衰期衰减,下限 `0.001`(floor,不会归零到不可召回);被经常调用的
155
+ 记忆按 AEIS `consolidate_cycle` 的既有门槛刷新(`access_count % 10 == 0` 且
156
+ `last_access > 0` 才 +1%)。
157
+ 2. **保护线不会被衰减穿过**:受保护节点(`importance ≥ 0.70`)的衰减乘子有下界
158
+ `0.70 / importance` ⇒ `importance × 乘子 ≥ 0.70` 恒成立,节点不会因衰减
159
+ **自动失去保护**。
160
+ 3. **不可遗忘 ≠ 不可覆盖;降级不是删除**:`freshness.recalc(apply=True)` 只写
161
+ `freshness_weight` 与 `freshness_state="degraded"` 标记,**从不删节点**;要跨层
162
+ 降级走既有 `_move_layer`(内含 `protect.guard_move`,受保护节点需显式 `override`)。
163
+
164
+ **粒度说明(本批的一处取舍)**:Δt 以**整日**为粒度(向下取整)。理由:γ 的单位本来
165
+ 就是「天」;仓内有「同查询两轮结果逐位一致 / 可复算」的硬纪律,不量化则分数会随
166
+ 系统时钟逐轮微变;量化后两侧(Python / Rust)在同一「天」桶上恒同值。量化损失上界 =
167
+ γ × 1 天 ≈ 2.3%。
168
+
169
+ **回滚(三件套,与权重重算同款)**:预演 `freshness.recalc(apply=False)` →
170
+ 逐节点 before/after 落 `_maintain.jsonl`(`action="freshness"`)→
171
+ 反向 `freshness.rollback(batch=...)`。AEIS 侧**没有**预演与回滚,这是移植时的净增。
172
+
173
+ ### 3. 读侧语言面的已知边界(**不要**把对拍 10/10 当成已对齐)
174
+
175
+ | 侧 | 缺省路集 | 说明 |
176
+ |---|---|---|
177
+ | Python | **6 路**:lexical / bucket / entity / graph / chain / temporal | 生产读面 |
178
+ | Rust | **4 路**:lexical / bucket / entity / graph | 评测/嵌入读面,**尚未**实现 chain/temporal 与六要素后两行索引键 |
179
+
180
+ `scripts/rank_parity.py` 现在仍报 10/10,**只因其语料无 edges / 无时间参数 /
181
+ 无六要素后两行声明**(缺省差异在这类语料上不可观测)——它是「两侧同口径下逐位一致」
182
+ 的证据,**不是**「两侧已对齐」的证据。P4 乘子的两侧逐位对拍另配了**有判别力**的夹具
183
+ (同分不同龄的节点,见 `md_cg/test_p4_freshness.py` 的 G12)。