Skip to content

A claim corrected during review still ships in history: the squash message is built from commit messages, which no review round reads #15913

Description

@os-warren

The gap

The Clause-② review loop reads, and corrects, the PR body and the changeset. It never reads the commit messages. This repository squash-merges, and its squash message is built from the concatenated commit messages — not from the PR body.

A false claim caught and corrected in review still lands in main's history, in the commit message, where nothing will correct it again.

Measured, with the control that makes it mean something

9e9f03abe — the landed squash of PR #15827:

$ git log -1 --format='%B' 9e9f03abe | grep -c '^\* '
4                                    <- four concatenated commit entries
$ git log -1 --format='%B' 9e9f03abe | grep -c 'Generated with'
0                                    <- the PR body's footer is ABSENT

Four * <subject> entries, each followed by that commit's full body — including a wip(...) subject. The PR-body footer that every PR in this repo carries is absent from the landed message, which is what proves the message is not body-derived.

⚠️ The single-commit case hides this. 6c439f2b4 (PR #15826) returns 0 for the same bullet scan and its message reads like clean prose, because with one commit GitHub uses that commit's own message. Reading only that sample gives the wrong answer — I made exactly that inference before checking a second one, and it was wrong.

The instance that prompted this

PR #15838 (card #15598). Its changeset claimed enforcement was "unchanged in both directions". Review measured that false on two inputs (an envelope, and a page with a non-object element: HEAD refuses, base granted — fail-closed and unreachable on the shipped engine, but the claim was unqualified). The changeset was corrected before landing.

The commit message 8da648334 still carries the original blanket claim. A later commit 4cc60aa7a qualifies it, so the landed squash will read as claim-then-correction rather than as a standing falsehood — which is why that PR was landed rather than held. But that outcome was luck of ordering, not a property of the process: had the correction been folded differently, or had the claim been in the only commit, the landed history would carry it uncorrected.

Why this is worth a card rather than a habit

Three PRs this session had a claim corrected during review (#15720's rider, #15787's cost sentence, #15838's enforcement claim). ⭐ In every one, the clause that was wrong was the clause no pin covered — which is the argument for reading prose, not just re-running tests. The review loop already does that for the two surfaces it knows about. The commit message is a third surface carrying the same kind of claim, on the artifact with the longest life, and no one reads it.

Not proposing a specific remedy — several are plausible and they trade off differently:

  • a landing-time squash-message edit (works, but manual and easy to forget, and it is the merge-queue that lands things here);
  • a gate that refuses a PR whose commit messages contain a claim the changeset contradicts (hard to specify — "contradicts" is not mechanically checkable);
  • a convention that the final commit's message is authored to stand alone, and reviewers read it (cheap, but relies on discipline);
  • configuring the squash message to come from the PR body instead (a repo setting, fixes it wholesale, but changes what every landed message looks like and needs a maintainer's call on whether the commit list is wanted).

The last one is a repository-settings decision, so this card is filed for a ruling rather than dispatched with a chosen fix.

Scope note

⚠️ This is not specific to domain:services — it affects every PR in the repo. Labelled domain:services only because that is the seat that measured it; retag freely.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions