**技术方案评审** 把 Cockpit 项目里的 Markdown 文件变成一个 LAN 分享的讨论页:网络里任何人打开 URL,浏览器里读,加行级评论 —— 不用登录、不用装东西。设计目标是**方案级评审**(这个思路对不对?),不是逐行代码 review。

| 章节 | 内容 |
|---|---|
| [创建与分享](#创建与分享) | 把文档切到 Review、获取 LAN URL、管理 Review |
| [评论线程](#评论线程) | 行级评论、回复、标记已解决 |
| [身份与匿名](#身份与匿名) | 昵称、MAC 范围的身份、"私密" 意味着什么 |

## 创建与分享

**技术方案评审**让你把一份技术提案 —— 设计文档、RFC、半成品想法 —— 摆到 LAN 上的队友面前让他们读和评，谁都不用装任何东西。他们在浏览器里打开一个 URL，就这样。

### 创建一份

在 Cockpit 里打开你想分享的 Markdown 文件（设计文档、RFC，任何 `.md`）。文件工具栏里有一个 **Share Review** 开关 —— 打开它。

Cockpit：

1. 从文件内容创建 Review 条目。
2. 生成 LAN URL。
3. **自动把 URL 复制到你的剪贴板。**

URL 形如 `http://192.168.1.42:4457/review/rv-a1b2c3d4e5f6` —— 你的 LAN IP、一个 Cockpit 端口 + 1000 的端口、从文件路径派生的 Review ID。粘到 Slack / 你们的聊天 / 便签里。

### 分享的是什么

Review 在你**打开 Share Review 开关时**捕获 Markdown 文件的当前内容。**之后文件继续在 Cockpit 里改不会自动同步过去** —— 想让读者看到新内容,把开关关了再开一次,Cockpit 会拿当前文件内容重新建一份(Review ID 不变,老 URL 继续可用)。

**文件名(路径最后一段)成为 Reviews 列表里的标题**(不是文件第一行)。

### 谁能访问

LAN 上任何拿到 URL 的人。无需登录。首次打开 URL 时会被提示输入昵称，让评论的人能区分（见 [身份](#身份与匿名)）。

如果你机器在 LAN 上访问不到（你在用流量、在敌意防火墙后、在咖啡馆 Wi-Fi），URL 对别人不会 work。这个功能假设的是你跟同事共享 `localhost:3000` 那种 LAN。

### 停止分享

把文件工具栏的 **Share Review** 开关关掉。URL 立即停止响应。你之后可以重新分享同一个文件 —— Cockpit 记住 Review ID，所以拿着老 URL 的人重新开启后会看到新版本。

### 管理你的 Review

有一个 Reviews 面板列出你创建过的所有 Review。从那里：

- 打开已有 Review 的 URL。
- 关闭（停止分享）一个 Review。
- 永久删除。
- 拖动重排。

### 这不是什么

技术方案评审用于**方案和设计讨论**，不是 code review。行级锚点指向你的 Markdown 文本，不是 git diff。要对真实改动做代码级评审，用你现有的 PR 工作流（GitHub/GitLab）—— Cockpit 不替代那个。

## 评论线程

在一份技术方案评审里，任何拿到 URL 的人都能给文档里任意文本附评论。评论可线程化 —— 别人能回复，你能接着说。这是该功能的讨论引擎。

### 怎么评论

在 Review 里用鼠标选中任意一段文字。旁边弹出一个小窗问你想说什么。打评论、提交。

选区可以是：

- 句子里几个词。
- 整段。
- 跨段落的多行。
- Markdown 里代码块的某一行。

评论按文本里的**字符位置**(`startOffset` / `endOffset`)锚定,不是按行,所以"第 3 节最后一段"的评论会一直锚在那几个词上,哪怕你在上方插入了内容。

> 同一位置加多条重叠评论是允许的 —— Cockpit 不阻止。多条评论可以挂在同一段文字上。

### 回复

每条评论有 **Reply** 按钮。回复线程化挂在原评论下。回复跟顶级评论一样是纯文本。

没有超过一层的嵌套 —— 回复总是回顶级评论，不是回其它回复。

### 解决 / 关闭

评论线程有 **Close** 按钮。关闭的线程仍然可见但折叠;点击展开看,可以用 **Reopen** 按钮重新打开。这是对话结束的方式。

> 关闭权限**不只**限评论作者 —— 任何能跟评论交互的人都能关。要拿回控制感就直接 Reopen。

没有"由代码改动解决"的概念,因为 Review 根本不跟踪代码。

### 你能写什么

评论**只是纯文本** —— 不支持 Markdown、不支持代码块、不支持图片。要分享代码就直接粘进来（会显示为一块没高亮的文本），或者在文档里按位置指代。

这是有意的选择：让评论轻量化，避免 Review 变成"设计文档里包着自己的讨论线程、讨论线程里又嵌着代码评审"的迷宫。

### 准实时更新

Cockpit 每 10 秒轮询 Review 看新评论和回复。所以同事发了想法时，你不刷新也能在 10 秒内看到。这不是实时 WebSocket —— 快速协作可能略卡，但跨任何网络都可靠。

### 谁能做什么

> Cockpit 用**访问 IP** 判断角色:从 `localhost` / `127.0.0.1` 进来的当 admin(就是跑 Cockpit 的那台机器);其它 IP 是访客。不是按"文档作者"或登录态。

| 角色 | 能做 |
|---|---|
| **Admin**(在 host 机器上,通过 localhost 访问) | 编辑 Markdown 源文件、加评论、回复、删任何评论、删 Review。 |
| **访客**(LAN 上别的 IP) | 读文档、加评论、回复。能关闭(和重开)任何评论线程,不限于自己的。不能删别人的评论,不能改 Markdown 源文件。 |

## 身份与匿名

技术方案评审没有登录界面 —— LAN 上拿到 URL 的任何人都能读和评论。为了仍能区分参与者，Cockpit 通过**设备在 LAN 上的 MAC 地址**加上自选昵称识别每位访客。

这一页讲实际中"谁以什么名字出现"。

### 第一次进入 Review

访客首次打开 Review URL 时,Cockpit 弹出**昵称**对话框。预填一个随机生成的友好名字 —— **adjective + noun 形式拼起来**(比如 `HappyPanda`、`BraveDolphin`、`QuietCrane`)。他们可以保留、改成真名、或者点 **Random** 再摇一个。

选好的昵称对那台设备持久 —— 同一台设备打开你的任何 Review 都显示同样名字，不用重新输。

### 设备怎么识别

Cockpit 从入站请求读取访客 IP,然后在你本地网络跑 `arp -n` / `arp -a`(看操作系统)把 IP 映射到 MAC 地址。MAC 被 SHA-256 哈希(`cockpit:<MAC>`,取前 16 字符)成一个稳定但匿名的**作者 ID**。

昵称按这个作者 ID 存。两个后果：

- **同一设备，同一身份。** 队友的笔记本跨会话、跨天、跨你创建的不同 Review 都会被识别。
- **不同设备，不同身份。** 同一个人用手机进来是另一个参与者。两边都可以挑同样昵称，但底下的作者 ID 不同。

这是**匿名但稳定**，不是认证。你没在证明某人是谁，只是一致地把他叫同一个名字。

### 显示

每条评论显示:

- 评论者昵称。
- 小头像 —— 一个圆圈带首字母。

> 注意:UI 里目前头像**颜色统一**(都是品牌主色调),不按身份做颜色区分 —— 区分参与者主要靠昵称和首字母。

### 改昵称

Review 头部有个小头像图标。点开**身份**对话框。任何时候都能改昵称。

改了之后：

- 你**之后**的评论显示新名字。
- 你**之前**的评论也显示新名字 —— 名字按当前 map 渲染，不是评论时保存的。

### 限制

- 基于 MAC + ARP 的识别在同一广播 LAN 上 work。把 Review 放到反向代理或 VPN 后面、Cockpit 看每个访客都是同一个 IP 时，识别就崩了 —— 所有人会被并成一个。那不是预期用法。
- 没办法封禁某个参与者，除非整个停止分享。
- Cockpit 不在 UI 里向其它参与者展示 IP 地址或 MAC 地址 —— 只显示昵称和头像。
