Files
NixMsg/docs/TASKS.md

410 lines
33 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NixMsg 开发任务拆分与多 Agent 协作
| 项 | 内容 |
|---|---|
| 版本 | 0.3 |
| 日期 | 2026-09-30 |
| 对应 | [PRD.md](./PRD.md) 0.5、[DEVELOPMENT.md](./DEVELOPMENT.md)(对应 PRD 0.5) |
| 仓库 | https://git.asio.asia/nixevol/NixMsg.git,主分支 `main` |
| 读者 | 总控 Agent、各开发线 Agent、负责人 |
## 1. 目标和交付标准
由多个 Agent 并行开发和测试,交付 NixMsg 服务端、管理后台、四种 SDK、Docker 镜像和文档。
下面全部满足才算交付:
1. `main` 上 `task check`(构建、代码检查、单元测试)和全部集成测试通过。
2. PRD 第 10 节 F01–F23 每条都有验收结果:通过;或未测,写明原因,列进交付说明供负责人事后审阅。
3. 四种 SDK 都通过 DEVELOPMENT 第 9 节的接入清单。
4. DEVELOPMENT 第 13 节的弱网、崩溃、压测、端到端测试做完并有报告。
5. 二进制(`linux/amd64`、`linux/arm64`、`windows/amd64`)和 Docker 镜像(amd64、arm64)能按文档启动;镜像已推到 `git.asio.asia/nixevol/nixmsg`。
6. 和文档不一致的实现、开发中自己拿的主意,都写进 `docs/DEVIATIONS.md`(写明原因和备选方案),并汇总进交付说明,供负责人事后审阅。
7. 最终代码按第 7 节审核过,打上 `v0.1.0` 和 `sdk/go/v0.1.0` 标签并推送;npm、PyPI、Maven 三个 SDK 包已发布到 Gitea 包仓库。
## 2. 资料
- `docs/PRD.md`:产品行为,以它为准。
- `docs/DEVELOPMENT.md`:实现规范。第 5 节的库用法和第 15 节「不要这样做」必须看。
- `docs/TASKS.md`:本文件。
- MemRelay 项目记忆(项目 NixMsg,ID `25464650-ed5d-440e-b362-190f2852d451`):已确认的决定、技术栈选型、依赖库行为核对结论,以及各线的进度检查点。随时可以查。
- 负责人已授权全程自动(第 9 节)。文档没写清或互相矛盾时不要停下来问,按和 PRD、DEVELOPMENT、PRD 第 9 节已确认决定最一致、最稳妥的做法自己定,写进 `docs/DEVIATIONS.md`(原因和备选方案);不改 PRD 的产品行为。子 Agent 定不了的写进报告,由总控定。
## 3. 环境
- 本机是 Windows,已有 Git、Go、Node.js LTS、pnpm、Python、JDK 21、Docker Desktop 和 scoop。缺的工具用 scoop 装,例如 `scoop install task golangci-lint`;包名不确定时先 `scoop search`。
- 丢包模拟(netem)、多架构镜像等 Linux 相关的测试,在 Docker 的 Linux 容器里跑。toxiproxy 用它的官方 Docker 镜像。
- 多个 Agent 在同一台机器上同时跑测试,必须互不干扰:
- 测试里的服务一律监听随机端口(`:0`),数据放临时目录,不要写死 7443。
- Docker 容器、网络、卷的名字带上自己的线名前缀,用完删除。
- 不改全局配置:全局 git 配置、系统环境变量、全局 npm 配置都不要动。
- 推送 git.asio.asia 用本机 Windows 凭据管理器里已存好的账号,不要把账号密码写进仓库、脚本或命令行。
- 发布 SDK 包和推送镜像只在阶段 3 做,用 Gitea 个人访问令牌:总控用密码库条目 `git.asio.asia` 的账号在 Gitea 里创建一个只有 `package` 读写权限的令牌,立即存进 MemRelay 密码库,只写进本机用户级配置,不进仓库。
## 4. 协作规则
### 4.1 分支、工作树和提交
- `main` 只由总控合并,任何时候都要能构建、测试全绿。
- 每条线在自己的 git 工作树(worktree)里、自己的分支上工作,不共用目录。Multitask 模式下由总控给每个子 Agent 开独立环境(第 8 节);需要手动建时:
```bash
git fetch origin
git worktree add ../NixMsg-wt/<任务号> -b feat/<任务号>-<简述> origin/main
```
- 分支名:`feat/<任务号>-<简述>`,例如 `feat/n2-websocket-mochi`;修别人发现的问题用 `fix/<任务号>-<简述>`。
- 一功能一验证一提交:做完一个能验证的小功能,就补测试、跑 `task check`、提交,并推送到自己的远端分支。
- 提交信息:`type: 中文一句话描述`,type 取 feat、fix、refactor、style、docs、test、chore、revert。
- 不提交:构建产物、`web/dist`、数据库文件、证书和私钥、任何密码或令牌、`aidocs/`。
- 只改自己线负责的目录(第 5 节)。必须动别人的目录时,改动尽量小,并在提交说明和报告里写明。
### 4.2 共享文件
| 文件 | 规则 |
|---|---|
| `go.mod`、`go.sum` | 各线可以加依赖;冲突时以 main 为准重新 `go mod tidy` |
| `internal/protocol` | 总控在阶段 0 定好。之后要改先找总控,由总控改完合进 main,各线再 rebase |
| `internal/store/migrations` | `0001` 由总控在阶段 0 写好,包含全部表。之后要改表结构就加新文件,编号在 rebase 时取当时最大号加一 |
| `cmd/nixmsg/wire.go`(组装各模块) | 各线只加自己的注册代码;冲突时两边都保留 |
| `Taskfile.yml` | 总控维护;各线自己的任务写在 `taskfiles/<线名>.yml`,由主文件引入 |
| `docs/DEVIATIONS.md` | 按线分节,各线只写自己那节 |
| `docs/PRD.md`、`docs/DEVELOPMENT.md`、`docs/TASKS.md` | 开发期间不改 PRD 的产品行为;DEVELOPMENT、TASKS 只有总控能改(例如修正写错的地方),改了什么写进 `docs/DEVIATIONS.md` |
### 4.3 合并进 main
1. 开发线:`git fetch` → `git rebase origin/main` → `task check` 和本任务的验证全过 → 推送分支 → 在 MemRelay 存一个检查点,标签 `ready-to-merge`,写清分支名、任务号、验证结果;Multitask 模式下,同样的内容也写进返回给总控的报告。
2. 总控:按第 7 节清单审阅差异 → 在主工作区 `git merge --ff-only <分支>` → 跑 `task check` 和集成测试 → 推送 main → 通知各线 rebase。
3. 不能快进(main 已经前进)时打回给开发线重新 rebase。冲突由开发线理解双方改动后解决。
4. 功能分支 rebase 后,用 `git push --force-with-lease` 更新自己的远端分支(负责人已同意,见第 9 节)。只能用在自己的 `feat/*`、`fix/*` 分支上,不许用于别人的分支;任何人都不许强推 `main`。
5. 如果仓库开了分支保护或合并请求审核,改成推分支、建合并请求,由总控合并。
6. 本期不做 CI(负责人决定)。合并前的全量验证由总控在本机执行,开发线的自测不能代替。
### 4.4 进度记录
- 各 Agent 按协作规则使用 MemRelay:开工前读项目上下文和最新检查点;完成一个任务、遇到阻塞、结束一次会话时存检查点,写明线名、任务号、分支、做了什么、验证结果、下一步。
- 不在仓库里另建进度文件,免得多条线同时改同一个文件。
## 5. 分工
| 线 | 负责目录 | 主要内容 |
|---|---|---|
| 总控 L | 根目录配置、`cmd/nixmsg/wire.go`、`internal/protocol`、迁移 `0001`、`test/harness`、`docs/` | 阶段 0(派子 Agent 做)、审阅合并、集成验证、最终验收和发布 |
| 平台 P | `cmd/nixmsg`(`wire.go` 除外)、`internal/config`、`internal/store`(`0001` 除外)、`internal/auth` | 配置和命令、写入合并、密码哈希池、令牌和锁定计数、指标注册 |
| 连接 N | `internal/listener`、`internal/broker` | 端口识别、TLS、WebSocket、mochi、登录与会话令牌、连接表、握手 |
| 消息 M | `internal/app/message` | 提交、分发、推送、确认、撤回、回执、清理、启动恢复 |
| 身份 I | `internal/app/identity`、`internal/app/group`、`internal/app/presence` | 注册、自己的资料、对话密码、在线与目录、群、停用和删除 |
| 后台接口 A | `internal/admin`、`internal/httpx` | 管理接口、API 令牌、操作日志、指标接口的访问规则 |
| 后台网页 W | `web/` | Naive UI 后台和端到端测试 |
| SDK 一 S1 | `sdk/go`、`sdk/js` | Go、JS/TS SDK |
| SDK 二 S2 | `sdk/python`、`sdk/java` | Python、Java/Android SDK |
| 测试交付 Q | `test/`(`harness` 除外)、`deploy/`、`README.md` | 测试基础设施、验收用例、弱网和压测、Docker、发布、运维文档 |
## 6. 阶段和任务
```mermaid
flowchart LR
T0[阶段0 总控 骨架与契约] --> P[平台 P]
T0 --> N[连接 N]
T0 --> M[消息 M]
T0 --> I[身份 I]
T0 --> A[后台接口 A]
T0 --> W[后台网页 W]
T0 --> Q[测试交付 Q]
N --> S[SDK S1 S2 接入清单]
M --> S
I --> S
A --> W2[网页联调 W4]
P & N & M & I & A & S & W2 --> V[阶段2 验收 弱网 压测]
V --> Z[阶段3 总控 审核与交付]
```
- **阶段 0**(总控负责,按第 8.2 节分三步派子 Agent 做):T0.1–T0.5。全部合进 main 并推送后才开阶段 1。
- **阶段 1、2**(并行开发、联调和验收):按第 8.2 节分四波,由总控派子 Agent 执行。前两波以各线开发为主,后两波以 SDK 接入清单、端到端测试、验收、弱网和压测为主。每波结束由总控审核、合并、验证;发现的问题开 `fix/` 分支,交回原负责线修。
- **阶段 3**(只有总控):全量回归、审核、偏差确认、打标签交付。
下面每个任务都要做到:代码、测试、文档依据里的规则都满足;验证项全部通过;`task check` 通过。任务说明里的「第 X 节」都指 DEVELOPMENT.md 的小节;指 PRD 或本文的会写明「PRD 第 X 节」「本文第 X 节」。
### 6.1 阶段 0:总控 L
**T0.1 仓库骨架** · 依赖:无
- 做:按 DEVELOPMENT 第 3 节建目录;`go.mod`(模块 `git.asio.asia/nixevol/NixMsg`);`Taskfile.yml`,目标至少有 `build`、`test`、`lint`、`check`(构建加检查加单元测试)、`web:dev`、`web:build`、`itest`(集成测试)、`docker`,并引入 `taskfiles/*.yml`;golangci-lint 配置;`web/` 用 Vite、Vue 3、TypeScript、Naive UI、Vue Router、Pinia 初始化,加 `web/embed.go`;`cmd/nixmsg` 先能 `version`,`serve` 先只打开库、跑迁移、在 `listen` 上提供 `/healthz`,端口为 0 时写 `listen.addr`;`deploy/config.example.yaml`;`.cursor/worktrees.json`,让新工作树自动执行 `go mod download` 和 `pnpm install`。
- 验证:Windows 上 `task check`、`task build` 通过,产物是嵌入了前端的单个可执行文件;在 Docker 的 Linux 容器里 `task check` 也通过。
**T0.2 协议包 `internal/protocol`** · 依赖:T0.1
- 做:DEVELOPMENT 第 6 节全部帧的 Go 类型,包括第 6.9 节注册的请求和响应、`session_token`、`self.logout`;第 6.10 节错误码常量;编码规则(不转义 HTML 和非 ASCII);字段校验(编号规则、正文和自定义字段大小、`send_at_ms` 和 `delay_ms` 互斥);第 7.3 节的请求指纹;整帧字节数计算。
- 验证:每种帧的编码、解码、校验都有表驱动单元测试;指纹对 `meta` 的键顺序不敏感。
**T0.3 数据库结构和存储接口 `internal/store`** · 依赖:T0.1
- 做:第 7.7 节的迁移执行器(有未应用版本时先 `VACUUM INTO` 备份);`0001_init.sql` 包含第 7.7 节全部表和索引;按第 7.7 节的 DSN 打开写连接和读连接池;写入队列的接口(提交一个写操作、拿到结果)和一个先不合并的简单实现,P2 再换成合并提交。
- 验证:空目录启动能建表;重复启动不会重复迁移;迁移前的备份文件存在;有单元测试。
**T0.4 模块接口和管理接口契约** · 依赖:T0.2、T0.3
- 做:`internal/auth` 和 `internal/app/*` 各服务的 Go 接口,以及测试用的假实现;broker 和 app 之间的接口(连接事件、上行帧分发、下行发布);`cmd/nixmsg/wire.go` 组装骨架;`docs/api/admin-api.md`,写清第 8 节每个管理接口的请求、响应、分页和错误格式,W 线据此先用假数据开发。
- 验证:`task check` 通过;契约文档覆盖第 8 节全部路由。
**T0.5 集成测试启动器 `test/harness`** · 依赖:T0.1
- 做:编译一次服务端;每个测试用随机端口、临时目录启动一个进程(配置里 `listen` 的端口写 0,服务端启动后把实际地址写进 `<data_dir>/listen.addr`,见 DEVELOPMENT 第 4.1 节,启动器读它),自动执行 `admin init` 拿到管理员密码;提供管理接口客户端和 MQTT 测试客户端(WebSocket 和 TCP 都支持,能收发第 6 节的帧);另外提供一个命令行启动器(例如 `go run ./test/harness/cmd/testserver`),在随机端口启动服务,把连接地址和管理员密码以 JSON 打到标准输出,收到 Ctrl+C 时退出并清理,给 JS、Python、Java 的集成测试用;测试结束时清理进程和目录。
- 验证:示例集成测试能启动服务、访问 `/healthz`,结束后进程和目录都清干净;两个测试并行跑互不干扰;命令行启动器能打出连接信息,退出后清理干净。
### 6.2 平台 P
**P1 配置和命令** · 依赖:T0.1、T0.3
- 做:第 11.1 节配置的加载和校验(`check-config` 拒绝 `max_body_bytes` 大于 262144);`admin init`、`admin set-password`、`backup`、`healthcheck`;`log/slog` JSON 日志;第 7.8 节的优雅停机。
- 验证:各命令有测试;`admin init` 的密码只在终端打印一次、不进日志,已初始化的库拒绝再次执行。
**P2 写入合并** · 依赖:T0.3
- 做:第 7.2 节的合并事务(最多 256 个操作或凑满 2 毫秒)、每个操作一个 SAVEPOINT、读连接池;写库失败时请求返回 `busy`,`/readyz` 返回失败。
- 验证:单个操作失败只回滚它自己;基准测试给出每秒能提交的写操作数,模拟每秒 200 条消息的写入量时队列不堆积。
**P3 认证工具 `internal/auth`** · 依赖:T0.1
- 做:argon2id 哈希池(第 12 节参数、PHC 格式、并发上限);会话令牌和 API 令牌的生成和哈希;锁定计数器(按键计数、时间窗口、到期解除、手动清除)。
- 验证:单元测试;并发池能限制同时运行的哈希数;锁定窗口到期自动解除。
**P4 指标注册** · 依赖:T0.1
- 做:用 `prometheus/client_golang` 建注册表,定义第 4.3 节列出的指标,给各线打点用;`/metrics` 的处理函数(访问规则由 A 线在路由里加)。
- 验证:单元测试能抓到指标文本。
### 6.3 连接 N
**N1 端口与 TLS** · 依赖:T0.1
- 做:第 4.1–4.3 节和第 4.5 节:首字节识别、TLS 和证书每小时重载、`admin_listen` 分离、通道 Listener、路由骨架、受信任代理的真实 IP。
- 验证:同一端口上明文 HTTP、TLS+HTTP、裸 TCP、TLS+TCP 都能识别;后台分离时的 404 规则;替换证书后新连接用上新证书;声明 ALPN `mqtt` 的客户端能完成握手。
**N2 WebSocket 与 mochi** · 依赖:N1、T0.2、T0.4
- 做:第 4.4 节;第 5 节的装配约束、连接代号、心跳校正、ACL、`OnPublish` 投进每端的串行队列(长度 256,满了形成背压);下行发布(整帧大小检查、QoS 选择、第 7.5 节的大帧并发名额)。
- 验证:浏览器页面从别的域名连 `/mqtt` 成功;子协议不对的连接被关闭;超过客户端上限的下行不发布,并回调上层;QoS 0 的事件不占 inflight。
**N3 登录、会话令牌和握手** · 依赖:N2、P3、T0.3
- 做:第 5 节「登录与会话令牌」和锁定(用 P3 的工具);内部故障时让 `OnConnect` 返回 error;顶号和连接表;第 6.1 节握手(返回 `session_token`、30 秒没握手就断开、没订阅 down 就断开);`self.logout`;`online_since` 和 `offline_since`;把上下线事件交给 I 线。
- 验证:F02 的全部验收(用测试启动器);数据库不可读时客户端连接被直接关闭,而不是收到 `0x86`。
### 6.4 消息 M
**M1 提交** · 依赖:T0.2、T0.3、T0.4
- 做:第 6.2 节和第 7.3 节:先查防重,再校验、查配额、写授权和回复授权,发送时刻已到的立即分发;请求频率桶(第 6.10 节)。
- 验证:表驱动测试覆盖防重命中、冲突、配额、授权、延迟和定时互斥。
**M2 分发与推送** · 依赖:M1、N2
- 做:第 7.4 节和第 7.5 节:调度器、`queue_full`、停用成员、推送窗口、确认计时和两种超时规则、`OnPublishDropped` 后重推、握手和断线时的投递调整、每秒清理循环。
- 验证:F08–F12 的状态机测试和集成测试。
**M3 确认、撤回、回执、状态** · 依赖:M2
- 做:第 6.3 节、第 6.4 节、第 7.6 节:确认、撤回结果的判定、回执写入和推送窗口、`revoked`、`status` 分页、收尾删正文、每小时清理(防重行按条件删、分批删、`wal_checkpoint`)。
- 验证:F13、F14、F18 的测试。
**M4 启动恢复** · 依赖:M2
- 做:第 7.8 节的启动恢复和写库失败处理。
- 验证:推送中杀掉进程再重启,不保留的消息在宽限内重连仍能送到;停机期间到点的定时消息在启动后发出。
### 6.5 身份 I
**I1 注册接口** · 依赖:T0.3、P3、N1
- 做:第 6.9 节:开关、安全码、锁定、跨域、字段规则、`source=self`;`settings` 表读写。
- 验证:F23 的全部验收。
**I2 自己的资料和对话密码** · 依赖:N3、T0.2
- 做:第 6.6 节的 `self.*`(改登录密码时返回新令牌)、`unlock`、授权表(版本、两种授权、回复授权)、按对方计总数的暂停。
- 验证:F15 的全部验收。
**I3 在线与目录** · 依赖:N3
- 做:第 6.5 节:`presence.get`、`presence.watch`(QoS 0 事件)、`directory.list`(分页和 `query`)。
- 验证:F03、F04 的验收。
**I4 群** · 依赖:M1、I2
- 做:第 6.7 节全部帧、群事件、成员上限、加人时的对话密码、退群、踢人、解散、转让,以及第 7.6 节表里的作废规则。
- 验证:F06、F16 的验收。
**I5 停用与删除** · 依赖:M3、I4
- 做:第 7.6 节表里停用、删除端的全部处理(清会话令牌、作废消息、转让群主、清理数据),提供给 A 线调用。
- 验证:F01 里停用和删除相关的验收;删除后用同一编号重新开通,不会串到旧数据。
### 6.6 后台接口 A
**A1 鉴权** · 依赖:T0.3、T0.4、P3
- 做:第 8 节的 Cookie 会话、`X-Nixmsg-Request` 头、管理员登录锁定、API 令牌鉴权和权限限制、令牌管理接口、操作日志。
- 验证:F17 里令牌相关的验收;用令牌调用改管理员密码和令牌管理接口被拒绝。
**A2 端管理** · 依赖:A1、I5、N3
- 做:列表(按来源、在线状态筛选)、开通、CSV 批量开通(整批校验、结果只给一次)、批量停用、启用、删除、编辑、重置密码、踢下线、`unlock`、设置对话密码。
- 验证:F01 的验收;导入 1000 行 CSV 成功。
**A3 其余接口** · 依赖:A1、I1、I4、M3、P4
- 做:注册设置、群管理、记录查询(筛选、分页、响应不含正文)、概览、只读设置、`/metrics` 的访问规则(第 4.3 节)。
- 验证:F17 和 F22 里指标相关的验收;在所有管理接口的响应里搜不到测试正文。
### 6.7 后台网页 W
**W1 框架** · 依赖:T0.1、T0.4
- 做:第 2.4 节的界面要求和 Naive UI 用法;布局、登录页、路由守卫、请求封装(CSRF 头、错误提示)、中文。先按契约用假数据开发。
- 验证:`vue-tsc` 类型检查、ESLint、Vitest 通过;页面在 1366×768 和 1920×1080 下没有重叠和遮挡。
**W2 端管理页** · 依赖:W1
- 做:列表、筛选、多选批量操作、开通和编辑弹窗、CSV 导入和结果下载、重置密码的结果只显示一次、解除锁定、设置对话密码。
- 验证:组件测试;假数据下主流程可用。
**W3 其余页面** · 依赖:W1
- 做:概览、注册设置、群、投递记录、API 令牌(创建后只显示一次)、改管理员密码、只读参数。
- 验证:组件测试;假数据下主流程可用。
**W4 联调和端到端测试** · 依赖:A2、A3
- 做:接真实接口;用 Playwright 走第 13 节的后台主路径(登录、开通、开启注册并设置安全码、建群、看到未完成记录),再加 API 令牌的创建和停用。
- 验证:端到端测试在 `task itest` 里通过。
### 6.8 SDK S1、S2
S1 先做 Go,再做 JS/TS;S2 先做 Python,再做 Java/Android。每种语言都按下面五个任务做,任务号带语言,例如 `S1-GO-1`、`S2-JAVA-3`。
| 任务 | 内容 | 依赖 |
|---|---|---|
| 1 连接和会话 | WebSocket(TCP 可选)、每次连接都带 Clean Start、握手、会话令牌(`onSession`、用令牌重连、`session_invalid`)、退避、停止重连的条件、连接超时 30 秒 | T0.2 |
| 2 收发 | 发送队列(上限 1000、在途 100、`rate_limited` 自动重交、`send_at_ms` 不重算)、去重和再确认、串行回调、自动和手动确认、`revoked`、本地大小检查 | 任务 1 |
| 3 其余接口 | 撤回、状态、回执、在线、目录、订阅、群、`self.*`、`logout`、注册 | 任务 2 |
| 4 接入清单 | 第 9 节的 15 条集成测试,用 T0.5 的启动器起真实服务端 | 任务 3,以及 N3、M3、I2、I4 已合进 main |
| 5 打包和文档 | 按 DEVELOPMENT 第 9 节设置包名、许可证信息和发布配置,用各工具的试运行方式确认能打包(真正发布在 Z3);写这种语言的 README 和最小示例 | 任务 4 |
各语言的要点在 DEVELOPMENT 第 2.3 节和第 9 节:Go 用 `ConnectPacketBuilder` 每次设 Clean Start;JS 同时支持浏览器和 Node,发 ESM 和 CJS,要测跨域;Python 同步为主,另给 asyncio 包装;Java 编译成 Java 8 字节码,写清 Android API 24 的用法。
### 6.9 测试交付 Q
**Q1 测试基础设施** · 依赖:T0.5
- 做:toxiproxy 和 netem 的 Docker 编排(名字带前缀);1000 连接的压测客户端;验收报告生成(F01–F23 对照表)。
- 验证:能对一个运行中的服务端注入延迟、丢包、断开;压测客户端能保持 1000 个连接。
**Q2 验收用例** · 依赖:各线的核心任务
- 做:PRD 第 10 节每条至少有一个集成测试;各线写过的算数,Q 负责补齐和汇总成报告。
- 验证:报告列出 F01–F23 每条的结果。
**Q3 弱网、崩溃、压测** · 依赖:Q1、Q2
- 做:DEVELOPMENT 第 13 节的全部相关测试,并出报告。
- 验证:报告里的数字满足 PRD 第 8 节。
**Q4 Docker 与发布** · 依赖:T0.1,最终在阶段 2 完成
- 做:第 11.4 节的多阶段、多架构镜像;compose 示例;三个平台的二进制;镜像冒烟测试;推送镜像的 Taskfile 目标(推到 `git.asio.asia/nixevol/nixmsg`,真正推送在 Z3);第 11.3 节 1Panel 证书说明。
- 验证:两个架构的镜像都能初始化、启动、通过健康检查。
**Q5 文档** · 依赖:各线完成
- 做:README(功能、构建、运行)、运维手册(配置、备份、升级、证书、时钟、指标)、SDK 文档汇总。
- 验证:按 README 在一台干净机器上能构建和启动。
### 6.10 阶段 3:总控 L
**Z1 全量回归**:在 main 上跑 `task check`、全部集成测试、端到端测试、四个 SDK 的接入清单、弱网和压测。
**Z2 审核**:按本文第 7 节清单逐项审核;做安全检查(日志和管理接口里没有正文、密码、令牌);检查依赖的许可证。
**Z3 交付**:汇总 `docs/DEVIATIONS.md` 写进交付说明,供负责人回来审阅,不等确认;打 `v0.1.0` 和 `sdk/go/v0.1.0` 标签并推送;按本文第 3 节创建发布令牌,把 npm、PyPI、Maven 三个 SDK 包发布到 Gitea 包仓库,把两个架构的镜像推到 `git.asio.asia/nixevol/nixmsg`(版本号标签和 `latest`);构建三个平台的二进制;写交付说明(功能清单、验收结果、已知问题)。
## 7. 审核清单
总控每次合并前和最终审核时都要过一遍:
- 行为和 PRD 一致,实现和 DEVELOPMENT 一致;不一致的已写进 `docs/DEVIATIONS.md`。
- 没有违反 DEVELOPMENT 第 15 节的任何一条。
- MemRelay 里「依赖库行为核对结论」涉及的点都做对了:`OnConnect` 和 `OnConnectAuthenticate` 的分工、`CodeSuccessIgnore`、下行大小自查、WebSocket 的 Origin 校验、TLS 的 `NextProtos`、每次连接都带 Clean Start。
- 所有写库都走写入队列;条件更新都检查了影响行数。
- 日志、错误信息、管理接口响应里没有正文、密码、令牌和注册安全码。
- 新代码有测试;测试用随机端口和临时目录。
- 没有引入技术栈以外的框架和中间件。
## 8. 负责人操作说明(Cursor Multitask 模式)
负责人只给总控发一段提示词,之后全程自动,不再向负责人提问。总控分波派出子 Agent 并行开发(阶段 0 也由子 Agent 完成),每个子 Agent 在独立的工作树和分支里工作;每波结束由总控审核、合并、验证,最后执行阶段 3 并发布。用本地 Agent:仓库在自建的 Gitea 上,Cursor 的云端 Agent 只支持 GitHub、GitLab 等托管平台,而且用不了本机的 Docker。
### 8.1 负责人要做的
1. 在 Cursor 里新建一个 Agent,模型选 Grok,切到 Multitask 模式,把下面的提示词原样发出,之后就可以离开。
2. 总控不会停下来问你。每完成一波,它会在对话里留一段汇报;它自己拿的主意和与文档不一致的地方都记在 `docs/DEVIATIONS.md`,最后汇总进交付说明,回来后审阅即可。
3. 回来时如果发现它停在半路(例如会话太长被截断、机器重启),新开一个 Multitask 会话再发一次同样的提示词。总控会看 MemRelay 检查点和 git 记录,从断点继续。
4. 并行 N 个子 Agent,用量大约是 N 倍。Cursor 默认整台机器最多保留 25 个工作树,超出会删掉最旧的,所以总控合并后要及时删掉用完的工作树;需要时在设置里调大 `cursor.worktreeMaxCount`。
提示词:
```text
你是 NixMsg 项目的总控 Agent,工作目录 e:\code\NixMsg(仓库 https://git.asio.asia/nixevol/NixMsg.git,主分支 main)。目标:用多个子 Agent 并行,把整个系统开发、测试、发布到交付状态。负责人不在,全程自动完成:中途不要向负责人提问,也不要等回复。
开工前:按协作规则读 MemRelay 项目记忆(项目 NixMsg)和最新检查点,看 git log,再完整阅读 docs/PRD.md、docs/DEVELOPMENT.md、docs/TASKS.md。如果前面的阶段或波次已经完成,从断点继续,不要重做。TASKS.md 第 8.2 节是编排计划,第 8.3 节是子 Agent 提示词模板,第 7 节是审核清单,严格照做。
执行顺序:
1. 按第 8.2 节从阶段 0 开始,一波一波推进。每一波在同一条消息里同时启动这一波的全部子 Agent;每个子 Agent 必须在各自独立的环境里运行(独立工作树和独立分支,each in its own environment),用和你相同的模型;用第 8.3 节模板把它的线、任务、负责目录、要读的文档小节和要返回的内容写清楚,因为子 Agent 看不到你的上下文。子 Agent 报告的工作路径如果是主工作区而不是独立工作树,这一波改为逐个串行执行。
2. 每一波的子 Agent 全部返回后:逐个按第 7 节审核;按第 8.2 节的合并顺序 rebase 后快进合并进 main,每合并一个跑一次 task check,全部合并后跑集成测试,再推送 main。审核或合并不通过的,让原来的子 Agent 接着修(resume),或者新开一个修复子 Agent(fix/ 分支),修好再合并。合并后删掉对应工作树,在 MemRelay 存检查点,在对话里写几句本波汇报(合并了什么、测试结果、遗留问题),然后不要结束,直接进入下一波。
3. 四波都完成后执行阶段 3(Z1–Z3):全量回归、审核,把 DEVIATIONS 汇总进交付说明,打标签、发布 SDK 和镜像、写交付说明。这些全部完成后才结束。
规则:
- 需要拿主意时,按和 PRD、DEVELOPMENT、PRD 第 9 节已确认决定最一致、最稳妥的做法自己决定,写进 docs/DEVIATIONS.md(写明原因和备选方案),不改 PRD 的产品行为。
- 卡住的问题先换思路解决;实在解决不了就记进遗留问题,继续推进其余工作,最后在交付说明里写清楚。
- main 只由你合并,任何时候都要构建和测试全绿;子 Agent 不能再派生子 Agent,只做自己那条线。
- 不做破坏性操作:不删除业务数据和别人的文件,不强推、不改写 main 的历史,要撤销就用 git revert;清理自己建的分支、工作树、容器和测试数据可以直接做。
- 具体的开发、调试、修复都交给子 Agent,你只做编排、审核、合并和验证;少读大段输出,保持自己的上下文精简,避免中途被截断。
```
### 8.2 编排计划(总控照此执行)
| 波次 | 同时启动的子 Agent(线:任务) | 合并顺序 |
|---|---|---|
| 阶段 0 | 分三步,每步合并后再开下一步:先 L:T0.1;再同时 L:T0.2、L:T0.3、L:T0.5;最后 L:T0.4 | 按步骤顺序;第二步里 T0.2 → T0.3 → T0.5 |
| 第 1 波 | P:P1–P4;N:N1–N2;M:M1;I:I1;A:A1;W:W1–W3(用假数据);Q:Q1 和 Q4 的镜像骨架;S1:Go、JS 的任务 1–3;S2:Python、Java 的任务 1–3 | P → N → M → I → A → W → Q → S1 → S2 |
| 第 2 波 | N:N3;M:M2–M4;I:I2–I4;A:A2;Q:已合并功能的验收用例(Q2 的第一部分) | N → M → I → A → Q |
| 第 3 波 | I:I5;A:A3;S1:Go、JS 的任务 4–5;S2:Python、Java 的任务 4–5;Q:补齐 Q2,做 Q3 | I → A → S1 → S2 → Q |
| 第 4 波 | W:W4;Q:Q4 定稿、Q5 | W → Q |
| 阶段 3 | 总控负责 Z1–Z3:回归中发现的问题派修复子 Agent(`fix/` 分支),打标签、发布等收尾由总控执行 | — |
- 每一波只依赖之前已经合进 main 的成果。同一波里依赖别的线还没合并的功能时(例如第 1 波的 A1、I1 用到 P3、N1,第 2 波的 I2、I3 用到 N3,A2 用到 I5),先用 T0.4 的接口和假实现写代码和单元测试,合并时由总控接上真实实现;需要真实实现的集成测试放到下一波补上。
- 同一波的子 Agent 互相看不到对方的改动,只能看到这一波开始时的 main。
- 每个子 Agent 做完先推送自己的分支、确认工作区干净,再返回报告。
- 同一波子 Agent 太多、机器吃不消时,分两批启动,合并顺序不变。
### 8.3 子 Agent 提示词模板(总控把花括号换成具体内容再发)
```text
你是 NixMsg 的开发线 {线名} 子 Agent,在自己独立的工作树和分支上工作,起点是 origin/main 的最新提交,分支按 feat/{任务号}-{简述} 命名。你看不到之前的对话,需要的信息都在仓库文档和 MemRelay 项目记忆(项目 NixMsg)里。
先读:docs/TASKS.md 第 3、4、5 节和第 6 节里 {任务号} 的说明;docs/DEVELOPMENT.md 的 {相关小节};docs/PRD.md 的 {相关功能编号};.cursor/rules/nixmsg-dev.mdc。
要做:按顺序完成 {任务号},只改 {负责目录}。这一波里别的线还没合并的功能,用 T0.4 的接口和假实现。
规则:一功能一验证一提交(补测试 → task check 通过 → 提交 → 推送自己的分支);提交信息用「type: 中文一句话」;测试用随机端口和临时目录;缺工具用 scoop 安装;实现和文档不一致的,写进 docs/DEVIATIONS.md 你那一节;不能再派生子 Agent;文档没写清或有疑问时,按和 PRD、DEVELOPMENT、PRD 第 9 节已确认决定最一致的做法实现,写进 DEVIATIONS 你那一节和报告,不要停下来等回复,也不要改 PRD;不做破坏性操作(不删别人的文件和数据,不碰 main)。
完成后返回:1)分支名和工作树路径;2)提交列表;3)每个任务的完成情况、验证命令和结果;4)写进 DEVIATIONS 的内容;5)没做完或拿不准的地方。返回前确认分支已推送、工作区干净。
```
## 9. 负责人已确认的协作事项
- 2026-09-30:允许各开发 Agent 在 rebase 后用 `git push --force-with-lease` 更新自己的 `feat/*`、`fix/*` 远端分支;`main` 任何时候都不许强推。
- 2026-09-30:SDK 发布到 Gitea 包仓库,镜像推到 `git.asio.asia/nixevol/nixmsg`;本期不做 CI;许可证为专有,源码仓库和发布物公开可读(DEVELOPMENT 第 2.1 节、第 9 节、第 11.4 节)。
- PRD 第 9 节的默认规则 D1–D33 已全部确认,开发中不再等待确认;和文档不一致的实现按第 4.2 节写进 `docs/DEVIATIONS.md`。
- 2026-09-30:负责人授权全程自动开发。开发、测试、发布过程中不向负责人提问、不等回复;需要拿主意时,按和 PRD、DEVELOPMENT、已确认决定最一致、最稳妥的做法自己定,写进 `docs/DEVIATIONS.md`(原因和备选方案),不改 PRD 的产品行为;不做破坏性操作;解决不了的问题记进遗留问题,继续推进其余工作。