Skip to content

fix(auto-review): 保留宿主审批并用当前模型静默兜底 - #1227

Merged
MagicLizi merged 56 commits into
makecindy:mainfrom
zqchris:auto-review-native-routing
Aug 1, 2026
Merged

fix(auto-review): 保留宿主审批并用当前模型静默兜底#1227
MagicLizi merged 56 commits into
makecindy:mainfrom
zqchris:auto-review-native-routing

Conversation

@zqchris

@zqchris zqchris commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

基础 PR #1226 已合入 main;本分支已按堆叠规则 merge 最新主干,当前 diff 只剩行为接线,现转 ready。

乱序安全:只合 #1226 不改变现有审批行为;#1227 在基础层已存在时独立接入 Claude / Codex 路由,单独回滚本 PR 也会恢复原行为。

这次改了什么

摘要

修正 Auto-review 的产品语义:用户选择 Auto 后,日常开发动作不应不断弹人工确认。

  • Claude Auto 恒走 SDK default + canUseTool,保留宿主 MCP、逐次确认与 AskUserQuestion 语义;Codex 官方 OpenAI OAuth 保留 Guardian。
  • 第三方 / 网关路由不再借用 harness 隐藏 reviewer,改用当前会话已经选择的 provider + model 做轻量审查,不假设用户还有其它模型或额度。
  • Codex 原生 reviewer 运行期失效时,会话仍保持 Auto,只把后续审批切到 Cindy fallback;Claude 已恒走宿主审批链,不再向 SDK 透传会绕过回调的 auto。两端都不持久化为 Ask,也不广播 Auto→Ask。
  • 本地确定性规则直接放行明显安全动作、直接询问明确红线;中间灰区才给当前模型判 allow / block / ask。只有 ask 才能弹用户,模型故障、超时或畸形输出都静默 block,让主 Agent 换安全做法。
  • reviewer 只看当前用户意图、当前动作和有限工作区根,不携带对话历史、工具结果、Memory、Skill 或可调用工具;同一轮完全相同动作复用裁决。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

UI 变化

仅 UI 文案:权限档选择器里 Claude Code「Auto-review」档的说明补一句「高风险操作可能被拒绝或要求确认」(en / zh-CN / ja / ko 四语)。没有新增或修改界面、布局、样式、动效或交互控件。

改动理由:本 PR 让 Claude 与 Codex 的 auto 档共用同一套确定性核心,而 claude-code 的原说明只讲「自动审批提权请求…能减少打断」,没提确定性红线仍会逐次征求确认(codex 档的说明本就有这句)。用户据此会以为 Auto 完全不打扰,实际偶发弹窗,预期不符。

  • 引用的设计规范:DESIGN.md §11 Voice & Content(微文案规范)——按 §11.3 自检逐条核对:四语 common.json 全部更新且各自符合本语言的大小写/标点约定(en 句式大小写、zh-CN 全角标点无句末句号约束不适用于正文说明、ja 、ko .);无「成功/successfully」填充词;非按钮/非错误/非进行中文案,对应条目不适用。术语门禁 pnpm check:i18n-glossaryscripts/check-i18n.mjs(6228 key 四语一致)均通过。

怎么验证的

自动验证

pnpm --filter @cindy/maker-core exec vitest run \
  src/agents/shared/auto-review-decision.test.ts \
  src/agents/shared/auto-review.test.ts \
  src/agents/claude-code/__tests__/auto-review-policy.test.ts \
  src/agents/claude-code/__tests__/auto-review-wiring.test.ts \
  src/agents/claude-code/__tests__/capability-routing.test.ts \
  src/agents/codex/index.test.ts \
  src/agents/codex/capability-routing.test.ts \
  --maxWorkers=1 --minWorkers=1
结果:554 tests passed

本轮 review follow-up 定向复验:
- auto-review.test.ts + codex/index.test.ts:484 tests passed(单 worker)
- 4 个相关文件定向 ESLint:通过;Codex 历史测试文件仅屏蔽既有 unused-variable 两处

pnpm --filter desktop exec vitest run \
  src/main/utility-model/__tests__/oneShotCandidates.test.ts \
  src/main/maker-host/__tests__/autoPermissionReviewer.test.ts \
  src/main/maker-host/__tests__/claudeAutoPermissionFallback.test.ts \
  --maxWorkers=1 --minWorkers=1
结果:66 tests passed

pnpm --filter desktop run typecheck
结果:通过

GitHub DCO check
结果:head 15ae910c 已通过

手工验证

用代表性的当前 Claude 与 Codex 会话模型发送生产形状的极小 reviewer prompt:

  • typecheck → 两端均返回 allow
  • 与用户清理意图一致的构建产物删除 → Claude 路由返回 allow
  • 强推主分支 → Codex 路由返回 ask
  • OpenAI ChatGPT Codex 私有 Responses 路由验证为不发送其不支持的 max_output_tokens,请求成功返回紧凑 JSON。

reviewer 请求使用低推理强度、8 秒超时;输入有 2,000 字符意图 / 4,096 字符动作 / 8 个工作区根上限,超长灰区动作不会截断后送审,而是在调用模型前静默 block;响应超过 1,024 字符或不符合三态 schema 时同样按失败处理。

未执行的验证

  • 未在本机运行无界全仓 pnpm test:unit:该机器曾被全仓高并发测试卡死,本地按定向单 worker 验证,完整门禁交由 CI。
  • 对变更文件执行了定向 ESLint;只报告这些历史大文件在当前 main 已存在的 unused-variable 项,本次 diff 未新增 lint finding。最终以 CI 为准。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 影响范围:Desktop 上 Claude Code / Codex 的 Auto 审批路由;本地与 SSH 路径分别传真实平台 / 保守 Linux 平台,MCP 既有审批政策不变。
  • 安全边界:明确凭证、提权、系统 / 磁盘控制和全局权限放宽仍由确定性规则逐次询问;AI 只处理灰区,失败不会退回 Ask 打扰用户,也不会 fail-open。
  • 回滚 / 降级方式:回滚本 PR 的行为 commit 即恢复 feat(auto-review): 增加当前模型轻量审查基础设施 #1226 之前的路由;不涉及数据库、持久化 schema、wire protocol、mobile fingerprint 或用户数据迁移。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

Signed-off-by: zqchris <chrisz83@gmail.com>
Copilot AI review requested due to automatic review settings July 31, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

本 PR 调整 Maker Core / Desktop Host 的 Auto-review 行为接线:在 Claude Code / Codex 的 官方 OAuth 路由优先使用原生 reviewer,而在第三方/网关路由或原生 reviewer 运行期失效时,改用 当前会话已选 provider+model 进行轻量三态裁决(allow/block/ask),并确保 故障/超时/畸形输出静默 block、不把会话模式从 Auto 反向持久化为 Ask。

Changes:

  • 重构 auto-review 核心策略为“两层判定”:确定性放行/红线必问 + 灰区交轻量 reviewer 三态裁决,并引入单轮裁决缓存。
  • Claude Code / Codex 接线改为“原生优先 + 当前模型 fallback”,并在原生 reviewer 故障时保持产品模式为 Auto,仅切换 reviewer 路由。
  • Desktop Host 增加轻量 reviewer(最小 prompt + 严格解析/上限),并把 reasoningEffort/max_output_tokens 兼容细节下沉到 utility-model one-shot 请求层。

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/maker-core/src/agents/shared/auto-review.ts 调整 shell/动作的确定性规则分层,引入灰区交给轻量 reviewer 的语义。
packages/maker-core/src/agents/shared/auto-review.test.ts 更新 auto-review 核心单测以匹配“极高风险必问,其余灰区交 reviewer”。
packages/maker-core/src/agents/shared/auto-review-decision.ts 新增统一三态裁决入口与 userIntent 抽取,负责本地规则 + delegate 兜底。
packages/maker-core/src/agents/shared/auto-review-decision.test.ts 覆盖 deterministic 不调用模型、灰区委托、故障静默 block、intent 截断等行为。
packages/maker-core/src/agents/index.ts 导出 AutoReviewDecision/Delegate/Request 与 ReviewableAction 类型供 host 侧使用。
packages/maker-core/src/agents/codex/index.ts Codex Auto 接线:仅官方 OAuth 用 Guardian;第三方路由用当前模型 reviewer;原生故障保持 Auto 并切 fallback。
packages/maker-core/src/agents/codex/index.test.ts 更新 Codex 侧接线测试,覆盖第三方路由当前模型审查、Guardian 故障不降 Ask、仅 ask 才弹 UI 等。
packages/maker-core/src/agents/claude-code/index.ts Claude Code Auto 接线:官方 OAuth 保留 SDK auto;第三方/故障走 SDK default 以触发 canUseTool 并用 Cindy fallback。
packages/maker-core/src/agents/claude-code/auto-review-policy.ts 抽出 normalizeBuiltinToolForAutoReview,使内置工具动作归一化结果可被本地规则与 fallback 共用。
packages/maker-core/src/agents/claude-code/tests/auto-review-wiring.test.ts 更新 Claude 接线集成测试:原生优先、fallback 后保持 Auto、灰区 allow/block 静默处理等。
packages/maker-core/src/agents/claude-code/tests/auto-review-policy.test.ts 更新 Claude 内置工具策略测试以匹配新分层语义。
packages/maker-core/src/agents/base-agent.ts AgentDeps 改为注入 reviewAutoPermissionAction(轻量 reviewer delegate),并在 SessionHandle 增加 useCindyAutoReviewFallback。
apps/desktop/src/main/utility-model/oneShotCandidates.ts one-shot 文本请求增加 reasoningEffort,并对部分私有 Responses 端点禁用 max_output_tokens。
apps/desktop/src/main/utility-model/tests/oneShotCandidates.test.ts 覆盖 reasoning.effort 传递与 max_output_tokens 禁用行为。
apps/desktop/src/main/maker-ipc/register.ts Claude 原生分类器不可用时不再持久化/广播 Auto→Ask,改为运行期切到 Cindy fallback。
apps/desktop/src/main/maker-host/index.ts 注入 createAutoPermissionReviewer + requestUtilityText,作为 host 侧 reviewAutoPermissionAction 实现。
apps/desktop/src/main/maker-host/claude-auto-permission-fallback.ts fallback coordinator 语义改为“保持 Auto,仅切换 reviewer”,并移除持久化/广播。
apps/desktop/src/main/maker-host/auto-permission-reviewer.ts 新增轻量 reviewer:最小 prompt、输入压缩、输出严格解析与日志脱敏。
apps/desktop/src/main/maker-host/tests/claudeAutoPermissionFallback.test.ts 更新 fallback 行为单测:不改持久态,仅触发 useCindyAutoReviewFallback。
apps/desktop/src/main/maker-host/tests/autoPermissionReviewer.test.ts 新增 host 侧 reviewer prompt/parse/故障兜底与日志不泄漏动作内容的测试。

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/desktop/src/main/maker-host/auto-permission-reviewer.ts
Comment thread packages/maker-core/src/agents/shared/auto-review-decision.ts
zqchris added 2 commits July 31, 2026 21:41
Signed-off-by: zqchris <chrisz83@gmail.com>
Signed-off-by: zqchris <chrisz83@gmail.com>
Copilot AI review requested due to automatic review settings July 31, 2026 13:44
@zqchris
zqchris force-pushed the auto-review-native-routing branch from 173d91c to 0529d63 Compare July 31, 2026 13:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Comment thread packages/maker-core/src/agents/shared/auto-review.ts
Signed-off-by: zqchris <chrisz83@gmail.com>
@zqchris
zqchris force-pushed the auto-review-native-routing branch from 0529d63 to e824b0f Compare July 31, 2026 14:02
Copilot AI review requested due to automatic review settings July 31, 2026 14:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/maker-core/src/agents/codex/index.ts:2803

  • autoReviewDecisionCache 的 key 直接 JSON.stringify(request) 会把 action.command/path、workspaceRoots 等原始字符串完整塞进 Map key;当命令/路径很长或 roots 很多时会造成不必要的大字符串分配与内存占用。建议对 key 使用截断/裁剪后的“等价”请求(与 host reviewer 的 compact 上限一致),避免缓存本身成为热点。
        action,
        workspaceRoots: runtimeWorkspaceRoots().filter(
          (dir): dir is string => typeof dir === 'string' && dir.length > 0,
        ),
        platform: sessionReviewPlatform,
      };
      const key = JSON.stringify(request);
      const cached = autoReviewDecisionCache.get(key);
      if (cached) return cached;

packages/maker-core/src/agents/claude-code/index.ts:1588

  • autoReviewDecisionCache 的 key 直接 JSON.stringify(request) 会把 action.command/path、workspaceRoots 等原始字符串完整塞进 Map key;在 Claude 侧 action 还可能包含 URL/query 等较长文本,导致大量大字符串分配。建议用与轻量 reviewer prompt 同步的截断/裁剪 key(不需要包含 sessionId 等短字段),避免缓存 key 过大。
      const request = {
        sessionId: opts.sessionId,
        agentKind: 'claude-code' as const,
        providerId: mutableProviderId,
        model: mutableModel,
        userIntent: currentAutoReviewIntent,
        action,
        workspaceRoots,
        platform,
      };
      const key = JSON.stringify(request);
      const cached = autoReviewDecisionCache.get(key);
      if (cached) return cached;

zqchris added 3 commits July 31, 2026 22:31
Signed-off-by: zqchris <chrisz83@gmail.com>
Signed-off-by: zqchris <chrisz83@gmail.com>
Signed-off-by: zqchris <chrisz83@gmail.com>
Copilot AI review requested due to automatic review settings July 31, 2026 14:31
@zqchris
zqchris force-pushed the auto-review-native-routing branch from e824b0f to b707fda Compare July 31, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/maker-core/src/agents/shared/auto-review.ts:172

  • 当前把执行影响型环境变量注入(如 LD_PRELOAD / DYLD_* / BASH_ENV / PROMPT_COMMAND / PS4)仅归为灰区走轻量 reviewer,这意味着 reviewer 一旦误判为 allow,会在无用户确认的情况下放行典型 RCE 注入。建议将这些“明确的本地代码执行注入”提升为确定性红线(prompt-each-time),只把相对常见的 PATH/PAGER 等留在灰区。
  /\bchmod\b[^|;&]*\s[ugoa]*[oa][ugoa]*[-+=][^\s]*w/,     // chmod 符号型对 other/all 开放写(a+w / o+w / a+rwx)
  ...CREDENTIAL_PATH_PATTERNS,                            // 凭证/密钥路径(见上)
  /\bsecurity\s+(?:find|dump|export|add)-/,               // macOS keychain
  /\$\{?[A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|APIKEY|_PAT)[A-Za-z0-9_]*\}?/i, // 敏感环境变量展开(echo "$API_KEY" 等)
];

packages/maker-core/src/agents/shared/auto-review.test.ts:515

  • 这里的“执行影响型环境变量赋值”用例现在全部断言为 prompt(灰区)。如果按上面建议把 LD_PRELOAD / DYLD_* / BASH_ENV / PROMPT_COMMAND / PS4 这类明确 RCE 注入提升为 prompt-each-time,这个测试需要拆分:高危变量应为 prompt-each-time,其余(如 PATH/PAGER)仍可保持 prompt。
  it('执行影响型环境变量赋值(LD_PRELOAD/PAGER/PATH/DYLD)→ AI 灰区', () => {
    for (const c of [
      'env LD_PRELOAD=/repo/payload.so /usr/bin/true',
      'env PAGER=./payload git --paginate log',
      'env GIT_PAGER=./p git -p log',

zqchris added 2 commits July 31, 2026 23:07
Signed-off-by: zqchris <chrisz83@gmail.com>
Signed-off-by: zqchris <chrisz83@gmail.com>
Copilot AI review requested due to automatic review settings July 31, 2026 15:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/maker-core/src/agents/shared/auto-review-decision.ts:138

  • resolveAutoReviewDecision 在接受 delegate 返回值时直接原样返回 decision;如果某个 host delegate(或未来实现)返回了超长/非字符串的 reason,可能导致后续日志/UI/LLM 反馈携带过大文本。建议在这里做一次防御性规范化:仅接受 string reason,并裁剪到固定上限。
  try {
    const decision = await delegate(request);
    if (
      decision?.verdict === 'allow'
      || decision?.verdict === 'block'
      || decision?.verdict === 'ask'
    ) {
      return decision;
    }

…routing

Signed-off-by: zqchris <chrisz83@gmail.com>

# Conflicts:
#	apps/desktop/src/main/utility-model/oneShotCandidates.ts
#	packages/maker-core/src/agents/base-agent.ts
#	packages/maker-core/src/agents/claude-code/index.ts
#	packages/maker-core/src/agents/codex/index.ts
#	packages/maker-core/src/agents/shared/auto-review-decision.test.ts
#	packages/maker-core/src/agents/shared/auto-review-decision.ts
Copilot AI review requested due to automatic review settings July 31, 2026 22:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f0215283d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/maker-core/src/agents/claude-code/index.ts
Comment thread packages/maker-core/src/agents/shared/auto-review.ts Outdated
Comment thread packages/maker-core/src/agents/shared/auto-review.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@zqchris 👋 这个 PR 还有 3 条 review conversation 没 resolve(packages/maker-core/src/agents/claude-code/index.ts / packages/maker-core/src/agents/shared/auto-review.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

三条 bot 反馈:
1) SSH 远端 `ask_user_question` 回调返回答案前没有并入审查意图 —— 同一个远端回调只为 plan_review
   更新了意图(第三十八批修的),ask 分支漏了。用户在远端把范围从 src/ 收窄到 build/ 后,后续工具
   仍按澄清前的意图裁决,越界操作可能被轻量 reviewer 静默允许。补 composeAutoReviewIntentWithClarification
   (顺带清空裁决缓存),与本地 AskUserQuestion 分支对称。
2) 归档/下载的落地选项在**短选项簇**里解析不到:原正则只认以 `-C`/`-o`/`-O`/`-d`/`-P` 开头的 token,
   `tar -xC /etc -f p.tar`、`unzip -oqd /etc p.zip`、`curl -so/etc/hosts URL`、`wget -qO/etc/hosts URL`
   全部只落灰区。新增 shortClusterOption 按 getopt 语义解析:簇内**第一个**带值字母之后的字符即其值,
   在簇尾则吃下一个 argv;要传该命令**全部**带值短选项字母,否则 `curl -do out URL` 会把 `-d` 的值
   误当输出文件。cp/mv/install/ln 的 `-t` 目标目录同样改走簇语义。
3) chroot 既不在包装器集合也不在红线,`chroot / rm -rf /outside` 的内层命令完全没被看见。chroot 与
   sudo/su 同族(需 CAP_SYS_CHROOT),且**换根后绝对路径也重新指向新根下**(`chroot /mnt rm -rf /repo`
   删的是 /mnt/repo)→ 目标作用域静态不可证,按确定性同意处理;与 `su` 一样只在命令位匹配,
   `git commit -m "fix chroot"` 不误升。

自审顺带修/补的两处(非 bot 报):
- **rsync 的 `-t` 是 --times、不是目标目录**:原 `-t` 判定对 rsync 生效,会把 `rsync -avt /etc/nginx/
  backup/` 的**读源**当写目标而误拦;改成只对 coreutils 的 cp/mv/install/ln 生效(修一处误拦)。
- 下载工具**不带落地选项**时按远端文件名写进当前目录(`curl -O URL`、`wget URL`),cwd 落系统目录即写
  系统文件(与第四十三批"解压落 cwd"同类)→ 以 `.` 为写目标交有效-cwd 解析;curl 默认写 stdout,
  只有 -O/--remote-name 系才算落盘,`curl -sSL URL | sh` 不受影响。

验证:双向语料 —— 22 条危险(六种簇形态 × tar/unzip/curl/wget、`cp -ft /etc`、`wget -o` 日志落盘、
`curl -O`/`wget` 在 /etc 下、`cd /etc && wget`、chroot 三形态)全部必问,改前 17 条只落灰区;
22 条良性(区内落地目录、`wget -qO-`、`curl -sSL`、`curl -d @body.json`、`tar -czf`、`rsync -avt /etc/nginx/
backup/`、`git commit -m "fix chroot …"`、`rg chroot src`)零误拦。均固化为回归测试。
maker-core 1403 单测 + typecheck 全绿。适配器那条(远端 ask)与本地分支对称,compose 函数本身已有单测;
远端回调深在闭包内,未加针对性单测。

Signed-off-by: zqchris <chrisz83@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/desktop/src/main/maker-host/claude-auto-permission-fallback.ts:219

  • 此处注释仍提到“持久态 CAS”,但当前 coordinator 已不再做条件持久化/compare-and-swap(只读 getSessionMeta + runtime fallback)。建议更新注释,避免误导后续维护者对并发/幂等性的理解。
    // 任何一次通知(瞬时升级或确定性 4xx 立即切 fallback)都清零该会话的瞬时记账:
    // 用户重开 Auto 时从零累计,不因残账被单次偶发失败提前推过阈值。协调器自身有
    // in-flight 去重 + 持久态 CAS,重复信号安全。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 940694892c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/maker-core/src/agents/shared/auto-review.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@zqchris 👋 这个 PR 还有 1 条 review conversation 没 resolve(packages/maker-core/src/agents/shared/auto-review.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

…令纳入判定(第四十六批评审)

bot 报的:`script -q -c 'rm -rf /outside' /dev/null` 会真的执行该命令,但 script 不在包装器集合里,
目标级分析只看到外层可执行文件,区外递归删除只落灰区。

script 有两种形态,都会跑命令,一并解析:
- util-linux `script [opts] -c '<命令串>' [file]`:值经 shell 执行(含 `-c'…'` 附着与 `--command=` 形态);
  带独立值的日志/管道选项(-T/-I/-B/-O/-m/-F 及长名)必须消费其值,否则解析会停在文件名而看不到 -c;
  `-t`(util-linux 的 --timing 可无值)刻意不消费 —— 少吃只会让它当 file 操作数被跳过,多吃可能把真正
  的命令吞掉。
- BSD/macOS `script [opts] [file [command ...]]`:跳过选项与 typescript 文件后即内层 argv。
`-c` 缺值或没有内层命令(纯记录交互会话)时留壳 fail-closed,不解包成空。

顺带把同族的启动器一次补齐(不逐条等报):sg(`sg GROUP -c '<命令串>'`,缺 -c 时末位操作数同样是命令串)、
unbuffer(expect 的透明包装,唯一选项 -p 不带值,复用 setsid 分支)、busybox(applet 多路复用器)、
macOS 的 arch(`-arch/-e` 带值)与 caffeinate(`-t/-w` 带值)。选项处理统一遵循既有的**只少吃不多吃**
policy:少吃会让选项值当命令名 → 未知 bin → 灰区 fail-closed,多吃会把真正的 rm 吞掉 → 漏红线。

验证:双向语料 —— 18 条危险(script 七形态含叠加 env、sg 两形态、unbuffer/busybox/arch/caffeinate)
全部必问,改前 **18 条全部只落灰区**;16 条良性(区内命令、`script -q /tmp/typescript` 无内层命令、
裸 arch/caffeinate、`rg "script -c" src`、`git commit -m "add script -c wrapper"`)零误拦。
均固化为回归测试。maker-core 1406 单测 + typecheck 全绿。

Signed-off-by: zqchris <chrisz83@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (1)

apps/desktop/src/renderer/i18n/locales/zh-CN/common.json:4687

  • 该中文描述里“自动审批提权请求”语义更偏向“自动批准”,与同一条目的英文/日文/韩文“reviews/レビュー/검토”(自动审查)不一致,也与本 PR 的三态裁决语义(高风险可能被拒绝或要求确认、灰区可 block)有冲突。建议把“自动审批”改为“自动审查/自动评审”以避免用户误解为必然放行。
          "auto": {
            "label": "自动审批",
            "description": "允许在工作区内读写,并自动审批提权请求;高风险操作可能被拒绝或要求确认。能减少打断,但存在误判风险。"
          },

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a9517b43a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/maker-core/src/agents/shared/auto-review.ts Outdated
Comment thread packages/maker-core/src/agents/shared/auto-review.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@zqchris 👋 这个 PR 还有 1 条 review conversation 没 resolve(packages/maker-core/src/agents/shared/auto-review.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

两条 bot 反馈:
1) `tar xCf /etc payload.tar` —— GNU/BSD tar 都接受传统无横线选项词,原先只认 `-` 开头的 token,
   既判不出解压模式也取不到 `/etc`。关键是这种写法的**带值字母按出现顺序依次取后面的操作数**
   (`xCf /etc p.tar` → C=/etc、f=p.tar),与 getopt 簇的"附着值"语义(`-Cf DIR FILE` 里 C 的值是
   字面 `f`)完全不同,不能复用 shortClusterOption。新增 tarOldStyleOptionWord/tarOldStyleValues,
   只把**首个**参数按传统选项词解析,且要求含功能字母(x/c/t/r/u/A/d),避免 `tar dist` 这类目录名
   被当成选项词。isArchiveExtraction 与 `P`(--absolute-names)判定同步认传统写法。
2) `chmod 000 /etc/passwd` / `chown attacker /etc/passwd` —— 改的是**访问控制**,与改内容同等危险;
   既有红线只覆盖 chmod 777 / 全局开放写这类"放宽"形态,收紧与换属主完全没覆盖,提取器对
   chmod/chown/chgrp 返回空目标。现在把 FILE 操作数当写目标复用系统路径判定,同族的
   chflags/chattr/setfacl 一并纳入。
   解析上的坎:chmod 的符号模式与 chattr 的属性词可以 `-`/`+`/`=` 起头(`chmod -w f`、`chmod +x f`、
   `chattr +i f`),当成选项跳过会把**真实目标**误当规格操作数吃掉 → 先正面识别规格词;大小写敏感,
   `-R`(递归)不落进 `-[rwxXstugo]+` 仍按选项跳过。`--reference=RFILE` 从参考文件取模式 → 没有规格
   操作数,首个操作数就是目标;setfacl 的 ACL 由 -m/-x/-M/-X 给出,同样无规格操作数。

验证:双向语料 —— 20 条危险(tar 四种传统写法 + cwd 落 /etc 的传统解压、chmod 数字/符号/收紧/
--reference、chown/chgrp/chflags/chattr/setfacl 写系统路径、`chmod 600 /usr/bin/node`,以及与
-exec 递归、`cd /etc &&` 有效-cwd 的组合)全部必问,改前 **20 条全部只落灰区**;17 条良性
(区内解压与落地目录、`tar cf`/`tar tvf` 打包列出、`tar dist`、区内 chmod/chown、`chmod +x scripts/…`、
`chmod 755 /usr/local/bin/tool`、`rg "chmod 000" docs`)零误拦。均固化为回归测试。
maker-core 1409 单测 + typecheck 全绿。

Signed-off-by: zqchris <chrisz83@gmail.com>
Comment thread packages/maker-core/src/agents/shared/auto-review.ts
Comment thread packages/maker-core/src/agents/shared/auto-review.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/maker-core/src/agents/claude-code/auto-review-policy.ts:125

  • 这里把 WebSearch 的 query 原样作为 network.target 传给 core。core 的 internal/metadata 判定(isInternalFetchTarget)会把任意字符串当“类似 URL 的目标”来剥 scheme/端口/空白,因此像 localhost:3000 / 169.254.169.254 这类搜索词可能被误判为“内网/metadata 抓取”而直接升级到 prompt-each-time,与注释里“WebSearch 查询词仍走灰区”的语义不一致。建议:要么让 core 仅对 WebFetch 做 internal host 判定(按 operation 分支),要么在这里对 WebSearch 的 target 做不可被 URL 解析的包裹编码(例如 search:<query>),并同步更新对应单测。
  if (toolName === 'WebFetch' || toolName === 'WebSearch') {
    return {
      kind: 'network',
      operation: toolName,
      target: extractNetworkTarget(toolName, input),

apps/desktop/src/renderer/i18n/locales/zh-CN/common.json:4686

  • zh-CN 文案里“自动审批提权请求”与 en/ja/ko 的“自动 review/검토/レビュー 昇格请求”语义不一致;同时本 PR 新增的后半句已说明高风险可能被拒绝或要求确认,因此“自动审批”容易造成误解。建议改为“自动审核提权请求”以与其它语言及当前行为对齐。
            "description": "允许在工作区内读写,并自动审批提权请求;高风险操作可能被拒绝或要求确认。能减少打断,但存在误判风险。"

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

if (bin === 'sort' && /(?:^|\s)(?:-o\b|-o\S|--o[a-z-]*\b|--compress[a-z-]*\b)/.test(segment)) return false;

P1 Badge 将 sort 的输出文件纳入系统路径红线

当 Auto 执行 sort -o /etc/passwd /tmp/input 时,本机 sort --help 明确将 -o, --output=FILE 定义为把结果写入 FILE;这里虽然识别该选项并取消只读放行,却只返回模型可审查的 prompt,而 argumentWriteTargets 没有提取这个静态可见的输出目标,因此覆盖系统文件时仍可能被 reviewer 静默允许。请提取 -o FILE-oFILE--output=FILE 并复用受保护系统路径判定。

AGENTS.md reference: AGENTS.md:L69-L71

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/maker-core/src/agents/shared/auto-review.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@zqchris 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

zqchris added 2 commits August 2, 2026 06:08
main 上已并行落了同一份设计的 auto-review 核心(ed4dc8b「keep native-first fallback quiet」
+ pi 线的 6cfd122/cacd1cf0),与本支 53 个提交在同一批文件上语义冲突。解法按"谁在该维度是超集"
分文件定:

- **适配器(claude-code / codex / base-agent / maker-host / 三个适配器测试)取 main**:
  main 在**路由维度**是超集 —— 官方 Claude OAuth 保留 CC 原生 Auto classifier、第三方/网关与原生
  失效后才落 Cindy 兜底(usesNativeClaudeAutoReview),另有本支没有的热切换收口(审查期间
  setPermissionMode 收紧/放宽按最新档位决策)与 setModel 后的 auto 审查重配 best-effort。
- **确定性分类器(shared/auto-review.ts 及其测试)取本支**:main 版 759 行,本支 2488 行,含
  第十六~四十七批评审的全部加固(系统路径写红线、包装器/启动器解包、短选项簇与 tar 传统选项词、
  find -exec 递归、权限属主变更、云 metadata、伪设备白名单等),main 一项都没有。
  同时采纳 main 的结构化改动:凭证正则抽到 shared/sensitive-credential-paths.ts(改用
  SENSITIVE_CREDENTIAL_PATH_PATTERNS,已核对 10 条正则无丢失)、ReviewableAction.other 增
  description。
- **本支独有的「审查意图同步」族重新贴回 main 的适配器**:澄清答案并入意图(cc 本地 + cc 远端 +
  codex requestUserInput)、计划获批/修订 turn 携带"原始意图 + 获批计划"(cc 两处 + codex,含
  CODEX_AUTO_REVIEW_INTENT sendOptions 透传与计划请求时的意图快照)、Guardian 失效时同 turn
  立即 pushThreadSettings({approvalsReviewer:'user'})、exec 审查动作的 cwd 三态。

**一处刻意保留的档位分歧(需 Chris 拍板是否回退)**:`curl x | sh` / `| bash` / `eval`、区外
`rm -rf /tmp/x`、`find . -delete`(遍历根=工作区根)、`git push --force origin main`、写系统目录
在本支是确定性红线(prompt-each-time),在 main 是灰区(prompt,可被轻量 reviewer 静默 allow)。
本支这些红线是第十六批起多轮 bot 评审的直接产物(理由:静态可证的任意代码执行/区外破坏,
reviewer 看不到载荷内容,不能静默放行)。因此把 main 侧这些断言按本支档位更新;若要回退成
main 的"全交 reviewer",改动点集中在 highImpactExecutionNeedsConsent / scopedDestructionNeedsConsent
与对应测试。main 用系统路径当"灰区 fixture"的 wiring/dispatch 测试改用 /tmp/... 非系统路径,
保持原测试意图(灰区由 reviewer 裁决)。

验证:submodule 对齐 main 的 cindy-protocol ef3a90d2 + pnpm install(main 新增
@cindy/model-access-protocol workspace 包);maker-core 1507 单测全绿、typecheck 绿;
apps/desktop 定向 maker-host + maker-ipc 155 文件 2469 测试全绿、desktop typecheck 绿。

Signed-off-by: zqchris <chrisz83@gmail.com>
bot 报的:`rm -- /etc/passwd` 不带 `-rf`,原先只有出现 rRfF/--recursive/--force/--dir 才提取目标,
普通单文件删除完全取不到目标 → 只落灰区。删除本身就是写通道,现在把删除目标纳入写通道提取,复用
受保护系统路径判定;**区外批量破坏**仍由 destructiveRmTargets 的递归/强制条件负责,故 `rm -rf build`
这类区内删除档位不变。

覆盖 rm / unlink / shred / srm(shred 的 `-n` 次数、`-s` 字节、`--random-source` 是带值选项,不能
当删除目标)与 cmd.exe 的 del / erase(开关形如 `/f` `/s` `/q` `/a:-h`,Windows 路径不会以单个 `/`+
字母起头)。

自审顺带补的同族缺口:**mv 的源操作数同样被销毁** —— `mv /usr/bin/node /tmp/` 等于删掉系统程序,
原先只把末位目标当写目标。cp/install/ln/rsync 的源是只读的,不在此列。

验证:双向语料 —— 11 条危险(rm/unlink/shred 删系统文件、mv 搬走系统文件、`cd /etc && rm passwd`、
`find . -exec rm /etc/passwd`)全部必问,改前 **11 条全部只落灰区**;11 条良性(区内删除、`rm -rf build`、
`rm -- build/x`、`mv src/a.ts src/b.ts`、`mv build/x /usr/local/lib/`、`rm /tmp/scratch.txt`、
`rm >/dev/null`)零误拦。均固化为回归测试。maker-core 1534 单测 + typecheck 全绿。

Signed-off-by: zqchris <chrisz83@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

packages/maker-core/src/agents/claude-code/index.ts:2442

  • 计划获批后这里用 currentAutoReviewIntent 组装实施阶段的审查意图,但该值可能已在 plan_review 等待期间被后续消息覆盖;应改用进入 plan_review 分支时快照的 planRequestAutoReviewIntent,与本地 ExitPlanMode 分支的处理保持一致。
                setAutoReviewIntent(composeAutoReviewIntentWithApprovedPlan(
                  currentAutoReviewIntent,
                  decision.editedPlan ?? plan,

Comment thread packages/maker-core/src/agents/claude-code/index.ts
copilot 报:远端 plan_review 分支用的是 await 之后的 currentAutoReviewIntent。审批等待期间用户可以
继续发消息(send 会 setAutoReviewIntent 覆盖它),于是实施阶段的审查意图会丢掉原始请求、掺进审批期间
的内部跟进。改成进入分支时先快照,与本地 ExitPlanMode 分支的 planRequestAutoReviewIntent 同款。

这是我上一轮把"意图同步"族重新贴回 main 适配器时留下的不一致:本地分支带了快照,远端分支没带。

顺带把两个适配器里所有"await 后拼装意图"的点都过了一遍,确认剩下的锚点是对的:
- cc 本地 ExitPlanMode / codex runPlanReviewFlow:已有快照。
- 澄清(cc 本地 + cc 远端 + codex requestUserInput)**刻意仍用 await 后的当前意图** —— 这里不能快照:
  若审问期间用户发了新消息,新消息才是 agent 正在执行的请求,用快照会把它覆盖回旧意图,反而是回退。
  计划审批不同:计划是为原始请求起草的,实施 turn 实施的是那份计划。

maker-core 1534 单测 + typecheck 全绿。远端回调深在 session 闭包内,与前几轮同样未加针对性单测。

Signed-off-by: zqchris <chrisz83@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

Suppressed comments (3)

packages/maker-core/src/agents/claude-code/index.ts:2414

  • 远端 approval 回调里 ask_user_question 分支同样用 Object.entries(decision.answers) 生成澄清列表:这会把 header/id 等重复键或 resolver 返回的额外键并入 intent,且顺序不稳定,影响裁决缓存与安全边界。建议复用本次实际下发的 questions 列表(params/questions 或 input/questions)按顺序生成澄清,并按 (question→header) 回退取值,只合并“真的问过的问题”。
              setAutoReviewIntent(composeAutoReviewIntentWithClarification(
                currentAutoReviewIntent,
                Object.entries(decision.answers ?? {}).map(([question, answer]) => ({ question, answer })),
              ));

packages/maker-core/src/agents/codex/index.ts:4972

  • 这里把澄清问答并入 auto-review intent 时使用了 Object.entries(decision.answers)answers 的 key 允许是 question/header/id(types/events.ts 里有注明),直接遍历会带来:1) 顺序不稳定,影响同轮裁决缓存命中;2) 可能把 header/id 等重复键都写进 intent;3) 若 resolver 返回了额外键,会把未展示给用户的问题文本也并入 intent,扩大 prompt 注入/误导裁决的面。建议按原始 questions 顺序生成澄清列表,并用与 responseFromAskUserAnswers 一致的 key 回退规则取答案,从而只合并“本次真正问过的问题”。
        setAutoReviewIntent(composeAutoReviewIntentWithClarification(
          currentAutoReviewIntent,
          Object.entries(decision.answers ?? {}).map(([question, answer]) => ({ question, answer })),
        ));

packages/maker-core/src/agents/claude-code/index.ts:1498

  • 本地 AskUserQuestion 分支在把澄清问答并入 auto-review intent 时直接 Object.entries(decision.answers),会把 header/id 等重复键或 resolver 返回的额外键一并写入 intent,且顺序不稳定,可能影响裁决缓存命中,并扩大 prompt 注入/误导裁决的面。建议按本次实际展示的 questions 顺序生成澄清列表,并只从 decision.answers 中按 (question→header) 回退取值。

This issue also appears on line 2411 of the same file.

        setAutoReviewIntent(composeAutoReviewIntentWithClarification(
          currentAutoReviewIntent,
          Object.entries(decision.answers ?? {}).map(([question, answer]) => ({ question, answer })),
        ));

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6250cea372

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!cluster) continue;
if (cluster.consumedNext) i++;
if (cluster.letter !== 't') continue;
return cluster.value ? [cluster.value] : [UNPROVABLE_WRITE_TARGET];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 同时检查 mv -t 的源操作数

当使用 mv -t /tmp /etc/passwdmv --target-directory=/tmp /etc/passwd 时,这里命中目标目录后立即返回,只检查安全的 /tmp,跳过了同样会被移走的系统源文件;本机 mv --help 明确其第三种用法为 mv ... -t DIRECTORY SOURCE...,实测分类结果也从普通 mv /etc/passwd /tmp/prompt-each-time 降为可被 reviewer 静默允许的 prompt。与已覆盖的普通 SOURCE DEST 形态不同,新证据是 target-directory 分支的提前返回;请在 mv 情况下把源操作数与目标目录一起纳入系统路径检查。

AGENTS.md reference: AGENTS.md:L149-L150

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment on lines +4496 to +4500
...(params.cwd?.trim()
? { cwd: params.cwd }
: params.cwd === undefined
? { cwd: opts.workingDir }
: { cwdUnknown: true }),

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查通过(heavy tier,含安全扫描)。零 P0/P1,代码实现正确、测试覆盖充分。

唯一 P2:auto-review.ts:63 注释 typo 'copidot' → 'copilot',不阻断。

structural-check 未上报但 CI 全绿、review 通过,admin bypass 合入。

@MagicLizi

Copy link
Copy Markdown
Contributor

把 auto-review 从「宿主审批或什么都不审」升级到「宿主优先 + 当前模型静默兜底」,同时把系统路径写入从灰区提到逐次确认——既没砍掉 Guardian/canUseTool 的原生保护力,又补上了它们不在场时的安全网。测试覆盖也很扎实 🛡️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants