Skip to content

fix(reachability): whole-identifier API-route match (kill substring false-green)#202

Open
agjs wants to merge 2 commits into
mainfrom
fix/reachability-api-route-boundary
Open

fix(reachability): whole-identifier API-route match (kill substring false-green)#202
agjs wants to merge 2 commits into
mainfrom
fix/reachability-api-route-boundary

Conversation

@agjs

@agjs agjs commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Problem

checkFeatureReachable (the static anti-hollow-feature check, #50 class) verified API registration with a bare substring:

!inputs.apiRoutes.includes(`${camel}Routes`)

So a feature named count matched an unrelated slice's accountRoutes (accountcount) and was reported reachable even when its own countRoutes mount was genuinely absent — a false green in the very check meant to catch unregistered features. Same defect class as #201 (fieldIsMentioned), but higher-severity: it lets a truly-unreachable feature pass rather than fabricating a spurious test. (The UI check on the same function is safe — its / path delimiters block the suffix collision.)

Fix

Match ${camel}Routes as a whole identifier via boundary lookarounds over the JS IdentifierPart set — [\p{ID_Continue}$] — the same idiom as fieldIsMentioned. Every real mount idiom still matches (count: countRoutes, .use(countRoutes), [countRoutes]); a substring (accountRoutes) or $-glued ($countRoutes) sibling does not. $ is added because \p{ID_Continue} omits it; _/ZWJ/ZWNJ are already in \p{ID_Continue} (verified at runtime).

Tests

Three regression tests: substring sibling (accountRoutes present, count absent → flagged), $-prefixed sibling ($countRoutes → flagged), and superstring co-registration (account+count both mounted → count reachable). 12/12 pass, lint + typecheck clean.

Review

Local 4-model harness-review panel: PASS (4/4). Two advisory findings (agreement 1) both claimed \p{ID_Continue} excludes ZWJ/ZWNJ — empirically false (bun -e confirms ZWJ ∈ ID_Continue and the regex rejects other\u200DcountRoutes); the one real gap ($) was incorporated.

agjs added 2 commits July 25, 2026 13:56
…alse-green)

The API-registration check used a bare `apiRoutes.includes(`${camel}Routes`)`, so a
feature named `count` matched an unrelated slice's `accountRoutes` (`account` ⊃ `count`)
and was reported reachable even when its own `countRoutes` mount was genuinely absent — a
false green in the very check meant to catch unregistered (hollow) features (#50 class).

Guard the match with \p{ID_Continue} boundary lookarounds (same idiom as fieldIsMentioned),
so only a whole-identifier mount counts, while every real idiom (`count: countRoutes`,
`.use(countRoutes)`, `[countRoutes]`) still matches. Adds two regression tests.
…rPart)

Panel advisory: \p{ID_Continue} omits $, a valid JS IdentifierPart, so $countRoutes
(a distinct identifier) matched as a whole-word countRoutes. Add $ to the boundary class
— the exact JS IdentifierPart set (ID_Continue already covers _, ZWJ, ZWNJ, verified at
runtime). Adds a $-prefixed-sibling regression test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant