v0.8.1
This release introduces critical stability fixes for hardware telemetry handling—ensuring unreadable or transient sysfs reads are no longer interpreted as zero or false—and completes the codebase transition away from legacy TypeScript parity framing into self-documenting, native Rust patterns.
🚀 Key Highlights & Bug Fixes
1. Distinguish Absent / Unreadable Readings from Zero (#14)
Previously, several sysfs parsers mapped unreadable, empty, or transient driver attributes to 0.0 or false. This led to several failure modes that have now been resolved:
- False Low-Battery & Health Alerts: An unreadable
capacityorenergy_fullsysfs attribute no longer triggers a sudden false "CRITICAL: Battery Low" or "Battery health at 0.0%" alert. - Cycle Count Loss & Spikes:
- Unreadable
energy_full_designno longer resets months of accumulated battery cycle counts to zero; it now preserves the carried count. - Unreadable
energy_nowno longer fabricates false cycle accumulation deltas.
- Unreadable
- Thermal False Negatives: Empty hwmon sensor files are now treated as absent rather than
0 °C, preventing false clearing of active thermal alerts. - Tri-State Battery Presence: Sysfs
presenthandling is now strictly tri-state (Some(true),Some(false), orNone). Unreadable or malformed presence values are treated as unknown rather thanfalse, ensuring active alert latches are not prematurely cleared on transient read errors. - Flight Recorder Retention Pruning: Buffer pruning has been decoupled from sample generation, ensuring the 6-hour retention window continues to be enforced even when a battery remains unreadable or absent.
- Reduced Log Spam & Stale Estimates:
- Unreadable sysfs states now warn once per episode rather than logging every tick (1 Hz).
- Stale UPower runtime estimates are explicitly invalidated when telemetry stops reading, preventing reinserted batteries from inheriting outdated time-to-empty calculations.
2. Retiring JavaScript Parity Framing (#13)
With the migration from the previous TypeScript implementation complete, all legacy parity references, JS-centric naming conventions, and comparisons have been removed in favor of clean, self-contained Rust implementations:
- Renamed
parityModule toformats: The module now reflects its true purpose—handling kernel text parsing, number rounding, and metric formatting. - Semantic Function Naming:
round_js→round_half_upto_fixed→format_decimalsjs_number→parse_numberjs_parse_int→parse_leading_int
- Documentation & Test Accuracy: Cleaned up documentation across alerts, thermal checks, migrations, and
/procparsers to document actual behavior, IEEE 754 edge cases, and pinned test properties directly without relying on obsolete implementation comparisons.
🛠️ What Changed
Telemetry & Hardware Handling
src/telemetry/battery.rs: Madeenergy()andcharge_pct()fallible (Option<Sample>); explicitly validatepresentattribute to distinguish0,1, and malformed/unreadable states.src/telemetry/thermal.rs: Unified battery and hwmon attribute readers to discard empty sensor files instead of coercing to 0.src/cycles.rs: Guaranteed accumulated cycle counts are preserved across unreadable driver ticks.src/daemon.rs: Hoisted retention pruning to run on all ticks, including early-return no-op ticks.
Refactoring & Code Quality
src/formats.rs(formerlysrc/parity.rs): Renamed module and utility helpers to standard descriptive naming.- Updated test suites and doc comments across
src/alerts/,src/migrations/,src/paths.rs, andsrc/telemetry/to assert native invariant behaviors.
Full Changelog: https://github.com/InvictusNavarchus/repository/compare/cfc97c3...2a50ecb