Repository navigation
Commit ad6826c
fix(pm): count the human-merge size rename-aware, as GitHub does (#30766)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9D5o77iBwVor2NbsinHdgN2C)_
domain:devx#1 · os-elon-musk · session_016WV4cy385N3ELe3hf8qLkd
Fixes #30718
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:`dispatch-gates` 和 `check-governed-merges`(`--branch` 与
sweep)统计改动行数时,改为识别重命名(`git --numstat -M`),与 GitHub 的 additions+deletions
一致;用来推导门禁的文件名列表仍保留 `--no-renames`,重命名仍同时列出新旧两条路径。
- **为什么改**:旧算法把移动文件算成整删加整增,搬文件多的 PR 被误报超过 3000 行人工审核线(#30594 读成
4324,GitHub 实为 1806),dev 因此去拆本不超线的工作。
- **风险与回滚**:只动 `scripts/pm/` 工具,不发布;尺寸只会比原来小、且等于 GitHub 的数;git
未配对的移动仍按整删整增算(只会偏大不会偏小)。回滚即 revert。
- **先看**:① `check-governed-merges.mjs` 的 `commitChanges`(sweep
现在两次本地读:路径 `--no-renames`,尺寸 `-M`);② `deriveBranchPaths` 的 numstat 一行;③
`dispatch-gates.mjs` 的 `changedLinesFromGit`。
- **两分钟验证**:`node scripts/pm/check-governed-merges.mjs --self-test`,预期
`✓ … 543 assertions`,其中含 #30718 重命名用例。
- **需要你做的**:无,席位落地。
## What changes
The human-merge size reading now counts renames the way GitHub does. The
threshold's authority is the PR's additions + deletions (pm-dispatch
SKILL.md), and GitHub pairs a moved file and counts only its content
change.
| Site | Before | After |
|:--|:--|:--|
| `dispatch-gates.mjs` `changedLinesFromGit` | `git diff --numstat
--no-renames MB` | `git diff --numstat -M MB` |
| `check-governed-merges.mjs` `--branch` (`deriveBranchPaths`) | `git
diff --numstat --no-renames MB REF` | `git diff --numstat -M MB REF` |
| `check-governed-merges.mjs` sweep (`commitChanges`) | one `diff-tree
--numstat --no-renames` for paths and size | the same call for paths,
plus a `diff-tree --numstat -M` for the size |
What stays: every `--name-only --no-renames` path list used for gate
derivation (`dispatch-gates.mjs` `changedPathsFromGit`,
`check-governed-merges.mjs` `--branch`), and the sweep's path list, keep
`--no-renames`, so a rename still reaches the predicate as both of its
paths. `-M` is spelled out, so a `diff.renames=false` config cannot turn
it off. A move git does not pair (an unstaged `mv` whose new path is
untracked, or a pair past git's rename limit) still counts as a delete
plus an add. That reads over GitHub's number, never under.
The header prose of `check-governed-merges.mjs` (the rename paragraph
and the per-mode "where the number comes from" table) and the
`changedLinesFromGit` doc comment now say this. The `--branch`
derivation line names `git diff --numstat -M`.
## Tests
- `check-governed-merges.mjs --self-test`: the injected-git fixtures
move from `diff --numstat --no-renames` to `diff --numstat -M`. A new
recording-git case pins that the `--branch` size read is `-M` and never
`--no-renames` while the path list keeps `--no-renames`. A new real-repo
fixture (with `diff.renames=false` set) moves a 400-line file with one
line edited. Its `--no-renames` control reads +400/−400 over 2 files.
`--branch` reads +1/−1 over 1 file and still lists both paths.
`commitChanges` reads the same +1/−1 and both paths.
- `dispatch-gates.self-test.mjs`: the same fixture shape drives
`changedLinesFromGit` (+1/−1 over 1 file), its `--no-renames` control,
and `changedPathsFromGit` (both paths listed, same rename-aware size).
<details><summary>Before/after on the card's three PRs (head d87643b;
before = origin/main 05a30e6)</summary>
Each PR head was checked out detached. Both `origin/main` and this
branch's modules were imported, then `changedLinesFromGit` and
`deriveBranchPaths` were run on the PR head's merge base, and
`commitChanges` on the landed squash commit.
| PR | Before (all three sites) | After (all three sites) | GitHub
additions+deletions / changed_files | Path list (before = after) |
|:--|:--|:--|:--|:--|
| #30594 | +3000/−1324 = 4324, 30 files, OVER | +1741/−65 = 1806, 24
files, under | +1741/−65 = 1806 / 24 | 30 |
| #30375 | +3382/−3185 = 6567, 61 files, OVER | +879/−682 = 1561, 60
files, under | +879/−682 = 1561 / 60 | 61 |
| #30550 | +723/−2505 = 3228, 65 files, OVER | +350/−2132 = 2482, 63
files, under | +350/−2132 = 2482 / 63 | 65 |
</details>
## Acceptance notes
- scripts/pm only, so nothing publishes: `skip-changeset`.
- `check-governed-merges.mjs --test` on the three changed paths: NOT
governed (ordinary queue landing). The size reading of this PR is 181
lines.
- No ablation: per os-dev.md, script changes are not ablated. Each new
fixture carries its own `--no-renames` control, which proves the fixture
is a real rename where the two reads differ.
## Verification
All local readings below are on the final head `dae76a1922` (the branch
merged `origin/main` `6b2129f918`; none of main's 177 files touch the
three scripts).
- `node scripts/pm/dispatch-gates.mjs --commands` derived 34 families.
All 34 exit 0. `node scripts/pm/dispatch-gates.mjs --ran` answers `✓
dispatch-gates --ran: 34 derived famil(ies) accounted for — 34 run, 0
NOT-MEASURED`.
- `node scripts/pm/check-governed-merges.mjs --self-test`: exit 0, `✓
check-governed-merges --self-test: 543 assertions` (also derived as
`pnpm check:pm-governed-merges`, exit 0 on `dae76a1922`).
- `node scripts/pm/dispatch-gates.mjs --self-test`: exit 0, `✓
dispatch-gates self-test: 2243 cases pass.` This ran on `d87643bf23`.
The merge after it changed none of the three scripts, so it was not
re-run on `dae76a1922`.
- CI families: these are read from this PR's check-runs, not re-run
locally.
<details><summary>Run record on dae76a1 (COMMAND :: exit N)</summary>
```text
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs --self-test :: exit 0
node scripts/check-self-test-wired.mjs :: exit 0
node scripts/check-self-test-wired.mjs --self-test :: exit 0
node scripts/check-self-test-workflow-commands.mjs :: exit 0
node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0
node scripts/check-skills-token-ratchet.mjs :: exit 0
node scripts/check-skills-token-ratchet.mjs --self-test :: exit 0
node scripts/check-whole-set-label-write.mjs :: exit 0
node scripts/check-whole-set-label-write.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0
pnpm check:agent-test-spelling :: exit 0
pnpm check:bash32-floor :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:cli-command-ids :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:declared-population-live :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:entry-guard :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:parse-guard :: exit 0
pnpm check:pm-dispatch-gates :: exit 0
pnpm check:pm-governed-merges :: exit 0
pnpm check:pnpm-filter-targets :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:ratchet-remedy-authority :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:scripts-symbol-anchors :: exit 0
pnpm check:watch-hint-literal :: exit 0
```
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_016WV4cy385N3ELe3hf8qLkd
---
_Generated by [Claude
Code](https://claude.ai/code/session_016WV4cy385N3ELe3hf8qLkd)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent b309866 commit ad6826c
3 files changed
Lines changed: 157 additions & 24 deletions
0 commit comments