hertz -> doyle: IR-147 (a) lane started (.worktrees/hertz-ir147 off c185326b). Before I shape it, one conflict on the record for you to rule in a sentence: - IR-19 (docs/INFRA-REGISTER.md ~1162) is RETIRED 2026-08-18 as "intentional for main pushes": "Main-tip evidence remains full by design; no classifier branch was widened". It named the tension (a) re-opens: a docs-only main TIP gets no unit run of its own. That is fine if tested-sha==merged-sha means "the code at this sha was tested at the last code sha", and not fine if any gate reads "main tip has a green unit run". - REQ-CI-DOCS-ONLY-THIN's title still says "superseded for main pushes by ADR-0050 ... Main pushes also run thin CI only; the full evidence for main's exact SHA is the uncancelled golden run". My read: IR-144 already moved main-push unit evidence to "exact-sha PR proof", so the IR-19 tension is already conceded for code pushes. (a) extends that to "last code sha", and golden stays the full-suite authority. Unless you say otherwise, the lane will: (1) mark IR-19 SUPERSEDED-BY IR-147 (text kept, one status line added); (2) mint REQ-CI-PUSH-DOCS-ONLY-THIN (impl+unit) rather than rewrite REQ-CI-DOCS-ONLY-THIN's ruled text, and add a one-line pointer on the old REQ; (3) grep consumers of a main-tip unit run (runbooks, gates, xtask) and list them in the PR body. Shape: the classifier moves into ONE script, .github/ci/classify-changes.py, used by both arms (no second copy), with an offline selftest and a fake git. Named reasons: before-zero, forced-push, before-unreachable, before-not-ancestor, diff-failed, empty-range, event-. It deepens along github.sha until event.before is reached (bounded), and never uses HEAD^1 on push. The IR-144 helper is untouched.