首页
/ 深入解析 ECC `/orch-review` 命令:将 Review 阶段落地为原生 Workflow 并守住院落式提交门禁

深入解析 ECC `/orch-review` 命令:将 Review 阶段落地为原生 Workflow 并守住院落式提交门禁

2026-09-07 23:57:12作者:裘旻烁

/orch-review 是 ECC(The agent harness performance optimization system)中把 orch-pipeline Phase 5(Review)移植为 Claude Code 原生 Workflow命令表层(command surface):它负责计算 diff、把 diff 交给 Workflow 并呈现审查结果。本篇文章基于 commands/orch-review.md 命令文档,结合其底层 workflows/orch-review.workflow.js 实现与 workflows/README.mdskills/orch-pipeline/SKILL.md 管道定义,完整拆解它的双模式输入、GATHER → INVOKE → REPORT 三阶段流程、Fail-Closed 契约与边界情况处理,并深入源码级原理(fan-out 维度构建、基于 evidence 的跨维度去重、对抗式验证器与 0.8 置信度阈值)。读完你可以掌握:如何对本地未提交改动或 GitHub PR 一键触发多维并行审查,如何理解 blocking/advisory 的分类逻辑,以及为什么这套命令在 Gate 2 之前永远不会"静默放行"未经完整审查的 diff。


1. 定位:命令表面对 Workflow 的实现边界

在 ECC 的 orch-* 技能族中,skills/orch-pipeline/SKILL.md 定义了共享的分阶段管道:0. Intake → 1. Research → 2. Plan → 3. Scaffold → 4. Implement(TDD) → 5. Review → 6. Commit,并在 Plan 之后(Gate 1)Commit 之前(Gate 2) 设置两道人工门禁。其中 Phase 5 Review 原本由 code-reviewer agent / /code-review 承担,命中安全触发器时追加 security-reviewer

/orch-review 是这条管道的原生 Workflow 移植:命令文档首行即声明它是 workflows/orch-review.workflow.js 的 surface。二者的职责被刻意切分:

  • 命令(command)负责输入与输出:计算 diff、决定模式、调用 Workflow、向用户呈现结果;
  • Workflow 负责自主的 fan-out 部分:按维度并行派出审查 agent、跨维度去重、对每条 CRITICAL/HIGH 执行对抗式验证。

为什么需要这种切分?workflows/README.md 指出,原生 Workflow 是后台自主运行的多 agent 编排,无法为交互式审批暂停,因此被 Gate 1/Gate 2 包围的外层主循环必须留在主会话中;命令文档将该脚本定义为"the human review gate"——Workflow 自身永远不会提交任何内容,最终批准权始终在人类手中。

命令元数据(front matter)还声明了它的调用参数约定:

description: Run the orch-review native Workflow over a diff (local changes or a GitHub PR) and report blocking vs advisory findings.
argument-hint: [pr-number | pr-url | blank for local uncommitted changes]

即:不带参数 = 审查本地未提交改动;带 PR 号或 PR URL = 审查 GitHub PR。


2. 模式选择(Mode Selection)

命令文档用一张表定义输入与模式的映射,这是 /orch-review 唯一的"入口分流"逻辑:

输入 模式
空白(不传参数) Local Mode —— 审查未提交改动
数字(如 42)或 PR URL PR Mode —— 审查一个 GitHub PR

该表同样被登记在 ECC 的 docs/COMMAND-REGISTRY.json 的命令清单中(path: "commands/orch-review.md"),并在根目录 COMMANDS-QUICK-REF.md 中作为可快速检索的命令入口列出。


3. Phase 1 — GATHER:构建 diff 与元数据

3.1 Local Mode:本地未提交改动

Local Mode 用两条 git 命令产出 Workflow 需要的两大输入——diff 文本与变更文件列表:

git diff --name-only HEAD          # changedFiles
git diff HEAD                      # diff text

若 diff 为空,命令立即停止并提示 "Nothing to review."——这是第一道空输入防线:没有可审查内容就不进入 Workflow。

3.2 PR Mode:安全的数字 ID 提取

PR Mode 最关键的一条安全纪律是:$ARGUMENTS 推导出"安全的纯数字 PR id",绝不把原始参数直接传给 shell。命令文档要求的规则是:

  • 接受裸整数(如 42);
  • 或接受 https://github.com/<owner>/<repo>/pull/<N> 这类 URL 的末尾数字
  • 其余任何输入(多余文本、shell 元字符、非 PR 的 URL)一律拒绝并报错停止

只有提取出的整数 <NUMBER> 才允许进入下面的命令:

gh pr diff <NUMBER>                       # diff text
gh pr view <NUMBER> --json files \
  --jq '.files[].path'                    # changedFiles

若 PR 不存在,同样报错停止。这一步在实现上属于"命令层输入消毒",其精神与底层 Workflow 入口处对 args 的严格校验(见第 6.1 节)完全一致:不可信输入在进入任何执行路径前就要被结构化、被验证

3.3 语言推导:language

随后从主导变更文件的扩展名推导 language

文件扩展名示例 language 值
.ts / .tsx typescript
.py python
.go go
…(见第 5.2 节完整映射)

当变更是混合语言或非代码时,language 保持不设置——Workflow 会直接跳过语言专属审查维度,这是"条件维度"设计的体现。


4. Phase 2 — INVOKE:调用原生 Workflow

Phase 2 把 Phase 1 的产物打包进 Workflow 工具调用。命令文档给出的调用骨架如下(其中 scriptPath 相对仓库根目录):

Workflow({
  scriptPath: "workflows/orch-review.workflow.js",
  args: {
    diff: "<unified diff text from Phase 1>",   // required
    language: "typescript",                      // optional
    changedFiles: ["src/auth.ts"]                // optional — feeds the security trigger
  }
})

值得注意的参数语义:

  • diff必填,非空。Workflow 会自行校验并"fail closed"——缺 diff 或空 diff 直接抛错,绝不为一个没被真正审查过的载荷给出 APPROVE。
  • language可选,用于选配语言维度审查器。
  • changedFiles可选,文件路径数组,喂给安全触发器做匹配(haystack 的一部分)。
  • scriptPath 使用 workflows/orch-review.workflow.js 的相对路径,与 workflows/README.md 中给出的调用方式完全一致,印证命令与 README 描述的接口契约是统一的。

Workflow 会并行 fan-out 各维度审查器、按"规范化 evidence 片段"跨维度去重、并对每条唯一的 CRITICAL/HIGH 运行对抗式验证器,随后返回如下结构(命令文档中的返回示例,stats 为演示值):

{
  "verdict": "APPROVE" | "CHANGES_REQUESTED",
  "incomplete": false,                 // true if a review dimension failed to run
  "failedDimensions": [ /* { dimension, error } */ ],
  "blocking": [ /* confirmed CRITICAL/HIGH + unverifiable findings */ ],
  "advisory": [ /* MEDIUM/LOW + adversarially-refuted findings */ ],
  "stats": { "dimensions": 3, "failed": 0, "raw": 11, "unique": 4, "confirmed": 3, "unverified": 0, "uncertain": 0, "refuted": 1 }
}

stats 是理解整条流水线价值的钥匙:raw(11) 是所有维度返回的原始 finding 数,unique(4) 是去重后保留的独立 finding 数,confirmed(3) 是验证器确认为真的 blocking 数,refuted(1) 是被对抗验证器以高置信度推翻的 false positive 数。workflows/README.md 记录了一个实测数据:11 条 raw findings 坍缩为 4 条 unique,验证器调用成本大约减半——这正是"先去重后验证"屏障的意义。


5. Phase 3 — REPORT:向人类门禁呈现结果

REPORT 阶段是 Gate 2 的人工审查界面。命令文档要求呈现顺序与要点:

  1. 先给 verdict 与一行 stats(dimensions、raw→unique 坍缩比例);
  2. 逐条列出所有 blocking findings,附文件、严重级别与证据——这些必须在 commit 前清空;其中被标记为 "could not be verified" 的项有意保留在 blocking,需特别提示用户做人工确认;
  3. 简要列出 advisory findings(MEDIUM/LOW 以及被验证器推翻的项);
  4. incomplete 为 true,说明 failedDimensions 中哪些维度没跑起来,并明确此时的 verdict 不构成干净的 APPROVE

这套展示顺序让人类在 Gate 2 只面对"能不能提交"这一个决策,而不是淹没在原始 finding 洪流中。


6. 源码级原理:Workflow 内部如何保证"可信的审查"

命令文档只描述输入输出,而真正决定审查质量的是 workflows/orch-review.workflow.js 的内部实现。以下从源码出发拆解其关键机制。

6.1 入口 Fail-Closed:任何坏输入直接抛错

Workflow 对调用方契约有明确注释(workflows/orch-review.workflow.js 顶部注释块):

// Caller contract — pass `args` (the main loop computes the diff and language):
//   { diff: string /* required */, language?: string, changedFiles?: string[] }
// Invalid input (missing/empty diff, bad JSON, non-array changedFiles) throws —
// the gate fails closed rather than silently approving an unreviewed payload.

入口实现按序校验:args 既接受对象也接受 JSON 字符串;然后逐条拒绝——非对象、diff 非字符串或 trim 后为空、changedFiles 非数组、数组内存在非字符串元素。其中最后一条校验的注释尤其值得玩味:一个非字符串元素(如 { path: '...' } 对象)会被 stringify 成 "[object Object]"静默污染安全触发器匹配的 haystack,因此必须 fail closed。

6.2 维度构建:quality 恒有,language 与 security 按条件叠加

审查维度不是固定写死的,而是"不可变地"条件叠加(源码逻辑):

const langReviewer = input.language && LANGUAGE_REVIEWER[String(input.language).toLowerCase()];
const securityNeeded = SECURITY_TRIGGER.test(haystack);
const dimensions = [
  { key: 'quality', label: 'correctness & quality', agentType: 'ecc:code-reviewer' },
  ...(langReviewer ? [{ key: `lang:${input.language}`, ..., agentType: langReviewer }] : []),
  ...(securityNeeded ? [{ key: 'security', ..., agentType: 'ecc:security-reviewer' }] : [])
];
  • quality(正确性与质量)维度永远运行,对应 ecc:code-reviewer(agent 定义见 agents/code-reviewer.md);
  • language 维度仅在 language 能映射到审查器时运行LANGUAGE_REVIEWER 常量映射表与 agents 目录下的语言审查器一一对应,例如 typescriptecc:typescript-reviewerpythonecc:python-reviewergoecc:go-reviewerreactecc:react-reviewerflutter/dartecc:flutter-reviewercppecc:cpp-reviewer 等共 18 个键;混合/非代码改动不设置 language,此维度自然缺席;
  • security 维度仅在安全触发器命中时运行,对应 ecc:security-revieweragents/security-reviewer.md)。触发器是源码中的正则,覆盖 auth/authz、口令/令牌/凭据/API key、session/JWT/OAuth/cookie、SQL/query、exec/eval、crypto/cipher/hash/HMAC、fs./readFile/writeFile、fetch/axios/request、subprocess、os.system 等;haystack 由 diff 文本与 changedFiles 路径共同构成。
const SECURITY_TRIGGER =
  /\b(auth|login|password|passwd|token|secret|credential|api[_-]?key|session|jwt|oauth|cookie|sql|query|exec|eval|crypto|cipher|hash|hmac|sign|fs\.|readFile|writeFile|fetch|axios|request|subprocess|os\.system)\b/i;

该触发逻辑与 skills/orch-pipeline/SKILL.md 中"安全审查器只在 diff 触及认证授权、用户输入、数据库查询、文件系统路径、外部 API、密码学或密钥时引入"的管道规则一脉相承(per rules/common/security.md)。

6.3 结构校验:blocker 必须有 proof

所有审查 agent 的输出必须满足 FINDINGS_SCHEMA(在工具层做校验),每个 finding 至少要含 titleseverityfileevidence。尤其关键的是在 schema 层而非 prompt 层强制约束:当 severityCRITICAL/HIGH 时(通过 JSON Schema allOf 条件)必须携带 proof(为什么它是真问题的论证),且可选携带 linefix。这样"无证据的 blocker"根本无法混进来。

6.4 阶段 1 并行审查 → 跨维度去重 → 阶段 2 对抗验证

两个阶段之间被刻意设计为屏障(barrier)。源码注释说明了理由:独立审查器经常命中同一行代码,若先去验证再去重,验证器会对同一条重复 finding(例如被三个维度同时报告的同一个 SQL 注入)空耗调用。于是:

  • 阶段 1(Review):所有维度并行执行,通过 parallel(dimensions.map(...)) 分发到 agent(reviewPrompt(...), { agentType, schema: FINDINGS_SCHEMA })。审查 prompt 中特别强调"只报告 >80% 确信是真问题的项;CRITICAL/HIGH 必须给证据与影响论证;零 findings + APPROVE 对干净 diff 是正常且预期的结果",并且将 diff 标记为 untrusted input,防止 diff 内嵌的 prompt injection 指令影响审查 agent。
  • 去重:以规范化的 evidence 片段为主键(标题措辞各异、行号随审查器漂移,但"违规代码本身"稳定):先 normalize(折叠空白、转小写、trim),键为 ${file}::${evidenceKey},evidence 为空时回退到 ${file}::${title}::${line}。合并时取所有报告维度的并集保留最严 severitySEVERITY_RANK = { LOW:0, MEDIUM:1, HIGH:2, CRITICAL:3 })。
  • 阶段 2(Verify):仅对去重后 unique 且 blocking(CRITICAL/HIGH) 的 finding 运行对抗式验证器;MEDIUM/LOW 直接落入 advisory。验证器是独立怀疑者,只依据 diff 文本判断——diff 可能是尚未 apply 的 PR,文件不在工作区不能作为推翻依据。

6.5 不确定永远不推翻 blocker:0.8 置信度阈值

验证器输出必须满足 VERDICT_SCHEMAisRealconfidence ∈ [0,1]、reasoning)。源码定义了判定规则:

const REFUTE_MIN_CONFIDENCE = 0.8;
// isReal=false 且 confidence >= 0.8 → refuted(才允许降级到 advisory)
// isReal=false 但 confidence < 0.8 → uncertain(仍留在 blocking)
// 验证器返回 null 或抛错 → unverified(仍留在 blocking)

源码注释反复强调同一原则:"Uncertainty must never clear a blocker." 只有验证器能"肯定性地从 diff 证明这是 false positive"且置信度 ≥ 0.8 时,blocker 才被降级为 advisory(并标记 refuted by adversarial verifier);凡是验证器没跑起来(返回 null)、抛错、或低置信度否定,finding 一律留在 blocking 并打上 could not be verified / verifier could not confidently refute 标签。这就是命令文档在 REPORT 阶段要求"人工确认未验证项"的底层来源。

6.6 汇总与 fail-closed 判语

最终 verdict 的判定只有一行,却是整套安全设计的收敛点:

const incomplete = failedDimensions.length > 0;
return {
  verdict: blocking.length > 0 || incomplete ? 'CHANGES_REQUESTED' : 'APPROVE',
  ...
};

即:只要有任一 blocker、或任一审查维度失败,verdict 就一定是 CHANGES_REQUESTED。其中"维度失败"有两种捕获途径(源码 parallel 中对每个 thunk 同时处理):agent() 返回 null(终态失败/跳过)以及 thunk reject,二者都会被归入 failedDimensions,错误信息被收敛为有界标签(agent returned null (terminal failure or skip) / review agent failed),绝不把 provider/runtime 内部细节泄露给调用方,但会写入 log 供运维排查。


7. Fail-Closed 契约与边界情况

命令文档用一节专门声明 Fail-Closed 契约:命令绝不能在审查未完整跑完时呈现干净的 APPROVE;若 Workflow 工具本身报错,命令应如实报告失败,不得回退到手工拼凑的审查,也不得暗示 diff 已通过。这与 workflows/README.md 的表述互为印证——"如果审查维度死亡,verdict 绝不可能是干净的 APPROVE;如果验证器死亡或返回 null,blocker 保留在 blocking 而不是降级为 advisory"。

除此之外,命令文档还列出三类边界情况,属于命令层必须自己处理的分支:

  • PR Mode 下没有 gh CLI:停止并告知用户 PR Mode 需要 gh,建议改用对已检出分支执行 Local Mode。
  • 超大 diff:Workflow 会自动限制审查器的并发度,因此大 diff 只是更慢而不会失控;命令应提前警告用户"可能耗时更长"。
  • 二进制或生成文件:在调用前把它们从 changedFiles 中剔除——它们只会给安全触发器增加噪音,却没有可审查的内容。

8. 使用前提、限制与当前状态

从本仓库现状可以确认该命令的使用前提与边界:

  1. 它是 Claude Code 原生 Workflow 引擎的 pilot 实现workflows/README.md 明确说明 ECC 目前的编排(orch-*multi-*、GAN/Santa loops)仍手工构建在 Task/Agent 工具之上,本脚本是"自主、fan-out 密集段"向原生引擎迁移的试点,因此运行环境依赖 Workflow 工具能力。
  2. 门禁归属不变:Gate 1(Plan 后)与 Gate 2(Commit 前)仍留在主会话;skills/orch-pipeline/SKILL.md 规定 Phase 6 Commit 走 conventional commits、CRITICAL/HIGH findings 必须在 Gate 2 之前解决。
  3. 集成状态:命令入口(commands/orch-review.md)、Workflow 实现(workflows/orch-review.workflow.js)、命令清单登记(docs/COMMAND-REGISTRY.json 与根 COMMANDS-QUICK-REF.md)均已就位;README 也列出了尚未完成的后续项(i18n 镜像、把 /orch-review 正式接入 orch-pipeline Review 相位作为原生选项、安装器清单接线、以及后续移植 Research 扫描与 Plan 评审组段)——因此部分能力仍属于 pilot 状态,接入完整 orch-* 主循环是规划中的下一步,而非已完成事实。
  4. 最终提交权在人:无论 verdict 是 APPROVE 还是 CHANGES_REQUESTED,Workflow 都不会自行 commit,呈现给 Gate 2 的 blocking 列表由人类确认后才放行。

综上所述,/orch-review 是一道把"多维并行审查 + 跨维度去重 + 对抗式验证 + fail-closed 判语"完整搬进原生 Workflow 引擎的命令面:向上它对人类提供一个干净的 verdict + blocking/advisory 二分类报告,向下它用结构化 schema、证据主键去重与 0.8 置信度阈值把"不确定不许放行"变成代码级事实。如果你在 ECC 的 orch-* 工作流中需要一个人工门禁可依赖的高置信 Review 环节,/orch-review 就是那个可复用、可追溯、且从设计上拒绝虚假批准的入口。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388