From 8b8bb1c3da27fb99fd43b92753d70c11412d29c6 Mon Sep 17 00:00:00 2001 From: Timothy Date: Wed, 26 Aug 2026 10:54:50 +0200 Subject: [PATCH] docs(708): record the live route-2 reproduction against PR #761 Pushed application code onto Renovate PR #761's branch and captured the review-verdict/h10 the gate posted: pending, with the classifier logging "authored by the 'renovate' bot account, but changes files outside the dependency-manifest set". Route 2 of #698 is refused on the live instance after PR #705; identity alone no longer exempts a head. Also records two things the issue got wrong or did not anticipate: the refusal reason surfaces only in the job log, never in the status description, and re-running the gate on the PR's ORIGINAL head tripped #751's page-2 "assume raced" rule, which is the live instance of #763 that issue predicts. Cold review found two defects in the first draft, both fixed here: the repair paragraph said "that head", which reads as the probe head when the repair in fact fired on the original head from the title edit five minutes earlier; and "every non-exempt head gets the generic description" was false, since the raced-repair sentinel is also a non-exempt description. PR #761 was restored to its recorded sha and verified byte-identical. fixes #708 Decisions-Edit: yes Co-Authored-By: Claude Opus 5 (1M context) --- .../records/ci/exemption-provenance.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/decisions/records/ci/exemption-provenance.md b/docs/decisions/records/ci/exemption-provenance.md index ba85d65bb..f51bf8b8b 100644 --- a/docs/decisions/records/ci/exemption-provenance.md +++ b/docs/decisions/records/ci/exemption-provenance.md @@ -90,5 +90,32 @@ a PR, because `pull_request_target` resolves this definition from `main` — the executed-behaviour tests in `scripts/tests/test_pr_changed_files.py`, each verified by mutation; the live re-check happens on `main` right after merge. +**Route 2 was reproduced live 2026-08-26 (#708), and it is REFUSED.** Application code was pushed onto +the branch of Renovate PR #761 (guarded first with a `WIP:` title prefix, confirmed `draft: true` / +`mergeable: false`, so the hijacked head could not merge), then the branch was force-restored to its +recorded sha and the PR verified byte-identical across title, head sha, base ref, draft, mergeable, +state, labels, body hash, author and milestone. With `AUTHOR: renovate` and a changed set of +`Directory.Packages.props` **and** `ErsatzTV.Core/Probe708.cs`, the classifier logged +`Decision: state=pending — authored by the 'renovate' bot account, but changes files outside the +dependency-manifest set`, and posted `review-verdict/h10=pending`. Before the manifest allow-list the +same head would have been `success` on identity alone. The classify step's start marker was present, +so this is a real classification and not the #751 silent no-op. + +**Where the refusal reason surfaces — the log, NOT the status description.** The route-2 explanation +lives in `reason`, which is only `echo`ed as `Decision: state=… — `. Of the three description +branches, two are distinctive — `Exempt: ` and the raced-repair sentinel `REPAIR_DESC` — and +every *other* non-exempt head falls to the generic `Awaiting review verdict for `. So a Route-2 +bot refusal and an ordinary awaiting-verdict head are indistinguishable from the status alone; +confirming *which branch* the classifier took means reading the job log. #708's own text expected the +reason in the description; it is not there. + +**Cost observed on the same PR, on its ORIGINAL head — not a defect in this record's mechanism.** +Re-running the gate on `8798a1d2` (the unmutated head, re-triggered by the `WIP:` title edit via +`types: [… edited]`, and five minutes *before* the code push) repaired its exemption to `pending` via +#751's conservative page-2 rule: that head's status history runs past `MAX_RESPONSE_ITEMS`, so *any* +page-2 rows are assumed raced. It could not have happened on the probe head — the page-2 check sits on +the `exempt=yes` path, which a Route-2 refusal never reaches. That is the blunt-instrument case `#763` +already predicts, now with a live instance of it; see that issue. + **Separate defect found reviewing this change:** `ci.grep-q-pipefail-inversion` — a pre-existing SIGPIPE inversion that let a large PR skip the `PROTECTED` guard entirely. Fixed in the same PR. -- 2.47.3