ProtectionAI v1.7.1
101 registered [WorkspaceView] modules, 30 AI copilot tools, 4 AI providers, 7 UI languages,
3,056 tests (3,055 at v1.7.0 — this release adds one). Ribbon: 17 tabs, 85 groups, 144 controls.
No module or tool count moves. One intermittent test is repaired at root cause, and the repair
carries a second latent instance of the same defect with it.
Fixed
-
A driver test could fail without anything being wrong with the driver.
AuxDcProfileTests.Playback_ReportsTheProfileValueForTheInstantItWasAppliedwent red during the
v1.7.0 release qualification while a background job was competing for this two-core machine, and
passed both in isolation and on an idle machine.The driver was never at fault and could not be:
PlayAuxDcProfileAsyncreads the elapsed time
once per iteration and derives the demanded voltage, the segment index and the reported
ElapsedSecondsfrom that one value, so the per-point assertions cannot race. Establishing that
first is what stopped the investigation hunting a race that does not exist.The fragile claim was
Assert.Contains(reports, r => r.AppliedVolts == 0.0)— "the interruption
was really played". Profile playback waits on absolute deadlines, which is the correct
production behaviour: a stalled host resynchronizes to real time rather than drifting, and the
elapsed time it reports stays honest. The consequence is that which instants get sampled is the
host scheduler's choice, so a stall spanning the profile's 300 ms zero segment leaves every
catch-up sample past it and nothing reports 0 V. The assertion was a statement about the
scheduler, not about the product.The repair is neither a widened tolerance nor a deleted assertion — that playback genuinely
drives the interruption still has to be verified. Aux-DC playback gained an internal clock seam
(IAuxDcPlaybackClock, withRealAuxDcPlaybackClockas the only implementation any shipping code
path can reach), and the test now runs on a virtual clock through
DriverTestKit.OnAVirtualClock(). It keeps every claim it made before — which simply become
decidable — and gains a stronger one: playback visited all four segments, in order. Production
behaviour is unchanged; the default clock is real time and nothing outside the test assembly can
replace it. -
The same defect, six times narrower, found while fixing the first.
Playback_ClampsToTheSupplyCeilingAndSaysSoRatherThanFailingSilentlyassertedAssert.NotEmpty
on an over-range segment only 50 ms wide — the identical bet that a sample lands inside a
window. It had never been observed failing, which is exactly why it was worth moving to the same
seam now rather than during some future release.
Added
Playback_OnTheRealClockNeverReportsAValueOffTheProfile— the real-clock companion that keeps the
production timing path covered, asserting only what holds whatever the scheduler does: every
report self-consistent against the profile, elapsed time non-decreasing, and the supply left on
the profile's final value. This is the one test the count grows by.
Verified 8 consecutive runs of the class green with a dotnet publish running in another shell —
one run took 5 s against a normal 1 s, so the contention was real — plus the full suite green on an
idle machine.
Installer
ProtectionAI-Setup.msi is a Windows Installer (MSI) package. It installs ProtectionAI in Program Files, creates a Start Menu shortcut, registers Apps & Features uninstall support, and supports in-place major upgrades. ProtectionAI.App.exe is the same application as a self-contained single-file executable, for people who cannot run an installer.
This release is not Authenticode code signed. Windows SmartScreen will warn you when you run it, and that warning is expected. The checks below prove integrity (the bytes are the bytes we built) and source binding (the signed manifest came from this repository, tag and commit). They are not a Windows trust decision and do not stop SmartScreen warning.
Artifact digests (SHA-256)
fbeaf583840971d6a64536f57cc5081e6042a77d722f508ac171f3132ea80955 protectionai-1.7.1-cyclonedx.json
82e19e9e6a2ba534f06346dbcd094fb096f8b930b955b28365e5b5d49825e0e3 protectionai-1.7.1-cyclonedx.json.sha256
36f2e3d729b10ed7fe3701273d2158c4805ce3161c40be68b8615bf5dd12da87 ProtectionAI-Setup.msi
1dd0674b27049cafa52e85af2f705f080bbb20ce6e5ae34b77e17ab51e298233 ProtectionAI.App.exe
Published alongside the artifacts as SHA256SUMS, with a detached Sigstore signature (SHA256SUMS.sig), the ephemeral signing certificate (SHA256SUMS.pem) and a self-contained bundle (SHA256SUMS.cosign.bundle). The software bill of materials (protectionai-1.7.1-cyclonedx.json) and its checksum sidecar (protectionai-1.7.1-cyclonedx.json.sha256) are both attached and covered by the signed manifest.
1. Verify integrity — the files are what we built
PowerShell:
foreach ($line in Get-Content .\SHA256SUMS) {
$expected, $name = $line -split '\s+', 2
$actual = (Get-FileHash $name.Trim() -Algorithm SHA256).Hash.ToLower()
"{0} {1}" -f $(if ($actual -eq $expected) { "OK " } else { "FAILED" }), $name.Trim()
}POSIX shell:
sha256sum -c SHA256SUMS2. Verify authenticity — the digest list itself is genuine
Step 1 only proves the files match the list. This proves the list was produced by this release workflow. Install cosign and run:
cosign verify-blob SHA256SUMS \
--signature SHA256SUMS.sig \
--certificate SHA256SUMS.pem \
--certificate-identity https://github.com/Cwgtshome/ProtectionAI/.github/workflows/release.yml@refs/tags/v1.7.1 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-github-workflow-repository Cwgtshome/ProtectionAI \
--certificate-github-workflow-ref refs/tags/v1.7.1 \
--certificate-github-workflow-sha 22cdeb09aeeed0e5e609748cd878c11a118f7947Or with the bundle, which needs no separate certificate:
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.cosign.bundle \
--certificate-identity https://github.com/Cwgtshome/ProtectionAI/.github/workflows/release.yml@refs/tags/v1.7.1 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-github-workflow-repository Cwgtshome/ProtectionAI \
--certificate-github-workflow-ref refs/tags/v1.7.1 \
--certificate-github-workflow-sha 22cdeb09aeeed0e5e609748cd878c11a118f7947Pin all five certificate constraints exactly as shown: identity, issuer, repository, ref and SHA. Together they reject a signature from another workflow, repository, tag or commit. There is no long-lived private key: the certificate above was issued to this workflow's OIDC identity, is valid for minutes, and the signing event is recorded in the public Rekor transparency log.
3. Build provenance — not available for this release
No GitHub-hosted SLSA build-provenance attestation was recorded, so gh attestation verify will not find one. GitHub's attestation store is not offered to user-owned private repositories on this plan, and the source repository is private.
What still holds: the signed SHA256SUMS manifest binds every shipped content file by digest, and the Sigstore certificate in step 2 binds that manifest to this repository, tag ref and exact source SHA against a public transparency log. What is missing is GitHub's separate SLSA predicate and attestation-store record; no SLSA level is claimed.
Built from Cwgtshome/ProtectionAI@22cdeb0. See docs/RELEASE-INTEGRITY.md for what each file is and why it exists.