This one is process rather than code, and it's already on your own list (TODO-windows.md, "Still open" item 1) — filing it because it sits on the update trust path that #13/#16 touch, and because the incident you documented makes it more than a checkbox.
Facts
release.yml has no signtool anywhere — the only signing is ad-hoc macOS codesign (.github/workflows/release.yml:278,350-351). Every Windows artifact ships with a fresh, unknown hash.
runtime/update.js:280-281 makes that explicit for the update path: "Windows has no codesign equivalent here; the https + sha256 manifest is the trust anchor" — so unlike macOS (Team ID pinning), a Windows install has nothing to verify the downloaded bundle against beyond TLS + the manifest hash.
- Your own 0.30.0 incident (TODO-windows.md): Defender's cloud heuristic (
Behavior:Win32/Execution.A!ml, severity "Severe") quarantined the freshly downloaded tjs.exe out of tinyjs update's staging dir mid-swap, and the dev box needed exclusions on %LOCALAPPDATA%\tinyjs, tinyjs.new, and the examples tree before a release pass could run. The trigger is structural — unsigned + new hash + Mark-of-the-Web + spawns/executes — and every release re-rolls it.
Consequences
No provenance users can verify, update availability hostage to cloud heuristics, SmartScreen flags first runs, and end users downloading the example -win.zips roll the same dice.
Suggested fix
Authenticode cert in the release CI (OV builds per-cert reputation over time; EV starts trusted), signing tjs.exe/launcher-win and the per-app exes tinyjs build emits. Longer term, a signed per-app exe gives update.js something to pin — the Windows analogue of the macOS Team ID check. Meanwhile, submitting each release's tjs.exe at microsoft.com/wdsi/filesubmission (as your TODO notes) keeps the heuristics tame.
Can't help test signing without a cert, so reporting rather than PR'ing this one.
This one is process rather than code, and it's already on your own list (TODO-windows.md, "Still open" item 1) — filing it because it sits on the update trust path that #13/#16 touch, and because the incident you documented makes it more than a checkbox.
Facts
release.ymlhas no signtool anywhere — the only signing is ad-hoc macOS codesign (.github/workflows/release.yml:278,350-351). Every Windows artifact ships with a fresh, unknown hash.runtime/update.js:280-281makes that explicit for the update path: "Windows has no codesign equivalent here; the https + sha256 manifest is the trust anchor" — so unlike macOS (Team ID pinning), a Windows install has nothing to verify the downloaded bundle against beyond TLS + the manifest hash.Behavior:Win32/Execution.A!ml, severity "Severe") quarantined the freshly downloaded tjs.exe out oftinyjs update's staging dir mid-swap, and the dev box needed exclusions on%LOCALAPPDATA%\tinyjs,tinyjs.new, and the examples tree before a release pass could run. The trigger is structural — unsigned + new hash + Mark-of-the-Web + spawns/executes — and every release re-rolls it.Consequences
No provenance users can verify, update availability hostage to cloud heuristics, SmartScreen flags first runs, and end users downloading the example
-win.zips roll the same dice.Suggested fix
Authenticode cert in the release CI (OV builds per-cert reputation over time; EV starts trusted), signing tjs.exe/launcher-win and the per-app exes
tinyjs buildemits. Longer term, a signed per-app exe givesupdate.jssomething to pin — the Windows analogue of the macOS Team ID check. Meanwhile, submitting each release's tjs.exe at microsoft.com/wdsi/filesubmission (as your TODO notes) keeps the heuristics tame.Can't help test signing without a cert, so reporting rather than PR'ing this one.