[PR #5874] [MERGED] fix(adb): report unrecognized package rows from resolve-adb-packages #7095

Closed
opened 2026-11-01 21:45:21 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5874
Author: @kaoru0822-kitauji
Created: 10/21/2026
Status: ✅ Merged
Merged: 10/21/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/adb-package-unparsed-lines


📝 Commits (2)

  • c68a6df fix(adb): report unrecognized package rows from resolve-adb-packages
  • fdd5fde Merge remote-tracking branch 'origin/main' into fix/adb-package-unparsed-lines

📊 Changes

12 files changed (+280 additions, -127 deletions)

View changed files

📝 docs/adb-device-analysis.md (+3 -2)
📝 src/adb/AdbDeviceOutput.test.ts (+34 -16)
📝 src/adb/AdbDeviceOutput.ts (+20 -16)
📝 src/adb/AdbDirectoryListing.ts (+11 -6)
📝 src/adb/AdbProvider.test.ts (+1 -0)
📝 src/adb/AdbProvider.ts (+59 -72)
📝 src/adb/AdbShellOutput.ts (+18 -14)
➕ src/adb/AdbUnparsedLines.ts (+27 -0)
📝 src/domain/adb/adbDeviceAnalysis.ts (+1 -0)
➕ tests/acceptance/applications/adbPackageInventoryCoverage.test.ts (+104 -0)
📝 tests/boundary/mcp/adbMcp.test.ts (+1 -0)
📝 tests/boundary/process/adbDirectoryListing.test.ts (+1 -1)

📄 Description

What broke: resolve_adb_packages marked coverage: "partial" when pm list packages -f printed unrecognized rows but dropped those rows, and with more than ten rows its limitation named an unparsed_lines field the result never carried.
Fix: ADB parsers now own unrecognized-line facts (first ten verbatim plus the exact total); one provider projection derives unparsed_lines, coverage, and the truncation limitation for every parsed listing and the package search, and the resolver schema now carries unparsed_lines.
Risk: Low; additive output field on one operation. Sibling listings keep their existing output and limitation text; parser internals changed shape.

Summary

Fixes #5843. resolve_adb_packages now retains unrecognized package-inventory rows exactly like list_adb_packages: the first ten as unparsed_lines, the exact total in a limitation when more were seen, and partial coverage. The truncation limitation can no longer appear without the field it describes.

Problem and expected behavior

Trigger: any pm list packages -f output with one non-package: line. The documented contract (adb-device-analysis.md, "Partial results keep facts") says listings expose such lines as unparsed_lines. The resolver computed coverage and reused the overflow-limitation helper from the raw parser array, but never projected the lines, and its strict result schema had no field for them. The cause: the sample (reported) and its limitation (unparsedOverflowLimitation) were two independent helpers that each call site had to pair by hand.

Change and scope

  • src/adb/AdbUnparsedLines.ts: AdbUnparsedLines { sample, total } with a collector that keeps at most ten lines while counting all. Every ADB parser that records unrecognized lines (devices, package list, pm path, processes, directory, features, services) returns it, so the parsers no longer hold unbounded arrays.
  • AdbProvider: reported and unparsedOverflowLimitation are replaced by one parsedListingExecution projection. It writes unparsed_lines, coverage and the truncation limitation from the same facts. Every parsed listing and resolve_adb_packages uses it. Fail-closed consumers (list_adb_devices, pm path) still refuse on the first unrecognized line.
  • resolve_adb_packages result schema: adds unparsed_lines: string[] (CLI and MCP share the contract).
  • Docs: the partial-result bullet now covers package searches and the ten-line bound.
  • Not included: a structured total-count field. The exact total stays in the existing limitation text for all listings, so sibling contracts do not change.

Contribution scope: ordinary fix within an existing read-only boundary; maintainer scope decision not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: ADB output parsers (src/adb/AdbDeviceOutput.ts, AdbShellOutput.ts, AdbDirectoryListing.ts) own unrecognized-line facts; the provider projection owns the result/limitation pairing.

  • Contribution scope fit and linked maintainer decision: fix within existing ADB read operations; not applicable.

  • CLI and MCP/tool-catalog contract: resolve_adb_packages output schema gains the required unparsed_lines array (additive for consumers). Other ADB outputs are unchanged.

  • Provider, bridge, target-format, or platform compatibility: none; same adb commands and arguments.

  • Evidence, artifact, provenance, or reconstruction contract: resolver Evidence now retains the sampled source rows that justify its partial coverage.

  • Target selection, authority, upstream behavior, and cleanup details: unchanged.

  • Generated metadata, package, or installation impact: catalog regenerates from the schema; docs:check and metadata:check pass.

  • Read existing files or captured data.

  • Launch or attach to a process.

  • Inject instrumentation or run scripts/code.

  • Change process memory, registers, files, or configuration.

  • Contact network services.

  • Recover protected code or work around protections.

  • Documentation or usability only; no target interaction.

  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:

    • New tests/acceptance/applications/adbPackageInventoryCoverage.test.ts: built CLI and stdio MCP against a fake adb, with 0, 1 and 11 unrecognized rows. It checks resolve-adb-packages and list-adb-packages unparsed_lines, coverage and limitations, that a limitation naming unparsed_lines appears only when the field is truncated, and that MCP resolve_adb_packages structured output (validated against the advertised schema) equals the CLI Evidence. On base source it fails at the first scenario (resolve-adb-packages 0: unparsed_lines absent). This was executed by stashing the source changes.
    • Parser test for the ten-line sample plus exact total; updated parser and MCP fixture expectations for the new shape and field.
  • Base reproduction (executed on origin/main f801b2fbf with the issue's fake-adb driver, isolated HOME/XDG, --json --full-output):

    {"command": "resolve-adb-packages", "rows": 1, "coverage": "partial", "unparsed_lines": "<absent>", "limitations": []}
    {"command": "resolve-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "<absent>", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]}
    {"command": "list-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines]", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]}
    
  • After (same driver on this branch):

    {"command": "resolve-adb-packages", "rows": 0, "coverage": "complete", "unparsed_lines": [], "limitations": []}
    {"command": "resolve-adb-packages", "rows": 1, "coverage": "partial", "unparsed_lines": ["unrecognized package row 1"], "limitations": []}
    {"command": "resolve-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines: 'unrecognized package row 1' .. 'unrecognized package row 10']", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]}
    {"command": "list-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines: 'unrecognized package row 1' .. 'unrecognized package row 10']", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]}
    
  • User-visible output: default rea resolve-adb-packages emulator-5554 example --json with 11 rows is 1,621 bytes, including the ten sampled rows. A complete inventory adds only "unparsed_lines":[]. Token counts were not measured.

  • Remaining proof gaps: adb was simulated by a fake script; no Android device or emulator was used. Fail-closed pm path / adb devices behavior was covered only by the existing unit tests.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • Issue repro driver (fake adb, built CLI) on base and on this branch — reproduced on base; fixed as shown above.
  • npm run test:local -- src/adb/AdbDeviceOutput.test.ts src/adb/AdbProvider.test.ts src/adb/AdbShellOutput.test.ts src/adb/AdbCommand.test.ts — 4 files, 146 tests passed.
  • npm run test:focused -- tests/boundary/process/adbDirectoryListing.test.ts tests/boundary/mcp/adbMcp.test.ts tests/acceptance/applications/adbPackageInventoryCoverage.test.ts tests/acceptance/applications/adbErrorIdentity.test.ts — 4 files, 7 tests passed.
  • npm run test:focused -- tests/acceptance/applications/adbPackageInventoryCoverage.test.ts with source changes stashed (base behavior) — failed as expected.
  • npm run check:fast — passed.
  • npm run format:check — passed.
  • npm run docs:check — passed.
  • npm run metadata:check — passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: none; resolve_adb_packages gains an output field.
  • Real Hopper/Ghidra, browser, or OS coverage: macOS (darwin arm64) only, with simulated adb; no real device.
  • Package or release metadata impact: none beyond regenerated catalog schema.
  • Security, privacy, process, or containment review: no new commands, arguments, or side effects; retained rows are bounded to ten.

Author readiness

Human owner: @kaoru0822-kitauji

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5874 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/21/2026 **Status:** ✅ Merged **Merged:** 10/21/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/adb-package-unparsed-lines` --- ### 📝 Commits (2) - [`c68a6df`](https://github.com/morluto/rea/commit/c68a6df8c6788d72f370410cfef1fc08a1305f90) fix(adb): report unrecognized package rows from resolve-adb-packages - [`fdd5fde`](https://github.com/morluto/rea/commit/fdd5fde9c4289ac8e8eefe73b49fd4704a0cef81) Merge remote-tracking branch 'origin/main' into fix/adb-package-unparsed-lines ### 📊 Changes **12 files changed** (+280 additions, -127 deletions) <details> <summary>View changed files</summary> 📝 `docs/adb-device-analysis.md` (+3 -2) 📝 `src/adb/AdbDeviceOutput.test.ts` (+34 -16) 📝 `src/adb/AdbDeviceOutput.ts` (+20 -16) 📝 `src/adb/AdbDirectoryListing.ts` (+11 -6) 📝 `src/adb/AdbProvider.test.ts` (+1 -0) 📝 `src/adb/AdbProvider.ts` (+59 -72) 📝 `src/adb/AdbShellOutput.ts` (+18 -14) ➕ `src/adb/AdbUnparsedLines.ts` (+27 -0) 📝 `src/domain/adb/adbDeviceAnalysis.ts` (+1 -0) ➕ `tests/acceptance/applications/adbPackageInventoryCoverage.test.ts` (+104 -0) 📝 `tests/boundary/mcp/adbMcp.test.ts` (+1 -0) 📝 `tests/boundary/process/adbDirectoryListing.test.ts` (+1 -1) </details> ### 📄 Description **What broke:** `resolve_adb_packages` marked `coverage: "partial"` when `pm list packages -f` printed unrecognized rows but dropped those rows, and with more than ten rows its limitation named an `unparsed_lines` field the result never carried. **Fix:** ADB parsers now own unrecognized-line facts (first ten verbatim plus the exact total); one provider projection derives `unparsed_lines`, coverage, and the truncation limitation for every parsed listing and the package search, and the resolver schema now carries `unparsed_lines`. **Risk:** Low; additive output field on one operation. Sibling listings keep their existing output and limitation text; parser internals changed shape. ## Summary Fixes #5843. `resolve_adb_packages` now retains unrecognized package-inventory rows exactly like `list_adb_packages`: the first ten as `unparsed_lines`, the exact total in a limitation when more were seen, and partial coverage. The truncation limitation can no longer appear without the field it describes. ## Problem and expected behavior Trigger: any `pm list packages -f` output with one non-`package:` line. The documented contract ([adb-device-analysis.md](https://github.com/morluto/rea/blob/main/docs/adb-device-analysis.md), "Partial results keep facts") says listings expose such lines as `unparsed_lines`. The resolver computed coverage and reused the overflow-limitation helper from the raw parser array, but never projected the lines, and its strict result schema had no field for them. The cause: the sample (`reported`) and its limitation (`unparsedOverflowLimitation`) were two independent helpers that each call site had to pair by hand. ## Change and scope - `src/adb/AdbUnparsedLines.ts`: `AdbUnparsedLines { sample, total }` with a collector that keeps at most ten lines while counting all. Every ADB parser that records unrecognized lines (devices, package list, `pm path`, processes, directory, features, services) returns it, so the parsers no longer hold unbounded arrays. - `AdbProvider`: `reported` and `unparsedOverflowLimitation` are replaced by one `parsedListingExecution` projection. It writes `unparsed_lines`, `coverage` and the truncation limitation from the same facts. Every parsed listing and `resolve_adb_packages` uses it. Fail-closed consumers (`list_adb_devices`, `pm path`) still refuse on the first unrecognized line. - `resolve_adb_packages` result schema: adds `unparsed_lines: string[]` (CLI and MCP share the contract). - Docs: the partial-result bullet now covers package searches and the ten-line bound. - Not included: a structured total-count field. The exact total stays in the existing limitation text for all listings, so sibling contracts do not change. Contribution scope: ordinary fix within an existing read-only boundary; maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: ADB output parsers (`src/adb/AdbDeviceOutput.ts`, `AdbShellOutput.ts`, `AdbDirectoryListing.ts`) own unrecognized-line facts; the provider projection owns the result/limitation pairing. - Contribution scope fit and linked maintainer decision: fix within existing ADB read operations; not applicable. - CLI and MCP/tool-catalog contract: `resolve_adb_packages` output schema gains the required `unparsed_lines` array (additive for consumers). Other ADB outputs are unchanged. - Provider, bridge, target-format, or platform compatibility: none; same adb commands and arguments. - Evidence, artifact, provenance, or reconstruction contract: resolver Evidence now retains the sampled source rows that justify its partial coverage. - Target selection, authority, upstream behavior, and cleanup details: unchanged. - Generated metadata, package, or installation impact: catalog regenerates from the schema; `docs:check` and `metadata:check` pass. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - New `tests/acceptance/applications/adbPackageInventoryCoverage.test.ts`: built CLI and stdio MCP against a fake `adb`, with 0, 1 and 11 unrecognized rows. It checks `resolve-adb-packages` and `list-adb-packages` `unparsed_lines`, coverage and limitations, that a limitation naming `unparsed_lines` appears only when the field is truncated, and that MCP `resolve_adb_packages` structured output (validated against the advertised schema) equals the CLI Evidence. **On base source it fails** at the first scenario (`resolve-adb-packages 0`: `unparsed_lines` absent). This was executed by stashing the source changes. - Parser test for the ten-line sample plus exact total; updated parser and MCP fixture expectations for the new shape and field. - Base reproduction (executed on `origin/main` f801b2fbf with the issue's fake-`adb` driver, isolated HOME/XDG, `--json --full-output`): ```jsonl {"command": "resolve-adb-packages", "rows": 1, "coverage": "partial", "unparsed_lines": "<absent>", "limitations": []} {"command": "resolve-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "<absent>", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]} {"command": "list-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines]", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]} ``` - After (same driver on this branch): ```jsonl {"command": "resolve-adb-packages", "rows": 0, "coverage": "complete", "unparsed_lines": [], "limitations": []} {"command": "resolve-adb-packages", "rows": 1, "coverage": "partial", "unparsed_lines": ["unrecognized package row 1"], "limitations": []} {"command": "resolve-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines: 'unrecognized package row 1' .. 'unrecognized package row 10']", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]} {"command": "list-adb-packages", "rows": 11, "coverage": "partial", "unparsed_lines": "[10 lines: 'unrecognized package row 1' .. 'unrecognized package row 10']", "limitations": ["unparsed_lines reports the first 10 of 11 unrecognized lines"]} ``` - User-visible output: default `rea resolve-adb-packages emulator-5554 example --json` with 11 rows is 1,621 bytes, including the ten sampled rows. A complete inventory adds only `"unparsed_lines":[]`. Token counts were not measured. - Remaining proof gaps: `adb` was simulated by a fake script; no Android device or emulator was used. Fail-closed `pm path` / `adb devices` behavior was covered only by the existing unit tests. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - Issue repro driver (fake `adb`, built CLI) on base and on this branch — reproduced on base; fixed as shown above. - `npm run test:local -- src/adb/AdbDeviceOutput.test.ts src/adb/AdbProvider.test.ts src/adb/AdbShellOutput.test.ts src/adb/AdbCommand.test.ts` — 4 files, 146 tests passed. - `npm run test:focused -- tests/boundary/process/adbDirectoryListing.test.ts tests/boundary/mcp/adbMcp.test.ts tests/acceptance/applications/adbPackageInventoryCoverage.test.ts tests/acceptance/applications/adbErrorIdentity.test.ts` — 4 files, 7 tests passed. - `npm run test:focused -- tests/acceptance/applications/adbPackageInventoryCoverage.test.ts` with source changes stashed (base behavior) — failed as expected. - `npm run check:fast` — passed. - `npm run format:check` — passed. - `npm run docs:check` — passed. - `npm run metadata:check` — passed. ## Compatibility, safety, and release - Breaking changes or migration steps: none; `resolve_adb_packages` gains an output field. - Real Hopper/Ghidra, browser, or OS coverage: macOS (darwin arm64) only, with simulated `adb`; no real device. - Package or release metadata impact: none beyond regenerated catalog schema. - Security, privacy, process, or containment review: no new commands, arguments, or side effects; retained rows are bounded to ten. ## Author readiness Human owner: @kaoru0822-kitauji - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:45:21 +00:00
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#7095
No description provided.