<!-- 本文件由 docs/agent-protocol.md 的「协议正文」生成,请勿手改;改协议先改源文件 -->

### 活点地图

本项目用「活点地图」记录探索状态：`.live-dot-map/map.json` 是**单一事实源**（路线/节点/方案线/标注的结构、状态、布局），长文本详情在 `.live-dot-map/nodes/`、`.live-dot-map/routes/` 的 Markdown 分片。你（Agent）和人读写同一组文件。（兼容：旧版项目根目录的 `map.json` 同样有效，读到就用；新建一律进 `.live-dot-map/`。）

#### 会话开始铁律

每次会话开始，读完入口文档后**必须读 `.live-dot-map/map.json`**（旧版项目读根目录 `map.json`），然后**主动输出一次地图摘要**（不用等用户问）：

1. 主路线（`main:true`）当前推进到哪个节点；
2. 等待用户验收/判断的方案清单（`status:pending`，附方案名与一句话等待原因）；
3. 停滞路线：其下节点与方案线的最大 `updatedAt` 距今超过 7 天的路线；
4. 你建议的下一步（一条即可）。

摘要控制在 10 行以内。之后正常响应用户指令。

#### 干活后同步

完成实质工作（实验、验证、决策、发现新问题）后，**会话结束前更新 `map.json`**：

- 新尝试 → 在对应节点下新增方案线（`status:pending`，递增 `counters.edge`）；
- 有客观证据的验证结果 → 改 `status` 为 `success`/`failed`，并把证据一句话写进该方案的标注或 md；
- 需要人审美/判断才能定论的 → **保持 `pending`**，写一条标注说明「等什么」（如「等用户播放 S1–S6 选优胜」）；
- 明确否决、以后不得再提议的方向 → `status:failed` + `shelved:true` + 标注写清否决原因；
- 发现新的独立问题 → 可新建问题路线（`source` 指向来源节点），不要把问题塞进主路线节点名里；
- 更新被改动对象的 `updatedAt` 与文件级 `updatedAt`；新建对象递增对应 counter，**编号不复用**。

#### 投影读取（地图变大时）

- 节点 < 100：`map.json` 无脑全读。
- 节点 ≥ 100（或读取占用明显）时，改读**投影**四块，细节按 `md` 指针按需下探：
  1. 主路线链（`main:true` 路线及其节点/方案）；
  2. 全部未归档的 `status:pending` 方案（等待人判断清单）；
  3. 停滞路线（最大 `updatedAt` 距今 > 7 天）；
  4. 每条未归档路线的一行摘要（路线名 + 当前所在节点 + 最近状态）。
- `archived:true` 的路线与方案线**一律不进投影**；只有用户明确问起历史时，才回 `map.json` 全文里翻归档区。

#### 整理例程（睡眠巩固）

用户说「整理地图」，或每 ~10 个会话且地图明显变乱时执行。先向用户说明要做什么，做完汇报改动清单：

1. 合并冗余：同义节点、重复方案线合并，保留信息更全的一方；
2. 建议归档：停滞 > 30 天且低分（`score < 60`）或 `failed` 且 `shelved` 的方案/路线 → 建议置 `archived:true`，**逐条等用户确认后才改**；只归档，永不删除；
3. 建议沉淀：走通的绿线（`success` 且 `score ≥ 80`）→ 建议把 SOP 写进 `AGENTS.md` 或 `skills/`，让经验下沉为习惯；
4. 重算每条未归档路线的一行摘要，保证投影新鲜。

#### 创新循环

会话摘要之后，或用户问「接下来做什么 / 有什么新想法」时，做一次**结构空隙检查**，从地图结构本身找机会：

- 停滞路线里值得复活的（停滞原因已消失）；
- 高分方案（`score ≥ 80`）可迁移到其他路线的场景；
- 两条路线的潜在交叉点（一条线的方案可能解另一条线的问题）;
- 低分但方向重要的路线，值得换条路径再试的。

只提 1–2 条，每条必须引用具体节点/方案 id 和理由，不说套话；没有就直说没有。

#### 语义规则（违反即数据损坏）

- 状态与连接解耦：改 `status` 不动 `to/dx/dy`；`to:null` = 悬空。手动状态变更不得增删连接。
- 节点只表达目的/问题/结果，方案永远在线（`edges`）上，不建成节点。
- 名称 ≤20 字、标注 ≤80 字；长内容写进 `.live-dot-map/nodes/`、`.live-dot-map/routes/` 分片，map.json 里只留结论。
- 分片命名：节点 `.live-dot-map/nodes/<num>-<名称>.md`，方案 `.live-dot-map/routes/<id>-<方案名>.md`；改名时同步改路径，不新建重复文件。
- `shelved:true` 的方案：**禁止再次提议**（它已死，原因在标注里）。
- `score`（0–100）由人打或你建议、人确认；只表达「结果有多好」，不改动 `status`；不要自动评分。
- `archived:true` 只置标志不删数据；归档对象不进投影、画布弱化显示，但你随时可以回全文读它。
- 隐藏标注（`hidden:true`）你始终可读，只是人暂时不看。

#### 安全边界

- 删除节点/路线、一次性改动超过 10 个对象前，先向用户说明并等确认。
- 不写 `version` 字段不认识的文件；遇到未知字段保留原样。
- 只读写本项目目录（唯一的例外是下面的画布程序目录）。

#### 画布程序位置

画布程序（`app.html`，零依赖单文件）安装在用户主目录下的 `~/.live-dot-map/`（Windows 即 `C:\Users\<用户>\.live-dot-map\`）。用户说「打开画布」时，直接拉起它：

- Windows：`start "" "%USERPROFILE%\.live-dot-map\app.html"`
- macOS：`open ~/.live-dot-map/app.html`
- Linux：`xdg-open ~/.live-dot-map/app.html`

拉起后提醒用户点画布里的「打开项目文件夹」选中本项目目录（浏览器安全限制，这步只能人来点）。如果该文件不存在，说明还没接入——引导用户去落地页复制接入口令，或按 `agent-kit/setup.md` 执行接入。

#### 初始化（项目还没有 map.json 时）

用户说「转成地图/初始化活点地图」时，按迁移四步：

1. 读入口文档（AGENTS.md 指定的）+ 按链接下探一层；
2. 提取：路线（按主题聚类）、节点（目的/问题/结果）、方案（每次尝试），从文字推断状态（「确定为默认/已验证」→ success，「未通过/弃用」→ failed，「待用户/未验收」→ pending）；
3. 在项目根新建 `.live-dot-map/` 目录，生成 `.live-dot-map/map.json` 草稿，节点挂**现有** md 链接（不新建内容文件）；
4. 明确告诉用户：这是草稿，请他在画布上审核修正——判断权在人。
