feat(pi-permission-system): AutoReview 改为跟随主模型的对话式工具调用审查

AutoReview:

- 审查器回到 Codex Guardian 风格的对话式审查,默认跟随会话当前主模型
  (每次审查实时读取 ctx.model);provider/model 必须同时设置才固定审查
  模型,只设其一视为配置错误并转人工。
- 结论只通过 approve / reject 两个工具给出,参数仅 reason;不强制
  toolChoice,正文文本(即使是合法 JSON)一律忽略。
- approve 自动放行;reject 转人工并在弹窗显示理由(标注模型生成)。
  超时、Provider 错误、截断、未调用工具、多次调用、参数无效等异常同样
  转人工,并附固定的系统说明;用户按 Esc 中止时直接拒绝。
- 模型调用改为 modelRegistry.streamSimple(...).result():Pi 1.3.0 面向
  扩展的 ModelRegistry 没有 completeSimple,原写法在真实环境中每次都会
  转人工。
- 对话记录保留可信度标注;工具结果在有更短的 pi-compaction 摘要时替换
  为摘要;token 估算改为非 ASCII 字符按 1 token 计;预算可配置。
- 同一条用户消息内完全相同的请求只缓存 approve 结论。
- 默认 reasoning low、总超时 30 秒、最多 2 次尝试、maxOutputTokens 4000。

删除:

- 未发布过的 TypeSafe Jev 分类器实现、DenialCircuitBreaker。
- 整个 annotator 机制(model-explanation、注册表、registerAnnotator、
  provider-timeout);annotators 配置键保留为已弃用并忽略,避免旧配置
  被拒绝。

测试:

- 新增 reviewer / transcript / 弹窗说明 / 默认配置测试;清理重复、恒真
  或只测实现细节的旧测试。
- 使用 deepseek-v4.1-flash 实测 5 个场景各 5 次,25 次结论全部符合预期。

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
云服务部-叶林立
2026-10-19 01:54:17 -07:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent dec48dab6d
commit 7e6a8faae1
87 changed files with 2831 additions and 2658 deletions
+3 -3
View File
@@ -98,9 +98,9 @@
- 权限策略默认允许常规工具,允许 FFF 工具;拒绝 Bash 直搜,硬防御默认只保留确定性的破坏性 Shell 命令;Git 非只读操作、包管理、文件/系统/网络高风险操作与普通 MCP 调用按唯一全局 policy 判定。项目外路径不再产生独立 `external_directory` 判断,只走配置中的工具、`path` 与 Bash pattern。
- SSH 权限沿用同一条 `pi-permission-system` gate 与 `auto-review` authorizer chain:`ssh_connect`、`ssh_cd`、`ssh_read`、`ssh_write`、`ssh_edit`、`ssh_find`、`ssh_grep` 默认 `ask`;连接前的证据解析已导入 host ID 为非秘密 target、port 与请求/default cwd,AutoReview 只可依据用户直接消息中的明确目标授权连接。`ssh_bash` 通过 `shellTools` 映射到完整 Bash 策略并设置 `decisionFloor: "ask"`,把普通 Bash `allow` 提升为复核请求,同时保留原有 `ask` 与硬 `deny`。全部远端路径不得送入基于本机 cwd 的默认 `input.path` 归一化。
- `auto-review` 是 `pi-permission-system` 内置 authorizer,不是独立扩展或第二个 `tool_call` gate;只复核普通策略产生的 `ask`,不会重复处理普通策略已 `allow` / `deny` 或硬防御已 `deny` 的请求。
- reviewer 返回 `allow` 时自动批准(包括 `path`),返回 `deny` 时直接拒绝;配置、模型、认证、超时或响应异常时必须 `defer` 到正常人工提示。不得在 authorizer chain 外增加第二层内置授权范围限制。
- 默认 reviewer 不设 provider/model 常量,也不合成替代模型:自动评审只使用用户在配置文件中显式命名的模型。`autoReview.provider` / `autoReview.model` 任一缺失即 `defer` 到人工审批,并在 `session_start` 提示一次(仅当 `auto-review` 已在 `authorizerChain` 中时);provider 未注册或模型未发布同样 `defer`。reasoning 也完全由配置决定,不设默认常量。90 秒总重试预算和内置 Codex Guardian 风格策略保持不变;只把 active branch 中的直接用户消息与已识别、未取消的结构化问答作为授权证据,assistant/tool/compaction 内容不能自行授权。
- `config/pi-permission-policy.jsonc` 必须显式配置 `authorizerChain: ["auto-review"]`,普通未匹配请求和需要自动复核的 Git 非只读、包管理等类别声明为 `ask`;普通 pattern 必须按具体度优先(精确匹配、字面字符更多、通配符更少、pattern 更长,最后才以声明顺序破同级);`autoReview` 段只保留 `enabled`,provider/model/reasoning 不设种子默认值,由用户按本机实际可用的模型自行填写;`config/pi-permission-hard-guards.jsonc` 独立保存可由用户调整但不能被普通策略、Session grant、per-agent 规则或 reviewer 覆盖的高危 `deny`。
- reviewer 是对话式 Codex Guardian 风格审查:以独立请求(不写入主会话)把有界 active-branch 对话记录与权限请求交给模型,模型只能通过 `approve` / `reject` 两个工具给出带 `reason` 的结论,不强制 `toolChoice`。`approve` 自动批准(包括 `path`);`reject` 以及配置、模型、超时、Provider 错误、截断、未调用工具、多次调用或参数无效等一切异常都必须 `defer` 到人工提示,并在弹窗中显示原因(模型理由标注为模型生成)。正文文本即使是合法 JSON 也不得作为结论;只有用户按 Esc 中止当前操作时才直接拒绝。不得在 authorizer chain 外增加第二层内置授权范围限制,也不得恢复 annotator 机制。
- reviewer 默认跟随会话当前主模型(每次审查实时读取 `ctx.model`),经 `modelRegistry.streamSimple(...).result()` 调用;`autoReview.provider` / `autoReview.model` 必须同时设置(固定审查模型)或同时留空,只设其一视为配置错误并 `defer`。默认 `reasoning: "low"`(仅对支持推理的模型生效)、总超时 30 秒、最多 2 次尝试(仅 Provider 错误重试)、`maxOutputTokens` 4000。只把 active branch 中的直接用户消息与已识别、未取消的结构化问答作为授权证据,assistant/tool/compaction 内容不能自行授权;工具结果可替换为更短的 pi-compaction 摘要,但仍属不可信证据。同一条用户消息内完全相同的请求只缓存 `approve` 结论。
- `config/pi-permission-policy.jsonc` 必须显式配置 `authorizerChain: ["auto-review"]`,普通未匹配请求和需要自动复核的 Git 非只读、包管理等类别声明为 `ask`;普通 pattern 必须按具体度优先(精确匹配、字面字符更多、通配符更少、pattern 更长,最后才以声明顺序破同级);`autoReview` 段只保留 `enabled`,不设 provider/model 种子值,使审查默认跟随主模型;`config/pi-permission-hard-guards.jsonc` 独立保存可由用户调整但不能被普通策略、Session grant、per-agent 规则或 reviewer 覆盖的高危 `deny`。
- `pi-lsp` 的 TypeScript/JavaScript 后端由根包固定依赖提供,`extensions/lsp.ts` 使用当前 Node 可执行文件直接启动包内 `typescript-language-server` CLI,不得依赖或调用 VS Code GUI;Kotlin/JDT LS 仍使用组合包部署的 `kotlin-lsp --stdio` 与 `jdtls` 配置,根包不安装这两个系统可执行文件,便捷脚本可在用户逐项明确确认后通过 Homebrew 安装 Kotlin LSP、Java 21 和 JDT LS。
- 终端环境配置只属于便捷脚本:Kitty 可选安装后可通过官方 kitten 启用 Solarized Dark;Oh My Zsh 使用不切换 shell 的 unattended 安装;Powerlevel10k 将仓库内置的 `config/p10k.zsh`(Rainbow/ASCII 单行紧凑主题)部署到 `~/.config/my-pi/p10k.zsh`(遵循 `XDG_CONFIG_HOME`),不得覆盖用户自己的 `~/.p10k.zsh`。`.zshrc` 中脚本拥有的内容必须使用 `# >>> my-pi:<id> >>>` / `# <<< my-pi:<id> <<<` 受管块,更新时只替换块内内容;标记不完整或重复时拒绝修改。实际修改前必须创建带时间戳的备份。`git`、`zsh-autosuggestions`、`zsh-syntax-highlighting` 在安装流程中逐项询问后才安装或启用。
- 原生远程压缩限定为 `openai-codex` + `openai-codex-responses` 与 `sub-api` + `openai-responses`,默认在 turn boundary 达到 effective 下界 90% 时触发。`pi-compaction/src/native-provider.ts` 统一资格与传输选择:Codex 保留原 endpoint/JWT/account ID;SubAPI 从显式 `baseUrl` 解析公共 `/responses`,使用配置的 API key 和请求头,不解析 ChatGPT account ID、不硬编码网关域名,也不调用独立 `/responses/compact`。两者复用 projection、`compaction_trigger`、SSE 结果、native checkpoint 恢复和 portable 模型切换摘要;SubAPI 部署须支持原生 compaction v2。普通聊天支持不代表压缩支持,失败回退 Pi,不自动改写用户模型配置。