Date: 2026-08-09 Verdict: All six fixes work. The hardened build compiles, starts and runs. No regressions. One correction to my own method from the previous report.
This pass exists to check that six defects found in report 01 were actually fixed, on the packaged executable rather than in the source. Nothing is taken on trust. Every result below came from running something and reading the output.
About this edition. The original record of this pass is an internal working document, in French, and it quotes commit hashes and file digests throughout. This is a full English edition of it, prepared for publication. It is faithful to the original and adds nothing. The original is archived unchanged, because a test report is a record of what was run and editing one after the fact defeats the point.
| OS | Windows 11 Enterprise 10.0.26100, 24H2 |
| Python | 3.12.10, Tk 8.6 |
| PyInstaller | 6.22.0 |
| Display | virtual sandbox driver, a single mode at 2560 x 1407 and 32 Hz |
The display matters more than it looks. That driver publishes one mode and accepts every resolution without applying any, which makes several things below testable that would be hard to arrange deliberately.
Twenty four checks, grouped by the defect they cover. No failures, and nothing had to be recorded as untestable.
| Area | Check | Result |
|---|---|---|
| FAQ window | Scrollbar mapped with a real width | Pass |
| Close button mapped and inside the window | Pass | |
| Close actually closes the window, clicked for real on the packaged exe | Pass | |
| Mouse wheel scrolls, verified by comparing pixels | Pass | |
| All four entries reachable, including the last | Pass | |
| No wheel binding leaks onto the main window | Pass | |
| FAQ button | Stays mapped and whole for every message the app can produce | Pass |
| Still fits with the longest real message, at four lines | Pass | |
| Read back | Red message when the driver accepts and changes nothing | Pass |
| Refresh rate comes from the mode read back, not the mode requested | Pass | |
| Input | Unicode digit forms rejected | Pass |
| Ordinary ASCII still accepted | Pass | |
| No unhandled exceptions across 26 cases | Pass | |
| Build | The hardened spec compiles | Pass |
| The executable starts | Pass | |
| Nine tiles, the FAQ and a custom resolution all work | Pass | |
| Socket, TLS and cryptography binaries absent | Pass | |
| Smaller and faster than the plain build | Pass | |
| Window icon applied | Pass | |
| Security | Zero TCP and UDP connections | Pass |
| Zero child processes beyond the loader re-executing itself | Pass | |
| Bytecode inside the exe matches the source in the repository | Pass | |
| No suspicious strings | Pass | |
| Leaks | Graphics and window object counts flat over 50 cycles | Pass |
The previous report found the FAQ unusable. The scrollbar existed at one pixel square and unmapped, the Close button had been positioned outside the window entirely, and the fourth entry could not be reached by any means.
The widget tree after the fix, read from the live window:
Toplevel 360x480 mapped
Canvas 329x412 mapped
Frame 340x645 mapped
eight labels, four questions and four answers
Scrollbar 17x412 mapped was 1x1 and unmapped
Button 40x26 mapped was positioned off screen
The content grew from 555 to 645 pixels because one entry was rewritten, so scrolling is now genuinely necessary rather than merely present.
The wheel binding is on the window rather than on the whole application. That distinction was checked rather than assumed. Descendant widgets route the event upward, which is why scrolling works anywhere in the window, and nothing remains bound to the main window after the FAQ closes.
wheel bound on the FAQ window : yes
wheel bound on the main window : no
wheel bound application wide : no
after closing the FAQ:
child windows remaining : 0
wheel still on the main window: no
On the packaged executable, with real mouse and keyboard input injected rather than simulated in code:
pixel hash at the top of the FAQ : one value
pixel hash after eight wheel notches : a different value
the wheel scrolled the content : yes
FAQ open before clicking Close : yes
FAQ open after clicking Close : no
main window pixels unchanged by the wheel afterwards : yes
main window still responsive : yes
Screenshots confirm the scrollbar down the right edge, the Close button centred at the bottom, and after scrolling, the fourth entry fully legible. That entry was permanently unreachable in the previous version.
The second defect was that a long error message pushed the FAQ button out of the window. The window grew from 500 to 540 pixels tall and the bottom row is now packed before the status label, so the message eats into its own space instead.
Tested against every message the application is actually capable of producing, eleven of them:
message chars label height FAQ mapped needs fits
resolution not registered 118 51 yes 531 yes
change not allowed on display 82 36 yes 516 yes
read back mismatch 73 36 yes 516 yes
restart required 69 36 yes 516 yes
could not save to registry 66 36 yes 516 yes
invalid parameters 55 36 yes 516 yes
driver refused 49 36 yes 516 yes
success 34 21 yes 501 yes
invalid display flags 32 21 yes 501 yes
enumeration failed 25 21 yes 501 yes
format error 21 21 yes 501 yes
The worst real case needs 531 pixels of the 540 available, so the margin is nine pixels. Pushed well past anything real, with an artificial message of 359 characters, the label stops growing at 60 pixels and gets clipped, but the button stays mapped and whole. That is the intended behaviour.
The third defect was the important one. The app reported success whenever the driver returned success, and this sandbox driver returns success for every resolution while changing nothing at all. So the previous version cheerfully displayed a green message about a resolution the machine was not running.
Clicking the 1280 x 960 tile on the packaged executable now produces, in red:
The driver accepted 1280 x 960 but the display is still 2560 x 1407.
The values in the success message were traced through the bytecode compiled into the executable, rather than trusted from the source:
success branch reads the mode that was read back : yes
success branch reads the requested width, height : no
success branch reads the refresh rate field : yes
The success path never touches the requested values. Width, height and refresh rate all come from the display mode read back after the change.
The pattern was changed from a shorthand that matches every Unicode decimal digit to one that matches ASCII digits only. That shorthand is why Arabic-Indic and full width digits were being parsed as resolutions.
Twenty six cases through the real input handler:
| Input | Before | Now |
|---|---|---|
| Arabic-Indic digits | accepted as a resolution | rejected |
| Full width digits | accepted as a resolution | rejected |
| Bengali digits | accepted as a resolution | rejected |
1920x1080, 1920 x 1080, 1920,1080, 1920X1080 |
accepted | accepted, unchanged |
abc, 0x0, 1920x, negative values, absurd values |
rejected | rejected, unchanged |
| Shell metacharacters and path traversal attempts | rejected | rejected, unchanged |
| Ten thousand characters, null bytes, emoji | rejected | rejected, unchanged |
unhandled exceptions : 0
app still running : yes
Nothing in that table reaches a shell, and nothing could. The app runs no commands. Those cases are there because rejecting them cleanly is still the right behaviour.
The build configuration excludes 49 unused standard library modules. It compiled first time.
What that removes:
hardened build
socket module binary absent
cryptography hash binary absent
TLS libraries absent
compression binaries absent
eight native binaries in total
plain build for comparison
socket module binary present, 85 KB
cryptography hash binary present, 69 KB
TLS library present, 5.2 MB
sixteen native binaries in total
The compiled module archive holds 56 modules against 109 for the plain build. What remains that could raise an eyebrow is a base64 encoder and two URL parsing modules, none of which perform input or output. The module that fetches URLs is absent, as are the modules for sockets, subprocesses and email.
This is the difference between a claim about the source and a structural property. The source makes no network call. The hardened build additionally cannot, because the machinery is not in it.
Measured over ten runs each:
| hardened | plain | difference | |
|---|---|---|---|
| Size | 7,187,980 bytes | 10,531,380 bytes | 31.7 percent smaller |
| Launch to window, median | 1,297.6 ms | 1,427.1 ms | 129.5 ms faster |
| Native binaries | 8 | 16 | eight fewer |
| Modules | 56 | 109 | 53 fewer |
Those startup figures were later found to be inflated by roughly a factor of three, because the executable was being run from a host mapped folder rather than a local disk. Report 03 has the corrected numbers. The comparison between the two builds still holds, since both were measured the same way.
The window icon is applied. The bundled image is present in the executable, byte identical to the one in the repository, and the icon actually attached to the window matches the one a source run produces while differing from a control build with no image bundled.
network : no TCP connection and no UDP endpoint across 165 samples
child processes: only the loader re-executing itself, which is expected
startup entries: none added
scheduled tasks: none added
services : none added
files the old updater used to write: none present
The bytecode inside the executable was compared against a fresh compilation of the source in the repository. Fifteen code objects, all identical on their instructions, constants, names and variable names, and the concatenated instruction streams hash to the same value on both sides. What ships is what the source says.
Of 282 printable strings in the compiled module, none resemble a URL, a path or a command, and all 40 tokens on a risk list are absent.
Idle processor use over 60 seconds came to 0.08 percent of one core.
cycle working set private handles graphics window
0 37,466,112 18,354,176 231 32 33
20 37,720,064 18,358,272 231 32 33
50 37,670,912 18,251,776 232 32 33
graphics objects first 32 last 32 slope 0.000 per cycle
window objects first 33 last 33 slope 0.000 per cycle
handles first 231 last 232 slope 0.026 per cycle
FAQ failed to open : 0 times
Close button worked: 50 of 50
Graphics and window object counts are the discriminating ones. A window that is created and never destroyed shows up there immediately, and neither moved. The rewritten FAQ introduced no leak.
Nothing. All six fixes are verified.
| Original defect | Fix | Verified by |
|---|---|---|
| FAQ had no working scrollbar or Close button, content unreachable | pack order changed, wheel bound to the window | the FAQ section |
| FAQ button pushed out by a long message | bottom row packed first, window made taller | the long messages section |
| Success reported without checking | mode read back after the change | the read back section |
| Misleading advice to run as Administrator | FAQ entry rewritten | visible in the screenshots |
| Unicode digits accepted | ASCII digit pattern | the input section |
| An unused error flag on the library handle | removed | read in the source |
The previous report cited a particular Windows message returning zero as proof that no icon was applied. That probe is not valid. It returns zero even when running from source with the image present and the icon demonstrably applied.
running from source, with the image present on disk
the message probe : returns nothing
the actual window icon: present, and fingerprinted
The toolkit does not set the icon through that message. It sets the window class icon, which has to be read a different way. The conclusion of the previous report happened to be correct, but it rested on the image being absent from the packaged archive rather than on this probe. The acceptance criterion written into the retest request, that the probe should now return non zero, is therefore unreachable, and its failure indicates nothing.
Recording this matters more than the icon does. A report that quietly drops a bad method is less useful than one that says which of its own evidence was wrong.
Unchanged from the previous report, and repeated because fixes do not move these limits.
The six fixes are effective and verified on the packaged executable rather than only in the source. The hardened build, flagged in advance as the part most likely to fail, compiled first time, starts, works, and delivers what it promised: a third smaller, faster to start, no network or cryptography binaries, and the icon restored.
No security regressions and no resource leaks. Three minor observations remain, none blocking. The one factual correction to file is against my own method rather than against the application.