[GH-ISSUE #4574] [Bug] push-adb-file pushes without overwrite after an ambiguous existence-probe failure #2376

Closed
opened 2026-10-17 21:03:53 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

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

Area

Other

Observed behavior

Running node scripts/rea.mjs push-adb-file emulator-5554 <local-file> /sdcard/rea-repro/payload.bin --json without --overwrite issued an adb push after the pre-push test -e command exited 1 with stderr adb: error: closed. REA exited 0, recorded parameters.overwrite: false, and reported normalized_result.overwritten: false. The fake adb copied the replacement bytes over its preexisting local device-file stand-in. A successful path-exists probe instead refused the same request and left the stand-in unchanged.

This was observed through the built public CLI with a deterministic fake adb selected using the documented REA_ADB_PATH. No Android device was attached; the observed replacement occurred only in the fixture. A real connection failure and actual device-file loss were not reproduced.

Reproduction

  1. For the source baseline listed below, use the repository's pinned development toolchain and run npm ci and npm run build:cached in a fresh checkout. For the published-package baseline, install the release listed below with npm install --prefix <release-dir> rea-agents@<release-version>; its package root is <release-dir>/node_modules/rea-agents. Both preparations and builds were executed with a disposable HOME and npm cache.
  2. Save this fixture outside the checkout/package as reproduce.py. From each baseline's root, run python3 <path-to-reproduce.py> with the Node runtime listed below on PATH. It creates an isolated HOME, removes client-config overrides, supplies a small fake adb, and deletes its temporary files on completion. It never contacts an Android device.
import json, os, pathlib, shutil, subprocess, tempfile
repo = pathlib.Path.cwd()
blocked = ('REA_', 'CLAUDE_', 'CODEX_', 'COPILOT_', 'OPENCODE_', 'XDG_', 'GEMINI_', 'QWEN_', 'GROK_', 'HERMES_', 'PI_', 'OMP_', 'SAND_', 'KIMI_', 'QODER_', 'DSH_')
env = {k: v for k, v in os.environ.items() if not k.startswith(blocked)}
fixture = r'''#!/usr/bin/env python3
import hashlib, json, os, pathlib, shutil, sys
root = pathlib.Path(os.environ['FAKE_ROOT'])
args = sys.argv[1:]
with (root / 'calls').open('a') as f:
    f.write(json.dumps(args) + '\n')
if args == ['version']:
    print('Android Debug Bridge version 1.0.41\nVersion 34.0.5-10900879\nInstalled as ' + __file__)
    sys.exit(0)
if args[:2] == ['-s', 'emulator-5554']:
    args = args[2:]
if args == ['shell', 'test', '-e', '/sdcard/rea-repro/payload.bin']:
    mode = (root / 'mode').read_text()
    if mode == 'exists':
        sys.exit(0)
    if mode == 'absent':
        sys.exit(1)  # Documented absence signal: nonzero exit, no adb diagnosis.
    if mode == 'ambiguous':
        print('adb: error: closed', file=sys.stderr)
    if mode == 'offline':
        print('error: device offline', file=sys.stderr)
    sys.exit(1)
if len(args) == 3 and args[0] == 'push':
    shutil.copyfile(args[1], root / 'device-file')
    print('1 file pushed')
    sys.exit(0)
if args == ['shell', 'sha256sum', '/sdcard/rea-repro/payload.bin']:
    print(hashlib.sha256((root / 'device-file').read_bytes()).hexdigest() + '  ' + args[2])
    sys.exit(0)
print('Unexpected fixture command: ' + repr(args), file=sys.stderr)
sys.exit(99)
'''
with tempfile.TemporaryDirectory(prefix='rea-repro-') as directory:
    root = pathlib.Path(directory)
    for name in ['home', 'runtime']:
        (root / name).mkdir()
    env['HOME'] = str(root / 'home')
    node = subprocess.check_output(['node', '-p', 'process.execPath'], env=env, text=True).strip()
    adb = root / 'adb'
    adb.write_text(fixture)
    adb.chmod(0o755)
    env.update(HOME=str(root / 'home'), TMPDIR=str(root / 'runtime'), REA_ADB_PATH=str(adb), FAKE_ROOT=str(root), PATH=str(pathlib.Path(node).parent) + ':' + env['PATH'])
    for mode, overwrite in [('exists', False), ('absent', False), ('ambiguous', False), ('ambiguous', False), ('offline', False), ('exists', True)]:
        (root / 'mode').write_text(mode)
        (root / 'device-file').write_text('original device bytes\n')
        if mode == 'absent':
            (root / 'device-file').unlink()
        (root / 'input.bin').write_text('replacement bytes\n')
        (root / 'calls').write_text('')
        args = [node, 'scripts/rea.mjs', 'push-adb-file', 'emulator-5554', str(root / 'input.bin'), '/sdcard/rea-repro/payload.bin', '--json']
        if overwrite:
            args.append('--overwrite')
        result = subprocess.run(args, cwd=repo, env=env, text=True, capture_output=True, timeout=60)
        value = json.loads(result.stdout)
        calls = [json.loads(line) for line in (root / 'calls').read_text().splitlines()]
        print(json.dumps({'mode': mode, 'overwrite': overwrite, 'exit': result.returncode, 'pushed': any('push' in call for call in calls), 'device_bytes': (root / 'device-file').read_text().strip(), 'reported_overwritten': value.get('normalized_result', {}).get('overwritten'), 'code': value.get('code'), 'reason': value.get('details', {}).get('reason')}))
  1. Inspect the printed results. Both ambiguous-probe attempts push despite overwrite: false, replace the stand-in bytes, and report overwritten: false. The existence and offline controls refuse without pushing; the clean absent-destination control exits its probe nonzero with no adb diagnosis, then succeeds without overwrite, receives the selected bytes, and reports overwritten: false. Explicit overwrite permits replacement. This fixture makes six CLI requests per baseline; the ambiguous cases reproduced 2/2 on each tested build (4/4 across both builds).

Expected behavior

Without explicit overwrite, an ambiguous pre-push probe must leave destination existence unknown and stop before transfer. REA must return a typed failure retaining the probe diagnostic instead of treating that failure as evidence that the destination is absent. The documentation promises an existing-target check and refusal without overwrite, and the provider's probe comment explicitly says other failures leave existence unknown and must not be followed by push. The documented non-atomic check caveat concerns concurrent creation after the check; this fixture has no competing process or destination creation.

Impact and scope

The observed defect bypasses overwrite refusal for an unrecognized nonzero probe diagnostic and returns an inaccurate replacement receipt. The deterministic fixture reproduced the erroneous transfer in both attempts on each tested build. Real-device frequency, affected destination contents, and severe loss of valuable data were not measured; actual device replacement remains an inference from issuing adb push to an existing selected path.

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The compiled public CLI performed a bounded unintended transfer after unknown existence and mislabeled the fixture replacement as not overwritten; no severe real-device loss was established.
  • Workaround status: unverified
  • Workaround basis: Independently checking and preserving the selected destination through the caller's adb before transfer is a proposed precaution; it was not validated on a live device and does not restore REA's refusal contract.

REA version

Current-main source commit f22e8e7268, built from a fresh clone; separately installed npm release rea-agents@6.5.0, confirmed as the latest published version by the registry. Both CLI entry points report 6.5.0.

Runtime and platform

Node.js v24.18.0; npm 11.16.0 (the source checkout's pinned development toolchain); macOS 27.0.1; uname -sm: Darwin arm64. The fake adb reports Android Debug Bridge 1.0.41 and version 34.0.5-10900879; this is fixture identity, not an installed platform-tools observation.

Target and artifact context

Selected synthetic serial emulator-5554, absolute destination /sdcard/rea-repro/payload.bin, local input containing replacement bytes followed by a newline, and a local destination stand-in containing original device bytes followed by a newline except in the absent-destination control, which removes the stand-in before invocation. The fake adb records commands, implements the specified probe outcomes, copies the actual private input snapshot on push, and computes SHA-256 over the copied bytes. No live Android filesystem or emulator was used.

Interface

CLI

Earliest failure stage

Capture or observation

Relevant output or evidence

  • Expected source: docs/adb-device-analysis.md:153-157; src/adb/AdbProvider.ts:2532-2534; node scripts/rea.mjs push-adb-file --help.
  • Failure source: src/adb/AdbProvider.ts:2548-2567; protocol-error classification at src/adb/AdbProvider.ts:455-461.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Executed identity and entry-point checks:

node --version
v24.18.0
uname -sm
Darwin arm64
node scripts/rea.mjs --version
6.5.0
node scripts/rea.mjs push-adb-file --help
rea push-adb-file — Push one local file to the device; refuses existing targets without --overwrite

Executed python3 <path-to-reproduce.py> from each baseline's root; both produced this exact meaningful output:

{"mode": "exists", "overwrite": false, "exit": 1, "pushed": false, "device_bytes": "original device bytes", "reported_overwritten": null, "code": "unreadable_output", "reason": "The device path already exists and overwrite was not requested: /sdcard/rea-repro/payload.bin"}
{"mode": "absent", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null}
{"mode": "ambiguous", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null}
{"mode": "ambiguous", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null}
{"mode": "offline", "overwrite": false, "exit": 1, "pushed": false, "device_bytes": "original device bytes", "reported_overwritten": null, "code": "unsupported_target", "reason": "error: device offline"}
{"mode": "exists", "overwrite": true, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": true, "code": null, "reason": null}

The fixture's invocation log established that the ambiguous cases ran version, shell test -e, push, and shell sha256sum in that order. The absent-destination control also ran version, shell test -e, push, and shell sha256sum, created the stand-in with the selected bytes, and reported overwritten: false. Successful-existence and offline controls ran only version and shell test -e. The fixture supplies the ambiguous stderr diagnostic rather than assuming it from REA's final output.

Typed outcome or recovery expected

Repeat the same ambiguous-probe request without overwrite: the current failure is exit 0 plus a push and false replacement receipt; the passing restoration is a nonzero typed refusal preserving unknown destination existence and the probe diagnosis, with no push and the original stand-in bytes intact. Keep the successful-existence control refused, the recognized offline control refused, the clean absent-destination control successful without --overwrite after a nonzero probe with no adb diagnosis, with the destination receiving the selected bytes and overwritten: false, and the explicit-overwrite control successful with overwritten: true. Those controls distinguish protecting unknown existence from disabling all transfers.

Analysis or suspected cause

Source-derived reasoning: the shared adb runner represents an unrecognized failed probe as a protocol error. The push workflow lets that error continue, derives the existence flag from probe success, and therefore treats it as false. The same flag controls both overwrite refusal and the replacement receipt. This explains the observed transfer and receipt without requiring a race.

Additional context

This is a focused follow-up to merged PR #2354: it fixed recognized offline/unauthorized/missing-device probes and explicitly left unclassified nonzero probes with stderr for a separate decision. The current provider comment still promises to preserve unknown existence rather than push. Open-and-closed issue/PR searches for push-adb-file, push_adb_file, test -e, and overwritten found no focused duplicate or pending fix. Related #4252 concerns host-source bytes changing between digest and transfer; #3369 concerns post-push checksum overflow; #2602 concerns tool-description wording. The broader overwrite search reached its result limit and later narrowing queries hit GitHub's search rate limit; the completed command-name searches each returned 11 results across both states. No live-device check was performed.

Originally created by @coygeek on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4574 ### 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 Other ### Observed behavior Running `node scripts/rea.mjs push-adb-file emulator-5554 <local-file> /sdcard/rea-repro/payload.bin --json` without `--overwrite` issued an adb push after the pre-push `test -e` command exited 1 with stderr `adb: error: closed`. REA exited 0, recorded `parameters.overwrite: false`, and reported `normalized_result.overwritten: false`. The fake adb copied the replacement bytes over its preexisting local device-file stand-in. A successful path-exists probe instead refused the same request and left the stand-in unchanged. This was observed through the built public CLI with a deterministic fake adb selected using the documented `REA_ADB_PATH`. No Android device was attached; the observed replacement occurred only in the fixture. A real connection failure and actual device-file loss were not reproduced. ### Reproduction 1. For the source baseline listed below, use the repository's pinned development toolchain and run `npm ci` and `npm run build:cached` in a fresh checkout. For the published-package baseline, install the release listed below with `npm install --prefix <release-dir> rea-agents@<release-version>`; its package root is `<release-dir>/node_modules/rea-agents`. Both preparations and builds were executed with a disposable HOME and npm cache. 2. Save this fixture outside the checkout/package as `reproduce.py`. From each baseline's root, run `python3 <path-to-reproduce.py>` with the Node runtime listed below on PATH. It creates an isolated HOME, removes client-config overrides, supplies a small fake adb, and deletes its temporary files on completion. It never contacts an Android device. ```python import json, os, pathlib, shutil, subprocess, tempfile repo = pathlib.Path.cwd() blocked = ('REA_', 'CLAUDE_', 'CODEX_', 'COPILOT_', 'OPENCODE_', 'XDG_', 'GEMINI_', 'QWEN_', 'GROK_', 'HERMES_', 'PI_', 'OMP_', 'SAND_', 'KIMI_', 'QODER_', 'DSH_') env = {k: v for k, v in os.environ.items() if not k.startswith(blocked)} fixture = r'''#!/usr/bin/env python3 import hashlib, json, os, pathlib, shutil, sys root = pathlib.Path(os.environ['FAKE_ROOT']) args = sys.argv[1:] with (root / 'calls').open('a') as f: f.write(json.dumps(args) + '\n') if args == ['version']: print('Android Debug Bridge version 1.0.41\nVersion 34.0.5-10900879\nInstalled as ' + __file__) sys.exit(0) if args[:2] == ['-s', 'emulator-5554']: args = args[2:] if args == ['shell', 'test', '-e', '/sdcard/rea-repro/payload.bin']: mode = (root / 'mode').read_text() if mode == 'exists': sys.exit(0) if mode == 'absent': sys.exit(1) # Documented absence signal: nonzero exit, no adb diagnosis. if mode == 'ambiguous': print('adb: error: closed', file=sys.stderr) if mode == 'offline': print('error: device offline', file=sys.stderr) sys.exit(1) if len(args) == 3 and args[0] == 'push': shutil.copyfile(args[1], root / 'device-file') print('1 file pushed') sys.exit(0) if args == ['shell', 'sha256sum', '/sdcard/rea-repro/payload.bin']: print(hashlib.sha256((root / 'device-file').read_bytes()).hexdigest() + ' ' + args[2]) sys.exit(0) print('Unexpected fixture command: ' + repr(args), file=sys.stderr) sys.exit(99) ''' with tempfile.TemporaryDirectory(prefix='rea-repro-') as directory: root = pathlib.Path(directory) for name in ['home', 'runtime']: (root / name).mkdir() env['HOME'] = str(root / 'home') node = subprocess.check_output(['node', '-p', 'process.execPath'], env=env, text=True).strip() adb = root / 'adb' adb.write_text(fixture) adb.chmod(0o755) env.update(HOME=str(root / 'home'), TMPDIR=str(root / 'runtime'), REA_ADB_PATH=str(adb), FAKE_ROOT=str(root), PATH=str(pathlib.Path(node).parent) + ':' + env['PATH']) for mode, overwrite in [('exists', False), ('absent', False), ('ambiguous', False), ('ambiguous', False), ('offline', False), ('exists', True)]: (root / 'mode').write_text(mode) (root / 'device-file').write_text('original device bytes\n') if mode == 'absent': (root / 'device-file').unlink() (root / 'input.bin').write_text('replacement bytes\n') (root / 'calls').write_text('') args = [node, 'scripts/rea.mjs', 'push-adb-file', 'emulator-5554', str(root / 'input.bin'), '/sdcard/rea-repro/payload.bin', '--json'] if overwrite: args.append('--overwrite') result = subprocess.run(args, cwd=repo, env=env, text=True, capture_output=True, timeout=60) value = json.loads(result.stdout) calls = [json.loads(line) for line in (root / 'calls').read_text().splitlines()] print(json.dumps({'mode': mode, 'overwrite': overwrite, 'exit': result.returncode, 'pushed': any('push' in call for call in calls), 'device_bytes': (root / 'device-file').read_text().strip(), 'reported_overwritten': value.get('normalized_result', {}).get('overwritten'), 'code': value.get('code'), 'reason': value.get('details', {}).get('reason')})) ``` 3. Inspect the printed results. Both ambiguous-probe attempts push despite `overwrite: false`, replace the stand-in bytes, and report `overwritten: false`. The existence and offline controls refuse without pushing; the clean absent-destination control exits its probe nonzero with no adb diagnosis, then succeeds without overwrite, receives the selected bytes, and reports `overwritten: false`. Explicit overwrite permits replacement. This fixture makes six CLI requests per baseline; the ambiguous cases reproduced 2/2 on each tested build (4/4 across both builds). ### Expected behavior Without explicit overwrite, an ambiguous pre-push probe must leave destination existence unknown and stop before transfer. REA must return a typed failure retaining the probe diagnostic instead of treating that failure as evidence that the destination is absent. The documentation promises an existing-target check and refusal without overwrite, and the provider's probe comment explicitly says other failures leave existence unknown and must not be followed by push. The documented non-atomic check caveat concerns concurrent creation after the check; this fixture has no competing process or destination creation. ### Impact and scope The observed defect bypasses overwrite refusal for an unrecognized nonzero probe diagnostic and returns an inaccurate replacement receipt. The deterministic fixture reproduced the erroneous transfer in both attempts on each tested build. Real-device frequency, affected destination contents, and severe loss of valuable data were not measured; actual device replacement remains an inference from issuing adb push to an existing selected path. - Impact level: P2 - Assessment status: supported - Impact basis: The compiled public CLI performed a bounded unintended transfer after unknown existence and mislabeled the fixture replacement as not overwritten; no severe real-device loss was established. - Workaround status: unverified - Workaround basis: Independently checking and preserving the selected destination through the caller's adb before transfer is a proposed precaution; it was not validated on a live device and does not restore REA's refusal contract. ### REA version Current-main source commit f22e8e72685c05e372c62582c7bc5fcd085b2fa6, built from a fresh clone; separately installed npm release `rea-agents@6.5.0`, confirmed as the latest published version by the registry. Both CLI entry points report `6.5.0`. ### Runtime and platform Node.js v24.18.0; npm 11.16.0 (the source checkout's pinned development toolchain); macOS 27.0.1; `uname -sm`: Darwin arm64. The fake adb reports Android Debug Bridge 1.0.41 and version 34.0.5-10900879; this is fixture identity, not an installed platform-tools observation. ### Target and artifact context Selected synthetic serial `emulator-5554`, absolute destination `/sdcard/rea-repro/payload.bin`, local input containing `replacement bytes` followed by a newline, and a local destination stand-in containing `original device bytes` followed by a newline except in the absent-destination control, which removes the stand-in before invocation. The fake adb records commands, implements the specified probe outcomes, copies the actual private input snapshot on push, and computes SHA-256 over the copied bytes. No live Android filesystem or emulator was used. ### Interface CLI ### Earliest failure stage Capture or observation ### Relevant output or evidence - Expected source: docs/adb-device-analysis.md:153-157; src/adb/AdbProvider.ts:2532-2534; `node scripts/rea.mjs push-adb-file --help`. - Failure source: src/adb/AdbProvider.ts:2548-2567; protocol-error classification at src/adb/AdbProvider.ts:455-461. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Executed identity and entry-point checks: ```text node --version v24.18.0 uname -sm Darwin arm64 node scripts/rea.mjs --version 6.5.0 node scripts/rea.mjs push-adb-file --help rea push-adb-file — Push one local file to the device; refuses existing targets without --overwrite ``` Executed `python3 <path-to-reproduce.py>` from each baseline's root; both produced this exact meaningful output: ```jsonl {"mode": "exists", "overwrite": false, "exit": 1, "pushed": false, "device_bytes": "original device bytes", "reported_overwritten": null, "code": "unreadable_output", "reason": "The device path already exists and overwrite was not requested: /sdcard/rea-repro/payload.bin"} {"mode": "absent", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null} {"mode": "ambiguous", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null} {"mode": "ambiguous", "overwrite": false, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": false, "code": null, "reason": null} {"mode": "offline", "overwrite": false, "exit": 1, "pushed": false, "device_bytes": "original device bytes", "reported_overwritten": null, "code": "unsupported_target", "reason": "error: device offline"} {"mode": "exists", "overwrite": true, "exit": 0, "pushed": true, "device_bytes": "replacement bytes", "reported_overwritten": true, "code": null, "reason": null} ``` The fixture's invocation log established that the ambiguous cases ran `version`, `shell test -e`, `push`, and `shell sha256sum` in that order. The absent-destination control also ran `version`, `shell test -e`, `push`, and `shell sha256sum`, created the stand-in with the selected bytes, and reported `overwritten: false`. Successful-existence and offline controls ran only `version` and `shell test -e`. The fixture supplies the ambiguous stderr diagnostic rather than assuming it from REA's final output. ### Typed outcome or recovery expected Repeat the same ambiguous-probe request without overwrite: the current failure is exit 0 plus a push and false replacement receipt; the passing restoration is a nonzero typed refusal preserving unknown destination existence and the probe diagnosis, with no push and the original stand-in bytes intact. Keep the successful-existence control refused, the recognized offline control refused, the clean absent-destination control successful without `--overwrite` after a nonzero probe with no adb diagnosis, with the destination receiving the selected bytes and `overwritten: false`, and the explicit-overwrite control successful with `overwritten: true`. Those controls distinguish protecting unknown existence from disabling all transfers. ### Analysis or suspected cause Source-derived reasoning: the shared adb runner represents an unrecognized failed probe as a protocol error. The push workflow lets that error continue, derives the existence flag from probe success, and therefore treats it as false. The same flag controls both overwrite refusal and the replacement receipt. This explains the observed transfer and receipt without requiring a race. ### Additional context This is a focused follow-up to merged [PR #2354](https://github.com/morluto/rea/pull/2354): it fixed recognized offline/unauthorized/missing-device probes and explicitly left unclassified nonzero probes with stderr for a separate decision. The current provider comment still promises to preserve unknown existence rather than push. Open-and-closed issue/PR searches for `push-adb-file`, `push_adb_file`, `test -e`, and `overwritten` found no focused duplicate or pending fix. Related [#4252](https://github.com/morluto/rea/issues/4252) concerns host-source bytes changing between digest and transfer; [#3369](https://github.com/morluto/rea/issues/3369) concerns post-push checksum overflow; [#2602](https://github.com/morluto/rea/issues/2602) concerns tool-description wording. The broader `overwrite` search reached its result limit and later narrowing queries hit GitHub's search rate limit; the completed command-name searches each returned 11 results across both states. No live-device check was performed.
Author
Owner

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

Addressed on main in github.com/morluto/rea@61e688070f. The destination check now treats only a clean, completed test -e false result as absence; ambiguous results such as adb: error: closed retain their diagnostic and stop before adb push. Main also includes CLI regression coverage that checks the destination remains unchanged. Verified by source review; I have not rerun the fixture or tested a live device. Closing as completed.

<!-- gh-comment-id:6244122768 --> @coygeek commented on GitHub (Oct 18, 2026): Addressed on main in https://github.com/morluto/rea/commit/61e688070f48016b6d178cd04c02fcc2f33e19ad. The destination check now treats only a clean, completed `test -e` false result as absence; ambiguous results such as `adb: error: closed` retain their diagnostic and stop before `adb push`. Main also includes CLI regression coverage that checks the destination remains unchanged. Verified by source review; I have not rerun the fixture or tested a live device. Closing as completed.
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#2376
No description provided.