# ЁЯдЦ dsh-auto-review
**DeepSeek Harness рдХреЗ рд▓рд┐рдП рджреНрд╡рд┐рддреАрдп-рдореЙрдбрд▓ AI рдЕрдиреБрдореЛрджрди тАФ рдПрдХ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдореАрдХреНрд╖рдХ рдЙрдк-рдПрдЬреЗрдВрдЯ рдЕрдиреБрдореЛрджрди рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкрд░ рдЕрдиреБрдорддрд┐/рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд╛ рдирд┐рд░реНрдгрдп рдХрд░рддрд╛ рд╣реИ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рдлрд▓-рдмрдВрджред**
*рдЬрдм рдХреЛрдИ рдХреНрд░рд┐рдпрд╛ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд╕реАрдорд╛ рдкрд╛рд░ рдХрд░рддреА рд╣реИ, рддреЛ рджреВрд╕рд░рд╛ рдореЙрдбрд▓ рд╕рд╛рдХреНрд╖реНрдп рдкрдврд╝рддрд╛ рд╣реИ рдФрд░ рдХрд╛рд░рдг рд╕рд╣рд┐рдд рдирд┐рд░реНрдгрдп рд▓реМрдЯрд╛рддрд╛ рд╣реИ тАФ рддрд╛рдХрд┐ рдордиреБрд╖реНрдп рдХреБрдЫ рднреА рд╕реНрд╡реАрдХреГрдд рди рдХрд░реЗрдВ рдФрд░ рдХреБрдЫ рднреА рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдЫреВрдЯ рди рдЬрд╛рдПред*
> **рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реАред** рдпрд╣ PerryLink рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░рдХреНрд╖рд┐рдд dsh-auto-review рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА рд╣реИред рдЕрдиреНрдп рдЦрд╛рддреЛрдВ рдХреЗ рд╕рдорд╛рди-рдирд╛рдо рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА рдЗрд╕рд╕реЗ рд╕рдВрдмрджреНрдз рдирд╣реАрдВ рд╣реИрдВред
[](LICENSE)
[](https://gitee.com/perrylink/dsh-auto-review)
[](https://github.com/topics/dsh-plugin)
[](https://github.com/PerryLink/dsh-plugin-doctor#verified-х╛╜чла)
[](#)
[](https://github.com/PerryLink/dsh-auto-review/actions)
[](https://github.com/PerryLink/dsh-auto-review/releases)
[](https://www.npmjs.com/package/dsh-auto-review)
[](https://www.npmjs.com/package/dsh-auto-review)
[English](README.md) ┬╖ [чоАф╜Уф╕нцЦЗ](README-zh.md) ┬╖ [Espa├▒ol](README-es.md) ┬╖ [Portugu├кs](README-pt.md) ┬╖ [рд╣рд┐рдиреНрджреА](README-hi.md)
---
## рдЕрдиреБрдХреВрд▓рддрд╛
| рд╕рддрд╣ | рд╕реНрдерд┐рддрд┐ |
|---|---|
| Harness | DeepSeek Harness `dsh-v0.1.6-alpha.2` (2026-09-18 рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд)ред рджреЛрд╣рд░реА-рд▓рд╛рдЗрди npm рд╕рдорд░реНрдерди: dev рдкрд┐рди рдФрд░ рд░рдирдЯрд╛рдЗрдо рдирд┐рд░реНрднрд░рддрд╛рдПрдБ `0.1.5-rc.2`, peers `>=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0 \|\| >=0.1.6-0 <0.2.0` тАФ рдкреНрд▓рдЧрдЗрди рдХреЛрдб рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реЛрд╕реНрдЯ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдлрд╝реАрдЪрд░-рдбрд┐рдЯреЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╣рд░ рд▓рд╛рдЗрди рдкреВрд░реА рдЧреЗрдЯ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЪрд▓рд╛рддреА рд╣реИ; рд░рдирдЯрд╛рдЗрдо рдирд┐рд░реНрднрд░рддрд╛рдПрдБ alpha рд▓рд╛рдЗрди рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреА рд╣реИрдВ рддрд╛рдХрд┐ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЗрдВрд╕реНрдЯреЙрд▓ рд╣реЛрд╕реНрдЯ рдХреЗ рдЕрдкрдиреЗ рдЯреНрд░реА рдХреЛ рд╢реИрдбреЛ рди рдХрд░реЗрдВред alpha.2 рд▓рд╛рдЗрди рдкрд░ eval рдлрд╝рд┐рдХреНрд╕реНрдЪрд░ `deepseek-flash` рдкрд┐рди рдХрд░рддреЗ рд╣реИрдВ (рд╣рдЯрд╛рдпрд╛ рдЧрдпрд╛ `deepseek-v4-flash` рдЕрдм `eval/` рдореЗрдВ рдирд╣реАрдВ рд╣реИ)ред |
| Node | `^22.19.0 \|\| >=24.0.0` |
| рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо | рд╕рднреА (рд╣реЛрд╕реНрдЯ answerer; рд╕рддреНрд░-рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдХреНрд╖рдорддрд╛ рдХреЗ рдЬрд╝рд░рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡реЗрдм рд╕рдореАрдХреНрд╖рд╛ рдкреИрдирд▓) |
| рдореЙрдбрд▓ | рдХреЛрдИ рднреА (рд╕рдореАрдХреНрд╖рдХ рд╕рддреНрд░ рдПрдЬреЗрдВрдЯ рдХрд╛ рдорд╛рд░реНрдЧ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ; `reviewerModel` рдЙрд╕реЗ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ) |
## рдЖрдкрдХреЛ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ
`dsh-auto-review` `approval/request` answerer рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкрд░ рджреВрд╕рд░рд╛ рдореЙрдбрд▓ рд░рдЦрддрд╛ рд╣реИ:
1. **рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕реАрдо** тАФ рдПрдХ answerer рдЬреЛ рдХреЗрд╡рд▓ рдЕрдкрдиреА рд╕реАрдорд╛ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ (`ai` рдиреАрддрд┐) рдХреЛ рдЕрдкрдирд╛рддрд╛ рд╣реИ рдФрд░ рдмрд╛рдХреА рд╕рдм `next()` рд╕реЗ рд╕реМрдВрдк рджреЗрддрд╛ рд╣реИ; рдорд╛рдирд╡ рдЕрдиреБрдореЛрджрди рдкреНрд░рд╡рд╛рд╣ рдХрднреА рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ред
2. **рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдореАрдХреНрд╖рдХ рдЙрдк-рдПрдЬреЗрдВрдЯ** тАФ `read`/`glob`/`grep` рдЯреВрд▓ рдЕрдиреБрдорддрд┐-рд╕реВрдЪреА рд╡рд╛рд▓рд╛ рдПрдХ-рдмрд╛рд░ рдХрд╛ fork рд╕рдВрд░рдЪрд┐рдд рдирд┐рд░реНрдгрдп `{ decision, reason, riskLevel }` рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд╕рдореАрдХреНрд╖рдХ рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд╣рдЪрд╛рди рд╕реЗ рдкрд╣рдЪрд╛рдиреЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╕реМрдВрдк рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ; `maxDepth` + рдЕрдиреБрдорддрд┐-рд╕реВрдЪреА рд╕рдореАрдХреНрд╖рдХ рдХреЛ рдЧреИрд░-рдкреНрд░рддреНрдпрд╛рдпреЛрдЬрдХ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред
3. **рд╡рд┐рдлрд▓-рдмрдВрдж** тАФ рд╕рдореАрдХреНрд╖рдХ рдХреНрд░реИрд╢, рдЯрд╛рдЗрдордЖрдЙрдЯ рдпрд╛ рд╕реНрдХреАрдорд╛ рдмреЗрдореЗрд▓ `fallbackPolicy` (рдбрд┐рдлрд╝реЙрд▓реНрдЯ `rejected`) рд╕реЗ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ; рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдирд┐рд░реНрдгрдп рдЕрдкрдирд╛ рдХрд╛рд░рдг рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдореЙрдбрд▓ рдХреЛ рд▓реМрдЯрд╛ рджреЗрддрд╛ рд╣реИред
4. **рдХреЙрдиреНрдлрд╝рд┐рдЧ-рдЪрд╛рд▓рд┐рдд рд░реВрдЯрд┐рдВрдЧ** тАФ рдкреНрд░рддрд┐-рдЯреВрд▓ рдиреАрддрд┐рдпрд╛рдБ (`ai`/`human`/`never`) рдФрд░ regex рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо, рд╕рдм cordis.yml рд╕реЗ рдмрджрд▓реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
5. **рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХрд╛рд░рдг рдореЙрдбрд▓ рддрдХ рдкрд╣реБрдБрдЪрддреЗ рд╣реИрдВ** тАФ рд╕рдореАрдХреНрд╖рдХ рдХрд╛ рдХрд╛рд░рдг рдЕрд╕реНрд╡реАрдХреГрдд рдЯреВрд▓ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (callId-рд▓рд┐рдВрдХреНрдб); fallback рдФрд░ `never`-рдиреАрддрд┐ рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпрд╛рдБ рднреА рдСрдбрд┐рдЯ-рдпреЛрдЧреНрдп рдорд╛рд░реНрдХрд░ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддреА рд╣реИрдВ (`[auto-review]` / `[auto-review-fallback]` / `[auto-review-never]`)ред
6. **рдкреВрд░реНрдг рдСрдбрд┐рдЯ рдЯреНрд░реЗрд▓** тАФ рдХреЗрд╡рд▓-рд▓реЙрдЧ `autoReview/verdict` + `autoReview/rejection` рд╕рддреНрд░ рдШрдЯрдирд╛рдПрдБ (рд▓рд┐рдлрд╝рд╛рдлрд╝рд╛ `ignorable: true`) рдФрд░ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ invariant рд╕рд╛рдереА рдЬреЛ рдорд╛рд░реНрдХрд░ тЯ║ рдШрдЯрдирд╛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
7. **рд╕реБрд░рдХреНрд╖рд╛ рдирд┐рдпрдВрддреНрд░рдг** тАФ рдЕрд╕реНрд╡реАрдХреГрддрд┐ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░ (3 рд▓рдЧрд╛рддрд╛рд░ рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпрд╛рдБ, рдпрд╛ рдЕрдВрддрд┐рдо 10 рдирд┐рд░реНрдгрдпреЛрдВ рдореЗрдВ рд╕реЗ 6, рдкреНрд░рддрд┐ рдЯрд░реНрди), рдПрдХ рдЬреЛрдЦрд┐рдо-рд╕реНрддрд░ рдиреАрддрд┐, рдПрдХ-рдмрд╛рд░ рдХрд╛ `/auto-review approve` рдУрд╡рд░рд░рд╛рдЗрдб, рдФрд░ рдПрдХ `never`-рдиреАрддрд┐ рдХрдареЛрд░ рдЕрдХреНрд╖рдорддрд╛ рдЬреЛ рдореЙрдбрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рд╕рдордЭрд╛рддреА рд╣реИред
8. **рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдореАрдХреНрд╖рдХ рд╕рдВрджрд░реНрдн** тАФ рдПрдХ рд╕реАрдорд┐рдд рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ (`contextBudget`) рдФрд░ рдПрдХ Codex-рд╢реИрд▓реА Markdown рдирд┐рд░реНрдгрдп-рдиреАрддрд┐ (`reviewerPolicyText`)ред
рд╣рд░ рдирд┐рд░реНрдгрдп рд╕рддреНрд░ рд▓реЙрдЧ рд╕реЗ рдкреБрдирд░реНрдирд┐рд░реНрдорд┐рдд рд╣реЛрддрд╛ рд╣реИ: `approval/asked` тЖТ `autoReview/verdict` (рдпрд╛ `autoReview/rejection`) тЖТ `approval/decided`ред
## рдирд┐рдпрдореЛрдВ рдХреЗ рдмрдЬрд╛рдп рджреВрд╕рд░рд╛ рдореЙрдбрд▓ рдХреНрдпреЛрдВ?
рдкреИрдЯрд░реНрди-рдЖрдзрд╛рд░рд┐рдд рд╕реНрд╡рддрдГ-рдЕрдиреБрдореЛрджрдХ рдкреНрд░реЗрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ, рдмрд┐рдирд╛ рд╕рд╛рдХреНрд╖реНрдп рдХреЗ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВред `dsh-auto-review` рдирд┐рд░реНрдгрдп рдПрдХ **рд╕рдореАрдХреНрд╖рдХ рдЙрдк-рдПрдЬреЗрдВрдЯ** рдХреЛ рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд░реНрдХрд╕реНрдкреЗрд╕ (рдЕрдкрдиреЗ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓реЗ рдЯреВрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдЬрд╝рд░рд┐рдП), рдкрд╣рд▓реЗ рд╕реЗ рд╕реНрдЯреНрд░реАрдо рдХрд┐рдП рдЧрдП рдЯреВрд▓-рдХреЙрд▓ рддрд░реНрдХ (рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдорд╛рди рд╕рдВрд╢реЛрдзрд┐рдд), рдЕрдиреБрд░реЛрдз рдХрд╛ рдХрд╛рд░рдг рдФрд░ рдЖрдкрдХреЗ рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо рдкрдврд╝рддрд╛ рд╣реИ тАФ рдлрд┐рд░ рд╕рдВрд░рдЪрд┐рдд рдирд┐рд░реНрдгрдп рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдирд┐рд░реНрдгрдп рдЕрдкрдирд╛ **рдХрд╛рд░рдг рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдореЙрдбрд▓ рдХреЛ рд▓реМрдЯрд╛ рджреЗрддрд╛ рд╣реИ**, рддрд╛рдХрд┐ рдПрдЬреЗрдВрдЯ рдЕрдВрдзрд╛рдзреБрдВрдз рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдХрд╛рд░рдг рд╕реАрдЦреЗред
## рддреНрд╡рд░рд┐рдд рд╢реБрд░реБрдЖрдд
```sh
# 1. рдЕрдкрдиреЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдмрдВрдбрд▓ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ
dsh plugin --profile web add "github:PerryLink/dsh-auto-review#main"
# рдпрд╛ npm рд╕реЗ (рдкреНрд░рдХрд╛рд╢рд┐рдд рд░рд┐рд▓реАрдЬрд╝)
dsh plugin --profile web add dsh-auto-review
# 2. рдкреБрдирдГ рдкреНрд░рд╛рд░рдВрдн рдХрд░реЗрдВ рдФрд░ рдкрдВрдХреНрддрд┐ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ
dsh --profile web --dump-config | grep -A4 'id: auto-review'
```
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╢рд┐рдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреИрдЪ `bash` рдФрд░ `write` рдХреА AI рд╕рдореАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ; рдмрд╛рдХреА рд╕рднреА рдЯреВрд▓ (`edit` тАФ рдЗрди-рдкреНрд▓реЗрд╕ рд╕рдВрд╢реЛрдзрди тАФ рд╕рд╣рд┐рдд) рдорд╛рдирд╡ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рд╕реМрдВрдк рджреЗрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рд▓реВрдк рдореЗрдВ рдмрд┐рдирд╛ рдорд╛рдирд╡ рдХреЗ рдЗрди-рдкреНрд▓реЗрд╕ рд╕рдВрдкрд╛рджрди рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ `edit: ai` рдЬреЛрдбрд╝реЗрдВред
## рдЗрдВрд╕реНрдЯреЙрд▓ рдФрд░ рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓
- **git рдЪреИрдирд▓** (рдирд╡реАрдирддрдо `main`): `dsh plugin --profile web add "github:PerryLink/dsh-auto-review#main"` тАФ рдкреГрдердХ `prepare` рдмрд┐рд▓реНрдб рдХреЛ рд╡рд╣ рдПрдХрд▓ `allowBuilds: { esbuild: true }` рдХреБрдВрдЬреА рдЪрд╛рд╣рд┐рдП рдЬреЛ `dsh` CLI `dsh-auto-review` рдХреЗ рд▓рд┐рдП рдЫрд╛рдкрддрд╛ рд╣реИред
- **npm рдЪреИрдирд▓** (рдкреНрд░рдХрд╛рд╢рд┐рдд рд░рд┐рд▓реАрдЬрд╝): `dsh plugin --profile web add dsh-auto-review`ред
- **1024 рд╕реНрдЯреЛрд░ рдЪреИрдирд▓**: рдПрдХ рдмрд╛рд░ `npm i -g dsh1024`, рдлрд┐рд░ `dsh1024 plugin --profile web add dsh-auto-review` ([deepseek1024.com](https://deepseek1024.com) рдЗрдВрд╕реНрдЯреЙрд▓ рд░реИрдВрдХрд┐рдВрдЧ рдореЗрдВ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИ)ред
- **tarball рдЪреИрдирд▓**: рдЗрд╕ рд░реЗрдкреЛ рдореЗрдВ `pnpm pack`, рдлрд┐рд░ `dsh plugin --profile web add ./dsh-auto-review-.tgz`ред
- **рдЕрдирдЗрдВрд╕реНрдЯреЙрд▓**: `dsh plugin --profile web remove dsh-auto-review` (рдпрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреИрдЪ рд╕реЗ рдкрдВрдХреНрддрд┐ рд╣рдЯрд╛рдПрдБ)ред
## рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди
рд╕рднреА рдЯреНрдпреВрдиреЗрдмрд▓ Schemastery `Config` рдлрд╝реАрд▓реНрдб рд╣реИрдВ (cordis.yml рд╕реЗ рдмрджрд▓реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред id-рд▓рдХреНрд╖рд┐рдд рдУрд╡рд░рд░рд╛рдЗрдб рдкреВрд░реА рдкрдВрдХреНрддрд┐ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ тАФ рд╣рд░ рдЬрд╝рд░реВрд░реА рдХреБрдВрдЬреА рджреЛрдмрд╛рд░рд╛ рд▓рд┐рдЦреЗрдВред
| рдХреБрдВрдЬреА | рдбрд┐рдлрд╝реЙрд▓реНрдЯ | рдЕрд░реНрде |
|---|---|---|
| `enableByDefault` | `true` | рд╕рддреНрд░ auto-review рд╕рдХреНрд╖рдо рд╣реЛрдХрд░ рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВ; `/auto-review on\|off` рдПрдХ рдЯрд┐рдХрд╛рдК рдУрд╡рд░рд░рд╛рдЗрдб рд▓рд┐рдЦрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рдкрд░ рднрд╛рд░реА рдкрдбрд╝рддрд╛ рд╣реИ |
| `toolsPolicy.default` | `human` | рдЕрд╕реВрдЪреАрдмрджреНрдз рдЯреВрд▓ рдХреА рдиреАрддрд┐ (рдорд╛рдирд╡ answerer рдХреЛ рд╕реМрдВрдкрдирд╛) |
| `toolsPolicy.overrides` | `{}` | рдкреНрд░рддрд┐-рдЯреВрд▓ рдиреАрддрд┐: `ai` / `human` / `never` |
| `riskRules` | `[]` | рдЯреВрд▓ рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрд╣рд▓реЗ рдорд┐рд▓рд╛рдпрд╛ рдЧрдпрд╛ `{pattern, policy, field?}`; `field` рдЪреБрдирддрд╛ рд╣реИ `reason` (рдбрд┐рдлрд╝реЙрд▓реНрдЯ), `toolName` рдпрд╛ `arguments` |
| `reviewerProvider` | `fork` | рд╕рдореАрдХреНрд╖рдХ рдХрд╛ рдЙрдк-рдПрдЬреЗрдВрдЯ рдкреНрд░рджрд╛рддрд╛ (рдЗрди-рдкреНрд░реЛрд╕реЗрд╕ fork рдмреИрдХрдПрдВрдб) |
| `reviewerModel` | *(рд╡рд┐рд░рд╛рд╕рдд)* | рд╕рдореАрдХреНрд╖рдХ рдореЙрдбрд▓ id; рдЦрд╛рд▓реА рд╣реЛрдиреЗ рдкрд░ рд╕рддреНрд░ рдПрдЬреЗрдВрдЯ рдХрд╛ рдорд╛рд░реНрдЧ рд▓реЗрддрд╛ рд╣реИ |
| `reviewerTimeoutMs` | `60000` | рдирд┐рд░реНрдгрдп рдХреА рд╕рдордп-рд╕реАрдорд╛; рд╕рдорд╛рдкреНрддрд┐ рдкрд░ fallback рдиреАрддрд┐ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ |
| `reviewerTools` | `[read, glob, grep]` | рд╕рдореАрдХреНрд╖рдХ рдЪрд╛рдЗрд▓реНрдб рдХреА рдЯреВрд▓ рдЕрдиреБрдорддрд┐-рд╕реВрдЪреА (рдЧреИрд░-рд░рд┐рдХреНрдд рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП) |
| `fallbackPolicy` | `rejected` | рд╕рдореАрдХреНрд╖рдХ рд╡рд┐рдлрд▓рддрд╛: `rejected` (рд╡рд┐рдлрд▓-рдмрдВрдж) / `delegate` / `allow-once` |
| `maxReviewsPerTurn` | `10` | рдкреНрд░рддрд┐ рдЦреБрд▓реЗ рдЯрд░реНрди рд╡рд╛рд╕реНрддрд╡рд┐рдХ AI-рдирд┐рд░реНрдгрдп рдмрдЬрдЯ; рдЗрд╕рд╕реЗ рдЕрдзрд┐рдХ рдкрд░ рдЕрдиреБрд░реЛрдз рд╕реМрдВрдк рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ |
| `maxFailuresPerTurn` | `10` | рдкреНрд░рддрд┐ рдЦреБрд▓реЗ рдЯрд░реНрди рд╕рдореАрдХреНрд╖рдХ-рд╡рд┐рдлрд▓рддрд╛ рдмрдЬрдЯ |
| `reasonMaxChars` | `2000` | рд╕рдореАрдХреНрд╖рдХ рдХрд╛рд░рдгреЛрдВ рдФрд░ рд╕рдВрд╢реЛрдзрд┐рдд рддрд░реНрдХ рдкреВрд░реНрд╡рд╛рд╡рд▓реЛрдХрди рдХреА рд╕реАрдорд╛ |
| `reviewerGuidance` | *(рдХреЛрдИ рдирд╣реАрдВ)* | рд╕рдореАрдХреНрд╖рдХ рдкреНрд░реЙрдореНрдкреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рд▓рд╛рд╣рдХрд╛рд░ рдорд╛рд░реНрдЧрджрд░реНрд╢рди |
| `reviewerPolicyText` | *(рдХреЛрдИ рдирд╣реАрдВ)* | рд╕рдореАрдХреНрд╖рдХ рдкреНрд░реЙрдореНрдкреНрдЯ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХреА рдЧрдИ Markdown рдирд┐рд░реНрдгрдп-рдиреАрддрд┐ (Codex рд╢реИрд▓реА) |
| `denyGuidance` | *(рдкрд░рд┐рд╣рд╛рд░-рд╡рд┐рд░реЛрдзреА рдкрд╛рда)* | рд╣рд░ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдП рдЧрдП рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХрд╛рд░рдг рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдорд╛рд░реНрдЧрджрд░реНрд╢рди |
| `contextBudget` | `{turns: 2, maxChars: 4000}` | рд╕рдореАрдХреНрд╖рдХ рдкреНрд░реЙрдореНрдкреНрдЯ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдмрдЬрдЯ (рдЦреБрд▓рд╛ рдЯрд░реНрди рдФрд░ рдЙрд╕рд╕реЗ рдкрд┐рдЫрд▓рд╛); `turns: 0` рдЗрд╕ рдЦрдВрдб рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИ тАФ рдФрд░ рдмрд┐рдирд╛ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рд╡рд╛рд▓рд╛ рд╕рдореАрдХреНрд╖рдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдЕрдзрд┐рдХреГрдд рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм 0 рдХрд┐рд╕реА `ai` рдиреАрддрд┐ рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рддреЛ рд░рдирдЯрд╛рдЗрдо рдЪреЗрддрд╛рд╡рдиреА рджреЗрддрд╛ рд╣реИред рд╡рд░реНрдг рдмрдЬрдЯ рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдкрд░ рдЦрд░реНрдЪ рд╣реЛрддрд╛ рд╣реИ |
| `riskPolicy` | `{maxAutoAllow: high, onHighRisk: delegate}` | `maxAutoAllow` рд╕реЗ рдКрдкрд░ рдХреЗ `allow` рдирд┐рд░реНрдгрдп рд╕реМрдВрдкрддреЗ рдпрд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ |
| `circuitBreaker` | `{consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate}` | рдЕрд╕реНрд╡реАрдХреГрддрд┐ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░ |
| `overrideTtlMs` | `300000` | `/auto-review approve` рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рддрдиреА рджреЗрд░ рдЙрдкрдпреЛрдЧреА рд░рд╣рддрд╛ рд╣реИ |
| `verdictCacheTtlMs` | `60000` | рд╕рдорд╛рди `рдЯреВрд▓ + рддрд░реНрдХ` рдлрд╝рд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдХреЗ рд▓рд┐рдП рд╣рд╛рд▓рд┐рдпрд╛ рдирд┐рд░реНрдгрдп рдкреБрдирдГ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ; `0` рдХреИрд╢ рдмрдВрдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ `contextBudget.turns: 0` рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ тАФ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдирд┐рд░реНрднрд░ рдирд┐рд░реНрдгрдп рдХреЗрд╡рд▓ `рдЯреВрд▓ + рддрд░реНрдХ` рд╕реЗ рджреЛрд╣рд░рд╛рдпрд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ |
| `verdictCacheMaxEntries` | `256` | рд╕рдмрд╕реЗ рдкреБрд░рд╛рдиреЗ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреИрд╢ рдХрд┐рдП рдЧрдП рдлрд╝рд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ |
| `language` | `en` | `/auto-review` рдХрдорд╛рдВрдб рдЖрдЙрдЯрдкреБрдЯ рдХреА UI рднрд╛рд╖рд╛ (`en` \| `zh`) |
| `allowUnmarkedAudit` | `false` | `ignorable` рдорд╛рд░реНрдХрд░ рдЫреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рд╣реЛрд╕реНрдЯ рдкрд░ рд╕рддреНрд░-рд▓реЙрдЧ рдСрдбрд┐рдЯ рдмрд▓рдкреВрд░реНрд╡рдХ рдЪрд╛рд▓реВ рдХрд░реЗрдВ (рдЦрддрд░рдирд╛рдХ: рдмрд┐рдирд╛ рдорд╛рд░реНрдХрд░ рд╡рд╛рд▓реА рдШрдЯрдирд╛рдПрдБ рдЕрдиреНрдп рд╣реЛрд╕реНрдЯ рдкрд░ рд╕рддреНрд░ рдЕрдкреНрд░рд╛рдкреНрдп рдмрдирд╛рддреА рд╣реИрдВ); рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкрд╣рдЪрд╛рди-рдФрд░-рдбрд┐рдЧреНрд░реЗрдб рд╣реИ (2026-09-02 рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд, 2026-09-11 рдХреЛ `0.1.5-rc.2` рдХреЗ рд╡рд┐рд░реБрджреНрдз рдкреБрдирдГ рд╕рддреНрдпрд╛рдкрд┐рдд) |
рдЙрджрд╛рд╣рд░рдг (рдЯрд┐рдкреНрдкрдгреА-рдпреБрдХреНрдд рдкреВрд░реНрдг рд░реВрдк: `fixtures/config/config-full.yaml`):
```yaml
- insert:
- id: auto-review
name: dsh-auto-review
config:
toolsPolicy:
overrides: { bash: ai, write: ai }
riskRules:
- pattern: '(?i)(rm\s+(-[a-z]+\s+)*/|git\s+push\s+--force)'
policy: never
- pattern: 'write'
policy: never
field: toolName
reviewerTimeoutMs: 30000
fallbackPolicy: delegate
riskPolicy: { maxAutoAllow: medium, onHighRisk: delegate }
circuitBreaker: { consecutiveDenies: 3, windowDenies: 6, windowSize: 10, action: delegate }
```
### рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЕрд╕рд▓ рдореЗрдВ рдХрд╣рд╛рдБ рд╕реЗ рдЖрддрд╛ рд╣реИ
**`~/.dsh/settings.yaml` рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧ рд╕реНрд░реЛрдд рдирд╣реАрдВ рд╣реИред** рд╡рд╣рд╛рдБ рд▓рд┐рдЦрд╛ `auto-review:` рдмреНрд▓реЙрдХ рди рдХреЛрдИ рдЕрд╕рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рди рдХреЛрдИ рдЪреЗрддрд╛рд╡рдиреА рджреЗрддрд╛ рд╣реИ: рд╣рд░ DSH рдлрд╝рдВрдХреНрд╢рди-рдкреНрд▓рдЧрдЗрди рдХреА рддрд░рд╣ `dsh-auto-review` рдЕрдкрдирд╛ `Config` рдЙрд╕реА рдкрдВрдХреНрддрд┐ рд╕реЗ рдкрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рд▓реЛрдбрд░ рдЙрд╕реЗ рдорд╛рдЙрдВрдЯ рдХрд░рддрд╛ рд╣реИ тАФ рдпрд╛рдиреА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреА cordis patch рдкрд░рдд рд╕реЗред (рдХреБрдЫ рдЕрдиреНрдп DSH рдкреНрд▓рдЧрдЗрди settings рд╕реЗрд╡рд╛ рднреА рдкрдврд╝рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЕрд╕рдВрдЧрддрд┐ рдЖрд╕рд╛рдиреА рд╕реЗ рдлрдБрд╕рд╛ рджреЗрддреА рд╣реИ, рдФрд░ рд▓рдХреНрд╖рдг "рд╕рдореАрдХреНрд╖рдХ рдиреЗ рдмрд╕ рдордирд╛ рдХрд░ рджрд┐рдпрд╛" рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ред)
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЕрдкрдиреА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ `cordis.patch.yml` рдореЗрдВ рд░рдЦреЗрдВред **id-рд▓рдХреНрд╖рд┐рдд override рдкреВрд░реА config рдкрдВрдХреНрддрд┐ рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ**, рдЗрд╕рд▓рд┐рдП рд╣рд░ рдЖрд╡рд╢реНрдпрдХ рдХреБрдВрдЬреА рджреЛрдмрд╛рд░рд╛ рд▓рд┐рдЦреЗрдВ тАФ `toolsPolicy` рдЫреЛрдбрд╝рдиреЗ рдкрд░ `bash`/`write` рдЪреБрдкрдЪрд╛рдк schema рдбрд┐рдлрд╝реЙрд▓реНрдЯ `human` рдкрд░ рд▓реМрдЯ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╕рдореАрдХреНрд╖рдХ рдЪрд▓рдирд╛ рд╣реА рдмрдВрдж рдХрд░ рджреЗрддрд╛ рд╣реИ:
```yaml
- id: auto-review
config:
toolsPolicy:
overrides: { bash: ai, write: ai }
contextBudget: { turns: 4, maxChars: 8000 }
```
## рдЙрдкрдХрд░рдг рдФрд░ рд╕рддрд╣реЗрдВ
| рд╕рддрд╣ | рдкреНрд░рдХрд╛рд░ | рдиреЛрдЯреНрд╕ |
|---|---|---|
| `auto-review` | answerer | `approval/request` рдХреИрд╕реНрдХреЗрдб answerer тАФ `ai`-рдиреАрддрд┐ рдЕрдиреБрд░реЛрдз рдЕрдкрдирд╛рддрд╛ рд╣реИ, рдмрд╛рдХреА `next()` рд╕реЗ рд╕реМрдВрдкрддрд╛ рд╣реИ |
| `/auto-review` | рдХрдорд╛рдВрдб | `on\|off\|status\|approve [n]` тАФ рдЯрд┐рдХрд╛рдК рдкреНрд░рддрд┐-рд╕рддреНрд░ рдУрд╡рд░рд░рд╛рдЗрдб, рдмрдЬрдЯ рдФрд░ рд╕рдВрдЪрдпреА рдЖрдБрдХрдбрд╝реЗ |
| рдЕрд╕реНрд╡реАрдХреГрддрд┐-рдХрд╛рд░рдг рдЗрдВрдЬреЗрдХреНрд╢рди | рд╢реНрд░реЛрддрд╛ | `tools/post-execute` тАФ рдирд┐рд░реНрдгрдп / fallback / `never` рдХрд╛рд░рдг рдЕрд╕реНрд╡реАрдХреГрдд рдЯреВрд▓ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд▓реМрдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ |
| `autoReview` | рд╕рддреНрд░ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди | рдХреЗрд╡рд▓-рд▓реЙрдЧ `autoReview/*` рдШрдЯрдирд╛рдУрдВ рд╕реЗ рдореЛрдбрд╝рд╛ рдЧрдпрд╛ |
| рд╡реЗрдм рд╕рдореАрдХреНрд╖рд╛ рдкреИрдирд▓ | рдХреНрд▓рд╛рдЗрдВрдЯ | рд╕рддреНрд░-рд╢реАрд░реНрд╖рдХ рдХреНрд░рд┐рдпрд╛: рд╕реНрд╡рд┐рдЪ, рдмрдЬрдЯ, рдЖрдБрдХрдбрд╝реЗ, рд╣рд╛рд▓ рдХреЗ рдирд┐рд░реНрдгрдп, рдПрдХ-рдмрд╛рд░ рд╕реНрд╡реАрдХреГрддрд┐ |
| `dsh-eval` | CLI | YAML-рдЪрд╛рд▓рд┐рдд рдПрдЬреЗрдВрдЯ рдореВрд▓реНрдпрд╛рдВрдХрди рдЗрдВрдЬрди (`bin/dsh-eval.mjs`) |
| invariant рд╕рд╛рдереА | invariant | `dsh-auto-review/invariant` (рд╡реИрдХрд▓реНрдкрд┐рдХ; `invariants` рд╕реЗрд╡рд╛ рдЪрд╛рд╣рд┐рдП) |
## рд╕рддреНрд░ рдХрдорд╛рдВрдб
```
/auto-review on|off|status|approve [n]
```
`on`/`off` рдЯрд┐рдХрд╛рдК `autoReview/state` рдУрд╡рд░рд░рд╛рдЗрдб рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ (рдореЛрдбрд╝ рдкреБрдирдГ рдкреНрд░рд╛рд░рдВрдн/рдкреБрдирдГ рдЖрд░рдВрдн рдХреЗ рдмрд╛рдж рднреА рдмрдЪрд╛ рд░рд╣рддрд╛ рд╣реИ тАФ рдкреБрдирд░реНрдкреНрд▓реЗ рд╣реА рд╕реНрдерд┐рддрд┐ рд╣реИ) рдФрд░ рдПрдХ рд╕реНрд╡рд┐рдЪ рд╕реВрдЪрдирд╛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдореЙрдбрд▓ рджреЗрдЦрддрд╛ рд╣реИ (рдПрдХ `user/message` рдШрдЯрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЙрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред `status` рдкреНрд░рднрд╛рд╡реА рд╕реНрдерд┐рддрд┐, рджреЛрдиреЛрдВ рдкреНрд░рддрд┐-рдЯрд░реНрди рдмрдЬрдЯ (AI рдирд┐рд░реНрдгрдп рдФрд░ рд╕рдореАрдХреНрд╖рдХ рд╡рд┐рдлрд▓рддрд╛рдПрдБ), рд╕рдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдкрд░ рдПрдХ рдЯреНрд░рд┐рдк рд╣реБрдЖ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░, рдФрд░ рд╕рддреНрд░ рдХреЗ рд╕рдВрдЪрдпреА рдЖрдБрдХрдбрд╝реЗ (рдЕрдиреБрдорддрд┐рдпрд╛рдБ/рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпрд╛рдБ/fallbacks/`never` рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпрд╛рдБ, рдФрд╕рдд рдЕрд╡рдзрд┐, рд╣рд╛рд▓ рдХреЗ рдирд┐рд░реНрдгрдп) рдмрддрд╛рддрд╛ рд╣реИред `approve [n]` n-рд╡реЗрдВ рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдЕрд╕реНрд╡реАрдХреГрддрд┐ (1 = рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛) рдХреЗ рд▓рд┐рдП рдПрдХрд▓-рдЙрдкрдпреЛрдЧ `autoReview/override` рджрд░реНрдЬ рдХрд░рддрд╛ рд╣реИ: `overrideTtlMs` рдХреЗ рднреАрддрд░ рдЙрд╕реА рдЯреВрд▓ рдХреА рдЕрдЧрд▓реА рд╕рдореАрдХреНрд╖рд╛ рд╕рдореАрдХреНрд╖рдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд▓реЗрдХрд░ рдЪрд▓рддреА рд╣реИ тАФ рд╕рдореАрдХреНрд╖рдХ рдлрд┐рд░ рднреА рдирд┐рд░реНрдгрдп рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдЙрд╕ рд╕рдореАрдХреНрд╖рд╛ рджреНрд╡рд╛рд░рд╛ рдЙрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рдЙрдкрднреЛрдЧ рдХрд░ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
## рд╡реЗрдм рд╕рдореАрдХреНрд╖рд╛ рдкреИрдирд▓
рд╡реЗрдм GUI (web рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓) рдореЗрдВ, рдкреИрдХреЗрдЬ рдПрдХ рд╕рддреНрд░-рд╢реАрд░реНрд╖рдХ рдХреНрд░рд┐рдпрд╛ (**AI Review**) рдпреЛрдЧрджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕рддреНрд░ рдХреА auto-review рд╕реНрдерд┐рддрд┐ рд╡рд╛рд▓рд╛ рдПрдХ рдкреИрдирд▓ рдЦреЛрд▓рддреА рд╣реИ: on/off рдмрдЯрди рд╡рд╛рд▓рд╛ рд╕реНрд╡рд┐рдЪ (рд╡реЗ `/auto-review on|off` рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ), рджреЛрдиреЛрдВ рдкреНрд░рддрд┐-рдЯрд░реНрди рдмрдЬрдЯ, рд╕рдВрдЪрдпреА рдЖрдБрдХрдбрд╝реЗ (рдХрдареЛрд░-рдЕрдХреНрд╖рдорддрд╛ рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпрд╛рдБ рд╕рд╣рд┐рдд), рд╕рд░реНрдХрд┐рдЯ рдЯреНрд░рд┐рдк, рд╣рд╛рд▓ рдХреЗ рдирд┐рд░реНрдгрдп, рдФрд░ рд╣рд╛рд▓ рдХреА рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ-рдмрд╛рд░ **approve** рдмрдЯрди (рд╡реЗ `/auto-review approve [n]` рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ)ред
рдпрд╣ рдХреИрд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИ:
- рд╣реЛрд╕реНрдЯ рдПрдХ `autoReview` **рд╕рддреНрд░ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди** рдкрдВрдЬреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ (рдХреЗрд╡рд▓-рд▓реЙрдЧ `autoReview/*` рдШрдЯрдирд╛рдУрдВ рд╕реЗ рдореЛрдбрд╝рд╛ рдЧрдпрд╛) рдФрд░ рдЙрд╕реЗ рд╕рддреНрд░-рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдЪреИрдирд▓ рдХреЗ рдЬрд╝рд░рд┐рдП рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред
- рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡рд╛рд▓рд╛ рдЖрдзрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдПрдХ **рдХреНрд▓рд╛рдЗрдВрдЯ рдореЙрдбреНрдпреВрд▓** рд╣реИ (`dsh.client` рдШреЛрд╖рдгрд╛ рд╕реЗ рд╕реНрд╡рддрдГ-рдЦреЛрдЬрд╛ рдЧрдпрд╛) рдЬреЛ `conversation.session.header.actions` рд╕реАрдЯ рдкрд░ рдкрдВрдЬреАрдХреГрдд рд╣реИред
- рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрдЪ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ: рдкреИрдирд▓ рддрдм рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИ рдЬрдм рднреА рдкреНрд▓рдЧрдЗрди рдХрд┐рд╕реА рдРрд╕реЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЗрдВрд╕реНрдЯреЙрд▓ рд╣реЛ рдЬрд┐рд╕рдХрд╛ web рдмрд┐рд▓реНрдб рд╕рддреНрд░-рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ (web рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХрд░рддрд╛ рд╣реИ)ред рдЙрд╕ рдХреНрд╖рдорддрд╛ рдХреЗ рдмрд┐рдирд╛ рдкреИрдирд▓ рд╕реНрд╡рдпрдВ рдХреЛ рдЕрдиреБрдкрд▓рдмреНрдз рдмрддрд╛рддрд╛ рд╣реИ; answerer рдЕрдкреНрд░рднрд╛рд╡рд┐рдд рд░рд╣рддрд╛ рд╣реИред
рдкреИрдирд▓ рдХреЗрд╡рд▓ рд╕рдВрдкреВрд░реНрдг рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдорд╛рди рдкрдврд╝рддрд╛ рд╣реИ тАФ рдЙрд╕реЗ рдХрдЪреНрдЪреА рд╕рддреНрд░ рдШрдЯрдирд╛ рдзрд╛рд░рд╛ рдХрднреА рдирд╣реАрдВ рдорд┐рд▓рддреАред
## рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
```text
approval/request waterfall (answerer chain)
тФВ
тФМтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФ┤тФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФР
тФВ dsh-auto-review answerer тФВ
тФВ ┬╖ session enabled? ┬╖ policy = ai? тФВ no тФАтФА next() тФАтФАтЦ╢ human answerer (UI)
тФВ ┬╖ risk rules тЖТ toolsPolicy тЖТ default тФВ
тФФтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФмтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФШ
тФВ yes
тЦ╝
тФМтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФР
тФВ reviewer subagent (fork, one-shot)тФВ
тФВ ┬╖ toolFilter: read/glob/grep тФВ
тФВ ┬╖ outputSchema: {decision, тФВ
тФВ reason, riskLevel} тФВ
тФВ ┬╖ timeout + req.signal abort тФВ
тФФтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФмтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФАтФШ
тФВ verdict / failure (fail-closed fallback)
тЦ╝
allow тЖТ allowed-once deny тЖТ rejected + reason injected into the
denied tool result (callId-linked)
тФВ never тЖТ rejected + [auto-review-never] feedback
тФВ (hard disable, no reviewer runs)
тЦ╝
audit: approval/asked тЖТ autoReview/verdict | autoReview/rejection
тЖТ approval/decided (session events, log-only, invariant-checked)
```
**рд░рдЪрдирд╛ рдХреНрд░рдоред** answerer рдХреИрд╕реНрдХреЗрдб рдореЗрдВ рдЕрдкрдиреА рдкрдВрдЬреАрдХрд░рдг рд╕реНрдерд┐рддрд┐ рдкрд░ рдЪрд▓рддрд╛ рд╣реИ: рдпрджрд┐ рдХреЛрдИ рдорд╛рдирд╡ UI answerer `auto-review` рдкрдВрдХреНрддрд┐ рд╕реЗ рдкрд╣рд▓реЗ рд░рдЪрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдорд╛рдирд╡ рдкрд╣рд▓реЗ рдЙрддреНрддрд░ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рд╕рдореАрдХреНрд╖рдХ рдХреЗрд╡рд▓ рд╡рд╣реА рджреЗрдЦрддрд╛ рд╣реИ рдЬреЛ рдЖрдЧреЗ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИред `dsh --profile --dump-config` рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ рдФрд░ рдЬрдм рдЖрдк рдЪрд╛рд╣реЗрдВ рдХрд┐ ai-рдиреАрддрд┐ рдЯреВрд▓ рдкрд╣рд▓реЗ рд╕рдореАрдХреНрд╖рдХ рдХреЛ рднреЗрдЬреЗ рдЬрд╛рдПрдБ рддреЛ `auto-review` рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрдкрдиреЗ рдорд╛рдирд╡ answerer рдкрдВрдХреНрддрд┐рдпреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рд░рдЦреЗрдВред
## dsh-eval тАФ рдПрдЬреЗрдВрдЯ рдореВрд▓реНрдпрд╛рдВрдХрди рдЗрдВрдЬрди
рдЕрдиреБрдореЛрджрди рд╕рдореАрдХреНрд╖рдХ рд╕реЗ рдкрд░реЗ, `dsh-auto-review` `dsh-eval` рд╢рд┐рдк рдХрд░рддрд╛ рд╣реИ: рдПрдХ YAML-рдЪрд╛рд▓рд┐рдд рдПрдЬреЗрдВрдЯ рдореВрд▓реНрдпрд╛рдВрдХрди рдордВрдЪ рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣реЗрдбрд▓реЗрд╕ DSH рд╕рддреНрд░ рдЪрд▓рд╛рддрд╛ рд╣реИ (рдкреНрд░рддрд┐ рдХреЗрд╕ рдПрдХ рдкреГрдердХ рдПрдЬреЗрдВрдЯ + рдЕрд╕реНрдерд╛рдпреА рд╡рд░реНрдХрд╕реНрдкреЗрд╕, рдЖрдзрд╛рд░рднреВрдд рд╕рд┐рд╕реНрдЯрдо рдкреНрд░реЙрдореНрдкреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ Minimal рд╡реНрдпрдХреНрддрд┐рддреНрд╡), рд╕рддреНрд░ рдШрдЯрдирд╛ рд▓реЙрдЧ рд╕реЗ рдЯреВрд▓-рдХреЙрд▓ рдЯреНрд░реЗрд╕ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рдВрд░рдЪрд┐рдд рджрд╛рд╡реЛрдВ рддрдерд╛ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рджреНрд╡рд┐рддреАрдп-рдореЙрдбрд▓ рд╕рдореАрдХреНрд╖рд╛ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рддрд╛ рд╣реИ тАФ рд╡рд╣реА рд╕рдореАрдХреНрд╖рдХ рд╕реАрдо рдЬреЛ рдЕрдиреБрдореЛрджрди answerer рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
```yaml
# eval/cases/demo.yaml (рд╕рдВрдХреНрд╖рд┐рдкреНрдд)
suite:
name: my-suite
cases:
- id: math-output
input: Solve 17 ├Ч 24 and reply with only the final number, nothing else.
expect:
output: { contains: "408" }
- id: glob-trace
seedFrom: '.'
input: Use the glob tool with pattern "src/**" to list the source filesтАж
expect:
toolCalls: [{ tool: glob, arguments: { contains: { pattern: "src" } } }]
results: [{ tool: glob, contains: "index.ts" }]
```
рдЗрд╕реЗ рдЪрд▓рд╛рдПрдБ (рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдПрдХ DeepSeek API рдХреБрдВрдЬреА рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП):
```sh
dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports
```
### рджрд╛рд╡рд╛ рдкрд░рд┐рд╡рд╛рд░
`expect` рдмреНрд▓реЙрдХ рдЫрд╣ рджрд╛рд╡рд╛ рдкрд░рд┐рд╡рд╛рд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ; рд╣рд░ рджрд╛рд╡рд╛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдореВрд▓реНрдпрд╛рдВрдХрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдкрд╛рд╕/рдлреЗрд▓ рдХреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд/рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд┐рдлрд▓ рдХреЗрд╕ рдмрд┐рдирд╛ рджреЛрдмрд╛рд░рд╛ рдЪрд▓рд╛рдП рдЦреБрдж рдХреЛ рд╕рдордЭрд╛ рджреЗрддрд╛ рд╣реИред
| рдкрд░рд┐рд╡рд╛рд░ | DSL рдХреБрдВрдЬрд┐рдпрд╛рдБ | рдпрд╣ рдХреНрдпрд╛ рдЬрд╛рдБрдЪрддрд╛ рд╣реИ |
|---|---|---|
| рдЯреВрд▓ рдЯреНрд░реЗрд╕ | `toolCalls`, `toolCallsExact`, `noToolCalls`, `results` | рдХреНрд░рдордмрджреНрдз рдЯреВрд▓-рдХреЙрд▓ рдЕрдиреБрдХреНрд░рдо (рдЫреВрдЯ рдХреЗ рд╕рд╛рде рдЙрдк-рдЕрдиреБрдХреНрд░рдо), рд╕рдЯреАрдХ рдирд╛рдо рдЕрдиреБрдХреНрд░рдо, рдкреНрд░рддрд┐-рдЯреВрд▓ рдкрд░рд┐рдгрд╛рдо (`isError`/`contains`/`regex`) |
| рдЖрдЙрдЯрдкреБрдЯ рдФрд░ рдмрдЬрдЯ | `output`, `turnEnds`, `maxTokens` | рдЕрдВрддрд┐рдо рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ/рд░реЗрдЧреЗрдХреНрд╕, рдЯрд░реНрди рдкрд░рд┐рдгрд╛рдо, рдЯреЛрдХрди рдмрдЬрдЯ |
| рдкреНрд░реЙрдореНрдкреНрдЯ рд░рд┐рдЧреНрд░реЗрд╢рди | `prompt` | рд░реЗрдВрдбрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╕рд┐рд╕реНрдЯрдо рдкреНрд░реЙрдореНрдкреНрдЯ рдПрдХ рдкреНрд░рддрд┐рдмрджреНрдз `baseline` (рдпрд╛ `baselineFrom` рдлрд╝рд╛рдЗрд▓) рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП; рдХреЛрдИ рднреА рд╡рд┐рдЪрд▓рди **side-by-side diff** рдХреЗ рд░реВрдк рдореЗрдВ рд░рд┐рдкреЛрд░реНрдЯ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЗрдЪреНрдЫрд┐рдд рд╕рдВрдкрд╛рджрдиреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рдХреЗ рд▓рд┐рдП `allowedChanges` рд░реЗрдЧреЗрдХреНрд╕ рд╣реЛрддреЗ рд╣реИрдВ |
| рд╕реНрдЯреНрд░реЗрд╕ рдореЗрдЯреНрд░рд┐рдХреНрд╕ | `stress` | P99 рд╕реНрдЯреЗрдк рд▓реЗрдЯреЗрдВрд╕реА (`maxP99Ms`), рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рдкрд╣рд▓рд╛-рдЯреЛрдХрди рд╕рдордп (`maxTtftMs`), рдХреБрд▓ рдЯреЛрдХрди рдирд┐рд░реНрдорд╛рдг рдЧрддрд┐ (`minTokensPerSecond`) |
| рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ | `bias` | рдЕрдВрддрд┐рдо рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдкреВрд░реНрд╡рд╛рдЧреНрд░рд╣ рд░рдбрд╛рд░: рдкреНрд░рддрд┐-рд╢реНрд░реЗрдгреА рд░реЗрдЧреЗрдХреНрд╕ рдЧрдгрдирд╛ (`categories`), рдХрдареЛрд░ `forbid` рдкреИрдЯрд░реНрди, `maxHits`/`maxCategoryHits` рд╕реАрдорд╛рдПрдБ |
| рджреНрд╡рд┐рддреАрдп-рдореЙрдбрд▓ рд╕рдореАрдХреНрд╖рд╛ | `review` | рд╕рдореАрдХреНрд╖рдХ рдЙрдк-рдПрдЬреЗрдВрдЯ рд╕реЗ рдПрдХ рдкреВрд░рдХ рдкрд╛рд╕/рдлреЗрд▓ рдирд┐рд░реНрдгрдп (рдЕрд▓рдЧ рдкрд░рдд, рдЕрдиреБрдореЛрджрди рд╕рдореАрдХреНрд╖рдХ рдЬреИрд╕реА рд╣реА рд╕реАрдо) |
```yaml
- id: regression-gate
input: Answer in one sentence.
expect:
prompt:
baseline: "You are a helpful software engineer assistant."
allowedChanges: ["copyright-year"]
stress:
maxP99Ms: 8000
maxTtftMs: 3000
minTokensPerSecond: 20
bias:
categories: { gender: ["[Hh]e is (un)?stable"] }
forbid: ["[Ss]crew that"]
maxCategoryHits: 0
```
CI рджреНрд╡рд╛рд░: рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд╡рд▓ рддрднреА 0 рд╕реЗ рдирд┐рдХрд▓рддреА рд╣реИ рдЬрдм рд╣рд░ рд╕реБрдЗрдЯ рдХрд╛ рд╣рд░ рдХреЗрд╕ рдкрд╛рд╕ рд╣реЛ тАФ рдЕрд╕рдлрд▓ рдореВрд▓реНрдпрд╛рдВрдХрди рдмрд┐рд▓реНрдб рдХреЛ рдЕрд╕рдлрд▓ рдХрд░ рджреЗрддреЗ рд╣реИрдВред рд╣рд░ рдХреЗрд╕ `report.md`/`report.json` рдХреЗ рдкрд╛рд╕ рдПрдХ рдкреБрдирдГ-рдЪрд▓рд╛рдиреЗ рдпреЛрдЧреНрдп рд╕рддреНрд░ JSONL рдФрд░ рдПрдХ рдЯреНрд░реЗрд╕ JSON рдЫреЛрдбрд╝рддрд╛ рд╣реИ; рджрд╛рд╡рд╛ рдкрд░рд┐рдгрд╛рдо (рдкреНрд░реЙрдореНрдкреНрдЯ side-by-side diff рд╕рд╣рд┐рдд), рдЯреЛрдХрди рдЙрдкрдпреЛрдЧ, рд╕реНрдЯреНрд░реЗрд╕/рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдФрд░ рд╕рдореАрдХреНрд╖рд╛ рдирд┐рд░реНрдгрдп рд╕рднреА рд░рд┐рдкреЛрд░реНрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВред
```yaml
- name: dsh-eval
run: npx dsh-eval eval/cases --model deepseek-flash --timeout-ms 240000 --out .eval-reports
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
```
`dsh-eval` [openai/codex-research](https://github.com/openai/codex-research) рд╕реЗ рднрд┐рдиреНрди рд╣реИ: codex-research рдЕрдиреБрд╕рдВрдзрд╛рди рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП рдПрдЬреЗрдВрдЯ рдЯреНрд░реИрдЬреЗрдХреНрдЯрд░реА рдХреЛ рд╕реНрдХреЛрд░ рдХрд░рддрд╛ рд╣реИ; `dsh-eval` рдПрдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рдкрд╛рд╕/рдлреЗрд▓ рд░рд┐рдЧреНрд░реЗрд╢рди рд╣рд╛рд░реНрдиреЗрд╕ рд╣реИ тАФ YAML рдХреЗрд╕, рд╕рдВрд░рдЪрд┐рдд рдЯреНрд░реЗрд╕/рдкреНрд░реЙрдореНрдкреНрдЯ/рд╕реНрдЯреНрд░реЗрд╕/рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рджрд╛рд╡реЗ, рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рджреНрд╡рд┐рддреАрдп-рдореЙрдбрд▓ рд╕рдореАрдХреНрд╖рд╛ рдФрд░ рдПрдХ CI рдПрдЧреНрдЬрд┐рдЯ рдХреЛрдб тАФ рдХрд┐рд╕реА рднреА DSH рдПрдЬреЗрдВрдЯ рдХреЛ рдЧреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдиреБрд╕рдВрдзрд╛рди рд░реИрдВрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред
## MCP рд╕рд░реНрд╡рд░ (рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди)
`dsh-auto-review` рдПрдХ stdio **MCP рд╕рд░реНрд╡рд░** (`dsh-auto-review-mcp`) рднреА рджреЗрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдмрд╛рд╣рд░реА MCP рдХреНрд▓рд╛рдЗрдВрдЯ (Claude, Codex, тАж) рдмрд┐рдирд╛ harness рдХреЗ рдПрдХ рдирд┐рд░реНрдзрд╛рд░рдХ рд╕рдореАрдХреНрд╖рд╛ рдкрде рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВред рдпрд╣ newline-delimited JSON (NDJSON) рдкрд░ JSON-RPC 2.0 рдмреЛрд▓рддрд╛ рд╣реИ тАФ рдкреНрд░рддрд┐ рдкрдВрдХреНрддрд┐ рдПрдХ JSON рдСрдмреНрдЬреЗрдХреНрдЯ, рдХреЛрдИ `Content-Length` рдлрд╝реНрд░реЗрдорд┐рдВрдЧ рдирд╣реАрдВред
**рд╕реАрдорд╛ред** рдкреВрд░реНрдг reviewer рдХреЛ harness рдХреЗ subagent seam рдФрд░ рджреВрд╕рд░реЗ рдореЙрдбрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рдЕрд▓рдЧ stdio рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рдкрд╣реБрдБрдЪ рд╕рдХрддреАред рдЗрд╕рд▓рд┐рдП рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рд╕рд░реНрд╡рд░ **рдирд┐рд░реНрдзрд╛рд░рдХ рдирд┐рдпрдо + рдХреИрд╢, рдХреЛрдИ рдореЙрдбрд▓ рд╕рдореАрдХреНрд╖рд╛ рдирд╣реАрдВ** рд╣реИ:
- `review_action` рд╕рдорд╛рди-рдлрд╝рд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рд╡рд░реНрдбрд┐рдХреНрдЯ рдХреИрд╢ (`src/cache.ts`) рдФрд░ рдЬреЛрдЦрд┐рдо-рдирд┐рдпрдо / рдЯреВрд▓-рдиреАрддрд┐ рд╕рдорд╛рдзрд╛рди (`src/config.ts`) рдХрд╛ рдкреБрдирдГ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: рдПрдХ `never` рдирд┐рдпрдо тЖТ `deny`; рд╕рдорд╛рди `tool + arguments` рдлрд╝рд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдкрд░ рдХреИрд╢ рд╣рд┐рдЯ рдЙрд╕ рд╡рд░реНрдбрд┐рдХреНрдЯ рдХреЛ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИ; рдмрд╛рдХреА рд╕рдм (`ai` рдХреЛ рдореЙрдбрд▓ рдЪрд╛рд╣рд┐рдП, `human` рдХреЛ рдорд╛рдирд╡ рдЪрд╛рд╣рд┐рдП) тЖТ fail-closed `deny` рдЬрд┐рд╕рдХрд╛ reason `"standalone path, no model"` рд╣реИред рдпрд╣ рдХрднреА рднреА рдРрд╕реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рдЬрд┐рд╕реЗ рдХрд┐рд╕реА рдореЙрдбрд▓ рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рдЕрдиреБрдорддрд┐ рди рджреА рд╣реЛред
- `cache_stats` рд╣рд┐рдЯ/рд╕реНрдЯреЛрд░ рдЧрдгрдирд╛ рдФрд░ TTL рд╕реНрдерд┐рддрд┐ рдХреА рд╕реВрдЪрдирд╛ рджреЗрддрд╛ рд╣реИред
| рдЯреВрд▓ | рдЙрджреНрджреЗрд╢реНрдп |
|---|---|
| `review_action` | `{tool, args?, reason?}` тЖТ `{decision, reason, riskLevel}` тАФ рдирд┐рд░реНрдзрд╛рд░рдХ рдЕрд╕реНрд╡реАрдХреГрддрд┐ / рдХреИрд╢ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ |
| `cache_stats` | `{}` тЖТ `{hits, stores, size, ttlMs, enabled}` |
рд╕реАрдзреЗ рдЪрд▓рд╛рдПрдБ:
```sh
# рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░реЛрдВ рд╕реЗ рдЖрддреЗ рд╣реИрдВ
export DSH_AUTO_REVIEW_RISK_RULES='[{"pattern":"rm -rf","policy":"never","field":"arguments"}]'
node bin/dsh-auto-review-mcp.mjs
# рдпрд╛, npm install рдХреЗ рдмрд╛рдж: npx dsh-auto-review-mcp
```
рдкрд░реНрдпрд╛рд╡рд░рдг рд╡рд┐рдиреНрдпрд╛рд╕: `DSH_AUTO_REVIEW_RISK_RULES` (`{pattern, policy, field?}` рдХреА JSON рд╕рд░рдгреА), `DSH_AUTO_REVIEW_TOOLS_POLICY` (JSON `{default?, overrides?}`), `DSH_AUTO_REVIEW_CACHE_TTL_MS`, `DSH_AUTO_REVIEW_CACHE_MAX_ENTRIES`ред
Claude Desktop (`claude_desktop_config.json`) рдЙрджрд╛рд╣рд░рдг:
```json
{
"mcpServers": {
"dsh-auto-review": {
"command": "npx",
"args": ["-y", "dsh-auto-review-mcp"],
"env": {
"DSH_AUTO_REVIEW_RISK_RULES": "[{\"pattern\":\"rm -rf\",\"policy\":\"never\",\"field\":\"arguments\"}]"
}
}
}
}
```
рд╕рд░реНрд╡рд░ рдХреЗрд╡рд▓-рдкрдарди рдФрд░ рдирд┐рд░реНрдзрд╛рд░рдХ рд╣реИ: рдХреЛрдИ рдиреЗрдЯрд╡рд░реНрдХ рдирд╣реАрдВ, рдХреЛрдИ рдореЙрдбрд▓ рдирд╣реАрдВ, рдХреЛрдИ рд▓реЗрдЦрди рдирд╣реАрдВред
## рдЕрдиреБрдорддрд┐рдпрд╛рдБ рдФрд░ рдбреЗрдЯрд╛
- **рдЕрдиреБрдорддрд┐рдпрд╛рдБ**: workshop рдореЗрдирд┐рдлрд╝реЗрд╕реНрдЯ `session:append`, `approval:answer`, `subagent:spawn`, `command:register` рдФрд░ `tools:observe` рдШреЛрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред
- **рдбреЗрдЯрд╛**: рдбрд┐рд╕реНрдХ рдкрд░ рдХреБрдЫ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛; рд░рд┐рдкреЛрд░реНрдЯ рд░рд┐рдВрдЧ рдмрдлрд╝рд░ рдореЗрдореЛрд░реА рдореЗрдВ рдФрд░ рд╕реАрдорд┐рдд рд╣реИред рдЕрдкрдиреА рдУрд░ рд╕реЗ рдХреЛрдИ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдирд╣реАрдВред
- **рд╕рддреНрд░ рд▓реЙрдЧ**: `autoReview/*` рдШрдЯрдирд╛рдПрдБ рд╕рдореАрдХреНрд╖рдХ рдкрд╣рдЪрд╛рди, рдирд┐рд░реНрдгрдп, рдХрд╛рд░рдг, рдЬреЛрдЦрд┐рдо рдФрд░ рдЕрд╡рдзрд┐ рд░рдЦрддреА рд╣реИрдВ тАФ рд▓рд┐рдлрд╝рд╛рдлрд╝реЗ рдХреЗ `ignorable: true` рдорд╛рд░реНрдХрд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реА рдЬрд╛рддреА рд╣реИрдВ рддрд╛рдХрд┐ рдХреЛрдИ рднреА рдмрд┐рд▓реНрдб рд▓реЙрдЧ рд▓реЛрдб рдХрд░ рд╕рдХреЗред рдЬрд┐рди рд╣реЛрд╕реНрдЯ рдХрд╛ `Session.append` рдорд╛рд░реНрдХрд░ рд╕реЗ рдкреБрд░рд╛рдирд╛ рд╣реИ (`0.1.1-rc.2` рддрдХ рдХреА рд╣рд░ рд░рд┐рд▓реАрдЬрд╝ rc рд▓рд╛рдЗрди тАФ рдХреЛрдИ рд░рд┐рд▓реАрдЬрд╝ рдЕрднреА рдорд╛рд░реНрдХрд░ рдирд╣реАрдВ рдЫрд╛рдкрддреА) рдЙрдиреНрд╣реЗрдВ рдкрд╣рд▓реЗ append рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдкрд╣рдЪрд╛рди рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (peer рд╕рдВрд╕реНрдХрд░рдг рдкреВрд░реНрд╡-рдЬрд╛рдБрдЪ, рдлрд┐рд░ рд▓реМрдЯреЗ рд▓рд┐рдлрд╝рд╛рдлрд╝реЗ рдХреА рдЬрд╛рдБрдЪ); рд╣реЛрд╕реНрдЯ `0.1.2-rc.1`, `0.1.3-alpha.2` рдФрд░ `0.1.5-rc.2` рд▓рд┐рдлрд╝рд╛рдлрд╝реЗ рдкрд░ `ignorable` рдлрд╝реАрд▓реНрдб рд░рдЦрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди `Session.append` рдЙрд╕реЗ рд╕реНрдЯреИрдореНрдк рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рджреЗрддрд╛ (рдЗрд╕рдХрд╛ рддреАрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗрд╡рд▓ рд╕рддрд╣реА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП `SurfaceIntent` рд╣реИ), рдФрд░ рдкрд░реНрд╕рд┐рд╕реНрдЯреЗрдВрд╕ рд░реАрдб рдкрде рдмрд┐рдирд╛-рдорд╛рд░реНрдХ рд╡рд╛рд▓реЗ рдЕрдЬреНрдЮрд╛рдд рдШрдЯрдирд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡реЗ рд▓рд╛рдЗрдиреЗрдВ тАФ рдФрд░ рдЕрд╕рдорд╛рдзреЗрдп рд╕рдВрд╕реНрдХрд░рдг тАФ рднреА рдХрд┐рд╕реА рднреА append рд╕реЗ рдкрд╣рд▓реЗ fail closed рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдСрдбрд┐рдЯ рдмрд┐рдирд╛ рдорд╛рд░реНрдХрд░ рд╡рд╛рд▓реЗ рдлреАрдбрдмреИрдХ рдХреЗ рд╕рд╛рде рдЗрди-рдореЗрдореЛрд░реА рдорд┐рд░рд░ рдореЗрдВ рдбрд┐рдЧреНрд░реЗрдб рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ тАФ рд╕рддреНрд░ рд╣рд░ рдЬрдЧрд╣ рд▓реЛрдб рд╣реЛрдиреЗ рдпреЛрдЧреНрдп рд░рд╣рддреЗ рд╣реИрдВред
## рд╕реБрд░рдХреНрд╖рд╛ рд╕реАрдорд╛рдПрдБ
- **рд╕рдореАрдХреНрд╖рдХ рдПрдХ рдореЙрдбрд▓ рд╣реИред** рдЙрд╕рдХреЗ рдирд┐рд░реНрдгрдп рд╕рд▓рд╛рд╣рдХрд╛рд░ рдиреАрддрд┐ рд╣реИрдВ, рд╕реБрд░рдХреНрд╖рд╛ рдХрд░реНрдиреЗрд▓ рдирд╣реАрдВ; рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП `human`/`never` рдирд┐рдпрдо рдЪреБрдиреЗрдВред
- **рд╡рд┐рдлрд▓-рдмрдВрджред** рд╣рд░ рдЕрд╕рд╛рдорд╛рдиреНрдп рдорд╛рд░реНрдЧ (рдкреНрд░рджрд╛рддрд╛ рдЕрдиреБрдкрд╕реНрдерд┐рдд, рдХреНрд╖рдорддрд╛ рдЕрдВрддрд░рд╛рд▓, рдкреНрд░рд╛рд░рдВрдн рдЕрд╕реНрд╡реАрдХреГрддрд┐, рдЯрд╛рдЗрдордЖрдЙрдЯ, рдЧреИрд░-`completed` рд╕реНрдЯреЙрдк рдХрд╛рд░рдг, рдЕрдиреБрдкрд╕реНрдерд┐рдд/рд╡рд┐рдХреГрдд рдирд┐рд░реНрдгрдп, рдСрдбрд┐рдЯ-рд╕рд╣рд╕рдВрдмрдВрдз рд╡рд┐рдлрд▓рддрд╛) `fallbackPolicy` рд╕реЗ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ `rejected` тАФ рдФрд░ рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдореЙрдбрд▓ рдХреЛ рдПрдХ рдСрдбрд┐рдЯ-рдпреЛрдЧреНрдп рдХрд╛рд░рдг рд▓реМрдЯрд╛рддреА рд╣реИред `allow-once` рдмрд┐рдирд╛ рд╢рд░реНрдд рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ; рдпрд╣ рдХреЗрд╡рд▓ рдЙрди рдЕрдкреНрд░рдмрдВрдзрд┐рдд рдкрд░рд┐рдирд┐рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬрд┐рдирдХрд╛ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдЙрд╕ рдЬреЛрдЦрд┐рдо рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред
- **рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдореАрдХреНрд╖рдХред** рд╕рдореАрдХреНрд╖рдХ рдХреА `toolFilter` рдЕрдиреБрдорддрд┐-рд╕реВрдЪреА (`read`/`glob`/`grep`) рд▓рд┐рдЦ, рд╕рдВрдкрд╛рджрд┐рдд, bash рдЪрд▓рд╛, рдиреЗрдЯрд╡рд░реНрдХ рдЙрдкрдпреЛрдЧ рдпрд╛ рдкреНрд░рддреНрдпрд╛рдпреЛрдЬрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА (`maxDepth` = рдЙрд╕рдХреА рдЕрдкрдиреА рдЧрд╣рд░рд╛рдИ)ред рдЙрд╕рдХрд╛ рд╕рддреНрд░ рд▓реЙрдЧ рд╕реНрдерд╛рдпреА рдФрд░ рдСрдбрд┐рдЯ-рдпреЛрдЧреНрдп рд╣реИред
- **рд╕рдВрджрд░реНрдн-рдкреГрдердХ рд╕рдореАрдХреНрд╖рдХред** рд╕рдореАрдХреНрд╖рдХ рдЪрд╛рдЗрд▓реНрдб рдХреЗ рд╣рд░ рдЪрд░рдг рдХреЛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ `agent/pre-step` рд╕реАрдо рдкрд░ рдЫрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ: рдХреЗрд╡рд▓ рдЙрд╕рдХрд╛ рдЕрдкрдирд╛ рдкреНрд░реЙрдореНрдкреНрдЯ рдФрд░ рдЙрд╕рдХреЗ рдЕрдкрдиреЗ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓реЗ рдЯреВрд▓ рдкрд░рд┐рдгрд╛рдо рд╣реА рднреАрддрд░ рдЖрддреЗ рд╣реИрдВред рд╡рд░реНрдХрд╕реНрдкреЗрд╕ рдирд┐рд░реНрджреЗрд╢ рдлрд╝рд╛рдЗрд▓реЗрдВ (`AGENTS.md` / `CLAUDE.md`), рд╣рд╛рд░реНрдиреЗрд╕ рдХрд╛ рд░рдирдЯрд╛рдЗрдо-рд╕рдВрджрд░реНрдн рд╕реНрдиреИрдкрд╢реЙрдЯ рдФрд░ рд╕рдВрджрд░реНрдн рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдИ рднреА рдкреНрд▓рдЧрдЗрди рд▓реВрдк рджреНрд╡рд╛рд░рд╛ рдЬреЛрдбрд╝реЗ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдЯрд╛ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА-рдирд┐рдпрдВрддреНрд░рд┐рдд рдкрд╛рда рдХрднреА рдЙрд╕ рдШрдЯрдХ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдБрдЪрддрд╛ рдЬреЛ рдХреЙрд▓ рдХреА рдЕрдиреБрдорддрд┐ рддрдп рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд┐рд╕реА рднреА subagent рдкреНрд░рджрд╛рддрд╛ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ тАФ рдпреЗ рдЙрддреНрдкрд╛рджрдХ рд╣рд░ рдирдП рдПрдЬреЗрдВрдЯ рд╕рддреНрд░ рдореЗрдВ рдирдП рд╕рд┐рд░реЗ рд╕реЗ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрдиреНрд╣реЗрдВ рдмрдВрдж рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдпрд╣реА рдлрд╝рд┐рд▓реНрдЯрд░ рд╣реИ, рдкреНрд░рджрд╛рддрд╛ рдХрд╛ рдЪреБрдирд╛рд╡ рдирд╣реАрдВред рдЕрдиреБрдорддрд┐-рд╕реВрдЪреА рд╕рдВрджреЗрд╢ рдХреЗ рд╕реНрд░реЛрдд рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдирдпрд╛ рд╕реНрд░реЛрдд рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд▓рдЧрдЗрди рднреА рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- **рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рддрд░реНрдХ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ** (рдХреБрдВрдЬреА-рдирд╛рдо рдорд┐рд▓рд╛рди: `token`, `password`, `api_key`, `Authorization`, рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓, рдирд┐рдЬреА рдХреБрдВрдЬрд┐рдпрд╛рдБ тАж) рд╕рдореАрдХреНрд╖рдХ рдкреНрд░реЙрдореНрдкреНрдЯ рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ; рдкреНрд▓рдЧрдЗрди рд╕рдореАрдХреНрд╖рд┐рдд рддрд░реНрдХреЛрдВ рдХреЛ рдХрднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ред рд╕рдВрд╢реЛрдзрди рдХреБрдВрдЬреА-рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рд╕рд╛рдордЧреНрд░реА-рдЖрдзрд╛рд░рд┐рдд рдирд╣реАрдВ тАФ рдЙрди рдЯреВрд▓ рдХреА AI рд╕рдореАрдХреНрд╖рд╛ рди рдХрд░реЗрдВ рдЬрд┐рдирдХреЗ рддрд░реНрдХ рдорд╛рди рдЖрдк рдХрд┐рд╕реА рдореЙрдбрд▓ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдирд╣реАрдВ рдЙрдард╛ рд╕рдХрддреЗред
- **рдХрдареЛрд░ рдЕрдХреНрд╖рдорддрд╛рдПрдБ рд╕реНрд╡рдпрдВ рдХреЛ рд╕рдордЭрд╛рддреА рд╣реИрдВред** рдПрдХ `never` рдЯреВрд▓ рдпрд╛ рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо рдирд┐рд░реНрдзрд╛рд░рдХ рд░реВрдк рд╕реЗ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдХреЗрд╡рд▓-рд▓реЙрдЧ `autoReview/rejection` рдШрдЯрдирд╛ рджрд░реНрдЬ рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдЕрд╕реНрд╡реАрдХреГрдд рдЯреВрд▓ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдПрдХ `[auto-review-never]` рдорд╛рд░реНрдХрд░ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ тАФ рдореЙрдбрд▓ рд╕реАрдЦрддрд╛ рд╣реИ рдХрд┐ рдХреНрд░рд┐рдпрд╛ рдХрдареЛрд░ рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо рд╣реИ рдмрдЬрд╛рдп рдЙрд╕реЗ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЗ (invariant-рдЬрд╛рдБрдЪрд╛ рдЧрдпрд╛: рдорд╛рд░реНрдХрд░ тЯ║ рдШрдЯрдирд╛)ред
- **рдЕрд╕реНрд╡реАрдХреГрддрд┐ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░ред** рдПрдХ рдЯрд░реНрди рдореЗрдВ рдЕрд╕реНрд╡реАрдХреГрддрд┐рдпреЛрдВ рдХреА рдПрдХ рд╢реГрдВрдЦрд▓рд╛ рдмреНрд░реЗрдХрд░ рдХреЛ рдЯреНрд░рд┐рдк рдХрд░рддреА рд╣реИ (`windowSize` рдХреЗ рднреАрддрд░ `consecutiveDenies` / `windowDenies`), рдЬреЛ рдПрдХ рдХреЗрд╡рд▓-рд▓реЙрдЧ `autoReview/circuit` рдШрдЯрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрдЬ рд╣реЛрддреА рд╣реИ; рдмрд╛рдж рдХреЗ рдЕрдиреБрд░реЛрдз рдЙрд╕рдХреА `action` (`delegate` / `reject` / `abort-turn`) рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВред
- **рд╕рдореАрдХреНрд╖рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рд╕реНрддреБрдд рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рд╣реИред** `contextBudget` рд╕рдореАрдХреНрд╖рдХ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рд╕рддреНрд░ рд╕рд╛рдордЧреНрд░реА рдЦрд┐рд▓рд╛рддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдорд╛рди-рдорд╛рд░реНрдЧ рд╕рдореАрдХреНрд╖рдХ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рд╡рд╣ рд╕рд╛рдордЧреНрд░реА рдПрдХ рд╣реА рдкреНрд░рджрд╛рддрд╛ рдХреЗ рднреАрддрд░ рд░рд╣рддреА рд╣реИ; `reviewerModel` рдХреЛ рдХрд┐рд╕реА рднрд┐рдиреНрди рдкреНрд░рджрд╛рддрд╛ рдкрд░ рддрднреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ рдЬрдм рдЖрдк рдЙрд╕ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЙрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реЛрдВред
- **`never` рдЗрд╕ рдкрд░рдд рдкрд░ рдПрдХ-рддрд░рдлрд╝рд╛ рд╣реИред** рдПрдХ `never` рдЯреВрд▓ рдпрд╛ рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо рдорд╛рдирд╡ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдЕрдиреБрд░реЛрдз рджреЗрдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджреЗрддрд╛ рд╣реИ тАФ рдПрдХ рд▓реЙрдХрдбрд╛рдЙрди рдирд┐рдпрдВрддреНрд░рдг, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдирд╣реАрдВред
## рдЬреНрдЮрд╛рдд рд╕реАрдорд╛рдПрдБ
- **рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдПрдХреНрд╕рдкреЛрдЬрд╝рд░, рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрд╛рдп тАФ рдХреЛрдИ рдПрдХ рджреВрд╕рд░реЗ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВред** *рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛* рд╕рдВрджрд░реНрдн (рд╡рд░реНрдХрд╕реНрдкреЗрд╕ рдирд┐рд░реНрджреЗрд╢ рдлрд╝рд╛рдЗрд▓реЗрдВ, рд░рдирдЯрд╛рдЗрдо-рд╕рдВрджрд░реНрдн рд╕реНрдиреИрдкрд╢реЙрдЯ, рддреГрддреАрдп-рдкрдХреНрд╖ рдкреНрд▓рдЧрдЗрди рдЗрдВрдЬреЗрдХреНрд╢рди) рд╣рд░ рдирдП рдПрдЬреЗрдВрдЯ рд╕рддреНрд░ рдореЗрдВ рдирдП рд╕рд┐рд░реЗ рд╕реЗ рдЗрдВрдЬреЗрдХреНрдЯ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ `reviewerProvider: fork` рдФрд░ `reviewerProvider: spawn` рджреЛрдиреЛрдВ рдореЗрдВ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рдореАрдХреНрд╖рдХ рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ тАФ рдПрдХ рд╣реА рдЕрдиреБрд░реЛрдз рдкрд░ рджреЛрдиреЛрдВ рдореЗрдВ рдмрд╛рдЗрдЯ-рджрд░-рдмрд╛рдЗрдЯ рд╕рдорд╛рди рдорд╛рдкрд╛ рдЧрдпрд╛ред рдЗрд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ `agent/pre-step` рд╕реНрд░реЛрдд рдлрд╝рд┐рд▓реНрдЯрд░ рд╣реИ, рджреЛрдиреЛрдВ рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде; **рдХреЗрд╡рд▓ `spawn` рдЕрдкрдирд╛рдиреЗ рд╕реЗ рд╡рд░реНрдХрд╕реНрдкреЗрд╕ рдирд┐рд░реНрджреЗрд╢ рд╕рдореАрдХреНрд╖рдХ рддрдХ рдкрд╣реБрдБрдЪрдирд╛ рдмрдВрдж рдирд╣реАрдВ рд╣реЛрддреЗред** рдЕрд▓рдЧ рд╕реЗ, `fork` рдЪрд╛рдЗрд▓реНрдб рдХреЛ рдкреНрд░рддреНрдпрд╛рдпреЛрдЬрдХ рд╕рддреНрд░ рдХреЗ рдкреВрд░реНрдг рд╣реБрдП рдЯрд░реНрди рд╕реЗ рд╕реАрдб рдХрд░рддрд╛ рд╣реИ: рд╡рд╣ рдЗрддрд┐рд╣рд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рдЪрд╛рдЗрд▓реНрдб рдХрд╛ рдЕрдкрдирд╛ рд▓реЙрдЧ рд╣реИ, рдХрд┐рд╕реА рдЪрд░рдг рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ, рдЗрд╕рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рдЙрд╕ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдБрдЪ рд╕рдХрддрд╛ рдФрд░ рдХреЗрд╡рд▓ `spawn` рдЙрд╕рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИ тАФ рдмреАрдЪ рдореЗрдВ рд╕рдореАрдХреНрд╖рдХ рдкреНрд░реЙрдореНрдкреНрдЯ рдХреА рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп-рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдмрд╛рдбрд╝ рд╢рдорди рдХреЗ рд░реВрдк рдореЗрдВ рд░рд╣рддреА рд╣реИред рдКрдкрд░ рдХреА рджреЛрдиреЛрдВ рдЯреНрд░реЗрд╕ рдореЗрдВ рд╕реАрдбрд┐рдВрдЧ рд╕реЗ рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрджреЗрд╢ рдирд╣реАрдВ рдмрдирд╛, рдЗрд╕рд▓рд┐рдП рдЙрд╕рдХрд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдкреНрд░рднрд╛рд╡ рдЕрдкрд░рд┐рдорд╛рдгрд┐рдд рд╣реИред
- рд╕рдореАрдХреНрд╖рдХ рдХреЛ рдПрдХ рдХрд╛рд░реНрдпрд╢реАрд▓ LLM рдорд╛рд░реНрдЧ рдЪрд╛рд╣рд┐рдП (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд); рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рд╣рд░ рд╕рдореАрдХреНрд╖рд╛ `fallbackPolicy` рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЧрд┐рд░рддреА рд╣реИ тАФ рдХрднреА рдореМрди рдЕрдиреБрдорддрд┐ рдирд╣реАрдВред
- `reviewerTools` рдирд╛рдо рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╡реИрд╢реНрд╡рд┐рдХ рдЯреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдореМрдЬреВрдж рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП; рдЕрдЬреНрдЮрд╛рдд рдирд╛рдо рд╕рдореАрдХреНрд╖рдХ рдЪрд╛рдЗрд▓реНрдб рдХреЛ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдмрд┐рдВрджреБ рдкрд░ рдЬрд╝реЛрд░ рд╕реЗ рд╡рд┐рдлрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ fallback рд╣реЛрддрд╛ рд╣реИред
- рдЬреЛрдЦрд┐рдо рдирд┐рдпрдо рдЕрдкрдиреЗ `field` рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдиреБрд░реЛрдз рдХреЗ `reason`, `toolName` рдпрд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХреЙрд▓ `arguments` рд╕реЗ рдорд┐рд▓рддреЗ рд╣реИрдВ; рдмрд╛рдХреА рд╢рд░реНрддреЗрдВ `toolsPolicy.overrides` рдореЗрдВ рд░рдЦреЗрдВред
- `/auto-review approve` рдУрд╡рд░рд░рд╛рдЗрдб рдЙрд╕реА рдЯреВрд▓ рдХреА рдЕрдЧрд▓реА рд╕рдореАрдХреНрд╖рд╛ рдХреЛ рдЕрдзрд┐рдХреГрдд рдХрд░рддрд╛ рд╣реИ, рдЙрд╕ рд╕рдЯреАрдХ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рдХреЙрд▓ рдХреЛ рдирд╣реАрдВ; рдЙрд╕реА рдЯреВрд▓ рдкрд░ рдПрдХ рднрд┐рдиреНрди рдХреНрд░рд┐рдпрд╛ рдЙрд╕реЗ рдЙрдкрднреЛрдЧ рдХрд░ рд▓реЗрддреА рд╣реИред
- рдирд┐рд░реНрдгрдп рдШрдЯрдирд╛рдПрдБ рдХреЗрд╡рд▓-рд▓реЙрдЧ рд╣реИрдВ; рд╡реЗрдм рд╕рдореАрдХреНрд╖рд╛ рдкреИрдирд▓ рдореБрдбрд╝рд╛ рд╣реБрдЖ `autoReview` рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдкрдврд╝рддрд╛ рд╣реИ (рдХрдЪреНрдЪреА рдШрдЯрдирд╛ рдзрд╛рд░рд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкреНрд▓рдЧрдЗрди рддрдХ рдХрднреА рдирд╣реАрдВ рдкрд╣реБрдБрдЪрддреА)ред
- рдорд╛рд░реНрдХрд░ рдХрд╛ рд╕рдореНрдорд╛рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╣реЛрд╕реНрдЯ рдкрд░ `autoReview/state` рдФрд░ `autoReview/verdict` рд▓рд┐рдлрд╝рд╛рдлрд╝реЗ рдХреЗ `ignorable: true` рдорд╛рд░реНрдХрд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдХреЛрдИ рднреА harness рдмрд┐рд▓реНрдб рд▓реЙрдЧ рд▓реЛрдб рдХрд░реЗ тАФ рдЬреЛ рдкрд╛рдардХ рд░реЗрдкреЛ-рдмрд╛рд╣рд░реА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╡реЗ рдЙрди рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдмрд╕ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред рд░рд┐рд▓реАрдЬрд╝ рдХрд┐рдП рдЧрдП rc рд╣реЛрд╕реНрдЯ (rc.1тАУrc.8) рдкрд░ runtime рдЫреВрдЯреЗ рдорд╛рд░реНрдХрд░ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдХрд░ рдпреЗ рдШрдЯрдирд╛рдПрдБ рдХрднреА рдирд╣реАрдВ рд▓рд┐рдЦрддрд╛ (рдЗрди-рдореЗрдореЛрд░реА рдорд┐рд░рд░ рдХрдорд╛рдВрдб, рдмрдЬрдЯ, рдмреНрд░реЗрдХрд░ рдФрд░ `approve` рдХреЛ рд╕рддреНрд░ рднрд░ рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИ); 0.5.1 рд╕реЗ рдкрд╣рд▓реЗ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╕реЗ рджреВрд╖рд┐рдд рд╕рддреНрд░ `dsh-permission-rules` рдХреЗ `scripts/repair-session-logs.mjs` рд╕реЗ рдорд░рдореНрдордд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдЗрд╕рдХрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯ рд╕рднреА рдкрд╛рдБрдЪ `autoReview/*` рдШрдЯрдирд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ)ред
- git рдЪреИрдирд▓ рдХреЛ рд╡рд╣ рдПрдХрд▓ `allowBuilds` рдХреБрдВрдЬреА рдЪрд╛рд╣рд┐рдП рдЬреЛ `dsh` CLI рд╕реНрд╡рдпрдВ `dsh-auto-review` рдХреЗ рд▓рд┐рдП рдЫрд╛рдкрддрд╛ рд╣реИред рд░реЗрдкреЛ рдЕрдкрдирд╛ `pnpm-workspace.yaml` `allowBuilds: { esbuild: true }` рдХреЗ рд╕рд╛рде рд╢рд┐рдк рдХрд░рддрд╛ рд╣реИ; `typescript` + `tsdown` рдирд┐рдпрдорд┐рдд `dependencies` рд╣реИрдВред
- рд╡реИрдХрд▓реНрдкрд┐рдХ invariant рд╕рд╛рдереА рдХреЛ `invariants` рд╕реЗрд╡рд╛ рдЪрд╛рд╣рд┐рдП (agent-spine рд░рдЪрдирд╛рдПрдБ рдЬреИрд╕реЗ headless/ACP); рд╕рд╛рджрд╛ web рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╡рд╣ рдирд╣реАрдВ рджреЗрддрд╛, рдЗрд╕рд▓рд┐рдП рдкрдВрдХреНрддрд┐ рдмрдВрдбрд▓ рдкреИрдЪ рдореЗрдВ рдЯрд┐рдкреНрдкрдгреА-рдмрдВрдж рд╢рд┐рдк рд╣реЛрддреА рд╣реИред
## рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдп
- [Andy8647/dsh-auto-approval](https://github.com/Andy8647/dsh-auto-approval) тАФ `tools/pre-execute` рдХреИрд╕реНрдХреЗрдб рдкрд░ рдлрд╝рд╛рдЗрд▓-рд▓реЙрдЧ рдСрдбрд┐рдЯ рдХреЗ рд╕рд╛рде рджреЛ-рд╕реНрдерд┐рддрд┐ allow/deny рд╡рд░реНрдЧреАрдХрд░рдгрдХрд░реНрддрд╛ред `dsh-auto-review` рдЬрд╛рди-рдмреВрдЭрдХрд░ рднрд┐рдиреНрди рд╣реИ: рдЖрдзрд┐рдХрд╛рд░рд┐рдХ **answerer** рд╢реНрд░реГрдВрдЦрд▓рд╛, рд╣рдореЗрд╢рд╛ рд╡рд╣реА рд╕реМрдВрдкрддрд╛ рд╣реИ рдЬреЛ рдЙрд╕рдХрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдВрд░рдЪрд┐рдд рдирд┐рд░реНрдгрдп рд╡рд╛рд▓рд╛ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ рджреВрд╕рд░рд╛ рдореЙрдбрд▓, рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХрд╛рд░рдг рдореЙрдбрд▓ рдХреЛ рд▓реМрдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╕рддреНрд░-рд▓реЙрдЧ рдСрдбрд┐рдЯред
- [ACP automation bridge](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/acp/acp) тАФ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ ACP-рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╡рд╛рд▓реЗ рдПрдЬреЗрдВрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ-рдмрд╛рд░ рдорд╢реАрди рдирд┐рд░реНрдгрдпред `dsh-auto-review` рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ harness рдХреЗ рд▓рд┐рдП рд╕рддреНрд░- рдФрд░ рдЯреВрд▓-рдиреАрддрд┐-рджрд╛рдпрд░реЗ рд╡рд╛рд▓рд╛ рд╣реИ; рдпрд╣ рдХрднреА рдЯрд┐рдХрд╛рдК рдЕрдиреБрджрд╛рди рдирд╣реАрдВ рдирд┐рдХрд╛рд▓рддрд╛ред
## рд╡рд┐рдХрд╛рд╕
```sh
pnpm install # node ^22.19 || >=24
pnpm run typecheck # tsc: src + tests, рд╕реНрдерд╛рдиреАрдп harness checkout рдХреЗ рд╡рд┐рд░реБрджреНрдз
pnpm test # vitest: 25 spec рдлрд╝рд╛рдЗрд▓реЗрдВ
pnpm run build # tsc рдШреЛрд╖рдгрд╛рдПрдБ + tsdown рдмрдВрдбрд▓ (lib/, рдХреНрд▓рд╛рдЗрдВрдЯ рдмрдВрдбрд▓ рд╕рд╣рд┐рдд)
pnpm run verify:self-contained
pnpm pack # рдкреНрд░рдХрд╛рд╢рд┐рдд tarball
```
рд░рд┐рдкреЙрдЬрд╝рд┐рдЯрд░реА рд▓реЗрдЖрдЙрдЯ: `src/index.ts` (рдкреНрд▓рдЧрдЗрди рдЕрдиреБрдмрдВрдз) ┬╖ `src/config.ts` (Schemastery рд╕реНрдХреАрдорд╛ + рд╕рдорд╛рдзрд╛рди) ┬╖ `src/runtime.ts` (answerer, рдХрдорд╛рдВрдб, рдЕрд╕реНрд╡реАрдХреГрддрд┐-рдХрд╛рд░рдг рдЗрдВрдЬреЗрдХреНрд╢рди) ┬╖ `src/review.ts` (рд╕рдореАрдХреНрд╖рдХ рдСрд░реНрдХреЗрд╕реНрдЯреНрд░реЗрд╢рди, рдкреНрд░реЙрдореНрдкреНрдЯ, рд╕реНрд╡рдЪреНрдЫрддрд╛) ┬╖ `src/events.ts` (рд╕рддреНрд░-рдШрдЯрдирд╛ рд╢рдмреНрджрд╛рд╡рд▓реА + рдореЛрдбрд╝) ┬╖ `src/projection.ts` + `src/projection-types.ts` (`autoReview` рд╕рддреНрд░ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди) ┬╖ `src/invariant.ts` (invariant рд╕рд╛рдереА) ┬╖ `src/eval/` (dsh-eval рдЗрдВрдЬрди) ┬╖ `eval/` (рд╢рд┐рдк рдХреА рдЧрдИ рдореВрд▓реНрдпрд╛рдВрдХрди рд░рдЪрдирд╛) ┬╖ `bin/dsh-eval.mjs` (CLI рд▓реЙрдиреНрдЪрд░) ┬╖ `src/client/` (рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЖрдзрд╛) ┬╖ `test/` ┬╖ `fixtures/`ред
## рд╡рд┐рд╖рдп
`deepseek-harness`, `dsh`, `dsh-plugin`, `cordis`, `approval`, `auto-review`, `second-model`, `ai-safety`, `sandbox`, `subagent`
## рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛
- [@PerryLink](https://github.com/PerryLink) тАФ рдирд┐рд░реНрдорд╛рддрд╛ рдФрд░ рдЕрдиреБрд░рдХреНрд╖рдХ: рдЕрдиреБрдореЛрджрди answerer, рд╕рдореАрдХреНрд╖рдХ рдЙрдк-рдПрдЬреЗрдВрдЯ, рдЬреЛрдЦрд┐рдо рдиреАрддрд┐ рдФрд░ рд╕рд░реНрдХрд┐рдЯ рдмреНрд░реЗрдХрд░, рд╕рддреНрд░-рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рд╕рдореАрдХреНрд╖рд╛ рдкреИрдирд▓, invariant рд╕рд╛рдереА, dsh-eval, рдФрд░ рдкрд╛рдБрдЪ-рднрд╛рд╖рд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ред
- [@weipeng1999](https://github.com/weipeng1999) тАФ рд╕рдореАрдХреНрд╖рдХ рдХреЗ рд╕реНрд╡рддрдВрддреНрд░ рдкреНрд░рджрд╛рддрд╛/рдореЙрдбрд▓ рд░реВрдЯрд┐рдВрдЧ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд░рдЦрд╛ ([#11](https://github.com/PerryLink/dsh-auto-review/issues/11), [рдЪрд░реНрдЪрд╛ #12](https://github.com/PerryLink/dsh-auto-review/discussions/12)), рдЬреЛ `reviewerProvider` / `reviewerModel` рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рд░реА рд╣реБрдЖред
- [@alexchenzl](https://github.com/alexchenzl) тАФ DSH рдкреНрд▓рдЧрдЗрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдкреНрд▓рдЧрдЗрди рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ ([#10](https://github.com/PerryLink/dsh-auto-review/issues/10))ред
## PerryLink DSH рдкреНрд▓рдЧрдЗрди рдкрд░рд┐рд╡рд╛рд░
рдпрд╣ рдкреНрд░реЛрдЬреЗрдХреНрдЯ [PerryLink](https://github.com/PerryLink) рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░рдХреНрд╖рд┐рдд [40 DeepSeek Harness рдкреНрд▓рдЧрдЗрдиреЛрдВ](https://github.com/PerryLink) рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдЕрдЧрд░ рдпрд╣ рдЖрдкрдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИ, рддреЛ рдмрд╛рдХреА рднреА рдХрд░реЗрдВрдЧреЗ:
| Plugin | One-liner |
|---|---|
| **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | рд╡реЗрдм UI рд╕рд╛рдЗрдбрдмрд╛рд░, рд╕рдВрджреЗрд╢ рдФрд░ рдЕрд╡рд░реЛрдзрди рдХреЗ рд╕рд╛рде рдЯрд┐рдХрд╛рдК рдкреГрд╖реНрдарднреВрдорд┐ рдЪрд╛рдЗрд▓реНрдб рдПрдЬреЗрдВрдЯ | |
| **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧрдд рдкреНрд░рд╢рд╛рд╕рди: рдмрдЬрдЯ, рдХрд╛рд░реНрдмрди рдФрд░ рд╡рд┐рд▓рдВрдмрддрд╛ рдПрдХ рдкреИрдирд▓ рдореЗрдВред | |
| **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-рд╕рдорддреБрд▓реНрдп: рд╕реНрдиреИрдкрд╢реЙрдЯ, рд╕рддреНрд░ рдлрд╝реЙрд░реНрдХ, рдПрдХ-рдмрд╛рд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ | |
| **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Claude Code рд╕рддреНрд░, рдореЗрдореЛрд░реА, рдХреМрд╢рд▓ рдФрд░ CLAUDE.md рдХреЛ DSH рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ | |
| **[dsh-click](https://github.com/PerryLink/dsh-click)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдиреЗрдЯрд┐рд╡ рдбреЗрд╕реНрдХрдЯреЙрдк рдирд┐рдпрдВрддреНрд░рдг тАФ Windows рдкрд╣рд▓реЗред | |
| **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | рд╡реЗрдм рдХрдВрдкреЛрдЬрд╝рд░ рдХреЗ рд▓рд┐рдП рдЯрд░реНрдорд┐рдирд▓-рд╢реИрд▓реА рдЗрдирдкреБрдЯ рдЗрддрд┐рд╣рд╛рд╕: рддреАрд░, Ctrl+R рдЦреЛрдЬ | |
| **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | рдбреЗрдЯрд╛рд╕реЗрдЯ рдЧреБрдгрд╡рддреНрддрд╛ рдЬрд╛рдБрдЪ рд╡ рдЙрджреНрдзрд░рдг рд╕рддреНрдпрд╛рдкрди (рдпрд╣рд╛рдБ рдЙрдкрднреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрдЦреНрдпрд╛-рд╕реЗрддреБ) | |
| **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдореНрдкреНрдЯ-рдЗрдВрдЬреЗрдХреНрд╢рди, рдЬреЗрд▓рдмреНрд░реЗрдХ рдФрд░ рд╕реАрдХреНрд░реЗрдЯ-рд▓реАрдХ рд░рдХреНрд╖рд╛ред | |
| **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ-рдЕрдиреБрд╢рд╛рд╕рди рд░рдХреНрд╖рдХ: рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреА рдкреВрдЫрддрд╛рдЫ, рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░, рдкреНрд░рддрд┐рджреНрд╡рдВрджреНрд╡реА рд╕рдореАрдХреНрд╖рд╛ | |
| **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдПрдХреАрдХреГрдд рд╕реНрдереИрддрд┐рдХ-рдЫрд╡рд┐ рдирд┐рд░реНрдорд╛рдг рд░реВрдЯрд┐рдВрдЧред | |
| **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд░реАрдб-рдУрдирд▓реА рдкреНрд░рджрд░реНрд╢рди рдбрд╛рдпрдЧреНрдиреЛрд╕реНрдЯрд┐рдХреНрд╕ред | |
| **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | рдЪреАрдиреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдореНрдпреВрдЪреБрдЕрд▓ рдлрдВрдб рдХреЗ рд▓рд┐рдП рдирд┐рдпрддрд╛рддреНрдордХ рдЕрдиреБрд╕рдВрдзрд╛рди рд░рд┐рдкреЛрд░реНрдЯ | |
| **[dsh-github](https://github.com/PerryLink/dsh-github)** | DSH рдХреЗ рд▓рд┐рдП GitHub PR/issues рдПрдХреАрдХрд░рдг, рд╣рд░ рд▓реЗрдЦрди рдЕрдиреБрдореЛрджрди-рджреНрд╡рд╛рд░рд┐рдд | |
| **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | рдЙрджреНрдпреЛрдЧ-рдЕрдиреБрд╕рдВрдзрд╛рди рдСрд░реНрдХреЗрд╕реНрдЯреНрд░реЗрд╢рди рдЬреЛ рдЗрд╕ рдкреНрд▓рдЧрд┐рди рдХреЗ `ctx.researchReport.assemble` рд╕реЗ рдбрд┐рд▓реАрд╡рд░реЗрдмрд▓ рд╕реАрд▓ рдХрд░рддрд╛ рд╣реИ | |
| **[dsh-library](https://github.com/PerryLink/dsh-library)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдЬреНрдЮрд╛рдирдХреЛрд╢ред | |
| **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдиреАрдп-рдореЙрдбрд▓ (Ollama) рдПрдХреАрдХрд░рдгред | |
| **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | рднрд╛рд╖рд╛ рд╕рд░реНрд╡рд░реЛрдВ рдкрд░ LSP рдирд┐рджрд╛рди, рдлрд╝реЙрд░реНрдореЗрдЯрд┐рдВрдЧ, рдкреВрд░реНрдгрддрд╛, рдХреЛрдб рдХреНрд░рд┐рдпрд╛рдПрдБ рдФрд░ рдирд╛рдо рдмрджрд▓рдирд╛ | |
| **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII рдорд╛рд╕реНрдХрд┐рдВрдЧ рдорд┐рдбрд▓рд╡реЗрдпрд░: рдореЙрдбрд▓ рд╕реАрдорд╛ рдкрд░ рдЕрдирд╛рдо рдХрд░реЗрдВ, рдбрд┐рд╕реНрдкреНрд▓реЗ рд▓реЗрдпрд░ рдкрд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ | |
| **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рд╡рд╛рд▓рд╛ MCP рд░рдирдЯрд╛рдЗрдо рдкреИрдирд▓: /mcp рдХрдорд╛рдВрдб + рд╕реНрдерд┐рддрд┐, рдЯреВрд▓ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╡рд╛рд▓рд╛ Settings рдЯреИрдм | |
| **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | рдЕрдиреБрдореЛрджрди-рджреНрд╡рд╛рд░рд┐рдд рдХреНрд░реЙрд╕-рд╕рддреНрд░ рдореЗрдореЛрд░реА: ctx.memory рд╕реАрдо + SQLite + рдореЗрдореЛрд░реА рдЯреВрд▓ | |
| **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП OpenTelemetry рдФрд░ Langfuse рдЕрд╡рд▓реЛрдХрдиреАрдпрддрд╛ рдирд┐рд░реНрдпрд╛рддрдХред | |
| **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-рд╕рдорддреБрд▓реНрдп рд░рдирдЯрд╛рдЗрдо рд╢реИрд▓реА рдмрджрд▓рд╛рд╡ | |
| **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | рдорд▓реНрдЯреА-рдЪреИрдирд▓ рдЕрдиреБрдореЛрджрди/рдкреНрд░рд╢реНрди рдмреНрд░рд┐рдЬ: WeChat/Telegram/Feishu, рд╕рддреНрд░ рдХрдВрд╕реЛрд▓ |
| **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | рдСрдбрд┐рдЯ рдХреЗ рд╕рд╛рде Claude Code-рд╢реИрд▓реА рдШреЛрд╖рдгрд╛рддреНрдордХ allow/deny/ask рдЕрдиреБрдорддрд┐ рдирд┐рдпрдо | |
| **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | рд╢реАрд░реНрд╖-рдмрд╛рд░ рдЯреЙрдЧрд▓ рдХреЗ рд╕рд╛рде рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд┐рд░реНрджреЗрд╢ рдЗрдВрдЬреЗрдХреНрдЯрд░ (рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕рдВрд╕реНрдХрд░рдг) |
| **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | рдорд╛рдБрдЧ рдкрд░ рдПрдЬреЗрдВрдЯ рдХреМрд╢рд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд▓рдЧрдЗрди-рд╡рд┐рдХрд╛рд╕ рдЬреНрдЮрд╛рди рдЖрдзрд╛рд░ | |
| **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | рд╕рд╛рдордЧреНрд░реА-рдкрддрд╛ рд╕рд╛рдХреНрд╖реНрдп рдФрд░ рд╕реАрд▓рдмрдВрдж рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╡рд╛рд▓рд╛ рд╕рддреНрдпрд╛рдкрди-рдпреЛрдЧреНрдп рдЕрдиреБрд╕рдВрдзрд╛рди-рд░рд┐рдкреЛрд░реНрдЯ рдЗрдВрдЬрди | |
| **[dsh-score](https://github.com/PerryLink/dsh-score)** | DeepSeek Harness рдкреНрд▓рдЧрд┐рдиреЛрдВ рдХреА рдмрд╣реБ-рдЖрдпрд╛рдореА рдЧреБрдгрд╡рддреНрддрд╛ рд╕реНрдХреЛрд░рд┐рдВрдЧред | |
| **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | рдЯрд┐рдХрд╛рдК рдХреНрд░рдо рдХреЗ рд╕рд╛рде рд╡реЗрдм рд╕рд╛рдЗрдбрдмрд╛рд░ рдореЗрдВ рд╕рддреНрд░ рдкрд┐рди рдХрд░реЗрдВ | |
| **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдбрд┐рд╡рд╛рдЗрд╕ рд╕рддреНрд░ рд╕рд┐рдВрдХ тАФ рдЖрдкрдХреЗ рд╕рддреНрд░ рд╕реНрдЯреЛрд░ рдХрд╛ рдПрдХ рд╕рдорд░реНрдкрд┐рдд git рдорд┐рд░рд░ред | |
| **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | рд╕реБрд░рдХреНрд╖рд╛-рдСрдбрд┐рдЯ рдХреМрд╢рд▓ рдкреИрдХ: рдЧреБрдкреНрдд рд╕реНрдХреИрди, рдирд┐рд░реНрднрд░рддрд╛ рдФрд░ рдЖрдкреВрд░реНрддрд┐-рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕рдореАрдХреНрд╖рд╛ | |
| **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рдЖрд╡рд╛рдЬрд╝-рдкреНрд░рдердо рд╕рддреНрд░ рд▓реВрдк: рдмреЛрд▓реЗрдВ рдФрд░ рдЙрддреНрддрд░ рд╕реБрдиреЗрдВред | |
| **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | DeepSeek Harness рдкреНрд▓рдЧрд┐рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдкреГрдердХ рдЗрдВрд╕реНрдЯреЙрд▓-рдПрдВрдб-рд╕реНрдореЛрдХ рдЯреЗрд╕реНрдЯ рдбреНрд░рд╛рдЗрд╡ред | |
| **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 рдХрд╛рд░реНрдп рдмреНрд░рд┐рдЬ: рд╕рддреНрд░-рд╣реЗрдбрд░ рдкреИрдирд▓ + 11 рдЯреВрд▓ |
| **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | DeepSeek Harness рдХреЗ рд▓рд┐рдП рд╡реЗрдВрдбрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрд╡рд╛рдж рдФрд░ рдирд┐рдпрддрд╛рддреНрдордХ JSON рдорд░рдореНрдорддред | |
| **[dsh-wechat](https://github.com/pan17/dsh-wechat)** | WeChat тЖФ DSH рдмреНрд░рд┐рдЬ (Tencent iLink bot): рдЯреЗрдХреНрд╕реНрдЯ/рдЗрдореЗрдЬ/рдлрд╝рд╛рдЗрд▓/рдЖрд╡рд╛рдЬрд╝, рдЪреИрдЯ рдореЗрдВ рдЕрдиреБрдореЛрджрди |
| **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | Automatic strong/cheap model-tier routing with deterministic risk guards and a `/tier` command | |
| **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
| **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
| **[dsh-kit](https://github.com/PerryLink/dsh-kit)** | One-command starter pack that installs the core family | |
| **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
| **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
| **[dsh-plugin-portal](https://github.com/PerryLink/dsh-plugin-portal)** | Zero-dependency static portal rendering the whole plugin family as one page | |
| **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` тЖТ `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
| **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
| **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
### DSH Desktop рдорд╛рд░реНрдХреЗрдЯ рд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВ
рд╕рднреА PerryLink рдкреНрд▓рдЧрдЗрди DSH Desktop рдХреЗ рдмрд┐рд▓реНрдЯ-рдЗрди рдорд╛рд░реНрдХреЗрдЯ рдореЗрдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ: **Market тЖТ Sources тЖТ add source тЖТ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВ** `https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json` **тЖТ рдЪреБрдиреЗрдВ**ред рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рдорд╛рд░реНрдХреЗрдЯ рдХреЗ npm-identity рд╕рддреНрдпрд╛рдкрди рдФрд░ рдЖрдкрдХреА рдкреБрд╖реНрдЯрд┐ рд╕реЗ рд╣реА рд╣реЛрддрд╛ рд╣реИред
## рд▓рд╛рдЗрд╕реЗрдВрд╕
[Apache License 2.0](LICENSE) ┬й 2026 dsh-auto-review contributors