381 lines
9.2 KiB
Markdown
381 lines
9.2 KiB
Markdown
# Inbox V2 P1
|
||
|
||
本文档定义 `inbox v2` 的 `P1` 范围。
|
||
`P1` 只包含“独立模块”。
|
||
|
||
这里的独立模块,不是指“所有包彼此完全隔离”,而是指:
|
||
|
||
- 不依赖 `store`、`runtime`、`agent runner`、`HTTP route`、`app service`
|
||
- 可以单独实现、单独测试
|
||
- 可以作为后续 `HTTP`、`app service`、`store`、`client` 的公共基础
|
||
- 允许按分层方向依赖更底层的 `P1` 模块
|
||
|
||
换句话说:
|
||
|
||
- `P1` 要先固定“底层规则和模型”
|
||
- `P1` 不要先混入“流程装配和基础设施”
|
||
- `P1` 内部允许存在清晰的自底向上依赖
|
||
|
||
`P1` 的目标不是先把服务跑起来,而是先把最底层、最稳定、最可复用的规则和模型固定下来。
|
||
|
||
数据库设计草案见 [docs/inbox-v2-database.md](./inbox-v2-database.md)。
|
||
|
||
## 背景
|
||
|
||
`inbox v2` 的主线已经明确:
|
||
|
||
- `HTTP` 是唯一业务入口
|
||
- `server` 是唯一正式启动入口
|
||
- `CLI` 只是给 AI 使用的 `HTTP` 封装
|
||
- `clarifier` 角色移除
|
||
- `product` 接管需求整理,并继续输出:
|
||
- `PRD`
|
||
- `Decision Log`
|
||
- `discovery` 保留
|
||
- 交互路径暂时保持:
|
||
- discovery
|
||
- 需求整理
|
||
- pool
|
||
- workflow
|
||
|
||
在这条主线下,最先该实现的不是 server,也不是 client,而是底层独立模块。
|
||
|
||
## P1 设计原则
|
||
|
||
1. `P1` 模块必须独立于基础设施层,但允许依赖更底层的 `P1` 模块。
|
||
2. `P1` 模块优先承载“稳定规则”,而不是“流程编排”。
|
||
3. `P1` 模块一旦定型,后续 `P2/P3` 都应复用它们,而不是复制一份。
|
||
4. `P1` 模块必须有单元测试。
|
||
5. `P1` 不实现 HTTP route、不实现 runtime 装配、不实现数据库。
|
||
|
||
## P1 分层
|
||
|
||
为了让后续实现可落地,`P1` 采用下面这套分层:
|
||
|
||
| 层级 | 类型 | 可以依赖 |
|
||
| --- | --- | --- |
|
||
| `L0` | 基础工具 | Go 标准库 |
|
||
| `L1` | 文档规范 | `L0` + Go 标准库 |
|
||
| `L2` | 核心领域 | `L0/L1` + Go 标准库 |
|
||
| `L3` | 领域组合规则 | `L0/L1/L2` + Go 标准库 |
|
||
|
||
约束只有一条:
|
||
|
||
- 依赖只能向下,不能横向乱连,更不能回依赖 `P2/P3`
|
||
|
||
## P1 模块清单
|
||
|
||
下面这些是 `inbox v2` 第一阶段应先落下的独立模块。
|
||
|
||
| 模块 | 建议路径 | 作用 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| 时间模块 | `internal/base/timeutil` | UTC 时间、标准时间格式、可注入 clock | 给记录、文档更新时间、事件时间统一格式 |
|
||
| 标识符模块 | `internal/base/idgen` | topic / message / requirement / merge request 等 ID 生成规则 | 先固定命名和生成策略 |
|
||
| slug 模块 | `internal/base/slug` | topic、workspace、project 的 slug 规范化 | 这是所有上层都会复用的基础规则 |
|
||
| HTTP 通用模块 | `internal/base/httpx` | 状态错误、JSON 编解码、通用响应封装 | 只做 transport 基础工具,不做具体业务 |
|
||
| 文档模板模块 | `internal/domain/docspec` | `PRD`、`Decision Log`、Discovery request/result 的模板与渲染规则 | `product` 将直接依赖它 |
|
||
| 消息模块 | `internal/domain/message` | message envelope、front matter 解析、渲染、收件人规则 | 统一所有消息文档格式 |
|
||
| Topic 模块 | `internal/domain/topic` | topic 的 space/status 生命周期规则 | 明确 clarify/pool/workflow/discovery 的推进规则 |
|
||
| Role 模块 | `internal/domain/role` | 角色分类、角色定义、角色能力边界 | 包括 `product`、`backend`、`frontend`、`reviewer`、discovery 系列 |
|
||
| Requirement 模块 | `internal/domain/requirement` | requirement 的结构、状态、优先级与验证规则 | pool 的结构化实体先独立出来 |
|
||
| Discovery 模块 | `internal/domain/discovery` | discovery 提案、投票、共识计算、结果文档规则 | 保留 discovery 的核心领域逻辑 |
|
||
| Workflow 模块 | `internal/domain/workflow` | workflow 阶段枚举、阶段合法流转、角色协作规则 | 只管规则,不管看板聚合 |
|
||
| Merge 模块 | `internal/domain/merge` | merge request 状态、元数据结构、状态流转规则 | 只管领域规则,不管 git 命令 |
|
||
|
||
## P1 依赖关系
|
||
|
||
下面是建议的依赖方向。
|
||
|
||
| 模块 | 层级 | 可依赖模块 |
|
||
| --- | --- | --- |
|
||
| `timeutil` | `L0` | 无 |
|
||
| `slug` | `L0` | 无 |
|
||
| `idgen` | `L0` | `timeutil`, `slug` |
|
||
| `httpx` | `L0` | 无 |
|
||
| `docspec` | `L1` | `timeutil` |
|
||
| `role` | `L2` | 无 |
|
||
| `topic` | `L2` | `slug` |
|
||
| `workflow` | `L2` | `role`, `topic` |
|
||
| `requirement` | `L2` | `slug` |
|
||
| `merge` | `L2` | `timeutil`, `idgen`, `slug` |
|
||
| `message` | `L3` | `role`, `topic`, `workflow`, `slug`, `timeutil` |
|
||
| `discovery` | `L3` | `role`, `docspec`, `idgen`, `timeutil`, `slug` |
|
||
|
||
这张表的意义是:
|
||
|
||
- `P1` 仍然是独立模块集合
|
||
- 但不是人为禁止复用
|
||
- 后续实现时可以从 `L0` 往上逐层推进
|
||
|
||
## P1 模块详细职责
|
||
|
||
### 1. `timeutil`
|
||
|
||
负责:
|
||
|
||
- `NowUTC()`
|
||
- RFC3339 / RFC3339Nano 格式化
|
||
- 可注入 clock
|
||
|
||
不负责:
|
||
|
||
- 调度
|
||
- 轮询
|
||
- timeout 策略
|
||
|
||
### 2. `idgen`
|
||
|
||
负责:
|
||
|
||
- message ID 规则
|
||
- requirement ID 规则
|
||
- merge request ID 规则
|
||
- discovery round ID / candidate ID 规则
|
||
|
||
不负责:
|
||
|
||
- 数据库存储
|
||
- 去重查询
|
||
|
||
### 3. `slug`
|
||
|
||
负责:
|
||
|
||
- topic slugify
|
||
- workspace slugify
|
||
- project slugify
|
||
- 安全截断规则
|
||
|
||
不负责:
|
||
|
||
- 校验是否重名
|
||
- 路径解析
|
||
|
||
### 4. `httpx`
|
||
|
||
负责:
|
||
|
||
- `WriteJSON`
|
||
- `WriteError`
|
||
- `ErrorWithStatus`
|
||
- 通用 JSON decode 辅助
|
||
- CORS 等通用 transport helper
|
||
|
||
不负责:
|
||
|
||
- route 注册
|
||
- 业务 request/response
|
||
|
||
### 5. `docspec`
|
||
|
||
这是 `P1` 里非常关键的模块。
|
||
|
||
负责:
|
||
|
||
- `PRD` 模板
|
||
- `Decision Log` 模板
|
||
- Discovery request 文档格式
|
||
- Discovery result 文档格式
|
||
- 文档 front matter 规范
|
||
- 文档固定章节顺序
|
||
|
||
不负责:
|
||
|
||
- 文档存储
|
||
- 文档版本管理
|
||
- 文档归属权限
|
||
|
||
这里要明确:
|
||
|
||
- 第二版中 `product` 会直接使用 `PRD` 和 `Decision Log`
|
||
- 模板沿用当前澄清模板,但所有权从 `clarifier` 转到 `product`
|
||
|
||
### 6. `message`
|
||
|
||
负责:
|
||
|
||
- message envelope 结构
|
||
- YAML front matter 解析
|
||
- markdown 渲染
|
||
- `from / to / type / topic / stage / reply_to / round` 规则
|
||
- 收件人解析
|
||
- 基础合法性校验
|
||
- 面向消息文档的稳定结构定义
|
||
|
||
不负责:
|
||
|
||
- 消息存储
|
||
- mailbox 查询
|
||
- HTTP handler
|
||
|
||
### 7. `topic`
|
||
|
||
负责:
|
||
|
||
- topic `space`
|
||
- `clarify`
|
||
- `pool`
|
||
- `workflow`
|
||
- `discovery`
|
||
- topic `status`
|
||
- space/status 的默认值
|
||
- 合法推进规则
|
||
- “能升不能降”之类的基础约束
|
||
|
||
不负责:
|
||
|
||
- topic record 存储
|
||
- topic 列表聚合
|
||
|
||
注意:
|
||
|
||
虽然 v2 去掉 `clarifier` 角色,但 `clarify` 这个对话整理阶段可以在兼容期继续存在;只是它背后的角色从 `clarifier` 变成 `product`。
|
||
|
||
### 8. `role`
|
||
|
||
负责:
|
||
|
||
- 角色枚举和分类
|
||
- 角色合法性校验
|
||
- 角色阶段边界
|
||
- 哪些角色属于 discovery
|
||
- 哪些角色属于 workflow
|
||
- `product` 的正式职责定义
|
||
|
||
不负责:
|
||
|
||
- role 存储
|
||
- role 技能绑定
|
||
|
||
### 9. `requirement`
|
||
|
||
负责:
|
||
|
||
- requirement 结构
|
||
- requirement 状态
|
||
- `pending`
|
||
- `dispatched`
|
||
- `completed`
|
||
- `archived`
|
||
- 优先级范围和校验
|
||
- requirement 文本字段校验
|
||
|
||
不负责:
|
||
|
||
- requirement 查询
|
||
- requirement dispatch 执行
|
||
|
||
### 10. `discovery`
|
||
|
||
负责:
|
||
|
||
- discovery candidate 结构
|
||
- vote 结构
|
||
- 共识判断
|
||
- result markdown 生成
|
||
- discovery request 文本格式规则
|
||
- discovery 阶段的固定角色集合规则
|
||
|
||
不负责:
|
||
|
||
- 并发执行
|
||
- codex 调用
|
||
- round 持久化
|
||
|
||
### 11. `workflow`
|
||
|
||
负责:
|
||
|
||
- workflow 阶段枚举
|
||
- `plan`
|
||
- `review`
|
||
- `execution`
|
||
- `verification`
|
||
- workflow 阶段流转规则
|
||
- workflow 角色协作边界
|
||
- workflow 消息的基础规则
|
||
|
||
不负责:
|
||
|
||
- workflow board 聚合
|
||
- dispatch 查询
|
||
|
||
### 12. `merge`
|
||
|
||
负责:
|
||
|
||
- merge request 结构
|
||
- merge request 状态流转
|
||
- merge metadata 规则
|
||
|
||
不负责:
|
||
|
||
- git diff
|
||
- merge 命令执行
|
||
|
||
## P1 明确不做的东西
|
||
|
||
下面这些不属于 `P1`:
|
||
|
||
- `server`
|
||
- `client`
|
||
- `http route`
|
||
- `app service`
|
||
- `store`
|
||
- `runtime`
|
||
- `agent runner`
|
||
- `workflow board`
|
||
- `pool dispatch`
|
||
- `merge` 的 git 执行
|
||
|
||
这些模块都依赖更高层或外部设施,不属于独立底层模块。
|
||
|
||
## P1 实现顺序
|
||
|
||
建议顺序如下:
|
||
|
||
1. `timeutil`
|
||
2. `slug`
|
||
3. `idgen`
|
||
4. `httpx`
|
||
5. `docspec`
|
||
6. `role`
|
||
7. `topic`
|
||
8. `workflow`
|
||
9. `requirement`
|
||
10. `merge`
|
||
11. `message`
|
||
12. `discovery`
|
||
|
||
原因很简单:
|
||
|
||
- 先做通用基础能力
|
||
- 再做文档规范
|
||
- 再做核心领域规则
|
||
- 最后做组合型领域模块
|
||
- 最后才进入 `P2` 的 `server/app/store`
|
||
|
||
## P1 输出结果
|
||
|
||
`P1` 完成后,应该得到这些结果:
|
||
|
||
1. 一组独立于基础设施的底层模块。
|
||
2. 一组稳定的领域结构、模板和状态流转规则。
|
||
3. 第二版可以明确复用的文档标准:
|
||
- `PRD`
|
||
- `Decision Log`
|
||
- Discovery request
|
||
- Discovery result
|
||
4. 一套从 `L0 -> L3` 的清晰依赖方向。
|
||
5. 后续 `P2` 实现 `HTTP server` 和 `app services` 时,不再需要重新发明这些规则。
|
||
|
||
## P1 完成标准
|
||
|
||
满足下面条件,`P1` 才算完成:
|
||
|
||
1. 上述每个模块都有明确目录。
|
||
2. 每个模块都有单元测试。
|
||
3. 每个模块都只依赖下层 `P1` 模块,不依赖任何 `P2/P3` 模块。
|
||
4. 文档模板和领域规则已经固定。
|
||
5. `product` 接管需求文档这一决策已经在底层模型中可以表达。
|