# Landing deviation — PR #267 landed as a MERGE COMMIT, not a fast-forward (doyle, 2026-09-24)

## What happened

I landed the W6 REQ seed (core PR #267) with `gh pr merge 267 --merge`. That produced merge
commit `437562d9`, whose parents are `07d04ba5` (previous main) and `09ac94fd` (the tested head).
ADR-0050's ff-only invariant is **tested sha == merged sha**, and it does not hold here:
CI run `36023567074` tested `09ac94fd`; main's tip is `437562d9`, a sha no run ever saw.

## Mechanism, measured

`gh api repos/BigscreenVR/spt-bs-core`: `allow_merge_commit=true`, `allow_squash_merge=true`,
`allow_rebase_merge=true`. With merge commits allowed, `--merge` **always** builds one — it never
degrades to a fast-forward. The earlier true-ff witnesses (PR #266, `mergeCommit.oid ==
headRefOid`) did not come from `--merge`.

For a single-commit lane whose parent already IS current main, `--rebase` is the verb that yields
sha identity: rebasing a commit onto its own parent rewrites nothing, so the merged sha equals the
tested sha and the `mergeCommit.oid == headRefOid` witness is available to assert afterwards.

`main` is **unprotected** (`/branches/main/protection` → 404 Branch not protected), so nothing
mechanical stopped this and nothing would stop a repair either. The guard is the verb, not the repo.

## Why this was NOT repaired by force-pushing main

- **Content risk is provably zero.** `git rev-parse origin/main^{tree}` equals
  `git rev-parse 09ac94fd^{tree}` — measured, identical. The merge commit carries exactly the tree
  CI tested; what differs is the sha, not a byte of content.
- **Two agents are mid-lane** (todlando on `feat/338-bundled-adapters-apply`, hertz reaping
  worktrees against main). Rewriting a shared branch they may have fetched, to repair a defect with
  measured-zero content risk, trades a real coordination hazard for a cosmetic one.
- The invariant's PURPOSE — no untested content on main — is satisfied by the tree equality. Its
  LETTER — tested sha == merged sha — is not, and that is what this record exists to say out loud
  rather than to quietly call equivalent.

## What a later reader must not conclude

This is not a precedent that merge commits on main are fine. It is one deviation with its content
risk measured and its repair cost measured, ruled on those two numbers. The next lane lands
`--rebase` and asserts `mergeCommit.oid == headRefOid` **before** calling it landed — the assertion
is what turns the verb choice into something a run can fail on rather than something a gater must
remember.

## Facts

- Tested sha: `09ac94fd`, run [36023567074](https://github.com/BigscreenVR/spt-bs-core/actions/runs/36023567074), conclusion success, classified docs-only (`unit`/`lint`/`docs-drift` skipped).
- Merge commit: `437562d9`, parents `07d04ba5` + `09ac94fd`.
- Tree: identical between `437562d9` and `09ac94fd`.
- main at time of writing: `437562d9`, unprotected.
