diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07ae512..c329b38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,8 @@ because it turns other people's test suites red.
## [Unreleased]
+## [0.4.0] - 2026-09-25
+
### Changed
- **`tfg preset eject` writes a `purpose` line for every target, so an
@@ -2412,7 +2414,8 @@ because it turns other people's test suites red.
Initial release.
-[Unreleased]: https://github.com/donislawdev/TestingFilesGenerator/compare/v0.3.0...HEAD
+[Unreleased]: https://github.com/donislawdev/TestingFilesGenerator/compare/v0.4.0...HEAD
+[0.4.0]: https://github.com/donislawdev/TestingFilesGenerator/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/donislawdev/TestingFilesGenerator/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/donislawdev/TestingFilesGenerator/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/donislawdev/TestingFilesGenerator/releases/tag/v0.1.0
diff --git a/README.md b/README.md
index b3fe7b1..240a6f0 100644
--- a/README.md
+++ b/README.md
@@ -590,7 +590,7 @@ interrupted. One entry per file:
```json
{
"manifest_version": "1.0",
- "tool": { "name": "testing-files-generator", "version": "0.3.0" },
+ "tool": { "name": "testing-files-generator", "version": "0.4.0" },
"run": {
"id": "run_b359aa8d94",
"seed": 0,
diff --git a/cmd/tfg-gui/rsrc_windows_amd64.syso b/cmd/tfg-gui/rsrc_windows_amd64.syso
index 1bba15e..abdb338 100644
Binary files a/cmd/tfg-gui/rsrc_windows_amd64.syso and b/cmd/tfg-gui/rsrc_windows_amd64.syso differ
diff --git a/cmd/tfg/rsrc_windows_amd64.syso b/cmd/tfg/rsrc_windows_amd64.syso
index d737cfc..f167bbc 100644
Binary files a/cmd/tfg/rsrc_windows_amd64.syso and b/cmd/tfg/rsrc_windows_amd64.syso differ
diff --git a/cmd/tfg/tfg.rc b/cmd/tfg/tfg.rc
index f6b2ee8..aaaef18 100644
--- a/cmd/tfg/tfg.rc
+++ b/cmd/tfg/tfg.rc
@@ -39,8 +39,8 @@
1 ICON "../../internal/gui/icon/chickpea.ico"
1 VERSIONINFO
-FILEVERSION 0,3,0,0
-PRODUCTVERSION 0,3,0,0
+FILEVERSION 0,4,0,0
+PRODUCTVERSION 0,4,0,0
FILEOS 0x40004L
FILETYPE 0x1L
BEGIN
@@ -50,12 +50,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DonislawDev"
VALUE "FileDescription", "Generates test files for QA, from the command line"
- VALUE "FileVersion", "0.3.0"
+ VALUE "FileVersion", "0.4.0"
VALUE "InternalName", "tfg"
VALUE "LegalCopyright", "Copyright (C) 2026 DonislawDev. GNU GPL version 3."
VALUE "OriginalFilename", "tfg.exe"
VALUE "ProductName", "Testing Files Generator"
- VALUE "ProductVersion", "0.3.0"
+ VALUE "ProductVersion", "0.4.0"
END
END
BLOCK "VarFileInfo"
diff --git a/internal/guard/testdata/screens/about.png b/internal/guard/testdata/screens/about.png
index 894c2d6..e269768 100644
Binary files a/internal/guard/testdata/screens/about.png and b/internal/guard/testdata/screens/about.png differ
diff --git a/internal/guard/testdata/screens/about.xml b/internal/guard/testdata/screens/about.xml
index c3d230d..66cc6ec 100644
--- a/internal/guard/testdata/screens/about.xml
+++ b/internal/guard/testdata/screens/about.xml
@@ -37,7 +37,7 @@
- Testing Files Generator 0.3.0
+ Testing Files Generator 0.4.0
diff --git a/internal/gui/icon/chickpea.rc b/internal/gui/icon/chickpea.rc
index 28d7cce..029ad37 100644
--- a/internal/gui/icon/chickpea.rc
+++ b/internal/gui/icon/chickpea.rc
@@ -38,8 +38,8 @@
* the fourth number of FILEVERSION is a zero rather than a build counter.
*/
1 VERSIONINFO
-FILEVERSION 0,3,0,0
-PRODUCTVERSION 0,3,0,0
+FILEVERSION 0,4,0,0
+PRODUCTVERSION 0,4,0,0
FILEOS 0x40004L
FILETYPE 0x1L
BEGIN
@@ -49,12 +49,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "DonislawDev"
VALUE "FileDescription", "Generates test files for QA"
- VALUE "FileVersion", "0.3.0"
+ VALUE "FileVersion", "0.4.0"
VALUE "InternalName", "tfg-gui"
VALUE "LegalCopyright", "Copyright (C) 2026 DonislawDev. GNU GPL version 3."
VALUE "OriginalFilename", "tfg-gui.exe"
VALUE "ProductName", "Testing Files Generator"
- VALUE "ProductVersion", "0.3.0"
+ VALUE "ProductVersion", "0.4.0"
END
END
BLOCK "VarFileInfo"
diff --git a/internal/version/version.go b/internal/version/version.go
index a6f78e5..27ee424 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -8,18 +8,23 @@ package version
// explain a hash mismatch after an upgrade.
//
// Set to 0.1.0 by the owner on 2026-08-02, raised to 0.2.0 on 2026-08-28, to
-// 0.3.0-rc1 on 2026-09-03 and to 0.3.0 on 2026-09-09, every one of them by the
-// owner. It stopped being an internal number the day 0.1.0 was published: this
+// 0.3.0-rc1 on 2026-09-03, to 0.3.0 on 2026-09-09 and to 0.4.0 on 2026-09-25,
+// every one of them by the owner. It stopped being an internal number the day 0.1.0 was published: this
// is what somebody compares their build against when a hash they stored months
// ago does not match.
//
-// 0.2.0 was a minor bump that moved no bytes. This one moves them, and before
+// 0.2.0 was a minor bump that moved no bytes. 0.3.0 moved them, and before
// 1.0 the minor is where that goes - D11 and immutable rule 3 ask for a bump,
-// not for a particular digit. Six formats have different bytes under Go 1.27,
-// a log advances through time, a GIF moves, a CSV quotes only the fields that
-// need it, and the padding of a ZIP, a TAR.GZ and a WAV is drawn eight bytes
-// at a time instead of one. The changelog lists each one and says whether
-// there is a way back to the old bytes.
+// not for a particular digit. Six formats had different bytes under Go 1.27,
+// a log advanced through time, a GIF moved, a CSV quoted only the fields that
+// needed it, and the padding of a ZIP, a TAR.GZ and a WAV was drawn eight
+// bytes at a time instead of one. The changelog lists each one and says
+// whether there is a way back to the old bytes.
+//
+// 0.4.0 moves no generated byte - the pre-release rehearsal compared every
+// format 0.3.0 had with 0.3.0 and found none changed. What does move is the
+// recipe_hash of a run from a preset, because a preset now gives every target
+// a purpose, and the changelog says so under Changed.
//
// The absence of a suffix is a decision rather than tidying up. The release
// workflow marks a release as a prerelease when the TAG NAME carries a hyphen,
@@ -32,7 +37,7 @@ package version
// anything. The entries that shipped as 0.3.0-rc1 were folded into the 0.3.0
// section on 2026-09-09 for the same reason the version has one place: someone
// upgrading from 0.2.0 needs one list of what changed, not two.
-const Version = "0.3.0"
+const Version = "0.4.0"
// LicenceNotice is what "tfg license" prints and what the window's about
// screen shows.
diff --git a/web/public/404.html b/web/public/404.html
index 1c0c0d1..469c110 100644
--- a/web/public/404.html
+++ b/web/public/404.html
@@ -56,7 +56,7 @@
That page is not here
The address you followed does not