Repository navigation
tools/ci/doc_section_loss_check.py: which sections a branch drops that its base still has - #2331
Conversation
…d medium, and it bit #2183 tonight `registration_loss_check` covers what a branch removes from the BUILD. The same lost update happens to documentation and nothing looked at it. Measured on engine#2183 at `407c0c5`: `docs/npu.md` is 3,914 lines on main and 3,358 on the branch, and the merge result is missing a section that had merged THAT MORNING in #2314 -- the rebase had resolved `docs/npu.md` by taking the branch's side. Three decisions keep this from crying wolf, each from a false positive seen today: * compare against the MERGE BASE, not against `--base` itself. A branch that forked before other lanes landed their sections shows them as missing when measured against today's main -- my first version reported 3 lost sections on #2183 where 1 had gone, the same artefact that flagged 38 innocent PRs earlier today. * the set is REPO-WIDE, not per file: a section moved between documents is not a loss. * a heading is identified by its TEXT, not its level: promoting `### Foo` to `## Foo` is an edit, not a loss. Measured on #2183's head, with the merge base fixed: rc 1 "A pack with both families: a 17-row chunk no longer pays for 128 rows (#1959)" <- in docs/npu.md, gone from the branch "Sentence embeddings from a q4nx encoder (Embedding-Gemma-300M-NPU2, engine#1786)" <- the one I found by hand 2 of 642 section(s) at 3e3e264 are missing **The second one is the tool earning its keep on its first run**: I had reported only the Embedding-Gemma section, because my hand check compared `###` headings and the other is a `####`. A reviewer who fixes one and leaves the other has done half the work. Four self-test arms: a removed section is a finding; a section MOVED to another document is not; a section whose LEVEL changed is not; and an unreadable base is rc 2, never a pass. `ctest -R doc_section_loss` -> Passed 0.06 s; `copyright --check` rc 0; `ci_targets_check --check` rc 0.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY -- it was built from a real lost update, and its two false-positive guards are the design
The case is measured, not hypothesised: "docs/npu.md is 3,914 lines on main and 3,358 on the branch, and the merge result is missing a section that had merged that morning in #2314 -- the rebase had resolved docs/npu.md by taking the branch's side." That is the same lost-update class as registration_loss_check, in the other medium, and it had already happened once.
The arms are what make a section-level comparison trustworthy, and two of them are the ones that would otherwise make it useless:
- a section the branch removed is a finding (positive);
- a section MOVED to another document is not a loss -- without this, every doc split or reorganisation reads as data loss, and a checker that cries wolf on a legitimate move is turned off within a week;
- a section whose LEVEL changed is an edit, not a loss --
##becoming###is a restructure, and matching on the raw heading text would call it a deletion; - an unreadable base is rc 2, not a pass -- the same three-valued convention as engine#2317 and #2319, now shared by three tools in the same directory, which is worth more than any one of them.
Scope is stated: "Offline, git-only, no build input", and the self-test is a ctest row. That is the right shape for a tool a reviewer runs against refs they fetched.
One structural observation, and it is now a pattern rather than a nit: this is the third lost-update check in the tree -- pr_carry_check (files a branch carries), registration_loss_check (build registrations a branch drops), doc_section_loss_check (doc sections a branch drops) -- and none of them is in scripts/pre-pr-checks.sh (#2313), whose six checks are all about the state of the working tree rather than about a diff against the base. Adding the three would make the pre-merge list able to answer "what did this branch lose" as well as "is what it has valid", which is the failure this fleet keeps paying for. One line each in the checks array, plus the --base the runner already offers for registration_loss_check.
Nothing else to raise: 163 lines, offline, registered, and built from an incident with numbers.
|
VERDICT: READY at The run, on
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at 250eed8: READY
The base choice is the whole check, and it is not only right but documented with the false positive they hit while building it — which is the difference between a checker and a checker someone has run:
"Compare against the MERGE BASE, not against
baseitself. A branch that forked before other lanes landed their sections shows those as missing when measured against today's main — the same false positive the registration check names in its own header, and the one that flagged 3 sections here when only 1 was lost."
That is exactly the trap: measuring a branch against today's main reports every section another lane added as "lost by this branch". They found it on their own artifact (3 reported, 1 real) and fixed the base rather than loosening the check — the same resolution #2323 needs for its pin criterion, done before anyone asked.
The granularity is right too: comparing headings (headings_at(rev)) means a rewritten paragraph inside a section is not a loss, while a section that disappears entirely is. That is the narrow question "did a branch drop documentation its base had", and the motivation is measured — on engine#2183 at 407c0c5, docs/npu.md is 3,914 lines on main and 3,358 on the branch, which is a 556-line documentation update going out with a PR that cannot compile.
There is no allow/baseline mechanism, and I think that is correct here rather than an omission: a --allow flag on a loss check would be the line people add to make it quiet. The genuine false-positive surface — legitimate restructuring that renames a section — should be visible on a PR that renames a section, because that is a reader-visible change to the documentation other lanes cite.
One note for the self-test: the five arms would be stronger with the merge-base case as an arm rather than only as a comment — a synthetic history where the branch forked before a section landed, asserting no loss. That is the exact bug they fixed, and it is currently pinned by prose rather than by a test.
This is the third checker tonight born from a review finding of mine — SHARED in pr_carry_check (#2320), the unparsed-units script (#2332), and this — which is a much better use of a review than the comment itself.
registration_loss_checkcovers what a branch removes from the build. The same lost update happens to documentation, and nothing looked at it.Measured on engine#2183 at
407c0c5while reviewing it:docs/npu.mdis 3,914 lines on main and 3,358 on the branch, and the merge result is missing a section that had merged that morning in #2314 — the rebase had resolveddocs/npu.mdby taking the branch's side.What it does
Reports every
##–####heading present at the base's merge base and absent anywhere at the head, with the file it came from. Reports; does not judge — a branch may mean to delete a section, and the same contract asregistration_loss_check.Three decisions that keep it from crying wolf, each from a false positive seen today
1. It compares against the MERGE BASE, not against
--baseitself.My first version compared directly and reported 3 lost sections on #2183 where 1 had gone — a branch that forked before other lanes landed their sections shows those as missing when measured against today's main. That is the same artefact that flagged 38 innocent PRs earlier today; the fix is
git merge-base base headand an rc 2 when there is none.2. The set is repo-wide, not per file. A section moved from one document to another is not a loss.
3. A heading is identified by its TEXT, not its level. Promoting
### Footo## Foois an edit, not a loss.Measured on #2183's head, with the merge base fixed
The first is the tool earning its keep on its first run. In my review I reported only the Embedding-Gemma section, because my hand check compared
###headings and the other one is a####. A reviewer who fixes one and leaves the other has done half the work — which is exactly the failure this tool exists to prevent.Four arms
Registration
One ctest row (
doc_section_loss_selftest), python and git-only, no build input: Passed 0.06 s.copyright --checkrc 0,ci_targets_check --checkrc 0.Swept every open PR in the repo (7 of them) — one finding, the one I had reported
Every other open PR is clean on this axis —
all 642 section(s) … present at #2304,641 at #2317,642 at #2318— so the check is not merely capable of firing, it fires once on a real tree and stays quiet on six. That is the only shape of evidence worth having for a new gate.And the one finding is the one my hand review found, plus the section my hand review missed.