# Agent Note: 显式报告仓库变更范围

Status: implemented

[English](2026-07-27-explicit-change-scope-report.md) | 中文

## 问题

[pre-push 工作流](../../../skills/dsh-pre-push-checks/SKILL.md)需要取得相对于实际基准的 diff，但按 `origin/<current-branch>` 构造引用存在两类问题：对于第一次推送前跟踪 `origin/master`、尚无同名远端分支的新 worktree 分支，该引用无法解析；对于 PR（Pull Request）以另一功能分支为基准的堆叠分支，该引用会错误描述基准。[代码评审](../../../skills/dsh-code-review/SKILL.md)与[文档审计](../../../skills/dsh-doc/SKILL.md)工作流同样需要判断当前基准。

错误的范围可能遗漏受影响的路径，从而削弱证据选择。三点范围产生的已提交 diff 也完全无法说明 Git 中彼此独立的已暂存、未暂存与未跟踪层。

## 决策

根目录的 `change-scope` 命令要求提供 `--base <ref>`，接受可选的 `--head <ref>`（默认为 `HEAD`），并写出一份带版本号的 JSON 报告。该命令会检测歧义，将两个输入解析为 commit，并要求二者恰好有一个合并基点，之后才会呈现报告。报告记录仓库根目录（不对路径中的合法空白字符作规范化处理）、输入引用、解析后的基准、头部与合并基点 commit ID，以及排序后的已提交、已暂存、未暂存和未跟踪路径集合。路径记录先按原始 NUL 字节切分；仓库根目录和每条路径都以严格 UTF-8 解码。遇到无效值时，报告会中止，不会用替换字符代替无效字节或把不同值合并为一条。

已提交路径由解析后的合并基点与头部之间的比较得出。即使 `--head` 指定其他 commit，各类未提交路径集合仍始终描述当前 worktree 与索引。每次 Git 探测都会禁用配置的文件系统监视器和可选加锁；diff 配置不能隐藏子模块，也不能调用外部 diff 或文本转换驱动；系统禁用重命名检测，因此重命名前后的路径都会保留在结果中。

该命令从不猜测或获取基准，不查询代码托管提供方，也不选择测试。调用该命令的每个工作流都会验证当前远端或堆叠状态、显式提供基准，并将这份事实报告作为语义评审或证据选择的输入。

聚焦的临时仓库测试覆盖显式引用与堆叠引用、所有未提交改动层、合法路径空白、严格路径解码、无副作用的探测、无效引用、确定性 schema，以及报告前后不变的引用、索引、配置与状态。

## 考虑过的替代方案

**继续使用临时拼装的 diff 命令，辅以文字化回退说明。** 这种方式无需添加仓库脚本，但不同工作流对常见的新 worktree 与堆叠基准拓扑仍会作出不一致处理，而且无法涵盖未提交改动层。

**根据配置的上游推断基准。** 第一次推送前，上游可能是 `origin/master`；推送后，它可能是同一功能分支；也可能是一个头部分支，而其 PR 以另一功能分支为基准。没有一种推断能够适用于所有拓扑。

**在命令内查询 GitHub 以确定基准。** 这会把本地只读报告绑定到单一代码托管平台与网络凭证，却仍然无法解析尚无 PR 的分支。

**根据变更路径生成必需的测试。** 变更路径无法揭示经由配置、动态加载、子进程、worker、构建产物或提供方触达的行为。pre-push 工作流仍须通过判断来选择证据。

**报告当前分支与上游，并维护并行的人类可读渲染器。** 调用方在调用前已经验证分支和基准状态，没有消费方使用这些字段，而格式化文字只会重复 JSON schema，并不能提高路径完整性。

## 后果

显式输入仍可能指定错误的基准，但这种错误是可见的：报告中会显示输入引用与解析出的三个 commit ID。调用方需要付出少量成本，在运行该命令前验证实时基准并从远端获取它。

字符串 schema 有意不表示非 UTF-8 路径字节。含有这类路径的仓库必须先重命名这些路径才能生成报告，以此保持范围精确，而非返回有损结果。

仓库需要维护一个 Git 拓扑辅助工具及相应的聚焦测试。由此，pre-push 证据选择、代码评审与文档审计可以共享一份关于已提交变更和本地变更的确定性只读说明，而不必混入代码托管平台或策略职责。
