--- type: Fixed pr: 2397 --- **api-coverage detector no longer false-positives non-API phases (and no longer fails open)** — the external-API-integration detector behind the blocking `verify:pre` seal gate required only same-line co-occurrence of an integration verb and an API noun, treated `/` as a word boundary (so first-party Next.js `src/app/api/…` route paths matched), and read any capitalized word before API/SDK/REST/GraphQL as a service name (so threat-model prose like "Resolver-only API" fired). It is now **fail-closed**: the compound rule requires the integration verb and API noun to share one clause (the clause boundary is the whole relationship test — no fragile word-gap cap that a genuine long integration clause would trip); fenced code, inline code spans, and path-shaped tokens are excluded before matching while external hosts like `api.stripe.com/v1` still count; and the ` API` surface rule rejects stopwords, locality/protocol descriptors ("Internal API", "REST API"), compound modifiers, and first-party-qualified services, so a real vendor name (`Stripe API`) fires from any clause position. A phase that integrates no external API can declare it first-class in `COVERAGE.md` — `No external API integration: ` — instead of fabricating a matrix row; when the detector still finds signals, the declaration overrides but the gate surfaces the overridden signals so the contradiction is visible. Because a false positive is cheaply dismissed by that declaration while a false negative silently slips a real API phase past the gate, the detector deliberately leans toward detecting. (#2365)