The repo squash-merges, so the PR title -- not the commits inside the PR --
becomes the commit subject on main. Nothing validated it. commitlint
(ci.yml:429) lints a PR's commits and therefore cannot catch this by
construction: a PR with clean conventional commits and a prose title passes CI
and then lands a prose subject on main.
That is how 31452426 landed:
Unify savings attribution across stats, perf, metrics, and dashboard (#2976)
release-please cannot parse it -- `unexpected token ' ' at 1:6`, because
`Unify` is five characters and position six is a space where the parser needs
`(`, `!` or `:`. The change is silently dropped from the changelog.
The check lives in pr-governance.py rather than ci.yml for two reasons: ci.yml's
pull_request trigger has no `edited` type, so a corrected title would never be
re-checked, and its paths-ignore skips docs-only PRs, which still squash-merge a
subject onto main. pr-health.yml already triggers on `edited` and reports through
the same governance comment the author is reading anyway.
Bot PRs keep their existing exemption; dependabot and release-please titles are
already conventional.
Validated against all 117 PRs opened in the last week: exactly one is flagged,
#2976 -- the one that jammed the release. No false positives.
The type vocabulary is asserted equal to .commitlintrc.json's type-enum, so the
two gates cannot drift apart.
The _event test helper gained the `title` field that a real pull_request
payload always carries; without it every existing case was exercising an
impossible shape.