diff --git a/src/app/api/insights/coach-read/route.ts b/src/app/api/insights/coach-read/route.ts index 149f0d951..82fe83c57 100644 --- a/src/app/api/insights/coach-read/route.ts +++ b/src/app/api/insights/coach-read/route.ts @@ -20,6 +20,7 @@ import { apiHandler, requireAuth } from "@/lib/api-handler"; import { annotate } from "@/lib/logging/context"; import { checkAnalyticsReadRateLimit } from "@/lib/rate-limit"; import { requireModuleEnabled } from "@/lib/modules/gate"; +import { requireAssistantSurface } from "@/lib/feature-flags"; import { measurementTypeEnum } from "@/lib/validations/measurement"; import { buildCoachReadStrip } from "@/lib/insights/derived/coach-read"; import type { MeasurementType } from "@/generated/prisma/client"; @@ -36,6 +37,11 @@ export const GET = apiHandler(async (request: NextRequest) => { const m = await requireModuleEnabled(user.id, "insights"); if (!m.enabled) return m.response; + // The strip is the ambient Coach presence on the metric page, so it + // gates on the Coach assistant matrix too: an operator who turns the + // Coach off must not see a "Coach read" line linger. + await requireAssistantSurface("coach"); + // Shared analytics-read budget — generous; caps a runaway navigation loop. const rl = await checkAnalyticsReadRateLimit(user.id); if (!rl.allowed) { diff --git a/src/app/api/insights/coach/seeded-question/route.ts b/src/app/api/insights/coach/seeded-question/route.ts index 42bc23ad9..6fdba6eb7 100644 --- a/src/app/api/insights/coach/seeded-question/route.ts +++ b/src/app/api/insights/coach/seeded-question/route.ts @@ -22,6 +22,7 @@ import { apiHandler, requireAuth } from "@/lib/api-handler"; import { annotate } from "@/lib/logging/context"; import { checkAnalyticsReadRateLimit } from "@/lib/rate-limit"; import { requireModuleEnabled } from "@/lib/modules/gate"; +import { requireAssistantSurface } from "@/lib/feature-flags"; import { prisma } from "@/lib/db"; import { loadBaselineProfile } from "@/lib/insights/derived"; import { detectDerivedBriefingSignals } from "@/lib/insights/derived-briefing"; @@ -50,6 +51,10 @@ export const GET = apiHandler(async () => { const m = await requireModuleEnabled(user.id, "insights"); if (!m.enabled) return m.response; + // The opener feeds the Coach hero, so it gates on the Coach assistant + // matrix: with the Coach off there is no hero to seed. + await requireAssistantSurface("coach"); + const rl = await checkAnalyticsReadRateLimit(user.id); if (!rl.allowed) { return apiError("Too many analytics requests. Please retry later.", 429);