An open API service indexing awesome lists of open source software.

https://github.com/killop/ai-harness


https://github.com/killop/ai-harness

Last synced: 23 days ago
JSON representation

Awesome Lists containing this project

README

          

# Harness Workspace

`harness-workspace/` 是这个项目的本地记忆工作区。

它不是游戏运行时代码,也不是共享数据库,而是一套围绕 `MemPalace` 搭起来的“知识缓存 -> 本地 palace -> MCP 查询”产品化壳层。

它的目标很直接:

- 让团队把项目知识沉淀成 Markdown,而不是散落在对话、脑子和聊天记录里
- 让每个人都能从同一份共享知识源生成自己的本地 palace
- 让 MCP 在不打断正在使用的情况下,安全刷新到新版本
- 让刷新尽量增量化,而不是每次全量重建

---

## 0. Windows 用户先看这里

如果你是人在 Windows 上手工执行,这个 README 最重要的就是下面这几条。

绝大多数人平时只需要认这 4 个入口:

```powershell
第一次安装:
python .\tools\mempalace_tools.py setup
.\tools\mempalace-install-agent-mcp.bat --agent codex

平时开 daemon:
.\tools\mempalace-daemon.bat

需要强制全量重建:
.\tools\mempalace-rebuild.bat

需要手工停 daemon:
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-stop
```

直接理解成:

- `setup`:新机器第一次安装时执行一次
- `mempalace-install-agent-mcp.bat`:把本地 agent 接到当前项目
- `mempalace-daemon.bat`:平时就开这个,持续监听知识目录
- `mempalace-rebuild.bat`:只有你明确要强制全量重建时才跑

注意:

- 如果你用 Claude Code,把 `--agent codex` 改成 `--agent claude-code`
- 日常优先用 `.bat`,不要自己手敲长 Python 命令
- 刚 `rebuild` 完再开 `daemon`,现在不会再无意义地重刷一遍

## 0.1 阅读地图

这份 README 同时写给两类读者:

- 人手工操作时看:`0`、`10`、`11`、`14`
- AI / 维护者 / 想理解设计时看:`1` 到 `9`、`12` 到 `16`

如果你现在只是想“把这套东西跑起来”,不要从第 `1` 节开始读。

### 0.2 macOS / Linux 人工执行速查

```bash
首次安装:
bash ./tools/mempalace-setup.sh
bash ./tools/mempalace-install-agent-mcp.sh --agent codex

日常全量重建:
bash ./tools/mempalace-rebuild.sh

日常常驻监听:
bash ./tools/mempalace-daemon.sh

手工停止 daemon:
./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py daemon-stop
```

注意:

- macOS / Linux 这里用 `bash ./tools/*.sh`
- 不要用 `sh ./tools/*.sh`
- `daemon-stop`、`daemon-status`、`daemon-restart` 这类高级控制目前还是直接走 Python CLI

### 0.3 人工执行时怎么选脚本

- `setup`:新机器第一次安装时执行一次
- `mempalace-install-agent-mcp`:把本地 agent 接到当前项目的 MemPalace
- `mempalace-rebuild`:立刻做一次全量重建
- `mempalace-daemon`:前台跑 daemon,持续监听知识目录
- `daemon-stop`:手工停掉后台或前台 daemon
- macOS / Linux 对应的是同名 `.sh`,用法统一写成 `bash ./tools/.sh`

---

下面从 `1` 开始,主要是设计和实现说明,偏 AI / 维护者阅读。

## 1. 给 AI / 维护者看的产品定位

这套东西的定位不是“文档仓库”,也不是“直接共享数据库”。

它更接近一个本地知识索引产品,分成两层:

- 共享层:团队维护 `knowledges-cache/` 里的 Markdown
- 本地层:每个人在自己的机器上生成 `.mempalace_local/palace/`

也就是说:

- 团队共享的是“知识源文件”
- 每个人本地拥有的是“索引产物”

这样做的原因是:

- 数据库文件不适合多人共享提交
- 本地 palace 可以按个人机器环境独立运行
- 本地 MCP 可以直接连本地 palace,查询快,风险低
- 刷新、回滚、切版本都可以只在本地完成

### 1.1 这个产品解决什么问题

- 项目知识分散,靠口口相传
- AI 工具每次都要重新读代码和文档,成本高
- 文档更新后,查询系统不能安全热切换
- Windows-only 的脚本体系太重,不利于跨平台运行

### 1.2 这个产品不做什么

- 不把 `.mempalace_local/` 当成团队共享产物
- 不直接改游戏运行时代码
- 不把所有外部目录做复杂同步编排
- 不试图做“中心化远程 palace 服务”

---

## 2. 产品总览

从产品视角看,可以把它理解成 4 个部件:

```text
+----------------------+ +----------------------+ +----------------------+
| Shared Knowledge | | Local Build Layer | | Query Layer |
| Source | | | | |
| knowledges-cache/ +----->+ mempalace_tools.py +----->+ MCP / tools / agent |
| Markdown + config | | refresh / daemon | | query active palace |
+----------------------+ +----------------------+ +----------------------+
|
v
+----------------------+
| Local Palace |
| .mempalace_local/ |
| versions + current |
+----------------------+
```

你可以把它记成一句话:

```text
Markdown 是事实源
Palace 是本地索引
MCP 只读当前 active palace
refresh/daemon 负责把源变成新版本
```

---

## 3. 目录结构

```text
harness-workspace/
|-- .mempalace_local/ # 本地运行产物,不提交
| |-- palace/
| | |-- current.json # 当前 active 版本指针
| | |-- versions/ # 蓝绿版本目录
| | `-- ... # chroma/sqlite/index 数据
| `-- refresh-daemon/ # daemon 锁、日志、状态
|
|-- knowledges-cache/ # 团队共享知识源
| |-- /
| | |-- mempalace.yaml # wing 配置
| | |-- manual/ # 手写知识
| | `-- generated/ # 脚本生成知识
| `-- README.md
|
|-- mempalace-github-code/ # MemPalace 源码副本
|
|-- tools/
| `-- mempalace_tools.py # 跨平台统一入口
|
`-- README.md
```

---

## 4. 核心概念

### 4.1 Wing

`wing` 是知识分区,不是物理数据库。

一个 wing 通常代表一个知识域,例如:

- `game_client`
- `game_server`
- `game_design`
- `game_shared`

每个 wing 目录下都有一个 `mempalace.yaml`,用于定义:

- wing 名称
- room 划分
- 关键词路由

### 4.2 Manual 和 Generated

- `manual/`:人手维护,优先放长期稳定、需要表达判断的知识
- `generated/`:脚本提炼出来的知识,适合大量同步型内容

这两类内容都会被挖掘进 palace,但维护方式不同。

### 4.3 Palace

`palace` 是本地索引库,不是共享源。

它里面保存的是:

- drawer / closet 等检索数据
- chroma / sqlite 等底层索引
- 当前 active 版本指针

所以 palace 的本质是“可再生缓存”。

### 4.4 Active Version

`current.json` 指向当前激活版本。

MCP 不直接绑定某个固定版本目录,而是读取:

```text
.mempalace_local/palace/current.json
```

然后跳到:

```text
.mempalace_local/palace/versions/
```

这就是蓝绿切换的基础。

---

## 5. 设计原则

### 5.1 共享源和本地产物分离

```text
team edits markdown
|
v
knowledges-cache/ <- shared, versioned, reviewable
|
v
.mempalace_local/ <- local, generated, disposable
```

这样可以让团队真正 review 的是知识本身,而不是二进制索引文件。

### 5.2 统一入口,全面 Python 化

这套工具只保留一个主入口:

```text
tools/mempalace_tools.py
```

所有常用动作都从这里进:

- `setup`
- `install-agent-mcp`
- `refresh`
- `rebuild`
- `start-mcp`
- `daemon`

这样做的好处:

- 跨平台
- 文件少
- 行为集中
- 文档和命令一致

### 5.3 蓝绿切换,而不是原地覆盖

如果 MCP 正在使用 palace,直接原地刷新有几个风险:

- 刷到一半被查询
- 文件锁冲突
- 索引状态不一致
- 刷新失败后没有回退点

所以这里采用蓝绿模型:

```text
active version A
|
| build new version
v
candidate version B
|
| success
v
current.json -> B
```

MCP 永远只读 active 版本,不读构建中的半成品。

### 5.4 增量优先,不无脑全量

最开始的蓝绿实现虽然安全,但每次都新建空版本,再全量 mine 所有 wing。

问题是:

- `file_already_mined` 的缓存只在“当前 palace 数据库”里有效
- 新版本如果是空的,就等于所有文件都第一次挖

现在改成了真正增量:

```text
old active palace
|
+--> copy to new version
|
+--> purge deleted files
+--> reset changed-config wings
+--> re-mine changed wings only
|
+--> current.json cutover
```

这样就同时满足:

- 查询安全
- 刷新可回退
- 未改的文件可以直接命中已有索引

---

## 6. 产品架构

### 6.1 逻辑架构图

```text
+----------------------+
| User / Agent |
| asks memory question |
+----------+-----------+
|
v
+----------------------+
| MCP Server |
| start-mcp |
+----------+-----------+
|
v
+----------------------+
| current.json |
| resolve active path |
+----------+-----------+
|
v
+----------------------+
| active palace |
| versions/ |
+----------------------+

Shared knowledge update path:

+----------------------+ +----------------------+ +----------------------+
| knowledges-cache/ | ---> | mempalace_tools.py | ---> | new palace version |
| markdown + yaml | | refresh / daemon | | candidate build |
+----------------------+ +----------------------+ +----------------------+
|
v
+----------------------+
| current.json cutover |
+----------------------+
```

### 6.2 启动和查询关系

```text
tools/mempalace_tools.py start-mcp
|
v
mempalace.mcp_server --palace
|
v
read current.json
|
v
attach active version
|
v
serve queries
```

### 6.3 刷新关系

```text
refresh
|
+-- if unmanaged path:
| mine directly into target palace
|
`-- if managed root:
run blue-green refresh
|
+-- compare source snapshot
+-- if no change -> no-op
+-- else build candidate version
+-- cutover current.json
```

---

## 7. 刷新设计

### 7.1 为什么需要 daemon

`refresh` 适合手动触发。

`daemon` 适合常驻监听 `knowledges-cache/`,在文件变化后自动刷新。

它的职责非常克制:

- 只看 `knowledges-cache/*`
- 只做快照对比
- 只做去抖和触发刷新
- 不负责复杂跨目录同步编排

### 7.2 Daemon 工作方式

```text
loop every N seconds
|
+-- scan knowledges-cache snapshot
|
+-- diff with previous snapshot
|
+-- if changed:
| record pending changes
| reset debounce timer
|
`-- if debounce elapsed:
run blue-green incremental refresh
```

### 7.3 蓝绿增量刷新流程

```text
1. read active palace
2. load previous source_snapshot.json
3. scan current knowledges-cache
4. compute changed files / changed wings
5. if nothing changed:
keep current active version
6. else:
copy active palace -> candidate version
purge deleted files
reset wings whose mempalace.yaml changed
re-mine changed wings only
write candidate source_snapshot.json
update current.json
prune old versions
```

### 7.4 哪些情况会触发什么行为

| 变化类型 | 行为 |
| --- | --- |
| 某个 Markdown 改了 | 只重挖所属 wing |
| 某个 Markdown 删除了 | 先 purge 旧 drawer,再重挖该 wing |
| `mempalace.yaml` 改了 | 整个 wing reset,再全量重挖该 wing |
| 没有变化 | 直接 no-op |
| 第一次没有快照 | 做一次 full refresh 建基线 |

### 7.5 为什么现在 refresh 会很快

如果日志出现:

```text
No knowledge changes detected. Keeping current active palace.
```

说明:

- 当前知识源和上次快照一致
- 没有进入真实 mine
- 也没有新建候选版本

这是预期行为,不是异常。

---

## 8. 数据流

### 8.1 从知识源到可查询记忆

```text
author writes markdown
|
v
knowledges-cache//
|
v
mempalace_tools.py refresh / daemon
|
v
MemPalace mine
|
v
palace versions/
|
v
current.json points to active version
|
v
MCP query reads active version
```

### 8.2 团队协作模型

```text
+----------------------+
| Git repository |
| knowledges-cache/ |
+----------+-----------+
|
+------------------+------------------+
| |
v v
+----------------------+ +----------------------+
| Developer A | | Developer B |
| local palace A | | local palace B |
| .mempalace_local/ | | .mempalace_local/ |
+----------------------+ +----------------------+
| |
v v
local MCP A local MCP B
```

重点是:

- 大家共享同一份知识源
- 但每个人都构建自己的本地索引

---

## 9. 核心目录说明

### 9.1 `.mempalace_local/palace/`

- 本地生成的 palace 数据目录
- `current.json` 指向 active version
- `versions/` 保存历史版本
- candidate version 构建期间会写 `.build-state.json`
- `source_snapshot.json` 记录上次构建对应的源文件快照
- 这是运行产物,不是人工编辑区

### 9.2 `.mempalace_local/refresh-daemon/`

- `daemon.lock`:防止同一工作区启动多个 daemon
- `daemon.log`:守护进程日志
- `state.json`:当前快照状态、pending 数量、最近刷新状态
- `stop-request.json`:优雅停止请求文件,`daemon-stop` 会先写它

### 9.3 `knowledges-cache/`

- 这是团队共享事实源
- 每个 wing 是一个知识域
- `mempalace.yaml` 决定这个 wing 怎么被 mine
- `manual/` 适合手工沉淀知识
- `generated/` 适合脚本生成知识

### 9.4 `mempalace-github-code/`

- MemPalace 源码副本
- `setup` 会在这里创建 `.venv`
- `setup` 之后,其余命令默认都应该走这里的 `.venv` Python
- `start-mcp` 和 `refresh` 最终都依赖这里的 Python 环境和 CLI

### 9.5 `tools/mempalace_tools.py`

这是整个产品的控制台入口。

你可以把它理解成:

```text
operator shell
|
v
mempalace_tools.py
|
+-- setup
+-- install-agent-mcp
+-- refresh
+-- rebuild
+-- start-mcp
`-- daemon
```

---

## 10. 给人看的常用命令(详细版)

在 `harness-workspace/` 目录下执行。

约定:

- 首次在新机器 bootstrap 时,用系统 Python 跑一次 `setup`
- `setup` 成功后,后续命令统一走 `mempalace-github-code/.venv` 里的 Python

如果你是人在手工执行,先记住这一条:

- Windows 优先用 `.bat`
- macOS / Linux 优先用 `bash ./tools/*.sh`
- 除非排障,不需要自己拼 `mempalace_tools.py` 参数
- 顶部 `0` 节是最短路径,这一节是详细版

Windows 推荐优先用这些批处理入口:

- 安装本地 Agent MCP:`.\tools\mempalace-install-agent-mcp.bat`
- 全量重建:`.\tools\mempalace-rebuild.bat`
- 常驻 daemon:`.\tools\mempalace-daemon.bat`

最常见的人手工操作可以直接记成:

```text
第一次安装 -> setup
接入本地 agent -> mempalace-install-agent-mcp.bat
强制重建一次 -> mempalace-rebuild.bat
持续监听刷新 -> mempalace-daemon.bat
```

### 10.1 安装和初始化

macOS / Linux:

```bash
bash ./tools/mempalace-setup.sh
```

Windows:

```powershell
python .\tools\mempalace_tools.py setup
```

说明:

- 这里只是第一次创建 `.venv`
- 后续 `refresh`、`daemon`、`start-mcp`、`rebuild` 都优先用 repo 内 `.venv` Python

作用:

- 创建专用虚拟环境
- 安装 MemPalace 依赖
- 校验 MCP 依赖能否正常导入

### 10.2 安装本地 Agent MCP

这个命令现在支持两个本地 target:

- `codex`:写当前项目根目录的 `.codex/config.toml`
- `claude-code`:调用 `claude mcp add -s local`,写 Claude Code 的本地项目作用域配置

macOS / Linux:

```bash
bash ./tools/mempalace-install-agent-mcp.sh
```

Windows:

```powershell
.\tools\mempalace-install-agent-mcp.bat
```

作用:

- 如果没传 `--agent`,会在终端里让你选择 `codex` 或 `claude-code`
- `--agent codex` 时,会自动创建或更新当前项目的 `.codex/config.toml`
- `--agent claude-code` 时,会调用本机 `claude` CLI 安装到 Claude Code 本地项目配置
- `codex` 安装模式下,只会定点写入 `mcp_servers.mempalace`,不会重写无关 section
- Windows 下日常推荐直接用 `.\tools\mempalace-install-agent-mcp.bat --agent codex` 或 `.\tools\mempalace-install-agent-mcp.bat --agent claude-code`

### 10.3 手动刷新

macOS / Linux:

```bash
bash ./tools/mempalace-refresh.sh
```

Windows:

```powershell
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py refresh
```

作用:

- 如果是 managed root,就走蓝绿增量刷新
- 如果没有变化,会直接 no-op

### 10.4 全量重建

macOS / Linux:

```bash
bash ./tools/mempalace-rebuild.sh
```

Windows:

```powershell
.\tools\mempalace-rebuild.bat
```

适合:

- 你要强制做一次全量重建
- 默认 managed root 上会走蓝绿全量重建
- 需要验证从零开始的构建链路
- Windows 下日常推荐直接用 `.\tools\mempalace-rebuild.bat`

不适合:

- 日常在线刷新

### 10.5 启动 MCP

macOS / Linux:

```bash
bash ./tools/mempalace-start-mcp.sh
```

Windows:

```powershell
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py start-mcp
```

作用:

- 启动本地 MemPalace MCP server
- 让查询跟随 `current.json` 指向的 active version

### 10.6 启动守护进程

macOS / Linux:

```bash
bash ./tools/mempalace-daemon.sh
```

Windows:

```powershell
.\tools\mempalace-daemon.bat
```

说明:

- `daemon-run` 会先安全停掉旧 daemon,再在当前终端里直接跑前台 daemon
- `mempalace-daemon.bat` / `mempalace-daemon.sh` 现在默认执行 `daemon-run`
- 前台模式下,你会一直看到日志;按 `Ctrl+C` 就会关闭 daemon
- `daemon-start` 会把 daemon 脱离当前终端,后台常驻
- 如果 active palace 的 `source_snapshot` 已经和当前知识源一致,daemon 启动时不会再额外跑一轮 refresh;刚执行完 `rebuild` 再起 daemon,会直接进入监听态
- `daemon-stop` 默认先请求优雅停止,等当前 refresh 收尾;超时后才会 force kill
- 关闭当前 Codex / Claude Code / 终端后,后台 daemon 仍然继续轮询
- 如果你就是想看前台实时输出,才直接用 `daemon`
- `daemon-restart` 默认先等当前 refresh 空闲,再重启;只有传 `--force` 才会中断正在进行的 refresh
- Windows 下日常推荐直接用 `.\tools\mempalace-daemon.bat`

常用参数:

macOS / Linux:

```bash
bash ./tools/mempalace-daemon.sh --debounce-seconds 3 --keep-versions 3
```

Windows:

```powershell
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-start --debounce-seconds 3 --keep-versions 3
```

### 10.7 只跑一次守护刷新

macOS / Linux:

```bash
./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py daemon --run-once
```

Windows:

```powershell
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon --run-once
```

适合:

- 手动验证刷新链路
- CI 或临时操作
- 不想常驻 daemon

### 10.8 查看或关闭守护进程

macOS / Linux:

```bash
./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py daemon-status
./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py daemon-stop
./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py daemon-restart
```

Windows:

```powershell
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-run
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-status
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-stop
.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py daemon-restart
```

---

## 11. 给人看的推荐使用方式

### 11.1 新机器首次接入

```text
git pull
|
v
bash ./tools/mempalace-setup.sh
|
v
bash ./tools/mempalace-install-agent-mcp.sh --agent codex
|
v
repo .venv python -> mempalace_tools.py daemon --run-once
|
v
bash ./tools/mempalace-start-mcp.sh
```

对应命令:

- Windows `setup`:`python .\tools\mempalace_tools.py setup`
- Windows 安装本地 Codex MCP:`.\tools\mempalace-install-agent-mcp.bat --agent codex`
- Windows 安装本地 Claude Code MCP:`.\tools\mempalace-install-agent-mcp.bat --agent claude-code`
- Windows 启动常驻 daemon:`.\tools\mempalace-daemon.bat`
- Windows 全量重建:`.\tools\mempalace-rebuild.bat`
- Windows 其他高级命令:`.\mempalace-github-code\.venv\Scripts\python.exe .\tools\mempalace_tools.py `
- macOS / Linux `setup`:`bash ./tools/mempalace-setup.sh`
- macOS / Linux 安装本地 Codex MCP:`bash ./tools/mempalace-install-agent-mcp.sh --agent codex`
- macOS / Linux 安装本地 Claude Code MCP:`bash ./tools/mempalace-install-agent-mcp.sh --agent claude-code`
- macOS / Linux 启动常驻 daemon:`bash ./tools/mempalace-daemon.sh`
- macOS / Linux 全量重建:`bash ./tools/mempalace-rebuild.sh`
- macOS / Linux 启动 MCP:`bash ./tools/mempalace-start-mcp.sh`
- macOS / Linux 其他高级命令:`./mempalace-github-code/.venv/bin/python3 ./tools/mempalace_tools.py `

### 11.2 日常写知识

```text
edit markdown under knowledges-cache/
|
v
run refresh or let daemon detect it
|
v
query through MCP
```

### 11.3 推荐工作流

#### 模式 A:手动模式

适合低频更新。

```text
改文档 -> refresh -> 查询
```

#### 模式 B:守护模式

适合你持续维护知识源。

```text
开 daemon-run 占住当前终端
|
+-- 改文档
+-- 等去抖
`-- 自动刷新
```

---

## 12. 典型场景

### 12.1 项目知识沉淀

把一次需求理解、方案总结、排错经验放进 `manual/`,让后续 agent 和开发都能查询。

### 12.2 自动知识编译

把脚本分析、设计文档提炼、代码结构总结放进 `generated/`,作为可再生知识层。

### 12.3 本地 AI 查询

通过 MCP 直接问:

- 这个系统入口在哪
- 某个模块依赖谁
- 某类逻辑通常放在哪

---

## 13. 关键设计取舍

### 13.1 为什么不共享 palace 数据库

因为它不适合做代码评审和多人协作源。

共享数据库的问题:

- 二进制不可读
- 冲突难处理
- 不同平台和环境容易不一致
- 很难看出“知识到底改了什么”

### 13.2 为什么不原地 refresh

因为在线查询时不够安全。

原地刷新意味着:

- 构建中的状态可能被读到
- 索引中间态可能暴露
- 出错时难回退

现在是 blue-green:

- 新版本先在 `versions//` 里单独构建
- 只有构建成功才切 `current.json`
- 如果中途异常或被强杀,active palace 仍然保持旧版本
- 未完成 candidate 会带 `.build-state.json`,下次 `refresh` / `rebuild` / `daemon` 启动时会自动清理

### 13.3 为什么只监听当前文件夹

因为产品边界需要稳定。

这套工作区现在刻意不做“全仓库复杂同步编排”,而是只对 `knowledges-cache/` 负责。

优点是:

- 行为简单
- 可解释
- 变更边界清楚
- 出问题时容易排查

---

## 14. 给人看的故障排查

### 14.1 `refresh` 没反应

先看你改的是不是:

```text
harness-workspace/knowledges-cache/
```

如果你改的是项目别的目录,`refresh` 不会理它。

### 14.2 `refresh` 很快结束

如果日志是:

```text
No knowledge changes detected. Keeping current active palace.
```

说明没有检测到知识源变化,属于正常。

### 14.3 `refresh` 很慢

重点看是不是以下情况:

- 第一次建立基线
- `mempalace.yaml` 改了,导致整 wing reset
- `seed copy` 失败,回退成 full refresh
- 本次真的有大 wing 发生改动
- 如果报 `UnicodeEncodeError: 'charmap' codec can't encode characters`,通常是 Windows 非 UTF-8 终端在打印装饰分隔线。更新到最新 `tools/mempalace_tools.py` 后,子进程会强制 UTF-8;终端里分隔线可能显示成 `?`,但不会中断 `refresh` / `rebuild`

### 14.4 daemon 启动失败

检查:

- 有没有旧 daemon 还活着
- `.mempalace_local/refresh-daemon/daemon.lock` 是否残留
- `.mempalace_local/refresh-daemon/stop-request.json` 是否被异常残留
- `state.json` 里的 pid 是否还存在

### 14.5 MCP 启动失败

检查:

- 是否先跑过 `setup`
- `.codex/config.toml` 里的 Python 是否指向 `harness-workspace/mempalace-github-code/.venv`
- `.codex/config.toml` 里 `mempalace_tools.py` 路径是否有效
- `mempalace-github-code/.venv` 是否存在
- 可以直接重新执行一次 `install-agent-mcp --agent codex` 或 `install-agent-mcp --agent claude-code` 修复本地 agent 配置

---

## 15. 维护约定

- 优先更新已有知识文件,不要随意创建 `v2`、`final_final` 一类副本
- 需要长期维护的人工知识放到各 wing 的 `manual/`
- 由脚本重新生成的内容放到各 wing 的 `generated/`
- 不要手改 `.mempalace_local/` 下的数据库和索引文件
- 不要把本地 `.mempalace_local/` 当成共享源提交
- 团队共享的事实源应始终是 `knowledges-cache/` 下的 Markdown

---

## 16. 一句话总结

```text
Harness Workspace = 用共享 Markdown 做事实源,
在本地生成可蓝绿切换、可增量刷新、可被 MCP 查询的项目记忆工作区。
```