enhance(#2554): resolve code review depth from path-scoped override rules (#3695)

* test(#2554): failing-first suite for path-scoped code review depth overrides

Binds the not-yet-built code-review-depth module: segment-aware path-prefix
matching of a changed-file set against ordered {paths,depth} rules, resolution
order flag > strongest matching rule > global > standard, typed validation
errors, and the large-scope downgrade boundary. Also proves behaviorally that
workflow.code_review_depth_overrides is not yet a registered config key.

Refs #2554

* feat(#2554): resolve code review depth from path-scoped override rules

Adds workflow.code_review_depth_overrides — an ordered array of {paths, depth}
rules matched against a review's changed-file set by segment-aware path-prefix
comparison. Resolution order is --depth= flag, then the strongest matching rule,
then workflow.code_review_depth, then standard; a matching rule replaces the
global rather than being max'd with it, so quick and standard rules stay
meaningful. Glob metacharacters are a hard configuration error rather than sugar
for a prefix, and malformed rules halt the review instead of degrading to
standard. The resolver is pure and reports its own provenance, so the workflow
can print the resolved depth and the rule that matched. The pre-existing
>50-file deep-to-standard downgrade moves into the module and now names the rule
it overrode.

The key is registered centrally rather than as a capability config slice: the
federated slice channel admits only boolean/string/number/enum, so an array
slice would be dropped as malformed.

Closes #2554

* test(#2554): correct depth-provenance assertions and pin out-of-repo paths

Two corrections to the failing-first suite. The source assertion for a
non-matching rule with no global configured expected 'config'; with no global
set the depth comes from the default, and a companion assertion tolerated
either value, so both passed against an implementation that derived provenance
from whether any rules existed rather than from where the depth came from.

The out-of-repo absolute-path case used a home-directory path that matched
neither implementation, so it never exercised the defect it named. It now pins
the discriminating cases: an absolute path outside the repo root must not match
a repo-relative rule, and one under the root must.

* docs(#2554): document path-scoped code review depth overrides

Reference rows for workflow.code_review_depth_overrides in the configuration,
features and commands references plus the locale copies that carry those tables,
and in the planning-config reference. Explanation of why escalation is
whole-review rather than per-file and why v1 is prefix-only. New how-to for
scoping review depth by path, carrying the configuration-error reason table and
the distinction between nothing to report and could not look. CONTEXT.md
glossary entry and the INVENTORY row for the new CLI module.

ja-JP and ko-KR CONFIGURATION.md carry no code_review keys at all, and ko-KR and
pt-BR FEATURES.md carry no code-review config table, so those files are
deliberately untouched.

* fix(#2554): make the depth-misconfiguration halt executable and reject control chars

Three review findings, all in this change.

The misconfiguration halt was prose rather than shell: the error-printing fence
was followed by an unconditional extraction fence, so an ok:false result threw
and left the depth empty instead of stopping the review. Prose is not a guard —
the two fences are now one block with a real conditional, and anything that is
not the literal string true fails closed.

An interior control character in a rule path survived validation and reached the
provenance string and the summary box; rule paths now reject control characters
via a new PATH_CONTROL_CHAR reason, after the glob check so precedence is
unchanged. That in turn makes the field record safe to delimit, so the seven
node invocations that each re-parsed the same result to read one field collapse
to one.

Also corrects the glossary entry's illustrative paths, which the glossary-ref
check read as real repository references.

* fix(#2554): use the fast-check v4 string API and acknowledge workflow growth

Two failures from the remote matrix on d3111f45, both this branch's.

The property block built its segment arbitrary with fc.stringOf, removed in
fast-check v4. Because the arbitrary is constructed in the describe body, the
throw took out all four property tests rather than one — they had never
executed. Rewritten to fc.string({unit, ...}), the form this repo already uses
in emitted-attribution.test.cjs. Every other fast-check helper in the file was
audited against the installed module.

The emitted-attribution growth arm needed an acknowledgment for code-review.md,
which grew 5376 bytes. The pre-existing 3503 fragment keying the same file is
spent — its ripple was absorbed when #3503 merged, and the base file is exactly
the 34435-byte baseline this growth is measured against — so it cannot clear
anything, while the ack lint hard-fails on a duplicate key across two sources.
Removed it in favor of the new fragment, which is exactly how #3503 itself
replaced the spent 3191 fragment.

* docs(#2554): backfill changeset PR number

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-08-19 22:45:35 -04:00
committed by GitHub
parent 71e00d426e
commit 2fca0e17e4
27 changed files with 1629 additions and 46 deletions

View File

@@ -1163,7 +1163,7 @@ node gsd-tools.cjs intel api-surface # 渲染 api-map.json → API-
| 参数 | 必填 | 描述 |
|----------|----------|-------------|
| `N` | **是** | 要审查的阶段编号(例如 `2` 或 `02`) |
| `--depth=quick\|standard\|deep` | 否 | 审查深度级别(覆盖 `workflow.code_review_depth` 配置)。`quick`:仅模式匹配(约 2 分钟)。`standard`:按文件分析,含特定语言检查(约 5-15 分钟,默认)。`deep`:跨文件分析,包括导入图和调用链(约 15-30 分钟) |
| `--depth=quick\|standard\|deep` | 否 | 审查深度级别。同时覆盖 `workflow.code_review_depth` 和任何匹配的 `workflow.code_review_depth_overrides` 路径规则——该标志始终优先。`quick`:仅模式匹配(约 2 分钟)。`standard`:按文件分析,含特定语言检查(约 5-15 分钟,默认)。`deep`:跨文件分析,包括导入图和调用链(约 15-30 分钟) |
| `--files file1,file2,...` | 否 | 显式逗号分隔的文件列表;完全跳过 SUMMARY/git 范围界定 |
| `--fix` | 否 | 审查后自动修复问题 — 读取 REVIEW.md,生成修复代理,原子性地提交每个修复 |
| `--fix --all` | 否 | 将 Info 级别的发现纳入修复范围(默认:仅 Critical + Warning) |

View File

@@ -47,6 +47,7 @@ GSD 将项目设置存储在 `.planning/config.json` 中。该文件在 `/gsd-ne
"use_worktrees": true,
"code_review": true,
"code_review_depth": "standard",
"code_review_depth_overrides": [],
"plan_bounce": false,
"plan_bounce_script": null,
"plan_bounce_passes": 2,
@@ -248,6 +249,7 @@ API 密钥字段接受字符串值(密钥本身)。也可以设置为哨兵
| `workflow.worktree_skip_hooks` | boolean | `false` | 为 `true` 时,worktree 模式下的执行器 agent 传递 `--no-verify`(跳过提交前钩子),波次后的钩子验证改为针对合并结果运行。适用于钩子无法在 agent worktree 中运行的项目的可选逃生舱口。默认 `false` 对每次提交运行钩子(#2924)。 |
| `workflow.code_review` | boolean | `true` | 启用 `/gsd-code-review` 和 `/gsd-code-review --fix` 命令。为 `false` 时,命令以配置门禁消息退出。v1.34 新增 |
| `workflow.code_review_depth` | string | `standard` | `/gsd-code-review` 的默认审查深度:`quick`(仅模式匹配)、`standard`(按文件分析)或 `deep`(带导入图的跨文件)。可通过 `--depth=` 按次运行覆盖。v1.34 新增 |
| `workflow.code_review_depth_overrides` | array | `[]` | 有序的 `{ paths: string[], depth }` 规则列表,按目录前缀匹配对特定目录提升 `/gsd-code-review` 的审查深度,例如 `[{ "paths": ["src/auth"], "depth": "deep" }]`。每条规则的 `paths` 按整段目录路径前缀与本次审查的变更文件集合匹配(`src/auth` 匹配 `src/auth/token.ts`,但绝不匹配 `src/authfoo/x.ts` 或 `docs/src/auth/x.ts`);匹配区分大小写,与 git 一致。glob 语法(`*`、`?`)是配置错误,而非前缀的简写形式。一个匹配的文件会将整次审查提升到该深度——深度并非逐文件应用。解析顺序:`--depth=` 标志 → 匹配到的最强规则 → `workflow.code_review_depth` → `standard`;即使规则的档位比全局默认值弱,匹配到的规则依然生效。格式错误的规则(`depth` 无效、glob 语法、绝对路径、`..` 段、路径为空、`overrides` 非数组、规则非对象、`paths` 格式错误)是配置错误,审查会中止,而不会静默回退。解析出的深度及匹配的规则会打印在审查输出中。#2554 新增 |
| `workflow.plan_bounce` | boolean | `false` | 针对生成的计划运行外部验证脚本。启用后,计划阶段编排器将每个 PLAN.md 通过 `plan_bounce_script` 指定的脚本管道处理,并在非零退出时阻塞。v1.36 新增 |
| `workflow.plan_bounce_script` | string | (无) | 用于计划反弹验证的外部脚本路径。接收 PLAN.md 路径作为第一个参数。当 `plan_bounce` 为 `true` 时必需。v1.36 新增 |
| `workflow.plan_bounce_passes` | number | `2` | 顺序执行的反弹轮数。每轮将上一轮的输出反馈给验证器。较高的值提升严格性,但会增加延迟。v1.36 新增 |

View File

@@ -2135,6 +2135,15 @@ PreToolUse 钩子,检测 Claude 在 GSD 工作流上下文之外尝试文件
|---------|------|---------|-------------|
| `workflow.code_review` | boolean | `true` | 启用代码审查命令 |
| `workflow.code_review_depth` | string | `standard` | 默认审查深度:`quick`、`standard` 或 `deep` |
| `workflow.code_review_depth_overrides` | array | `[]` | 按目录路径前缀匹配变更文件集合、为特定目录提升审查深度的有序 `{ paths, depth }` 规则列表(#2554)。详见下文。 |
**按路径限定代码审查深度**
`workflow.code_review_depth_overrides` 通过整段目录路径前缀,将规则与本次审查的变更文件集合进行匹配 —— `src/auth` 匹配 `src/auth/token.ts` 及 `src/auth` 本身,但绝不匹配 `src/authfoo/x.ts` 或 `docs/src/auth/x.ts`。匹配区分大小写,与 git 保持一致。
升级是**针对整次审查,而非逐文件**的:深度是传递给审查代理的单一标量值,而非逐文件设置,因此规则集中匹配到的最强档位适用于本次审查中的每一个文件 —— 一个敏感文件不会因为与无关文件同处一次审查中而被浅层审查。
v1 **仅支持目录前缀匹配,不支持 glob 语法**:本项目中不存在 glob 引擎(`minimatch`、`picomatch`、`fast-glob`),本功能也未引入。路径中包含 `*` 或 `?`(例如 `src/auth/**`)会被视为配置错误,而不是悄悄地按前缀近似处理。
---