Silemetry v0.2.1
Silemetry v0.2.1 — Stability & Data Integrity
Tests: 70/70 passing · CI: #15 success · Min macOS: 14.0 (Apple Silicon) · Signing: ad-hoc
🔧 Telemetry handle lifecycle & concurrency
All Rust-handle FFI (create/start/wait/stop/destroy) now runs on one serial queue; stop is enqueued behind in-flight reads so wait_next returns before destroy — no concurrent alias / use-after-free. The actor never touches the raw pointer again. The handle is wrapped in an @unchecked Sendable box so the invariant is type-checked.
🎯 Per-metric validity masks
Rust available_mask is now per-metric (sensor count + is_finite + sane ranges), no more blanket valid. First sample no longer skipped (seq starts at 1).
🛑 Stop / Discard / failure finalization
Discard after a failed save deletes the run explicitly — no orphan records. Failure state and archive write errors surfaced in UI.
📦 JSONL archive integrity & streaming summaries
Archive load cross-checks disk file vs stored summary; stored Complete degrades to Partial when missing/truncated/corrupt. Streaming 64 KB line-by-line decode cuts peak memory in Compare.
⚖️ Compare comparability & corrupt-data checks
Verdict uses disk-effective raw status so summary/details/banner can never contradict. Tighter comparability rules (ambient diff >2°C, both-unknown conditions, both-legacy metadata now warn).
🔄 SwiftData rollback & file transactions
Failed inserts roll back immediately; History deletes/renames roll back with files restored; sample dirs staged in Trash, purged only after the DB save succeeds.
💻 Dynamic device, power changes & true startedAt
Power source / Low Power Mode recorded at start+end with change flags; Compare warns on mid-test AC↔battery or low-power switches. createdAt reflects real test start. Battery-unreadable runs stay Unknown.
✅ Validation
7/7 acceptance from the final DMG: Quick Check, GPU Only, Combined, Monitor Only, Stop Save, History restart, Compare.
Assets: drag-to-install DMG, ZIP, and SHA256SUMS.