Introducing Frontdesk: earlier feedback on sponsoring requests
At Debcrafters we’re always looking for ways to make Ubuntu’s contribution
processes smoother and give people a better experience when they show up
with a patch, a merge, or an SRU.
One recurring pain point is sponsoring. Contributors without upload rights
depend on a relatively small group of sponsors and reviewers to look at
their merge proposals and bugs, and that group is busy — juggling their own
work, other reviews, and everything else that comes with being an Ubuntu
developer. That’s fine when demand is low, but when the queue grows the
wait can stretch to weeks, and it’s genuinely frustrating to wait that long
only to be told your MP targets the wrong branch, or that the fix needs to
land in the current series before it can be SRUed. Frustrating for the
contributor who could have fixed it on day one, and wasted effort for a
reviewer who has to say the same few things over and over.
Why we built this
We went back through several cycles of Patch Pilot reports and looked at
the reasons sponsoring requests were most often bounced back to the
contributor: wrong target branch, a fix that should land in devel before
being SRUed, a missing or malformed changelog entry, a patch attached as a
plain diff instead of a debdiff, a version that’s already stale by the
time anyone looks at it, and so on. A good number of these have nothing to
do with judgment — they’re mechanical checks a reviewer currently has to
do by hand, every time, before they can even get to the interesting part
of the review.
So we picked off the ones we could detect reliably and are building a bot
for them. The goal isn’t to replace sponsors or reviewers, and it doesn’t
approve, merge, or upload anything — it can’t. It’s a first pass: give
contributors the same feedback a reviewer would have given, but within
minutes instead of weeks, point them at the relevant documentation, and
strip the mechanical noise out of the report so the humans doing the real
review can spend their time on the parts that actually need judgment.
How it works
The bulk of the work is deterministic, plain code, not a model guessing.
For each sponsoring request it fetches the relevant state from Launchpad
(the merge proposal or bug, the diff, linked bugs, comment history) and
the Ubuntu archive, and turns that into a fingerprint:
That fingerprint is what makes re-checking cheap: if nothing relevant
changed since the last pass, the bot has nothing new to say and skips the
item entirely. When something did change, it runs a fixed set of checks
against the current state: is this targeting the branch it should, does
the changelog entry look right, is the proposed version still current,
and so on.
A small number of checks need more judgment than a deterministic rule can
give — things like “does this SRU bug actually explain what regressed and
how it was fixed” — and for those we use an LLM, but narrowly: no tools,
no open-ended access to the request, just a fixed prompt over a bounded
piece of text, asked to return a specific verdict. It’s used sparingly,
partly to keep it cheap, but mostly because we want the bulk of what the
bot says to be traceable back to a rule we can point at, not a model’s
opinion.
Here’s the flow those checks sit in, simplified — the real one has more
checks and more edge cases than are useful to show here; the full version
lives in doc/flow.dot
in the repository if you want the details:
A few things worth calling out in that picture. Several cases return
early without ever reaching the LLM: an item that hasn’t changed, a
private bug, one that isn’t really in the sponsoring queue, or a check
that already has a conclusive answer on its own (the fix is already
uploaded, the diff already landed) — those get a comment and status
update straight from the deterministic check, no model involved. If a
human reviewer is already active on the request, the bot holds back
findings that are a matter of opinion and only keeps the ones that are
plain facts about the state of the archive or the branch — and even
those, if the reviewer already said the same thing themselves, it won’t
repeat. The LLM only comes in for the small number of checks that
genuinely need judgment, with no tools and a fixed scope. And the
possible outcomes are deliberately narrow: stay silent and leave it for
a human, post one advisory comment that doesn’t block anything, or post
one comment and flip the status to Needs Fixing / Incomplete — never a
silent status change, and never more than one comment per pass.
Separately, there’s a maintainer notification channel for
infrastructure problems that aren’t the contributor’s to fix — a
Launchpad diff that fails to generate, or git-ubuntu’s importer not
auto-closing an MP it should have. Those don’t get posted on the
request at all; they ping the team directly so someone can look.
What it currently checks
This is v0.1, and the list below is a sample of what’s implemented
today, not the full set — a few examples in each category to give a
feel for the kind of thing it catches.
The obvious, recurring ones
- Does the MP have merge conflicts against its target?
- Is the proposed version already uploaded to the archive, or stale
against what’s already there — meaning it needs a rebase? - Is there actually something to sponsor here — a patch, an MP — or is
the bug asking for something already covered elsewhere? - Is the MP targeting the right branch (Debian
sid/experimentalfor
a merge, the rightubuntu/<series>-develfor an SRU, rather than
ubuntu/devel)? - Does the changelog cite an
LP: #NNNNNNbug, and is it the right one?
“Linter”-style checks
- Is there a
debian/changelogentry at all? - Does a first-time Ubuntu delta add
XSBC-Original-Maintainerto
debian/control, preserving the Debian maintainer? - Does the changelog version carry a leftover
~ppaNsuffix from a PPA
build? - Are upstream files edited directly instead of via a patch under
debian/patches, or is a bug’s attached patch a plain diff where a
debdiff is needed?
A few more involved cases
- For an SRU, has the fix already landed in a newer series first, as
policy requires — and separately, does the bug’s description actually
hold up to the SRU template it needs? - When a change looks uploaded but the MP hasn’t auto-closed, is that a
real inconsistency worth flagging, or just git-ubuntu’s importer
lagging behind?
Each of these maps back to a real recurring bounce reason we found going
through past cycles’ reports — none of them are hypothetical.
An example
Here’s a real case from the queue: secvarctl MP #508867.
The proposal adds a real fix — an OpenSSL4 compatibility patch — versioned
1.1.0-0ubuntu3:
But that exact version was already uploaded to the archive, as a
no-change rebuild with no relation to this patch:
Same version number, different content — the upload would be rejected on
sight, and as-is this MP can’t be sponsored without a rebase onto a new
version. The bot caught the collision, checked that a reviewer had
already engaged (the submitter had replied in the thread since the last
diff, so it resumed instead of staying quiet), and posted:
Thanks for your contribution! The automated review spotted the
following points:Needs fixing before this can be sponsored:
- An upload with the same version (
1.1.0-0ubuntu3) but different
content already exists in the archive. Your change needs to be
rebased (with a new version number) and resubmitted.Once the points above are addressed, please let us know!
—
This is an automated initial review of sponsoring requests. If this
review seems wrong, please report it at
https://github.com/canonical/ubuntu-sponsoring-frontdesk/issues
Where this stands
This is v0.1. It’s running today, but manually and under close watch —
I’m going through its output myself before anything gets posted, tuning
checks as false positives and rough edges turn up. The plan was to get
it running unattended before the summer break; that slipped a bit due to
some recent infrastructure outages, so unattended operation is now a
post-summer-holidays goal. We’ll keep learning from what it actually
catches and misses in practice and adjust from there, adding checks as
they turn out to be worth it rather than chasing a fixed list — one
we’re already looking at is hooking into ubuntu-lint for version-string
and SRU convention checks instead of reimplementing that logic
ourselves.
The code is at
github.com/canonical/ubuntu-sponsoring-frontdesk.
If you spot a comment from the bot that’s wrong, confusing, or missing
context, we’d like to know — reply here, or open an issue on the
repository if it’s something concrete enough to track. Both are useful:
Discourse for general feedback and discussion, GitHub issues for
anything that needs a fix.



