Commit b49d873
fix(viewer): make the frontend build hermetic and actually verify dist/
The committed viewer bundle is 424 KB of minified JS that no reviewer can
read. CI's job is to prove it is exactly what building the committed source
produces, so the bundle stays a derived value rather than a trust input. Two
independent defects meant it was not proving that.
1. The build was self-referential. dist/ is tracked, so Tailwind v4's
automatic source detection scanned the PREVIOUS bundle and treated words
inside it as class-name candidates. `npm run build` over a populated dist/
emitted three utilities a clean build does not (.static, .table, .resize),
making the committed state a fixed point rather than a function of src/.
CI therefore passed only because it built on top of the very artifact it
was verifying, and a contributor could steer the emitted CSS by planting
strings in dist/ instead of in reviewable source.
`@source not '../dist'` in src/index.css makes the build a pure function of
src/. Verified identical output across a clean dist/, a populated dist/, and
a dist/ seeded with decoy class names. dist/ is regenerated here; the only
CSS delta is the removal of those three utilities, which no source file
uses (resize-y and resize-none are separate utilities and are unaffected).
2. The staleness check used `git diff --quiet`, which only reports tracked,
modified files. A PR that ADDS a file to dist/ passed it cleanly —
confirmed by committing a dist/assets/evil.js, which the old check waved
through. It now builds into an emptied dist/ and uses `git status
--porcelain`, which reports modified, added and missing files alike.
Output was verified byte-identical on Node 20.19.5 and 22.20.0; the job now
pins the version exactly, since its output is the security property.
This check is only meaningful if it cannot be skipped. For `pull_request`
GitHub runs the workflow as written in the PR, so a PR can delete this job:
it must be configured as a required status check on main, which is tracked
separately along with CODEOWNERS on package*.json.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1 parent 72b243c commit b49d873
6 files changed
Lines changed: 74 additions & 9 deletions
File tree
- .github/workflows
- src/nooa/viewer/frontend-react
- dist
- assets
- src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
65 | 78 | | |
66 | 79 | | |
| 80 | + | |
| 81 | + | |
67 | 82 | | |
68 | 83 | | |
69 | 84 | | |
70 | 85 | | |
71 | 86 | | |
72 | | - | |
73 | | - | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
74 | 92 | | |
75 | 93 | | |
| 94 | + | |
76 | 95 | | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
77 | 104 | | |
78 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
79 | 108 | | |
80 | | - | |
81 | | - | |
82 | | - | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
83 | 132 | | |
84 | 133 | | |
| 134 | + | |
85 | 135 | | |
86 | 136 | | |
87 | 137 | | |
| |||
Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
| 7 | + | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
4 | 19 | | |
5 | 20 | | |
6 | 21 | | |
| |||
0 commit comments