docs(skills): web selectors are exact, native ones are substrings

This commit is contained in:
pj committed 2026-08-16 01:08:19 +05:30
1 parent 906759dc15
commit 7c085c8c9d
1 file changed
+14 -6
+14 -6
View File
@@ -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.