kovey/dsh-engineering-suite--packages-dsh-quality-gate ↗★ 0
dsh-quality-gate
Deterministic quality gate for DeepSeek Harness: host-configured test/typecheck/lint commands, PASS/WARN/BLOCK verdicts, a post-write lint feedback loop and a turn-stop gate that refuses to let an agent declare completion on red. 适合在Agent完成任务前强制运行测试和格式检查的开发流程。
インストール
$
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:kovey/dsh-engineering-suite#4a618ac4376c4a075c99c92b69895163bb21b0ce&path:packages/dsh-quality-gateドキュメント
README 全文を読む ↗项目级配置(同一个 dsh 进程服务多个仓库)
profile 配置是上限,每个仓库可以用自己的 .dsh/quality-gate.json 细化:
{
"commands": [
{ "id": "test", "name": "单元测试", "command": "cargo test", "required": true, "phase": "gate" },
{ "id": "clippy", "name": "clippy", "command": "cargo clippy", "required": false, "phase": "lint" }
],
"limits": { "maxChangedFiles": 30 },
"turnStop": { "maxBlocksPerTurn": 3 }
}
commands替换 profile 的命令集(Rust 仓库不该跑pnpm test);commands[].cwd相对会话工作区解析。- 可覆盖键:
commands、limits、defaultTimeoutMs、maxOutputBytes、writeTools、turnStop、afterWrite。 - 不可覆盖:
enabled、logFile、布局路径等宿主决策——写了也会被忽略并记日志(模型可能经 shell 改这个文件,所以它不能是"关掉门禁"的开关)。 - 文件损坏 → 回退 profile 配置并记日志;
commands: []是"这个仓库没有门禁命令"的显式决定 → 诚实 WARN 并指出文件路径。 quality_gate_run/quality_gate_status都会显示命令来源(profile 还是哪个项目文件)。
配置
- id: quality-gate
config:
logFile: '~/.dsh/quality-gate.log'
defaultTimeoutMs: 300000
writeTools: ['write', 'edit']
commands:
- id: test
name: 单元测试
command: pnpm test # 不经过 shell:按 shell-word 规则切分成 argv
required: true # 失败 → BLOCK
phase: gate # 只在收尾时跑
timeoutMs: 600000
- id: lint
name: ESLint
command: pnpm run lint
required: false # 失败 → WARN
phase: lint # 写文件后也跑
trigger:
turnStop: { enabled: true, maxBlocksPerTurn: 2 }
afterWrite: { enabled: true, blockOnFailure: true, maxPerTurn: 2 }
prompt: { enabled: true, order: 640 }
| 键 | 默认 | 说明 |
|---|---|---|
commands[] | [] | 命令表;phase: gate 默认必需,phase: lint 默认非必需 |
commands[].cwd | 会话工作区 | 子目录里跑命令 |
commands[].env | — | 追加环境变量 |
defaultTimeoutMs | 300000 | 未声明 timeoutMs 时的超时(超时按失败处理) |
maxOutputBytes | 64000 | 单命令输出上限(保留尾部) |
limits.maxChangedFiles | 0(关闭) | 一次任务的改动文件数上限(docs.md §9);超限 → BLOCK。计数来自 git status --porcelain,排除 .dsh/ 工程台账自身(否则任务自己的工件会吃掉预算);不是 git 仓库时按 fail closed 阻断 |
writeTools | ['write','edit'] | 触发写后 lint 与 pendingWrites 计数的工具(shell 改动靠收尾时的指纹兜底,不要加 bash) |
turnStop.enabled | true | 收尾门禁开关(长测试套件可关掉,改用 quality_gate_run) |
turnStop.maxBlocksPerTurn | 2 | 每轮最多纠正几次(防死循环)。0 = 照跑照记,但不 steer;负数 = 完全停用收尾门禁(连记录都不做) |
afterWrite.enabled | true | 写后 lint 开关 |
afterWrite.blockOnFailure | true | 失败时阻断工具结果 |
afterWrite.maxPerTurn | 2 | 每轮最多阻断几次 |