DeepSeek Harness GitHub 评审怎么接内部策略?run()、仓库映射与 202
GitHub 评审的默认规则只接受一个仓库、一个事件和一个动作,真正让它接入企业内部流程的是 run()。 它是普通受信任 JavaScript:在返回 Session 请求之前,可以查策略服务、把仓库名映射到本地 checkout,或直接返回 null 跳过。理解这一点,才能解释“webhook 返回 202 但没看到会话”和“同一 PR 生成了两个会话”这两类现象。
DeepSeek Harness:规则入口 run() 能做什么
run() 在签名校验之后、Session 创建之前执行,是策略插入的唯一位置。 三件事:(来源)
- 查内部策略 — 调公司策略服务,决定是否自动评审。预期:不满足条件时返回
null,不创建会话。 - 映射仓库路径 — 把
repository.full_name映射到本地绝对路径。预期:不同仓库落到不同 checkout。 - 返回 Session 请求 — 包含标题、workspacePath、提示词等。预期:交给 WorkspaceRegistry 规范化并启动只读评审。
run() 的返回值不是“HTTP 响应”,而是“要不要创建会话、创建在哪”。HTTP 202 在这之后才返回。
DeepSeek Harness:仓库映射与策略服务
两种最常见的扩展:按仓库选路径,按策略决定是否放行。 官方示例:(来源)
const response = await fetch('https://policy.internal/pr-review', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ repository: payload.repository.full_name }),
signal,
})
if (!response.ok || (await response.json()).automaticReview !== true) return null
const workspacePath = {
'deepseek-ai/deepseek-harness': '/path/to/deepseek-harness',
'deepseek-harness/dsh-sdk': '/path/to/dsh-sdk',
}[payload.repository.full_name]
if (workspacePath === undefined) return null
- 先判仓库 — 不在映射表里的仓库直接返回
null。预期:不会误在默认目录创建会话。 - 再判策略 — 策略服务不可用或返回不允许时返回
null。预期:失败关闭,不自动评审。 - 最后给路径 — 返回绝对路径,交给 WorkspaceRegistry。预期:首次创建,后续复用。
策略服务调用要带 signal,让请求可以跟随 webhook 的取消;不要在这里做长时间阻塞。
DeepSeek Harness:202 与交付语义
202 是“已接受并调度”,不是“已匹配并创建”。 三个边界:(来源)
- 202 不代表规则匹配 — 规则可能因为仓库、事件或动作不匹配而返回
null。 - 202 不代表 Session 已创建 — 规则调用只是进入内存调度。
- 重复交付会重复运行 — runtime 不存交付状态,重复 webhook 可能创建第二个 Session。
要判断是否真的创建,回到 DSH 的会话列表与日志;不要只看 GitHub 的投递记录。
DeepSeek Harness:安全边界
webhook 密钥只解决“请求是不是 GitHub 发的”,不解决“Agent 能不能改 GitHub”。 四条:(来源)
- payload 是不可信元数据 — 规则会把 JSON 标为不可信,不要把它当可信指令拼接。
- 评审会话只读 — 默认使用
standardagent preset 与read-onlypermission preset,禁止改文件、分支、PR 或 GitHub 状态。 - 密钥只验入站 — 不会给规则或 Agent 授予出站 GitHub 访问权。
- 工作区路径要可信 — 仓库映射表应由部署方维护,不要让 payload 决定任意本地路径。
如果企业策略服务本身需要认证,凭据应放在受控环境里,不要写进 webhook payload 或规则源码。
DeepSeek Harness:三种策略落地方式
硬编码、内部服务、映射表,复杂度与可控性依次上升。 三种:(来源)
- 硬编码白名单 — 只接受固定仓库与动作。预期:最简单,适合单仓库。
- 内部策略服务 — 每次评审前查询,按团队/分支/作者决定。预期:灵活,但策略服务故障会阻断评审。
- 映射表 + 默认拒绝 — 仓库到路径的显式映射,未命中即跳过。预期:路径可控,适合多仓库。
三种方式可以组合。最常见的是“映射表决定路径 + 策略服务决定是否放行”。
如果规则返回 null,webhook 仍会给出 202;这是设计上的弱响应,不是失败。排查时以 DSH 会话列表为准。
DeepSeek Harness:一个可运行的规则骨架
规则的核心是“先校验来源,再决定路径,最后返回 Session 请求或 null”。 骨架:(来源)
export async function run(payload, { signal }) {
if (payload.action !== 'ready_for_review') return null
if (payload.repository.full_name !== 'your-org/your-repo') return null
const workspacePath = '/srv/checkouts/your-repo'
return {
title: `Review PR #${payload.pull_request.number}`,
workspacePath,
prompt: `Review the changes in PR #${payload.pull_request.number}.`,
}
}
真实实现还应查询内部策略、处理 head SHA、限制提示词长度;但骨架能先验证 webhook、签名与 Workspace 路径是否通。
DeepSeek Harness 常见问题
Q:为什么配置了 webhook,PR 变成 ready 后没有会话?
先确认事件是 pull_request、动作是 ready_for_review,再看规则是否因为仓库或动作不匹配返回了 null。202 不能证明匹配成功。
Q:同一 PR 反复 ready 会重复评审吗? 可能会。runtime 不存交付状态;规则需要自己做幂等,例如查内部已评审记录。
Q:评审会话能不能改成可写? 可以改 preset,但这会突破默认只读边界;需要写操作时,应单独设计权限与审计,而不是直接放宽。
一句话收束: GitHub 评审的“策略”不在 YAML 里,而在 run() 里;202 只说明请求被接住了,是否真的评审要看规则与 Session。
常见问题
DeepSeek Harness 里,GitHub webhook 收到通过签名校验的 payload 后,overlay 会调用规则的 run()。它是普通受信任 JavaScript,在返回 Session 请求之前可以查内部策略服务、映射仓库路径,或返回 null 跳过。
DeepSeek Harness 里,在 run() 里用 payload.repository.full_name 做键,把仓库名映射到本地绝对路径;映射不到时返回 null。返回的 workspacePath 会交给 WorkspaceRegistry.create() 规范化,首次不存在时创建,后续复用。
DeepSeek Harness 里,不是。202 只表示签名与 JSON 已被接受、规则调用已在内存中调度;它不代表规则已匹配,也不代表已创建 Session。要看是否真的创建,得回到 DSH 的会话与日志。
DeepSeek Harness 里,可能。webhook runtime 不存储交付或执行状态,重复交付会再次运行规则,并可能创建另一个 Session。规则需要幂等时,应自己查内部状态或做去重。
DeepSeek Harness 里,不能。密钥只验证入站 GitHub 数据,不会给规则代码或创建的 Agent 授予出站 GitHub 访问权。需要读写 GitHub 时,必须单独配置权限。
相关术语
- github-review overlay
- github-review overlay 是 DeepSeek Harness 的可选配置层,为 dsh web 增加签名 GitHub 端点;PR 从 draft 变为 ready_for_review 时创建只读评审会话。— DeepSeek Harness 官方文档 - 通过 GitHub Webhook 创建评审会话
- run()
- run() 是 github-review 规则的受信任 JavaScript 入口,在返回 Session 请求前执行,可查询内部策略、映射仓库路径或返回 null 跳过。— DeepSeek Harness 官方文档 - 通过 GitHub Webhook 创建评审会话
- WorkspaceRegistry.create()
- WorkspaceRegistry.create() 是 DeepSeek Harness 规范化 workspacePath 的入口;首次匹配时若 Workspace 不存在会创建,后续交付复用同一个。— DeepSeek Harness 官方文档 - 通过 GitHub Webhook 创建评审会话
- 202
- 202 是 github-review webhook 的 HTTP 响应,表示签名与 JSON 已被接受、规则调用已在内存中调度,不表示规则匹配或 Session 已创建。— DeepSeek Harness 官方文档 - 通过 GitHub Webhook 创建评审会话
来源
- DeepSeek Harness 官方文档 - 通过 GitHub Webhook 创建评审会话· deepseek-ai
- DeepSeek Harness 官方参考 - 工作区· deepseek-ai