@ric-infra/harness
v0.1.5
Published
Protocol-first, evidence-gated workflow harness for Codex and other agent executors.
Maintainers
Readme
ric-infra
ric-infra 是一个面向企业级 Agent 开发流程的参考基础工程:由确定性 Harness 控制状态、权限、预算、并发、重试、证据和发布,Codex 只作为默认的 Planner / Worker / Reviewer 执行器。
它解决的不是“怎样写一个更长的主 Prompt”,而是怎样把 Agent 工作变成可恢复、可审计、可验证、可终止的工程流程。核心协议使用版本化 JSON Schema,因此通用范式与具体语言、模型和 Agent SDK 解耦;当前仓库则用 Node.js 24 + TypeScript 提供一套可运行的参考实现。
先看这里
如果你第一次进入仓库,按下面的目标选择入口:
| 你的目标 | 从哪里开始 | | ------------------------------------------------ | ------------------------------------------------------------------------------------ | | 看懂仓库每个目录的作用 | 仓库地图 | | 理解 Codex、主 Agent、Subagent 与 Harness 的关系 | Codex 与 Harness 的边界 | | 在 Codex 中使用这套框架处理一个需求 | 在 Codex 中使用本框架 | | 理解完整状态机、验证与修复 LOOP | 框架运行逻辑 | | 先零成本跑通一个闭环 | 10 分钟快速体验 | | 接入其他业务工程或其他语言 | 办法 B:把工作规范合并进业务项目 | | 查看恢复、取消、Artifact 和退出码 | CLI 与运维 | | 发布新的 npm 版本 | npm 发布手册 | | 深入研究通用方法论 | 企业级 Agent 工作流通用范式 | | 查看“一句话开发”落地与 Provider 协议 | 从业务项目接入到一句话开发 |
推荐的第一次阅读顺序是:
- 先看“仓库地图”,知道文件放在哪里。
- 再看“Codex 与 Harness 的边界”,避免把 Codex 原生多 Agent 当成持久状态机。
- 按“在 Codex 中使用本框架”运行一次需求。
- 最后阅读“框架运行逻辑”和
docs/中的细节文档。
核心结论
- 模型负责理解、规划、实现、语义审查和修复建议。
- Harness 是 Run、Task、Attempt、Artifact、Evidence 与 GateDecision 的唯一事实来源。
- 主 Agent 是用户交互和决策入口,但不是唯一状态存储;强状态机必须位于模型之外。
- Worker 只能提交
candidate和不可信声明;只有绑定精确候选 tree 的 Harness GateEvidence 才能使任务通过。 - 每次失败进入有预算、有失败指纹、有写范围的修复 LOOP;无进展、无权限或有歧义时终止到
NEEDS_HUMAN。 - 全部任务通过后仍要串行集成,并在最终组合 tree 上重新执行全局门禁;集成回归会重新打开责任任务及其传递依赖。
- Codex 可以被替换,协议、状态机、Gate、事件与证据信任边界不能依赖某个模型的“自觉”。
0.1.5 的细粒度拆分与共享修复预算
0.1.5 修复了真实复杂项目中两类会导致“还有总预算却提前失败”的调度缺陷:Contractor 不再为了给每个业务组静态预留三次机会而把独立领域压缩成六个超大任务;默认 maxTasks=12、maxAttempts=24 时最多保留 11 个业务 taskGroups,并为唯一终端集成任务保留一个任务位和一次首轮机会。即使用户用一句很短的话提出“企业级 + 完整交付 + 系统/平台/工作流/方案”,RunSpec 也会确定性要求至少 6 个独立业务组,而不是仅按字符数把它误判成小需求;该下限仍受任务位和首轮 Attempt 容量约束。单 Task 自动尝试上限提升为 6,但它只是局部安全上限,不是预算预留;所有 Task 共享 Run 的 24 次权威预算,Scheduler 始终先为每个未启动 Task 保留一次机会,只有剩余部分可以进入 Repair LOOP。
累计 Repair 的 WorkResult.changes 现在严格表示“相对继承候选的本轮增量”,而 writeScope 同时检查本轮增量与相对集成基线的累计差异。删除上一候选新增、从而恢复到集成基线的文件会被正确接受;任何本轮触碰的越界路径仍会 fail closed。Bootstrap 更新质量命令后,Harness 会在仓库干净且 HEAD 未漂移的前提下确定性同步并单独提交 AGENTS.md 受管块,避免文档仍显示 none detected。
Bootstrap 的项目控制门禁也从“配置引用存在”升级为“新目录中的每条质量命令都已在候选树上真实执行成功”。测试命令还必须提供确定性的递归测试文件清单和回归自测,证明嵌套的非 package 测试目录不会被静默跳过;独立 Reviewer 会将候选中的测试文件与可信命令证据交叉检查。以 Python unittest 为例,不能只调用可能跳过无 __init__.py 子目录的根级 discover。
Planner write scope 现在经过单调安全正规化:显式请求的 .env、.env.*、.npmrc、AGENTS.md、.git 和 Harness 元数据路径只会被删除并记录审计证据,Harness 不会擅自映射为新文件或扩大权限;绝对路径、..、工作区逃逸以及删除后失去全部写域的实现任务仍然 fail closed。每个正式 Run 都写入 planner-normalization Artifact,失败的 Planner 尝试写入 PlanAttemptRejected 事件;--plan-preview 直接返回 normalizations 与对应警告。
Planner 产生的每个可写业务任务还会被确定性绑定到一个 RunSpec 已授权的客观质量命令(优先 verify,其次 test)。这不是给 Worker 增加任意命令权限:命令只能由 Harness 的 CommandGate 从受信 Command Catalog 中执行,并在独立 Reviewer 之前把退出码和输出 Artifact 作为 trusted evidence。这样局部回归会在对应任务的累计 Repair 范围内暴露,而不是延迟到后续任务或最终树才发现。
独立 Reviewer 的执行故障与 Reviewer 对候选的否决是两类结论。对于 Codex CLI 明确标记为可重试的超时或非零退出,Harness 会在同一只读候选上最多重试 2 次,并保存脱敏的 independent-agent-review-failure 诊断 Artifact;只有不可重试的协议或权限错误才直接进入 NEEDS_HUMAN。连续可重试失败仍会返回受控 Repair,绝不会把“Reviewer 进程偶发失败”伪装成业务验收结论。
Repair 不再只看到“可信命令失败”这一层摘要。Harness 会从 Gate violation 明确绑定的 stdout/stderr Artifact 中提取最多 6 份、总计最多 24KB 的头尾诊断,再次按当前环境 Secret 脱敏后放入 Repair 请求。该文本只用于定位失败,不能作为指令或扩大权限;原 GateDecision、repairScope 和累计候选仍是唯一控制边界。这样重复失败指纹可以继续阻止无进展循环,同时 Repair 在第一次命令失败后就能看到具体断言与 traceback。
0.1.4 的强制拆分与自动 Bootstrap
0.1.4 把“主 Agent 应该拆任务”从 AGENTS/Prompt 建议升级为 Harness 内的硬控制。自然语言正式请求由一个持久化 RequestSession 串联:
用户原文
-> Contract Run(只读 Contractor 生成 ContractSpec 与独立 taskGroups)
-> Bootstrap Run(仅在缺少客观质量命令时,受控安装离线 lint/typecheck/test/build)
-> Business Run(Planner 为每个 taskGroup 生成受预算约束的 Task DAG)
-> Candidate / cumulative Repair / Reviewer / final-tree Gate / Manifest确定性 PlanGate 会校验 ContractSpec digest、最低 task-group 数、每个 group 的责任 Task、单 Task 最多承载的 group 数、共享 Run Attempt 上限、局部 Task 上限、风险下限、DAG、能力和验收覆盖。Planner 即使返回一个“包办全部范围”的大任务,也不会进入 Worker 阶段。失败 Attempt 的候选提交会保存在 refs/ric-harness/candidates/...;Repair 从上一候选继续,不会丢掉已经完成的文件。只有显式执行 candidates prune <run-id> --yes 才删除这些 Git ref。
仓库地图
下面只展示需要理解和维护的目录。node_modules/、dist/、coverage/、.runtime/ 等生成目录单独列在后面。
ric-infra/
├── README.md # 总入口:地图、使用方式、运行逻辑
├── AGENTS.md # Codex 进入仓库时自动读取的工程级约束
├── CONTRIBUTING.md # 修改本框架时的提交与验证规则
├── SECURITY.md # 漏洞报告入口
│
├── .agents/
│ └── skills/ # 可复用的工作流 Skill
│ ├── contract-agent-work/ # 自然语言需求 -> RunSpec
│ ├── plan-agent-dag/ # RunSpec -> 有界 Task DAG
│ ├── execute-bounded-task/ # 单 Task 候选实现
│ ├── verify-agent-evidence/ # 独立验证与 GateDecision
│ ├── repair-gate-failure/ # 按失败证据做最小修复
│ ├── integrate-agent-results/# 最终树集成与再验证
│ └── operate-ric-harness/ # CLI 运行、恢复、审计、取消
│
├── .codex/
│ ├── config.toml # 项目级多 Agent 并发、深度和 Hook 开关
│ ├── agents/ # Codex 原生窄角色定义
│ │ ├── planner.toml
│ │ ├── explorer.toml
│ │ ├── implementer.toml
│ │ ├── verifier.toml
│ │ └── integrator.toml
│ ├── hooks.json # Codex 生命周期 Hook 配置
│ ├── hooks/harness-hook.mjs # 只记录经过清洗的生命周期 metadata
│ └── rules/default.rules # 阻止破坏性 Git、宽泛删除等命令
│
├── contracts/ # 对外协议:版本化 JSON Schema
│ ├── run-spec.schema.json # 一次 Run 的需求、验收、预算和策略
│ ├── plan.schema.json # 绑定 RunSpec digest 的 Task DAG
│ ├── task-spec.schema.json # 单任务边界、写范围、能力和预算
│ ├── work-result.schema.json # Worker 只能返回 candidate
│ ├── gate-evidence.schema.json # 绑定 attempt/tree 的可信证据
│ ├── gate-decision.schema.json # pass/repair/needs_human/abort
│ └── ... # Event、Coverage、Manifest、CLI Envelope
│
├── policies/
│ ├── command-catalog.json # Gate 可以执行的受信命令白名单
│ ├── default-policy.yaml # 默认风险与能力策略
│ └── risk-matrix.example.yaml # 风险分类示例
│
├── src/
│ ├── core/ # 纯领域逻辑:状态机、DAG、预算、重试、scope
│ ├── application/ # Run 驱动、恢复、调度、修复、集成、发布
│ ├── ports/ # Executor/Store/Artifact/Workspace/Gate 接口
│ ├── adapters/ # Codex、Fake、SQLite、Git、进程、Artifact 实现
│ ├── gates/ # Schema、Diff、Command、Review、Coverage 门禁
│ ├── contracts/ # Schema 加载、类型与 Executor Schema 打包
│ ├── project/ # 项目检测、init、Codex 安装、Provider 与自然语言入口
│ └── cli/ # ric-harness 命令行控制面
│
├── examples/
│ ├── fake-repair/ # 第一次失败、第二次修复成功
│ └── budget-exhausted/ # 有界重试后预算耗尽
│
├── docs/
│ ├── experience/ # 通用范式,以及 0.1.5 一句话开发/Provider/档位落地
│ ├── adr/ # 关键架构决策记录
│ ├── architecture.md # 组件、状态、事件、一致性和恢复
│ ├── codex-integration.md # Codex 配置与安全边界
│ ├── protocols.md # RunSpec/Plan/Result/Evidence 协议
│ ├── operations.md # CLI 运维、恢复、取消和退出码
│ ├── releasing.md # npmjs 登录、发布、验收与回滚约束
│ ├── security.md # 威胁模型与残余风险
│ ├── evaluation.md # 评测方法
│ └── implementation-plan.md # 参考实现演进计划
│
├── tests/ # 单元、集成、E2E、安全与恢复测试
├── scripts/ # build/smoke/package/skill 校验脚本
├── completions/ # PowerShell/Bash/Zsh/Fish CLI 补全
├── .github/workflows/ci.yml # Windows + Ubuntu CI
├── package.json
├── pnpm-lock.yaml
└── LICENSEsrc/ 分层怎样理解
| 层 | 可以做什么 | 不应该做什么 |
| -------------- | -------------------------------------------- | ---------------------------------- |
| core/ | 计算状态迁移、任务就绪、冲突、预算、失败指纹 | 访问文件、网络、SQLite、Git、Codex |
| application/ | 按状态机编排 Port,规定事件顺序与恢复动作 | 写死某个数据库、模型或 Git 命令 |
| ports/ | 定义外部能力契约 | 包含具体实现和领域状态决策 |
| adapters/ | 接入 SQLite、Git worktree、Codex、Fake、进程 | 降低验收标准或自行改变 Run 状态 |
| gates/ | 从真实候选树产生可信证据 | 接受 Worker 自证、绕过失败证据 |
| contracts/ | 加载和打包 Schema,提供 TypeScript 类型 | 承担调度 |
| cli/ | 提供稳定、可自动化的控制面 | 保存只存在于 CLI 进程内的隐藏状态 |
修改某类能力时去哪里
| 你要修改的能力 | 通常需要一起检查 |
| ----------------------------- | ------------------------------------------------------------------------ |
| Run/Task/Result/Evidence 协议 | contracts/、src/contracts/types.ts、Schema 测试、示例 |
| 状态或迁移规则 | src/core/state-machine.ts、reducer.ts、harness-engine.ts、恢复测试 |
| 调度、并发或写范围 | src/core/scheduler.ts、write-scope.ts、Workspace Adapter、策略测试 |
| 新 Executor | src/ports/、src/adapters/、ExecutionProfile、协议测试 |
| 新 Gate | src/gates/、policies/、GateEvidence、Coverage 和安全文档 |
| Codex 项目体验 | AGENTS.md、.agents/skills/、.codex/、docs/codex-integration.md |
| CLI 命令 | src/cli/、CLI Envelope Schema、补全、package smoke |
运行后生成的目录
这些目录不属于源代码,不要提交,也不要手工修改它们来“修复”一个 Run:
node_modules/ # pnpm 依赖
dist/ # TypeScript 构建结果
coverage/ # 测试覆盖率
.runtime/ric-harness/
├── state.db # SQLite WAL 事件存储、幂等键、Run Lease
├── state.db-wal # 运行期间的 WAL
├── artifacts/
│ ├── metadata/ # Artifact metadata
│ └── sha256/ # 不可变内容寻址 blob
├── executor/ # Codex Schema 约束的最终 JSON
└── hooks/ # 已清洗的 Hook metadata每个 Task Attempt 的 Git worktree 默认位于操作系统临时目录:
Windows: %LOCALAPPDATA%/ric-harness/worktrees/<workspace-digest>/
Linux/macOS: ${XDG_STATE_HOME:-~/.local/state}/ric-harness/worktrees/<workspace-digest>/它们故意不放在目标仓库内,避免把隔离工作区嵌套进集成仓库。
Codex 与 Harness 的边界
这套工程中存在三种不同的“Agent 层次”,不要混为一谈:
flowchart TB
U["用户"] --> O["外层 Codex 主任务(可选的操作入口)"]
O -->|"生成/确认 RunSpec,调用 CLI"| H["ric-harness 确定性控制面"]
H --> DB["Event Store / Artifact Store / Lease"]
H --> P["Codex Planner 执行"]
H --> W["Codex Worker 执行"]
H --> V["Codex Reviewer 执行"]
P --> H
W --> H
V --> H
H --> G["确定性 Gate Pipeline"]
G --> H
H --> PUB["最终树 CAS 发布"]| 层次 | 作用 | 是否是可信状态源 |
| ----------------------------- | -------------------------------------------------------------------- | -------------------- |
| 外层 Codex 主任务 | 接收用户自然语言、读取 Skill、帮助生成 RunSpec、调用 CLI、向用户汇报 | 否 |
| Codex Planner/Worker/Reviewer | 规划、实现、语义审查、修复建议 | 否,只能产生候选输出 |
| ric-harness | 状态机、预算、Attempt Token、DAG、Gate、事件、恢复、集成、发布 | 是 |
最重要的使用原则:
在 Codex 中直接说“请规划并调用 Subagent 完成任务”,不会自动启用本仓库的持久状态机。只有实际执行
ric-harness run,才会获得事件存储、Attempt Token、隔离 worktree、可信 GateEvidence、修复上限、崩溃恢复、最终树验证和 CAS 发布。
根 AGENTS.md、.agents/skills/ 和 .codex/agents/ 能提高 Codex 原生协作的规范性,但它们仍是模型上下文和角色配置,不是数据库、锁、状态机或可信证据系统。
.codex/agents/ 与 Harness 内部角色的关系
.codex/agents/*.toml服务于你在 Codex App、CLI 或 IDE 中直接操作本仓库时的原生多 Agent 协作。- Harness 启动的
codex exec子进程使用自己生成的角色 Prompt、输出 Schema、Sandbox 和 Attempt Token。 - Harness 子进程禁用用户配置、Rules、Hooks、Web、MCP 和 Plugins,不依赖
.codex/agents/决定正确性。 - Harness 的集成不是让一个模型“觉得可以合并”,而是 Git Adapter 按固定拓扑顺序集成已封印候选,再对最终树重跑 Gate。
Codex 项目配置和 Subagent 文件格式以当前官方文档为兼容性基线:
在 Codex 中使用本框架
从 0.1.2 开始采用“办法 B”:把通用工作规范、Skills、Codex 角色、Rules、Hooks、项目配置和 Golden Case 幂等合并进业务仓库;0.1.3 加入三档运行模型、readiness 与生产资格判定;0.1.4 加入 Contractor 强制拆分、RequestSession、自动 Bootstrap 和累计候选 Repair;0.1.5 再把拆分与重试改为细粒度 taskGroups 加共享 Attempt 池。使用者不再手工复制本仓库文件,也不需要先编写 RunSpec。
办法 B:把工作规范合并进业务项目
1. 安装一次 CLI
环境要求为 Node.js 24、Git 和 pnpm 11。发布包已包含构建产物,业务项目不需要手工 build。
$env:PYTHONUTF8 = '1'
pnpm add --global @ric-infra/[email protected]
ric-harness --version
ric-harness --json describe也可以固定为项目 dev dependency:
pnpm add --save-dev @ric-infra/[email protected]
pnpm exec ric-harness --json describe2. 在业务仓库根目录执行一次 init
Set-Location D:\workspaces\business-app
ric-harness init --profile local-developmentinit 会自动:
- 检查或初始化 Git,并要求目标路径是仓库根目录。
- 识别 Node.js、Python、Go、Rust、Java/Kotlin、Dart/Flutter 等项目标志。
- 从
package.jsonscripts 或语言标准工具生成项目命令目录。 - 创建
.ric-harness/project.json、.ric-harness/command-catalog.json和项目 Golden Case。 - 在现有
AGENTS.md中创建或替换带 marker 的 ric-harness 规范块,不删除业务规则。 - 安装
.agents/skills/、.codex/agents/、.codex/rules/ric-harness.rules和清洗后的生命周期 Hook。 - 合并
.codex/config.toml与.codex/hooks.json,保留已有非 ric-harness 配置。 - 将 Harness 运行目录和 Python 的瞬态解释器/测试缓存加入
.gitignore,避免本地命令把__pycache__、*.pyc、.pytest_cache等非交付物污染候选变更集。 - 如果仓库在 init 前是干净的,只提交上述受管文件,生成
chore: initialize ric-harness workflow;若原仓库已有未提交内容,则不代替用户提交并给出明确警告。
新项目不传 --profile 时也默认 local-development。该命令可重复执行:普通重复执行升级受管模板并保留项目级 Provider、预算、约束和自定义命令;显式 --profile 只切换档位与可确认的受管 Provider 默认值。没有 workflowProfile 的 0.1.2 旧项目保持 legacy-0.1.2-strict,必须显式执行 init --profile local-development 才会放宽为可信本机开发。--force 用于重新检测受管项目命令;只刷新 Codex 资产时使用:
ric-harness codex install初始化后的关键结构是:
business-app/
├── AGENTS.md
├── .ric-harness/
│ ├── project.json
│ ├── command-catalog.json
│ ├── contracts/
│ ├── README.md
│ └── golden/
├── .agents/skills/
├── .codex/
│ ├── config.toml
│ ├── hooks.json
│ ├── hooks/ric-harness-hook.mjs
│ ├── agents/ric-harness-*.toml
│ └── rules/ric-harness.rules
└── .runtime/ric-harness/ # 不提交3. 先验证接入,不消耗模型额度
ric-harness --json project validate
ric-harness --json --executor fake doctor
ric-harness --json readiness
ric-harness --json golden run四个命令证明的内容不同:
| 命令 | 证明内容 |
| ------------------ | ---------------------------------------------------------------- |
| project validate | 跟踪配置、Command Catalog 与 Provider 声明结构合法 |
| doctor | Git、Node、包资源、Codex 安装、登录和原生 Sandbox 基础能力正常 |
| readiness | 当前 workflowProfile 的真实执行条件已经满足 |
| golden run | Harness 的失败、Repair、集成、最终树复验和 Manifest 状态机可运行 |
golden run 不修改业务文件,也不调用模型,并且在任何档位下都永远是非生产结果。
3.1 三档运行模型
| 能力 | local-preview | local-development | enterprise-isolated |
| ------------------------------- | --------------- | ------------------- | --------------------- |
| validate / readiness / Golden | 允许 | 允许 | 允许 |
| request dry-run / contract-only | 允许 | 允许 | 允许 |
| 真实 Planner 预览 | 禁止 | 允许 | readiness 成功后允许 |
| 真实 Codex Run / resume | 禁止 | 允许 | readiness 成功后允许 |
| trusted-local Command Runner | 仅 Golden | 允许,证据降级 | 禁止 |
| 外层 host-read attestation | 不需要 | 不需要 | 必需 |
| 生产资格 | 永远否 | 永远否 | 按实际 Run 派生 |
local-development 的目标是可信本机上的完整闭环,不是伪装成企业隔离。Windows Sandbox、WSL、容器、容器服务器、虚拟机平台和 Hyper-V 都不是该档位的前置条件。Codex 原生 Windows 沙箱是 Codex CLI 自带的受限令牌/ACL 边界,不等于 Windows 可选功能“Windows Sandbox”,也不是企业外层 host-read-isolation 证明;Beta permission profiles 在本版本同样不计入生产资格。
Windows 上 Harness 默认显式选择 Codex 原生 unelevated 沙箱,避免非交互执行静默退化为只读;组织完成 elevated 沙箱设置后可通过 RIC_CODEX_WINDOWS_SANDBOX=elevated 选择更强实现。readiness 会在用户本地状态目录创建并立即清理一个隔离写探针,只有真实 workspace-write 成功后才报告 canExecute=true。
Codex 项目 Hooks 只有在仓库被信任并由用户审查后才会生效;首次进入项目时应在 Codex 中检查 /hooks。Rules 是额外命令保护,不替代 Harness Gate。
4. 在 Codex 中怎样提出需求
完成 init 后,在 Codex 中打开业务仓库,直接提出业务目标即可,例如:
创建一个全屋定制报价系统。或者附上真正影响结果的约束:
创建一个全屋定制报价系统。金额按人民币分计算,提供 HTTP API 和浏览器界面,
不得接入外部数据库,最终必须通过现有 lint、typecheck、test 和 build。不需要再告诉 Codex 怎样拆任务、怎样调用 Subagent、怎样写 RunSpec、失败后重试几次或最终怎样复验;init 写入的 AGENTS 规范已经要求主任务调用:
ric-harness request '<用户原始需求>'request 默认完成“自然语言 -> RequestSession -> Contractor/ContractSpec -> 必要时 Bootstrap -> Codex Planner -> 强制拆分 Task DAG -> Worker/累计 Repair -> Gate -> 集成 -> 最终树复验 -> 发布”的完整同步流程。只查看自动生成的基础 RunSpec 而不执行:
ric-harness --json request '创建一个全屋定制报价系统' --dry-run在系统临时目录依次调用只读 Contractor 与 Planner,校验 ContractSpec、task-group 拆分、Plan Schema、Digest、DAG、预算、风险、能力和验收覆盖,并返回只减权限的 normalizations;它不创建正式 Run、不创建业务 worktree、不修改业务文件:
ric-harness --json request '创建一个全屋定制报价系统' --plan-preview只生成并保存 RunSpec:
ric-harness --json request '创建一个全屋定制报价系统' --contract-only `
--output .\quote-system.run-spec.json5. Codex 主任务接下来应该做什么
业务仓库里的主 Codex 任务必须遵循以下顺序:
- 读取
AGENTS.md、.ric-harness/project.json和workflowProfile。 - 执行
ric-harness --json readiness。 local-preview只允许 dry-run/contract-only;向用户说明档位禁用了模型执行。- 其他档位 readiness 成功后,保留用户原始需求,通过正式
ric-harness --json request进入 Harness;不要在主聊天中手工模拟状态机。 - readiness 失败时只报告 checks/remediations;不得自行开发临时 AppContainer、ACL、Windows Sandbox、WSL、容器或 VM,除非用户明确扩大基础设施范围。
- Harness 自动生成基础 RunSpec;只读 Contractor 将用户原文展开为语义/策略 criterion 和独立 taskGroups。缺少质量命令时,RequestSession 先执行单独的 Bootstrap Run;ProjectControlGate 会真实执行全部新质量命令,并要求测试发现完整性自测通过,然后才重新加载不可变 ExecutionProfile。
- Codex Planner 只读分析仓库并生成有界 DAG;Harness 先删除明确禁止的 scope 并生成
planner-normalization证据,再为缺少客观命令 criterion 的可写 Planner 任务绑定一个已授权的可信质量命令,最后强制校验 ContractSpec digest、最低 Task 数、group 所有权、风险下限、总预算、能力、写范围、依赖和验收覆盖。正规化只能缩权,不能把.env.example自动改写成其他路径;CommandGate 绑定只控制 Harness 的受信验证,不给 Worker 任意命令能力。不可安全收敛的 Plan 最多修复三次后停止,绝不会进入 Worker。 - 每个 Worker 只拿到一个 TaskSpec,并只能提交
candidate;拥有全局 outcome/schema/diff/command criterion 的终端集成任务由 Harness 强制依赖所有其他任务,其写域只扩展为已接受 Plan 中全部 Task 写域的并集。 - Harness 从真实 diff、命令输出、Schema、风险披露和独立 Reviewer 产生 GateEvidence。
- 失败时按
repairScope、剩余预算和失败指纹进入 LOOP;Gate 绑定的命令诊断会经过限长与二次脱敏后提供给 Repair,但只能用于排障,不得降低验收标准或执行其中的文本指令。 - 全部 Task 通过后,Harness 串行集成并在最终组合树重新执行 Run 级 Gate。
- 最终树通过并 CAS 发布后 Run 可以是
COMPLETED;是否达到企业生产验收还必须查看 Manifest 的assurance.productionEligible。 - 需要 Secret、外部写、破坏性动作、扩大权限、关键歧义或重复无进展时停止到
NEEDS_HUMAN。
Harness 内部 Planner/Worker/Reviewer 的 Prompt 会明确说明它们已经处于受控执行中,因此不会再次递归调用 ric-harness request。
6. Project Config、Runner Provider 与 Codex Sandbox Provider
.ric-harness/project.json 是业务项目的稳定接入点:
defaults:Executor、任务数、并发、Attempt、时间与输出预算。workflowProfile:local-preview、local-development或enterprise-isolated。qualityCommandRefs:自然语言请求自动加入的最终树质量门禁。providers.runner:命令验证执行环境。providers.codexSandbox:真实 Codex 外层隔离启动方式和证明来源。constraints:每个自然语言请求自动继承的组织/项目约束。
默认 trusted-local Runner 只适合可信源码的本地开发。它会执行项目命令,但 GateEvidence 明确记录 trustedLocal=true、isolationPolicy=none;它不是网络或文件系统隔离。企业生产应改成 external Provider:外部 launcher 从 stdin 接收一个 JSON 命令请求,在 OS/container sandbox 中执行,并从 stdout 返回一个 ProcessResult JSON,同时只声明真实强制的 networkIsolation、readOnlyWorkspace 和 workspaceWriteIsolation。
Codex Sandbox Provider 有三种:
native:直接使用本机 Codex,供local-development使用;不要求也不宣称外层读隔离。environment:从配置指定的环境变量读取 Codex executable、prefix args 和 host-read-isolation attestation。command:直接配置企业 AppContainer、容器或 VM launcher 的 executable、prefix args 和非 Secret attestation。
enterprise-isolated 真实 Codex 运行仍然 fail closed。Codex 内建 read-only 主要限制写入,不证明模型只能读取当前 worktree;没有真实外层读根隔离时,不能伪造 attestation。local-development 则明确接受可信本机边界,同时在所有 Evidence 和 Manifest 中标记非生产。
ReleaseManifest 始终区分功能完成与生产验收:
{
"executionProfileDigest": "<sha256>",
"assurance": {
"workflowProfile": "local-development",
"class": "trusted-local",
"productionEligible": false,
"hostReadIsolation": false,
"objectiveVerification": true,
"limitations": [
"Commands executed on a trusted local host without external OS/container isolation."
]
}
}只有 enterprise-isolated、真实 Codex、完整外部隔离 readiness、独立审查、semantic/evidence + command + schema + diff 必需标准、最终树全部 passing GateEvidence、无 waiver、无残余风险且无未决问题同时成立时,productionEligible 才会为 true。
7. 仍然存在的边界
0.1.5提供单机同步控制面,不提供多机调度、多租户 RBAC 或人工审批后原 Run 继续。- 项目检测只生成它能从确定性文件确认的命令;未识别的质量命令应加入
.ric-harness/command-catalog.json和qualityCommandRefs。 trusted-local是明确的开发便利档位,不适合运行不可信仓库。externalProvider 提供标准接入协议,但具体 AppContainer、容器镜像、VM、凭据挂载和组织审计仍由部署方实现。- 目标 Git 仓库必须干净;Harness 不会把未提交业务改动悄悄带入隔离 worktree。
更完整的接入与安全说明见 Codex 集成、运维手册 和 安全说明。
Skill、Codex Agent 与 Harness 阶段对应关系
| 阶段 | Skill | Codex 原生角色 | Harness 中的真正控制者 |
| ---------- | ------------------------- | -------------- | ----------------------------------------------- |
| 需求契约化 | contract-agent-work | 外层主 Agent | 外层操作者生成 RunSpec,Schema 校验 |
| DAG 规划 | plan-agent-dag | planner | Harness 调用 Planner,再校验 digest、覆盖和 DAG |
| 有界执行 | execute-bounded-task | implementer | Scheduler + Attempt Token + 隔离 worktree |
| 独立验证 | verify-agent-evidence | verifier | GatePipeline;Reviewer 不能覆盖客观失败 |
| 最小修复 | repair-gate-failure | implementer | RetryPolicy、repairScope、剩余预算、失败指纹 |
| 集成 | integrate-agent-results | integrator | Git Workspace Adapter 串行集成和全局 Gate |
| 运维 | operate-ric-harness | 外层主 Agent | CLI、Event Store、Artifact Store、Run Lease |
框架运行逻辑
1. 从用户需求到可执行合同
用户自然语言不能直接进入调度。第一步必须形成 RunSpec:
用户需求
-> 目标与约束
-> 可观察的 acceptanceCriteria
-> gateIds
-> Run/Task 尝试、并发、时间、输出预算
-> Sandbox、外部写和人工升级策略
-> RunSpec Schema 校验RunSpec 只描述“什么必须为真”和“自动化可以做什么”,不把模型的实现猜测当成需求。
2. Run 级状态机
stateDiagram-v2
[*] --> RECEIVED
RECEIVED --> CONTRACTING
CONTRACTING --> CONTRACTED: contract-only RequestSession child
CONTRACTING --> PLANNING
PLANNING --> PLAN_REVIEW
PLAN_REVIEW --> EXECUTING
EXECUTING --> INTEGRATING
INTEGRATING --> GLOBAL_VERIFYING
GLOBAL_VERIFYING --> COMPLETED
GLOBAL_VERIFYING --> EXECUTING: final-tree repair
RECEIVED --> CANCELLED
CONTRACTING --> NEEDS_HUMAN
PLANNING --> NEEDS_HUMAN
PLAN_REVIEW --> BLOCKED
EXECUTING --> BUDGET_EXHAUSTED
EXECUTING --> FAILED
INTEGRATING --> NEEDS_HUMAN
GLOBAL_VERIFYING --> NEEDS_HUMAN主路径含义:
RECEIVED:固化 RunSpec、原始目标分支 head、ExecutionProfile 和幂等身份。CONTRACTING:只读 Contractor 生成受 Schema 和请求 digest 绑定的 ContractSpec;缺少关键决定时进入NEEDS_HUMAN。RequestSession 的合同子 Run 可终止为CONTRACTED。PLANNING:使用提供的 Plan,或让只读 Codex Planner依据已接受 taskGroups 生成 Plan;明确禁止的 scope 会被单调删除并写入审计 Artifact,绝对/逃逸路径和失去全部写域的任务仍拒绝。Planner 生成的可写任务会在不扩大写域的前提下绑定 Harness-owned 的可信verify/testCommandGate,以便候选在独立 Reviewer 前取得客观证据;手工提供的旧 Plan 保持兼容,不会被静默改写此项。每次无效输出产生PlanAttemptRejected,最多进行三次有界再规划。PLAN_REVIEW:验证 Plan/Contract digest、最低拆分、group 所有权、DAG、风险、能力、总 Attempt 预算、写范围和验收覆盖。EXECUTING:根据依赖、并发上限、write scope 和 resource claim 调度 Task。INTEGRATING:确认所有 Task 都有当前pass决策和 sealed candidate。GLOBAL_VERIFYING:在组合后的 staging final tree 上重新执行 Run 级验收。COMPLETED:CAS 发布目标分支,校验并持久化 ReleaseManifest。
NEEDS_HUMAN、BLOCKED、FAILED、CANCELLED 和 BUDGET_EXHAUSTED 都是可审计终态,不会通过降低标准自动变成成功。当前 0.1.x 没有“暂停后原 Run 人工审批继续”的提供方;修正权限或需求后应创建一个关联旧 Run ID 的新 Run。
3. Task 级执行与修复 LOOP
stateDiagram-v2
[*] --> PENDING
PENDING --> READY
READY --> DISPATCHED
DISPATCHED --> EXECUTING
EXECUTING --> CANDIDATE
CANDIDATE --> VERIFYING
VERIFYING --> PASSED
VERIFYING --> REPAIR_REQUESTED
REPAIR_REQUESTED --> READY
PASSED --> REPAIR_REQUESTED: final-tree regression
VERIFYING --> NEEDS_HUMAN
VERIFYING --> FAILED
VERIFYING --> BUDGET_EXHAUSTED一次 Task Attempt 的精确流程:
- Scheduler 只选择依赖已
PASSED且资源不冲突的 Task。 - Workspace Adapter 从冻结的 base commit 创建一次性 Git worktree。
- Harness 生成新的 Attempt Token,并先持久化
ExecutionRequested,再启动 Executor。 - Codex Worker 只能在
TaskSpec.writeScope内工作,并返回 Schema 合法的WorkResult(status=candidate)。 - Harness 重新读取真实 worktree,记录 candidate tree、实际 changed paths 和 base commit,并在任何 Gate 执行前创建不可变 candidate commit/ref。
- GatePipeline 按顺序执行:
SchemaGate -> WriteScopeGate -> CommandGate -> ProjectControlGate -> RiskDisclosureGate -> AgentReviewGate/FakeAssertionGate -> EvidenceCoverageGate。 - 任一 Gate 失败即产生绑定当前 attempt/tree 的
GateDecision:pass:封印精确候选 tree,按拓扑序进入私有 staging。repair:生成 repair scope 和失败指纹;新 Attempt 从上一失败候选 tree 继续,最终候选仍相对原 integration base 形成完整累计变更。needs_human:缺少权限、存在歧义、风险披露或无法安全判断。abort:不可修复的协议、策略或完整性失败。
- 新 Attempt 必须使用新 Token;旧进程的晚到结果只能记录为 discarded,不能覆盖新状态。
4. LOOP 为什么不会无限循环
RetryPolicy 同时检查:
- Task 的
maxAttempts; - Run 的总
maxAttempts; - Run 创建时刻起算的
maxWallTimeSeconds; - Executor 输出的
maxOutputBytes; repairScope是否仍在原writeScope内;- Gate 是否明确标记
retryable; - 是否需要 Secret、外部副作用、扩大权限或用户决策;
- 标准化失败指纹是否重复。
当前实现的同一失败指纹上限为 2 次;第二次出现相同指纹时视为没有进展,进入 NEEDS_HUMAN,而不是继续消耗模型调用。Task 或 Run 尝试预算耗尽则进入 BUDGET_EXHAUSTED。
模型生成的单 Task maxAttempts 会被 Harness 确定性收紧到最多 6 次。该值是局部安全上限,不会从 Run 总预算中静态划走;Scheduler 为所有尚未启动的 Task 保留一次首轮机会,Repair 只能消费共享池中扣除这些保留后的余额。命令失败指纹排除每次变化的 Artifact 引用,只由 Gate、criterion、错误码、严重级别和稳定消息计算,因此相同无进展失败不会通过变化的日志摘要逃避收敛。为了让第一次 Repair 可以定点修改,violation 直接引用的文本 Artifact 会以头尾保留、单份 8KB、最多 6 份且总计 24KB 的方式进入 repairEvidence;二进制内容、缺失 Artifact 和超额内容不会进入 Prompt,所有摘录还会再次执行 Secret redaction。
5. 为什么 Task 通过后还要再验证一次
Task GateEvidence 只证明某个独立 candidate tree,不自动证明多个候选组合后的最终树。全部 Task 通过后:
PASSED candidates
-> 按稳定拓扑顺序进入私有 staging ref
-> 获取 staging final tree 快照
-> 重新执行所有 Run 级 Gate
-> pass: 绑定 final tree 的发布授权
-> CAS 更新目标分支
-> 生成 ReleaseManifest如果最终树 Gate 失败:
- 根据失败 criterion 找到拥有该 criterion 的 Task。
- 重新打开责任 Task 及其传递依赖。
- 在剩余预算内执行新的修复 Attempt。
- 重新集成并再次验证完整最终树。
- 没有责任 Task、失败指纹重复或需要扩大权限时进入
NEEDS_HUMAN。
自然语言流程中的全局命令 criterion 由唯一终端集成任务拥有。Contractor 输出超过任务位或首轮 Attempt 容量时,Harness 会在不丢失 criterion 的前提下按稳定顺序合并相邻 taskGroups;默认 12 个任务位、24 次总预算时可保留最多 11 个业务组,再增加 1 个终端集成任务。每个 Task 最多可使用 6 次,但所有 Task 共享 24 次总上限,未启动 Task 的首轮机会不会被早期 Repair 抢占。PlanGate 会确定性地让集成任务等待全部上游任务,并把修复范围限制为各 Task 已声明写域的并集;因此最终命令发现上游回归时可以修正对应已授权路径,但仍不能写入 Plan 外目录、连接外部系统或扩大能力。
这就是第二层 LOOP:第一层是单 Task 的“执行 -> 验证 -> 修复”,第二层是全局的“集成 -> 最终验证 -> 重开责任任务”。
6. 证据信任边界
| 输出 | 产生者 | 信任级别 | 能否直接使 Task 通过 |
| --------------------------- | ------------------- | ----------------------------- | --------------------------------- |
| WorkResult.workerEvidence | Worker | 不可信声明 | 不能 |
| 实际 Git diff/snapshot | Workspace Adapter | 可信事实 | 可作为 Gate 输入 |
| 命令 stdout/stderr | 受控 Command Runner | 绑定环境与 tree 的证据 | 经 Gate 后可以 |
| Reviewer GateDecision | 独立 Codex Reviewer | 模型判断 | 不能覆盖 Schema/Diff/Command 失败 |
| GateEvidence | Harness Gate | 可信、绑定 attempt/token/tree | 可以 |
| ReleaseManifest | Harness | 最终审计结果 | 表示完整 Run 已通过 |
Evidence 必须绑定 Run、Task、Attempt、Attempt Token、Workspace、base commit、candidate tree、Gate ID/version 和 Artifact digest。复制旧日志、Worker 自述“测试已通过”或手改数据库都不能构成新候选树的证据。
7. 崩溃、恢复和取消
ExecutionRequested在启动外部进程前持久化,所以恢复时知道是否存在未知执行。- Run Lease 和单调 fencing token 阻止两个 Scheduler 同时控制同一 Run。
resume <run-id>根据最后一个持久事件继续;中断中的旧 Executor 会尽力取消,隔离 worktree 被丢弃,并按预算决定是否重试。cancel先写持久取消请求,不需要等待当前 Run Lease;活动驱动者在控制轮询和外部效果边界执行取消。status、events、runs list和 Artifact 查询使用只读观察运行时,不会悄悄创建空数据库。- 不要通过关闭终端代替
cancel,也不要手改state.db、WAL、Artifact 或 JSONL 导出进行恢复。
完整状态、事件、一致性和恢复设计见 架构说明 与 运维手册。
10 分钟快速体验
1. 检查已安装 CLI
$env:PYTHONUTF8 = '1'
ric-harness --version
ric-harness --help
ric-harness --json describe
ric-harness --json --executor fake doctor2. 初始化一个业务项目
Set-Location D:\workspaces\business-app
ric-harness --json init
ric-harness --json project validate
ric-harness --json readinessinit 会检测项目、合并 AGENTS/Codex 规范、生成项目命令目录和 Golden Case。仓库在 init 前干净时,受管文件会自动形成一个独立提交;否则先处理并提交原有变更。
3. 零模型费用运行修复闭环
ric-harness --json golden run预期结果:
- 第一个 Attempt 产生
repair; - 第二个 Attempt 产生
pass; - 候选进入 staging;
- 最终树 Gate 通过;
- Run 为
COMPLETED; .runtime/ric-harness/中存在事件、证据和 ReleaseManifest。
4. 预览一句话开发合同
ric-harness --json request '创建一个全屋定制报价系统' --dry-run该命令展示自动生成的 RunSpec、预算、项目约束和质量命令,不创建持久状态,也不调用 Codex。
5. 查看预算耗尽
源码仓库中的预算耗尽示例会按设计返回退出码 6 和 BUDGET_EXHAUSTED 错误 Envelope:
ric-harness --json --executor fake plan bind `
.\examples\budget-exhausted\run-spec.json `
.\examples\budget-exhausted\plan.template.json `
--output .\.runtime\budget-plan.json
ric-harness --json --executor fake run `
.\examples\budget-exhausted\run-spec.json `
--plan .\.runtime\budget-plan.json6. 使用真实 Codex
默认 local-development 在可信本机上无需外层 attestation:
ric-harness --json --executor codex doctor
ric-harness --json readiness
ric-harness --json --executor codex request '创建一个全屋定制报价系统' `
--idempotency-key feature-2026-07-16省略 --plan 时,Harness 会自动调用 Codex Planner。Worker 使用有界 workspace-write 或 read-only Sandbox,独立 Reviewer 使用 read-only Sandbox;最终结果仍由真实 diff、受信命令、独立证据和 Coverage 决定。
enterprise-isolated 才要求外部 Runner、非 native Codex Provider 和真实 host-read attestation 全部就绪。不要在 readiness 失败后让主 Agent 自行拼装临时主机安全设施。
CLI 与运维
主要命令:
init [path] [--profile <local-preview|local-development|enterprise-isolated>] [--force] [--no-git] [--no-commit]
codex install [path]
project detect [path]
project validate [path]
request <natural-language request...> [--dry-run|--plan-preview|--contract-only] [--output] [--force]
golden run [path]
describe
doctor
readiness
validate <schema-kind including project-config> <file>
plan bind <run-spec> <plan> [--output] [--force]
run <run-spec> [--plan] [--idempotency-key] [--dry-run]
resume <run-id>
status <run-id>
events <run-id> [--after] [--limit]
export-events <run-id> [--output] [--force]
runs list [--limit]
requests list [--limit]
requests show <session-id>
candidates list <run-id> [--task]
candidates prune <run-id> [--task] --yes
artifacts list [--run] [--task]
artifacts get <artifact-ref> [--output] [--force]
artifacts verify <artifact-ref>
cancel <run-id> [--reason]全局选项:
--json
--workspace <git-root>
--runtime-dir <path>
--worktrees-dir <path>
--executor <codex|fake>
--no-color
--log-level <level>自动化统一使用 --json:stdout 恰好一个 ric-harness.cli/v1 Envelope;错误代码与退出码稳定,stderr 不混入 JSON。自动化应判断 ok、error.code 和退出码,不解析自然语言 message。
常用运维命令:
ric-harness --json status run_xxx
ric-harness --json events run_xxx --after 0 --limit 100
ric-harness --json resume run_xxx
ric-harness --json cancel run_xxx --reason 'operator requested stop'
ric-harness --json artifacts list --run run_xxx
ric-harness --json artifacts verify artifact://sha256/<digest>
ric-harness --json export-events run_xxx --output .\run_xxx.jsonl
ric-harness --json requests show request_session_xxx
ric-harness --json candidates list run_xxx带 --output 的命令默认拒绝覆盖现有文件并返回 OUTPUT_EXISTS(退出码 5);只有操作者明确传入 --force 才会替换。
稳定退出码:
| 退出码 | 含义 |
| -----: | --------------------------------------------------------- |
| 0 | 命令成功 |
| 2 | 参数或 Schema 错误 |
| 3 | 配置、环境或 Executor 不可用 |
| 4 | Run、输入或 Artifact 不存在 |
| 5 | 冲突、非法迁移、输出冲突或策略拒绝 |
| 6 | NEEDS_HUMAN、BLOCKED、FAILED、CANCELLED、预算耗尽 |
| 7 | Executor 超时、协议错误或 Gate 命令错误 |
| 8 | 状态、Artifact 完整性或内部错误 |
| 130 | 中断 |
完整运维说明见 运维手册。
安全边界
- MVP 是单机、可信操作者、单 Run 单租约;不承诺主机磁盘损坏容错。
- 默认禁止外部写型 MCP / API;缺少权限与不可逆副作用进入
NEEDS_HUMAN。 - Planner、Reviewer 与纯读任务使用只读 Sandbox;只有同时声明
repo.write与非空 write scope 的执行任务才可获得workspace-write。 - 写任务在一次性 Git worktree 内执行;候选先按 DAG 顺序进入私有 staging ref,最终树全局门禁通过后才以原始 target head 为前置条件执行 CAS 发布。
RunCreated固化 Executor/Gate 版本、Command Catalog、Executor Schema 与外层隔离证明摘要;恢复时任何执行配置漂移都 fail closed。.git、.runtime、.codex、.agents、.env*、.npmrc、绝对路径和..均不可进入 Task write scope。- 基础 tree 含 tracked symlink 或 gitlink/submodule 时拒绝创建 Attempt。
- 子进程不做 shell 字符串拼接;Windows
.cmd只允许无 shell 元字符的受控参数。 - Secret 在日志与 Artifact 写入前做 canary/redaction;Artifact 使用 SHA-256 内容寻址并在完成前逐一校验。
- RunSpec、Plan 和持久事件在进入 Prompt 或 Event Store 前拒绝 secret-bearing 字段。
- Worker 披露的具体 known risk 必须先进入有界 Repair 并被真正消除;相同风险重复出现时按无进展停止条件升级。unresolved question、缺失权限或缺失责任主体会直接进入
NEEDS_HUMAN。当前版本不提供隐式 Waiver,也不会把风险字段静默清空后发布。 - 未初始化项目使用的基础本地 Command Runner 不宣称网络、只读文件系统或写范围隔离,并在策略要求这些能力时 fail closed。
init生成的trusted-localProvider 是显式开发信任档位,会运行项目白名单命令并在证据中记录没有隔离;企业生产应切换到externalRunner。
威胁模型与残余风险见 安全说明。
验证本仓库
$env:PYTHONUTF8 = '1'
pnpm verify
pnpm skills:validate
pnpm smoke
pnpm smoke:package
pnpm smoke:scenario
pnpm release:checkpnpm verify 依次执行格式、Lint、仓库 Skill 校验、严格类型检查、带覆盖率门槛的测试和生产构建。pnpm smoke 从临时 Git 仓库运行构建产物。pnpm smoke:package 会执行 pnpm pack,在仓库外同时验证项目本地安装和隔离 PNPM_HOME 的真实全局安装,再通过安装生成的 bin 执行 Help、Version、Describe、Doctor 和完整 Fake Executor 修复闭环。pnpm smoke:scenario 会在操作系统临时目录把“创建一个全屋定制报价系统”契约化为 RunSpec/Plan,驱动三任务 DAG、一次失败修复、最终树验证、ReleaseManifest、应用测试、构建和真实 HTTP API 验收。pnpm release:check 是 npm 发布前的完整门禁,并额外检查最终 tarball。
CI 在 Windows 与 Ubuntu 上执行同样流程,不依赖 Codex 凭证。
npm 发布流程、显式 npmjs 登录和不修改用户级 Registry 的操作见 npm 发布手册。
非目标
0.1.x 不提供多机器调度、分布式锁、远程对象存储、多租户 RBAC、自动批准外部副作用或部署执行。Schema 保留 Token/成本预算字段,但在接入可信 Executor 用量计与成本计之前,配置 maxTokens 或 maxEstimatedCostUsd 会 fail closed;rebase-and-reverify 同样在完整重基线协议实现前拒绝执行。
出现这些真实需求时,应保留协议与 Port,再替换 Adapter;不要先把尚未稳定的领域拆成微服务。
