Skip to content

fix(#2492): html func_start must not anchor a non-executable <script type=...> - #2496

Merged
squid-protocol merged 3 commits into
mainfrom
fix/2492-html-func-start-nonexec-script-type
Aug 30, 2026
Merged

fix(#2492): html func_start must not anchor a non-executable <script type=...>#2496
squid-protocol merged 3 commits into
mainfrom
fix/2492-html-func-start-nonexec-script-type

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Part 2 of #2492 (part 1 — the tree-sitter-audit side — shipped in #2493). Closes #2492.

Problem

A <script> whose type is anything other than a JS MIME type / module / bare is an inert data block the browser never runs — reveal.js text/template slide samples, x-shader/* GLSL, math/tex. GitGalaxy's html func_start (<(script|style)…) anchored a function-analog on those too; for a block with no embedded code the detector recognises, the anchor was left with the bare name script.

In the crucible this was exactly one occurrencescript @ revealjs_decks/demo.html:142 — the sole reproducer of ledger shape html/function/existence/agree[gitgalaxy]_vs[ctags,tree_sitter], and the 1 "extra" dragging html tree-sitter func precision to 97.4%.

Fix — two coordinated changes, one shared denylist

  • language_standards.py: new module-level _HTML_NONEXECUTABLE_SCRIPT_TYPES (the denylist complement of tree_sitter_accuracy_audit.py's _EXECUTABLE_SCRIPT_TYPES allowlist) + HTML_NONEXECUTABLE_SCRIPT_TAG. html func_start gains a Rule-15 negative lookahead over that set — gates the raw structural-signal count (matched against un-shielded source).
  • detector.py: the Mode B slicer (_slice_by_braces) re-applies HTML_NONEXECUTABLE_SCRIPT_TAG against the raw code for the named-function list, because _build_brace_safe_stream blanks every quoted attribute value (incl. type=) out of the safe_code that func_start is matched against there. Keeps struct_func_start and function_count consistent.

Verification (full Differential Scan chain)

Check Result
Standalone regex all KEEP still match (<script>, type="module", type="text/babel", <style>, <script src=>); all SKIP rejected (text/template, x-shader/*, math/tex, application/ld+json, case-insensitive, type not first attr). ReDoS smoke clean at n=20000
html gauntlet (+15 cases) + strict + test_detector.py + test_language_standards_strict.py 226 + 172 pass
ruff / mypy / dead-key / ast-accuracy all clear
crucible_check.py full ~80-repo corpus 6 diffs both modes — every one is the demo.html:142 script removal or its direct ripple (that file's Structural Magnitude 0.04→0.05, the revealjs_decks group mass 0.18→0.19, the global html impact 1.50→1.51). Zero unrelated files or languages
Both golden masters re-blessed (update_golden_master.py --yes per mode)
html ts-accuracy baseline re-blessed: extra_functions 1→0, precision 97.4% → 100%. --all --ci green; summary table regenerated (Html | 100.0% | 100.0%)
tri-comparison chart/ledger/points_of_interest regenerated — agree[gitgalaxy]_vs[ctags,tree_sitter] no longer reproduces; html Func Precision is now a clean GitGalaxy/tree-sitter tie at 37/37 (the transient "tree-sitter leads" state from #2493 is closed)

Docs

docs/language_status/html.md §7 / §9 updated.

🤖 Generated with Claude Code

squid-protocol and others added 3 commits August 30, 2026 13:31
…type=...>

Part 2 of #2492 (part 1, the audit-tool side, shipped in #2493).

A `<script>` whose `type` is anything other than a JS MIME type / `module` /
bare is an inert data block the browser never runs -- reveal.js
`text/template` slide samples, `x-shader/*` GLSL, `math/tex`. GitGalaxy's html
`func_start` (`<(script|style)...`) anchored a function-analog on those too; for
a block with no embedded code the detector recognises, the anchor was left with
the bare name `script`. In the crucible this was exactly one occurrence --
`script` @ revealjs_decks/demo.html:142 -- the sole reproducer of the ledger
shape `html/function/existence/agree[gitgalaxy]_vs[ctags,tree_sitter]`, and the
1 "extra" dragging html tree-sitter func precision to 97.4%.

Fix (two coordinated changes, one shared denylist):
- language_standards.py: new module-level `_HTML_NONEXECUTABLE_SCRIPT_TYPES`
  (the denylist complement of tree_sitter_accuracy_audit.py's
  `_EXECUTABLE_SCRIPT_TYPES` allowlist) + `HTML_NONEXECUTABLE_SCRIPT_TAG`.
  html `func_start` gains a Rule-15 negative lookahead over that type set --
  this gates the raw structural-signal count (matched against un-shielded
  source).
- detector.py: Mode B slicer (`_slice_by_braces`) re-applies
  `HTML_NONEXECUTABLE_SCRIPT_TAG` against the raw `code` for the named-function
  list, because `_build_brace_safe_stream` has blanked every quoted attribute
  value (incl. `type=`) out of the `safe_code` that `func_start` is matched
  against there -- so the lookahead alone can't fire for the named path.
  Keeps `struct_func_start` and `function_count` consistent.

Verification (full Differential Scan chain):
- Standalone regex: all KEEP (`<script>`, `type="module"`, `type="text/babel"`,
  `<style>`, `<script src=>` ...) still match; all SKIP (`text/template`,
  `x-shader/*`, `math/tex`, `application/ld+json`, case-insensitive, `type` not
  first attr) rejected. ReDoS smoke clean at n=20000.
- html extraction gauntlet +15 cases (12 regex, 3 detector-integration) +
  strict: 226 pass. test_detector.py + test_language_standards_strict.py: 172 pass.
- ruff / mypy / dead-key / ast-accuracy: all clear.
- crucible_check.py full ~80-repo corpus: 6 diffs BOTH modes, every one the
  demo.html:142 `script` removal or its direct ripple (that file's Structural
  Magnitude 0.04->0.05, the revealjs_decks group mass 0.18->0.19, the global
  html impact 1.50->1.51) -- zero unrelated files or languages.
- Both golden masters re-blessed (`update_golden_master.py --yes` per mode).
- html ts-accuracy baseline re-blessed: extra_functions 1->0, precision
  97.4%->100%. `--all --ci` green; summary table regenerated (Html 100/100).
- tri-comparison chart/ledger/points_of_interest regenerated: the
  `agree[gitgalaxy]_vs[ctags,tree_sitter]` shape no longer reproduces; html Func
  Precision is now a clean GitGalaxy/tree-sitter tie at 37/37 (the transient
  "tree-sitter leads" state from #2493 is closed).
- docs/language_status/html.md §7/§9 updated.

Closes #2492.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTkRyd9CxYQx42EMBdVkGx
…art-nonexec-script-type

# Conflicts:
#	docs/self_scan/tri_comparison_ledger.json
#	docs/self_scan/tri_comparison_points_of_interest.md
#2494, #2495)

Post-merge regen. Chart/ledger diff vs origin/main is scoped to html:
Func Found 38->37, Func Precision 37/38->37/37 (the demo.html:142 script
over-anchor removed by this branch), tree-sitter no longer sole precision
leader for html. html ledger verdicts preserved through the --ours resolution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VTkRyd9CxYQx42EMBdVkGx
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

@squid-protocol
squid-protocol merged commit ae2d0e8 into main Aug 30, 2026
30 checks passed
@squid-protocol
squid-protocol deleted the fix/2492-html-func-start-nonexec-script-type branch August 30, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Non-executable <script type=...> blocks: audit walk over-counted (fixed), html func_start over-anchors (open)

1 participant