[PR #5223] [CLOSED] fix(flutter): select an ABI by the lib/ label discovery reports #6820

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5223
Author: @Yi-111-a
Created: 10/19/2026
Status: ❌ Closed

Base: main ← Head: fix/flutter-abi-selector-label


📝 Commits (2)

  • d700fc2 fix(flutter): select an ABI by the lib/ label discovery reports
  • b9ccd2a fix(flutter): bound the ABI selector by the inventory path budget

📊 Changes

5 files changed (+190 additions, -18 deletions)

View changed files

📝 docs/flutter-analysis.md (+3 -1)
📝 src/cli/flutterCommands.ts (+5 -5)
📝 src/domain/flutter/flutterBuildAnalysis.ts (+50 -8)
📝 src/flutter/FlutterBuildProvider.ts (+6 -4)
➕ tests/boundary/flutter/reportedAbiSelection.test.ts (+126 -0)

📄 Description

Problem

inspect_dart_aot refused an explicit --abi unless it was 2–16 lowercase letters (/^[a-z0-9_]+$/), but identify_flutter_build reports the literal lib/<abi>/ directory label it read. A payload under any other label — ARM64-V8A, arm64.v8a, armeabi-eabi, A — could be reported yet never selected.

In a paired APK the omission silently selects a different payload, so the caller cannot recover the intended one at all.

Refs #5219, and the advertised-schema half of #5217.

Approach

The selector now takes the grammar discovery already reads — one archive path segment (^lib/([^/]+)/(libapp|libflutter).so$), neither empty nor a separator or control character — instead of a lowercase subset of it.

Selection remains an exact match against the labels discovery reported (candidates.find((candidate) => candidate.abi === abi)), so widening the selector cannot reach a payload that was not already found, and the selected label is preserved in the result.

  • src/domain/flutter/flutterBuildAnalysis.ts — one exported abiSelectorSchema owning the selector grammar and its bound, shared by the canonical input schema. The 1024-byte archive-path budget moves here from the provider so the two cannot drift: the selector bound is derived from it (floor((1024 - 18) / 3) = 335 code units, using the worst case of 3 UTF-8 bytes per UTF-16 code unit) rather than from NAME_MAX. Extraction writes the fixed member name, so no extracted file ever carries the label.
  • src/flutter/FlutterBuildProvider.ts — imports MAX_FLUTTER_LIBRARY_PATH_BYTES from the domain module instead of declaring a private copy.
  • src/cli/flutterCommands.ts — the CLI option schema reuses that schema instead of redeclaring only .min(2).max(16), so the emitted --schema carries the character constraint rather than advertising a grammar admission does not enforce.
  • docs/flutter-analysis.md — states that an explicit abi is the label exactly as identify_flutter_build reports it.

Bounds moved from 2..16 to 1..335, one archive path segment within the inventory's own path budget. 1 matches discovery ([^/]+).

Evidence

  • npx tsc --noEmit -p tsconfig.json — clean.
  • npm run check:fast (cached typecheck + lint; oxfmt/oxlint pre-commit) — 2/2 tasks successful.
  • npx vitest run tests/boundary/flutter src/flutter src/domain/flutter src/cli — 6 files, 73 passed. tests/boundary/flutter/reportedAbiSelection.test.ts drives the production Flutter provider over real APK fixtures: a lib/ARM64-V8A/libapp.so inventory reports ["ARM64-V8A", "x86_64"], explicit abi: "ARM64-V8A" succeeds with the label preserved and the a snapshot hash, default selection still returns the x86_64/b payload, and the sole-library fixture returns the same payload explicitly and by default. A third case builds an APK under a 256-character label — past NAME_MAX, inside the inventory budget — and asserts the inventory reports it, explicit inspection selects it, and the schema admits it; that case fails against the previous .max(255) bound. Schema cases pin the accepted and refused spellings ("", lib/x86_64, ..\x86_64, and a label carrying an embedded NUL stay refused).
  • npx vitest run tests/boundary/mcp/dartAotSummaryMcp.test.ts — 3 passed (explicit-ABI MCP coverage and SDK schema validation).
  • npx prettier --check on the three touched sources — clean.

Not run: npm run docs:check and the compiled-CLI acceptance suites. This environment has Node v20.19.2 while .nvmrc pins 24.18.0, and docs:check loads node:sqlite. The compiled-CLI path is covered by the shared abiSelectorSchema, but no compiled-CLI run was executed here.

Author readiness

Left for the human owner to complete, per CONTRIBUTING.md#pull-request-ownership-and-readiness.


🔄 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/5223 **Author:** [@Yi-111-a](https://github.com/Yi-111-a) **Created:** 10/19/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/flutter-abi-selector-label` --- ### 📝 Commits (2) - [`d700fc2`](https://github.com/morluto/rea/commit/d700fc21bd27a132297d61c8d9ff06f01b068106) fix(flutter): select an ABI by the lib/ label discovery reports - [`b9ccd2a`](https://github.com/morluto/rea/commit/b9ccd2a349922cd3e354baac5234febe9823c956) fix(flutter): bound the ABI selector by the inventory path budget ### 📊 Changes **5 files changed** (+190 additions, -18 deletions) <details> <summary>View changed files</summary> 📝 `docs/flutter-analysis.md` (+3 -1) 📝 `src/cli/flutterCommands.ts` (+5 -5) 📝 `src/domain/flutter/flutterBuildAnalysis.ts` (+50 -8) 📝 `src/flutter/FlutterBuildProvider.ts` (+6 -4) ➕ `tests/boundary/flutter/reportedAbiSelection.test.ts` (+126 -0) </details> ### 📄 Description ## Problem `inspect_dart_aot` refused an explicit `--abi` unless it was 2–16 lowercase letters (`/^[a-z0-9_]+$/`), but `identify_flutter_build` reports the literal `lib/<abi>/` directory label it read. A payload under any other label — `ARM64-V8A`, `arm64.v8a`, `armeabi-eabi`, `A` — could be *reported* yet never *selected*. In a paired APK the omission silently selects a *different* payload, so the caller cannot recover the intended one at all. Refs #5219, and the advertised-schema half of #5217. ## Approach The selector now takes the grammar discovery already reads — one archive path segment (`^lib/([^/]+)/(libapp|libflutter).so$`), neither empty nor a separator or control character — instead of a lowercase subset of it. Selection remains an exact match against the labels discovery reported (`candidates.find((candidate) => candidate.abi === abi)`), so widening the selector cannot reach a payload that was not already found, and the selected label is preserved in the result. - `src/domain/flutter/flutterBuildAnalysis.ts` — one exported `abiSelectorSchema` owning the selector grammar and its bound, shared by the canonical input schema. The 1024-byte archive-path budget moves here from the provider so the two cannot drift: the selector bound is derived from it (`floor((1024 - 18) / 3)` = 335 code units, using the worst case of 3 UTF-8 bytes per UTF-16 code unit) rather than from `NAME_MAX`. Extraction writes the fixed member name, so no extracted file ever carries the label. - `src/flutter/FlutterBuildProvider.ts` — imports `MAX_FLUTTER_LIBRARY_PATH_BYTES` from the domain module instead of declaring a private copy. - `src/cli/flutterCommands.ts` — the CLI option schema reuses that schema instead of redeclaring only `.min(2).max(16)`, so the emitted `--schema` carries the character constraint rather than advertising a grammar admission does not enforce. - `docs/flutter-analysis.md` — states that an explicit `abi` is the label exactly as `identify_flutter_build` reports it. Bounds moved from `2..16` to `1..335`, one archive path segment within the inventory's own path budget. `1` matches discovery (`[^/]+`). ## Evidence - `npx tsc --noEmit -p tsconfig.json` — clean. - `npm run check:fast` (cached typecheck + lint; oxfmt/oxlint pre-commit) — 2/2 tasks successful. - `npx vitest run tests/boundary/flutter src/flutter src/domain/flutter src/cli` — 6 files, 73 passed. `tests/boundary/flutter/reportedAbiSelection.test.ts` drives the production Flutter provider over real APK fixtures: a `lib/ARM64-V8A/libapp.so` inventory reports `["ARM64-V8A", "x86_64"]`, explicit `abi: "ARM64-V8A"` succeeds with the label preserved and the `a` snapshot hash, default selection still returns the `x86_64`/`b` payload, and the sole-library fixture returns the same payload explicitly and by default. A third case builds an APK under a 256-character label — past `NAME_MAX`, inside the inventory budget — and asserts the inventory reports it, explicit inspection selects it, and the schema admits it; that case fails against the previous `.max(255)` bound. Schema cases pin the accepted and refused spellings (`""`, `lib/x86_64`, `..\x86_64`, and a label carrying an embedded NUL stay refused). - `npx vitest run tests/boundary/mcp/dartAotSummaryMcp.test.ts` — 3 passed (explicit-ABI MCP coverage and SDK schema validation). - `npx prettier --check` on the three touched sources — clean. Not run: `npm run docs:check` and the compiled-CLI acceptance suites. This environment has Node v20.19.2 while `.nvmrc` pins 24.18.0, and `docs:check` loads `node:sqlite`. The compiled-CLI path is covered by the shared `abiSelectorSchema`, but no compiled-CLI run was executed here. ## Author readiness Left for the human owner to complete, per `CONTRIBUTING.md#pull-request-ownership-and-readiness`. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:43:16 +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#6820
No description provided.