Why this cycle
v0.14.4 was the “Story coverage” cycle. The headline work was a 52-test suite for the diagnostic-story generator (src-tauri/src/story.rs) and the anonymiser (src-tauri/src/anonymize.rs). Before this cycle, both modules had zero test coverage. After, they have 52 tests and a deterministic coverage of the public surface.
The motivation: the story generator is the user-facing surface for sharing diagnostic data. People export anonymised snapshots to share with friends, forums, and indie shops. Without test coverage, every change to the story format was a chance to break the user-facing contract.
The 52 tests
The 52 tests break down as 32 for story.rs and 20 for anonymize.rs.
story.rs (32 tests)
- Severity bucketing + ordering — 4 tests. Verifies the severity buckets sort predictably and the priority ordering is stable.
parse_cost_range— 6 tests. Handling single values, tilde, hyphen, en-dash, whitespace, empty, and garbage. The cost range format is the source of the most user-visible output; getting it right matters.format_vehicle— 4 tests. Across empty, VIN-only, mileage-only, and decoded inputs.build_context— 3 tests. Freeze-frame string assembly.- The full
generate()pipeline — 8 tests. Against the live community knowledge base; cost range sum, cost-max invariant, DTC code case-insensitive lookup, summary text counts, title format. - Property tests — 7 tests. Severity bucket assignment, cost-max invariant across random inputs, DID decoder stability.
anonymize.rs (20 tests)
hash_vinproperties — 4 tests. 16 hex chars, stable across calls, distinct across inputs, case-sensitive (pinned as an invariant test).- The full
anonymize()pipeline — 10 tests. VIN never leaks, fingerprint substitution, missing VIN tounknownfingerprint,engine_familypreserved, modules / DTCs / freeze frames preserved, mileage stripped, empty modules,fault_countNone to 0,live_dataalways empty. export_json— 6 tests. No VIN / mileage leak, pretty-printed, serde round-trip.
Test count went from 149 to 201 in cargo test --lib --offline.
The audit
The v0.14.4 cycle plan also included a CLAUDE.md refresh. Four stale “NOT YET IMPLEMENTED” / “migration in progress” claims were wrong against main. The PR refreshed them to “INVARIANT — enforced” with citations:
- Async commands: migration complete (24 sync
#[tauri::command]are in-memory / local-fs helpers gated bytests/async_commands.rs::SYNC_ALLOWLIST). - Tester Present keep-alive: shipped in
src-tauri/src/keepalive.rs(3000 ms interval,[0x3E, 0x00]frame). - ISO-TP multi-frame: shipped in
src-tauri/src/transport/isotp.rs(430 LOC, FF/CF/FC state machine). - VIN reads:
protocol::read_vinshipped atsrc-tauri/src/protocol/mod.rs:296; all callers incommands.rsroute through it. - ENET/DoIP UDP discovery remains honestly not implemented.
The ROADMAP.md v0.3.0 historical audit was a separate PR. Six items in the v0.3.0 “Real Car” section were marked “Ready” but had actually shipped. The PR moved them to a new “Done — historical (shipped)” table with PR references and code locations.
The CI fix
The CI & Autonomous Merge workflow’s test-rust job ran cargo test on a bare ubuntu-latest runner that lacked Tauri’s Linux system libraries (glib, gtk, webkit2gtk-4.1). The build failed in 20 s on every PR.
The fix: mirror the apt-get install step from test.yml::rust into ci.yml::test-rust. 20 seconds to a green build, every PR since.
What we didn’t ship
- No
transport/**changes. The K+DCAN / ENET/DoIP paths were not touched. - No
protocol/**changes. - No frontend changes (JS, HTML, CSS).
- No community data changes.
- No
git tag v0.14.4in this cycle — that is the Tier C release cut, separate from this Tier A merge.
What’s next
The v0.14.5 cycle is up next. Candidate slices include the ENET/DoIP UDP broadcast discovery (the long-standing Tier B item), more DTC catalog coverage (P2002/P2003 for DPF, P0401/P0402 for EGR), and the public /api/release-info endpoint.
See the v0.14.5 cycle page for the candidate list.