diff --git a/.github/actions/build-installer/action.yml b/.github/actions/build-installer/action.yml
index df13f65d..b51a61b4 100644
--- a/.github/actions/build-installer/action.yml
+++ b/.github/actions/build-installer/action.yml
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
# The installer build shared by release.yml and alpha.yml, so a build step is changed in one place.
#
# Runs after actions/checkout. It reads the version from src/version.h, runs every test gate and
@@ -25,6 +27,11 @@ runs:
. ./tools/version.ps1 # Get-WindVersion: the one src/version.h reader
"version=$(Get-WindVersion (Get-Location).Path)" >> $env:GITHUB_OUTPUT
+ # Cheap provenance gate first: every first-party source file carries the copyright header.
+ - name: Copyright headers
+ shell: pwsh
+ run: pwsh -File tools/check_copyright.ps1
+
- name: Install NSIS
shell: pwsh
run: choco install nsis --no-progress -y
diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml
index 5d346678..423fd12d 100644
--- a/.github/workflows/alpha.yml
+++ b/.github/workflows/alpha.yml
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
# Alpha / nightly channel: build an installer from ANY branch, on demand, without touching the
# stable download.
#
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8a7bcd66..7fa878c8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
name: build
on:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 22e9397a..d8fc4478 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
# Keep the published release in step with main.
#
# The problem this exists for: v0.1.0 shipped, a fix landed on main, and the release kept
@@ -109,6 +111,43 @@ jobs:
if ($LASTEXITCODE -ne 0) { throw 'gh release create failed' }
}
+ # Provenance: a record of this commit, its tree and the SHA-256 of its source
+ # archive and installer, stamped with OpenTimestamps (Bitcoin-anchored, cannot be backdated).
+ # The proof starts pending; docs/provenance/README.md says how to upgrade and verify it. A
+ # calendar outage must never block a release, hence continue-on-error.
+ - name: Timestamp provenance
+ continue-on-error: true
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ github.token }}
+ GH_REPO: ${{ github.repository }}
+ run: |
+ $ErrorActionPreference = 'Continue'
+ $PSNativeCommandUseErrorActionPreference = $false
+ $v = '${{ steps.ver.outputs.version }}'
+ $sha = '${{ github.sha }}'
+ git archive --format=tar -o src.tar $sha
+ $rec = "provenance-$v.txt"
+ @(
+ 'Wind release provenance record'
+ 'Owner: Max Aubert'
+ "Repository: https://github.com/${{ github.repository }}"
+ "Version: $v"
+ "Commit: $sha"
+ "Tree: $(git rev-parse "$sha^{tree}")"
+ "Source archive (git archive --format=tar $sha) SHA-256: $((Get-FileHash src.tar -Algorithm SHA256).Hash.ToLower())"
+ "Installer Wind-Setup-x64-$v.exe SHA-256: $('${{ steps.notes.outputs.sha }}'.ToLower())"
+ ) | Set-Content $rec -Encoding utf8NoBOM
+ python -m pip install --quiet opentimestamps-client
+ # python-bitcoinlib cannot find OpenSSL on Windows by name (the plain `ots` command dies
+ # at import), so point it at Python's own libcrypto and call the client's main directly.
+ $dll = Get-ChildItem (Join-Path (python -c "import sys;print(sys.base_prefix)") 'DLLs') -Filter 'libcrypto*.dll' | Select-Object -First 1
+ $shim = "import sys,ctypes.util as u;o=u.find_library;u.find_library=lambda n: r'$($dll.FullName)' if n in ('ssl','libeay32','crypto') else o(n);from otsclient.ots import main;sys.argv[0]='ots';main()"
+ python -c $shim stamp $rec
+ if (-not (Test-Path "$rec.ots")) { throw 'ots stamp failed' }
+ gh release upload "v$v" $rec "$rec.ots" --clobber
+ if ($LASTEXITCODE -ne 0) { throw 'provenance upload failed' }
+
- name: Summary
shell: pwsh
run: |
diff --git a/CLAUDE.md b/CLAUDE.md
index 3f504ea8..303682d3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -18,6 +18,7 @@ are frozen history cited from code, not kept in step with it.
- `build.bat installer`: NSIS setup (needs `winget install NSIS.NSIS`), then `tools\installer_check.ps1`.
- `pwsh -File tools\release.ps1`: release installer into `dist\` (what CI runs).
- UI tests: `npx playwright test` in `ui/` (run when anything under `ui/` changes).
+- `pwsh -File tools\check_copyright.ps1`: CI gate; every new source file needs the copyright/SPDX header. See 11.
## Stack and map
- Three binaries: `Wind.exe` (core, UIAccess when installed), `WindConfig.exe` (WebView2 settings),
diff --git a/build.bat b/build.bat
index 12fb43d9..5f2a2da9 100644
--- a/build.bat
+++ b/build.bat
@@ -1,4 +1,6 @@
@echo off
+rem Copyright (c) 2026 Max Aubert. All rights reserved.
+rem Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
setlocal enabledelayedexpansion
set "ROOT=%~dp0"
cd /d "%ROOT%"
diff --git a/docs/architecture/11-build-test-release.md b/docs/architecture/11-build-test-release.md
index c9b2bddb..429b572a 100644
--- a/docs/architecture/11-build-test-release.md
+++ b/docs/architecture/11-build-test-release.md
@@ -94,6 +94,18 @@ keys), the Playwright UI suite and `tools/release.ps1`, so an NSIS compile error
`installer_check.ps1` breaks the PR, not main. Nothing is published from it. Run the Playwright suite
locally too when anything under `ui/` changes.
+**Copyright headers.** Every tracked first-party source file opens with a two-line notice,
+`Copyright (c) 2026 Max Aubert. All rights reserved.` and `Proprietary
+source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary`, in
+the file's own comment syntax (`//`, `#`, `;`, `rem` after `@echo off`, `/* */`, `` after
+``). `tools/check_copyright.ps1` fails when a covered file lacks the SPDX line in its
+first 5 lines; it is the first gate in `build-installer`, and `-List` prints the files it covers.
+It skips third-party code (`third_party/`, `upscale_nis.h`, `upscale_shaders.h`, which keep their
+upstream notices), generated files (`flyout_palettes.h`, `themes.css`, `themes.js`, `over.nsh`),
+`docs/` and `tests/fixtures/`. A new source file needs the header; a new generated or vendored
+file goes in the script's exclusion lists. The binaries carry the same notice as `LegalCopyright`
+(`src/wind.rc`, `src/tray_app/wind_tray.rc`, `installer/wind.nsi`).
+
## Local UIAccess deploy
UIAccess is needed for the input-transform publish (transform on the desktop), binds over
diff --git a/installer/app.nsh b/installer/app.nsh
index a4ebc1cf..ea6f7d74 100644
--- a/installer/app.nsh
+++ b/installer/app.nsh
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup, the parts that are about Wind rather than about installing.
;
diff --git a/installer/kit.nsh b/installer/kit.nsh
index a1779ee6..5b1f8cf3 100644
--- a/installer/kit.nsh
+++ b/installer/kit.nsh
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup, part one: the window.
;
diff --git a/installer/local-sign.ps1 b/installer/local-sign.ps1
index a6415da5..62e08106 100644
--- a/installer/local-sign.ps1
+++ b/installer/local-sign.ps1
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
<#
Signs the installed Wind on THIS PC so Windows grants it UIAccess.
diff --git a/installer/make-loop.mjs b/installer/make-loop.mjs
index bb63a054..7ed01157 100644
--- a/installer/make-loop.mjs
+++ b/installer/make-loop.mjs
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
/**
* Builds the video loop setup plays, from a source clip.
*
diff --git a/installer/make-over.mjs b/installer/make-over.mjs
index b17e2041..34c336e4 100644
--- a/installer/make-over.mjs
+++ b/installer/make-over.mjs
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
/**
* Renders installer/over.html into the alpha overlays the installer composites over its
* video loop, plus the rectangles NSIS needs to know about.
diff --git a/installer/over.html b/installer/over.html
index 4333a2b8..bc9ff59e 100644
--- a/installer/over.html
+++ b/installer/over.html
@@ -1,4 +1,6 @@
+
diff --git a/installer/plain.nsh b/installer/plain.nsh
index 4be85d66..5487fdac 100644
--- a/installer/plain.nsh
+++ b/installer/plain.nsh
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup, the accessible plain pages (issue #513).
;
diff --git a/installer/screens.nsh b/installer/screens.nsh
index 8763647e..940c1e7a 100644
--- a/installer/screens.nsh
+++ b/installer/screens.nsh
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup, the five screens.
;
diff --git a/installer/user-localappdata.ps1 b/installer/user-localappdata.ps1
index b299dea1..2c134eac 100644
--- a/installer/user-localappdata.ps1
+++ b/installer/user-localappdata.ps1
@@ -1,3 +1,5 @@
+# Copyright (c) 2026 Max Aubert. All rights reserved.
+# Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
<#
Prints the %LOCALAPPDATA% folder of the user who owns the desktop in this session (issue #274).
diff --git a/installer/video.nsh b/installer/video.nsh
index c7fa43ac..426879a6 100644
--- a/installer/video.nsh
+++ b/installer/video.nsh
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup, the picture: a video loop with the UI composited over it.
;
diff --git a/installer/wind.nsi b/installer/wind.nsi
index ee03ee48..1869252c 100644
--- a/installer/wind.nsi
+++ b/installer/wind.nsi
@@ -1,3 +1,5 @@
+; Copyright (c) 2026 Max Aubert. All rights reserved.
+; Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
;
; Wind setup.
;
@@ -43,7 +45,7 @@ VIAddVersionKey "FileDescription" "Wind setup"
VIAddVersionKey "FileVersion" "${WIND_VERSION}"
VIAddVersionKey "ProductVersion" "${WIND_VERSION}"
VIAddVersionKey "CompanyName" "${PUBLISHER}"
-VIAddVersionKey "LegalCopyright" "Copyright (c) 2026 ${PUBLISHER}"
+VIAddVersionKey "LegalCopyright" "Copyright (c) 2026 ${PUBLISHER}. All rights reserved."
!include "MUI2.nsh"
!include "LogicLib.nsh"
diff --git a/src/color/color_filter.cpp b/src/color/color_filter.cpp
index f523c447..fe0d82ff 100644
--- a/src/color/color_filter.cpp
+++ b/src/color/color_filter.cpp
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#include "color_filter.h"
#include "mag_host.h"
#include "logging.h"
diff --git a/src/color/color_filter.h b/src/color/color_filter.h
index 4c8dbfaa..914de1d0 100644
--- a/src/color/color_filter.h
+++ b/src/color/color_filter.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
// Colour filter controller (issue #288). Applies the DWM colour effect (MagSetFullscreenColorEffect)
// on the tick thread, deduped so an unchanged filter costs one compare
diff --git a/src/color/color_matrix.h b/src/color/color_matrix.h
index 27e32283..bddd0e39 100644
--- a/src/color/color_matrix.h
+++ b/src/color/color_matrix.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
// Colour filter matrices (issue #288). Pure; tests/test_color_matrix.cpp.
//
diff --git a/src/color/cursor_tint.cpp b/src/color/cursor_tint.cpp
index 957d5b4c..fa843cdc 100644
--- a/src/color/cursor_tint.cpp
+++ b/src/color/cursor_tint.cpp
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#include "cursor_tint.h"
#include "cursor_tint_pixels.h"
#include "logging.h"
diff --git a/src/color/cursor_tint.h b/src/color/cursor_tint.h
index aa1e9e21..f4d1bcf4 100644
--- a/src/color/cursor_tint.h
+++ b/src/color/cursor_tint.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
// Tinted system pointers at 1x (spec 2026-09-30-cursor-tint-design.md). Windows draws the pointer on
// a hardware plane the DWM colour effect never reaches, so while Warmth/Brightness are on Wind swaps
diff --git a/src/color/cursor_tint_pixels.h b/src/color/cursor_tint_pixels.h
index 437d3f15..5974bf46 100644
--- a/src/color/cursor_tint_pixels.h
+++ b/src/color/cursor_tint_pixels.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
// Pixel work for the tinted 1x pointer (spec 2026-09-30-cursor-tint-design.md). Pure; tests in
// tests/test_cursor_tint.cpp. Pixels are 32bpp BI_RGB DIB values: 0xAARRGGBB, straight (not
diff --git a/src/config/config.cpp b/src/config/config.cpp
index 0120fa39..7f3ad007 100644
--- a/src/config/config.cpp
+++ b/src/config/config.cpp
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#include "config.h"
#include "keybind_rules.h" // one safety rule set for every bind (#285)
#include "ini_edit.h" // wheel migration (#318): pure text edits
diff --git a/src/config/config.h b/src/config/config.h
index 2002ded6..92aecd8c 100644
--- a/src/config/config.h
+++ b/src/config/config.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
#include
namespace wind {
diff --git a/src/config/config_path.h b/src/config/config_path.h
index 8cc4a3aa..a72ff06d 100644
--- a/src/config/config_path.h
+++ b/src/config/config_path.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
// Shared helper to resolve magnifier.ini's runtime path. MUST be included AFTER .
//
// Returns the exe's directory if it is writable (dev workflow, repo dir), else
diff --git a/src/config/ini_edit.cpp b/src/config/ini_edit.cpp
index 3de67820..d574580d 100644
--- a/src/config/ini_edit.cpp
+++ b/src/config/ini_edit.cpp
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#include "ini_edit.h"
#include
namespace wind {
diff --git a/src/config/ini_edit.h b/src/config/ini_edit.h
index fa946f01..426451bf 100644
--- a/src/config/ini_edit.h
+++ b/src/config/ini_edit.h
@@ -1,3 +1,5 @@
+// Copyright (c) 2026 Max Aubert. All rights reserved.
+// Proprietary source-available software; see LICENSE. SPDX-License-Identifier: LicenseRef-Wind-Proprietary
#pragma once
#include
#include