Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ This project follows a Keep a Changelog-style format and uses version tags for r

## [Unreleased]

## [1.6.1] - 2026-07-29

Docs only — no code change.

### Added
- **Landed `docs/TODO-layering-cleanup-2026-07-02.md`, the design record behind
LC-1→LC-3** (shipped v1.2.4–v1.3.0: `SystemSnapshot` as the sole frame
contract, `ProcessSample` through L2, and `analytics.py`'s `AlertEngine` /
throttle / session-energy move out of the widget). The plan drove all three
releases but lived only on an unmerged branch, so the code shipped while its
rationale stayed unpublished — the violation inventory, per-violation fix
design, and sequencing are now in the repo instead of one branch tip.

§§1–9 are the July plan verbatim, so their line references point at July code.
A new **§10** records status verified against `main`, and is the only open
scope.
- **Two roadmap items promoted out of that plan** into
`docs/TODO-architecture-roadmap.md`:
- **Export parity** (§10.2) — per-process rows, throttle/alert flags, and
session energy are still TUI-only and never reach `--json` / `--serve`, so
profiling a local inference run through the export backends cannot answer
which process drew the watts, whether the chip throttled, or what the run
cost in energy. Both candidate designs and the recommendation are recorded,
along with the per-PID Prometheus cardinality constraint that keeps process
data NDJSON-only either way.
- **LC-4** (§10.1) — the watt/GB-s history deques and `_avg_max` reducer never
moved to an `analytics.RollingStats`. Explicitly low priority: it relocates
working code, and the reason to do it is export parity needing the same
aggregates outside the TUI.

§10.3 records one acceptance criterion that does not literally pass and should
be reworded rather than "fixed": `tui/app.py` still imports `get_soc_info` for
a single construction-time call that builds `DashboardConfig`. The criterion
targeted per-frame L1 acquisition in the view, which is gone; routing that one
call through another module to satisfy a grep would add indirection for no
layering gain.

## [1.6.0] - 2026-07-29

Reading-plane audit §8: adopt the GPU driver's `IOAccelerator`
Expand Down
3 changes: 3 additions & 0 deletions docs/TODO-architecture-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Completed work is **not** tracked here — its as-built design is folded into `d
* [ ] **Net / disk I/O via native ctypes** → **`docs/TODO-net-disk-io-2026-07-02.md`.** Moderate effort; deliberately widens scope. **Feasibility spike complete (2026-07-02)** — verified on-device (M4 Max, unprivileged) and cross-checked against `mactop`'s shipped implementation; the full impl-ready design (exact syscalls, struct layouts, IOKit matching strings, property keys, aggregation, and where each plugs into the sampler/models/TUI/API/export layers) lives in that dedicated plan. Summary of the verified approach: **network** via `getifaddrs()`/`freeifaddrs()` walking `AF_LINK` entries and casting `ifa_data` → `struct if_data` (one new ctypes binding in `native_sys.py`; the originally-guessed `net.link.generic.system.stats` MIB does not exist on-device); **disk** via IOKit `IOServiceMatching("AppleAPFSVolume")` summing each volume's `Statistics` dict, with `IOServiceMatching("IOBlockStorageDriver")` as the non-APFS fallback (read the way `gpu_registry.py` walks `IOAccelerator` — no new IOKit binding classes); both **aggregated** as `(current_total - previous_total) / elapsed_seconds`, the same delta-over-interval shape as `sampler._compute_bandwidth_gbps` (§3.5). Update `DESIGN-system.md` §3.6 to drop the non-goal framing once it ships.
* **Why a must-have despite being single-peer breadth:** per `docs/REVIEW-architecture-comparison.md` §4 this is *single-peer breadth* (mactop-only; macmon deliberately omits it), **not** a converged peer expectation. We keep it as a conscious bet on narrowing the gap to the breadth leader, tracked openly rather than silently declined. Post-launch — launch gates on none of it.

* [ ] **Export parity for processes / alerts / session energy** → **`docs/TODO-layering-cleanup-2026-07-02.md` §10.2.** The layering cleanup (LC-1→LC-3, shipped v1.2.4–v1.3.0) made `SystemSnapshot` the sole frame contract, but three data points the TUI shows still never reach `--json` / `--serve`: per-process rows (the export loops build `Monitor` without `include_processes=True`), the throttle/alert flags, and cumulative session energy (both produced by `analytics.AlertEngine`, which only the dashboard widget drives). **Why it matters:** someone profiling a local inference run through the export backends gets watts and utilization but cannot answer *which process drew them*, *did the chip throttle*, or *what did the run cost in total energy* — the questions that profiling session exists to ask. That plan's §10.2 records both candidate designs (opt-in export flags vs. moving `AlertEngine` behind `Monitor`), the recommendation, and the per-PID Prometheus cardinality constraint that keeps process data NDJSON-only either way.
* [ ] **LC-4 — rolling native-unit stats out of the widget** → **`docs/TODO-layering-cleanup-2026-07-02.md` §10.1.** The watt/GB-s history deques and the `_avg_max` reducer behind the `avg N · max N` suffixes still live in `HardwareDashboard`; `analytics.RollingStats` was never built. Deliberately low priority — it relocates working code and fixes no user-visible defect. The reason to do it is the item above, which needs those same aggregates outside the TUI.

---

## Nice-to-Have — Distribution & UX
Expand Down
Loading