MUSE / ARCHITECTURE NOTES
Muse 智能体 · 状态层详解
本篇目录
- 0. 一句话状态层
- 1. DB 平面总览:196 表 / 18 schema 的验证(11-04;10-17 为 194/17)
- 2. 逐 schema 导览(18 个,11-04 快照;10-17 为 17 个)
- 3. DB 与文件:分工判定规则
- 4. `muse.db` 只读通道:Agent 侧唯一 DB 入口
- 5. 文件平面:目录地图实况
- 6. 双轨实体的分工解剖
- 7. 投影 ≠ 本体:全系统反复出现的模式
- 8. 恢复与检查点:VM 可替换的底气
- 9. 边界:状态层在本机看不见的部分
- 附录 A. 逐 schema 表数表(实测:解析 schema.md 求和验证;明细为 10-17 快照)
- 附录 B. 本机状态快照(实测,2026-10-17 深夜)
配套《00-Muse技术架构解构》的 §8 展开篇。调查日期:2026-10-17(Asia/Shanghai)。 证据范围:
/opt/muse/skills/muse_db/技能包全套参考(SKILL.md+references/schema.md+references/querying.md+references/identifiers.md+references/tables/逐表指南)、muse.db工具当场实测查询、本机 home 与~/workspace/目录实况清点、~/docs/与 system prompt 的状态相关明文。 标注规则同主报告:实测 = 本机命令/工具当场验证;文档 = 本地 docs/system 文件明文;推断 = 由表结构/文件形态拼出、未经服务端证实。 复核修订:2026-11-04(Asia/Shanghai)——基于当前会话运行时逐项重测;DB 表数/schema 数与文件侧数字凡未注日期者均为 11-04 快照,10-17 旧数见各处双日期标注;muse.db 行数快照(§4.3/附录 B)与附录 A 各 schema 明细为 10-17 口径(文内已注明,未重测)。
0. 一句话状态层
Muse 的状态不在 Agent 进程里,而在三个平面上:Postgres 状态库(结构化本体:196 张表 / 18 个 schema(11-04 快照;10-17 为 194 表 / 17 schema,新增
saved),事件账本 + 检查点 + outbox)、文件系统(语义层:Markdown 记忆、目标工作区、会话转录 JSONL、人可读的投影)、运行时易失状态(套接字、锁、就绪标记、变更信号文件)。DB 与文件之间靠水位线/指纹/epoch 做带新鲜度建模、可失效、可重算的投影同步("最终一致"的收敛保证未验证,见 §7);靠恢复所有权 + 代次 + 检查点实现 VM 被整体替换后的接管恢复(恢复语义是检查点+投影重建,不是事件重放,见 §1.1/§8)——这正是 00 §8 那句「运行时即数据库」的完整展开。
┌─ DB 平面(本体) Postgres 196 表 / 18 schema(11-04;10-17 为 194/17)
│ runtime.events 事件账本 · agent.context_items 有序上下文
│ 检查点/恢复所有权 · 各域 outbox · 水位线与投影表
├─ 文件平面(语义层 + 投影)
│ ~/MEMORY.md + ~/memory/(记忆叙事) · ~/agents/<id>/sessions/*.jsonl(转录)
│ ~/workspace/goals/(目标工作区) · ~/workspace/cron.d/(调度投影,只读)
│ ~/workspace/space_data/spaces.catalog.*(产物目录信号)
├─ 同步/信号平面
│ ~/.postgres-ready · ~/runtime.lock · ~/.hatch-db-change-signals/
│ DB 行的 source_watermark / fingerprint / stale_after / writer_epoch
└─ 读通道(Agent 侧唯一入口)
muse.db 受限只读 SELECT(安全屏障视图) + 专用产品工具(写路径)
1. DB 平面总览:196 表 / 18 schema 的验证(11-04;10-17 为 194/17)
实测验证方法(不靠 00 的转述,当场重数;11-04 复核用同方法重测):
- 解析
references/schema.md的全部条目链接:去重后恰 196 个schema.table,按### <schema>分节计数求和 = 196,分节数 = 18(新增saved:saved.items/saved.item_links2 表;10-17 为 194/17,逐项明细见附录 A); references/tables/目录下逐表指南文件数同为 196 个,一表一文件(11-04 复测;10-17 为 194);- schema.md 页首标注其生成来源:迁移集
5af4f2bfdee2b934a53bbcc22602c602ab85059e0ac97ea20137fd299c06036b(文档)——即这份目录是某次迁移快照的产物,线上实际表数可能随部署漂移,引用时应以「该迁移集口径」理解; muse.db活查询抽验多表count(*)均可达且返回合理量级(见 §4.3),证明目录与活库对应、非纸面清单。
1.1 从表结构读出的设计风格(实测列定义,风格归纳为推断)
| 风格 | 证据(表/列) | 含义(推断) |
|---|---|---|
| 事件账本打头 | runtime.events(有序事件账本,带请求归因);agent.runtime_state.last_event_seq 外键指回它;runtime.tool_calls/tool_outputs 各有 event_seq 唯一键 |
一切先落成有序事件,再投影成各域当前态;event_seq 是审计追溯与恢复定位的坐标("读到哪了"),不是 event sourcing 式的重放起点——恢复走检查点+投影(见 §8),因为事件载荷是不透明 text 且大量状态(文件、外部世界)本就不在事件里,从事件流重放出完整状态在结构上不可能。 |
| 软引用多于硬外键 | 大量列标注 “Soft local reference”;memory.claims.supersedes_claim_id / run_id 明示 “Opaque correlation identifier; no declared local table relationship”;identifiers.md 须按域上下文消歧同名 ID |
跨域解耦:各 schema 可独立演进/清理,完整性靠应用层而非 DB 约束 |
| JSON 装进 text 列 | payload_json / state_json / item_json / execution_config_json 普遍为 text 而非 jsonb(少数如 memory.claims.evidence_handles、feed.run_steps.output_json 用 jsonb) |
载荷当不透明字节存取,结构演进不触发迁移;查询面只暴露扁平化投影(runtime.event_payload_fields、agent.context_item_fields) |
| 时间戳双制 | agent.* 多用 timestamp with time zone + now();scheduler.* 多用 bigint epoch(*_utc / *_at_ms) |
两个子系统世代不同:调度器按 epoch 毫秒做跨时区算术,Agent 域用 timestamptz 做审计呈现(推断) |
| 单例表 | runtime.writer_epoch(singleton bool PK)、scheduler.scheduled_resume_state(singleton bool PK) |
全局唯一状态行当「寄存器」用:写者 epoch、下一次唤醒投影 |
| outbox 反复出现 | scheduler.delivery_outbox、feed.fleet_engagement_outbox / fleet_reaction_outbox、agent.message_mailbox、agent.context_item_derived_write_backlog、runtime.chat_event_derived_write_backlog |
「先落表、再投递、可重试」是全系统的投递语义基线(见 §7、§8) |
2. 逐 schema 导览(18 个,11-04 快照;10-17 为 17 个)
完整计数见附录 A;下表只讲「这个 schema 在状态层里扮演什么角色」,代表表均取自 schema.md 的一句话定义(文档)。11-04 仅复核总数(196)与 schema 数(18,新增
saved),各 schema 明细表数为 10-17 快照(未重测)。
| schema(表数) | 角色 | 代表表 → 存什么 |
|---|---|---|
| runtime(38) | 运行时总账:事件、消息、工具、工单、检查点 | events 有序运行时事件账本(请求归因);messages 消息角色/文本/事件引用;tool_calls+tool_outputs 工具调用与结果全记录;work_items 持久化工单(父/请求/会话关系);browser_tasks 浏览器任务所有权与执行态;context_snapshots 带来源水位线的版本化上下文快照;writer_epoch 可靠卷当前写者 epoch |
| agent(25) | Agent 本体:身份、会话、上下文、恢复 | agents 身份/种类/会话/父关系;agent_ancestors 祖先链与距离;context_items 有序可读会话条目(消息/工具引用);compactions+agent_compactions 压缩检查点与摘要;runtime_restart_checkpoints 重启恢复检查点;recovery_owners 可恢复工作的持久所有权与代次;message_mailbox 已受理提交的排序与路由态;subagent_spawns/progress 子 Agent 派生与进度;token_usage 用量归因 |
| ideas(22) | Ideas 卡片与策略学习管线 | ideas 卡片本体(描述/理由/类别);idea_quality 相关性/新颖度/可行性评分;idea_dedup 指纹与去重映射;bandit_arm_state / bandit_fold_state / bandit_folded_events 策略学习统计、折叠水位线、已折叠事件;feed_snapshots(+cards/sections) 快照三件套 |
| feed(16) | Feed 生成、发布与 fleet 同步 | units 生成内容与版次/来源 prompt;runs+run_steps 生成运行与步骤尝试;prompts 保存的 brief 与启用态;fleet_publish_state 已发布贡献的水位线;fleet_engagement_outbox / fleet_reaction_outbox 待发布互动/反应(带重试态);preferences_projection 由互动折叠出的当前偏好投影 |
| self_improvement(13) | 后台进化流水线的账本(02 篇 Part II 的状态面) | runs 改进运行(objective/阶段);objective_state+objective_markers 目标当前态、源修订与进度标记;leases 改进工作的租约与所有权;handoff_dedupe 已发 handoff 的防重记录;connector_read_audit 连接器读取的目的与请求归因(审计);calculation_records / calibration_records 计算与校准的证据句柄 |
| device(13) | 配对设备的同步副本 | nodes 配对设备、广播命令与已启用权限;contacts(+contact_emails/phones/addresses 三张标签子表) 同步联系人;calendar_events 同步日历;call_log 通话记录;data_sync_state 每设备的同步游标与全量同步范围;upload_sessions / upload_chunks / media_upload_batches / media_upload_events 上传会话、分片摘要与处理车道 |
| scheduler(12) | 定时任务的定义、运行与投递 | jobs 保存的计划/启用态/来源;job_definitions 版本化定义与 prompt 引用;job_runs 每次运行(定义版本/起止);cron_mutations 变更审计(请求归因);delivery_outbox 待投递结果(见 §7);scheduled_resume_registrations/state 唤醒注册与下一次唤醒投影;doctor_* 维护任务的计划与证据 |
| goals(12) | 目标域本体(与 ~/workspace/goals/ 文件工作区双轨,见 §6) |
goals 目标描述与生命周期态;updates 带日期的进展更新;actions+thread_actions 行动项及其与对话线程的链接;briefings 简报位置与打开时间;momentum_history 进展评估与调整建议;learning_state 学习类目标的先修/掌握证据/误解;suggestions 目标↔想法链接 |
| activity(8) | 活动监控面(App 里「正在做什么」的呈现层) | activity_monitor_threads 线程身份/呈现/当前态;…_thread_sections / …_thread_actions 分节与动作(含 Agent 归因);…_agent_threads / …_message_threads / …_runtime_work_threads / …_carrier_user_messages 四张链接表把 Agent、消息、持久化工单挂到同一线程;feed_entries 工作/消息/目标的活动条目 |
| health(8) | 健康数据的同步与聚合 | samples+sample_values 原始测量与命名值/单位;aggregates 按时段+时区聚合;sleep_sessions、workouts 专题表;events+record_values 事件与记录值;synced_ranges 每来源/类别已同步的时间范围(游标,见 §8) |
| memory(6) | 记忆的机器层(与 Markdown 记忆双轨,见 §6.1) | claims 记忆主张:引文、出处(source_path/source_line)、重要度、置信度、supersedes_claim_id 替代链、首见/强化/有效期;entries 索引条目:memory_uri、分块、来源位置(citation_path/line_start/line_end)、隐私分类;embeddings+embedding_models 检索向量与模型/维度/距离度量;entry_attributes 条目命名属性;metadata 子系统元数据 |
| media(4) | 媒体库索引 | items 媒体清单(来源身份/类型/文件位置);descriptions 生成描述及模型/版本;exif_values 抽取的 EXIF;locations 坐标与地理编码状态 |
| chat(3) | 聊天规范层(side chat 的本体在此,不在文件,见 §5.3) | chats 规范聊天元数据(chat_id = 根会话 UUID);message_bindings 供应商消息 ↔ 原生会话 ↔ Muse 消息的绑定;event_transports 聊天事件的供应商归因 |
| podcasts(3) | 播客产物登记 | episodes 剧集(描述/音频路径/时长);feeds feed 身份与发布 URL;feed 旧版单 feed 配置(遗留表与新表并存,演进痕迹) |
| spaces(9) | Artifact(空间)的登记与调用 | spaces 产物清单(名称/源码位置/会话关联);proposals 提案与确认态;shares 分享设置与发布态;action_invocations / action_arguments / action_results 产物 action 的请求—参数—结果三段;file_artifact_identities 文件产物的稳定身份;user_state 收藏/访问史/排序 |
| ingest(1) | 外部数据源入口 | data_source_events 数据源事件(有序、带来源)——单表 schema,最薄的入口层 |
| shell(1) | 客户端外壳偏好 | user_state 外壳条目的收藏/访问史/排序——与 spaces.user_state 同构(推断:各表面一份 user_state 是通用小模式) |
| saved(2,11-04 新增) | — | saved.items / saved.item_links——10-17 快照无此 schema,用途未细查(❓) |
分布形态(实测计数,10-17 明细;占比按 11-04 总数 196 重算):头部三家 runtime+agent+ideas = 85 表(43.4%)——状态层的重心是「运行时自身」而非用户内容;用户内容域(goals/feed/device/health/media/chat/podcasts)合计 57 表(29.1%);横切域(scheduler/self_improvement/activity/memory/spaces/ingest/shell)52 表(26.5%);11-04 新增 saved(2 表,1.0%)。
3. DB 与文件:分工判定规则
从双轨实例反推的判定规则(推断,实例均为实测):
| 进 DB 的 | 进文件的 |
|---|---|
| 需要有序/事务/跨实体关联的(事件 seq、所有权、代次、outbox 重试态) | 人要读、要改、要引用的叙事(MEMORY.md、GOAL.md、技能/连接器文档) |
| 高频小粒度写入(context_items 逐条、tool_outputs 逐次) | 低频整篇修订(每日 memory 日志、对齐合成) |
| 机器消费的索引/向量/评分(memory.entries/embeddings、ideas.idea_quality) | 交付物本体(报告、表格、artifact 源码、媒体文件;DB 只登记路径/身份) |
| 权限与生命周期状态(device.nodes 的启用权限、goals 的生命周期态、spaces.shares 的发布态) | 工作区草稿与中间产物(goals/*/agent_notes、feed/research/) |
一句话:DB 存「系统必须算对的」,文件存「人必须看懂的」;同一实体常两边都有,DB 侧是登记/状态/索引,文件侧是内容/叙事/工作区。
4. muse.db 只读通道:Agent 侧唯一 DB 入口
4.1 约束清单(文档:SKILL.md + querying.md + 工具定义)
- 单条、受限、只读:一次提交一条 bounded
SELECT;底层是最小权限 DB 角色,仅对目录内允许关系有SELECT,不能改数据; - 词表封闭:只能用 querying.md 列出的内置函数(约 120 个)与转型拼写;非递归 CTE 名必须以
hatch_cte_开头,递归 CTE 直接拒;集合聚合(json_agg/jsonb_agg/array_agg/string_agg)被禁(防在输出限额前先构造无界值);联表时投影列必须别名唯一(重复输出名拒); - 域外即不可见:Postgres 系统目录、迁移簿记、备份表、凭据、Sentinel 审批库、每个 artifact 的
app.db都在此面之外;凭据(令牌/密码/密钥/支付秘密)永远在凭据服务之后,此面只可见非秘密的生命周期记录(如 spend-request 状态); - 受保护内容走安全屏障视图:私有模型推理(thinking/redacted-thinking)永不可读;逐轮保存的 developer 指令同样 withheld;受影响的表经 security-barrier view 读取,withheld 列会以「未知列」报错、被过滤的行无声缺席——查不到 ≠ 不存在,须先读逐表指南的 read restrictions 再下结论;
- 定位纪律:普通产品读写优先用专用工具(chat/goal/artifact/feed/scheduler/connector…),它们持有产品语义且可能含 DB 之外的活状态;
muse.db只用于诊断缺失/孤儿记录、重建执行史、查跨域不一致(SKILL.md 明文)。
4.2 限额(本会话工具返回实测)
工具每次返回自带 limits,本会话两次查询一致:
| 限额 | 值 |
|---|---|
max_rows |
200 行 |
max_output_bytes |
262,144 字节(256KiB,即 00 §8 所说「262KB 输出上限」的精确值) |
max_row_bytes |
65,536 字节/行 |
query_timeout_ms |
5,000(即 00 所说 5s 的精确口径:工具层总超时) |
statement_timeout_ms |
3,000(语句层超时,比总超时更紧) |
4.3 活库抽验快照(实测,2026-10-17 深夜本会话)
count(*) 一批(同一工具、同一分钟内):
| 表 | 行数 | 对照 |
|---|---|---|
agent.agents |
163 | 与 ~/agents/ 目录数 163 精确吻合(§5.2) |
agent.context_items |
2,413 | 上下文条目总账(含全部 Agent) |
runtime.messages / runtime.events |
588 / 593 | 消息数与事件数同量级,事件略多(推断:含非消息事件) |
runtime.tool_calls |
0 | 计数面与明细面口径差或该表走屏障视图过滤(见下注) |
scheduler.jobs / scheduler.job_runs |
28 / 532 | 定义 28、运行史 532(约 19 次/定义) |
goals.goals |
3 | 与 ~/workspace/goals/ 三个目标目录吻合 |
chat.chats |
5 | 本机聊天总数(主 + side chats) |
memory.claims / memory.entries |
4 / 98 | 主张层薄、索引层厚(见 §6.1) |
ideas.ideas / feed.units / spaces.spaces |
94 / 63 / 2 | 内容域量级 |
self_improvement.runs |
190 | 进化流水线累计运行(02 篇的账本实证) |
device.nodes |
1 | 已配对设备 1 台 |
agent.runtime_restart_checkpoints |
1(count) | 但明细 SELECT 返回 0 行——见下注 |
agent.recovery_owners / agent.compactions / runtime.workflow_runs / agent.sessions / media.items |
0 | 当前无恢复所有权登记、无压缩记录、无 workflow 运行、会话表为空(会话实体在文件侧,§5.2) |
注(实测现象,解释为推断):
runtime_restart_checkpoints的count(*)得 1、明细查询得 0 行;runtime.tool_calls计数为 0 而本会话显然发生过大量工具调用。二者都符合 querying.md 的警告——受屏障视图/行过滤影响的表面上,不可见 ≠ 不存在,计数与明细的口径也可能不同。这是本报告对「只读通道」最重要的一条使用纪律,压过任何单次查询结果。
4.4 写路径不变量:Agent 是状态层的纯读者
本篇所有证据拼出一条架构定理:Agent 侧对 DB 只有 muse.db 这一条只读通道(§4.1–§4.3);一切写 DB 的动作都由 daemon/服务端进程执行,Agent 的"写"(建 cron、记目标、存记忆、发消息)本质是调专用产品工具,由工具经可信侧落库。
这是 06 篇 privsep 隔离在状态面的镜像:执行面是"Agent 不碰凭据",状态面是"Agent 不碰 DB 写"。两层合起来,Agent 进程的破坏半径被收敛到"调工具"+"写自己的 workspace 文件"。该不变量的反例搜索(Agent 直连 Postgres 的 socket/DSN)本轮未做,列为待验证 ❓。
5. 文件平面:目录地图实况
5.1 home 根:注入文件与运行时标记(实测)
| 路径 | 实测 | 性质 |
|---|---|---|
~/MEMORY.md |
22,389 B(11-04;10-17 为 5,284 B) | 长期记忆精选层,每轮注入(00 §9) |
~/AGENTS.md / SOUL.md / IDENTITY.md / USER.md / TOOLS.md |
886 / 795 / 254 / 335 / 337 B | 注入文件组(操作手册/人格/身份/用户档案/工具笔记) |
~/HEARTBEAT.md / PROACTIVE_PREFERENCES.md |
113 / 496 B | 心跳清单与主动消息偏好(00 §11) |
~/runtime.lock |
0 B | 运行时单实例锁(存在即标记,内容为空) |
~/.postgres-ready |
6 B,内容 ready |
DB 就绪门(推断:启动序里 DB 就绪后才拉起依赖它的组件) |
~/.hatch-db-change-signals/ |
8 个 spaces.catalog.* 信号文件(11-04;10-17 为 4 个,各 61–62 B) |
DB 变更→文件侧的失效信号(与 ~/workspace/space_data/ 下同名 catalog 文件成对出现;推断:文件观察者靠它刷新产物目录缓存) |
5.2 记忆与会话:两个「agents」目录必须分清(实测)
记忆树 ~/memory/(共 37 个文件、1.8M;10-17 为 18 个文件、144K):
- 根:按日日志 28 篇(
2026-09-26.md…2026-11-04.md,合计 812,581 字节;10-17 为 10 篇 / 41,653 B)——当日活动量直接写在文件大小上; bank/4 篇:world.md32,729 B、reflections.md28,290 B、experience.md970 B、opinions.md68 B——运行时托管的长期沉淀(00 §9 的「bank」层),体量远大于每日日志,是真正的厚资产;people/3 人页 +INDEX.md(11-04;10-17 为 2 人页,页数随用户变化);groups/仍仅INDEX.md(尚无群组页,11-04 复核);~/memory/index/本机不存在:00 §9 转述的通用结构里有 index 层,本机实况只有 bank 一个托管子目录——索引功能实测由 DB 的memory.entries/embeddings承担(§6.1),文件侧 index 目录或是其他形态/已演进(推断)。
会话转录 ~/agents/(home 根,非 workspace):1,417 个 agent-<uuid>/ 目录(11-04;10-17 为 163 个)。每目录固定 sessions/<uuid>.jsonl + sessions/sessions.json 各一份(10-17 为 163+163 实测)——每个 Agent 一份 append-only 转录。这是 DB agent.agents 163 行的文件侧孪生(10-17 实测数量吻合;11-04 文件侧为 1,417 目录,DB 行数未复测,该吻合论断以 10-17 为准):DB 管身份/关系/状态,JSONL 管逐字转录(推断分工)。
工具输出溢出 ~/workspace/agents/:278 个 <uuid>/ 目录(11-04;10-17 为 90 个,00 晚间口径 89),每目录仅 tool-output/ 一项,且绝大多数为空:10-17 实测全树仅 2 个实际输出文件(11-04 未复测)。说明该目录是按需落盘的溢出区(工具输出超限/需留存时才写文件并回传句柄),不是全量日志——全量在 DB runtime.tool_outputs 与转录 JSONL 里。
5.3 workspace 侧主要状态目录(实测)
| 路径 | 实况 | 本体在哪 |
|---|---|---|
~/workspace/goals/(6.6M,10-17) |
12 个目标目录(11-04;10-17 为 3 个),每目标同构 7 件(10-17 实测):GOAL.md / files/ / hidden_files/ / briefs/ / crons/ / agent_notes/ / references/ |
内容与工作区在文件;生命周期/行动/动量在 DB goals.*(§6) |
~/workspace/cron.d/ |
10 个子目录(minutely/hourly/daily/weekly/monthly/yearly/runonce/secondly + _archive/_invalid),现行投影 2 个(minutely/heartbeat__interval@30m.md + runonce/ 1 个),_archive/ 4 篇(11-04;10-17 为现行 1 个 + 归档 1 篇) |
投影:本体在 DB scheduler.jobs(28 条,10-17 快照)+ job_definitions;文件名即计划编码(名__周期@时刻.md);prompt 明文禁止直改投影,须走 cron 工具改本体。28 条定义只投影出个位数文件——推断:投影只含用户面可见的 job,系统/目标内嵌 job 不落此目录 |
~/workspace/system/system_prompt.md |
73,296 B 单文件(11-04;10-17 为 71,868 B) | 主聊天启动时落盘的 prompt 快照,本身就是「DB/运行时→文件」的一次投影(00 §3) |
~/side-chats/ |
本机不存在 | side chat 本体在 DB(chat.chats 5 行 + runtime.messages);文档里的 ~/side-chats/<id>/MEMORY.md 路径模式在本机未物化为目录——该形态或是按需生成/其他表面专用(推断)。这是「DB 原生、文件缺席」的实例,与 cron 的「DB 本体+文件投影」恰成对照 |
~/dreams/ |
根 17 篇日期反思(11-04;10-17 为 4 篇)+ alignment/derived/ 4 文件 + alignment/repair/ 2 文件(后两项 10-17 实测) |
Dreaming 流水线产物(02 篇 Part II);其中 derived 的对齐合成每轮注入上下文 |
~/workspace/self_improvement/ |
objectives/(8 个 objective,11-04;10-17 为 7 个,各带 CURRENT.md + archive/ 历史版)+ staging/(各次运行的暂存区)+ migrations/relationships/ |
进化层的文件账本:DB self_improvement.* 管运行/租约/去重,文件管每 objective 的当前态全文与归档链 |
~/workspace/feed/ |
research/(按 feed-id 分目录的调研素材)、media/(1p/3p/staging/ + index.json)、runs/(空) |
素材在文件;单元/运行/发布水位线在 DB feed.* |
~/workspace/space_data/ |
spaces.catalog.<ts>.<n> 信号文件多份 |
与 §5.1 的变更信号呼应;~/workspace/spaces/ 本身为空目录,~/workspace/ts-spaces/ 下 2 个空间(ai / space)与 DB spaces.spaces 2 行吻合 |
~/workspace/proactivity/hidden_files/<id>/ |
2 个快照目录,各含 context.md / conversation.md / scheduled-crons.md / tracking.md |
主动消息 worker 每轮的输入快照包(00 §11)——「快照即输入」的留痕 |
~/workspace/memory/ |
reconciliation_state.json(364 B)+ reconciliation_attempts/ |
记忆对账(reconciliation)子流程的状态文件——DB 索引与文件记忆对账的落点(推断) |
~/hooks/ |
definitions/ scripts/ state/ logs/ runtime/ 五件套,runtime 仅 1 个脚本 |
hooks 子系统(00 §11)的文件面;定义/状态与 DB 无对应 schema(ingest/events 之外无 hooks 表)——推断:hooks 以文件为本体,是少数「文件原生」子系统 |
6. 双轨实体的分工解剖
6.1 记忆:四层双轨(本报告重点案例)
同一个「记忆」,四处各存一份、职责不重叠:
| 层 | 载体 | 实测规模 | 职责 |
|---|---|---|---|
| 精选注入层 | 文件 ~/MEMORY.md + people/groups 索引 + 对齐合成 |
5,284 B 等 | 每轮直接进上下文,贵在小而准 |
| 叙事沉淀层 | 文件 ~/memory/ 每日日志 + bank/ 四篇 |
37 文件 / 1.8M(11-04;10-17 为 18 文件 / 144K) | 人可读的完整轨迹;bank 是跨日蒸馏物 |
| 主张层 | DB memory.claims |
4 行 | 机器可判的主张:引文、说话人、置信度、重要度、supersedes 替代链、有效期——muse.memory_explain 追溯的正是这层(列定义为文档,行数为实测) |
| 索引实现面 | DB memory.entries + embeddings |
98 条索引 | 检索入口(访问面是三工具经 JARVIS_MEMORY_SOCK,见 08 §3.3 的统一口径);每条带 memory_uri 与指回文件的引用坐标(citation_path / line_start / line_end;claims 同理带 source_path / source_line) |
关键设计(由列定义推断,坐标字段为实测列):DB 索引不复制记忆正文,而是持有「文件路径+行号」的引用——文件是正文本体,DB 是可检索的目录卡。muse.memory_search 命中后给出文件行号引用、muse.memory_get 按行回读文件,两步正好走完「DB 索引 → 文件本体」的路径。记忆被更正时,claims 层用 supersedes_claim_id 留替代链、文件层改正文、entries 层重建索引——三处一致性靠 memory upkeep 流水线与 ~/workspace/memory/reconciliation_* 对账文件维持(推断)。
6.2 其余双轨(同一模式的复用)
- 目标:DB
goals.goals(3 行,10-17 快照,11-04 未复测)↔ 文件goals/<slug>/(12 个目录,11-04;10-17 为 3 个)(GOAL.md 正文 + files 交付物 + hidden_files 簿记)。注入上下文的目标列表来自 DB 侧状态,正文细节读文件。 - 调度:DB
scheduler.jobs/job_definitions(28 条,版本化定义+变更审计)↔ 文件cron.d/只读投影(个位数)。改走工具→写 DB→重投影。 - Agent:DB
agent.agents(163 行,10-17 快照,11-04 未复测)↔ 文件~/agents/(1,417 目录,11-04;10-17 为 163,转录 JSONL)。数目精确相等是本机最干净的双轨吻合证据(实测,10-17)。 - Feed:DB
feed.units/runs(63 单元)↔ 文件feed/research|media/(素材)。生成管线读文件素材、写 DB 单元、再由客户端读 DB 呈现。 - 会话:
agent.sessions表实测 0 行,而文件侧 sessions.json/jsonl 齐全。三种兼容解释(❓,未区分):(a) 该实体当前以文件为本体,DB 表空置/预留;(b) 该表被屏障视图/行过滤隐藏,如tool_calls的 0 行之谜(§4.3 注);(c) 旧 schema 残留,如podcasts.feed的"遗留表与新表并存"。按 §4.1 纪律,"查不到 ≠ 不存在",此处不下结论。说明双轨的权重配比会随子系统演进而漂移,不是每个实体都五五开。
7. 投影 ≠ 本体:全系统反复出现的模式
00 §8 点名的这条模式,在 schema 与文件两侧能数出至少七个实例(表名/文件名均为实测):
- cron.d 投影:改投影无效,须走 cron 工具改 DB 本体(system prompt 明文);
agent.context_item_resume_projection:专为「恢复时重建可读上下文」生成的投影表——名字里直接带 projection,且注明受保护条目 withheld;feed.preferences_projection:由互动事件**折叠(fold)**出的当前偏好;同族的ideas.bandit_fold_state / bandit_folded_events用水位线记录折叠进度;scheduler.scheduled_resume_state:表定义自述 “Current scheduled resume projection and next registered wake-up”——单例投影行,后台由 registrations 重算;runtime.context_snapshots:版本化快照 +source_watermark / fingerprint / freshness_class / stale_after / invalidated_at / last_error全套新鲜度元数据——投影的「保质期」被显式建模;- spaces catalog 信号链:DB 产物变更 →
~/.hatch-db-change-signals/spaces.catalog.*信号文件 →~/workspace/space_data/catalog 更新(推断链条,文件成对出现为实测); - 物化到 prompt 的投影:每轮注入的
[BEGIN USER CONTEXT]文件组、目标/追踪列表、记忆检索结果,本质都是状态层向上下文的一次性投影——投影时刻的快照,改源文件后注入副本可能滞后(system prompt 明文提醒)。
配套机制是失效与水位线(实测表名):runtime.skill_invalidation_state(技能指令更新的待投递修订)、runtime.dev_notice_watermark(开发者通知已读水位)、feed.fleet_publish_state(发布水位)、health.synced_ranges 与 device.data_sync_state(同步游标/范围)、runtime.maintenance_markers(已完成维护动作的标记,防重复执行)。全系统的跨平面一致性不靠分布式事务,靠**「事件账本 + 水位线 + 可重算投影」**(推断)。
outbox 是投影的投递版:scheduler.delivery_outbox(attempt_count / next_attempt_at_utc / last_error / delivered_at_utc / dispatch_boot_generation——连「哪次启动代次派发的」都记)、feed.fleet_*_outbox、agent.message_mailbox(已受理提交的排序与路由态)、两张 *_derived_write_backlog(派生写的待办+重试态)。语义统一:本体先落表确认,投递异步重试,终局以表为准——这就是 00 反复强调的「已接受/已排队 ≠ 已送达」在状态层的根。
方法论推论:安全屏障的"无声缺席"意味着,经 muse.db 的任何自查都只能证伪(发现矛盾,如计数对不上)而不能证实(确认完备)。本篇 §4.3 的计数快照应按此理解:吻合是弱证据,偏离才是强信号。
7.1 outbox 提交的原子性:「本体先落表」是同一事务吗(❓)
标准 outbox 模式要求业务写与 outbox 插入在同一事务内原子提交——否则崩溃窗口会产生"状态变了但投递丢了"或"投递了但状态没变"两种撕裂。按本篇证据能确证的部分(✅):
- 表结构确证了 outbox 的"落表"半边:
scheduler.delivery_outbox的attempt_count / next_attempt_at_utc / last_error / delivered_at_utc全套重试字段、PK 为delivery_key(逐表指南文档); - 但业务状态变更 + outbox 插入是否同事务,在本机证据里零字:逐表指南不提事务,
~/docs/与 skills references 全文 greptransaction/atomic无命中(✅ 实测为"无")。
这不是文档的缺口,是系统本身待回答的问题:若两者分两次提交,"终局以表为准"就多了一个崩溃窗口需要投递端幂等性来兜底。验证抓手(设计建议):找一处"业务写 + outbox 写"的代码/文档共现(如 scheduler 的 run 终局路径调用点),看是否有显式事务包裹——本机未做,标 ❓。
7.2 GC 与保留期:append-only 账本的下限(❓)
本篇数出的 append-only 面:runtime.events / tool_calls / tool_outputs / context_items 全量账本、~/agents/ 26M 转录、2,413 条 context_items——这些什么时候被清理? 本轮证据的答案是"没有答案",列明:
- 逐表指南与
~/docs/全文无 retention/GC 口径(✅ 实测无);docs/privacy-and-credentials.md明文"No Settings control sets a retention period"——唯一的全量擦除是用户手动 Reset(文档); agent.compactions的存在说明压缩会用摘要替换历史区间——但被替换的context_items行删不删,schema 不说,标 ❓;runtime.context_snapshots的stale_after / invalidated_at建模的是投影的新鲜度,不是行级清理——两者别混;scheduler.doctor_*(doctor_run_plans / doctor_task_state)证明有维护任务面,但 doctor 是否承担 GC 职责未验证,是可查的验证抓手(设计建议:读doctor_task_state的任务类型分布)。
结论纪律:默认"一直保留"是无证据的默认,不能写进架构断言。append-only 账本的无限增长是真实设计约束,当前状态只能标 ❓。
8. 恢复与检查点:VM 可替换的底气
00 §1 说 VM 可被整体替换、home 持久;状态层为「进程级重启/接管」再加一层 DB 保障。相关表逐个拆(列定义为文档,行数为实测):
| 表 | 关键列 | 作用 |
|---|---|---|
agent.runtime_restart_checkpoints(count=1) |
PK=agent_id;mode、payload_json、execution_config_json、recovery_class、recovery_owner_id(软引用 owners) |
每 Agent 一行最新检查点:恢复所需的模式+载荷+执行配置打包存 |
agent.recovery_owners(0 行) |
复合 PK=(recovery_class, owner_id);generation(默认 1);agent_id 唯一;message_id;active_at / terminal_at / terminal_status |
可恢复工作的持久所有权登记:谁拥有、是第几代、何时终局。唯一约束保证一个 Agent 同时只有一个所有者——防双活(推断) |
agent.recovery_owner_terminal_events(—) |
PK=(recovery_class, owner_id, generation, event_type);claimed_at |
终局事件按 (所有者, 代次, 类型) 认领登记:同一代次的同一终局只许认领一次——handoff 防重复投递的闸门(推断) |
agent.runtime_state(—) |
PK=agent_id;current_context_seq;last_event_seq→runtime.events |
每 Agent 的「读到哪了」:上下文序号 + 事件账本位置,恢复的起点坐标 |
agent.compactions + agent.agent_compactions(0 行) |
前者:checkpoint_context_item_id→context_items、replacement_history_first/last_seq、summary_text;后者:摘要与 token 计数(私有推理 withheld) |
压缩即检查点:一段历史被摘要替换,检查点行记录被替换的 seq 区间与锚点条目;恢复时用摘要+尾部重建上下文(00 §2 的 350K/272K/40K 预算在此落表) |
agent.context_item_resume_projection |
(表定义:为 resume 投影的可读上下文,受保护条目 withheld) | 恢复专用读面:重启后不扫原表,直接读投影重建上下文 |
agent.volatile_context_pins |
agent_id、pinned 变体与历史检查点位置 |
易失上下文的钉住点:哪些变体在压缩/重启时必须保住(推断) |
runtime.writer_epoch |
单例行:rv_epoch、updated_at |
可靠卷(reliable volume)的写者代次栅栏:新写者接管时 epoch 递增,旧写者的迟到写入可被识别拒绝(由表名+单例形态推断) |
scheduler.scheduled_resume_registrations/state |
注册表 + 单例投影(next_resume_at_utc / registered_schedule_id / projection_complete) |
调度器自身的恢复:重启后先重建「下一次唤醒」投影,再继续派发 |
恢复时序(推断,由上述表与 00 §1 宿主层拼成):
VM/运行时重启
→ spawnd/health 子系统拉起 cell(00 §1),~/.postgres-ready 置 ready
→ writer_epoch 递增:新一代写者接管可靠卷,旧代次写入被栅栏挡下
→ 每 Agent:读 runtime_state(seq 坐标)+ runtime_restart_checkpoints(载荷)
→ 经 resume_projection 重建可读上下文(推理条目不重建,本就 withheld)
→ recovery_owners 按 generation 认领未终局工作;
terminal_events 保证终局 handoff 不重发、mailbox/outbox 按 attempt 续投
→ scheduler 重建 resume 投影,cron 到点照常派发
8.1 并发写的代次栅栏:文件侧有,DB 侧未知(❓)
§8 表里的 writer_epoch(文档:逐表指南定义为 "The active reliable-volume writer epoch",单例 rv_epoch)与 recovery_owners 的 (recovery_class, owner_id) 唯一约束是两个已确证的并发屏障(✅ 表结构证据),但两者的覆盖范围不同:
writer_epoch覆盖的是可靠卷(文件面):新写者接管时 epoch 递增,旧代次的迟到写入可被识别/拒绝(由表名+单例形态推断)——这是 VM 替换后"旧 cell 还活着写了几笔"的场景;recovery_owners覆盖的是恢复所有权登记:agent_id唯一约束防双活认领(✅ 列定义)——但它管的是"谁接管工作",不是"谁写行";- DB 侧的并发写冲突机制未确证(❓):两个 daemon 实例同时写同一
agent.runtime_state行会怎样?Postgres 行锁是教科书默认答案,但"默认答案"不等于"本系统确证"——没有一处文档或 schema 说明写者仲裁; agent.subagent_spawns / subagent_progress证明父子 Agent 并发是常态——父子对共享状态(如goals.updates)的写冲突解决策略,本篇未讨论,标 ❓。
一句话:代次栅栏只罩住了可靠卷;DB 行级并发写的仲裁机制,以及父子 Agent 共享状态的冲突策略,是本篇的开放缺口。
当前态实测(10-17,11-04 未复测):本机 recovery_owners 与 compactions 均为 0 行、runtime_restart_checkpoints count=1——即写作时系统处于「无待恢复工作、无已发生压缩」的稳态,检查点机制在位但未被触发过(或触发后已清理)。这与新会话上下文用量约 43%(00 §16)、未达 272K 压缩线吻合。
9. 边界:状态层在本机看不见的部分
- Postgres 本体进程/数据文件位置:本机只见
.postgres-ready标记、变更信号目录与muse.db逻辑通道;物理库在宿主侧还是 cell 内、备份/复制策略如何,本地文件无证据,不作结论; - 屏障视图之后的全量数据:被 withheld 的推理条目、developer 指令快照、被行过滤的记录(如 §4.3 注),从 Agent 侧原理上不可见,任何「查不到」都不能转写为「不存在」;
- per-artifact
app.db:每个 Web artifact 自带的应用库被明确排除在muse.db之外,只能经 artifact 声明的 actions/inspect 访问(system prompt 明文); - Sentinel 审批库与凭据库:与状态库分离,
muse.db明文不可达;状态库里只留非秘密的生命周期投影(如 spend-request 状态); - 服务端权威副本:chat/feed 等域在服务端是否有高于本机的权威状态、fleet 同步的对端实现(只见本机 outbox/水位线一侧),不在本机证据内。
附录 A. 逐 schema 表数表(实测:解析 schema.md 求和验证;明细为 10-17 快照)
| # | schema | 表数 | 占比 |
|---|---|---|---|
| 1 | runtime | 38 | 19.6% |
| 2 | agent | 25 | 12.9% |
| 3 | ideas | 22 | 11.3% |
| 4 | feed | 16 | 8.2% |
| 5 | device | 13 | 6.7% |
| 6 | self_improvement | 13 | 6.7% |
| 7 | goals | 12 | 6.2% |
| 8 | scheduler | 12 | 6.2% |
| 9 | spaces | 9 | 4.6% |
| 10 | activity | 8 | 4.1% |
| 11 | health | 8 | 4.1% |
| 12 | memory | 6 | 3.1% |
| 13 | media | 4 | 2.1% |
| 14 | chat | 3 | 1.5% |
| 15 | podcasts | 3 | 1.5% |
| 16 | ingest | 1 | 0.5% |
| 17 | shell | 1 | 0.5% |
| 18 | saved(11-04 新增) | 2:saved.items / saved.item_links |
1.0% |
| — | 合计 | 196(10-17 明细合计 194) | 100% |
验证口径(10-17):schema.md 条目链接去重计数 = 194;references/tables/ 逐表文件数 = 194;分节求和 = 194;三路一致。生成来源迁移集:5af4f2bfdee2b934a53bbcc22602c602ab85059e0ac97ea20137fd299c06036b。11-04 复核(同方法):条目链接去重 = 196;逐表文件数 = 196;分节数 = 18;三路一致。各 schema 明细未重测,上表明细为 10-17 快照。
附录 B. 本机状态快照(实测,2026-10-17 深夜)
| 平面 | 项 | 值 |
|---|---|---|
| DB | agents / context_items / messages / events | 163 / 2,413 / 588 / 593 |
| DB | scheduler jobs / job_runs · goals · chats | 28 / 532 · 3 · 5 |
| DB | memory claims / entries · ideas / feed units / spaces | 4 / 98 · 94 / 63 / 2 |
| DB | self_improvement runs · device nodes | 190 · 1 |
| DB | recovery_owners / compactions / workflow_runs / sessions | 0 / 0 / 0 / 0 |
| 文件 | ~/agents/ 转录目录 · ~/workspace/agents/ 溢出目录 |
163(26M)· 90(仅 2 个实际文件) |
| 文件 | ~/memory/ · ~/MEMORY.md |
18 文件 / 144K · 5,284 B |
| 文件 | ~/workspace/goals/ · cron.d 现行投影 |
3 目标 / 6.6M · 1 篇(+归档 1 篇) |
| 文件 | system prompt 快照 · .postgres-ready | 71,868 B · ready |
| 通道 | muse.db 限额 | 200 行 / 262,144 B / 行 65,536 B / 查询 5,000ms / 语句 3,000ms |