Scope / Safety

How Scope for Linux keeps changes safe

Scope changes packages on a machine you depend on, so every change is checked twice. This page explains what runs, when, and what stops it.

Every change starts as a preview

Each uninstall and update builds a plan before anything runs. The plan lists the exact commands, such as apt remove -y for an APT app or flatpak update -y --user for a Flatpak app in your user scope.

A plan works once. Scope stores it for five minutes, and applying it a second time or after that window fails. You can cancel at any point before you confirm.

Scope checks the system again before it runs

Packages change between the moment you read a plan and the moment you confirm it. An update can finish in the background, or another tool can remove the app. Right before it runs anything, Scope checks that:

  • the package is still installed,
  • an update's version has not changed since the plan was built, and
  • the deny-list still allows the action.

If Scope cannot confirm one of these, it stops and does not run the command. Failing closed means a stale plan never runs against a different system.

APT changes are simulated first

Before it previews an APT removal, Scope runs the transaction as a simulation with LC_ALL=C. The simulation shows what else would be removed or upgraded. Scope rejects the plan if the transaction would take a protected package with it.

Scope stores a fingerprint of the simulation in the plan. Right before it applies the plan, it runs the simulation again and compares the result. If the fingerprint differs, the plan does not run.

Admin rights go through the system dialog

Commands that need root run through pkexec, which shows the standard Polkit dialog. Scope never sees, asks for, or stores your password.

Scope does not run commands through a shell. It builds each command as a fixed argument list, so text from the interface cannot turn into extra shell syntax.

Critical packages are protected

A deny-list in the backend blocks changes to packages that the system depends on. It covers:

  • critical APT packages,
  • kernel images,
  • lib* packages, matched by a heuristic,
  • Snap runtimes, and
  • AppImage paths outside the allow-list.

Protected rows show a disabled uninstall action. The deny-list runs at preview and again before apply, so a protected package stays protected even if you turn on Show all. Show all only reveals rows. It does not bypass the checks.

Deleted files go to the Trash

When Scope removes a file of its own, it moves the file to the Trash with gio trash. If gio is unavailable, Scope writes to ~/.local/share/Trash directly. Files are not deleted outright.

Flatpak scope is never guessed

Flatpak installs are scanned in two scopes, user and system. Each app keeps the scope it was found in, and every later command uses that scope. If the scope is missing, Scope fails at preview, probe, and apply. It never falls back to system scope.

Scope updates are verified too

The self-updater downloads the release manifest, checks its minisign signature with a public key compiled into the app, and then checks the SHA-256 hash of the package. Downloads go to a private temporary folder. Builds that predate the embedded key must be updated by hand.

What these checks do not cover

The checks reduce risk, but they do not replace a backup. A removed app can take its user data with it, and Scope does not back up that data. Scope also cannot judge whether an app is one you need. Read the plan before you confirm it.