Files
codex-app-server/docs/chv-muse-p7-gap.md
T
host 29fa0c8813 feat(chv): 对齐 Muse P7——状态与记忆分离
- 每 VM 一个 SQLite 状态库(cloud/chv/app_state.py):
  state_dir/<vm>/app-state.sqlite(0600,WAL),表 tasks/goals/
  sessions/audit(只追加)/meta;写操作过无凭证守卫(键名 +
  值模式);备份用 sqlite3 在线备份 + manifest(sha256),恢复
  先验 manifest、先留 pre-restore 副本;DDL 用 SQLite 与
  Postgres 共通受限子集,换 Postgres = 换连接工厂。
- 记忆文件接线(cloud/chv/memory_files.py):宿主镜像读/列/
  写/追加(路径穿越守卫、写审计);MemorySystemClient 调真实
  记忆系统 CLI(search/get/explain/forget-plan/forget-confirm/
  backup/restore/export),不重造引擎;forget = plan → confirm
  → 本地清行 → search 验证查不到;pull_memory_home 经 SSH +
  tar 拉取客机记忆家目录。
- 客内脚本 chv-guest/chv-memory.py(纯标准库,list/read/
  append/forget/export),家目录 /home/chv/memory(workspace
  之外,不同步到 Gitea);build.sh 拷入 + buildinfo 登记。
- 新测试 cloud/tests/test_chv_muse_p7.py 46 项全过(含真 CLI
  write/search/forget/backup/restore 实测、假 ssh 拉取、否定
  测试);全量 cloud 套件 1913 项 OK(skipped=8)。
- 存储选型:SQLite 不是 Postgres(见差距表 §4;轻量 VM 跑
  Postgres server 太重,宿主共享 Postgres 破坏每用户 VM
  隔离);忘记是尽力删除 + 验证,不是密码学擦除。
- 真机待验证(未做,等测试机空闲):见
  docs/chv-muse-p7-gap.md §6 清单
2026-11-06 22:39:04 +00:00

113 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 对齐 Muse P7 差距表:状态与记忆分离
依据:`~/workspace/research_notes/meta-muse-ai-architecture-20261101-0755/report.md`
(Meta 官方 security.muse.ai / 设计文 / 新闻室 2026-09-08 为准;第三方拆解只作参考,
逆向细节不得写成官方架构)。基线:`06c3e17`。
## §1 Muse 官方要求(本轨范围)
| # | 官方要求 | 来源 |
|---|---|---|
| 1 | Postgres 存持久应用状态,与运行时单元、凭证存储分离 | 安全文 §2.1 架构图 + §3.4 |
| 2 | 凭证与 OAuth token 存于用户 VM 内、不在 Meta 集中基础设施;VM 是用户放入 Muse 的一切内容的系统记录 | 安全文 §3.3 |
| 3 | 用户可检查、编辑、下载 VM 内所有文件,包括 Muse 关于用户的记忆 | 安全文 §3.3 |
| 4 | 记忆跨对话持续存在,用户可回指以往讨论过的内容;记忆文件可直接阅读与编辑 | 设计文 + 帮助中心 §2.4 |
| 5 | 用户可随时让 Muse“忘记”它学到的特定内容 | 新闻室 §2.4 |
| 6 | VM 数据持续备份以便恢复 | 安全文 §3.3 |
官方**没有**披露:Postgres 表结构、记忆文件内部结构、记忆向量索引细节
(报告 §4/§5:这些来自逆向与用户观察,不得写成官方架构)。本轨的表结构、
文件布局是本项目自定的,只对齐上面六条高层要求。
## §2 现状
- 应用状态散落在 `state_dir` 下的多个 JSON 文件(net.json、snapshots.json、
pool registry、host-state.json),无结构化存储、无统一审计、无备份恢复。
- 记忆系统是另一个已闭合的项目(`~/workspace/memory-system`,v13 终态
730/730,常驻部署在 172):Markdown 为可读源头、SQLite bank + FTS5 为派生
索引、bge-m3 语义检索(阈值 0.47)、claim 写库、忘记传播、备份恢复已做。
对外接口是真实 CLI:`node dist/cli.js <search|get|explain|forget-plan|
forget-confirm|backup|restore|export|import|...>`。
- 凭证已分离(P3 authd):真 token 只进客内守护进程,agent 只拿替身。
但**没有任何机制阻止应用状态里误写凭证**——状态 JSON 可含任意内容。
- 客机记忆文件:不存在。`~/workspace` 经 chv-sync 同步到 Gitea;记忆若放
进 workspace 会进 git 历史,不符合“VM 是系统记录、备份恢复”的口径。
## §3 改动清单(本轨)
1. `cloud/chv/app_state.py`(新):每 VM 一个 SQLite 状态库
`state_dir/<vm>/app-state.sqlite`(0600,WAL),表 tasks / goals /
sessions / audit(只追加)/ meta。写操作一律过“无凭证”守卫
(键名与值模式双重检查,拒绝时只报键名/模式、不含值);备份用
sqlite3 在线备份 API + manifest(sha256),恢复先验 manifest、
先留 pre-restore 副本。
2. `cloud/chv/memory_files.py`(新):客机记忆文件接线。
- `MemoryFiles`:宿主侧镜像 `state_dir/<vm>/memory-home/`
(MEMORY.md + memory/*.md)读/列/写/追加,路径穿越守卫,写操作审计。
- `MemorySystemClient`:subprocess 调真实记忆系统 CLI
(search / get / explain / forget-plan / forget-confirm /
backup / restore / export),不重造检索引擎、不重造忘记传播;
CLI 未配置时本地模式(只动 Markdown 镜像,bank 忘记记为待办)。
- `pull_memory_home`:经 SSH + tar 拉取客机 `/home/chv/memory`
到宿主镜像(命令构造可测,传输走已有 SSH 通道)。
- `forget`:plan → confirm → 本地 Markdown 清行 → search 验证
查不到 → 审计,全程不含凭证值。
3. `chv-guest/chv-memory.py`(新,纯标准库):客内记忆文件操作
(list / read / append / forget / export),记忆家目录
`/home/chv/memory`(0700,chv 所有),在 workspace 之外——
记忆不同步到 Gitea。`build.sh` 拷入脚本并建目录。
4. `docs/chv-production-readiness.md`:补 P7 一节。
## §4 存储选型结论:SQLite,不是 Postgres
| 维度 | Postgres(Muse 原样) | SQLite(本轨采用) |
|---|---|---|
| 部署成本 | 每 VM 一个 server 进程 + 端口 + 认证 + 数据目录;镜像 +150–250MB,常驻 RSS 约 50–100MB | 零 server,单个 0600 文件,WAL,空闲成本 0 |
| 隔离 | VM 内 Postgres 才符合“VM 是系统记录”;宿主侧共享 Postgres 会把多用户状态集中到宿主,破坏每用户 VM 隔离 | 文件随 VM 走,`state_dir/<vm>/`,与 VM 同生死 |
| 本仓既有模式 | 无 | 记忆系统本身用 SQLite 作 claim bank;cloud.db 的 AutoMemoryStore 回落 SQLite |
| 并发 | 多写者 + 行级安全 | 单写者每 VM(进程内锁 + 文件锁守卫);客机 cell 绝不直读库文件 |
**差距(诚实写明,不冒充 Postgres)**:无多写者服务器、无网络访问、
无行级安全、无内置复制(复制 = 备份/恢复路径 + Gitea 只管仓库内容)。
DDL 用 SQLite 与 Postgres 共通的受限子集(TEXT/INTEGER/REAL 列、TEXT id、
无 AUTOINCREMENT、无 SQLite 专有语法、参数化查询),仓库层只依赖连接
工厂;将来换 Postgres = 换工厂 + 同一份 DDL + 可序列化隔离说明。
## §5 诚实边界
- 记忆**引擎**不在本轨:检索、bank、FTS5、语义索引、忘记传播、审计
全是记忆系统 v13 的已有实现,本轨只调它的 CLI。CLI 不可用时
降级为本地 Markdown 模式,bank 忘记明确记为待办,不谎称已忘。
- 备份恢复演练在本机做(备份→改坏→恢复→校验条数与内容一致);
真机上的定时备份是 P8(crons)那轨的活,本轨只留接口与一次手工演练。
- “忘记”是尽力删除 + 验证查不到,不是密码学擦除:已备份的快照里
仍有旧内容(与记忆系统 CLI 的 backup 语义一致:快照在 home 之外,
忘记不 scrub 快照),差距表与用户可见文案里写清。
- 单元内直读状态库被拒是**构造性保证**:库文件在宿主 `state_dir`,
不在客机磁盘镜像里,cell 物理上够不着;测试钉住“库路径不在
客机 rootfs 内”与“客机脚本无 state 库引用”。
## §6 真机待验证清单(round-11 之后,测试机空闲后)
1. lite12 镜像含 `chv-memory.py`,`/home/chv/memory` 存在且 0700。
2. 客内 `chv-memory.py` append → 宿主 `pull_memory_home` → 宿主镜像
内容一致;再经 CLI search 能查到。
3. CLI forget-confirm 后,客机与宿主两处都查不到;审计有 forget 记录。
4. 状态库备份→删库→恢复→条数与内容一致;备份文件里无 token 值
(以测试 token 做扫描)。
5. 单元内(nspawn cell)`ls /home/chv/memory` 与直读库路径均被拒;
经 executor 的记忆读接口可通。
6. 备份恢复演练在真机跑一遍(含 pre-restore 副本存在)。
## §7 与 P1/P2/P3/P4/P5/P6 的接口
- P3 authd:状态库与记忆文件绝不存凭证值(守卫 + 否定测试);authd
的 vault 不动。
- P2 cell/broker:cell 不直读状态库;客机记忆脚本跑在 cell 外(与
chv-sync 同级),由 executor 经 SSH 调用。
- P1 常驻池:常驻 VM 的状态库与记忆家目录随 VM 持久化(文件在
state_dir/<vm>/,VM pause/resume 不丢);VM 销毁时状态库与记忆
家目录随任务盘清理策略走(删盘即删,不留孤儿——接 orphans 口径)。
- P4/P5/P6:不碰浏览器、Sentinel、privsep;P6 的安全检查层如需审计
记忆读,读本轨的 audit 表(只读)。