任务执行模型
本文说明 ArchSpine 当前如何运行 scan、check、fix 和 sync。 目标是在保持现有产品形态的前提下,让运行模型尽量确定、可组合、可维护:
- CLI 仍然是入口
- service 层负责编排与生命周期
- task 只做单一阶段的工作
- 共享状态被收紧,而不是继续当作隐式数据总线
为什么需要这份说明
ArchSpine 的目标是把仓库语义做成显式、可治理的控制面。 因此,执行模型也应该遵循同样的原则,而不是依赖一条松散的隐式流水线。
这种模型主要避免这些风险:
- task 之间的顺序耦合
- 对可变共享状态的隐式依赖
- 重试时把旧运行数据带回下一轮
- 运行逻辑难以复用到其他入口
当前模型
1. 阶段输入和输出是显式的
每个 task 都接收一个有类型的输入,并返回一个有类型的输出。
这意味着某个 pipeline 步骤依赖上一步时,依赖关系写在数据契约里,而不是写在“大家都记得要先改某个共享对象”这种约定里。
例如:
scan产出文件选择结果,供提取阶段使用- AST 提取产出 skeleton 和支持信息,供 summarize 与 validate 使用
- summarize 产出待提交信息,供 state commit 使用
- state commit 产出已提交的选择结果,供 reverse index 与 aggregation 使用
- fix 显式消费 violations,并返回需要复检的文件集合
2. TaskContext.state 只保留 telemetry
共享的 state 现在只用于执行遥测:
- usage 计数
- warning 记录
- diagnostics 快照
它不再是 pipeline 数据流转的主通道。
3. TaskContext.runtimeCache 保存临时产物
有些 task 在单次运行里仍然需要短生命周期的运行时产物。
这些内容现在放在 runtimeCache,而不是 state 里:
- file skeletons
- unsupported file 标记
- pending commit 缓冲
runtimeCache 被视为运行期缓存,不是 pipeline 契约本身。
4. service 负责编排
check-service、sync-service 和 fix-service 负责决定:
- 哪些 task 要执行
- 每个 task 接收什么显式输入
- 重试时如何重置
- 何时获取或释放锁
这样编排逻辑就不会散落在 task 内部。
5. CLI 保持轻薄
CLI 只负责解析参数、选择 service、呈现用户输出。 它不应该承担 pipeline 规则、阶段串联或重试状态的职责。
当前流水线形态
现在主链已经是显式流:
scan -> ast -> validatescan -> ast -> summarize -> state-commit -> reverse-index -> aggregationviolations -> fix -> recheck scan -> revalidate
这是有意设计的。 这条链更像数据流,而不是一串副作用。
这带来的收益
- 步骤之间的隐藏耦合更少
- 每个阶段更容易单测
- 重试行为更清晰
- 后续做 server 或 daemon 入口更简单
- 新增 task 的风险更低
不要做的事
不要把旧的隐式模式加回来。
- 不要再通过
TaskContext.state上的临时字段传递新的 pipeline 信息 - 不要让 task 依赖未显式写进输入类型的前序副作用
- 不要把
runtimeCache当成跨阶段契约 - 不要把 CLI 交互塞回 task 逻辑里,能放到 runtime I/O 或 service 层的就不要放进 task