## Defect
In `packages/tool-server/src/utils/react-profiler/pipeline/03-tag.ts`,
the animation-detection regex was both unanchored and case-insensitive:
```ts
const ANIMATED_PATTERN = /(Animated|Animation|Transition|Motion)/i;
```
Because of the `/i` flag, the token `Motion` matches the lowercase
substring "motion" that appears inside perfectly ordinary PascalCase
component names: `PromotionCard`, `EmotionThemeCard`, `CommotionList`,
`LocomotionView`, and so on. Those components get tagged `isAnimated =
true` in stage 3, and stage 4 (`04-rank.ts`) then unconditionally drops
every animated component from the findings (`if (comp.isAnimated)
continue;`).
The result: a genuinely slow or frequently re-rendering component such
as `PromotionCard` silently disappears from the report's Top Components
/ Suggested Improvements, even though it is exactly the kind of
component the profiler exists to surface. `ProductCard` (no "motion"
substring) is handled correctly, which is what makes the bug easy to
miss.
## Fix
Dropping only the `/i` flag removes the lowercase-embedded false
positives, but still mis-tags acronym/number-glued names such as
`SVGAnimatedPath`, `RNAnimatedView`, and `MotionlessIndicator`. So the
committed pattern anchors the token to a genuine PascalCase segment
boundary:
```ts
const ANIMATED_PATTERN = /(?<![A-Z0-9])(Animated|Animation|Transition|Motion)(?=[A-Z0-9_(.]|$)/;
```
- **Case-sensitive**, so a lowercase-embedded "motion" (`PromotionCard`,
`Emotion`, `Locomotion`) never contains the capitalized token.
- The leading `(?<![A-Z0-9])` rejects acronym/number-glued prefixes
(`SVGAnimatedPath`, `RNAnimatedView`, `CMMotionManager`,
`G2MotionSensor`) where the token is not a real PascalCase word-start.
- The trailing `(?=[A-Z0-9_(.]|$)` requires the token to end a segment —
another capitalized word, a digit/underscore, `(` or `.` (HOC/dotted
display names like `Animated(View)`, `Animated.View`), or end-of-string
— so it still matches real names while rejecting tokens that bleed into
more lowercase (`MotionlessIndicator`).
**Known limitation:** a bare `Motion` starting a PascalCase word
(`MotionSensor`, `MotionManager`) still matches — it is structurally
indistinguishable from a real animation name of the same shape
(`MotionView`, and `@legendapp/motion`'s `Motion.View`) that we intend
to tag. This over-tag is accepted collateral (it only excludes a
component from perf findings); a hardcoded device-motion denylist would
be more fragile than the rare false positive it removes. The behavior is
documented in the code comment and pinned by a test.
## Tests
`packages/tool-server/test/react-profiler-animated-pattern.test.ts`
covers:
- lowercase-embedded false positives (`PromotionCard`,
`EmotionThemeCard`, `CommotionList`, `ProductCard`) → `isAnimated =
false`, and `PromotionCard` reappears in `rank()` findings;
- real animation components (`Animated`, `AnimatedView`, `MotionView`,
`FadeTransition`, dotted/HOC forms) → `isAnimated = true`;
- acronym-prefixed and digit-suffixed device-motion names
(`CMMotionManager`, `G2MotionSensor`, …) → `isAnimated = false`;
- the accepted bare-`Motion` device-name over-tag (`MotionSensor`,
`MotionManager`, `MotionDetector`, `MotionTracker` → `isAnimated =
true`), pinned so any future change is deliberate.
The suite fails against the old `/i` regex and passes with the fix. `tsc
--build` and ESLint on the changed files are clean.