fix(firmware): stop reflashing supported WiFi modules when the release lookup fails (part of #269) - #434
Conversation
…e lookup fails (part of #269) CheckWifiFirmwareStatusAsync compared the module's version against the latest GitHub release. When that lookup failed - offline bench, blocked egress, rate limit - it reported LatestReleaseUnavailable with no version opinion at all, and UpdateWifiModuleAsync's `default:` arm fell through to "flash conservatively". A network outage therefore triggered a multi-minute destructive WINC reflash of a module whose own reported version was already fine. Core now owns the minimum supported WINC firmware (19.7.7, the policy resolved on #269) and answers that question without a network: - FirmwareUpdateServiceOptions.MinimumSupportedWifiFirmwareVersion, defaulting to the new DefaultMinimumSupportedWifiFirmwareVersion const, validated at construction so a typo fails loudly instead of silently disabling the check. - WifiFirmwareStatus.MinimumSupportedVersion / MeetsMinimumSupportedVersion, populated on every result path. The latter is a three-state bool? on purpose: false means "read the device, it is below the bar", null means "could not tell". - The update flow's version gate honors a true verdict and skips the flash. null still proceeds to flash, so an unreadable module is never mistaken for a good one. IsUpToDate keeps its exact latest-release meaning and its existing values, so no current behavior of the status record changes; the new answer sits beside it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
/agentic_review |
PR Summary by QodoAvoid reflashing supported WINC modules when GitHub release lookup fails
AI Description
Diagram
High-Level Assessment
Files changed (4)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTo customize comments, go to the Qodo configuration screen, or learn more in the docs. Previous review resultsReview updated until commit e5c41a3 Results up to commit b92809e
|
|
Ready for review: Qodo review came back clean (0 bugs, 0 rule violations, 0 requirement gaps, no unresolved threads) and CI |
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit 0b17b1f |
|
Ready for review (supersedes the earlier note, which pinned This PR was The merge was checked for conflict first: main's only new commit ( Current head
The PR's own change was not benched, deliberately: it is about the GitHub release lookup failing — a host-side network condition, not a device one — and the surrounding WINC paths can only be exercised by a destructive flash, so hardware could not observe it either way. The only new commit since |
# Conflicts: # SESSION_LOG.md
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit e5c41a3 |
|
Ready for review (supersedes the earlier note, which pinned This PR had gone Diagnosed before anything was touched: Resolved chronologically, keeping both entry blocks in full (this branch's entry is from the 23:37 fire, after main's last #437 note at 23:28, so it sorts last). Verified lossless mechanically rather than by eye: every non-blank line of both parents is still present — 0 missing against each. Merged-vs-branch shows exactly main's Current head
Only the merge commit is new since
One thing worth your attention: this is the second time this PR has been unblocked from a |
SESSION_LOG.md is an agent scratch journal, not a project artifact. Every branch that appends to it conflicts every other open PR. Removing the delta here; a follow-up untracks it and adds it to .gitignore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Part of #269. Not merging — for review.
The problem
CheckWifiFirmwareStatusAsynchad exactly one way to form a version opinion: compare the module's reported firmware against the latest GitHub release. When that lookup failed — offline bench, blocked egress, rate limit, GitHub down — it returnedLatestReleaseUnavailablewith no opinion at all, andUpdateWifiModuleAsync's version gate fell through to itsdefault:arm:So a network failure triggered a multi-minute, destructive WINC reflash of a module whose own reported version was already fine. "Conservative" was doing a lot of work in that comment: on a network outage, flashing is the expensive guess, not the safe one.
This is the same failure class
PowerOnWifiModuleBeforeProbe(#301) andKickLanApplyOnNotInitialized(#203) already exist to prevent — each closed a path where a probe that couldn't answer sent callers into a needless reflash. This closes the remaining one, which is the only one that isn't the device's fault.The fix
#269's comment thread resolved the policy: model "minimum supported version" as the canonical concept in Core and own the
19.7.7constant in the SDK, since it's a firmware-contract fact. That question is answerable with no network at all — the device already told us its version.FirmwareUpdateServiceOptions.MinimumSupportedWifiFirmwareVersion, defaulting to the newDefaultMinimumSupportedWifiFirmwareVersionconst. Validated at construction, so a typo'd minimum throws instead of silently degrading the check back to "no version opinion" — the exact invisible failure the option exists to remove.WifiFirmwareStatus.MinimumSupportedVersionandMeetsMinimumSupportedVersion, populated on every result path.trueverdict and skips the flash.MeetsMinimumSupportedVersionis a three-statebool?deliberately:falsemeans "read the device and it is below the bar";nullmeans "could not tell". Collapsing those into onefalseis the conflation that made an unreadable module indistinguishable from an outdated one — and it's load-bearing here, becausenullstill proceeds to flash. OnlyLatestReleaseUnavailablecan reach the gate with a non-null verdict; every other fall-through reason leaves the device version unknown or unparseable.IsUpToDateis untouched — it keeps its strict latest-release meaning and all its current values. The new answer sits beside it rather than redefining it, so nothing that reads the status record today changes behavior. The two genuinely disagree (a module can be supported but not newest), which is why they're modeled separately. A caller that wants to reflash regardless already hasskipVersionCheck: true.This also removes the reason daqifi-desktop hard-codes its own
MinimumWifiFirmwareVersion = "19.7.7"inFirmwareUpdateCoordinator.WifiFirmwareNeedsFlash.Bench validation (real Nq1, fw 3.7.2, USB, non-destructive)
Ran
CheckWifiFirmwareStatusAsyncagainst the live device with a download service that throws on every call — the field failure, reproduced:Before this change the same offline call produced no version opinion and the gate said PROCEED to flash. The bench module reports exactly
19.7.7, so this also exercises the inclusive boundary (>=) against real hardware rather than a fixture.Same device, minimum raised to
99.0.0:— proof the verdict is driven by the configured bar and not hard-coded to
true. Only chip-info reads plus the WINC power-on Core's probe already performs; no flash, no NVM write, no reboot. Device answered SCPI normally afterward.UpdateWifiModuleAsyncitself was not run on the bench — that's the destructive path. Its gate is covered by unit tests.Tests
+14 tests. Two mutation checks rather than eyeballing coverage:
== falsefails both new update-flow tests (the skip stops happening, and the below-minimum module stops being flashed).!= false— treatingnullas "meets" — fails 9 tests including the new chip-info-unavailable guard, confirming the null/false distinction is genuinely load-bearing and already fenced by the existing suite.FULL suite green net9 + net10: 2,543 passed, 2 skipped, each TFM.
Daqifi.Mcp.Tests23 passed. Release solution build 0 warnings on both TFMs.Not in scope
The rest of #269 — the port-release wait, the LAN-update-mode prep/recovery sequences, and the single-entry-point orchestration — all touch the destructive flash path and need a supervised bench session. This PR is the piece that is fully validatable non-destructively.
🤖 Generated with Claude Code