本文是
ctl的设计与愿景记录(原README.md)。面向使用者的项目介绍与安装方式见 README.md;落地顺序见 ROADMAP.md,架构约束见 ARCHITECTURE_GUARDRAILS.md。
把以下能力融合成一个更干净的体系:
- OMP:作为主执行器,负责模型路由、代码编辑、LSP、DAP、浏览器、subagents、工具调用。
- Trellis:吸收其任务、归档、spec、workspace journal、context manifest 能力。
- Spec-Driven Develop:重点吸收钱学森工程控制论式闭环,而不是照搬整套 Markdown 流程。
- Rust 重写控制层:把任务状态、事件、telemetry、drift 计算做成确定性状态机。
一句话定位:
Trellis 的任务/归档/记忆能力 + Spec-Driven 的闭环控制系统,用 Rust 做成确定性 AI 开发控制层,OMP 作为执行器。
本文是设计与愿景记录。为避免「文档脱离实际架构」,这里明确区分已落地与规划中。里程碑现状以 ROADMAP.md 为准(M0–M6 + V1 认知层均已落地)。
已实现并强制(M0–M6 + V1 认知层)
- 事件溯源任务账本:
events.jsonl为唯一事实源,task.json为可重建投影;存储根为.ctl/(由.trellis/迁移,后者已整体退役)。 - 分层 Rust(
domain纯 reducer /application/infrastructure/cli/adapters)。domain纯度与依赖方向由ctl architecture check的check_modules(实现位于src/cli/mod.rs,扫描src/domain/顶层.rs文件)机器强制(禁止use crate::{infrastructure,cli,adapters,application}与std::{fs,io,net,process,time})。 - 路径边界(
PathNormalizer)、gate 模板(cargo_check/test/fmt/clippy)、受控执行状态机(Planning→Ready→InProgress→Review→Completed,正交 hold)。phase 机器串统一为 serdein_progress(Phase::as_str()为唯一来源)。 - 运行时治理 hook:OMP(
.omp/hooks/pre/ctl-context.ts)、Claude Code(.claude/hooks/ctl-gate.py,PreToolUse)与 OpenCode(.opencode/plugins/ctl-gate.ts)。越界写入被拦截,但 fail-closed 按工具/平台分级:路径作用域的 Write/Edit/MultiEdit 在ctl不可用时 fail-closed;Claude Code 的 Bash fail-open(不锁死 shell、不做路径作用域检查),其 Task/子智能体派发不被 PreToolUse 匹配(U-1 平台边界,非待办);OpenCode 的task与 Bash 经会话级插件 fail-closed。 - M4:worktree 隔离 + run-scoped lease + approval 流程(
ctl workspace / approval / run);manual + omp + opencode 执行器 adapter(ctl adapter list/status/doctor)。 - M5(可解释控制闭环):
telemetry.jsonl证据索引(ctl telemetry add)、control.jsonreconcile 决策投影(ctl board)、确定性 drift 引擎(ctl drift compute/explain)、ctl next-action建议(pass/ask/stop/replan/rescope,只读、不发事件)。 - M6(并发执行切片 1–3 + lease 接线):
ctl schedule plan/validate/run将校验过的计划首个并行安全组激活为并发 AgentRun 聚合(run-store,domain/run.rs),各自隔离 worktree + scoped lease;ctl agent-report、ctl run merge-candidate/recover/expire-lease;共享.git写操作硬化。从不 spawn 执行器。 - V1 认知层(record-and-disclose):
ctl brainstorm(来源溯源)、ctl uncertainty(未知项账本 + oracle 证据,modeloracle 仅顾问性、命令层拒绝以其 resolve)、ctl research(spike/研究任务)、ctl handoff export、ctl prd init、ctl ralph(无人值守安全监督,只读 dead-man switch)。 - 归因层(attestation / record-and-disclose,0.0.4 后):
ctl run finish为run_finished补上生产调用方(run 终达 Completed,不再永远 open);ctl run finish记录 host-attested run 溯源(model/provider/起止时间/exit_code+ 供给制品的 sha256,仅记录不验证);新增 canonicalsubagent_dispatched任务事件 +ctl dispatch record/list,OMP / OpenCode 在放行子智能体派发时自动记录(Claude 受 U-1 限制不可);非 canonical gate 决策日志.ctl/decisions.jsonl+ctl decisions(三宿主 hook 经ctl hook record-decision记录 deny / bash_write);Claude hook 测试(CI +adapter doctor --verify)与 Claude hook 平台 doctor 检查。全部 host-attested 证据,非密码学证明——审计的「Do Not Claim」仍然成立。
规划中 / 愿景(下文有描述但尚未实现)
- Codex adapter(manual / omp / opencode 已实现,Codex 仍为兼容目标)。
- 经认证的执行主体(authenticated principal)、L3 级事件日志(签名 / 防篡改)、OS 级写沙箱。这三项需引入签名 / OIDC / 沙箱依赖,受当前依赖红线(仅
clap/serde/anyhow/sha2/libc,禁 HTTP client)限制——须先有意识地修订 ARCHITECTURE_GUARDRAILS.md 才能动工。 - 任务级多 run 镜像状态(
run_scheduled/run_launched/run_mergedreducer 已就绪并测试,但生产路径以 run 聚合为唯一事实源,未启用任务级镜像——详见 ROADMAP「已知缺口」)。
当前激活平台:OMP(原生 hook)+ Claude Code(PreToolUse / SessionStart hook)+ opencode(.opencode/plugins/ctl-gate.ts 插件:tool.execute.before 门禁 + experimental.chat.system.transform 上下文注入;另带 opencode 执行器 adapter)。.cursor / .pi 与 Trellis 旧体系已移除;skills 单一来源内嵌于 ctl 二进制,经 ctl init 注入 .omp/(.claude/、.opencode/ 为随仓库直接维护的集成)。
边界是第一优先级,高于功能数量、自动化程度和模型能力。
详细落地顺序见:ROADMAP.md。
后续设计与实现必须遵守:ARCHITECTURE_GUARDRAILS.md。
使用 OMP /glob 分阶段推进实现时,参考:GLOB_WORKFLOW.md。
这个项目首先要解决的不是“让 agent 做更多事情”,而是明确:
什么可以做?
什么不能做?
谁可以做?
在什么范围内做?
越界时由谁决定是否继续?
所有能力都必须建立在可定义、可检查、可审计的边界之内。
| 边界 | 约束 |
|---|---|
| 项目边界 | Rust 控制层负责状态、事件、权限、验收和调度,不负责重新实现模型执行器。 |
| 阶段边界 | 第一阶段只替换 Trellis 的 task 能力;telemetry、drift、agent schedule 分阶段加入。 |
| 任务边界 | 每个任务必须声明目标、范围、允许修改的文件和验收 gate。 |
| 写入边界 | 子智能体默认最小权限;只有明确授权后才能写代码、改依赖或操作 Git。 |
| 文件边界 | agent 只能修改 assignment 中允许的路径;越界修改必须停止并记录事件。 |
| 架构边界 | 公共 API、依赖、数据库迁移和安全策略变化必须触发人类确认。 |
| Adapter 边界 | 控制层只依赖统一协议,不绑定 OMP、Codex、Claude 或 OpenCode 的内部实现。 |
| 自动化边界 | 无法解释的 drift、权限不足和高风险动作必须暂停,不能自动扩大权限继续执行。 |
衡量一个功能是否应进入系统,先问:
它的边界能否被机器表达?
它的越界能否被检测?
它的行为能否被事件日志解释?
失败时能否停在一个可恢复的位置?
如果答案是否定的,该功能暂时不进入自动执行路径。
当前项目级 OMP 围栏验证了默认只读、scope 限制、受保护路径和 shell 模板白名单的价值,也暴露了一个更重要的问题:
限制模型能否写入
!=
限制模型能否继续修改、扩大范围或宣布完成
因此,正式控制层必须冻结一条独立于执行器和模型的协议:
proposal
-> pending_approval
-> scoped lease
-> implement
-> audit_hold
-> deterministic audit
-> human_resume | completed | stopped
硬约束:
- 批准对象是结构化 proposal,不是自然语言中的“继续”或“批准”。
- lease 绑定 task、run、资源、动作、TTL 与最大使用次数。
- 命中 schema、依赖、scope、required gate、受保护路径或批量变更触发器后,立即进入只读
audit_hold。 - completion interlock 独立检查固定证据清单。模型和 reviewer 都不能自行宣布里程碑完成。
- baseline manifest 记录 schema、fixture、required gate、审计矩阵和稳定检查项。数量下降时默认
STOP,即使现有测试仍然通过。 ASK、STOP和UNVERIFIED是合法结果,不应被自动重试逻辑覆盖。
M0 现在冻结协议、审计矩阵和机器检查。正式 OMP adapter 与自动 reviewer 仍然留在 M4 阶段及以后;自动 reviewer 只提供 evidence,不取代确定性 gate。
- 工具面完整:
read/search/find/edit/lsp/debug/browser/task统一接口。 - Windows 原生,无需 WSL。
- 多模型路由强:GPT、Claude、GLM、DeepSeek、MiMo、Copilot、Cursor、Kimi 等可按 role 分配。
- LSP / DAP 深度集成:能做引用、重命名、诊断、调试。
- 文件与 URL 抽象统一:本地文件、GitHub PR/Issue、skills、URL、PDF 都可通过
read处理。 - 更适合高可靠工程:hashline edit、subagents、debug、review、LSP 能降低误改概率。
- 生态规模不如 Claude Code / Codex 官方工具。
- 功能密度高,复杂度也高。
- 官方模型一手体验:Claude Code 对 Claude、Codex 对 OpenAI 可能更稳。
- 插件兼容不等于 hook 行为完全等价。
- 团队采纳需要额外培训。
个人/小团队高强度工程执行:
OMP = 主力执行器
Trellis-like layer = 项目治理层
Spec-Driven control loop = 大型任务控制论
Claude/Codex/OpenCode = 兼容目标或备用执行器
团队推广时保持兼容:
仓库里放 .omp/skills(单一来源,内嵌于 ctl 二进制)/ .claude/hooks / AGENTS.md
让 OMP 与 Claude Code 读取并强制治理。
(注:.cursor / .pi 与 Trellis 旧体系已退役;opencode 已落地为活跃集成——`.opencode/plugins/ctl-gate.ts` 插件 + `opencode` 执行器 adapter;Codex 仍为规划中的兼容目标。)
当前仓库已经先落地 OMP 项目级围栏配置,入口为:.omp/settings.json。
按失败代价分工,不按厂商平均轮换。
| 工作 | 首选模型 |
|---|---|
| 架构方案 / API 决策 / 迁移计划 | GPT / Codex 高推理 |
| 高风险调试 / 最终 review | GPT / Codex 高推理 |
| 日常实现 | GLM |
| 批量重构 | DeepSeek |
| 单测补齐 | DeepSeek / GLM |
| 简单子任务 / 摘要 / commit | Xiaomi MiMo |
| S.U.P.E.R 架构评估 | GPT + GLM 交叉 |
OMP 推荐配置示例:
modelRoles:
plan: openai/gpt-5.3-codex:high
slow: openai/gpt-5.3-codex:high
default: z.ai/glm-5
smol: xiaomi/<mimo-model-id>
commit: xiaomi/<mimo-model-id>DeepSeek 可作为默认实现模型切换:
modelRoles:
default: deepseek/<model-id>Trellis 不是纯 Python 项目,主体仓库是 TypeScript,但落地到项目里的核心脚本大量使用 Python(已退役的遗留脚本,如 task.py、get_context.py、add_session.py,其职责现由 Rust ctl 二进制承担)。
Rust 重写时,不应照搬实现语言或全部平台适配,而应吸收它的文件协议与生命周期。
.ctl/tasks/<MM-DD-slug>/
task.json
prd.md
design.md
implement.md
implement.jsonl
check.jsonl
research/
planning -> in_progress -> review -> completed -> archived
.ctl/tasks/archive/YYYY-MM/<task>/
.ctl/workspace/<developer>/journal-N.md
.ctl/spec/
{"file": ".ctl/spec/backend/index.md", "reason": "backend conventions"}- 多平台 generated files 的复杂度。
- 过多 hook 适配。
- 每个平台一套 prompt 的膨胀。
- Python 脚本式状态修改。
docs/progress/MASTER.md作为第二套进度源。
最有价值的是它的钱学森工程控制论闭环,不是完整 Phase 0-6 Markdown 流程。
应抽象成真正的控制系统:
Set Point 目标状态:PRD / design / specs / S.U.P.E.R
Plant 被控对象:代码库
Sensor 传感器:diff / tests / LSP / deps / coverage / review
Observer 观测器:把传感器结果转成 telemetry
Comparator 比较器:计算 target vs actual 的偏差
Controller 控制器:决定继续、修正、重规划、暂停询问
Actuator 执行器:OMP / Codex / Claude / OpenCode agent
Feedback 反馈:events.jsonl + telemetry.jsonl + spec updates
| Drift | 动作 |
|---|---|
< 0.2 |
continue |
0.2 - 0.4 |
annotate next task |
0.4 - 0.6 |
replan remaining tasks |
> 0.6 |
stop and ask human |
硬围栏与 completion interlock 始终先于 drift 分数。命中 STOP、进入 audit_hold 或存在 baseline 回退时,不得使用较低 drift 分数继续执行。
建议计算:
drift_score =
scope_delta
+ architecture_violation_delta
+ unplanned_dependency_delta
+ test_failure_delta
+ touched_files_delta
+ requirement_coverage_gap
示例 telemetry:
{
"scope_delta": 0.2,
"super_violations": 2,
"unplanned_dependencies": ["new-auth-lib"],
"tests_failed": 3,
"requirement_coverage_gap": 0.15,
"drift_score": 0.41,
"control_action": "replan_remaining_tasks"
}新项目不要叫 Trellis fork,也不要叫 Spec-Driven fork。建议定位为:
AI Development Control System
或:
Rust task/control layer for AI-assisted software development.
Trellis-compatible task store, Spec-Driven adaptive control loop.
注:以下为早期扁平化草案,已被实际的分层布局取代。当前规范布局见 ARCHITECTURE_GUARDRAILS.md 与实际目录树:
src/{cli,application,domain,infrastructure,adapters}/,adapter 仅manual / omp / opencode(无 codex / claude 模块)。
src/
cli/ → clap 解析 + architecture check
application/ → ControlApp 命令服务(含 schedule)
domain/ → 纯 reducer:task / run / event / drift / lease / approval / policy / audit_matrix / telemetry
infrastructure/ → store / boundary / gates / workspace / skills / schema_validator
adapters/ → manual / omp / opencode
兼容 Trellis 路径,减少迁移成本:
.ctl/
spec/
tasks/
workspace/
control/
每个任务:
.ctl/tasks/<task>/
task.json # 机器状态
events.jsonl # 状态事件日志
telemetry.jsonl # 执行观测数据
control.json # 控制系统当前判断
prd.md # 人类可读需求
design.md # 技术设计
implement.md # 实施计划
implement.jsonl # 实现上下文 manifest
check.jsonl # 检查上下文 manifest
research/ # 研究记录
必须是:
events.jsonl = append-only canonical truth
telemetry.jsonl = append-only evidence index
task.json = 由 replay 重建的任务投影视图
control.json = 由 reconcile 重建的决策投影视图
而不是 Markdown progress。
外部执行器不能直接追加 canonical event。agent、adapter 和人工工具只能提交 evidence,由控制层验证后生成事件。
Markdown 只做人类可读解释:
prd.md / design.md / implement.md / research/*.md
CLI 是底层能力;日常使用不需要手动敲命令。OMP agent 通过 .omp/skills/control-guard/SKILL.md 自动执行以下循环:
用户请求 → agent 判断是否是任务
→ 是:agent 推断边界 → 展示提案 → 用户确认/调整 → 自动创建 ctl task
→ 否:跳过 control,自由工作
→ agent 在 write_allow 范围内实现
→ agent 自动运行 gates (fmt/check/test/clippy)
→ agent 检查 completion readiness
→ 用户确认完成
用户只需要在 agent 提案时回答 yes/adjust/skip,其余全自动。
| Agent 自动做的事 | 命令 |
|---|---|
| 检测任务请求,推断 objective/scope/gates | agent 内部推理 |
| 展示任务提案,等待人类确认 | agent 对话 |
| 创建 ctl task | ctl init + ctl task create + ctl task ready |
| 检查写入是否在 scope 内 | ctl boundary check --path <path> |
| 验证事件流 | ctl validate |
| 运行全部 gates | cargo fmt/check/test/clippy |
| 架构合规 | ctl architecture check |
| 展示完成摘要 | ctl task status --id <id> |
| 重建投影 | ctl replay --task <id> |
| 未来的 agent 行为 | 里程碑 |
|---|---|
| 自动执行 gate runner | M2 |
| 自动构建 context snapshot | M2 |
| 自动比对 touched files vs write_allow | M3 |
| 自动 ingest evidence | M3 |
| 自动完成 interlock 检查 | M3 |
| 自动生成审计报告 | M3 |
| OMP adapter 直接调用 control | M4+ |
首版发布边界是 M3 Manual 闭环 MVP,不接模型、不做全平台大一统——这是历史起点。当前(0.0.3)已发布至 M6 并发执行 + V1 认知层,但「ctl 从不 spawn 执行器」这条边界始终未变。详细里程碑见:ROADMAP.md。
ctl init
ctl task create
ctl task ready
ctl task start
ctl context build
ctl task submit
ctl task finish
ctl task archive
ctl task status
ctl assignment export
ctl run ingest --adapter manual
ctl replay
ctl reconcile
ctl validate
ctl doctor
- 创建任务。
- 记录 PRD/design/implement。
- 生成 implement/check context manifest。
- 由控制层追加 canonical events。
- 检查实际 diff 是否越过 scope。
- 执行 required gates,保存 evidence hash。
- 通过 manual adapter 导出 assignment、回填执行结果。
- replay 状态并生成可审计报告。
- 归档任务并写 journal。
telemetry / drift / next-action / OMP adapter / schedule 在 MVP 之后分阶段加入。
来源:
- https://github.com/github/spec-kit
- https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html
值得借鉴:
- constitution 概念。
/specify -> /plan -> /tasks -> /implement。- 模板化 artifacts。
- 多 agent 集成。
注意:容易 Markdown 过载。
可吸收为:
.ctl/spec/constitution.md
值得借鉴极简结构:
requirements.md
设计 design.md
任务 tasks.md
适合小中型任务。
值得借鉴:
task directory + specs + workspace journal + context manifests
只吸收:
S.U.P.E.R
adaptive control loop
drift
large transformation analysis
以下项目值得借鉴,但仍然遵守“边界优先”:第一阶段只吸收协议思想和数据模型,不直接引入新的平台依赖。
来源:
值得吸收:
spec = desired state
status = observed state
event = observation
reconcile(spec, status) -> next action
- 控制器不直接假设任务已经成功,而是持续比较目标状态与实际状态。
- 调和动作必须幂等:重复运行不应破坏状态。
- desired state 必须声明式、可版本化、可审计。
落地到本项目:
task.json = desired task state + materialized status
events.jsonl = observed facts
control.json = last reconciliation decision
ctl reconcile <task>
来源:
- https://docs.cedarpolicy.com/
- https://docs.cedarpolicy.com/auth/authorization.html
- https://docs.cedarpolicy.com/policies/validation.html
Cedar 的授权模型很适合表达 agent 边界:
principal 谁在执行:agent / human / adapter
action 想做什么:read / write / delete / exec / commit / network
resource 对什么做:file / command / dependency / git / secret
context 在什么条件下:task / scope / approval / risk / ttl
值得吸收:
- 默认拒绝:没有明确
permit就不能执行。 forbid优先:命中禁止规则时,即使存在允许规则也拒绝。- schema 先行:权限请求和策略都应可验证。
- 决策必须返回 diagnostics,说明为什么允许或拒绝。
第一阶段不必立即嵌入 Cedar runtime,但权限数据模型应保持 Cedar-compatible。
来源:
in-toto 强调:步骤应由授权主体执行,并记录输入材料、输出产物和证据。这个模型可以直接映射到子智能体。
assignment = layout step
agent = functionary
allowed files = artifact rules
input hashes = materials
output hashes = products
agent output = link metadata
值得吸收:
- 每次 agent run 记录输入、输出、命令、文件 hash 和执行身份。
- 验收不是只看 agent 自述,还要验证实际产物是否落在授权范围内。
- 后续可为高风险任务增加签名 attestation。
第一阶段先记录 hash 和 evidence,不急着做完整签名链。
来源:
值得吸收:
- durable execution:中断后可以从已记录状态继续。
- replay:从事件历史重建状态。
- 把确定性控制逻辑与有副作用的外部执行分开。
- retry 必须有边界,不能把非幂等动作盲目重放。
本项目只吸收设计原则:
reducer / replay = deterministic
agent / command run = side effect
第一阶段不引入 Temporal 服务。
来源:
- https://modelcontextprotocol.io/docs/learn/architecture
- https://modelcontextprotocol.io/docs/learn/client-concepts
- https://modelcontextprotocol.io/specification/2025-06-18/client
值得吸收:
- capability negotiation:adapter 先声明能力,再接收任务。
- tools / resources 分离:可执行动作与只读上下文分开。
- tool input 使用 schema。
- roots 用于告诉执行器当前工作范围。
重要限制:
MCP roots 是范围提示,不是强安全边界。
真正的文件隔离必须由控制层、sandbox 或 worktree 执行。
来源:
值得吸收统一术语:
trace = 一次完整任务执行
span = 一次 agent run / tool call / gate check
log = 结构化事件
metric = drift、耗时、失败率、重试次数
baggage = task_id / run_id / agent_id / approval_id
第一阶段继续使用 JSONL,只预留 correlation id。等 dashboard 或分布式 adapter 出现后,再考虑接 OpenTelemetry exporter。
来源:
- https://docs.github.com/actions/deployment/targeting-different-environments
- https://developer.hashicorp.com/hcp/docs/vault-secrets/dynamic-secrets
值得吸收:
- 高风险能力在审批前不可见、不可用。
- 权限按任务临时授予,并带 TTL。
- 执行结束或 session 终止后自动撤销。
- agent 不应默认持有长期凭据。
落地形式:
capability lease:
subject
permissions
resources
task_id
issued_at
expires_at
approved_by
revoked_at
第一阶段直接使用 JSON Schema 校验:
task.json
events.jsonl
control.json
assignment.json
agent-output.json
来源:
边界严格的对象默认关闭未知字段:
{"unevaluatedProperties": false}CUE 适合后续做配置组合、约束推导和 policy 校验,但不是 MVP 必需依赖。
第一阶段不要部署或强绑定:
Temporal server
OPA / Cedar runtime
OpenTelemetry Collector
Vault
完整 in-toto 签名链
先把字段、事件和 trait 边界留出来。只有实际需求出现后,再把对应能力接入。
- Trellis:AGPL-3.0。
- Spec-Driven Develop:MIT。
- GitHub Spec Kit:MIT。
如果复制 Trellis 代码、模板、脚本,新仓库大概率应按 AGPL-3.0 处理。
如果只吸收思想并用 Rust 重新实现状态机与模板,许可证空间更大。
值得做 Rust 版,但方向应是:
不是 Trellis rewrite
不是 Spec-Driven fork
而是 AI development control system
吸收 Trellis 的:
task / archive / spec / journal / context manifest
吸收 Spec-Driven 的:
闭环控制论 / drift / S.U.P.E.R / replan
再用 OMP 做执行器。这样比简单合并两个项目更干净、更强。
控制论术语必须落到项目对象上,避免只停留在比喻:
| 控制论组件 | 本项目对象 | 说明 |
|---|---|---|
| Set Point | TaskDefinition + PRD/design/spec + required gates |
目标状态必须同时包含人类意图和机器验收。 |
| Plant | repository / disposable worktree | 被控对象是实际代码树;worktree 是隔离手段,不是安全边界。 |
| Sensor | diff、tests、LSP、deps、gate output、review evidence | 传感器只产生观测,不产生事实。 |
| Observer | evidence ingest | 把不可信输出归档、hash、标注来源和 trust level。 |
| Comparator | boundary check、gate check、drift compute | 比较 target 与 actual,输出 rule IDs 和 evidence IDs。 |
| Controller | reducer + reconcile + completion interlock | 只有控制层能生成 canonical event 和完成判定。 |
| Actuator | manual / OMP / Codex / Claude adapter | 执行器只消费 assignment,提交 evidence。 |
| Feedback | events.jsonl + telemetry.jsonl + new proposal |
反馈不能自动扩权;重规划必须形成新的 proposal。 |
Task phase 表达任务生命周期;执行协议表达一次受控执行授权;Assignment / AgentRun 表达执行单元。三者不能互相替代:
| Task phase | 允许的执行协议状态 | Assignment / AgentRun 语义 |
|---|---|---|
planning |
proposal / pending_approval |
可创建 draft assignment,不得执行写入。 |
ready |
approved proposal 可生成 scoped_lease |
可导出 assignment;lease 绑定 task、run、动作、资源、TTL、max_uses。 |
in_progress |
implement / audit_hold |
M3 只有 manual run;M4 只有单 OMP run;M6 前禁止多个写入 run 并发。 |
review |
audit_hold / deterministic audit |
只允许 evidence ingest、只读检查和 allowlist gate。 |
completed / cancelled |
completed / stopped |
只能归档或报告,不得继续写入。 |
执行器输出、reviewer 结论和 telemetry 都是 evidence。控制层必须先验证,再决定是否追加 canonical event:
adapter output / human output / gate output
-> evidence ingest
-> schema + hash + source + scope validation
-> boundary / gate / baseline / interlock checks
-> verified domain command
-> canonical event append
验证失败时只能记录 audit evidence 或 boundary_violation_recorded,不能把失败输出折叠成成功事件。
本节只冻结设计方向,不在当前批次修改 schemas/**。后续 schema 变更需要单独 REVIEW:
| Schema | 最小字段 |
|---|---|
control.proposal.v1 |
proposal_id, task_id, objective, milestone, requested_scope, forbidden_changes, expected_schema_changes, expected_dependency_changes, required_gates, risk_triggers |
control.approval.v1 |
approval_id, proposal_id, approver, decision, approved_scope, expires_at, reason |
control.scoped-lease.v1 |
lease_id, task_id, run_id, subject, actions, resources, issued_at, expires_at, max_uses, revoked_at |
control.assignment.v1 |
assignment_id, task_id, adapter, contract, scopes, context_hashes, required_capabilities, acceptance, lease_id |
control.evidence.v1 |
evidence_id, run_id, source, command, exit_code, touched_files, input_hashes, output_hashes, artifact_hashes, self_report, trust_level |
control.audit-report.v1 |
audit_id, task_id, trigger, observed_files, dependency_changes, schema_changes, gate_results, baseline_result, verdict, rule_ids |
control.completion-interlock.v1 |
task_id, required_evidence, satisfied_evidence, pending_approvals, baseline_status, gate_status, verdict |
control.drift-report.v1 |
task_id, evidence_ids, signals, score, action, explanation, generated_proposal_id |
drift-report 的 generated_proposal_id 只能指向待审批 proposal;drift 不能自动扩大 scope、启动执行或解除 hold。
阶段边界:本节描述 M6 的受限多智能体目标模型。M3 只验证 manual
assignment.json/agent-output.json合同;M4 只允许单 OMP 执行器在 disposable worktree 中运行;M6 前不得把多个写入子智能体并发接入执行路径。
子智能体必须是一等公民,不是简单“并发提示词”。它们应被控制系统调度、观测、记录,并纳入 drift 计算。
主控制器负责状态机、任务边界、调度与验收。
子智能体负责单一职责工作包。
所有子智能体输出必须结构化落盘。
所有子智能体行为都必须由控制层验证,并记录到 events.jsonl / telemetry.jsonl。
| 子智能体 | 职责 | 写权限 | 推荐模型 |
|---|---|---|---|
research-agent |
代码库调查、外部资料、方案对比 | 只写 research/ | DeepSeek / GLM |
architecture-agent |
架构分析、边界设计、S.U.P.E.R 评估 | 只写 research/ 与 design draft | GPT |
task-planner-agent |
任务拆分、依赖图、执行顺序 | 只写 implement.md draft | GPT / GLM |
implement-agent |
按单个任务包实现代码 | 可写代码 | GLM / DeepSeek |
test-agent |
补测试、设计边界用例 | 可写测试 | DeepSeek / GLM |
review-agent |
diff review、风险识别、规范检查 | 只写 review report | GPT |
control-agent |
汇总 telemetry、计算 drift、建议控制动作 | 只写 control.json | GPT / GLM |
archive-agent |
归档、journal、摘要、commit notes | 只写归档与 workspace | MiMo / GLM |
每个任务下保留子智能体输出:
.ctl/tasks/<task>/
agents/
research-agent/
output.md
telemetry.json
architecture-agent/
output.md
telemetry.json
implement-agent-001/
output.md
touched-files.json
telemetry.json
review-agent/
findings.json
output.md
如果输出需要被后续执行读取,应再显式加入 implement.jsonl 或 check.jsonl:
{"file": ".ctl/tasks/<task>/agents/research-agent/output.md", "reason": "research findings for implementation"}
{"file": ".ctl/tasks/<task>/agents/review-agent/findings.json", "reason": "review findings for verification"}调度器输入:
{
"task_id": "05-28-auth-refactor",
"agent": "implement-agent",
"scope": ["src/auth/session.ts", "src/auth/token.ts"],
"contract": "Implement token refresh without changing public API.",
"context": [
"prd.md",
"design.md",
".ctl/spec/architecture/super.md"
],
"write_policy": "code_and_tests",
"acceptance": [
"existing auth tests pass",
"new refresh expiry tests pass",
"no new circular dependencies"
]
}子智能体输出必须包含:
{
"status": "completed | blocked | failed",
"summary": "short factual summary",
"files_touched": [],
"tests_run": [],
"risks": [],
"open_questions": [],
"telemetry": {
"estimated_effort": 1,
"actual_effort": 2,
"scope_delta": 0.1,
"unplanned_dependencies": [],
"super_violations": 0
}
}可以并发:
- 多个只读 research-agent。
- 互不重叠文件的 implement-agent。
- test-agent 与 review-agent 在实现完成后并行。
不应并发:
- 两个子智能体写同一文件。
- 架构边界未定时启动实现。
- control-agent 与正在写代码的 implement-agent 同时更新
control.json。
子智能体是控制系统里的 actuator / sensor hybrid:
Actuator:执行具体任务包。
Sensor:报告实际变更、测试结果、偏差、风险。
Observer:由主控制器汇总所有子智能体 telemetry。
Controller:根据汇总 drift 决定 continue / annotate / replan / stop。
每个子智能体完成后追加事件:
{"type":"agent_started","agent":"implement-agent","task":"05-28-auth-refactor","time":"..."}
{"type":"agent_completed","agent":"implement-agent","status":"completed","telemetry":{"scope_delta":0.1}}
{"type":"drift_updated","score":0.27,"action":"annotate_next_task"}注:早期草案用过
control二进制名与control agent *命名;二进制现为ctl, 已发布的等价命令见下(ctl 本身从不 spawn agent——run由 OMP 等执行器驱动, ctl 只做计划 / 上报 / 回填)。
ctl agent-report # 列出 / 汇报所有 agent run(原 control agent list/report)
ctl run ingest --id <task> --result … # 回填执行结果为 evidence(原 control agent ingest)
ctl telemetry add … # 提交信号(原 control agent telemetry)
ctl schedule plan <task>
ctl schedule run <plan>
Rust 控制层不直接实现模型调用。它生成结构化 assignment,然后交给 OMP 的 subagent 能力执行。
ctl schedule plan <task> -> 生成 agent assignments
OMP task tool -> 并发执行
ctl run ingest -> 读取不可信输出,验证后写入 evidence 与 canonical events
ctl drift compute -> 计算下一步控制动作
第一个正式 adapter 是 manual,先验证 assignment 协议。自动执行器第一版只需要支持 OMP。omp 与 opencode adapter 已落地;Codex 后续再做 adapter。
不要只保存当前状态。所有状态变化都应先写事件,再由事件折叠出当前 task.json / control.json。
events.jsonl = append-only truth
task.json = materialized view
control.json = materialized control state
telemetry = 带来源标记的不可信 evidence
外部不能直接写 canonical event。日常命令必须通过领域操作追加事件,不能把任意 JSON append 作为普通入口。
示例事件:
{"type":"task_created","task":"05-28-auth-refactor","by":"shaob","time":"..."}
{"type":"agent_started","agent":"research-agent","task":"05-28-auth-refactor","time":"..."}
{"type":"telemetry_recorded","source":"test-agent","tests_failed":2,"time":"..."}
{"type":"control_action_selected","action":"replan_remaining_tasks","drift_score":0.43,"time":"..."}
{"type":"task_archived","task":"05-28-auth-refactor","archive_path":"archive/2026-05/05-28-auth-refactor","time":"..."}这样以后可以做:
ctl replay --task <task>
ctl audit --id <task>
ctl drift explain --id <task>
所有机器可读文件都必须带 schema version:
{
"schema": "control.task.v1",
"id": "05-28-auth-refactor",
"status": "planning"
}Rust CLI 提供:
ctl doctor
ctl validate
(schema 迁移目前由 ctl init 的 bootstrap 步骤处理,无独立 migrate 命令。)
否则一旦任务文件格式演进,旧任务会不可读。
大型并发任务必须支持 worktree,避免子智能体互相踩文件。
worktree 只负责隔离变更和降低冲突,不是安全边界。它仍然共享 Git 元数据,也不能限制仓库外访问。真正的强制边界必须由控制层 policy 与 sandbox 执行。
推荐策略:
单任务小改动:当前工作树
多 agent 并发实现:每个 implement-agent 一个 worktree
review/test:基于合并候选分支运行
任务字段预留:
{
"branch": "task/05-28-auth-refactor",
"base_branch": "main",
"worktrees": {
"implement-agent-001": "../.worktrees/05-28-auth-refactor-impl-001"
}
}prd.md 可以写人类语言,但验收不能只靠文字。每个任务应有可执行 gate:
{
"gates": [
{"type": "command", "cmd": "cargo test -p control-core"},
{"type": "command", "cmd": "cargo clippy -p control-core -- -D warnings"},
{"type": "lsp", "target": "changed_files"},
{"type": "review", "agent": "review-agent", "severity_block": ["P0", "P1"]}
]
}控制系统只在 gates 通过后允许:
in_progress -> review -> completed
子智能体必须有明确权限边界:
read_only
write_research
write_tests
write_code_scoped
write_code_any
git_commit
network
默认策略:
- research-agent:
read_only + write_research - implement-agent:
write_code_scoped - test-agent:
write_tests - review-agent:
read_only - archive-agent:
write_workspace - 没有任何子智能体默认拥有
git_commit
Rust 控制层不要绑定某个 agent CLI 的内部实现。定义统一 adapter trait:
trait AgentBackend {
fn capabilities(&self) -> Capabilities;
fn run_assignment(&self, assignment: Assignment) -> AgentRun;
fn collect_output(&self, run: AgentRun) -> AgentOutput;
}第一批 backend:
manual
omp
codex
claude
opencode
manual 是第一个正式 adapter,不是临时兜底:CLI 先生成结构化任务包,让人或任意 AI 工具执行并回填结果。这样可以在接入自动执行器前验证协议是否完整。
注册表(SUPPORTED_ADAPTERS + adapter_for)是 adapter 的唯一真相源,但“注册了”不等于“接对了”:Rust 侧契约可能没接好(capabilities 形状不对、prepare_run 没盖对名字、validate_output 漏判 source),宿主侧集成也可能缺失(control-guard skill 不存在、managed-protocol 漂移、插件 / hook 文件缺位)。adapter-doctor-v1 沿这两条轴诊断。
只报事实,不给综合分。 每条 check 带一个状态枚举,而非单个 bool:
enum CheckStatus { Pass, Fail, Warn, Unknown, NotTracked } // JSON: SCREAMING_SNAKE_CASE- 我们刻意不输出 0–100 的“支持健康分”——只有逐条状态 +
PASS/FAIL/WARN/UNKNOWN/NOT_TRACKED计数 +healthy/total。 - 判失败的唯一依据是
counts.fail > 0;WARN/UNKNOWN/NOT_TRACKED永不算失败。 - 未实际执行或无法判定的检查保持
NOT_TRACKED/UNKNOWN,绝不冒充PASS。
数据结构(src/adapters/mod.rs,全部 Serialize,--json 直出事实):
struct AdapterCheck { name: String, status: CheckStatus, detail: String }
struct StatusTally { pass, fail, warn, unknown, not_tracked: usize }
struct AdapterDiagnostic { adapter, resolved: bool, checks: Vec<AdapterCheck>, counts: StatusTally }
struct AdapterSummary { adapter, output_format, workspace, capabilities: Vec<String> }
struct AdapterDoctorReport{ adapters, total, healthy, failed: usize, counts: StatusTally }AdapterDiagnostic 没有 healthy 布尔——失败是事实 counts.fail > 0(has_failures())。AdapterDoctorReport 里 healthy 是“无 FAIL 的 adapter 数”,是计数而非评分。
healthy 的语义严格是「没有失败检查」(no failing checks),不等于「安全可用」。WARN / UNKNOWN / NOT_TRACKED(平台 wiring 缺失、Bun 测试未运行、协议状态无法判定等)仍可能代表现实风险,只是不构成命令失败。请把 healthy 读作「无 FAIL」,而非「已验证可用」。
两类 check:
contract.*—— 纯函数,住在crate::adapters::adapter_contract_checks(无 fs / process)。是 conformance 套件的线上孪生,条款一一对应:resolves、name_matches、capabilities_adapter、capabilities_output_format、capabilities_list、prepare_run、validate_output_accepts、validate_output_rejects_foreign。未知名字只返回一条失败的contract.resolves。platform.*—— 需要文件系统与协议检查器,因此在 application 层装配(application::adapter_doctor_report),折进同一个AdapterDiagnostic:platform.skill_present:该 adapter 的 control-guard skill 是否存在(缺失 = FAIL)。platform.protocol_in_sync:复用infrastructure::skills::evaluate_protocol_drift——即 CI 漂移测试的同一套 marker/version/core 解析比对逻辑(已从#[cfg(test)]提升为编译进二进制的公共 API)。漂移 = FAIL,skill 缺失 = UNKNOWN。- opencode:
platform.opencode_plugin_present(.opencode/plugins/ctl-gate.ts,缺失 = FAIL);platform.opencode_bun_tests(默认NOT_TRACKED,仅--verify真跑bun test,Bun 不可用 = UNKNOWN)。 - omp:
platform.omp_hook_present与platform.omp_config_present——“检测得到才检查”,缺失分别为 WARN / UNKNOWN,绝不硬判 FAIL(某个 checkout 可能本就没接 OMP),也从不断言 hook 的运行时行为。
CLI(逻辑在 adapters/ + application/ + infrastructure/,cli/ 只格式化):
| 命令 | 作用 | 失败语义 |
|---|---|---|
ctl adapter list [--json] |
列出全部注册 adapter 的 output_format / 能力 |
总是成功 |
ctl adapter status --adapter <name> [--json] [--verify] |
单个 adapter:contract + platform | 存在 FAIL → 非零退出 |
ctl adapter doctor [--json] [--verify] |
全部 adapter:contract + platform | 任一 adapter 有 FAIL → 非零退出 |
诊断只读文件与注册表,从不触碰任务 / run 账本;--verify 之外不跑任何外部进程,因此默认随时可跑。
控制系统必须知道哪些动作需要人确认:
删除文件
数据库迁移
公共 API 变更
依赖升级
安全策略变更
超过 drift 阈值的重规划
git commit / push
对应事件:
{"type":"human_approval_requested","reason":"public_api_change","time":"..."}
{"type":"human_approval_granted","by":"shaob","time":"..."}吸收 SDD 时必须防止 Markdown 膨胀。建议三档任务模式:
| 模式 | 文件 |
|---|---|
| small | task.json + 简短 notes.md |
| medium | prd.md + implement.md |
| large | prd.md + design.md + implement.md + research/ + control telemetry |
不要让小 bug 生成完整 PRD/design/research。
后续可以加一个本地 dashboard,但第一版先输出结构化报告:
ctl board --json # 跨任务控制板(原 control status)
ctl report # 全任务汇总报告
ctl drift explain --id <task>
ctl agent-report # agent run 汇报
报告应回答:
现在目标是什么?
已经做了什么?
偏差在哪里?
谁做出的判断?
哪些证据支持这个判断?
下一步为什么是这个动作?
审计不是实现过程中的提示消息,而是权限状态变化:
implement -> audit_hold -> deterministic audit
在 audit_hold 中,只允许读取文件、解释规则和运行 allowlist 内的离线 gate。实现者、reviewer 和 telemetry 的 PASS 只是 evidence;控制层必须独立检查固定审计矩阵、baseline manifest 和未决审批,再决定恢复、完成或停止。
固定审计矩阵至少覆盖:
Schema 正例与反例
reducer 合法与非法转换
replay 一致性
Windows UNC / junction / symlink / root escape
受保护文件变更
依赖变化
required gate 变化
baseline 回退
最小可落地不是“写完整平台”,而是先完成 M0-M3,替换 Trellis 的基础 task 能力并形成 manual 闭环。详细退出条件见:ROADMAP.md。
ctl init
ctl task create/ready/start/submit/finish/archive
ctl context build
ctl board # 原 control status
ctl assignment export # 仅 export(无 assignment create 子命令)
ctl run ingest --adapter manual
ctl replay/reconcile/validate
低级事件入口不能作为 agent 或普通用户路径。外部只能提交 evidence,由控制层验证后生成 canonical event。
然后按真实 dogfood 结果再加:
M4: OMP 单执行器隔离运行
M5: telemetry / drift / next-action
M6: 受限多智能体与 schedule