[GH-ISSUE #4673] [Bug] uninstall-adb-package requests all-users removal while reporting user-0 scope #2436

Closed
opened 2026-10-17 21:04:37 +00:00 by bsakaguchi · 6 comments
Owner

Originally created by @coygeek on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4673

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

With a fake adb selected through REA_ADB_PATH, rea uninstall-adb-package emulator-5554 com.example.app --json sends ["-s", "emulator-5554", "uninstall", "com.example.app"]. After the fixture returns Success, REA exits 0 and reports: Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed.

Both tested builds produced this mismatch in 2/2 attempts each. The command has no user selector. AOSP source establishes that this requests all-users uninstall, without requesting data retention. Only the outgoing command and REA result were executed; no real device or data deletion was tested.

Reproduction

Use a source checkout with dependencies installed and npm run build:cached completed, or an unpacked published npm archive with its production dependencies installed. The source build used its pinned Node/npm toolchain. Python 3 and Node must be on PATH. No device or platform-tools installation is needed.

Save this as reproduce.py outside the checkout:

import json
import os
from pathlib import Path
import shutil
import subprocess
import sys

entry = Path(sys.argv[1]).resolve()
fixture = Path(sys.argv[2]).resolve()
fixture.mkdir(parents=True, exist_ok=True)
home = fixture / "home"
home.mkdir(exist_ok=True)
adb = fixture / "fake-adb"
log = fixture / "calls.jsonl"
log.write_text("")
adb.write_text("#!" + sys.executable + "\n" + r'''
import json, os, sys
args = sys.argv[1:]
with open(os.environ["ADB_CALL_LOG"], "a") as log:
    log.write(json.dumps(args) + "\n")
if args == ["version"]:
    print("Android Debug Bridge version 1.0.41\nVersion 34.0.5-fixture\nInstalled as " + sys.argv[0])
elif args == ["-s", "emulator-5554", "uninstall", "com.example.app"]:
    print("Success")
else:
    sys.exit(2)
''')
adb.chmod(0o755)
node = str(Path(shutil.which("node")).resolve())
env = {
    "HOME": str(home),
    "PATH": str(Path(node).parent) + os.pathsep + "/usr/bin:/bin",
    "TMPDIR": str(fixture),
    "REA_ADB_PATH": str(adb),
    "ADB_CALL_LOG": str(log),
}
version = subprocess.run([node, str(entry), "--version"], cwd=home, env=env, capture_output=True, text=True, check=True)
print("REA version=" + version.stdout.strip())
print("Node=" + subprocess.check_output([node, "--version"], text=True).strip())
for attempt in (1, 2):
    result = subprocess.run(
        [node, str(entry), "uninstall-adb-package", "emulator-5554", "com.example.app", "--json"],
        cwd=home, env=env, capture_output=True, text=True,
    )
    (fixture / f"run-{attempt}.stdout.json").write_text(result.stdout)
    (fixture / f"run-{attempt}.stderr.txt").write_text(result.stderr)
    print(f"run={attempt} exit={result.returncode}")
    if result.returncode:
        print(result.stdout, result.stderr)
        sys.exit(1)
    evidence = json.loads(result.stdout)
    for limitation in evidence["limitations"]:
        if limitation.startswith("Uninstall "):
            print(limitation)
    assert not result.stderr
print(log.read_text(), end="")

From the directory containing that script, run one of the following with the entry point for the build under test. The fixture directories must be new. The script uses an isolated HOME and a minimal environment, so client-config overrides are absent.

python3 reproduce.py /path/to/source/scripts/rea.mjs ./main-run
python3 reproduce.py /path/to/unpacked/package/scripts/rea.mjs ./release-run

Both commands above were exercised against the corresponding builds. The fixture only records arguments and supplies synthetic success; it does not simulate Android deletion.

Expected behavior

The ADB operations guide describes this tool as removing a package and its data for user 0. The tool description also specifies user-0 data removal, and the success result repeats that scope. An operation advertised with this scope should preserve another user's installation and app data while removing the requested package and data for user 0.

Impact and scope

For an ordinary removable app installed for user 0 and a secondary user, a successful all-users uninstall can remove the secondary user's app and local data beyond the documented scope. Reinstalling the app does not itself restore that data. No real-device data-loss incident was observed. Protected or system packages, APEX, policy refusals, and vendor-specific behavior were not tested.

  • Impact level: P1
  • Assessment status: provisional
  • Impact basis: The observed request selects an AOSP uninstall mode that can cause severe data loss for particular multi-user device/package inputs; the downstream deletion consequence is source-derived, not an observed device incident.
  • Workaround status: unverified
  • Workaround basis: The CLI takes only a serial and package, with no user selector. AOSP supports a caller-controlled adb -s emulator-5554 shell pm uninstall --user 0 com.example.app alternative outside REA, but its device result was not tested here. This is a prospective way to avoid the excess scope, not recovery for deleted data.

REA version

Published npm package rea-agents@6.5.0, the latest published release at testing; fresh main checkout at cc2e18a265198492dff1587a343bfb802d8c591b. Both entry points report that package version.

Runtime and platform

Node.js v24.18.0; npm 11.16.0 for the source build; macOS 27.0.1, Darwin arm64. No Hopper or Ghidra provider was used.

Target and artifact context

Synthetic serial emulator-5554, package com.example.app, and fake adb version 34.0.5-fixture. No Android device, real APK, or private app data was used. The semantic comparison uses AOSP's Android 14 release-tag sources.

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

  • Expected source: docs/adb-device-analysis.md:101, src/contracts/adb/adbToolContracts.ts:314, and the success limitation in src/adb/AdbProvider.ts:2658 on the tested main checkout. The release tag has the same guide/contract wording and the same limitation at src/adb/AdbProvider.ts:1944.
  • Failure source: Public CLI argument capture below; main src/adb/AdbProvider.ts:2627 and release-tag src/adb/AdbProvider.ts:1913 construct the unqualified uninstall request. src/adb/AdbCommand.ts:57 adds the serial selector.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Each build produced the following two-call output; all four captured CLI calls exited 0 with empty stderr:

run=1 exit=0
Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed
run=2 exit=0
Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed
["version"]
["-s", "emulator-5554", "uninstall", "com.example.app"]
["version"]
["-s", "emulator-5554", "uninstall", "com.example.app"]

AOSP source-derived semantics:

  • Android 14 adb_install.cpp, lines 88–128, forwards uninstall arguments to cmd package or legacy pm, without adding a user selector.
  • Android 14 PackageManagerShellCommand.java, lines 2269–2348, initializes the user to USER_ALL and flags to zero. --user changes that selection; only -k enables DELETE_KEEP_DATA. The default selects DELETE_ALL_USERS and forwards it to the package installer, even though the translated installer user argument becomes user 0. The same file's help at lines 4320–4327 describes user-scoped removal and data/cache retention.

Typed outcome or recovery expected

The failing observable is an unqualified uninstall request followed by a result asserting user-0 scope. A passing argument-capture check should establish that the request honors that promised scope. A proposed device check uses an ordinary test app installed for users 0 and 10, with distinct sentinel data: after the operation, user 0's installation/data should be removed while user 10's installation/data remains. That device check has not been run.

Analysis or suspected cause

Source-derived reasoning: the public CLI reaches the shared uninstall_adb_package handler, which constructs an uninstall request containing only the package operand. The serial helper does not select a user. This contradicts the scope stated by the guide, tool description, and returned limitation. No Android authorization bypass was demonstrated; the caller already supplies an authorized adb connection.

Additional context

No matching report was found in open/closed issue and PR searches for the command name, adb uninstall, all-users, or multi-user removal. No last known good version was established.

Originally created by @coygeek on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4673 ### Before submitting - [X] I searched the open and closed issues for a related report. - [X] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior With a fake adb selected through `REA_ADB_PATH`, `rea uninstall-adb-package emulator-5554 com.example.app --json` sends `["-s", "emulator-5554", "uninstall", "com.example.app"]`. After the fixture returns `Success`, REA exits 0 and reports: `Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed`. Both tested builds produced this mismatch in 2/2 attempts each. The command has no user selector. AOSP source establishes that this requests all-users uninstall, without requesting data retention. Only the outgoing command and REA result were executed; no real device or data deletion was tested. ### Reproduction Use a source checkout with dependencies installed and `npm run build:cached` completed, or an unpacked published npm archive with its production dependencies installed. The source build used its pinned Node/npm toolchain. Python 3 and Node must be on PATH. No device or platform-tools installation is needed. Save this as `reproduce.py` outside the checkout: ```python import json import os from pathlib import Path import shutil import subprocess import sys entry = Path(sys.argv[1]).resolve() fixture = Path(sys.argv[2]).resolve() fixture.mkdir(parents=True, exist_ok=True) home = fixture / "home" home.mkdir(exist_ok=True) adb = fixture / "fake-adb" log = fixture / "calls.jsonl" log.write_text("") adb.write_text("#!" + sys.executable + "\n" + r''' import json, os, sys args = sys.argv[1:] with open(os.environ["ADB_CALL_LOG"], "a") as log: log.write(json.dumps(args) + "\n") if args == ["version"]: print("Android Debug Bridge version 1.0.41\nVersion 34.0.5-fixture\nInstalled as " + sys.argv[0]) elif args == ["-s", "emulator-5554", "uninstall", "com.example.app"]: print("Success") else: sys.exit(2) ''') adb.chmod(0o755) node = str(Path(shutil.which("node")).resolve()) env = { "HOME": str(home), "PATH": str(Path(node).parent) + os.pathsep + "/usr/bin:/bin", "TMPDIR": str(fixture), "REA_ADB_PATH": str(adb), "ADB_CALL_LOG": str(log), } version = subprocess.run([node, str(entry), "--version"], cwd=home, env=env, capture_output=True, text=True, check=True) print("REA version=" + version.stdout.strip()) print("Node=" + subprocess.check_output([node, "--version"], text=True).strip()) for attempt in (1, 2): result = subprocess.run( [node, str(entry), "uninstall-adb-package", "emulator-5554", "com.example.app", "--json"], cwd=home, env=env, capture_output=True, text=True, ) (fixture / f"run-{attempt}.stdout.json").write_text(result.stdout) (fixture / f"run-{attempt}.stderr.txt").write_text(result.stderr) print(f"run={attempt} exit={result.returncode}") if result.returncode: print(result.stdout, result.stderr) sys.exit(1) evidence = json.loads(result.stdout) for limitation in evidence["limitations"]: if limitation.startswith("Uninstall "): print(limitation) assert not result.stderr print(log.read_text(), end="") ``` From the directory containing that script, run one of the following with the entry point for the build under test. The fixture directories must be new. The script uses an isolated HOME and a minimal environment, so client-config overrides are absent. ```sh python3 reproduce.py /path/to/source/scripts/rea.mjs ./main-run python3 reproduce.py /path/to/unpacked/package/scripts/rea.mjs ./release-run ``` Both commands above were exercised against the corresponding builds. The fixture only records arguments and supplies synthetic success; it does not simulate Android deletion. ### Expected behavior The ADB operations guide describes this tool as removing a package and its data for user 0. The tool description also specifies user-0 data removal, and the success result repeats that scope. An operation advertised with this scope should preserve another user's installation and app data while removing the requested package and data for user 0. ### Impact and scope For an ordinary removable app installed for user 0 and a secondary user, a successful all-users uninstall can remove the secondary user's app and local data beyond the documented scope. Reinstalling the app does not itself restore that data. No real-device data-loss incident was observed. Protected or system packages, APEX, policy refusals, and vendor-specific behavior were not tested. - Impact level: P1 - Assessment status: provisional - Impact basis: The observed request selects an AOSP uninstall mode that can cause severe data loss for particular multi-user device/package inputs; the downstream deletion consequence is source-derived, not an observed device incident. - Workaround status: unverified - Workaround basis: The CLI takes only a serial and package, with no user selector. AOSP supports a caller-controlled `adb -s emulator-5554 shell pm uninstall --user 0 com.example.app` alternative outside REA, but its device result was not tested here. This is a prospective way to avoid the excess scope, not recovery for deleted data. ### REA version Published npm package `rea-agents@6.5.0`, the latest published release at testing; fresh `main` checkout at `cc2e18a265198492dff1587a343bfb802d8c591b`. Both entry points report that package version. ### Runtime and platform Node.js v24.18.0; npm 11.16.0 for the source build; macOS 27.0.1, Darwin arm64. No Hopper or Ghidra provider was used. ### Target and artifact context Synthetic serial `emulator-5554`, package `com.example.app`, and fake adb version `34.0.5-fixture`. No Android device, real APK, or private app data was used. The semantic comparison uses AOSP's Android 14 release-tag sources. ### Interface CLI ### Earliest failure stage Capture or observation ### Relevant output or evidence - Expected source: `docs/adb-device-analysis.md:101`, `src/contracts/adb/adbToolContracts.ts:314`, and the success limitation in `src/adb/AdbProvider.ts:2658` on the tested main checkout. The release tag has the same guide/contract wording and the same limitation at `src/adb/AdbProvider.ts:1944`. - Failure source: Public CLI argument capture below; main `src/adb/AdbProvider.ts:2627` and release-tag `src/adb/AdbProvider.ts:1913` construct the unqualified uninstall request. `src/adb/AdbCommand.ts:57` adds the serial selector. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Each build produced the following two-call output; all four captured CLI calls exited 0 with empty stderr: ```text run=1 exit=0 Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed run=2 exit=0 Uninstall removes the package and its data for user 0; keeping data (-k) is not exposed ["version"] ["-s", "emulator-5554", "uninstall", "com.example.app"] ["version"] ["-s", "emulator-5554", "uninstall", "com.example.app"] ``` AOSP source-derived semantics: - [Android 14 adb_install.cpp](https://android.googlesource.com/platform/packages/modules/adb/+/refs/tags/android-14.0.0_r1/client/adb_install.cpp#88), lines 88–128, forwards uninstall arguments to `cmd package` or legacy `pm`, without adding a user selector. - [Android 14 PackageManagerShellCommand.java](https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-14.0.0_r1/services/core/java/com/android/server/pm/PackageManagerShellCommand.java#2269), lines 2269–2348, initializes the user to `USER_ALL` and flags to zero. `--user` changes that selection; only `-k` enables `DELETE_KEEP_DATA`. The default selects `DELETE_ALL_USERS` and forwards it to the package installer, even though the translated installer user argument becomes user 0. The same file's help at lines 4320–4327 describes user-scoped removal and data/cache retention. ### Typed outcome or recovery expected The failing observable is an unqualified uninstall request followed by a result asserting user-0 scope. A passing argument-capture check should establish that the request honors that promised scope. A proposed device check uses an ordinary test app installed for users 0 and 10, with distinct sentinel data: after the operation, user 0's installation/data should be removed while user 10's installation/data remains. That device check has not been run. ### Analysis or suspected cause Source-derived reasoning: the public CLI reaches the shared `uninstall_adb_package` handler, which constructs an uninstall request containing only the package operand. The serial helper does not select a user. This contradicts the scope stated by the guide, tool description, and returned limitation. No Android authorization bypass was demonstrated; the caller already supplies an authorized adb connection. ### Additional context No matching report was found in open/closed issue and PR searches for the command name, adb uninstall, all-users, or multi-user removal. No last known good version was established.
Author
Owner

@XinwangTao commented on GitHub (Oct 17, 2026):

Confirmed — the captured argv matches the unqualified form: adb uninstall <package> without --user maps to AOSP's all-users uninstall (PackageManagerShellCommand treats an absent user as USER_ALL on the cmd path), so the "user 0" wording in the tool description and success limitation overstates the actual scope. The P1 framing is right: on a multi-user device this can silently delete a secondary user's app and local data that the documented contract claims is preserved. A concrete fix: add an explicit --user <id> option (default 0) and emit -s <serial> shell pm uninstall --user <id> <package> so the executed request matches the advertised scope; and until that lands, update adbToolContracts, docs/adb-device-analysis.md and the limitation string to describe the real all-users behavior. Your AOSP source citations (adb_install.cpp 88–128) are the right evidence basis.

<!-- gh-comment-id:6229552209 --> @XinwangTao commented on GitHub (Oct 17, 2026): Confirmed — the captured argv matches the unqualified form: `adb uninstall <package>` without `--user` maps to AOSP's all-users uninstall (PackageManagerShellCommand treats an absent user as USER_ALL on the cmd path), so the "user 0" wording in the tool description and success limitation overstates the actual scope. The P1 framing is right: on a multi-user device this can silently delete a secondary user's app and local data that the documented contract claims is preserved. A concrete fix: add an explicit `--user <id>` option (default 0) and emit `-s <serial> shell pm uninstall --user <id> <package>` so the executed request matches the advertised scope; and until that lands, update adbToolContracts, docs/adb-device-analysis.md and the limitation string to describe the real all-users behavior. Your AOSP source citations (adb_install.cpp 88–128) are the right evidence basis.
Author
Owner

@XinwangTao commented on GitHub (Oct 17, 2026):

Confirmed — the captured argv matches the unqualified form: adb uninstall package without --user maps to AOSP's all-users uninstall (PackageManagerShellCommand treats an absent user as USER_ALL on the cmd path), so the "user 0" wording in the tool description and success limitation overstates the actual scope. The P1 framing is right: on a multi-user device this can silently delete a secondary user's app and local data that the documented contract claims is preserved. A concrete fix: add an explicit --user id option (default 0) and emit "-s serial shell pm uninstall --user id package" so the executed request matches the advertised scope; and until that lands, update adbToolContracts, docs/adb-device-analysis.md and the limitation string to describe the real all-users behavior. Your AOSP source citations (adb_install.cpp 88-128) are the right evidence basis.

<!-- gh-comment-id:6229575104 --> @XinwangTao commented on GitHub (Oct 17, 2026): Confirmed — the captured argv matches the unqualified form: adb uninstall package without --user maps to AOSP's all-users uninstall (PackageManagerShellCommand treats an absent user as USER_ALL on the cmd path), so the "user 0" wording in the tool description and success limitation overstates the actual scope. The P1 framing is right: on a multi-user device this can silently delete a secondary user's app and local data that the documented contract claims is preserved. A concrete fix: add an explicit --user id option (default 0) and emit "-s serial shell pm uninstall --user id package" so the executed request matches the advertised scope; and until that lands, update adbToolContracts, docs/adb-device-analysis.md and the limitation string to describe the real all-users behavior. Your AOSP source citations (adb_install.cpp 88-128) are the right evidence basis.
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Published in be0b2d138c on main.

The shared provider now sends adb -s SERIAL shell pm uninstall --user 0 PACKAGE through the existing quoted shell-operand boundary. This explicitly selects the user promised by the current contract. No user-selection surface was added. Tool guidance and returned limitations describe the request, including omitted data retention, without claiming independent verification of device enforcement. AOSP Android14 PackageManagerShellCommand distinguishes the absent-user default from --user 0 and sets DELETE_ALL_USERS only for USER_ALL.

Validation executed on Node24.18/Darwin arm64:

  • Two strengthened provider controls failed with the old unqualified command and passed after the fix (68 unrelated controls explicitly skipped in that selected run).
  • Three public CLI/official MCP scenarios with caller-selected fake adb: Success/exit0, device Failure/exit0 and device Failure/exit1. Exact recorded arguments include serial, shell pm uninstall --user 0, and the selected package on both interfaces; no broader fallback command appears. Success Evidence facts/parameters/limitations agree across interfaces, and device refusal reasons remain typed unsupported_target.
  • 19 command-boundary/existing MCP schema checks passed; check:fast, docs:check with five README checks, normal commit/pre-push hooks passed.

This verifies REA's request construction and adapter behavior. No real device was contacted or mutated. The proposed multi-user installation/data sentinel test, real platform-tools/device lane, system/APEX/vendor behavior and performance/full-task tokens/peak-family-memory costs remain unverified. The issue stays open for supported-device qualification. The separate multi-display focus issue #4660 remains pending.

<!-- gh-comment-id:6230206341 --> @morluto commented on GitHub (Oct 17, 2026): Published in be0b2d138c46bb951fc3c8ee57ef7b0d57fed312 on main. The shared provider now sends `adb -s SERIAL shell pm uninstall --user 0 PACKAGE` through the existing quoted shell-operand boundary. This explicitly selects the user promised by the current contract. No user-selection surface was added. Tool guidance and returned limitations describe the request, including omitted data retention, without claiming independent verification of device enforcement. [AOSP Android14 PackageManagerShellCommand](https://github.com/aosp-mirror/platform_frameworks_base/blob/android-14.0.0_r1/services/core/java/com/android/server/pm/PackageManagerShellCommand.java) distinguishes the absent-user default from `--user 0` and sets DELETE_ALL_USERS only for USER_ALL. Validation executed on Node24.18/Darwin arm64: - Two strengthened provider controls failed with the old unqualified command and passed after the fix (68 unrelated controls explicitly skipped in that selected run). - Three public CLI/official MCP scenarios with caller-selected fake adb: Success/exit0, device Failure/exit0 and device Failure/exit1. Exact recorded arguments include serial, `shell pm uninstall --user 0`, and the selected package on both interfaces; no broader fallback command appears. Success Evidence facts/parameters/limitations agree across interfaces, and device refusal reasons remain typed `unsupported_target`. - 19 command-boundary/existing MCP schema checks passed; check:fast, docs:check with five README checks, normal commit/pre-push hooks passed. This verifies REA's request construction and adapter behavior. No real device was contacted or mutated. The proposed multi-user installation/data sentinel test, real platform-tools/device lane, system/APEX/vendor behavior and performance/full-task tokens/peak-family-memory costs remain unverified. The issue stays open for supported-device qualification. The separate multi-display focus issue #4660 remains pending.
Author
Owner

@XinwangTao commented on GitHub (Oct 17, 2026):

Thanks for the fix in be0b2d1 — sending adb -s SERIAL shell pm uninstall --user 0 PACKAGE explicitly selects the user the contract promises, and updating the tool guidance to describe the actual request (including omitted data retention) closes the scope mismatch cleanly. The AOSP evidence (USER_ALL vs --user 0 distinction in PackageManagerShellCommand) makes the fix easy to verify. One follow-up suggestion: since the CLI still has no user-selection surface, a --user <id> flag (default 0) would let multi-user workflows target a specific secondary profile without dropping to a manual adb call — otherwise a user-0-scoped uninstall is all the CLI can ever express. The strengthened provider controls are a good guard against regressing back to the unqualified form.

<!-- gh-comment-id:6231532013 --> @XinwangTao commented on GitHub (Oct 17, 2026): Thanks for the fix in be0b2d1 — sending `adb -s SERIAL shell pm uninstall --user 0 PACKAGE` explicitly selects the user the contract promises, and updating the tool guidance to describe the actual request (including omitted data retention) closes the scope mismatch cleanly. The AOSP evidence (USER_ALL vs --user 0 distinction in PackageManagerShellCommand) makes the fix easy to verify. One follow-up suggestion: since the CLI still has no user-selection surface, a `--user <id>` flag (default 0) would let multi-user workflows target a specific secondary profile without dropping to a manual adb call — otherwise a user-0-scoped uninstall is all the CLI can ever express. The strengthened provider controls are a good guard against regressing back to the unqualified form.
Author
Owner

@XinwangTao commented on GitHub (Oct 17, 2026):

Confirmed the fix closes the scope mismatch: routing through shell pm uninstall --user 0 makes the executed request match the documented user-0 contract instead of AOSP's USER_ALL default. One follow-up worth considering: expose an explicit --user option for multi-user targets, since the current contract only covers user 0 and some setups may legitimately target a secondary user. The sentinel test (user 0 vs user 10 data retention) remains a good final validation once a device lane is available.

<!-- gh-comment-id:6231532017 --> @XinwangTao commented on GitHub (Oct 17, 2026): Confirmed the fix closes the scope mismatch: routing through `shell pm uninstall --user 0` makes the executed request match the documented user-0 contract instead of AOSP's USER_ALL default. One follow-up worth considering: expose an explicit `--user` option for multi-user targets, since the current contract only covers user 0 and some setups may legitimately target a secondary user. The sentinel test (user 0 vs user 10 data retention) remains a good final validation once a device lane is available.
Author
Owner

@coygeek commented on GitHub (Oct 18, 2026):

Closing as addressed on main by be0b2d138. Package uninstall now explicitly sends shell pm uninstall --user 0, and its Evidence describes the requested scope without claiming independent device enforcement. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.

<!-- gh-comment-id:6244111240 --> @coygeek commented on GitHub (Oct 18, 2026): Closing as addressed on `main` by [be0b2d138](https://github.com/morluto/rea/commit/be0b2d138c46bb951fc3c8ee57ef7b0d57fed312). Package uninstall now explicitly sends shell pm uninstall --user 0, and its Evidence describes the requested scope without claiming independent device enforcement. I verified the committed source and regression coverage; I have not rerun the runtime reproduction.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2436
No description provided.