@furongjun1999/dsh-memory 0.7.4 → 0.8.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 (46) hide show
  1. package/README.md +632 -630
  2. package/codebuddy/CODEBUDDY.md +5 -5
  3. package/docs/discipline/templates/zcode-user.md.tmpl +4 -1
  4. package/docs/eval/issue64_replay_check_/346/240/270/351/252/214/344/270/216/344/277/256/345/244/215_v1.0.md +284 -0
  5. package/docs/eval//345/217/221/345/270/20312_/344/270/226/347/225/214/346/250/241/345/236/213/345/212/237/350/203/275/347/253/257_v1.0.md +1 -1
  6. package/docs/eval//345/217/221/345/270/20313_/344/270/212/344/270/213/346/226/207/350/207/252/347/256/241/347/220/206/346/234/272/345/210/266_v1.0.md +114 -0
  7. package/docs/eval//345/217/221/345/270/20314_/350/272/253/344/275/223/303/227/350/204/221/347/273/204/345/220/210_v1.0.md +152 -0
  8. package/docs/eval//351/262/270/345/250/230/344/270/203/347/261/273/347/212/266/346/200/201/350/277/275/350/270/252_v1.0.md +176 -0
  9. package/docs/mdcg//344/270/226/347/225/214/346/250/241/345/236/213/345/212/237/350/203/275/347/253/257_/344/275/277/347/224/250/344/270/216/350/277/220/347/273/264_v1.0.md +92 -13
  10. 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 +43 -43
  11. package/docs/mdcg//345/217/221/345/270/203/351/227/250/347/246/201/351/223/276_v0.1.md +14 -3
  12. 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 +85 -1
  13. package/docs/plans//347/201/265/346/236/242/350/272/253/344/275/223/303/227/350/204/221_/344/270/226/347/225/214/346/250/241/345/236/213/345/257/271/346/216/245/350/256/276/350/256/241_v0.1.md +119 -0
  14. 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 +461 -461
  15. package/docs//350/256/260/345/277/206/347/263/273/347/273/237/345/215/263/347/231/275/347/256/261/345/214/226/346/231/272/350/203/275_/346/236/266/346/236/204/345/257/271/347/205/247_v0.2.md +121 -0
  16. package/docs//350/256/260/345/277/206/347/263/273/347/273/237/345/215/263/347/231/275/347/256/261/345/214/226/346/231/272/350/203/275_/346/236/266/346/236/204/345/257/271/347/205/247_v0.3.md +117 -0
  17. package/lib/hooks.d.ts +34 -0
  18. package/lib/hooks.js +165 -0
  19. package/lib/index.js +22 -1
  20. package/lib/lib/mdcg_client.d.ts +37 -0
  21. package/lib/lib/mdcg_client.js +44 -0
  22. package/md_cg/audit.py +7 -1
  23. package/md_cg/bench_governance.py +4 -1
  24. package/md_cg/bench_locomo_zh.py +12 -2
  25. package/md_cg/bench_zh_mad.py +12 -2
  26. package/md_cg/chain.py +23 -7
  27. package/md_cg/consolidate.py +81 -10
  28. package/md_cg/interop.py +25 -9
  29. package/md_cg/lifecycle.py +7 -0
  30. package/md_cg/mcp_server.py +22 -0
  31. package/md_cg/mdcg.py +6 -1
  32. package/md_cg/scrub.py +4 -2
  33. package/md_cg/sleep.py +273 -103
  34. package/md_cg/sustain.py +150 -4
  35. package/md_cg/test_lifecycle_retire_leak.py +90 -0
  36. package/md_cg/test_p6_consolidate.py +389 -7
  37. package/md_cg/test_sleep_gitlock.py +134 -0
  38. package/md_cg/test_spatial_coords3d.py +292 -0
  39. package/md_cg/test_sustain_bounded.py +624 -0
  40. package/md_cg/units.py +4 -1
  41. package/package.json +2 -2
  42. package/skills/plugin.json +1 -1
  43. package/src/hooks.ts +177 -0
  44. package/src/index.ts +22 -1
  45. package/src/lib/mdcg_client.ts +48 -0
  46. package/zcode/AGENTS.md +5 -5
@@ -27,13 +27,20 @@
27
27
  > 两道互补(R3 只覆盖发布清单内的件,覆盖不到 hive/ 等非发布目录)。合成夹具(`X:/custom`、
28
28
  > `C:/Windows/win.ini` 等)与通用通例(Git/Docker 默认安装路径)不在判据面,避免平凡红;
29
29
  > 判据带 `--selftest`(正负样例 + 不命中自身源码)与注入探针红侧自证。
30
+ >
31
+ > **2026-10-06 更新(0.8.0 身体×脑对接 · 四条裁定之四:冒烟进发布链)**:门禁链再由 **11 条
32
+ > 扩至 12 条腿**——链尾新增 `scripts/body_e2e_smoke.py`(**身体侧视角 MCP 全链冒烟**:身体侧
33
+ > 进程逐行 JSON-RPC → 记账 `cg(op=state_event)` → 台账 → 投影 → 查询 `stg(op=state_chain)`;
34
+ > 隔离库(临时根断言)、零在役写入、退出码判据、内嵌合成样本与 `--events` 真实序列两态)。
35
+ > Linux 容器腿同步补登(python 套件清单新增守卫 + 本冒烟独立 record 行);同批新增守卫
36
+ > `md_cg/test_spatial_coords3d`(spatial 直存透传:15 断言 + 两处定点变异自证)入容器清单。
30
37
 
31
38
  ## 三层防线
32
39
 
33
40
  | 层 | 触发 | 跑什么 | 行为 |
34
41
  |---|---|---|---|
35
42
  | 本地 pre-commit | `git commit` | `python scripts/cogmap_sync.py build` + 认知图投影两道(建最小库 → `verify_discipline.py --cg-root`) | **自动重挂**行号并把两份投影文档一并暂存;投影判据体真跑,红了即拒提交(`--no-verify` 可绕) |
36
- | 发布链 | `npm publish` | `prepublishOnly`:build → test → **`npm run gate`**(十一道门禁,见下) | 任一步失败即阻断发布 |
43
+ | 发布链 | `npm publish` | `prepublishOnly`:build → test → **`npm run gate`**(十二道门禁,见下) | 任一步失败即阻断发布 |
37
44
  | CI | push / PR | `cogmap-check.yml`:`cogmap_sync.py check` + `link_check.py` | 远端兜底红灯 |
38
45
 
39
46
  ## 为什么本地钩子跑 build 而不是 check
@@ -56,7 +63,7 @@ git config core.hooksPath scripts/git-hooks
56
63
 
57
64
  ## 发布门禁清单(`npm run gate`)
58
65
 
59
- `prepublishOnly` 在 build + test 之后调用 `npm run gate`,十一道门禁与 CI **同形但不完全同覆盖**:
66
+ `prepublishOnly` 在 build + test 之后调用 `npm run gate`,十二道门禁与 CI **同形但不完全同覆盖**:
60
67
 
61
68
  | # | 命令 | 守什么 | 对应 CI |
62
69
  |---|---|---|---|
@@ -71,11 +78,15 @@ git config core.hooksPath scripts/git-hooks
71
78
  | 9 | `python scripts/gate_rust_crate_test.py` | `cargo test` @ `rust/`(Rust 侧口径漂移的回归保障) | **无**(`hive-check.yml` 只跑 `hive/Cargo.toml`,`rust/` 至今零 CI) |
72
79
  | 10 | `python scripts/gate_rust_parity.py` | `scripts/rank_parity.py` 逐位对拍(Python `search_rrf` vs Rust `mdcg-eval --serve`) | **无** |
73
80
  | 11 | `python scripts/check_local_paths.py` | **追踪面本机路径门禁**:`git ls-files` 全量公开面上不得有本机目录结构路径(npm 面由第 2 道 R3 另守;判据=机器实有前缀 8 族 + `--selftest` 正负样例 + 不命中自身源码) | `publish-artifact-check.yml`(同 workflow 内自检 + 扫描两步) |
81
+ | 12 | `python scripts/body_e2e_smoke.py` | **身体×脑组合冒烟**(0.8.0 对接):身体侧视角经 MCP 全链——记账 → 台账 → 投影 → 查询;隔离库、退出码判据、两态样本(内置/真实序列) | **无**(仅本地/发布链;Linux 容器腿同款一行) |
74
82
 
75
- > **第 11 道追加在链尾是有意的**:第 3 道的 C2 位序断言(smoke 腿紧随第 2 道)与
83
+ > **第 11 道追加在链尾是有意的(2026-10-06 起其后又有第 12 道,位序意图不变)**:第 3 道的 C2 位序断言(smoke 腿紧随第 2 道)与
76
84
  > `test_gate_rust_legs.py` 的链尾等价复跑通道(自 Rust 腿①起截尾)都不受影响;
77
85
  > 路径违规是本机秒级可判面,位序不承担反馈距离职责。
78
86
 
87
+ > **第 12 道追加在链尾同样是刻意的**:它是跨仓组合面冒烟(依赖 spawn 一个隔离 MCP 子进程,
88
+ > 秒级);C2 位序断言与 `test_gate_rust_legs.py` 链尾截尾逻辑均按「Rust 腿起点」定位,不受尾追加影响(实测 53/0 全过)。
89
+
79
90
  > **第 3 道的位序不是随意的**:它紧跟第 2 道(同为「发布件面」),且**必须在第 4 道
80
91
  > `cogmap_sync.py check` 之前**——前者的 `npm pack` 会触发 `prepare`(= 本仓的 `tsc` 构建,
81
92
  > 会重写 `lib/`),越靠近链首越能让「包面自检」与「包已定形」两件事挨着发生;塞在链尾则
@@ -232,7 +232,7 @@ python -X utf8 -m md_cg.sleep --status # 只读:含 last_cycle(
232
232
  对账的**并发闸**(物化时记下的 `baseline_face` 水位)逐项判「**主库优先**」、挂起不
233
233
  自动解决(同 §三.4)。`source_face_delta` 与 `baseline_face` 两个读数**原样保留**。
234
234
 
235
- ### 3. 台账 skip 文案分三类,不再混成一句
235
+ ### 3. 台账 skip 文案分类,不再混成一句(v1.2 补「物化超时」一支)
236
236
 
237
237
  ②③④ 步的 `skipped` 现在明确区分「门拦」与「物化未完成」(CLI 的
238
238
  `last_cycle.not_iterated_reason` 与 `--once` 打印的那一行**同源**,即下表文案本身):
@@ -242,6 +242,88 @@ python -X utf8 -m md_cg.sleep --status # 只读:含 last_cycle(
242
242
  | `窗口外(MDCG_SLEEP_WINDOW=…;只记账不迭代)`/`MDCG_SLEEP=0(总开关关)`/`MDCG_SLEEP_MERGE=never(只记账不迭代)`/`稳态:盘点候选数为 0(只记账不动手)` | **门拦**:按设计不动手 |
243
243
  | `物化未完成:根级锁被占(另一进程在周期内)`/`物化未完成:<error 摘要>` | **物化未完成**:想动手却没做成(取不到根级锁/影子未挂上) |
244
244
  | `本轮未迭代` | `ledger_steps` 的**缺省兜底**(`run_cycle` 的三条路径都显式给文案,不落这条) |
245
+ | `物化超时:<error 摘要>` | **物化超时**(issue #63):git 子进程超时已被 kill——**操作没完成**,与「git 的裁决失败」分开(见 §十) |
246
+
247
+ ---
248
+
249
+ ## 十、常驻循环的卡死防护与观测(v1.2 · issue #63)
250
+
251
+ > 这一节说明「循环卡住会怎样、怎么第一时间看出来、怎么处置」。三层无界
252
+ > (时间 / 输入 / 观测)在本批一并收口,读数与处置全部落在**既有面**上。
253
+
254
+ ### 1. 三层无界,三处消灭
255
+
256
+ `SustainLoop._run()` 是**单线程串行六档**(心跳 → 自愈 → 自净 → 演化 → 整理 →
257
+ 睡眠):任一档**无界阻塞**,整条循环停摆(issue #63 实测停 **9.5 小时**:六档
258
+ 全停、`loop.state=dead`、心跳年龄无限增长)。三层根因与修法:
259
+
260
+ | 层 | 根因(现场判据见 §十.4) | 修法 |
261
+ |---|---|---|
262
+ | ① 时间无界 | `sleep._git()` 调 git **无 `timeout=`**——子进程无界等待 | `timeout=_GIT_TIMEOUT_S`(**120s**,模块常量单点可调):超时即 kill |
263
+ | ② 输入无界 | 同处**未指定 `stdin`** ⇒ 子进程**继承父进程 stdin**——DSH 常驻宿主的 **JSON-RPC 活管道**(不写入也不关闭) | `stdin=subprocess.DEVNULL`:读 stdin 的子进程立即 EOF(先例形态 `md_cg/run_tests.py:105`) |
264
+ | ③ 观测无界 | tick 台账在 `run_cycle` **返回后**才写 ⇒ 卡住期间 `phases` 为空,外部读不到卡在哪档 | 六档进 / 出各刷**既有心跳戳**:`current_tick` / `last_tick_done` / `last_tick_error`,另给 `stale_tick` 告警 |
265
+
266
+ **超时语义(可区分)**:git 超时抛 `SleepGitTimeout`(`SleepError` 子类),消息含
267
+ 「git … 超时(120s)已被 kill」+ 命令名;它与 git 的 rc≠0 失败
268
+ (`git … 失败: <stderr>`)是**两条**文案面。物化档的台账文案同样分两支:
269
+ `物化超时:…` vs `物化未完成:…`(issue #60 的 mat_fail 文案族续)。
270
+
271
+ ### 2. 读数:`cg(op=sustain, action=status)` 新增进度四字段
272
+
273
+ | 字段 | 含义 | 读法 |
274
+ |---|---|---|
275
+ | `current_tick` | 此刻正在跑的档:`{name, started_at, pid}` + `running_s`(已运行秒数);空闲为 `null` | 卡住时这一条直接回答「卡在哪档、多久了」 |
276
+ | `last_tick_done` | 上一档完成读数:`{name, t, ok}`(`ok=false` = 该档抛了异常) | 与 `last_tick_error` 配套看失败态 |
277
+ | `last_tick_error` | 最近一次档内异常:`{name, t, error: 类名+摘要}`——**容忍 ≠ 静默**(六档异常一律记入此处;由**单点包装**实现,`_run` 的六档 try/except 形态逐字未改——既有守卫 `md_cg/test_sleep_p1.py` G3a 把它钉死) | 非 null 即至少有一档在报错 |
278
+ | `stale_tick` | 告警:`current_tick` 年龄 > `max(2×该档 interval, 1800s)` 时给出 `{tick, age_s, limit_s, alert}`(alert 含档名与已运行时长) | 非 null = **疑似卡死** |
279
+
280
+ 写点即**既有心跳戳**(`<net_dir>/heartbeat.<name>.stamp`)——不新增状态文件;
281
+ 每档**进入时**就刷一次(卡住场景下「没有下一次写」是常态,所以必须在进入时
282
+ 落盘),退出时清 `current_tick` 并记 `last_tick_done`。同进程读内存、跨进程
283
+ 回落戳内字段。
284
+
285
+ ### 3. 处置:`stale_tick` 报出来之后怎么办
286
+
287
+ `stale_tick` **只告警、不杀线程**(线程不可安全强杀;强杀会留下半截写)。
288
+ 处置 = **人工重启常驻进程**(宿主侧重启 serve / 重新拉起灵枢插件);重启后从
289
+ 心跳戳与 `<state_root>/sleep/_sleep.jsonl` 台账接着看。
290
+
291
+ **残留锁(有界自清,2026-10-06 落地)**:git 子进程被 kill 后可能留下 `index.lock`
292
+ ——现由 `sleep._clear_git_lock` **有界**自清(三闸口径):①只碰本模块影子仓
293
+ (单属仓,无第三方合法持锁面);②时机两处——`_git` 每次调用**前置巡检**清
294
+ **超龄锁**(mtime ≥ 300s ≫ 全调用 120s 超时上界,即崩溃残留),超时 kill 后
295
+ **force 清**当场残留(此刻仓内锁只可能来自被 kill 进程);③其余一律不动——
296
+ 超时消息如实带「已自动清理 / 未动,若后续报 lock 请人工核删」处置读数。
297
+ 清理动作记一行 `git_lock_cleared` 台账(含 age_s/force)。守卫
298
+ `python -X utf8 -m md_cg.test_sleep_gitlock`(8 断言,含「新锁不误删」反向腿)。
299
+
300
+ ### 4. issue #63 的现场判据(四条,引录)
301
+
302
+ 1. **停摆形态**:六档全停(心跳 / 自愈 / 巡检 / 演化 / 整理 / 睡眠),
303
+ `loop.state=dead`、心跳年龄无限增长——单线程串行的放大效应。
304
+ 2. **时间无界**:`sleep._git()` 无 `timeout=`——子进程无界等待。
305
+ 3. **输入无界(受控复现)**:父 stdin 为「活管道(不写入不关闭)」时,读 stdin
306
+ 的子进程 **6 秒后仍悬挂(poll=None)**;`stdin=DEVNULL` 时 **0.02s 立即 EOF
307
+ 返回**。
308
+ 4. **观测无界**:tick 台账 / `phases` 在 `run_cycle` 返回后才写 ⇒ 卡住期间外部
309
+ **无法知道卡在哪档**(`phases` 空)。
310
+
311
+ ### 5. 同批加固面(常驻可达面之外)
312
+
313
+ `md_cg/interop.py`(git add/commit)· `md_cg/audit.py`(test_cmd)·
314
+ `md_cg/units.py`(tasklist)· `md_cg/bench_locomo_zh.py` / `md_cg/bench_zh_mad.py`
315
+ (评测跑批,1800s)· `md_cg/bench_governance.py`(git rev-parse)统一补
316
+ `timeout=` + `stdin=subprocess.DEVNULL`;`md_cg/whitebox.py` 的 Popen 是
317
+ **长驻对话协议面**(stdin=PIPE 与后端持续对话),**不在加固面**(申报理由)。
318
+
319
+ ### 6. 守卫
320
+
321
+ `python -X utf8 -m md_cg.test_sustain_bounded`(T1 参数面 / T2 真超时有界 /
322
+ T3 循环续走回归 / T4 进度面 / T5 审计面)+ `--mutate` 定点变异自证
323
+ (删 `timeout=` / 删 `stdin=DEVNULL` / 删进入写点 / 删 `last_tick_error`
324
+ 四条,每条必须转红;「红项」一律取**本轮自身**计数)+ `--mutate --null`
325
+ 空转检出对照(new==old 的无害变异必须判 MISS——钉住「拿累计值当本轮红项」
326
+ 一类判据失效通道)。
245
327
 
246
328
  ---
247
329
 
@@ -249,5 +331,7 @@ python -X utf8 -m md_cg.sleep --status # 只读:含 last_cycle(
249
331
 
250
332
  | 日期 | 要点 |
251
333
  |---|---|
334
+ | 2026-10-06 | **v1.3**(退役/锁裁定批):残留锁**有界自清**落地(`_clear_git_lock` 三闸+`_git` 两时机:前置巡检清超龄、超时 kill 后 force 清;台账 `git_lock_cleared`;守卫 `md_cg.test_sleep_gitlock` 8 断言)——原「是否自动清理待裁(issue #63 台账)」收口 |
335
+ | 2026-10-06 | **v1.2**(issue #63):常驻循环三层无界收口——①`sleep._git` 加 `timeout=120s` + `stdin=subprocess.DEVNULL`(超时抛 `SleepGitTimeout`,与 rc≠0 失败文案分开、物化超时另支文案)②六档进/出刷既有心跳戳(`current_tick` / `last_tick_done` / `last_tick_error`)+ `stale_tick` 告警(只上报不杀线程,处置=人工重启)③同批加固 interop / audit / units / bench×3(whitebox Popen 不在加固面)——见 §十 |
252
336
  | 2026-10-06 | **v1.1**(issue #60/#61):①物化 `ok` 拆为「物化成功」+ `face_stable` 读数,**物化成功即迭代**(真源面漂移交并发闸、主库优先)②新增手动入口 `--once` / `--once --dry-run`(零落盘预览)与 `--status` 的 `last_cycle` 读数 ③台账 skip 文案区分「门拦」与「物化未完成」——见 §三.5 / §四 / §六 / §九 |
253
337
  | 2026-10-01 | v1.0 首版:版本库位置 / 维护动作(看历史·看改动·只 revert 的回退·冲突挂起)/ 开关与自动边界 / P2·P4 发版披露(§一–§八) |
@@ -0,0 +1,119 @@
1
+ # 灵枢「身体 × 脑」世界模型对接设计 v0.1
2
+
3
+ > 任务来源:使用者 2026-10-06「0.8.0 版本工作就是和之前的身体核心组合。让世界模型真正端到端可用。」
4
+ > 三步流程:**测试验证成功 → 脱敏 → 全部公开**(本稿完成第一步并出读数)。
5
+ > 状态:**v0.2——四条已裁并落地**(使用者 2026-10-06「0.8.0 对接设计四条 开始吧」,
6
+ > 按各条推荐执行);M1/M2 最小闭环已贯通,落地记录见 §七。
7
+
8
+ ---
9
+
10
+ ## 一、测试验证读数(第一步已达成)
11
+
12
+ | 验证 | 内容 | 读数 |
13
+ |---|---|---|
14
+ | V1 身体包冒烟 | `lingshu` 包导入(python 3.12.10) | core 零依赖 ✓ · world(numpy 2.5.3)✓ · gen ✓ |
15
+ | V1b 既有连接 | `tools/coggraph/view_memory.py` 七步在当前库重跑 | rc=0、203s、**20135 节点**/5918 显式边/78685 推导边/4 会话链;只读真源、产物仓外 |
16
+ | V3 世界模型端到端 | 身体侧进程 → MCP stdio → 脑(v0.7.4) | 握手 ✓ → **写口 25/25 入账** → **查询 11 槽位**(含 2 退役、区间/变迁史全对);隔离库 |
17
+ | **固化件** | `scripts/body_e2e_smoke.py`(本仓) | 内置样本 3/3→2 槽位 ✓ · 真实事件 25/25→11 槽位 ✓(两遍 VERDICT=PASS,可复跑) |
18
+
19
+ ## 二、对接面盘点(读码级)
20
+
21
+ ### 2.1 身体侧(`lingshu/world` 24 件)关键面
22
+
23
+ - **`scene_model.py`=「语义时空图 ↔ 3D 场景绑定层」**——天然对接件:
24
+ - store 协议:`get_nodes_by_tag(tag, limit)`(读);节点带 `tags`(`spatial`+`cat:<类>`+`ent:<名>`)、`spatial_coordinates {x,y,z}`(米)、`state_attributes {"state": …}`;`ingest_scene` 写路径。
25
+ - `load_world_from_memory(store)`=世界重建("记忆即缓存:场景=记忆节点的实时投影")——**理念与脑侧「事件是源、槽位是投影」同构**。
26
+ - `semantic_anchor_graph.py`:3D 语义锚点图(节点=类别+坐标;边=关系;"事物是其关系的总和")。
27
+ - `seven_layer_loop.py`:感知→记忆→理解→预测→验证→物理→决策("记忆"层即对接位)。
28
+ - `spacetime_consistency / anchored_verification / anchor_verify`:时空一致性、锚定分级验证(多感知通道)。
29
+
30
+ ### 2.2 脑侧(本仓)对应面
31
+
32
+ - `stg` 五 op(`timeline / anchors[2D bbox] / consistency / relation / state_chain`);
33
+ - `state_events` 台账 + `state_slots` 投影 + `cg(op=state_event)` 写口 + 两个《秤》探针;
34
+ - MCP 面(V3 smoke 已证跨进程全链)。
35
+
36
+ ### 2.3 映射表与缺口
37
+
38
+ | 身体侧约定 | 脑侧对应 | 状态 |
39
+ |---|---|---|
40
+ | tags:`spatial` / `cat:` / `ent:` | 节点 tags(写侧可带) | 写 ✓;**读侧缺 tag 过滤维(缺口①)** |
41
+ | `spatial_coordinates {x,y,z}`(米) | `frontmatter.spatial.bbox`=2D 图像坐标四元组 | **缺口②:3D↔2D 方案待裁**(见 §四.2) |
42
+ | `state_attributes.state`(每实体状态) | **槽位寄存器**(subject=实体/slot=state/value)+状态事件台账 | **✓ 同构,直接对接**(世界模型的"状态追踪"=本版新地基:记账→台账→投影) |
43
+ | `ingest_scene` 写 | `cg(op=state_event)` / `mdcg_remember`(经 MCP,已证) | ✓ |
44
+ | `load_world_from_memory` 读 | 需"按 tag 读+坐标取回"的组合 | **缺口①③:标签过滤读;场景整体重建的组合接口** |
45
+
46
+ ## 三、最小闭环(两条路线)
47
+
48
+ - **M1(读向·身体重建世界)**:给 `scene_model` 提供"**脑版 store**"(实现 `get_nodes_by_tag` /
49
+ `state_attributes` 等 → 经 MCP `cg` 读+台账投影取值)→ `load_world_from_memory` 零改动直接以脑为底。
50
+ - **M2(写向·身体观测入脑)**:`ingest_scene` 的写落到 `cg(op=state_event)`(状态变迁)+场景节点
51
+ (坐标入库)→ 由脑的投影/查询供任意端消费(**smoke 已证全链**)。
52
+
53
+ 两条路线共用同一验证工具:`python -X utf8 scripts/body_e2e_smoke.py`(隔离库、零在役写入、退出码判据)。
54
+
55
+ ## 四、四条裁决(2026-10-06 已裁,按各条推荐执行)
56
+
57
+ 1. **适配器归属侧**:身体侧件(`lingshu/world/brain_store.py`,聚合仓工具面)vs 脑侧件(本仓)。
58
+ 推荐:**身体侧适配器**——章程口径"脑为包依赖、身侧件进身仓",且 `scene_model` 零改动即插。
59
+ → **已裁/已落地**:`lingshu` 仓 `fb4b98b`(含 intake 登记与双清单审计)。
60
+ 2. **3D 坐标方案**:推荐 **`spatial.coords3d` 自定义键直存米制+可选 bbox 投影**(不改既有
61
+ `spatial.bbox` 的 2D 语义、stg 四 op 零位移);不建议扩 bbox 为 3D(破坏既有语义)。
62
+ → **已裁/已落地**:本仓 `e5d7f0c1`——`mdcg_remember` 两分支经单点 `_spatial_kw` 透传
63
+ (**缺省不落键**,既有 fm 形态逐位不变);守卫 `md_cg/test_spatial_coords3d.py`(15 断言,
64
+ 两处定点变异各自恰好命中 1 项)。
65
+ 3. **tag 过滤读(缺口①)**:脑侧给 `read/search` 加 tag 维(小活,进脑)vs 适配器侧读后过滤
66
+ (零脑改、性能略差)。推荐:**先适配器侧**(探针验证后再决定是否进脑)。
67
+ → **已裁/已落地**:适配器侧过滤(`BrainStore.get_nodes_by_tag`:`cg(op=read)` 候选 →
68
+ 按 tags 过滤);探针实测读面召回充足(三种 query 全命中场景节点且 tags 在场)。
69
+ 4. **smoke 进门禁**:是否把 `scripts/body_e2e_smoke.py` 纳入发布链附加腿(与《秤》探针同列)。
70
+ → **已裁:进**——`npm run gate` 链尾第 12 腿 + Linux 容器腿同步补登(发布门禁链文档已更新)。
71
+
72
+ ## 五、边界
73
+
74
+ - 不改 `scene_model` 既有语义(适配层在 store 接口外侧);不动在役库(smoke 全隔离);
75
+ 身体件入聚合仓走章程双清单与 `docs/intake/` 登记;脑侧改动一律走本仓批次纪律(守卫+变异+门禁)。
76
+
77
+ ## 六、三步位置
78
+
79
+ **测试验证 ✓(§一)** → 脱敏(readiness 扫描已 CLEAN;正式步骤=组合件入库时过双清单并登记)→
80
+ 全部公开(转公开时机属使用者操作;公开前终检清单可随时编制)。
81
+
82
+ ## 七、落地记录(2026-10-06 当日,四条按推荐执行)
83
+
84
+ ### 脑侧(本仓,提交 `e5d7f0c1` 已推送)
85
+
86
+ - `mdcg_remember` 两分支(gated / 非 gated add)经**单点** `_spatial_kw(a)` 透传 `spatial`:
87
+ 声明则 `frontmatter.spatial` 直存;**缺省不落键**(既有写入 fm 形态逐位不变——首版实现曾
88
+ 引入 `spatial: null` 落键,守卫 B2 当场钉出后改为条件传参);复现 meta 同键(入队后
89
+ accept 与直接落盘元数据等价);TOOLS schema 同步声明。
90
+ - 守卫 `md_cg/test_spatial_coords3d.py`:**18 断言全绿**(A–E 组,含 gated 闸门路径行为断言)
91
+ + `--mutate` 两处定点变异(M1 行为变异剥 `add` 的 spatial ⇒ 直写面与 gated 面**恰好各 1 红=2**;
92
+ M2 源码变异删一处 `_spatial_kw` 调用 ⇒ 恰好 1 红)。独立复核(子代理)全项 PASS、
93
+ 零推翻,6 条观察中两条已当场收口(本断言补强 + 沙箱扩键)。
94
+ - **smoke 进门禁**:`npm run gate` 链尾第 12 腿(`scripts/body_e2e_smoke.py`)+
95
+ Linux 容器腿同步补登;`npm run gate` **12 腿全绿**(含新腿 VERDICT=PASS 读数);
96
+ 发布门禁链文档(第 12 道)与容器套件清单(+`test_spatial_coords3d` 及其 `--mutate` 自证)同步。
97
+
98
+ ### 身侧(`lingshu` 仓,提交 `fb4b98b`/订正 `2d05e6d` 已推送)
99
+
100
+ - `lingshu/world/brain_store.py`:最小 MCP stdio 客户端 + `BrainStore`(`get_nodes_by_tag`
101
+ 适配器侧 tag 过滤 + 状态取槽位投影)+ `BrainEngine`(`add_perception` → `mdcg_remember`,
102
+ `spatial.coords3d` 直存)+ **`_ConnShim`**(legacy `ingest_scene` 的
103
+ `UPDATE nodes SET state_attributes` 直写语句 → `cg(op=state_event)` 记账翻译)+
104
+ `connect()`(连接参数零本机字面量;缺省剔除继承 `MDCG_*`、fail-closed)。
105
+ - **零改动对接实证**:`scene_model.ingest_scene` 与 `load_world_from_memory` 一行未改;
106
+ `tests/test_brain_store.py` 隔离库端到端 **10/10**(S1 握手 / S2 写入 3 实体 /
107
+ S3–S7 实体·类别·坐标·状态逐项 / S8 状态更新重载现算 / S9 tag 过滤对照)。
108
+ - intake 登记:`docs/intake/brain-store-v0.1/`(README + AUDIT:机械扫描 2 文件 0 命中
109
+ CLEAN)+ 章程引入登记表行。
110
+
111
+ ### 组合读数(发布面)
112
+
113
+ - 组合冒烟两态(内置 3 条→2 槽位;真实 25 条→11 槽位)保持 **VERDICT=PASS**(两遍复跑);
114
+ - 读面召回探针:`cg(op=read)` 对 `query=场景实体 / world_model / spatial` 三式**全命中**
115
+ 场景节点且 tags 在场——适配器侧过滤无缺口①阻塞。
116
+
117
+ ---
118
+
119
+ *v0.1 · 2026-10-06 · 编排侧编制(读码:身体侧 scene_model/semantic_anchor_graph/seven_layer_loop 等;脑侧 stg/state_slots)*