Skip to content

check-pr-size and check-commit-trailers abort on every fork PR, so CI never validates an outside contributor's trailers #773

Description

@localai-bot

What

Both checkers require the base SHA to be an ancestor of head:

  • scripts/check-pr-size.py:546require_ancestor()raise ValueError("base must be an ancestor of head")
  • scripts/check-commit-trailers.py:281raise ValueError("range base must be an ancestor of range head")

CI passes github.event.pull_request.base.sha, which is the tip of the base branch. That stops being an ancestor of head the moment main moves after the branch was cut — which on this repo is constantly.

Measured on three open PRs:

PR base is ancestor of head? merge-base exists?
#506 NO yes — e1087a881
#523 NO yes — fdd452637
#559 NO yes — fafa16f0f

A merge base exists every time.

Consequence, and it is worse than a red check

agent-record runs the trailer checker over the PR range. When the range cannot be computed the checker aborts before validating anything, and the job fails with an ancestry message. So:

CI has never actually validated commit trailers on an external contribution. The check that is supposed to enforce the FOLLOWING_AGENTS_PROTOCOL / Assisted-by: contract exits before it looks at a single commit. On the external PRs reviewed this week, hand-checking by a reviewer was the only verification those trailers received.

The same abort hits pr-size, so path classification and the checker-evidence contract also go unenforced on fork PRs.

Contributors meanwhile see two permanently red checks that carry no information, which is how a gate teaches people to ignore it.

Fix

Diff from the merge base, which is what a pull request actually is and what GitHub itself shows (three-dot diff):

git diff base...head      # equivalently: git diff $(git merge-base base head) head

Two-dot diffing against a moved main is not merely stricter — it is wrong: it renders main's own commits as reversions inside the contributor's diff, so paths the contributor never touched get classified and counted against them.

Both checkers should compute git merge-base base head and use it as the range base. Where no merge base exists at all (genuinely unrelated histories) they should still fail closed — absence of information must not look like absence of work.

Per AGENTS.md this is a checker-semantics change: spec, red-before test, green-after evidence.

Found while reviewing the external-contributor backlog; hit live while pushing to a contributor's fork, where the trailer checker refused the range and I had to verify the trailers by hand from the merge base.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions