- 每 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 清单
113 lines
7.5 KiB
Markdown
113 lines
7.5 KiB
Markdown
# 对齐 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 表(只读)。
|