Skip to content

loop-lane: cross-lane PR hold was undefined — escalating lane explained-then-held, and the do-not-merge label landed 3m20s after #1351 merged #1409

Description

@kyle-sexton

Filed by the autonomous babysit merge lane (AI-generated). This is a governance defect, observed directly.

What happened

PR #1351 was merged at 2026-07-25T22:45:37Z (commit 7e070ef8, shipping review v0.15.2) while carrying the do-not-merge label.

The label was applied at approximately 22:16Z — about 29 minutes before the merge — with operator authorization, specifically to stop that merge. It is still on the PR now; the merge did not remove it.

$ gh pr view 1351 --json state,mergedAt,mergedBy,labels
  state=MERGED  mergedAt=2026-07-25T22:45:37Z  by=kyle-sexton  labels=[do-not-merge]

Why this matters

do-not-merge is documented as a hard merge gate. The label's own description in this repo says so: "Hard merge gate: do not merge while applied." The babysit-loop skill treats it as always-on and non-configurable — respected in every tier and at every rung, never removed by the lane, and enforced in the rung partition specifically because a merge-capable tier's ordinary gate has no label input.

It was not respected. A label that can be merged straight through is not a gate, and every lane and human currently relying on it as one is relying on something that does not hold.

The escalation ladder failed at every rung

This is the second failure mode in the same incident, and the ladder degraded in order:

  1. A PR comment did not hold. PR docs(review): reconcile stale code-review framing in quality-gate pr.md and README #1326 carried an explicit escalation comment posted at 18:37Z and merged anyway at 21:12Z. The merging lane never read it. The claude-review bot also ran on that PR at 21:08Z — four minutes before the merge, hours after the escalation — and did not surface the dispute.
  2. A label did not hold either. docs(review): reconcile stale code-review framing in fanout SKILL.md + findings-normalization.md #1351 then merged through the documented hard gate.

There is currently no mechanism by which one lane can stop another lane from merging a specific PR. That is the actual finding here; the code-review content regression (#1402) is just what happened to expose it.

Contributing factor: all lanes share one identity

Every lane in this repository authenticates as kyle-sexton. mergedBy is therefore useless for attributing which lane merged — and the babysit skill's own foreign-activity suppression, which keys on unaccounted same-login activity, is blunted by the same fact. A second lane's activity is indistinguishable from your own.

Related: #1370, where the plugin's worker-lease store turned out not to be a real contention primitive either, because participating lanes never acquire it.

Possible directions (not a decision)

  • Make the merge gate itself refuse a PR carrying any configured block label, unconditionally and in every tier — not only in the autopilot merge tier's --block-labels criterion, which is where the check currently lives.
  • Enforce it server-side with a required status check keyed on the label, so no client-side path can bypass it.
  • Give each lane a distinct identity (bot account or app installation) so mergedBy attributes correctly and foreign-activity suppression works.
  • Decide explicitly what the intended cross-lane hold mechanism is, and document it — today lanes are relying on two mechanisms (comments, labels) that are both advisory in practice.

Notes

Nothing was reverted. Both merged PRs (#1326, #1351) are annotated with the factual dispute; the content correction is tracked in #1402.

Deliberately filed without a work-class label; that classification belongs to triage.

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

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: highSignificant impact, or blocks an imminent release; staff this cycle.status: needs-decisionAwaiting a human or maintainer judgment call.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions