Dev Flow 架构

August 31, 2026 · View on GitHub

中文 | English

设计目标

Dev Flow 的架构围绕一个原则展开:过程事实只保存一次。Go Core 管理 Task、状态图、流转、 证据、恢复和终态;Codex 与 DeepSeek 负责把 Host 能力接到这个权威上。

flowchart TB
    U[Developer] --> H[Codex / DeepSeek Adapter]
    H --> M[Local STDIO MCP · 15 tools]
    M --> A[Application Service]
    A --> W[Workflow Engine]
    A --> R[Recovery]
    A --> G[Read-only Git Observer]
    W --> D[Domain Aggregate]
    R --> D
    G --> B[Repository Binding]
    A --> S[(SQLite Store)]
    D --> S
    B --> S

组件职责

Host Adapter

packages/codex/packages/deepseek/ 负责:

  • 显式进入 Dev Flow;
  • 启动 packaged Core 并完成 capability handshake;
  • 呈现当前节点、合法 transitions 与理解审查请求;
  • 把 semantic method steps 映射为 Host 中可用的操作;
  • 按当前 Action 的 submission_tool 提交节点结果;
  • 在不确定 mutation 后保留 Task ID 与 Action ID,并读取 Core 保存的规范化提交后恢复。

Adapter 不保存 Task、current node、transition table、baseline、repository claim 或 recovery classification,也不推断 completion 或 destination。

Codex Adapter 的 setup lifecycle 在任何 registration mutation 前创建或验证固定用户配置,并在 registration readback 后从配置与 receipt 的实际写入事实构造 setup result。rich/plain/JSON 只是该 结果的表现层;mcp STDIO、Core 和 DeepSeek Adapter 不参与该展示。

MCP Contract

internal/mcp/ 通过 local STDIO 暴露十五个工具:

dev_flow_server_info
dev_flow_open_task
dev_flow_get_task
dev_flow_get_next_action
dev_flow_submit_requirements
dev_flow_submit_design
dev_flow_submit_tasks
dev_flow_submit_implementation
dev_flow_submit_test
dev_flow_submit_comprehension
dev_flow_submit_refactor
dev_flow_submit_delivery
dev_flow_resolve_blocker
dev_flow_recover_action
dev_flow_cancel_task

每个工具使用 closed JSON Schema 和 typed Result Envelope。Host 首先读取 server info 与 live schema,再进行 task-bearing 调用。

Application Service

internal/application/ 协调 Store、Workflow、Recovery 和 Repository Observer。它负责 use case 顺序、事务输入与投影,不维护第二份流程定义。

Workflow

internal/workflow/standard-development 的可执行权威,定义:

  • 11 个节点及其 contract;
  • 29 条 transition、guard 与 reason rule;
  • node-specific payload validator;
  • authority invalidation;
  • method semantic steps;
  • process definition digest。

当前实现是直接、静态的 Go 定义,没有 runtime graph parser、registry、DSL 或 compatibility process。

Domain

internal/domain/ 定义 ProcessTask 聚合及其不变量,主要 authority 包括:

TaskIntent
RequirementsBaseline
DesignBaseline
TaskPlanBaseline
ImplementationRecord
TestRecord
ComprehensionAssessment
ProcessOutcome

TaskIntent 保存初始授权与不可变 method profile。Requirements、Design 和 TaskPlan 使用递增 revision 表示当前 authority。上游变更会使对应下游记录失效,避免旧证据继续驱动新状态。

Store

internal/store/ 使用 CGo-free SQLite driver 保存:

  • current Task snapshot;
  • 独立的可恢复 Action 操作记录;
  • append-only TaskEvent audit;
  • bounded evidence;
  • repository claim;
  • LastOperation;
  • revision CAS。

普通 mutation 在一个事务中更新 snapshot、event、evidence 与 claim。Task snapshot 用于当前 读取,TaskEvent 用于审计,不依赖 event replay 重建日常状态。

Core-retained Action 提交先在内存中完整构造并校验下一版 TaskMutation,再把有界、规范化的 payload 作为 BLOB 写入独立 action_operations 记录。随后一个事务以 revision CAS 更新 Task、 写入 Event、处理完整 Claim 集并填写该操作的 applied_revision。Task snapshot 不保存恢复 payload; 响应不确定时 Recovery 直接读取独立操作记录。

Store 在开放写能力前执行只读 preflight,验证 SQLite Schema、snapshot、process definition、 Task/Action-operation/Event/Claim 关联与当前节点 authority。不兼容或 pre-graph 数据返回 SCHEMA_UNSUPPORTED 并保持零写入。

Read-only Git Observer

internal/repository/ 读取 canonical repository identity、branch、HEAD、index/worktree 与有界 changed paths,用于建立 repository binding 和判断 mutation 前后的仓库事实。

Action result 以相对当前 Action 签发状态新产生的 changed_paths,或本节点未改文件时的 no_file_changes 明确声明 mutation envelope;artifact references 只保留证据职责。Application 对照签发基线与 fresh observation 验证每仓路径,再决定 rebind 或 REPOSITORY_DRIFT。若 binding 完全一致但结果声明了文件变化,Application 返回 repository_effect_not_observed 字段错误,不把它 误报为真实仓库漂移。

节点专用 MCP 工具使用从内部完整 Schema 派生的提交 Schema;Design baseline 的 requirements_revision、Tasks baseline 的 design_revision 与 Implementation 的 task_plan_revision 改为可省略。Delivery 的 acceptance、自动/人工 evidence ID 和 Test/Comprehension record ID 从提交 Schema 中删除,由 Core 补齐;提交这些字段会按 unknown_member 拒绝。内部完整契约保持不变。MCP 边界按提交 Schema 递归检查必填字段,嵌套对象和 数组项缺失时返回准确路径。

SubmitAction 先确认当前 Action ID、kind 与 Task 状态,再拒绝重复 JSON member,并从同一 Task 快照填充省略的系统 revision;旧客户端提交的值必须等于该快照当前值。随后 Workflow 校验完整内部 payload,Application 再按当前 Task 校验 revision、record、work item、测试通过条件、用户确认、 acceptance 与 evidence 集合。Delivery authority 字段在这一步已经由 Core 从同一 Task 快照写入完整 payload,不属于调用方纠正范围。失败返回不包含提交值的 ContractViolationGuardFailure。节点 提交中已证明零写入且路径准确的 required_member_missing 可以进入一次 correct_current_action;缺失内容需要新的用户决定时 Host 必须停止。Application 还会在任何操作记录写入前构造并校验完整下一版 Task、Action、Event 与 Claim mutation。全部通过后才暂存规范化 payload,Recovery 仍只重放该不可变提交。

Core 不执行 checkout、reset、clean、stash、commit、merge、rebase、push、tag、publish,也不 暴露 generic shell。Action 中的 allowed_effects 描述 Host 在用户授权下可执行的动作。

Recovery

internal/recovery/ 根据独立 Action 操作记录中的规范化提交、Task 的 LastOperation 和一次只读 repository observation 生成五分类 Assessment:

not_started
completed_and_recorded
completed_but_unrecorded
partially_completed
conflicting

普通读取自动返回这份提交对应的 Assessment。dev_flow_recover_action 可以完成原 transition,或为 partial/conflicting 创建 BLOCKED。Blocker 保存原 source node,解除后只回到该 resume node。

Repository Scope、配置与持久化边界

internal/webui 是 Core 内的 loopback HTTP adapter;packages/webui 构建 React/TypeScript/Vite 静态资产并通过 go:embed 进入同一 binary。Application/Workflow/Recovery 继续决定 Task、Action、Guard、Recovery、Blocker 和 Outcome,浏览器只投影视图并提交当前身份。mode 0600 receipt 绑定 PID、进程启动身份、data-root digest 与 URL,使 Codex 和 DeepSeek 携带的兼容 Core 复用同一进程和 SQLite 权威。reset 位于 CLI/Store 边界, 通过 target-bound plan、SQLite 独占访问和目标复核完成;HTTP route 集合中没有 reset mutation。 前端 typed catalog 维护简体中文/英文;首次按 navigator.languages 选择,手工选择只进入 local site storage, 不形成 Core、Task、receipt 或账号状态。

ProcessTask.Repository 继续保存主仓库 binding;PrimaryRepositoryKey 缺省为 primaryAdditionalRepositories 保存零至七个按 key 严格升序排列的附加 binding。Scope 的成员、角色和 key 创建后不可变。单仓库的有效 repository_binding_digest 仍等于主 binding digest;多仓库的唯一 有效摘要按固定 domain、entry 数、主仓角色/key/component digest 和 sorted additions 进行长度前缀 SHA-256 聚合。Action、operation、Recovery、Blocker 与 Outcome 继续共用这个既有字段,不增加第二 Scope digest。

Application 创建 Task 时先观察主仓库,再按 key 顺序观察附加仓库;全部 identity 唯一且观察成功后 才构造一次 Store mutation。恢复可以从任一参与仓库的 claim 找到同一 Task,但不会改变主仓、key 或顺序。多仓库公共路径使用 <repository-key>::<repository-relative-path>,Application 将其分派为 各 Observer 使用的普通仓库相对路径;单仓库路径语法保持不变。

Repository binding 同时保留两个不同用途的身份:GitCommonDirDigest 把 linked worktree 归到同一 本地逻辑仓库组,RepositoryIdentity 由该 digest 与 canonical root 共同形成并表示实际 worktree。 Store 继续按后者排他 claim,因此不同 worktree 的 Task 可以并行,而同一 worktree 的第二个活动 Task 仍然冲突。Control Center 从 Task snapshot 投影主仓库组标识和 worktree path,不保存新状态。

SQLite 继续以一行 Task 和一个 revision CAS 保存整个流程聚合;每个 Task 至多保留一条最近的 action_operations 记录,用于 Core-retained submission 的幂等与恢复,不形成第二个流程游标。 活动 Task 为 Scope 中每个 identity 持有一条 repository_claims 记录;Acquire、Retain 和 Release 都在 Task snapshot/event 的同一事务 中处理完整、有序的 claim 集。任一冲突或集合不一致都会回滚或 safe-stop,不产生部分 claim、仓库级 revision 或第二状态机。

Codex Skill 在单 Task admission 之前识别用户明确声明的并行批次。协调路径只调用 Host 已提供的 worktree-backed task/thread 能力,为每个有界项创建独立 Codex task;协调者不调用 Core,也不创建 父 Task。每个子 task 在自己的 canonical worktree 中执行原有 handshake 和 Action loop。共享目录的 sub-agent、Core Git mutation 和自动合并都不属于这条路径。

单个新请求不进入这条 admission 前路径。它先在当前 worktree 调用一次 dev_flow_open_task;只有 调用携带非空 new_task 且完整结果为 ACTIVE_TASK_CONFLICT 时,Codex Skill 才使用同一 Host 能力 创建且只创建一个子 task。创建参数固定为 target.environment.type="worktree",省略 startingState,由 Host 从项目默认分支的已提交状态建立 worktree;Skill 不读取、复制或应用占用中 checkout 的 index、已跟踪工作区改动或未跟踪文件。子 task 收到原有界请求和精确 selector 后独立 进入 handshake;协调者不再调用 Core,也不重试创建。显式 resume、HOST_OWNERSHIP_CONFLICT 和 其他错误仍然 safe-stop,原 Task、claim 与 worktree 不变。

dev_flow_open_task 在现有 hostrepository_pathnew_task 旁仅增加可选 primary_repository_key 和最多七项的 closed additional_repositories[{key,repository_path}]。 Task result 保留主 repository,并返回主 key 与 sorted additional_repositoriesdev_flow_server_info({}) 返回进程启动时从只读 $HOME/.dev-flow/config.json 得到的 host_preferences.codex.codebase_memoryhost_preferences.deepseek.codebase_memory。配置不存在时 均为 false;配置或索引状态不进入 Task 或流程摘要。

Store 在开放 writable connection 前以 immutable read-only preflight 校验当前精确 Schema、closed snapshot 和完整 claim 集。旧或未知 Schema 使用 reject-and-reset:零写入拒绝,不迁移、不自动 删除、改名或覆盖。用户可以选择新的 DEV_FLOW_DATA_DIR,或在 Core 外手工归档旧目录。

一次任务如何流动

sequenceDiagram
    participant Developer
    participant Host
    participant Core
    participant Store
    participant Git as Read-only Git

    Developer->>Host: 显式选择 Dev Flow
    Host->>Core: server_info
    Core-->>Host: capabilities + schemas
    Host->>Core: open_task / get_next_action
    Core->>Store: read Task
    Core->>Git: observe repository
    Core-->>Host: node contract + legal transitions
    Host->>Developer: 执行并解释当前节点工作
    Host->>Core: submission_tool(node result)
    Core->>Git: re-observe
    Core->>Core: plan + validate complete TaskMutation
    Core->>Store: insert prepared action_operations row
    Core->>Store: CAS Task/Event/Claim + mark operation applied
    Core-->>Host: updated Task + next action

如果最后一步响应不确定,Core-retained submission 的 Host 只保留 Task ID 与 Action ID,随后读取 独立操作记录对应的恢复结论;显式 operation-probe 路径继续由调用方携带其完整 probe。

版本与分发

Core、Codex、DeepSeek 是三个独立产品:

Core      → CORE_VERSION
Codex     → packages/codex/package.json
DeepSeek  → packages/deepseek/package.json

Host package 内含一个 macOS arm64 Core executable,构建与发布证据从实际 executable 读取 Core 版本和 digest。Codex Plugin manifest 只镜像 Codex package 版本。

发布工具位于 release/scripts/,不进入 Core、MCP 或 SQLite。产品发布使用固定检查、精确 confirmation、仓库外 release directory,并通过远端回读安全重试。

源码导航

路径责任
cmd/dev-flow/Core CLI、version、STDIO server lifecycle
internal/domain/Task 聚合、baselines、actions、evidence、outcome、limits
internal/workflow/process、node、transition、payload、guard、invalidation
internal/application/use case orchestration
internal/recovery/reconciliation、assessment、blocker
internal/repository/read-only Git observation
internal/store/SQLite bootstrap、strict codec、Action operations、CAS、events、claims
internal/mcp/fifteen tools、closed JSON、Result Envelope
packages/codex/Codex Plugin、Skill、lifecycle 与 package
packages/deepseek/DSH bundle、Skill、guard 与 package
protocol/fixtures/public contract 与 Host parity fixtures
tests/contract/, tests/journeys/deterministic contract 与 process evidence
release/, scripts/standalone release contracts and tooling

当前行为权威是代码、机器可读 Schema 与可执行测试。文档帮助读者理解系统,不作为运行、 构建或发布输入。

Codex Skill 激活边界

packages/codex/plugin/skills/dev-flow/agents/openai.yaml 允许 Host 隐式选择 Skill,SKILL.md 的 description 提供任务型正向用途和非任务型排除边界。精确 $dev-flow-codex:dev-flow selector 与隐式 选择汇合到同一 admission;launcher 从 packages/codex/lib/lifecycle.mjs 复用同一 MCP instructions, setup validator 校验 metadata、Skill 和 instructions 自洽。激活来源不进入 Core、Task、SQLite、 receipt 或用户配置。