Search for compliance checks in pull requests and most of what you find is about GitHub's required status checks: making sure the test suite and the linter went green before a merge. That is a real and useful thing, but it is not what this page is about. A compliance check is a different question asked of the same pull request: does this change touch a control your company is audited on, in SOC 2, ISO 27001, the GDPR, or another framework you are bound to.
That question rarely has an owner in code review. Correctness and security each have well-understood checks; whether a change moved a control you are audited on is a separate reading, and it is the one a compliance check on the pull request adds. It is worth being precise about what that check is and is not.
What it is, and what it is not
A compliance check reads the diff, not the test results. It maps the actual change to the specific control it affects and reports that control by name, at a grain you can verify. It is not a pass or fail on your test suite, not a coverage threshold, and not a policy document an auditor samples once a year. It is a per-change reading of whether the pull request in front of you moved something you are obligated to keep.
The output that makes it useful is the citation. "This looks non-compliant" is noise. "This removes the audit log for a privileged action, which ISO 27001:2022 A.8.15 expects you to keep" is something an engineer can act on or argue with. A compliance check that cannot name the control is not worth adding.
Three control-relevant changes that hide in routine pull requests
A widened access path. A pull request broadens an IAM role or opens a new route to a resource. The code is correct and may be perfectly safe, but it enlarges who can reach protected data, which is exactly what SOC 2 CC6.1 (logical access controls) is about. It can read as a routine config change while the control it moves goes unnamed.
A weakened audit log. A cleanup removes or trims a log line that happened to be the record of a privileged action. Nothing breaks, and it can read as a harmless cleanup, but the evidence an auditor samples under ISO 27001:2022 A.8.15 (logging) is now gone. The change that caused it is the cheapest possible place to catch it.
A new store of personal data with no bound. A migration adds a table that starts collecting personal data with no retention limit. It is clean, working code, and it quietly puts you on the wrong side of GDPR Art. 5(1)(e) (storage limitation), which requires personal data to be kept no longer than necessary. None of these three is a bug or a vulnerability. Each is a control-relevant change hiding in a routine pull request.
Advisory by default, blocking only if you choose
A compliance check that blocks every merge on any finding trains people to click past it; one that never blocks anything gets ignored. The useful default is advisory: the check posts the control and the clause as a comment and a neutral status, so the finding is visible without interrupting the merge. The decision to gate belongs to your branch-protection policy, not to the tool.
If a missed control is genuinely costly, anything touching access control, cryptography, or personal data, you can require the check through branch protection on the repositories or protected branches where it matters most, and leave it advisory everywhere else. The mechanism should let you choose the posture rather than force one on everything.
How to add one
A compliance check runs on the pull request the way your other checks do: it triggers when a PR is opened or updated, reads the diff against the frameworks you have selected and your company context, and posts the controls a change touches with the clause attached. The hard part is not noticing that something changed; it is naming exactly which control it changed, correctly, which is why the frameworks you are bound to and your own context have to feed the check.
heygrc is built to be that check as a GitHub App: install it, tell it your frameworks and context once, and it reviews each pull request for compliance impact, posting a neutral Checks status plus inline comments so it informs rather than blocks unless you decide to require it. The setup walkthrough covers the three-minute onboarding.