Same defect class as gate-64 in #184 — "a checker that greps a STRING LITERAL misses every constant and matches every comment — it fails BOTH ways at once." gate-34 has it too.
Found while clearing gate-34 on ConductionNL/doriath (#182). After the native call was genuinely replaced with an NcDialog, gate-34 still failed — pointing at the explanatory comment I had written about the replacement.
Reproduction
Four arms, run against hydra-gates/scripts/run-hydra-gates.sh at main (756fe89). Each arm is a single .vue file; only that file changes between arms.
Arm 1 — comment mentions it, zero real calls → false RED
<template>
<div>
<!-- This component deliberately avoids window.confirm() and uses NcDialog. -->
<NcDialog :open="open" />
</div>
</template>
[gate-34] window-confirm: FAIL — 1 native dialog call(s) — use NcDialog / CnFormDialog
Arm 2 — same file, comment deleted → PASS (control: proves arm 1's finding is the comment)
[gate-34] window-confirm: PASS
Arm 3 — a REAL native confirm via bracket access → false GREEN
if (!window['confirm']('Delete everything?')) {
return
}
this.destroy()
[gate-34] window-confirm: PASS
Arm 4 — the same code as window.confirm(...) → FAIL (control: proves the probe can fire)
[gate-34] window-confirm: FAIL — 1 native dialog call(s)
Why each direction hurts
- False RED (arm 1) punishes exactly the code that did the right thing, and teaches people that the way to clear gate-34 is to not write down why. That is a direct incentive against explanatory comments in the one place they are most useful.
- False GREEN (arm 3) is the serious one.
window['confirm'], const c = window.confirm, and destructured const { confirm } = window all sail through. On doriath the native call being replaced guarded a cascading delete — the exact case where a silently-unenforced gate matters.
Note that arm 3 is not a contrived bypass: window['confirm'] is what several minifiers and some lint autofixes emit, and destructuring is ordinary style.
Suggested fix
Strip comments and string literals before matching, and match on member access rather than a fixed spelling — i.e. detect confirm / alert / prompt as a property of window (dot or bracket), plus bare confirm( at call position, after comment/string removal. The gate-64 fix in #184 already had to do the comment-stripping half; this is the same helper.
Worth checking whether the sibling text-matching gates have the same hole — at minimum gate-2 (forbidden-patterns) and gate-48 (csrf-cochange, already known to match a REMOVED comment per #191) look like the same family.
Workaround in the meantime
Reword the prose so it does not contain the literal spelling. That is what doriath#182 does, and it is obviously the wrong lever — the code is correct either way.
Same defect class as gate-64 in #184 — "a checker that greps a STRING LITERAL misses every constant and matches every comment — it fails BOTH ways at once." gate-34 has it too.
Found while clearing gate-34 on ConductionNL/doriath (#182). After the native call was genuinely replaced with an
NcDialog, gate-34 still failed — pointing at the explanatory comment I had written about the replacement.Reproduction
Four arms, run against
hydra-gates/scripts/run-hydra-gates.shatmain(756fe89). Each arm is a single.vuefile; only that file changes between arms.Arm 1 — comment mentions it, zero real calls → false RED
Arm 2 — same file, comment deleted → PASS (control: proves arm 1's finding is the comment)
Arm 3 — a REAL native confirm via bracket access → false GREEN
Arm 4 — the same code as
window.confirm(...)→ FAIL (control: proves the probe can fire)Why each direction hurts
window['confirm'],const c = window.confirm, and destructuredconst { confirm } = windowall sail through. On doriath the native call being replaced guarded a cascading delete — the exact case where a silently-unenforced gate matters.Note that arm 3 is not a contrived bypass:
window['confirm']is what several minifiers and some lint autofixes emit, and destructuring is ordinary style.Suggested fix
Strip comments and string literals before matching, and match on member access rather than a fixed spelling — i.e. detect
confirm/alert/promptas a property ofwindow(dot or bracket), plus bareconfirm(at call position, after comment/string removal. The gate-64 fix in #184 already had to do the comment-stripping half; this is the same helper.Worth checking whether the sibling text-matching gates have the same hole — at minimum gate-2 (forbidden-patterns) and gate-48 (csrf-cochange, already known to match a REMOVED comment per #191) look like the same family.
Workaround in the meantime
Reword the prose so it does not contain the literal spelling. That is what doriath#182 does, and it is obviously the wrong lever — the code is correct either way.