MUNDERDIFFLIN / LEARN
CHAPTER 14
06 · STATE MODEL12 分钟阅读深入

四层状态:UI、Runtime、Persistent、External CLI

最重要的纠偏:当前 SQLite 只有 kv 与 command_history;Agent、队列、任务并没有统一进入 SQLite,而是分布在 Zustand/localStorage、roster.json、Hive 文件和外部 CLI 自己的存储中。

本课核心问题同一个界面事实为什么可能同时存在于四个地方?
学完你能
  • 区分 UI cache、config、SQLite 与协议文件。
  • 为任意状态判断 authority 与恢复路径。
01
状态关系图

一次状态变化通常跨越两到四层

例如 Agent 输出先改变 External CLI/PTTY 状态,再由 Main 推送事件,Renderer 写入 Zustand,必要时镜像 roster;但 CLI 会话/上下文本身仍由外部 Agent 保存。

交互图解

状态不是一张表:五层权威

01
SQLitekv · command_history
02
config / rosterconfig.json · roster.json · localStorage
03
Hive files + Gitregistry · tasks · mailboxes · memory
04
运行时内存PTY sessions · timers · breaker
05
外部 CLItranscripts · CODEX_HOME · credentials
源码当前 SQLite 仅保存窗口 KV 和命令历史;其余状态各有明确归属。
02
实际数据库

SQLite Phase A 只有两张表

harness.db 位于 Electron userData,开启 WAL。kv 目前主要保存窗口 bounds;command_history 保存用户提交的 prompt。代码注释明确把 agents、message_queue、cost_ledger 标记为未来迁移,不应按 SPEC.md 的理想模型描述为已完成。

WATCH

文档差异:SPEC.md 写“SQLite: Agents, layouts, command history, goals”,但当前 `db.ts` 明确说明 agents/message_queue 尚未实现。以源码为准。

03
持久化矩阵

同一业务域使用多种持久化机制

config.json 保存设置;localStorage 保存 UI/roster 并镜像到 harnessHome/roster.json;Hive registry/tasks/mailboxes/memory 是文件,且 Hive 自身是由单一 committer 管理的 Git repo;外部 CLI 会话保存在各自目录。

  • 01内存:PtyManager sessions、timers、liveWorkers、breaker state、Zustand transient fields。
  • 02userData:config.json、harness.db、analytics install/version stamps、knowledge store。
  • 03harnessHome:roster.json、hive/registry.json、tasks.json、board.md、agents/*、cost-ledger.jsonl。
  • 04External CLI:Claude transcripts、per-agent CODEX_HOME、provider sessions 与凭据。
04
Memory Graph 实况

Memory Graph 已有 UI;语义 memory 与 Knowledge Graph 仍是可选模块

旧 MEMORY_GRAPH_SPEC.md 自称“未写组件”,但当前源码已有 MemoryGraphPanel 与 client-side topic extraction。语义检索依赖可选 mempalace CLI;企业 Knowledge Graph 是另一套可选本地 store,不要混成 SQLite 内的一张统一图表。

05
状态工作表

为任何新字段先填六格,再决定 schema

字段名、scope、authority、写入者、副本、恢复/删除共同定义状态契约。只写一个 Zustand slice 或 DB column 还没有完成设计。

‘selectedAgentId’可能只是当前窗口选择;‘agentStatus’却是跨进程事实。名字相似,生命周期完全不同。

LESSON CHECKPOINT

能用自己的话回答核心问题了吗?

存储位置不等于权威来源;先定义谁能覆盖谁。