chore(repo): reinitialize repository

This commit is contained in:
2026-03-18 11:29:54 +08:00
commit 24871e213a
288 changed files with 44369 additions and 0 deletions
+648
View File
@@ -0,0 +1,648 @@
# Lane Worktree 物化与代码流转改造计划
本文档定义 `inbox v2``lane -> worktree -> runtime` 的代码流转改造方案。
目标很明确:
- 保留 `lane` 级隔离执行能力
- 让下游 `lane` 能消费上游 `lane` 的真实代码产物
- 避免 worker summary 充当“伪代码同步”
- 逐步把当前执行模型修正为“依赖图 = 代码图”
本文档按阶段拆分,便于逐步实现和回归。
## 背景
当前系统已经把术语统一到 `lane`,但运行时还存在一个关键缺口:
- `leader` 规划出 task DAG
- 系统按 task 依赖自动派生 execution lanes
- 每个 `lane` 都有独立 `worktree``podman` 容器
- 但跨 `lane` 的依赖目前只传递 worker summary,不传递代码
这会导致一个结果:
- 调度层认为 `Task B` 依赖 `Task A`
- 运行层却没有把 `Task A` 的代码产物同步给 `Task B`
- `Task B` 只能在自己的空 worktree 里“重建”上游结果
这不是真正的依赖执行,而是“读摘要后重写”。
## 真实问题示例:`todo-lane-smoke-2`
`todo-lane-smoke-2` 的 task 图如下:
1. `Scaffold full-stack project structure`
2. `Implement Todo API with SQLite`
3. `Implement React Todo UI`
4. `Integrate stack and verify runnable demo`
5. `Todo demo ready for review`
其依赖关系如下:
- `Scaffold full-stack project structure`:根任务
- `Implement Todo API with SQLite`:依赖 `Scaffold`
- `Implement React Todo UI`:依赖 `Scaffold`
- `Integrate stack and verify runnable demo`:依赖 `Backend API` + `Frontend App`
- `Todo demo ready for review`:依赖 `Integrate`
当前系统会把它派生成 4 条 execution lanes
- `Foundation Setup`
- `Backend API`
- `Frontend App`
- `Integration And Verification`
问题在于:
- `Backend API``Frontend App` 在各自 worktree 中写代码
- `Integration And Verification` 也在自己的 worktree 中执行
- 但它拿不到前两个 lane 的真实代码,只能拿到消息摘要
这意味着 `Integration` 不是在“上游代码之上做集成”,而是在“读了两段总结之后重新拼代码”。
## 总目标
实施完成后,系统应满足以下条件:
- 每个代码型 `lane` 都有可复用的 git 产物,而不是只有未提交改动
- 下游 `lane` 启动前可以显式物化上游 `lane` 的代码输入
- `lane` 之间的依赖关系能在 git 历史中体现出来
- merge 冲突会显式阻塞执行,而不是被摘要绕过
- `milestone` / `gate` 不再滥用独立 worktree
- `lane` 是“代码演进线”,不是“任意 task 容器”
## 术语
本文统一使用以下术语:
- `lane`:执行泳道,代表一条相对连续的代码演进线
- `worktree`:该 `lane` 对应的 git 工作目录
- `runtime`:该 `lane` 对应的容器与 worker 进程
- `snapshot`:某个 `lane` 在成功完成代码任务后的已提交 git 状态
- `materialization`:将上游 `lane` 的代码输入同步到当前 `lane`
## 设计原则
### 1. 代码依赖必须用代码流转表达
只要下游 task 需要基于上游代码继续开发、联调、验证,就必须物化上游代码,而不是只传摘要。
### 2. lane 隔离要保留,但不能成为代码孤岛
`lane` 的价值是隔离并行开发,不是让每个 worker 在自己的平行宇宙里重写同一份实现。
### 3. 失败要显式
如果下游 lane 在物化上游代码时发生 merge 冲突,应显式标记 `blocked`,并触发 replan 或人工介入。
### 4. 优先 clean replacement,不做兼容分叉
不增加“新老同步方式同时存在”的运行时兼容逻辑。
应使用显式 schema / 数据迁移把新模型落下。
### 5. runtime 职责保持窄边界
- `workspaceruntime` 负责 ensure worktree / container
- `taskexec` 负责调度与状态推进
- git 产物提交与代码物化应放在单独模块中
不要把代码同步逻辑散落到 handler、runtime、leader prompt 中。
## 非目标
本计划不包含以下内容:
- 多机调度
- 远程仓库 push / pull
- GitHub / GitLab PR 集成
- 二进制产物仓库
- 通用 artifact storage
- 对历史旧 topic 的运行时兼容兜底
## 理想工作流
`todo-lane-smoke-2` 举例,理想形态如下。
### Lane 拆分
保留 4 条 execution lanes,但语义要变:
1. `Foundation Setup lane`
`main` 起步,产出基础脚手架代码快照。
2. `Backend API lane`
`Foundation Setup` 的代码快照起步,负责后端与 SQLite。
3. `Frontend App lane`
`Foundation Setup` 的代码快照起步,负责 React 前端。
4. `Integration And Verification lane`
在开始执行前,先物化:
- `Foundation Setup`
- `Backend API`
- `Frontend App`
然后再做联调、启动脚本、验证、补丁修复。
5. `Todo demo ready for review`
这是 `milestone`,不需要独立 worktree。
### Git 视角下的理想状态
- `Foundation Setup lane` 成功后,lane 分支上至少有一笔提交
- `Backend API lane` 成功后,lane 分支上至少有一笔提交
- `Frontend App lane` 成功后,lane 分支上至少有一笔提交
- `Integration` 开始前,自己的 branch 已显式 merge 上游分支
换句话说,`Integration` 看到的应该是:
- `foundation commit`
- `backend commit`
- `frontend commit`
而不是:
- “Backend worker 说自己完成了”
- “Frontend worker 说自己完成了”
## 当前缺口
### 缺口 1:代码没有被自动提交
当前 worker 执行成功后,代码通常还停留在未提交状态。
这会导致:
- 上游 `lane` 没有稳定的可消费产物
- 下游即使要 merge,也没有明确的输入 commit
### 缺口 2:下游 lane 没有物化步骤
当前 `taskexec` 在给 worker 分配任务前,不会把依赖 lanes 的代码同步进当前 lane。
### 缺口 3merge_request 模型未接入执行主路径
系统里虽然有 `merge_requests` 表和 API,但当前并没有把它们接入 `leaderloop` / `taskexec` 的主执行链路。
### 缺口 4:lane 拆分策略过于宽松
当前 task DAG 会自动派生 lane,但不会约束:
- 哪些任务必须共用 lane
- 哪些任务值得独立 lane
- 哪些节点根本不需要独立 worktree
## 目标架构
建议引入两个新模块和一个新的持久化记录层。
### 模块 A`lanesnapshot`
建议路径:
- `inbox/internal/app/lanesnapshot/`
职责:
- 检查 lane worktree 是否有代码变更
- 过滤不应纳入版本控制的运行时垃圾
- 生成 lane 的提交快照
- 把最新提交记录回 lane 元数据
它不负责:
- 分配任务
- merge 上游 lane
- 启动容器
### 模块 B`lanematerialize`
建议路径:
- `inbox/internal/app/lanematerialize/`
职责:
- 根据 task 依赖关系识别当前 task 的上游 lanes
- 将上游 lane 的最新代码快照同步到当前 lane
- 记录 merge / 物化结果
- 冲突时产生结构化阻塞信息
它不负责:
- 选择哪个 task 该执行
- 自动 replan
- worker prompt 组装
### 模块 Clane 同步记录
建议新增表:
- `lane_syncs`
建议字段:
- `id`
- `workspace_id`
- `topic_id`
- `downstream_lane_id`
- `upstream_lane_id`
- `task_id`
- `upstream_commit`
- `merge_commit`
- `status`
- `error_message`
- `created_at`
- `updated_at`
用途:
- 保证物化过程可观测
- 避免重复 merge 同一输入时缺乏依据
- 为 dashboard / 调试 / 重试提供基础数据
## 数据模型改造
### 阶段性最小变更
在现有 `lanes` 表上新增字段:
- `head_commit TEXT NOT NULL DEFAULT ''`
说明:
- 领域名词与底层表名现在都使用 `lane / lanes`
- 先在现有 `lanes` 表上扩字段,避免一次性大迁移
### 后续可选扩展
如需更强的可观测性,可继续新增:
- `last_materialized_at`
- `last_materialized_commit`
- `last_sync_error`
但这些不是第一阶段必需项。
## 关键执行点
### 1. 成功 task 完成后,自动生成 lane snapshot
建议接入点:
- `inbox/internal/app/taskexec/service.go`
- `Complete(...)` 主路径
顺序建议:
1. worker 返回成功
2. 宿主机确认 lane runtime 与 worktree 可访问
3. `lanesnapshot` 检查并提交 worktree 代码
4. 成功后才真正把 task 标成 `succeeded`
5. 如果提交失败,则这次 run 视为失败或阻塞
原因:
- 一旦 task 已被标成成功,但代码并未形成稳定快照,下游 lane 仍然无法消费
- 所以“成功完成 task”的定义应当包含“代码产物已稳定落盘到 git”
### 2. 下游 task 被 claim 前,先做 lane materialization
建议接入点:
- `inbox/internal/app/taskexec/service.go`
- `ClaimNext(...)` 主路径
顺序建议:
1. 找到当前 lane 中下一个 ready task
2. 识别其依赖 tasks
3. 推导依赖 tasks 所属的上游 lanes
4. `lanematerialize` 将上游 lane commits 同步到当前 lane
5. 同步成功后再真正 claim task
6. 如冲突,则不 claim,改为 `blocked`
原因:
- worker 启动时就应该处于“已拿到所有上游代码输入”的环境
- 不要把 merge 责任甩给 worker
### 3. `workspaceruntime` 不做业务同步
`workspaceruntime` 继续只负责:
- ensure repository
- ensure worktree
- ensure container
- stop container
不要把以下逻辑塞进去:
- 依赖 lanes 分析
- 自动 commit
- 自动 merge
- 冲突策略判断
## 推荐 merge 策略
第一版建议使用最朴素、最可审计的策略:
- 上游 lane 产物必须先成为 git commit
- 下游 lane 物化时使用显式 `git merge`
- 保留 merge commit,不做 squash
原因:
- 依赖关系能在历史中直接看见
- 调试时容易定位是哪条 lane 带进来的改动
- 比起复制文件或 patch 应用,git merge 更符合当前 worktree 模型
### 合并顺序
建议按依赖拓扑顺序进行 merge。
`Integration And Verification` 为例,建议顺序:
1. `Foundation Setup`
2. `Backend API`
3. `Frontend App`
如果 `Backend``Frontend` 都已经是从 `Foundation` 分化出来的,并且各自分支历史完整,也可以只 merge 最终两个分支,由 git 自动通过共同祖先处理基础提交。
第一版不要求做最优优化,要求的是语义正确和行为稳定。
### 冲突处理
发生冲突时:
- 停止当前 materialization
- 记录 `lane_syncs.status = failed`
- task 标记为 `blocked`
- lane 可标记为 `blocked`
- 通过 message 或 task event 通知 leader
不要做以下行为:
- 自动硬解冲突
- 静默 fallback 为“只读摘要继续执行”
- 自动丢弃上游改动
## lane 拆分策略建议
除了代码流转,lane 数量本身也要更收敛。
### 应当独立 lane 的情况
- 明确并行价值高
- 文件边界清晰
- 预期实现时间较长
- 失败隔离有意义
- 产物可以作为其他 lane 的明确输入
### 应当共用 lane 的情况
- 前后两个 task 本质上是同一条连续实现链
- 第二个 task 高度依赖第一个 task 的局部未抽象代码
- 拆开后只会制造频繁 merge 和冲突
### 不应拥有独立代码 lane 的情况
- `milestone`
-`gate`
- 单纯汇报 / 审阅 / 总结型节点
## 分阶段实施
### 阶段 0:基线梳理与命名统一
目标:
- 明确以 `lane` 为统一术语
- 建立当前缺口的自动化验证样例
实现内容:
- 文档统一使用 `lane`
-`todo-lane-smoke-2` 这类场景补回归测试描述
- 梳理现有旧命名残留,不要求立刻全量改名
验收标准:
- 团队对外讨论统一使用 `lane`
- 有一份可复现“下游 lane 看不到上游代码”的基线案例
### 阶段 1lane snapshot 落地
目标:
- 成功的代码型 task 必须沉淀为 lane 分支上的 commit
实现内容:
-`lanes` 表新增 `head_commit`
- 新增 `lanesnapshot` 模块
- 在 task 成功完成路径中自动:
- 检查 worktree dirty 状态
- 执行 `git add`
- 执行 `git commit`
- 写回 `head_commit`
建议约束:
- 只对 `execution` / `verification` 这类代码型 task 做 snapshot
- `milestone` / `gate` 不生成代码提交
验收标准:
- `todo-lane-smoke-2``foundation` / `backend` / `frontend` 成功后,各自 lane 均有非空 `head_commit`
- worktree 不再只停留在未提交改动
### 阶段 2:下游 lane materialization
目标:
- 下游 lane 能在 worker 执行前拿到上游 lane 的真实代码输入
实现内容:
- 新增 `lanematerialize` 模块
- 新增 `lane_syncs`
-`ClaimNext(...)` 中对 candidate task 执行 materialization
- materialization 成功后才 claim task
验收标准:
- `Integration And Verification` 在执行前能看到 `Backend API``Frontend App` 的真实代码
- 回归时不再依赖 worker summary 重建实现
### 阶段 3:阻塞与 replan 闭环
目标:
- merge 冲突成为受控状态,而不是隐性失败
实现内容:
- 统一 materialization failure 到 `blocked`
- 增加 task event / message,向 leader 报告冲突
- leader 收到冲突后走 patch replan
验收标准:
- 冲突 topic 会稳定停在 `blocked`
- leader 能基于冲突信息重新编排,而不是盲目新起 lanes
### 阶段 4:lane 拆分规则收紧
目标:
- 减少不必要的 lane / worktree / container 增生
实现内容:
- 调整 leader prompt 与 lane 派生规则
- 倾向于把连续实现链保留在同一 lane
- 仅在明确并行或集成汇聚点时拆新 lane
- `milestone` / `gate` 不派生代码 lane
验收标准:
- 类似 `todo-lane-smoke-2` 的 topic 中,lane 数量与实际代码边界一致
- 不再出现“为了一个收口任务额外生成空 lane”的情况
### 阶段 5:可观测性与回收策略
目标:
- 让 lane 运行时资源与代码同步状态都可追踪、可回收
实现内容:
- dashboard 展示:
- `head_commit`
- 最新 materialization 状态
- lane sync 历史
- topic 完成后可选执行:
- 停止 lane runtime
- 延迟回收容器
- 延迟清理 worktree
说明:
- 本阶段是运维优化,不阻塞前四阶段主路径落地
验收标准:
- topic 完成后不再长期残留无意义运行中的 lane runtime
- 调试时能直接看到 lane 的代码输入输出链路
## 需要修改的主要模块
### 必改
- `inbox/internal/app/taskexec/service.go`
- `inbox/internal/store/sqlite/taskexec_store.go`
- `inbox/internal/store/sqlite/migrations/`
- `inbox/internal/domain/lane/`
### 新增建议
- `inbox/internal/app/lanesnapshot/`
- `inbox/internal/app/lanematerialize/`
- `inbox/internal/domain/lanesync/`
- `inbox/internal/store/sqlite/lane_syncs_store.go`
### 暂不建议承载业务逻辑的模块
- `inbox/internal/app/workspaceruntime/`
- `inbox/internal/httpapi/`
- `inbox/internal/app/leaderloop/`
这些模块可以消费结果,不应承担主要 git 业务逻辑。
## 测试建议
### 单元测试
- snapshot 成功创建提交
- worktree 无变化时不重复提交
- materialization 能识别依赖 lanes
- materialization 在冲突时稳定失败并写入 `blocked`
### 集成测试
`todo-lane-smoke-2` 类型流程验证:
1. `Foundation Setup` 成功后生成 commit
2. `Backend API` / `Frontend App` 都从基础快照继续开发
3. `Integration` 在启动前合并上游代码
4. `milestone` 自动完成且不新建代码 lane
### 回归重点
- 不能破坏当前单 lane 串行执行
- 不能让 `gate` / `milestone` 意外触发 git commit
- 不能把未提交脏状态错误标记成“已可下游消费”
## 开放问题
### 1. 自动提交的粒度
第一版建议:
- 每个成功 task 最多生成一笔提交
不建议第一版支持:
- 一个 task 内自动切多笔提交
### 2. merge 粒度是按 task 还是按 lane
第一版建议按 `lane` 的最新成功快照物化。
原因:
- 实现简单
- 与当前 runtime 粒度一致
- 更符合“lane 是代码演进线”的模型
### 3. 是否必须使用 merge request 模型
第一版不必强制接入 `merge_requests`
建议先把:
- 真实 commit 产物
- lane materialization
- 冲突阻塞
这三个核心闭环做完。
之后再决定是否把 `merge_requests` 升级成:
- lane 间同步记录
- 人工审批面板
- 最终 topic 合并机制
## 最小可上线版本
如果只做最小闭环,建议范围如下:
1. `lanes.head_commit`
2. 成功 task 后自动提交
3. `ClaimNext` 前 merge 上游 lane commits
4. merge 冲突时标记 `blocked`
做到这一步,系统就已经从“摘要依赖”升级成“代码依赖”。
## 结论
这次改造的本质,不是“再加一个 merge 功能”,而是修正整个 lane 执行模型的语义:
- 上游 `lane` 的产物应该是代码快照
- 下游 `lane` 的输入应该是上游代码状态
- worker summary 应回归为编排证据,而不是代码同步手段
`todo-lane-smoke-2` 这样的 DAG 来说,这不是优化,而是让系统终于按自己宣称的依赖关系去工作。