[PR #3485] [MERGED] fix(adb)!: keep the exact Android long version code #5771

Closed
opened 2026-10-31 01:09:19 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

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

Base: main ← Head: fix/adb-package-version-code-exact


📝 Commits (1)

  • b2c3816 fix(adb)!: keep the exact Android long version code

📊 Changes

4 files changed (+38 additions, -7 deletions)

View changed files

📝 src/adb/AdbProvider.test.ts (+25 -1)
📝 src/adb/AdbShellOutput.ts (+5 -4)
📝 src/domain/adb/adbDeviceAnalysis.ts (+7 -1)
📝 tests/boundary/mcp/adbMcp.test.ts (+1 -1)

📄 Description

Summary

inspect_adb_package rounded Android long version codes above 2^53 and dropped negative ones. It now returns version_code as the exact decimal string that dumpsys package prints.

Fixes #3368

Problem and expected behavior

dumpsys package prints versionCode= from PackageInfo.getLongVersionCode(), a signed 64-bit long (versionCodeMajor << 32 | versionCode). parseDumpsysPackageOutput passed it through Number():

  • 9007199254740993 became 9007199254740992, with the same Evidence ID as a real 9007199254740992, while still reported as observed / complete.
  • -1 didn't match ^\d+, so it came back as null with coverage: "complete".

The observation should keep the exact value Package Manager reported.

Change and scope

  • AdbShellOutput.parseDumpsysPackageOutput keeps the matched -?\d+ spelling instead of converting it to a number.
  • adbResultSchemas.inspect_adb_package.version_code is now string | null (^-?\d+$). This matches the apktool and JADX version_code contracts, which are already exact strings.
  • Not included: user_id stays numeric because Linux UIDs fit in 32 bits.

Contribution scope: an ordinary fix within existing boundaries, so no maintainer scope decision is needed.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/adb/AdbShellOutput.ts, which parses the dumpsys text.

  • Contribution scope fit and linked maintainer decision: not applicable (ordinary fix).

  • CLI and MCP/tool-catalog contract: the inspect_adb_package output schema changes version_code from integer to decimal string. This is breaking (see below).

  • Provider, bridge, target-format, or platform compatibility: none.

  • Evidence, artifact, provenance, or reconstruction contract: different long version codes now produce different results and Evidence IDs.

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

  • Generated metadata: npm run docs:generate ran and changed no tracked files.

  • Read existing files or captured data.

Evidence and regression coverage

  • Tests added or updated: src/adb/AdbProvider.test.ts gains keeps the long version code %s exactly as dumpsys prints it for 9007199254740993 and -4294967296, run through the real provider and a stub adb binary. The existing package-detail test and tests/boundary/mcp/adbMcp.test.ts now expect "45".
  • Base reproduction: with the source change reverted, the new cases and the updated package-detail test fail (3 failures).
  • User-visible CLI output: the reproduction from #3368, a fake adb running the built CLI inspect-adb-package probe-device com.example.app --format json:
dumpsys versionCode= main version_code this PR
45 45 "45"
9007199254740991 9007199254740991 "9007199254740991"
9007199254740992 9007199254740992 (ev_6f25af9e…) "9007199254740992" (ev_257085fd…)
9007199254740993 9007199254740992 (ev_6f25af9e…, collision) "9007199254740993" (ev_95988cc5…)
-1 null "-1"
  • Remaining proof gaps: no live Android device or real adb was available. The fixture models only the dumpsys package text.

  • 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

  • npm run test:local -- src/adb/AdbProvider.test.ts src/adb/AdbShellOutput.test.ts: 67 passed
  • npm run test:focused -- tests/boundary/mcp/adbMcp.test.ts: 2 passed
  • npm run check:fast: passed
  • npm run docs:generate then npm run docs:check: passed, no tracked changes
  • Built CLI reproduction from #3368: table above

Compatibility, safety, and release

  • Breaking changes or migration steps: version_code was 45 and is now "45". Callers that compare numerically should parse it with BigInt(version_code). A JSON number cannot keep the value exactly, and an int/string union would make every consumer branch on type, so the field is a string, like the apktool and JADX outputs.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable. No real device was used.
  • Package or release metadata impact: none beyond the ! changelog entry.
  • Security, privacy, process, or containment review: no change in what runs on the device.
  • Cost: unchanged runtime. Output grows by two quote characters.

Author readiness

Human owner:

  • 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/3485 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/14/2026 **Status:** ✅ Merged **Merged:** 10/15/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/adb-package-version-code-exact` --- ### 📝 Commits (1) - [`b2c3816`](https://github.com/morluto/rea/commit/b2c3816c9095515ad1d149b7e8429f63493ef27a) fix(adb)!: keep the exact Android long version code ### 📊 Changes **4 files changed** (+38 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `src/adb/AdbProvider.test.ts` (+25 -1) 📝 `src/adb/AdbShellOutput.ts` (+5 -4) 📝 `src/domain/adb/adbDeviceAnalysis.ts` (+7 -1) 📝 `tests/boundary/mcp/adbMcp.test.ts` (+1 -1) </details> ### 📄 Description ## Summary `inspect_adb_package` rounded Android long version codes above 2^53 and dropped negative ones. It now returns `version_code` as the exact decimal string that `dumpsys package` prints. Fixes #3368 ## Problem and expected behavior `dumpsys package` prints `versionCode=` from `PackageInfo.getLongVersionCode()`, a signed 64-bit long (`versionCodeMajor << 32 | versionCode`). `parseDumpsysPackageOutput` passed it through `Number()`: - `9007199254740993` became `9007199254740992`, with the same Evidence ID as a real `9007199254740992`, while still reported as `observed` / `complete`. - `-1` didn't match `^\d+`, so it came back as `null` with `coverage: "complete"`. The observation should keep the exact value Package Manager reported. ## Change and scope - `AdbShellOutput.parseDumpsysPackageOutput` keeps the matched `-?\d+` spelling instead of converting it to a number. - `adbResultSchemas.inspect_adb_package.version_code` is now `string | null` (`^-?\d+$`). This matches the apktool and JADX `version_code` contracts, which are already exact strings. - Not included: `user_id` stays numeric because Linux UIDs fit in 32 bits. Contribution scope: an ordinary fix within existing boundaries, so no maintainer scope decision is needed. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/adb/AdbShellOutput.ts`, which parses the dumpsys text. - Contribution scope fit and linked maintainer decision: not applicable (ordinary fix). - CLI and MCP/tool-catalog contract: the `inspect_adb_package` output schema changes `version_code` from integer to decimal string. This is breaking (see below). - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: different long version codes now produce different results and Evidence IDs. - Target selection, authority, upstream behavior, and cleanup details: unchanged. - Generated metadata: `npm run docs:generate` ran and changed no tracked files. - [x] Read existing files or captured data. ## Evidence and regression coverage - Tests added or updated: `src/adb/AdbProvider.test.ts` gains `keeps the long version code %s exactly as dumpsys prints it` for `9007199254740993` and `-4294967296`, run through the real provider and a stub adb binary. The existing package-detail test and `tests/boundary/mcp/adbMcp.test.ts` now expect `"45"`. - Base reproduction: with the source change reverted, the new cases and the updated package-detail test fail (3 failures). - User-visible CLI output: the reproduction from #3368, a fake `adb` running the built CLI `inspect-adb-package probe-device com.example.app --format json`: | dumpsys `versionCode=` | main `version_code` | this PR | |---|---|---| | `45` | `45` | `"45"` | | `9007199254740991` | `9007199254740991` | `"9007199254740991"` | | `9007199254740992` | `9007199254740992` (ev_6f25af9e…) | `"9007199254740992"` (ev_257085fd…) | | `9007199254740993` | `9007199254740992` (ev_6f25af9e…, collision) | `"9007199254740993"` (ev_95988cc5…) | | `-1` | `null` | `"-1"` | - Remaining proof gaps: no live Android device or real `adb` was available. The fixture models only the `dumpsys package` text. - [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 - `npm run test:local -- src/adb/AdbProvider.test.ts src/adb/AdbShellOutput.test.ts`: 67 passed - `npm run test:focused -- tests/boundary/mcp/adbMcp.test.ts`: 2 passed - `npm run check:fast`: passed - `npm run docs:generate` then `npm run docs:check`: passed, no tracked changes - Built CLI reproduction from #3368: table above ## Compatibility, safety, and release - Breaking changes or migration steps: `version_code` was `45` and is now `"45"`. Callers that compare numerically should parse it with `BigInt(version_code)`. A JSON number cannot keep the value exactly, and an int/string union would make every consumer branch on type, so the field is a string, like the apktool and JADX outputs. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. No real device was used. - Package or release metadata impact: none beyond the `!` changelog entry. - Security, privacy, process, or containment review: no change in what runs on the device. - Cost: unchanged runtime. Output grows by two quote characters. ## Author readiness Human owner: <!-- @GitHub-handle --> - [ ] 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](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-10-31 01:09:19 +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#5771
No description provided.