From fa2b8a52c34838038cb3cc1d5274fa8cd74e8765 Mon Sep 17 00:00:00 2001 From: Neil Date: Fri, 18 Sep 2026 20:49:21 -0700 Subject: [PATCH] test(terminal): verify contrast pixels after fresh calculation --- .github/workflows/mobile.yml | 2 + config/scripts/pr-code-change-scope.mjs | 3 +- config/scripts/pr-code-change-scope.test.mjs | 3 + .../README.md | 7 + .../reproduce.mjs | 11 +- .../review-validation.json | 476 ++++++++++++++++++ 6 files changed, 500 insertions(+), 2 deletions(-) create mode 100644 docs/audits/terminal-contrast-cache-retention/review-validation.json diff --git a/.github/workflows/mobile.yml b/.github/workflows/mobile.yml index 47f56009739..968610bfb8d 100644 --- a/.github/workflows/mobile.yml +++ b/.github/workflows/mobile.yml @@ -9,6 +9,7 @@ on: - ready_for_review paths: - 'mobile/**' + - 'config/scripts/xterm-patch-text*' # Mobile launch contracts exercise the real host dispatcher and durable receipt store. - 'src/main/agent-launch/**' - 'src/main/runtime/rpc/**' @@ -46,6 +47,7 @@ on: - main paths: - 'mobile/**' + - 'config/scripts/xterm-patch-text*' - '.github/workflows/mobile.yml' concurrency: diff --git a/config/scripts/pr-code-change-scope.mjs b/config/scripts/pr-code-change-scope.mjs index a2dfcc0082f..a650e74eaa7 100644 --- a/config/scripts/pr-code-change-scope.mjs +++ b/config/scripts/pr-code-change-scope.mjs @@ -73,7 +73,8 @@ const XTERM_PREFIXES = [ 'config/patches/xterm-upstream.json', 'config/patches/@xterm', 'config/patches/xterm-src/', - 'config/scripts/regenerate-xterm-patches' + 'config/scripts/regenerate-xterm-patches', + 'config/scripts/xterm-patch-text' ] const SHELL_PREFIXES = [ diff --git a/config/scripts/pr-code-change-scope.test.mjs b/config/scripts/pr-code-change-scope.test.mjs index 493ac528c26..3b202302f93 100644 --- a/config/scripts/pr-code-change-scope.test.mjs +++ b/config/scripts/pr-code-change-scope.test.mjs @@ -181,6 +181,9 @@ describe('per-job path classification', () => { expectClassification(['config/patches/@xterm__xterm@6.1.0-beta.287.patch'], { xterm_patch_sync: true }) + expectClassification(['config/scripts/xterm-patch-text.mjs'], { + xterm_patch_sync: true + }) expectClassification(['config/scripts/regenerate-xterm-patches-mobile.mjs'], { xterm_patch_sync: true }) diff --git a/docs/audits/terminal-contrast-cache-retention/README.md b/docs/audits/terminal-contrast-cache-retention/README.md index ac4f67cbedf..88ba89db24b 100644 --- a/docs/audits/terminal-contrast-cache-retention/README.md +++ b/docs/audits/terminal-contrast-cache-retention/README.md @@ -80,3 +80,10 @@ The fixed engine stays within 4,096 entries; the baseline exceeds 10,000. - Revisited evicted pairs incur the existing contrast calculation again. No incident report establishes the distinct-color traffic used in this proof; renderer retention does not explain #19768's separately measured main PID. + +The follow-up [review-validation.json](./review-validation.json) reruns both installed +WebGL bundles in normal and dim modes on Node 24.20.0. Its clear/recompute check +also clears the glyph atlas, requires the contrast cache to repopulate, and compares +the probe pixels after fresh calculation. The original before/after measurements +remain in `results.json`. The focused contrast and CI-scope suites pass 41 tests; +changes to the shared patch-text generator now trigger desktop and mobile checks. diff --git a/docs/audits/terminal-contrast-cache-retention/reproduce.mjs b/docs/audits/terminal-contrast-cache-retention/reproduce.mjs index 960874d93fe..63701e1e3ee 100644 --- a/docs/audits/terminal-contrast-cache-retention/reproduce.mjs +++ b/docs/audits/terminal-contrast-cache-retention/reproduce.mjs @@ -171,12 +171,21 @@ try { const afterAtlasClear = entries() cache.clear() const afterThemeClear = entries() + first.addon.clearTextureAtlas() first.addon._renderer.renderRows(0, 0) + const afterRecompute = entries() const recomputedProbePixels = window.glyphAudit.pixelHash(first, 2) - return { beforeAtlasClear, afterAtlasClear, afterThemeClear, recomputedProbePixels } + return { + beforeAtlasClear, + afterAtlasClear, + afterThemeClear, + afterRecompute, + recomputedProbePixels + } }) assert.equal(checks.beforeAtlasClear, checks.afterAtlasClear) assert.equal(checks.afterThemeClear, 0) + assert.ok(checks.afterRecompute > 0) assert.equal(checks.recomputedProbePixels, samples[0].contrastProbePixels) results.push({ phase, diff --git a/docs/audits/terminal-contrast-cache-retention/review-validation.json b/docs/audits/terminal-contrast-cache-retention/review-validation.json new file mode 100644 index 00000000000..5dd40dd222d --- /dev/null +++ b/docs/audits/terminal-contrast-cache-retention/review-validation.json @@ -0,0 +1,476 @@ +{ + "node": "v24.20.0", + "browser": "146.0.7680.0", + "webglSha256": "c4b646075065e9ed5f885880ff80e2edd54f481f982adaf193cc742de17e1a4f", + "atlasClearEveryUpdates": 1000, + "results": [ + { + "phase": "after", + "format": "cjs", + "mode": "normal", + "sha256": "5a40045331d16d5c30e558576a07f6b13c7d9aa0c9027211af78b12a10ad8f12", + "samples": [ + { + "contrastProbePixels": 482738276, + "contrast": 2, + "dimContrast": 0, + "updates": 0, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 95, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3350996 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1002, + "dimContrast": 0, + "updates": 1000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1095, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3913560 + }, + { + "contrastProbePixels": 482738276, + "contrast": 907, + "dimContrast": 0, + "updates": 5000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 4, + "shared": true, + "preserved": true, + "heap": 3839976 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1814, + "dimContrast": 0, + "updates": 10000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 9, + "shared": true, + "preserved": true, + "heap": 3959172 + }, + { + "contrastProbePixels": 482738276, + "contrast": 873, + "dimContrast": 0, + "updates": 50000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 49, + "shared": true, + "preserved": true, + "heap": 3587688 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1746, + "dimContrast": 0, + "updates": 100000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 99, + "shared": true, + "preserved": true, + "heap": 3623580 + } + ], + "checks": { + "beforeAtlasClear": 1746, + "afterAtlasClear": 1746, + "afterThemeClear": 0, + "afterRecompute": 3, + "recomputedProbePixels": 482738276 + } + }, + { + "phase": "after", + "format": "cjs", + "mode": "dim", + "sha256": "5a40045331d16d5c30e558576a07f6b13c7d9aa0c9027211af78b12a10ad8f12", + "samples": [ + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1, + "updates": 0, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 5, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 4, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3303056 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1001, + "updates": 1000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1095, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 4044360 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 905, + "updates": 5000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 4, + "shared": true, + "preserved": true, + "heap": 3867648 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1811, + "updates": 10000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 9, + "shared": true, + "preserved": true, + "heap": 3951968 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 860, + "updates": 50000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 49, + "shared": true, + "preserved": true, + "heap": 3623496 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1721, + "updates": 100000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 99, + "shared": true, + "preserved": true, + "heap": 3656200 + } + ], + "checks": { + "beforeAtlasClear": 1721, + "afterAtlasClear": 1721, + "afterThemeClear": 0, + "afterRecompute": 2, + "recomputedProbePixels": 3123285829 + } + }, + { + "phase": "after", + "format": "esm", + "mode": "normal", + "sha256": "f644ab7b834e7866be59b48fd35456b4350554f22b6cc815bcdba00d36a2d827", + "samples": [ + { + "contrastProbePixels": 482738276, + "contrast": 2, + "dimContrast": 0, + "updates": 0, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 95, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3250568 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1002, + "dimContrast": 0, + "updates": 1000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1095, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3810892 + }, + { + "contrastProbePixels": 482738276, + "contrast": 907, + "dimContrast": 0, + "updates": 5000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 4, + "shared": true, + "preserved": true, + "heap": 3742124 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1814, + "dimContrast": 0, + "updates": 10000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 9, + "shared": true, + "preserved": true, + "heap": 3856056 + }, + { + "contrastProbePixels": 482738276, + "contrast": 873, + "dimContrast": 0, + "updates": 50000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 49, + "shared": true, + "preserved": true, + "heap": 3606684 + }, + { + "contrastProbePixels": 482738276, + "contrast": 1746, + "dimContrast": 0, + "updates": 100000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 99, + "shared": true, + "preserved": true, + "heap": 3642024 + } + ], + "checks": { + "beforeAtlasClear": 1746, + "afterAtlasClear": 1746, + "afterThemeClear": 0, + "afterRecompute": 3, + "recomputedProbePixels": 482738276 + } + }, + { + "phase": "after", + "format": "esm", + "mode": "dim", + "sha256": "f644ab7b834e7866be59b48fd35456b4350554f22b6cc815bcdba00d36a2d827", + "samples": [ + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1, + "updates": 0, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 5, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 4, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3371468 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1001, + "updates": 1000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1095, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 94, + "layoutVersion": 0, + "shared": true, + "preserved": true, + "heap": 3795404 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 905, + "updates": 5000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 4, + "shared": true, + "preserved": true, + "heap": 3760004 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1811, + "updates": 10000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 9, + "shared": true, + "preserved": true, + "heap": 3848448 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 860, + "updates": 50000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 49, + "shared": true, + "preserved": true, + "heap": 3829480 + }, + { + "contrastProbePixels": 3123285829, + "contrast": 1, + "dimContrast": 1721, + "updates": 100000, + "firstCellPixels": 638013437, + "secondCellPixels": 395161943, + "regular": 1003, + "combined": 0, + "empty": 0, + "pages": 1, + "glyphs": 3, + "layoutVersion": 99, + "shared": true, + "preserved": true, + "heap": 3670332 + } + ], + "checks": { + "beforeAtlasClear": 1721, + "afterAtlasClear": 1721, + "afterThemeClear": 0, + "afterRecompute": 2, + "recomputedProbePixels": 3123285829 + } + } + ] +}