DEV Community

Scarab Systems
Scarab Systems

Posted on

Scarab Diagnostic Field Test #037 - xdg-desktop-portal Startup Inventory Boundary

Target: flatpak/xdg-desktop-portal
Issue: flatpak/xdg-desktop-portal#1947
Pull request: flatpak/xdg-desktop-portal#2054
Field Lab record: xdg-desktop-portal #1947
This field test was about a missing background app, but the real boundary was not "background apps are unreliable."
That would be too vague.
The public issue reported that background applications already running before xdg-desktop-portal starts were not listed in BackgroundApps until some later window or app-state change triggered an update.
The failing path was narrow.
The portal listened for future changes.
It did not check what was already running when it started.
That is the bug shape.
Not a broken public API.
Not a broad Flatpak background-app failure.
A missing startup inventory pass.

Field Lab record

The public Field Lab record for this case is here:
ADD FIELD LAB LINK HERE
The record contains the public issue, public pull request, repair scope, validation summary, and claim boundaries.
This post is the readable field report.
The Field Lab record is the evidence layer.

SDS result

SDS surfaced a startup inventory boundary in the background portal.
The important finding was small:
the background portal needed to check already-running background apps during startup.
That matters because the existing monitor path already handled later changes.
The bug was the gap before the first change event.
A background app could already be present.
The portal could already be running.
But BackgroundApps could still start empty until some later signal caused the monitor to refresh.
That is a classic startup-state bug.
The system is capable of becoming correct later.
It just begins wrong.

Before

Before the repair, background-app state depended on future monitor-triggering events.
The portal could miss apps that were already running before it started.
The first SDS-guided patch used the obvious narrow repair:


c
monitor_background (background);

That was the right diagnosis.

But it reused the existing monitor path, and that path was not just a quick one-time check.

It also scheduled delayed follow-up checks.

That mattered.

Calling the full monitor path during portal initialization added slow async work to startup and caused a CI timeout in the large integration/notification test.

So the first patch found the right boundary, but not the right runtime shape.

After

The final patch keeps the same repair idea, but separates startup from normal monitor events.

Startup gets one immediate background-app check.

Later app/window/instance changes keep the existing delayed monitor behavior.

That is the key difference.

At startup:

check what is already running.

During normal runtime changes:

keep the existing monitor cycle.

The final patch fixes the missing initial inventory without dragging the full delayed monitor sequence into every portal initialization.

Cold baseline vs final patch

The cold Codex API baseline reached the same general diagnosis.

It proposed calling the background monitor during portal initialization and also initializing background->cancellable.

The useful part was correct:

the portal needed an initial monitor pass.

But the cold patch did not account for the timing behavior inside the monitor path.

It treated the monitor function like a cheap “check now” call, when in practice it also ran delayed checks.

The final PR patch is stronger because it keeps the cold patch’s useful insight, removes unrelated cleanup, and adapts the implementation to the runtime behavior exposed by CI.

In Scarab terms:

same root cause.

smaller repair context.

better proof.

What changed

The repair changes startup behavior so already-running background applications are checked when the background portal initializes.

It preserves the existing delayed monitor behavior for later change events.

That is the whole repair shape.

No public API change.

No broad background portal redesign.

No unrelated cleanup.

No claim that every background-app issue is fixed.

Just a startup inventory repair submitted upstream.

Field test result

Result:

diagnostic proof and startup-inventory repair submitted.

The field test produced a narrow upstream PR, a cold baseline comparison, and a CI-informed final patch.

The point is not that the patch is large.

The point is that it is small for the right reason.

When the failure is a startup inventory boundary bug, the best repair is not to remodel the whole background portal stack.

The best repair is to ask the right question at the right moment:

what is already running?

Public claim

This field test supports a narrow public claim:

SDS identified a startup inventory boundary in xdg-desktop-portal, where the background portal monitored future changes but did not perform an initial check for already-running background applications. A human-submitted repair was prepared to add startup inventory behavior while preserving the existing delayed monitor behavior for later change events.

It also supports a comparison claim:

A cold Codex API baseline identified the same general root cause, but the final PR patch was refined through SDS-guided boundary control and CI feedback to avoid adding the full delayed monitor cycle to portal initialization.

It does not claim that the PR has merged, that upstream accepted the patch, that every background-app issue is fixed, or that maintainers endorsed Scarab.

Disclosure

This field report was prepared with AI-assisted editing from public field-test notes, public issue and PR records, and the public Field Lab record. The diagnostic claim, repair boundary, and final wording were human reviewed.

Scarab Diagnostic Suite is proprietary. The Field Lab publishes public case records, issue links, validation summaries, and claim boundaries only.

SDS finds evidence. People make claims. Maintainers decide.
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
marcusykim profile image
Marcus Kim

The startup-state framing is sharp: BackgroundApps was not fundamentally broken, it was missing the inventory pass for apps already running before xdg-desktop-portal came up. The important distinction is between the first patch calling the existing monitor path and the final patch splitting the immediate startup check from delayed monitor behavior, especially once CI exposed the timeout cost. As an engineering lesson, "subscribe to future changes" and "reconcile current state" deserve to be treated as two separate contracts, even when they appear to return the same data.

Collapse
 
scarab-systems profile image
Scarab Systems

Yes — exactly. That was the important boundary.

The first instinct was: “we already have a monitor path, so call it at startup.” That was directionally right, but CI exposed that the monitor behavior carried delayed/asynchronous costs that did not belong in the startup inventory contract.

The final repair became cleaner once the contracts were separated:

  • startup reconciliation: what is already true right now?
  • monitor behavior: what changes after we are subscribed?

That distinction is the real field-test lesson. A system can expose the same kind of data through two paths, but the timing contract still matters. If the repair ignores that, it may fix the visible bug while smuggling the wrong runtime behavior into startup.