Shaance/review-surfaces

GitHub: Shaance/review-surfaces

一个本地优先的代码审查控制台,专为审查 AI 编程代理产生的代码变更而设计,通过基于本地证据的变更影响分析、测试削弱检测和信任审计帮助人工审查者高效判断 agent 变更的可信度。

Stars: 0 | Forks: 0

# review-surfaces **Agent 编写代码的信任层。** 这是一个本地优先的审查控制台,它回答了人类在审查 agent 产生的变更时真正关心的三个问题: 1. **Agent 是否超越了其指令?** — 变更影响图、引导式阅读顺序和语义变更事实(schema/API 契约 diff、新依赖、架构漂移)使 diff 的真实范围具体化。 2. **Agent 是否为了通过测试而削弱了测试?** — 测试削弱检测将删除的测试、新跳过的测试、移除的断言和重新生成的快照标记为头等风险。 3. **Agent 是否声称了它没有做过的事情?** — 信任审计和按句子的叙述信任标记将经过验证的声明与毫无根据的文字描述区分开来。*“Agent 说测试通过了;但没有记录可以证明”* 是任何通用审查机器人都无法产生的头条结论。 每个答案都基于本地证据——文件、diff、命令记录、覆盖率报告——而不是隐藏的聊天上下文。一切均在离线运行;默认的 provider 是确定性的,且不需要 API key。 **在安装前阅读一个数据包:** [`docs/example/`](https://github.com/Shaance/review-surfaces/blob/main/docs/example/README.md) 包含了对该工具从未见过的存储库(`sindresorhus/got`,无 spec,无 config)进行真实运行的未编辑输出——markdown 审查、HTML 控制台和置顶评论,以及生成它们的精确命令。 ## 快速开始 适用于任何 git 存储库——无需配置、无需 spec 文件、无需设置: ``` cd your-repo npx review-surfaces all open .review-surfaces/human_review.html # the cockpit; human_review.md is the text surface ``` 基准分支会自动解析为您的默认分支(origin/HEAD、origin/main、origin/master、main、master——以第一个存在的为准);传递 `--base ` / `--head ` 来审查不同的范围。无法解析的基准分支是一个严重的错误,消息中会包含修复方法——绝不会产生静默错误审查。 该命令会生成一个合并就绪结论、一个按优先级排序的审查优先队列(包含内联 diff 片段和“为何排在此处”的说明)、diff 的引导式阅读顺序、变更影响图、信任审计、审查者问题、具体的测试计划以及建议的审查评论——所有内容都保存在 `.review-surfaces/` 下,并且都根据已签入的 schema 进行了验证(`npx review-surfaces validate .review-surfaces --surface all`)。 ## 您会得到什么 ### HTML 控制台 每次 `review-surfaces all` 运行都会写入一个独立的 `human_review.html` 文件(也可以通过 `review-surfaces human --format html` 单独获取)——包括结论、lens 过滤器、阅读顺序、带有每行覆盖率边界的排名队列、带有概览 ↔ 缩放功能的可点击 SVG 变更图,以及进度跟踪。无需服务器,无需 CDN,可直接从磁盘打开: ![HTML 控制台:结论、lens 标签和引导式阅读顺序](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/9db3bf7e01013224.png) ### 变更图 两个缩放级别,根据可读性预算进行选择,因此无论 diff 大小如何,该图都保持可读。小型 diff 会获得文件级别的映射:按模块分组的已更改文件、它们之间的导入边、变动和风险 lens 色调,以及依赖于所更改内容的未更改文件的光晕。当 diff 范围太宽而无法逐个文件清晰地渲染时,会改为使用**概览**作为引导——每个顶层区域一张卡片,包含文件/集群计数、变动和加权边(考虑了模型中的每一条导入边)——在控制台中点击卡片会放大到该区域的详细视图(其文件、内部边和明确的“→ 其他区域 ×N”存根端口)。在控制台中渲染为确定性的内联 SVG,在评论界面上渲染为 mermaid;布局会自动换行而不是缩小,因此任何内容都不会以小于全尺寸的方式渲染: ![变更图概览:每个区域一张卡片、加权边和爆炸半径光晕](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5b9688ba6a013230.png) ### 置顶 PR 评论 可重用的 GitHub Action(或在本地使用 `review-surfaces comment --format sticky`)会在每个 PR 下发布一条幂等评论:结论、带有 diff 片段的顶部队列项,以及每次 push 时的自上次审查以来的增量变化: ![置顶 PR 评论:结论、审查优先队列、内联 diff 片段](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/46187cb2b8013235.png) 这三张截图均来自该工具在其自身存储库上的真实运行——该项目使用自身审查自身(相关故事请参见 [`docs/history/`](https://github.com/Shaance/review-surfaces/tree/main/docs/history))。 ## 范围:分析实际涵盖的内容 对深度的诚实态度,以便您可以校准信任度: - **以 TypeScript/JavaScript 为先的深度分析。** 导入图、导出的 API 表面 diff、爆炸半径(“此移除的导出被 14 个文件使用”)和架构漂移事实会解析 TS/JS 源代码(通过 TypeScript 编译器)。实现根目录的检测会读取*您*仓库的 `tsconfig.json` 和 `package.json`——`source/` 布局的分类方式与 `src/` 完全一样。 - **在其他地方保持语言无关。** 测试削弱信号、机密扫描、覆盖率增量(任何 `lcov.info`)、依赖/lockfile 事实、CI 工作流、Dockerfile 和 SQL 迁移检查、JSON-schema 契约 diff、变更图的聚类、信任审计以及审查队列本身适用于任何存储库。 - **契约保证的确定性。** 相同的输入产生字节完全相同的产物。LLM 输出是可选的扩展,绝不会被当作证明——参见 [Provider](#providers)。 - **诚实的否定。** 没有覆盖率报告会显示为“没有覆盖率证据”,绝不会显示为红色。无法解析的 lockfile 会产生“没有 lockfile 事实”,绝不是猜测。截断的导入图会抑制漂移事实,而不是断言它无法证明的新颖性。 种子化回归评估工具在 CI 中对审查质量本身进行门控——此 README 底部的 [记分板](#eval-scoreboard) 是根据其结果重新生成的。 ## 本地审查循环(无需 CI) ``` pnpm run local-review # produce every surface for your branch + validate them pnpm run local-gate # the full merge gate: lint, typecheck, tests, # determinism-check, packaging smoke test, strict self-review ``` `local-review` 接受 `--base `、`--head `、`--out `、`--provider ` 和 `--previous `(用于自上次审查以来增量的先前数据包;最后一次本地运行会被自动检测)。网络使用:仅限 git。GitHub Actions 是这些审查界面的分发渠道,但绝不是生成或验证它们的唯一方式——此仓库中的 `action.yml` 只是基于同一本地流水线的轻量级渲染器。 ### 作为 GitHub Action 使用 相同的流水线可作为可重用的复合 action 运行。发布到 PR 是**仅限同仓库**的:它需要写入 token,因此它必须在 `pull_request_target` 上运行——从基准分支进行评估——并受到排除分支头部的 `if:` 保护。默认的 `provider: mock` 就可以很好地发布确定性的置顶摘要(此仓库自己的 `ci.yml` 冒烟测试就是那样渲染它的);只有当您想在评论界面上呈现 LLM 叙述时,才添加带有 API-key secret 的 `provider: ai-sdk`。 在**您的**仓库中,运行该工具的步骤是以下代码片段: ``` # 在你的 pull_request_target job 中运行该工具的那一个步骤 — 关于周围的 job、split checkouts 和 permissions,请参见下面的 # worked example - uses: Shaance/review-surfaces@8ba7c46d73f429c71060040463899333fdd92c9d # pin a full SHA you trust with: provider: mock # mock posts the deterministic sticky; switch to ai-sdk for the LLM narrative spec: features/**/*.feature.yaml # YOUR spec(s); the action defaults to this repo's own spec base-ref: origin/${{ github.base_ref }} head-ref: HEAD subject-directory: subject # PR head, checked out credentialless pr-number: ${{ github.event.pull_request.number }} github-token: ${{ github.token }} post: "true" ``` `Shaance/review-surfaces` 是一个**从固定的 commit 处从源码构建的复合 action**——执行调用的 runner 会在该 SHA 处检出 action 仓库并运行 `pnpm install --frozen-lockfile && pnpm run build`。因此,默认分支上的任何真实 commit 都是有效的固定版本(上面的 SHA 仅供说明);请固定一个您信任的版本。 由于它是从源码构建的,因此您的作业需要与示例中展示的相同设置(checkout + 无凭据拆分——pnpm/Node 由 action 提供)。 请固定到**完整的 40 字符 commit SHA**,而不是标签或分支:像 `@v0.2.0` 这样的标签可以被移动或删除,而 `@main` 是可变的,因此这两者以后都可能将您的写入 token 或 LLM key 重定向到受攻击者控制的代码。 此仓库自己的 [`.github/workflows/pr-review-comment.yml`](https://github.com/Shaance/review-surfaces/blob/main/.github/workflows/pr-review-comment.yml) 是连接方式的实际**参考**——`pull_request_target` 触发器、同仓库的 `if:` 保护、`permissions:` 块(包括 `actions: read`)以及无凭据拆分 checkout。不要逐字复制:因为 action 的源代码位于*此*仓库中,所以该文件将基础 ref 检出到 `tool/` 中并运行 `uses: ./tool`(仓库内 action)。采用相同的作业结构,但**将 `uses: ./tool` 替换为 `uses: Shaance/review-surfaces@`**(即上面的代码段),以便您的作业运行固定的 action。 作业的 `permissions:` 块授予 `contents: read`、`pull-requests: write` 和 `actions: read` ——最后一个是必需的,否则先前数据包的 artifact 查找会被拒绝(被作为首次审查的回退吞没),并且自上次审查以来的增量永远不会出现。 同仓库的 `if:` 保护是核心关键。`pull_request_target` 在**基准**仓库的上下文中运行,因此 `GITHUB_TOKEN` 是读/**写**的,并且仓库的 secret 会暴露出来——即使对于来自公共 fork 的 PR 也是如此(fork 在这里**不会**获得只读 token)。该保护(`head.repo.full_name == github.repository`)可防止不受信任的 fork 接触到带有 secret 的发布路径。相反,Fork PR 由另一个单独的纯 `pull_request` 作业(`provider: mock`,无 secret,`post: "false"`)提供服务,该作业上传 artifact 而不是发布——即此仓库 `ci.yml` 中仅上传的 `pr-surface-smoke` 模式。 ### 退出代码 `review-surfaces`(和 `--strict`)针对每种失败类别返回一个不同的退出代码,因此 CI 步骤可以在不解析 artifact 的情况下进行分支处理: | 代码 | 含义 | | --- | --- | | `0` | 成功 — 运行完成(并且在 `--strict` 下,门控已通过)。 | | `1` | 运行时错误 — 运行期间发生的意外失败。 | | `2` | 使用错误 — 错误的标志或参数。 | | `3` | Schema 验证失败 — 生成的 artifact 与其 schema 不匹配。 | | `4` | 证据验证失败 — 声明的证据无效(无法锚定到本地证据)。 | | `5` | 隐私被阻止 — 隐私/机密边界检查拒绝继续执行。 | | `10` | 质量门控失败 — `--strict` 发现缺失的要求超过了配置的 max-missing,或者确定性风险达到或超过了 `--fail-on` 严重性阈值。 | 质量门控(代码 `10`)有两个方面:缺失要求预算(`--max-missing` / `quality_gate.max_missing`)和风险严重性门控(`--fail-on ` / `quality_gate.fail_on`)。例如,设置 `--fail-on high`,以便在任何确定性(非假设)风险达到或超过 `high` 时也会失败。这两个方面都可以与 `--strict` 组合使用。 该表格涵盖了 review-surfaces 命令自身的门控和使用代码。`review-surfaces run -- ` 则**转发被包装命令自身的退出代码**,因此当您使用 `run` 记录被包装的测试命令时,可能会出现此表格之外的代码(例如 `7`、`127`)。 ## 命令 | 命令 | 作用 | | --- | --- | | `all` | 运行整个本地流水线并写入每个审查界面。添加 `--surface-mode pr` 以获取 PR 范围的 sidecar。 | | `human` | 从现有 artifact 渲染 `human_review.json` / `human_review.md`(以及用于控制台的 `--format html`),无需重新计算。 | | `comment` | 渲染 PR 评论。`--format sticky` 用于幂等的置顶摘要,`--format sarif` 用于 SARIF,`--format review` 用于 GitHub 待处理(草稿)审查,其中包含基于 hunk 锚定的建议评论——绝不会自动提交。 | | `review` | 排名队列的交互式演练;接受 / 标记 / 误报 / 评论决策会反馈到本地反馈记忆中,以便后续运行进行调整。 | | `validate [dir]` | 根据内置 schema 验证生成的 artifact(`--surface packet\|human\|pr\|all`)。可在任何目录下工作。 | | `run [--id ] -- ...` | 执行命令并记录有限的记录作为直接证据(这就是“测试通过变得可验证的方式)。 | | `queue` / `comments` / `trust` / `risk-lenses` / `intent-mismatch` / `routes` / `evidence-cards` / `since-last-review` / `test-plan` | 从 `human_review.json` 渲染的专注独立部分。 | | `init [--force]` / `bootstrap [--strict]` | 搭建(创建或验证)或仅验证仓库的 review-surfaces 设置。 | | `scoreboard [--check]` | 从 `eval_scoreboard.json` 重新生成(或验证)README 中的评估记分板块。 | 运行 `npx review-surfaces --help` 获取完整的选项列表。常用选项:`--base` / `--head`(diff 范围;base 会自动解析为默认分支)、`--out`(artifact 目录,默认为 `.review-surfaces`)、`--provider mock|agent-file|ai-sdk`、`--coverage `(自动检测 `coverage/lcov.info`)、`--budget 15m`(阅读/略读/推迟审查计划)、`--previous-packet `(轮次间的增量)。 ## Provider - **`mock`**(默认):完全确定性,离线。上面介绍的所有功能均在此模式下工作。 - **`agent-file`**:编码 agent 通过 `--agent-input ` 贡献有限的、经过 schema 检查的假设——无需网络。 - **`ai-sdk`**:可选的实时 LLM 扩展(基于确定性事实的叙述性文字)。隐私过滤和机密脱敏会在任何远程调用之前运行;凭据保存在本地 `.env.local` 中,从不提交。 LLM 和 agent 输出绝不会被当作证明:每个声明都必须通过确定性的锚点验证,否则将被降级为带有可见标记的未验证声明。LLM 输出不能创建或清除阻碍、更改覆盖率状态或更改结论。 ## 可选的增强功能 该工具在零配置下已完全可用。以下每一层都是可选的: - **`review-surfaces.config.yaml`** — 审查区域、风险 lens 切换、有限的输出上限、每个路径模式所需的手动检查(例如“在结论可以清除之前,任何 `.github/workflows/**` 更改都必须记录一次机密边界检查”)。 - **Acai 风格的功能规格**(`features/*.feature.yaml`)— 需求账本层。在索引了规格之后,每个需求都会获得一个实现和测试覆盖率状态(`satisfied` / `partial` / `missing` / `overreach`)、意图与 diff 不匹配的发现,以及适用于 CI 的严格质量门控(`--strict`)。如果没有规格,数据包只需说明一次(`spec_mode: none`),并且每个基于 diff 生成的审查界面仍然有效——无规格仓库是一条一等路径,而不是降级模式。 - **`review-surfaces.policy.yaml`** — 已提交的、经过 schema 验证的团队策略:带有原因和过期日期的抑制、严重性覆盖、所需的手动检查。与本地反馈记忆组合使用(从不替换)。 - **覆盖率、测试结果和记录** — 将 `--coverage` 指向 lcov 报告,将 `--test-output` 指向 JUnit XML,或者将命令包装在 `review-surfaces run` 中,以将“作者声称测试通过”升级为经过验证的证据。 ## 安装 / 开发 - Node.js `>= 22`,[pnpm](https://pnpm.io/)(版本通过 `packageManager` 固定)。 ``` pnpm install --frozen-lockfile pnpm run build # compiles the CLI to dist/, executable at bin/review-surfaces.js pnpm run test # full suite (includes the seeded-regression eval harness) ``` 有关 PR 工作流程,请参见 [`CONTRIBUTING.md`](https://github.com/Shaance/review-surfaces/blob/main/CONTRIBUTING.md);有关面向 agent 的工作规则,请参见 [`AGENTS.md`](https://github.com/Shaance/review-surfaces/blob/main/AGENTS.md)(此仓库采用 spec 优先和 dogfood 优先的方式开发)。 ## 项目布局 - `src/` — CLI 和流水线模块(收集器、意图、评估、图表、方法论、风险、人类控制台、渲染、schema、隐私、provider)。 - `schemas/` — 用于数据包、人工审查模型、PR sidecar 和策略文件的 draft 2020-12 契约(与包捆绑在一起;`validate` 可在任何目录下工作)。 - `features/review-surfaces.feature.yaml` — 此仓库本身的需求权威账本。 - `docs/history/` — 构建此工具所依据的目标文件和头脑风暴,agent 优先,在每个阶段都进行自我审查。 - `.review-surfaces/` — 生成的本地优先 artifact。 ## License [MIT](https://github.com/Shaance/review-surfaces/blob/main/LICENSE)。 ### 评估记分板 种子化回归评估工具(在 `pnpm run test` 内运行)目前能在审查队列的前 10 名中,捕捉到 13 个事实类别中的 **13/13** 个种子案例: | 事实类别 | 前 N 名中的案例 | | --- | --- | | api_break | 1/1 | | arch_drift | 1/1 | | benign_format | 1/1 | | benign_redaction_placeholder | 1/1 | | benign_rename | 1/1 | | blast_radius | 1/1 | | ci_permission_broadening | 1/1 | | destructive_migration | 1/1 | | schema_change | 1/1 | | secret_in_diff | 1/1 | | sneaky_dependency | 1/1 | | uncovered_changed_lines | 1/1 | | weakened_test | 1/1 | _由 `review-surfaces scoreboard` 基于 `.review-surfaces/eval_scoreboard.json` 生成;请勿在标记内编辑。_
标签:AI辅助编程, CCS 2025, MITM代理, 代码审查, 多模态安全, 威胁情报, 开发者工具, 数据可视化, 数据管道, 本地离线工具, 自动化攻击, 软件工程