~ 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

A private repository's merge queue lands through the gateway

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:queue/private-landing

What changes

The gateway reads a landing as the owner. When a runner lands a merge queue through dev.knotless.pushRefs, and when a collaborator's push is held to the merge gate, the gateway now reads the repository, its queue and each pull's head with a context acting as the owner, through the session they delegated. A private repository's queue is in its space, which takes a member's credential to read; the gateway's own context has nobody logged in, so reading it failed with not logged in: run knotless login <handle>, a 500 for every landing.

A landing that keeps failing ends. The runner ejected a batch's pulls only when the gateway refused it (403); any other failure dropped the batch, which was rebuilt, checked and failed again for ever. Now the same batch (same tip, same heads) failing to land three times in a row has its pulls ejected, saying its batch passed its checks but failed to land 3 times in a row: <error>.

Why

chadtmiller.com/group-host, private, names runner.knotless.dev, which may not push, so it lands through knotless.dev's gateway. Every batch passed its checks and every landing failed with a 500 (not logged in), the runner retrying every 40 seconds or so. The failing read was Target::queue_entries in landing_refusal: for a private repository it joins the space as session::me, which the gateway does not have. Reading as the owner, whose session the gateway holds once they delegate, is what the gateway already writes as.

How it was checked

  • runners_land_a_private_merge_queue_through_a_gateway (knotless-serve gateway tests, spaces alpha only): a private repository, its named runner a member that may not push, the owner delegated; two queued pulls land through the gateway, their branches deleted and both merged.
  • a_runner_named_lands_through_the_gateway (knotless-run) goes on: once the owner delegates, the gateway, having no appview of its own, fails each landing with a 500, and the pull is ejected after the third, saying why.
  • The rest left to CI.

Shortcomings

  • The count of failed landings lives in the runner's memory: a restart starts it again.
  • A gateway down for three batches' runs in a row ejects the pulls; they are queued again by hand.
  • landing_refusal still reads a pull whose head is in the repository itself by opening it again, rather than from the snapshot it holds: that works now the gateway reads as the owner, and is left as it was.

Changeset: none

🤖 Generated with Claude Code

Approved

This pull makes the gateway read the repository, its queue and each pull's head as the owner for a runner's landing and for a collaborator's gated push. It also makes the runner eject a batch's pulls once the same batch fails to land three times in a row. I found nothing that must change.

  • Session lookup: the gateway keeps owners' sessions in app.ctx's config directory, keyed by DID (session::load(&app.ctx, did)). as_owner only sets identifier on a clone of that context, so it picks up the delegated session as intended. Clearing the password stops it falling back to a login.
  • Delegation: writer has already required session::ensure for the owner, so the owner has delegated by the time as_owner is used.
  • Failure counter: it is keyed on the batch's base plus each pull's URI and head, so a moved branch or a different batch resets it. It is cleared on a landing, on an ejection, and when the line goes idle, and idleness now accounts for it. The rule that a 403 ejects at once is unchanged.
  • Tests and docs: the tests cover the private landing path and the third-failure ejection. The docs pages for the gateway and the merge queue are updated, as AGENTS.md asks. Changeset: none fits, since only the server and runner change.

I didn't read the checks, and the gateway test passes without running anywhere but the spaces alpha. Please make sure CI's spaces-alpha test run passes before it lands.

Merged as 80dfda1