From 7c085c8c9d5eb79e94ebc02343fa058ec05e2092 Mon Sep 17 00:00:00 2001 From: PJ Date: Sun, 16 Aug 2026 01:08:19 +0530 Subject: [PATCH] docs(skills): web selectors are exact, native ones are substrings --- skills/sanderling-spec-review/SKILL.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/skills/sanderling-spec-review/SKILL.md b/skills/sanderling-spec-review/SKILL.md index 4bef943..4307afa 100644 --- a/skills/sanderling-spec-review/SKILL.md +++ b/skills/sanderling-spec-review/SKILL.md @@ -86,12 +86,20 @@ function of that string can separate them. **Match whole keys, not endings or substrings.** `endsWith` attribution judges an older account named `Emergency Fund` when the user typed `Fund`. -Selector matching has the same trap and it is easy to miss which keys carry it. -`id`, `text`, `desc` and `descPrefix` resolve by their own rules, so `{id: "Sub"}` -correctly matches nothing. Every other key, `testTag` included, falls through to a -substring compare, so `{testTag: "Sub"}` matches `AddAccountSubmit`. That is not a -match, it is a coincidence, and a property built on it judges whichever element -happens to contain the fragment. +Selector matching has the same trap on Android and iOS, and it is easy to miss +which keys carry it. `id`, `desc` and `descPrefix` resolve by rules of their own +(exact or `:id/`-suffixed, exact or comma-prefixed, starts-with), so +`{id: "Sub"}` correctly matches nothing. Every other key, `text` and `testTag` +included, falls through to a substring compare, so `{testTag: "Sub"}` matches +`AddAccountSubmit`. That is not a match, it is a coincidence, and a property +built on it judges whichever element happens to contain the fragment. + +The web path does not share the rule, which is its own trap. `web-runtime.ts` +compiles an object selector to CSS, and every key becomes an exact attribute +match (`descPrefix` alone becomes a `^=` prefix). So the loose selector that +resolved on Android resolves to nothing on web, and every property over it goes +vacuously true rather than red. Reviewing a cross-platform spec means checking +that each selector is exact enough for native and literal enough for web. **Drop the carrier when the screen changes.** A value carried across a route change is a value read from a screen that is no longer there.