|
| 1 | +# PR #324 Windows validation |
| 2 | + |
| 3 | +This document is for the Windows machine or AI validating PR #324. Test the |
| 4 | +PR branch only. Do not merge it, publish a Release, or test a binary from an |
| 5 | +older workflow run. |
| 6 | + |
| 7 | +## Scope |
| 8 | + |
| 9 | +PR #324 addresses three community-theme failures while keeping macOS and |
| 10 | +Windows behavior aligned: |
| 11 | + |
| 12 | +- #318: importing a newer ZIP with the same `theme.json.id` updates the saved |
| 13 | + theme in place instead of creating another `-2` entry. |
| 14 | +- #320: shared Safe CSS can reach the registered main, sidebar, home, and |
| 15 | + composer parts on newer renderer DOMs. This applies to every community theme, |
| 16 | + not only colors-only themes. |
| 17 | +- #322/#326: Codex `26.727.40816` replaced the legacy main/header classes with |
| 18 | + app-shell data attributes and CSS Module classes. The shared selector and CSS |
| 19 | + contract now recognizes the current main surface, header, and top-fade while |
| 20 | + retaining the legacy anchors. A visible current Codex `app://` renderer can |
| 21 | + pass target verification when it has both Codex/ChatGPT identity evidence and |
| 22 | + the required structure; unrelated targets still fail closed. |
| 23 | + |
| 24 | +The final review also covers regressions found after the first Windows pass: |
| 25 | + |
| 26 | +- Missing, non-string, or Windows-reserved source IDs are normalized to the |
| 27 | + same stable cross-platform ID before the mandatory final payload check. That |
| 28 | + check must finish before an existing saved theme is moved or replaced. |
| 29 | +- Hidden transaction/recovery directories are never listed as saved themes, |
| 30 | + even if an obsolete backup cannot be deleted immediately. |
| 31 | +- Validated Safe CSS keeps the website/server glass-filter contract (blur up |
| 32 | + to 30 px plus bounded saturate/brightness/contrast), does not erase the |
| 33 | + registered wallpaper merely because a root or surface sets a background |
| 34 | + color, and still reaches the real composer when a search input appears first. |
| 35 | + |
| 36 | +The import repair is deliberately conservative. A legacy `id-2`/`id-3` |
| 37 | +directory is removed only when its stored suffix identity and semantic |
| 38 | +fingerprint both prove that it is the same package. A matching display name is |
| 39 | +not evidence. Ambiguous directories, unrelated numeric-suffix themes, files, |
| 40 | +junctions, and reparse points must be preserved and rejected rather than |
| 41 | +overwritten. |
| 42 | + |
| 43 | +## Crash and restart recovery gate |
| 44 | + |
| 45 | +The replacement protocol is shared with macOS and must be checked as a |
| 46 | +transaction, not only through the normal `catch` rollback path: |
| 47 | + |
| 48 | +```text |
| 49 | +journal -> durable backup -> publish candidate -> verify fingerprint |
| 50 | + -> durable committed marker -> cleanup |
| 51 | +``` |
| 52 | + |
| 53 | +Run the complete Windows ZIP-import suite in both PowerShell 5.1 and 7. It |
| 54 | +contains a real process-termination/restart test for the first uncatchable |
| 55 | +window and deterministic restart-state coverage for all three windows: |
| 56 | + |
| 57 | +1. after the old canonical directory is moved to its backup; |
| 58 | +2. after the candidate is published at the canonical path; and |
| 59 | +3. after the durable `committed` marker is published. |
| 60 | + |
| 61 | +The first two states are uncommitted and must restore the exact old semantic |
| 62 | +fingerprint on the next importer/store invocation. The third state is committed |
| 63 | +and must retain the verified new fingerprint. Every recovery must remove its |
| 64 | +transaction files after successful verification and must never show dotted |
| 65 | +transaction directories in the tray menu. |
| 66 | + |
| 67 | +The suite also has fail-closed cases for a corrupt candidate, a malformed or |
| 68 | +path-conflicting journal, duplicate journals targeting one destination, and an |
| 69 | +impossible committed-plus-temporary marker. In those cases the verified old |
| 70 | +theme (when available) stays visible, the journal and suspicious payload remain |
| 71 | +for diagnosis, and no cleanup or overwrite is attempted. A legacy cleanup |
| 72 | +failure after commit is only a bounded warning; it must not roll back the new |
| 73 | +canonical theme. |
| 74 | + |
| 75 | +When reporting results, distinguish the exact phase tested (`prepared`, |
| 76 | +`old-moved`, `new-published`, or `committed`) and state whether it used the real |
| 77 | +FailFast child process or a deterministic restart-state fixture. |
| 78 | + |
| 79 | +## Checkout and automated checks |
| 80 | + |
| 81 | +Record the exact commit before testing: |
| 82 | + |
| 83 | +```powershell |
| 84 | +git fetch origin pull/324/head:pr-324 |
| 85 | +git switch pr-324 |
| 86 | +git rev-parse HEAD |
| 87 | +node --version |
| 88 | +``` |
| 89 | + |
| 90 | +Use `RemoteSigned`; do not use `ExecutionPolicy Bypass` and do not change the |
| 91 | +machine or user execution policy. A normal Git clone should not carry browser |
| 92 | +download zone marks. If Windows says a cloned test file is blocked, unblock |
| 93 | +only this checkout before retrying: |
| 94 | + |
| 95 | +```powershell |
| 96 | +Get-ChildItem -LiteralPath . -Recurse -File | Unblock-File |
| 97 | +powershell.exe -NoLogo -NoProfile -ExecutionPolicy RemoteSigned ` |
| 98 | + -File .\windows\tests\run-tests.ps1 |
| 99 | +``` |
| 100 | + |
| 101 | +Also run the portable parity checks: |
| 102 | + |
| 103 | +```powershell |
| 104 | +node .\tools\sync-runtime-assets.mjs --check |
| 105 | +node .\tools\renderer-runtime.test.mjs |
| 106 | +node .\windows\tests\injector-bootstrap.test.mjs |
| 107 | +node .\windows\tests\injector-window-readiness.test.mjs |
| 108 | +``` |
| 109 | + |
| 110 | +If PowerShell 7 is installed, repeat the Windows suite without replacing the |
| 111 | +required Windows PowerShell 5.1 run: |
| 112 | + |
| 113 | +```powershell |
| 114 | +pwsh.exe -NoLogo -NoProfile -ExecutionPolicy RemoteSigned ` |
| 115 | + -File .\windows\tests\run-tests.ps1 |
| 116 | +``` |
| 117 | + |
| 118 | +All commands must exit `0`. Keep the complete failure output if one does not. |
| 119 | + |
| 120 | +Before manual renderer testing, close Codex and exit the Dream Skin tray, then |
| 121 | +install the runtime from this checkout. Do not reuse the engine left by an |
| 122 | +older PR head or Release: |
| 123 | + |
| 124 | +```powershell |
| 125 | +powershell.exe -NoLogo -NoProfile -ExecutionPolicy RemoteSigned ` |
| 126 | + -File .\windows\scripts\install-dream-skin.ps1 |
| 127 | +
|
| 128 | +$engine = Join-Path $env:LOCALAPPDATA 'CodexDreamSkin\engine' |
| 129 | +foreach ($relative in @( |
| 130 | + 'assets\dream-skin.css', |
| 131 | + 'assets\renderer-inject.js', |
| 132 | + 'assets\safe-css-validator.mjs', |
| 133 | + 'scripts\injector.mjs', |
| 134 | + 'scripts\theme-windows.ps1' |
| 135 | +)) { |
| 136 | + $source = Join-Path (Resolve-Path .\windows) $relative |
| 137 | + $installed = Join-Path $engine $relative |
| 138 | + if ((Get-FileHash -LiteralPath $source -Algorithm SHA256).Hash -cne |
| 139 | + (Get-FileHash -LiteralPath $installed -Algorithm SHA256).Hash) { |
| 140 | + throw "Installed engine does not match PR source: $relative" |
| 141 | + } |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | +Record `git rev-parse HEAD` after installation. If any hash differs, stop; the |
| 146 | +manual result belongs to another build and is not evidence for this PR head. |
| 147 | + |
| 148 | +The automated generic renderer fixture is deliberately minimal: it contains |
| 149 | +only structural anchors such as main, sidebar, composer, and the registered |
| 150 | +Codex identity marker. Its typography, native form controls, placeholder copy, |
| 151 | +and layout are not product UI and are not visual acceptance evidence. Do not |
| 152 | +return a screenshot of that fixture as proof that #320 or #322 is fixed; the |
| 153 | +manual checks below must use the real current Codex app. |
| 154 | + |
| 155 | +## Manual import checks (#318) |
| 156 | + |
| 157 | +Use ZIPs that contain non-empty `theme.json`, `theme.css`, and one registered |
| 158 | +background image. Importing a ZIP must not change the currently active theme. |
| 159 | + |
| 160 | +1. Import version A, then import a modified version B with the same |
| 161 | + `theme.json.id`. |
| 162 | +2. Confirm the second notification says that the saved theme was updated. |
| 163 | +3. Confirm the Gallery has one entry for that ID and |
| 164 | + `%LOCALAPPDATA%\CodexDreamSkin\themes\` has no newly-created `id-2` folder. |
| 165 | +4. Import version B again. It must report an exact duplicate and write nothing. |
| 166 | +5. Reproduce an old exact `id` plus `id-2` duplicate, then import that same |
| 167 | + semantic package. It must consolidate to the canonical `id` directory. |
| 168 | +6. Create an independent `id-2` theme with different content, even with the |
| 169 | + same display name. Importing `id` must preserve the independent `id-2`. |
| 170 | +7. Put a normal file at a candidate canonical theme path. Import must fail and |
| 171 | + leave that file byte-for-byte unchanged. |
| 172 | +8. Import packages whose source ID is missing, non-string, or Windows-reserved. |
| 173 | + Each must receive the documented stable fallback ID and a later equivalent |
| 174 | + package must update that same directory. Invalid payloads must fail before |
| 175 | + the existing canonical directory is moved. |
| 176 | +9. Simulate or retain an obsolete hidden `.theme-replace-*` recovery copy. |
| 177 | + The committed new theme may report a cleanup warning, but no dotted |
| 178 | + transaction directory may appear in the tray's saved-theme menu. |
| 179 | + |
| 180 | +After each case, confirm there are no hidden `.theme-import-*`, |
| 181 | +`.theme-replace-*`, `.theme-legacy-cleanup-*`, or `.theme-failed-*` residues. |
| 182 | +If an import fails, the previous canonical theme must still open and its |
| 183 | +semantic fingerprint must be unchanged. Any rollback or cleanup failure must |
| 184 | +be reported explicitly; it must not be silently swallowed. |
| 185 | + |
| 186 | +## Renderer and target checks (#320/#322) |
| 187 | + |
| 188 | +Use the source-installed engine verified above, then launch the current official |
| 189 | +Microsoft Store Codex through DreamSkin. Do not test an older Setup.exe. |
| 190 | + |
| 191 | +1. Apply at least three complete community themes with different Safe CSS, |
| 192 | + backgrounds, and token sets. Do not limit this to colors-only themes. |
| 193 | +2. Check Home and a normal task view. Main content, sidebar, home surface, and |
| 194 | + composer must receive the intended shared styling without styling search, |
| 195 | + settings, modal, or unrelated textbox containers as the composer. |
| 196 | + Include a view where a search textbox occurs in DOM order before the prompt |
| 197 | + composer; the prompt composer must still receive `data-ds-part="composer"`. |
| 198 | +3. On Codex `26.727.40816` or newer, confirm the real outer main surface has the |
| 199 | + theme background from the very top of the window. There must be no native |
| 200 | + white strip or white top-fade left behind. The header controls must remain |
| 201 | + visible and keep their native fixed position while scrolling. |
| 202 | +4. Confirm the installed verification output reports `scope.level` as `L1` and |
| 203 | + an empty `missingL1` list on both Home and the normal task view. A report that |
| 204 | + only says injection succeeded is insufficient if any required L1 anchor is |
| 205 | + missing. `L0` is accepted only while the Settings route is visibly replacing |
| 206 | + the normal shell; it is never a successful Home or task-view result. |
| 207 | +5. Confirm sidebar navigation, project selection, task content, composer input, |
| 208 | + and send controls remain interactive and readable. |
| 209 | +6. Include at least one full-wallpaper theme whose Safe CSS sets a root or main |
| 210 | + `background-color`. Its registered wallpaper must remain visible. Also test |
| 211 | + a theme using `blur(21px..30px)` with bounded `saturate`, `brightness`, or |
| 212 | + `contrast`; it must import and render instead of being rejected by the |
| 213 | + client validator. |
| 214 | +7. Run the installed verification script and save its screenshot: |
| 215 | + |
| 216 | + ```powershell |
| 217 | + powershell.exe -NoLogo -NoProfile -ExecutionPolicy RemoteSigned ` |
| 218 | + -File "$env:LOCALAPPDATA\CodexDreamSkin\engine\scripts\verify-dream-skin.ps1" ` |
| 219 | + -ScreenshotPath "$env:TEMP\dreamskin-pr324.png" |
| 220 | + ``` |
| 221 | + |
| 222 | +8. Restart Codex, reapply a theme, and verify again. A visible real Codex |
| 223 | + `app://` renderer must pass exact payload, theme ID, and revision checks. |
| 224 | +9. The automated bootstrap negative fixture must still reject an unbranded |
| 225 | + `app://` page with only generic main/input structure. Loopback endpoints not |
| 226 | + owned by the verified Codex package must also remain rejected. |
| 227 | + |
| 228 | +Windows confirms the shared runtime and Windows adapter. It does not by itself |
| 229 | +prove the macOS-specific issue report on Codex 26.727.40816; that remains a |
| 230 | +separate macOS/user acceptance check before release. |
| 231 | + |
| 232 | +## Result to return |
| 233 | + |
| 234 | +Report all of the following: |
| 235 | + |
| 236 | +- exact PR commit SHA; |
| 237 | +- Windows edition/build, Codex version, and Node version; |
| 238 | +- Windows PowerShell 5.1 result and optional PowerShell 7 result; |
| 239 | +- first import, same-ID update, exact duplicate, legacy cleanup, independent |
| 240 | + suffix preservation, file-collision, fallback-ID, rollback, cleanup-warning, |
| 241 | + and hidden-directory menu-filter results; |
| 242 | +- the names of the three non-colors-only themes used for renderer testing; |
| 243 | +- wallpaper-preservation, composite-filter, and search-before-composer results; |
| 244 | +- verification output, screenshot path, and whether restart/reapply passed; |
| 245 | +- confirmation that the screenshot came from the real Codex app, not the |
| 246 | + generic renderer fixture; |
| 247 | +- sanitized `injector.log`, `injector-error.log`, and `verify.log` excerpts for |
| 248 | + any failure. Remove tokens, private paths, and conversation content. |
0 commit comments