~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

Queued pulls stall until their own author notices and moves them

Open
Open chadtmiller.com opened this issue 1 comment
kind/featurearea/runner

What happened

Every author keeps its own pull moving through the queue by hand. AGENTS.md's "Landing a change" is a runbook for it: merge main in before queueing, read why a pull was ejected, queue the same head again only when the failure was not the pull's, quarantine a flaky test, stop after three ejections, and have one agent land everyone's pulls. Agents follow it unevenly while doing their real work, and pulls sit ejected, conflicted or stuck until someone notices.

This asks for a keeper: a second job for knotless-agent beside review, run as an account of its own, that does this for queued pulls under a policy the repository writes, so any repository on knotless can use it.

What other tools do

A survey of merge queues, branch bots, AI CI fixers, flaky-test systems and merge-conflict research found no tool that is a generic, policy-driven keeper, but every part of one exists somewhere.

  • Merge queues (Mergify, Trunk, Zuul, GitLab merge trains, bors) keep everything they do mechanical. Requeueing on their own is rare and narrow: a lost runner, or a pull evicted from a failed batch it did not break. Chromium blames a test failure on a change only if the test fails with the change and passes without it.
  • Renovate stops updating a branch once a person pushes to it, and rebases only on conflict by default, since rebasing on every move of the base can keep a pull from ever merging. Kodiak comments and drops its label on conflict rather than retrying.
  • AI fixers split in two. Copilot's Agent Merge (Oct 2026) is a free agent in a sandbox that watches a pull and fixes failing CI and conflicts. Nx Self-Healing CI and claude-code-action's --json-schema mode keep the model's output apart from fixed rules for what is applied: paths allowed, confidence, never the default branch. CodeRabbit never commits workflows, lockfiles or CI config.
  • Only claude-code-action documents reading its own instructions from the base branch, as knotless-agent already reads .knotless/review.md. No product documents a generic "pipe the state to a command, read a verdict back" contract like knotless-agent's.
  • Conflicts: LLMs reproduce the developer's resolution on about 55 to 60% of real conflicts (arXiv 2607.27674, Merge-Bench). Structure-aware tools such as Mergiraf resolve fewer but abstain when unsure. A model judging its own merge accepted 4 of 5 that were structurally broken, so a resolution is trusted only once check and test pass at the resolved head.
  • Flaky tests: every system defines a flaky test as one that passes and fails on the same commit, keeps quarantined tests running, and ties each to an owner, a ticket and an end. Slack's first design let new broken tests through as "flaky", and its second had no way to bring a test back automatically.
  • Models fix about half of reproducible flaky tests (FlakyGuard 47.6%, FlakyDoctor about 57%). The documented failure of agents that repair tests is weakening the assertion until it passes.

What the keeper should be

The model never holds a shell. knotless-agent gathers the pull, its checks, its queue standing and why it was ejected, passes them to the command as review does, and reads back one action from a fixed list, which it checks against the policy and carries out itself: requeue, rerun, update_branch, resolve_conflict, quarantine_propose, comment or give_up.

  • Policy in .knotless/keeper.md on the base branch, so a pull cannot loosen its own rules.
  • Only pulls the owner or a collaborator opened, and only once queued or idle, so it never races an author still pushing. Keeper: off on a line of the body opts a pull out.
  • Never touches workflows, lockfiles, .knotless/ or harness/, except by proposing a change as a pull of its own.
  • Merges main into a pull only when the pull conflicts, since a pass against an older main counts and an update throws it away. Never over a push a person made since its own last one.
  • Requeues only with evidence the failure was not the pull's: a lost runner, a pull evicted from a failed batch it did not break, the test failing on main too, or the test being in harness/quarantine.json. Never the same head after the pull's own failure.
  • Remembers each pull's head and what it tried there. One action open per pull. A comment only when something changes. Hands the pull back with a comment after the third ejection, as AGENTS.md says now.

When a test fails, it does not fix it inside the pull. A failure the pull caused goes back to its author with what failed and why. A test that also fails on main gets an issue or a fix pull against main. A flaky test gets a quarantine entry proposed as a pull, with an issue and an expiry, and maybe a fix pull against main. If its own merge of main broke the pull, it takes that merge back out.

Phases

  1. No model. Merge main in when git merges it cleanly, requeue an ejection that was not the pull's once per head, and comment and stop after the third. knotless show and knotless queue say what the keeper is doing, and AGENTS.md's landing section becomes: queue it and move on. Measured against the ejections from 2026-10-22 to 11-02.
  2. Conflicts git cannot merge, resolved by the command as a merge commit of their own that must pass check and test. Lines both sides only add, as in the docs pages most pulls touch, merged without a model.
  3. Quarantine proposals and fixes to flaky tests, as pulls against main.

Status on main at ac86342b. Phase 1 has partly landed: 71c54165 (knotless-agent keep merges the base into an ejected pull that conflicts and queues it again, honouring Keeper: off and --attempts), 16abb823 (deploys start it) and 5f4a2c65. Still open: requeueing a pull ejected for a reason that isn't its own (a lost runner, a failure on main too, a quarantined test), showing what the keeper is doing in show and queue, the .knotless/keeper.md policy, and phases 2 and 3.