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
70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,78 @@ All notable changes to this repository should be documented in this file.

## [0.2.2] - Unreleased

### Added

- **Adaptive asks the controller whether the processor is throttling, instead of guessing.** It used to infer
it from a performance ratio, which also falls for power limits, parked cores and a workload that simply
stopped — none of which is a thermal emergency, and each of which spun the fan up for a reason nobody could
explain. The embedded controller now states it directly, and distinguishes trimming clocks from protecting
the silicon, so the fan's response is proportionate to which is happening. Firmware that cannot answer keeps
the old behaviour rather than losing throttle handling.

- **Temperature sensors are labelled with the firmware's own names.** Where the controller has a name for a
sensor, that is what the chips and the thermal page show, instead of a position like "Temp 0". The name is
the one printed in the service manual, so it is the one worth searching for.

- **The firmware's own limits are visible.** The thermal history chart marks where the controller starts
warning, and the Adaptive target cannot be set above that point — a target beyond it is one the machine
would never be left to hold, and the fan behaviour that followed read as this app misbehaving.

- **Embedded controller health on Warnings & Issues.** A new card reports what the controller says about
itself: the processor being held back, a recorded panic, firmware write protection left off, or a machine
running its recovery image. Only conditions that are true are listed, and the card is absent entirely on
firmware that does not answer — an empty card would read as "no problems" rather than "cannot be asked".

- **What each USB-C port actually negotiated.** Alongside the live voltage and current, and the slot's own
rating, ports now show the contract this cable and this charger agreed on, and say so when it falls well
short of what the slot supports. Between them the three answer "why is this charging so slowly", which no
one of them could.

- **Pack health on Power Telemetry.** A section, read on request rather than polled, showing per-cell voltages
with the spread called out, the pack's age beside its cycle count, what it is asking the charger for, and
its own state of health. Cell drift is the early sign of a failing battery and nothing in the app showed it.
A sealed pack says so plainly instead of showing blanks.

- **Component firmware in Device Capabilities.** Versions for cameras, USB hubs, audio, input modules, the
power-delivery controllers, the retimer and NVMe drives, under the platform firmware they sit beneath.
Groups the machine does not have are omitted rather than shown empty. Each Modules slot card also names the
firmware of the module in it, matched by vendor and product id rather than by slot number — the peripheral
descriptors number slots by USB enumeration order, which bears no relation to the physical positions that
page draws. A drive whose firmware the operating system does not report now falls back to what the drive
itself says.

The proto gained fields for all of the above, so **the service and the app must be rebuilt together.**

### Changed

- **Adaptive fans are driven by duty percent, always.** Where calibration judged that the embedded controller
could hold a commanded speed, the demand used to be converted to an RPM setpoint and handed to the EC's own
loop. That loop clamps the request to the firmware's configured maximum for the channel — around 4900 RPM on
Framework 16, where the same fan reaches past 6200 on a direct duty write. The top quarter of the range could
not be asked for: the fan sat well short of a speed nothing was ever going to deliver, and because the
shortfall happened inside the firmware rather than at the controller's own clamp, the trim wound to +100%
against a ceiling it had no way to see. The learner was being taught from duty values the EC had quietly
replaced, so the model drifted away from the machine it was supposed to describe.

Its one advantage was the firmware holding a speed steady as a fan ages — which is exactly what the adaptive
learner already does, so removing it costs nothing. Speeds are still shown: each duty demand is reported
alongside the speed it is expected to produce, interpolated between the two speeds calibration actually
measures (the minimum-spin point and full duty) rather than scaled off the maximum, which read far too low
across the lower half of the range. Calibration no longer probes speed tracking and is one settle shorter.

**Re-run calibration on each fan** to pick up the full-speed reading the new display is anchored to.

### Fixed

- **The service took its entire 90-second shutdown budget to stop whenever the app was connected**, which is
what made uninstalling put up "Installer is no longer responding" and need retrying until that budget ran
out. Every `Watch…` call streams forever by design, and each waited only on its own request's cancellation
token — which ASP.NET Core fires when the client disconnects, or when it *aborts* the request, and it only
aborts once graceful shutdown has already timed out. So the host sat waiting the full ninety seconds for
streams that were never going to end on their own. Each stream is now linked to the host's stopping token as
well and unwinds the moment shutdown is signalled, so the service stops in well under a second. Stopping,
restarting and upgrading the service are all affected, not only uninstalling.

- **The installed 0.2.1 app could not start.** It died on launch with `Could not load file or assembly
'SubZeroFramework.GrpcContracts, Version=0.2.1.0'` while every local build ran fine. CI built the app with
the run's version, then built the test project without it — and that second build walks
Expand Down
Loading
Loading