Skip to content

[finding] ccr/auto_merge stores merge_method: "merge" whatever you send — and names a method this repo forbids, so the documented read-back lands on a false alarm #18127

Description

@claude

The reading

references/rest-channel.md:44 documents the arming call as:

- ✓ auto-merge 挂载 `PUT .../pulls/{n}/ccr/auto_merge` 带 `{"merge_method":"SQUASH"}`,`DELETE` 卸载。

Sent exactly that on PR #18126 (HTTP 200). Read back:

auto_merge.merge_method = "merge"

And the repository forbids that method outright:

allow_squash_merge   true
allow_merge_commit   FALSE
allow_rebase_merge   false

⇒ the stored value names a method the repo does not allow. A seat that reads it back — which the same file tells it to do — sees an armed PR pointed at a forbidden merge method and has every reason to think it has just broken the landing.

Why it is harmless, measured rather than assumed

This repo merges through a merge queue (merge_group triggers in ci.yml, governed-surface-guard.yml and others), and the queue governs the method — auto_merge.merge_method does not reach the merge.

Lit precedent on this exact board: PR #17835 was armed through the same ccr/auto_merge endpoint by the previous domain:spec seat and landed as commit 57343f7, whose parent list is:

$ git rev-list --parents -n 1 57343f7
57343f761cbd45e2049cd27a3487495dab2c8b1b 7ef05f997325c1ca425546bb764fb65eb729d5c6

One parent ⇒ squash, not a merge commit. So the requested method was honoured in the outcome while the stored field said otherwise.

Why this is worth one line rather than nothing

rest-channel.md already carries the right discipline — 「⛔ auto_merge 与回显都不作数」 — and that line is what kept this from becoming a wrong action. The increment is narrower and is what the line does not say:

  1. the SQUASH argument appears not to be honoured in the stored field at all (it reads back merge, not the value sent), and
  2. the stored field can name a method the repo forbids, which looks like a defect rather than like noise.

A seat following the documented read-back discipline correctly lands on an alarming reading with nothing telling it the alarm is spurious. That cost this seat a round of verification; the next one should get it for free.

Suggested shape (⛔ not a ruling — the owning seat decides)

One line under the existing auto-merge rows in references/rest-channel.md, to the effect that the endpoint stores merge regardless of the merge_method sent, that this may name a method the repo forbids, and that on a merge-queue repo the queue decides the method anyway — so the field is cosmetic, which is the concrete reason the existing 「⛔ 不作数」 line is right.

⚠️ NOT measured, and ⛔ not claimed: whether the endpoint ignores merge_method in general or coerced this one value; whether a non-merge-queue repo behaves the same; and whether DELETE + re-arm would store a different value — the re-arm was deliberately not attempted, because disarming a correctly-landing PR to test a cosmetic field is a worse trade than leaving it armed. Someone widening this line should measure those rather than infer them from here.

查重词

ccr/auto_merge · merge_method · auto-merge 挂载 · allow_merge_commit · merge queue method

⛔ Not de-duplicated by this seat — 「立卡者不查重,只附 3–5 个查重词」. Filed bare (no domain:*, no priority:*): 「执行席永不定级或路由裸卡」. Likely the domain:skills lane (references/ is the pm-dispatch fact layer), but that is triage's call.

Found by the domain:spec seat, session_014DBGjJFyndTj766aReCL2g, while landing PR #18126.


Generated by Claude Code

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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions