M6: Bugfix & Stability — milestone integration #39

Merged
gronod merged 8 commits from milestone/m6-bugfix-stability into develop 2026-09-08 15:18:53 +01:00
Owner

Summary

Milestone 6 integration — fixes all reported post-v0.0.1 defects.

Contents

  • PR #35 — Snapshot contract realignment (#30, #31): decodeSnapshot now reads the actual emitted identifiers/keys for all 9 drifted subsystems; new provider emissions (network isUp, process isStopped/isZombie, fan name); new MMSnapshotContractTests (6 tests).
  • PR #36 — SMC resurrected (#32): IOServiceMatching("AppleSMC") + removed #pragma pack(1) that shrank SMCKeyData_t to 74 bytes (driver requires 80). Both bugs independently fatal to all SMC telemetry. Alert batteryLevel now uses the SMC-independent batteryHealth path.
  • PR #37 — Low-storage alert skips read-only and <1 GB volumes (#33) — kills the "Ghostty" DMG false positive.
  • PR #38 — Alerts sidebar row selectable again (#34) — .badge-after-.tag detached the row's tag.

Quality Gate

  • 95 tests, 0 failures; SwiftLint 0 violations; clean x86_64 build.
  • SMC path verified live on Intel hardware (service opens, #KEY GetKeyInfo returns valid data).

Closes #30, closes #31, closes #32, closes #33, closes #34.

## Summary Milestone 6 integration — fixes all reported post-v0.0.1 defects. ### Contents - **PR #35** — Snapshot contract realignment (#30, #31): decodeSnapshot now reads the actual emitted identifiers/keys for all 9 drifted subsystems; new provider emissions (network `isUp`, process `isStopped`/`isZombie`, fan `name`); new `MMSnapshotContractTests` (6 tests). - **PR #36** — SMC resurrected (#32): `IOServiceMatching("AppleSMC")` + removed `#pragma pack(1)` that shrank `SMCKeyData_t` to 74 bytes (driver requires 80). Both bugs independently fatal to all SMC telemetry. Alert `batteryLevel` now uses the SMC-independent `batteryHealth` path. - **PR #37** — Low-storage alert skips read-only and <1 GB volumes (#33) — kills the "Ghostty" DMG false positive. - **PR #38** — Alerts sidebar row selectable again (#34) — `.badge`-after-`.tag` detached the row's tag. ### Quality Gate - 95 tests, 0 failures; SwiftLint 0 violations; clean x86_64 build. - SMC path verified live on Intel hardware (service opens, `#KEY` GetKeyInfo returns valid data). Closes #30, closes #31, closes #32, closes #33, closes #34.
gronod added 8 commits 2026-09-08 15:18:44 +01:00
Providers emitted identifiers and field keys that decodeSnapshot never
looked up, leaving CPU/kernel/load/disk sections zeroed and memory%,
storage%, network, process RSS, and fan fields decoded as zero.

Store-side decode now reads the emitted schema; providers gain the
previously-missing fields: network isUp (IFF_UP via getifaddrs), process
isStopped/isZombie (pbi_status), fan name (F{i}ID). Memory utilization is
computed as used/total in the decoder. decodeSnapshot is internal for
@testable access; new MMSnapshotContractTests cover the emitted-key
contract with synthetic dictionaries (93 tests total, 0 failures).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Two latent bugs kept all SMC telemetry dead:
- IOServiceMatching("AppleSMCClient") never matched — the kernel service
  is AppleSMC, so openWithError always failed and every SMC-gated provider
  (thermal, fan, component, power) reported unavailable.
- #pragma pack(1) shrank SMCKeyData_t to 74 bytes; the SMC user client
  requires the canonical 80-byte layout and rejected every
  IOConnectCallStructMethod with kIOReturnBadArgument. Verified live on
  Intel hardware: unpacked calls succeed and return key data.

Also sources the alert engine's batteryLevel from the SMC-independent
batteryHealth path (currentCapacity/maxCapacity), falling back to the
power provider.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Read-only mounts (DMG images like /Volumes/Ghostty, update snapshots) with
~0% free produced false-positive low-storage alerts. StorageVolumeContext
now carries isReadOnly and totalBytes; the rule skips read-only volumes and
volumes under 1 GB where thresholds are meaningless. Regression tests cover
both exclusions plus the normal trigger path.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Applying .badge after .tag on a List(selection:) row wrapped the tagged
label in a view that no longer carried the tag, making the "Alerts &
Notifications" row unselectable on macOS 14. Replaced with an explicit
Label + HStack row showing the active-alert count as a styled capsule —
tag stays on the row, count still renders when alerts are active.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
gronod added the Kind/Bug
Priority
High
2
Project/Antigravity
labels 2026-09-08 15:18:51 +01:00
gronod merged commit 125c489881 into develop 2026-09-08 15:18:53 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/MacMonitor#39