OpenRemap Docs

0.7.2 — 2026-08-25

The full-picture release — unified analyze workflow, real Intel HEX / S-Record input, VIN decoding, fuzzy family lookup, faster recipe parsing, and dead-dependency cleanup.

Added

  • openremap analyze command — the unified full-picture workflow (roadmap item 10): one pass describes a whole ECU binary — container (raw / Intel HEX / S-Record), identity + confidence, VIN candidate, flash-layout regions, map discovery (axes/tables, top-5), checksum status (ME7 / Denso / swept schemes), and the six-check health verdict. Composes existing services (no new detection logic, no new dependencies); the map scan feeds segment() so layout costs no extra pass. --fast (~1–2 s) skips maps + checksums + health; --no-maps skips only the map scan; --json emits the sectioned report (tables capped at 50 by score). Descriptive — exit 0 even with warnings; health remains the CI-gateable verdict. Measured on the real 4 MB EDC17 stock: full ~14 s, --fast ~1 s. identify gained the container display (Container / Byte Order / Cell Size rows + JSON container field) — facts that were already computed but hidden.

  • VIN decoding (vininfo) — every VIN candidate the scanner finds is now decoded: WMI → manufacturer, region, country, model years, plus the ISO 3779 check digit. Surfaced in scan-vins (new decoded column + JSON fields), health (decoded make next to reported VINs), and identify (a separate VIN candidate section + vin JSON field, shown only for a top candidate ≥ 0.6 — measured floor: 2/1,871 corpus files qualify, so VIN-less dumps stay clean). Decoded names are labelled decoded, unverified (community database, US/EU-centric); decoding is permissive — unknown WMIs yield decoded: false, malformed input never errors. Backed by vininfo 1.11 (BSD-3, pure Python).

  • Fuzzy family lookup (rapidfuzz)openremap families --family now prints "Closest families: …" suggestions with scores when the name or alias doesn't match exactly (edc16cEDC16 — 91%, EDC1 / EDC2 — 90%, …). Exact matching is unchanged; exit code stays 1 on a miss. Backed by rapidfuzz 3.14 (MIT, compiled C++ — wheels for every platform).

  • Real Intel HEX / Motorola S-Record input — binary inputs are now sniffed by content (not extension): files starting with : parse as Intel HEX, S+type-digit as S-Record, everything else stays a raw dump (the Subaru/RomRaider raw-.hex convention is byte-identical). Parsing validates per-record checksums, base-normalises addresses, and fills gaps with 0xFF (erased flash) with a warning. Corrupt record-shaped files are loud errors; a raw dump that happens to start with :/S but does not parse falls back to raw with a warning. Backed by bincopy (20.1.1, MIT, pure Python — universal wheel, no platform work). Every binary-reading command (identify, cook, cook-volatile, tune, validate, audit, diff-maps, scan-maps, layout, scan-vins, checksum, health, merge --stock, scan, TUI) routes through the shared loader; the .s19/.srec/.mot extensions join the advisory set.

  • openremap convert command — normalise any binary image to flat bytes: convert boot.hex -o boot.bin, with --format auto|ihex|srec|bin (strict override), --json summary (format, address range, segments, warnings), default <stem>.bin output. Verified end-to-end on the real 4 MB EDC17 stock: HEX and S-Record round-trips are byte-identical and identify/cook results match the raw-binary run.

  • orjson for recipe JSON parsing — the recipe-load paths in tune, validate, merge, audit, diff-maps and the TUI now parse JSON with orjson (faster, spec-strict). Serialization is intentionally left on the stdlib json module everywhere: recipe files and JSON reports must stay byte-stable (stdlib float formatting, inf handling, and pretty-print output are all part of the on-disk contract), and the recipe fingerprint in recipe_builder.py is a stability contract. orjson.JSONDecodeError is a subclass of json.JSONDecodeError, so all existing error handlers are unchanged.

  • Measured (real 153 KB EDC17 recipe): orjson.loads 0.257 ms vs stdlib 0.926 ms — 3.6× faster per recipe load (~0.7 ms saved per tune/validate/audit/merge/diff-maps invocation). Full 0.7.2 suite: 5883 passed, 12 skipped, 1 xfailed; end-to-end check: a cooked recipe applied via tune reproduces the real tuned binary byte-for-byte.

  • Platform verification — the crate compiles for all four release targets: Linux glibc (uv buildcp310-abi3 wheel + sdist), musllinux/Alpine (maturin --zigmusllinux_1_2_x86_64 wheel, .so links musl libc.so), Windows (cargo check --target x86_64-pc-windows-gnu), macOS (cargo check --target aarch64-apple-darwin). orjson 3.12.0 ships prebuilt wheels for every platform/Python in the matrix (manylinux, musllinux, win, macos — cp310–cp314), so it never needs to compile on a target. Full wheels for Windows/macOS are produced by the existing release.yml matrix.

Removed

  • Unused pydantic dependency — the last Pydantic models were deleted from the codebase on 2026-08-13; pydantic and its pydantic-core compiled wheel were still declared in pyproject.toml. Zero imports remain — dropped from the dependency list and the lockfile.