Require shared helpers to be declared in every file that calls them

The surface widening in this branch turned per-file helper contracts into
surface-wide ones. QML and JS files share no function scope, so main.qml,
NotificationMemo.js and ProviderIdentity.js each declare their own hasOwnKey;
`require_in_surface "function hasOwnKey(item, key)"` is satisfied by any one of
them. Renaming main.qml's declaration while its 21 callers stayed put left the
applet with a ReferenceError and `make check` green — the exact regression class
these checks exist to catch. qmllint runs with `--unqualified disable`, so it
does not cover the gap either.

require_definition_where_used asserts the declaration in every file that calls
the helper unqualified, plus the surface root when components reach it through
`applet.foo(...)` (ProviderHeader calls applet.contrastTextColor). Its optional
body fragment is required inside every copy, so the prototype-pollution guard is
now enforced on each declaration rather than on whichever one a search reached
first. The rule still follows the code: a probe moving hasOwnKey and a caller
into contents/ui/controllers/ keeps the suite green, and the same file calling
it without declaring it fails.

Applied to the three assertions the sweep found weakened: hasOwnKey (with its
Object.prototype.hasOwnProperty.call guard), contrastTextColor, and
boundedDisplayText. Four mutations that previously passed now fail `make check`;
clean tree passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
b53dbd0a45Simone committed on 8/17/2026, 9:50:52 PMparentc60a053

Checks

All checks passed
6 files changedLine totals unavailable