* feat(rules): add 8 mined correctness, performance, a11y, and security rules
Mined from a 12-cluster pass over the design/engineering brain and
synthesized into docs/rule-candidates-backlog.md. Ships the highest-signal,
lowest-noise batch, each with adversarial + FP-regression tests:
- no-call-component-as-function (Bugs)
- no-create-ref-in-function-component (Bugs)
- no-async-effect-callback (Bugs)
- no-json-parse-stringify-clone (Performance)
- img-missing-dimensions (Performance)
- no-img-lazy-with-high-fetchpriority (Performance)
- dialog-has-accessible-name (Accessibility)
- auth-token-in-web-storage (Security)
Adds the shared has-jsx-spread-attribute util and registers the three
in-house ported-bucket rules in RULES_NOT_PORTED_FROM_EXTERNAL.
* fix(rules): drop img-missing-dimensions; make component rules shadow-safe
- Drop `img-missing-dimensions`: width/height attributes are only one of
several valid ways to reserve space (CSS aspect-ratio, container sizing),
and the authoritative signal lives in stylesheets a static linter can't
see. This is a runtime check (Lighthouse `unsized-images`), so a syntax
rule would false-positive on any CSS-sized image.
- `no-call-component-as-function`: resolve the callee through its scope
symbol instead of by name, so a parameter/local shadowing a component
name is no longer flagged. The component signal is the binding's
declaration (same-file component returning JSX) or an imported binding
also rendered as JSX.
- `no-create-ref-in-function-component`: skip a shadowing local `createRef`
(only flag React's import / `React.createRef`).
- Adds shadow-safety regression tests for both.
* fix(rules): tag no-call-component-as-function test-noise (eval finding)
An OSS eval sweep (react-use, radix primitives, excalidraw, mantine;
~2.8k diagnostics) showed every real-world hit of this rule was a test
render-helper (`render(Wrapper({...}))` in `.test.tsx`/`.story.tsx`) —
harmless for hookless wrappers and the dominant firing surface. Tag it
`test-noise` so it skips test/story/playground files and only nags
shipped code. The sweep also confirmed dialog-has-accessible-name (2 real
a11y bugs in excalidraw) and no-create-ref-in-function-component (1 real
bug in a mantine story) as true positives with zero false positives.