ProtectionAI v1.8.0
101 registered [WorkspaceView] modules, 30 AI copilot tools, 4 AI providers, 7 UI languages,
3,056 tests. Ribbon: 17 tabs, 85 groups, 144 controls. No module, tool or test count moves — the
minor version reflects a change to where the operator's most-used control lives and a type ramp that
now governs the whole front end.
Changed
-
Search moved to the centre of the title bar, where Outlook puts it. It sat at the right end of
the ribbon tab row, competing with seventeen tabs for the same strip.A note in the XAML had claimed true title-bar centring was impractical and would mean fighting the
window-drag hit test. That was wrong, but only just:RibbonTitleBaris aHeaderedItemsControl
whoseHeaderis positioned byHeaderAlignment, and Center is one of the values it supports, so
the search box simply becomes the header the window title used to occupy. Two things in the stock
control had to be undone first, and finding them is the work:- the style applies a
HeaderTemplatethat renders the header as text, so assigning a
UIElementprinted its type name — the running app showed a title bar reading
ProtectionAI.App.Views.RibbonSearchHost, and because the host never entered the visual tree the
search box disappeared from the automation tree entirely; PART_HeaderHolderisIsHitTestVisible="False", which is correct for a caption you drag the
window by and fatal for a text box.
Both are corrected at runtime. The cost is that this strip of the caption no longer drags the
window, which is exactly how Outlook behaves around its own search box; the rest of the caption
still drags. Every failure path leaves the box where it used to be, at the right end of the tab
row, and says so in the log — a search box that silently vanished would be worse than one that is
merely not centred.Because the box no longer shares a row with the tabs, the ribbon fit engine no longer shrinks it to
buy the tab strip width — that step bought nothing once they stopped competing. It is now sized
against the window, and the whole tab row is available to tabs, so fewer are ever parked into the
overflow menu.Verified on the running app: centred, correctly themed (
#252526on dark),ShellSearchBox
findable in the automation tree, click-to-focus working, typingdistopening the results popup. - the style applies a
-
Every font size in the front end is now a named step on one ramp. An audit found 356
hard-coded sizes across 217 files in twenty distinct values — 9, 9.5, 10, 10.5, 11, 11.5, 12,
12.5, 13, 13.5, 14, 15, 16, 17, 18, 20, 22, 24, 26 and 28 — where the house idiom describes about
five. Half-steps that differ by half a pixel are not a design decision; they are drift, and their
existence means the next contributor picks a number rather than a meaning. Fifty-four were below
11 px, which on a field laptop in sunlight is where text stops being readable and starts being
decoration.Ui.Sizenow names the ramp —Micro11,Body12,Strong13,Subtitle14,Title16,
SectionHeader18,Page22,Display24,Hero28 — and 280 call sites across 83 files were
converted. Near-duplicates were snapped to the step they were already pretending to be and
everything below 11 was raised: 9/9.5/10/10.5/11.5 → 11, 12.5 → 12, 13.5 → 13, 15 → 14, 17 → 16,
20 → 22, 26 → 24. Sizes already on a step kept their value and gained a name. The intent was to
remove invisible variation and raise unreadable text, not to resize the product.Chart text is deliberately not on this ramp: OxyPlot renders through its own pipeline and
ChartTheme.csremains its single source of truth. Ten OxyPlot annotation sizes were identified
and left alone rather than converted by pattern-matching on the property name.
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)
0939d9d5c1e6bcc6f83c652f70869544a2a4fcf6139acaa949f35d341b616c08 protectionai-1.8.0-cyclonedx.json
dfdc44708ed73388f1029f06dbab0411db35b42613d7586510ecd86d28fa5d90 protectionai-1.8.0-cyclonedx.json.sha256
b571ec50562c436a3f9b9181db8c2708a42e13c66b4331e9a744bc60bc561ebf ProtectionAI-Setup.msi
1188ee0caa22d0af4b6670889768c3d15cc250c4cea54b376b147bef3f464602 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.8.0-cyclonedx.json) and its checksum sidecar (protectionai-1.8.0-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.8.0 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-github-workflow-repository Cwgtshome/ProtectionAI \
--certificate-github-workflow-ref refs/tags/v1.8.0 \
--certificate-github-workflow-sha 1f8ca994a45dd8ed1997d68ac36aacdc62b05e2cOr 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.8.0 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-github-workflow-repository Cwgtshome/ProtectionAI \
--certificate-github-workflow-ref refs/tags/v1.8.0 \
--certificate-github-workflow-sha 1f8ca994a45dd8ed1997d68ac36aacdc62b05e2cPin 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@1f8ca99. See docs/RELEASE-INTEGRITY.md for what each file is and why it exists.