Protect & storage lists:
- protect.csv: unlocked garage cars (state != 0, locked == false) worth
locking more copies of. Needed copies = best configs surviving the
RQ-band thresholds (prize cars and RQ >= 80 always count); already
locked copies (copy_count) are subtracted, surplus drops off the list.
- storage.csv: Keep/Trash recommendation for storage cars (state == 0)
using the same copy-count logic; surplus unlocked copies are fusion
material.
- user_data.rs now parses card state (garage vs storage), garage slots
(user.garageSlots/garageSlotsUsed), and unlocked card maps.
Dynamic trash thresholds:
- TrashThresholds derive RQ 20-29/30-39 as half/a quarter of a base
value (--trash-base-count, default 4); RQ 40+ never covered.
- plan_trash_rules escalates the base automatically while projected free
garage slots (capacity - used + unlocked non-best copies + new trash
candidates, copies counted per card) stay below --garage-min-free
(default 20), stopping when no further cars qualify. Effective
thresholds and projection are printed.
- Improve-based low-value cars (best target count at or below the band
threshold) land in trash.csv; collect_improve_entries is shared with
improve.csv and computed once per run.
Same-car tie resolution:
- resolve_tied_configs collapses tie-equivalent configs of the same car
per track (compute_car_counts, write_details_csv), preferring the
player's owned final-build config. Fixes phantom rows like the
Mercedes 280 SL 332 entry tied at 61.31 by its owned 323, inflated
per-config track counts, and pointless second-copy recommendations.
Wishlist:
- Prize cars are excluded from the ideal wishlist and surface in
remove.csv via the ideal-set difference.
CLI: new protect command; --trash-base-count/--garage-min-free on
trash/protect/all; details command reuses counts for tie resolution.
README updated for all new files, flags, and criteria.
- Gate env_logger init behind #[cfg(feature = "bin-logging")] in
records.rs main() so the binary respects the feature flag
- Set default-features = false on the dev-dependency self-reference
in Cargo.toml; previously default features were silently re-enabled
during tests, making feature isolation accidental rather than real
- Bind guid.to_string() once per card in user_data.rs deck loop and
reuse it via clone, replacing three allocations per locked card
- Add per-field help text to the Track subcommand args clarifying
human-readable names ("Laguna Seca", "Dry") vs raw codes
- Document write_details_csv DashMap snapshot memory tradeoff
(full clone, roughly doubled peak memory during the write)
- Extend my_cars fixture test: duplicate guids count as 2 copies
with per-copy configs, and incomplete-tune cards still count in
copy_count
Library no longer prints to stderr:
- Replace every eprintln! with log::warn! (lib: user_data, http; bin:
parsing, output, commands); initialize env_logger in main with a
warn-level default so output is unchanged unless RUST_LOG is set
- Warn on missing/non-numeric "t" time fields instead of silently
coercing them to 0.0; suppress the per-car NotFound warning (most
cars legitimately have no timing file), keep warnings for real I/O
errors
Ownership and clone cleanup:
- CarCounts no longer duplicates the car database: drop the car_list
field and build car_map by consuming car_list (each Car stored once);
iterate car_map.values() where the list was previously used
- run_analysis takes MyCarsData by value: owned moves into the parse
Arc, owned_configs/copy_count move into CarCounts; only the three
commands that need owned/wishlist afterwards retain their own copy
- is_final_build checks the digits directly (no per-call String
allocation) and treats malformed configs as non-final so they
surface in improve.csv; owned_final_configs becomes a borrowed
rid-to-configs map so the target-exclusion check allocates nothing
- Normalize sum arithmetic to u8 in normalize_to_final_build
Docs and structure:
- Document the first-seen-wins tie-breaking in compute_ideal_wishlist
and the non-final/non-best coverage gap in write_trash_csv
- Extract compare_by_rq_config_brand_name shared by compare_records
and the remove.csv sort; drop the unused _output_dir parameter from
run_track; add a retry_delay helper de-duplicating the three HTTP
backoff sites; rename the shadowed `entry` binding to config_data
- Count only configs meeting min_count as qualifying in the wishlist
copy-coverage check (previously ALL guid_to_rid entries inflated the
denominator, producing phantom wishlist entries), pre-computed once
per guid instead of per record
- Update stale write_improve_csv doc to match single-best-target
behavior including cross-copy exclusion
- Borrow owned configs for the trash CSV join instead of cloning the Vec
- Build owned_final_configs via filter_map + flat_map without the
throwaway intermediate Vec
- Remove runtime assertions on literal constants (clippy
assertions_on_constants) and replace a redundant closure with the
function reference (clippy redundant_closure)
- Apply rustfmt across the crate and drop a duplicated test-section header
- Change owned_configs from HashMap<String, String> to HashMap<String, Vec<String>>
to capture all configs across copies (previously last-write-wins lost data)
- Add copy_count field to MyCarsData and CarCounts for wishlist copy-coverage logic
- Fix improve.csv to exclude already-owned final configs as targets (e.g., Fiat
Campagnola 1974 now targets 332 instead of already-owned 323)
- Fix wishlist to check all owned configs for exact-match and final-build detection
- Fix trash to check all configs for final-build-not-best detection
- Update all tests for new Vec type and add multi-copy improve test
- Add normalize_to_final_build() to map tune configs to final builds (323/233/332)
- Add normalized_config field to BestCarRecord
- Change CarCounts.by_rid key from String to (String, String) for per-config tracking
- Change CarCounts.guid_to_rid to HashMap<String, HashSet<(String, String)>>
- Extract owned tune configs from my_cars.json (engineMajor/weightMajor/chassisMajor)
- Add improve command: owned cars not yet at final build, sorted by track count
- Strip version prefixes (v2c_/v1c_) from config keys at parse time
- Update dedup check in update_best_car to consider normalized_config
- Add atomic_write helper for safe CSV output
- Delete completed plans/code-review-v2.md
- Apply rustfmt formatting across codebase