test(ui): semantic defect gate for inline scripts (#111 hardening)#113
Merged
jmagly merged 1 commit intoJul 26, 2026
Merged
Conversation
hardening) elder-plinius#111 shipped 8 bad-auto-merge scars into the SPA past a CI that only ever lints/tests `src/` — the 27k-line docs/index.html had (and still has) no static gate. The parse test added with the elder-plinius#111 fix catches outright syntax failures; this adds the *semantic* layer that parsing misses. It runs ESLint's high-precision "possible problem" rules programmatically over each inline <script> (no new dependency — `eslint` is already a devDependency; no eslint.config or CI change — rides the existing `npm test`): no-redeclare, no-unreachable, no-dupe-keys, no-dupe-args, no-dupe-else-if, no-duplicate-case, no-const-assign, no-import-assign, no-class-assign — the exact shapes a conflict-concatenating merge leaves behind. Tight, always-a-bug rules, each script linted in isolation → zero false positives on the real file. no-undef / no-unused-vars are excluded (the SPA relies on cross-<script> and browser globals a per-block lint can't see) and no-func-assign is excluded (the app legitimately monkey-patches navigateTo). Verified: 0 findings on the fixed tree, and it rejects the pre-fix main (catches the duplicate `response`). Full suite green. Also drops a now-unused eslint-disable directive in the parse test.
lyubomir-bozhinov
force-pushed
the
ci/frontend-defect-gate
branch
from
July 25, 2026 12:15
210d726 to
837f3c7
Compare
jmagly
approved these changes
Jul 26, 2026
jmagly
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed PR #113 at 837f3c7cd2cc5288eaa3be226fc0947789a6cff3.
No blocking findings.
Verification:
- GitHub Actions T3MP3ST CI / test: success
- npm run typecheck: pass
- focused UI gate: 3/3 pass
- npm run lint: 0 errors, baseline warnings only
- Public-input threat preflight: low risk
The semantic rules are narrowly scoped to high-confidence defects and complement the syntax gate without adding a dependency.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✅ Now standalone — #112 has merged
Its dependency (#112, the fix for #111) merged on 2026-07-24, so I've rebased this onto current
main. The diff is now just the one new commit — a single test file, +49/−1.Chain: #111 (issue) → #112 (fix, merged) → this PR (the CI gate that stops #111 from recurring).
What & why
#111 shipped 8 conflict-concatenation scars into the 27,000-line SPA — and sailed straight through CI, because
lint/testonly ever look atsrc/. The product's primary surface has no static gate at all. #112's fix added avm.Scriptparse test (catches outright syntax breakage). This PR adds the semantic layer parsing can't see — the shapes a bad auto-merge leaves behind that still parse but are always bugs.The gate
A new check in the existing test file runs ESLint's high-precision "possible problem" rules over each inline
<script>:no-redeclare,no-unreachable,no-dupe-keys,no-dupe-args,no-dupe-else-if,no-duplicate-case,no-const-assign,no-import-assign,no-class-assign.Deliberately minimal, additive, dependency-free:
eslintis already a devDependency; used via itsLinterAPI.eslint.config.jsorci.ymlchange — rides the existingnpm test.Precision over recall — each script is linted in isolation and the rule set is only "always-a-bug" checks, so it's false-positive-free on the real file. Two rules are excluded, reasons documented in-code:
no-undef/no-unused-vars— the SPA relies on hundreds of cross-<script>and browser globals a per-block lint can't see (would flood).no-func-assign— the app legitimately monkey-patchesnavigateTo(wraps it to add CTF-range init).Validation
main(no false positives).response).tsc --noEmitclean;npm run lintadds 0 errors/warnings; full suite 647 green.Relates to #111 / #112.