OpenPanel is an open-source web and product analytics platform, an open-source alternative to Mixpanel with optional self-hosting.
This report summarizes scanner evidence for Openpanel-dev/openpanel, a TypeScript project with 7,232 GitHub stars. SynthScan examined 374,716 lines of code across 2203 source files, recording 403 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 1.3 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 348 finding(s).
Are imports declared and package/API names verified? 26 finding(s).
Are wrappers, guards, and repeated structures necessary? 332 finding(s).
Which changes need focused human review? 403 finding(s).
Run additional scans to build a history of the legacy pattern signal. Score changes are not a measure of AI adoption or code quality.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 403 distinct pattern matches across 8 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tooling/gates/conformance/rules.ts | 245 | export function checkCreateServicesCallSites(sources: ParsedSource[]): Metric { | CODE |
| LOW | tooling/gates/conformance/rules.ts | 538 | export function checkModuleScopeConstruction(sources: ParsedSource[]): Metric { | CODE |
| LOW | tooling/gates/conformance/rules.ts | 636 | export function checkSharedPackageIsolation(repoRoot: string): Metric { | CODE |
| LOW | tooling/gates/conformance/rules.ts | 784 | export function checkRpcProceduresWithoutCallers( | CODE |
| LOW | test/retention-fixtures.ts | 268 | export async function teardownRetentionFixtures( | CODE |
| LOW | packages/payments/scripts/sync-subscriptions.ts | 100 | function calculateSubscriptionEndsAt(subscription: { | CODE |
| LOW | packages/payments/src/subscription-state.ts | 94 | export function subscriptionBlocksDashboard(state: SubscriptionState): boolean { | CODE |
| LOW | packages/payments/src/polar.ts | 156 | export function applySubscriptionDiscount( | CODE |
| LOW | packages/core/test/rpc-fixtures.ts | 150 | export function servicesWithProjectAccess(): Services { | CODE |
| LOW | packages/core/src/slug-id.test.ts | 10 | function fixedSessionKeySegmentsInSource(): Set<string> { | CODE |
| LOW | packages/core/src/clients/integrations/discord.ts | 36 | export function sendTestDiscordNotification( | CODE |
| LOW | packages/core/src/shared/ch-dates.ts | 21 | export function convertClickhouseDateToJs(date: string): Date { | CODE |
| LOW | packages/core/src/shared/js-runtime/ast-walker.ts | 35 | export function collectDeclaredIdentifiers(ast: unknown): Set<string> { | CODE |
| LOW | packages/core/src/shared/js-runtime/ast-walker.ts | 69 | function collectPatternIdentifiers( | CODE |
| LOW | packages/core/src/http/client-auth.ts | 127 | async function authenticateAllowedClient( | CODE |
| LOW | packages/core/src/http/query.ts | 42 | export function parseQueryStringTransform({ | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 100 | export async function getOrganizationByProjectId( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 248 | export async function connectUserToOrganization( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 368 | export async function getOrganizationBillingEventsCount( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 404 | export async function getOrganizationEventsCount( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 427 | export async function getOrganizationEventsCountSince( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 488 | export async function getOrganizationBillingUsage( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 573 | export async function getOrganizationSubscriptionChartEndDate( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 594 | export async function getSettingsForOrganization( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 815 | export async function scheduleOrganizationDeletion( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 852 | export async function cancelOrganizationDeletion( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 1049 | async function assertProjectsInOrganization( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 1071 | export async function updateOrganizationMemberAccess( | CODE |
| LOW | …/core/src/modules/organization/organization.service.ts | 1106 | export function createOrganizationService( | CODE |
| LOW | …ore/src/modules/organization/organization.constants.ts | 51 | export function normalizeOrganizationRole(stored: string): OrganizationRole { | CODE |
| LOW | …/src/modules/organization/organization.service.test.ts | 462 | function seedMemberWithTwoProjects() { | CODE |
| LOW | packages/core/src/modules/assistant/src/title.ts | 12 | export async function generateConversationTitle( | CODE |
| LOW | packages/core/src/modules/widget/widget.rpc.ts | 91 | async function findPublicCounterWidgetOrThrow(db: Ctx['db'], shareId: string) { | CODE |
| LOW | packages/core/src/modules/widget/widget.rpc.ts | 91 | async function findPublicCounterWidgetOrThrow(db: Ctx['db'], shareId: string) { | CODE |
| LOW | packages/core/src/modules/auth/auth.service.ts | 76 | export function resetAccessChecksForTests(): void { | CODE |
| LOW | packages/core/src/modules/group/group.service.ts | 452 | export async function getGroupMemberProfilesPage( | CODE |
| LOW | packages/core/src/modules/group/src/dates.ts | 15 | export function convertClickhouseDateToJs(date: string): Date { | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 182 | export function notificationTemplateEvent({ | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 213 | export function notificationTemplateFunnel({ | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 368 | export async function getNotificationRuleByIdOrThrow( | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 375 | function assertRegexFiltersAreSafe(input: ICreateNotificationRule) { | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 397 | export async function createOrUpdateNotificationRule( | CODE |
| LOW | …/core/src/modules/notification/notification.service.ts | 490 | export function createNotificationService( | CODE |
| LOW | …/src/modules/notification/src/notification-dispatch.ts | 109 | export async function checkNotificationRulesForEvent( | CODE |
| LOW | …/src/modules/notification/src/notification-dispatch.ts | 187 | export async function checkNotificationRulesForSessionEnd( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 42 | async function assertProjectAccessAndGetOrg( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 113 | export async function listIntegrationsForProject( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 234 | export async function createOrUpdateSlackIntegration( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 312 | export async function testIntegrationConnection( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 334 | export async function testExportIntegrationConnection( | CODE |
| LOW | …es/core/src/modules/integration/integration.service.ts | 394 | export async function completeSlackOAuthCallback( | CODE |
| LOW | …ages/core/src/modules/integration/src/flush-exports.ts | 437 | function convertClickhouseDateToJs(date: string): Date { | CODE |
| LOW | …ore/src/modules/integration/src/export/export-event.ts | 5 | function convertClickhouseDateToJs(date: string): Date { | CODE |
| LOW | …ore/src/modules/integration/src/export/export-event.ts | 48 | export function clickhouseEventToExportEvent( | CODE |
| LOW | …ckages/core/src/modules/ingest/src/consumer-handler.ts | 24 | export function createIncomingEventHandler( | CODE |
| LOW | …/core/src/modules/ingest/src/incoming-event-handler.ts | 185 | async function isEventExcludedByProjectFilter( | CODE |
| LOW | packages/core/src/modules/chart/sankey.service.ts | 141 | export function assertSankeyWindowIsAnswerable( | CODE |
| LOW | packages/core/src/modules/chart/sankey.service.ts | 235 | function groupTransitionsByStepAndSource(transitions: Transition[]) { | CODE |
| LOW | packages/core/src/modules/chart/sankey.service.ts | 417 | function buildSankeyFromTransitions( | CODE |
| LOW | packages/core/src/modules/chart/retention.service.ts | 106 | export function getRetentionLastSeenSeries( | CODE |
| 243 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 17 | // ─── Public types ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 111 | // ─── Defaults ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 118 | // ─── SVG helpers ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 169 | // ─── Animated Segment ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 593 | // ─── Label overlay ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/funnel-chart.tsx | 746 | // ─── Main Component ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/loading-sweep.tsx | 54 | // ─── Pure, SSR-safe helpers ────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/loading-sweep.tsx | 104 | // ─── Shared mask defs (`${chartId}-mask` is the mask id) ───────────────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/loading-sweep.tsx | 180 | // ─── Line / Area loading sweep (its own re-randomizing silhouette) ─────────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/loading-sweep.tsx | 353 | // ─── Bar loading skeleton (seeded bars under the sweep, inner coords) ───────── | COMMENT |
| MEDIUM | apps/start/src/components/charts/bar.tsx | 24 | // ── Bar-depth perspective trim ─────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 11 | // ── Config ────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 32 | // ── Auth paths ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 110 | // ── Redis key helpers ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 126 | // ── Timing ────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 147 | // ── Report framework ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 184 | // ── HTTP ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 224 | // ── Latency percentiles ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 284 | // ── Auth-cache warming and the scrypt outlier ─────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/lib.ts | 425 | // ── Fixtures ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 55 | // ── The proxy ─────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 162 | // ── Probes ────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 303 | // ── The API under test ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 357 | // ── warm-up: the L1 caches the criterion turns on ────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 375 | // ── B. sustained outage ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 413 | // ── C. recovery ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 440 | // ── D. the blip ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 484 | // ── E. blackhole ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/api/e2e/redis-fail-fast.ts | 502 | // ── F. boot with Redis already down ─────────────────────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | bunfig.toml | 1 | # Root `bun install` policy (ADR-014). | COMMENT |
| LOW | bunfig.toml | 21 | # that only holds when someone remembers a flag is not a policy. | COMMENT |
| LOW | mise.toml | 1 | # Pins the toolchain per checkout, so `cd` into the repo selects the versions it | COMMENT |
| LOW | tooling/gates/conformance.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | tooling/gates/p13-images.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | docker/redpanda/auth-entrypoint.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | self-hosting/redpanda/bootstrap.template.yaml | 1 | # Redpanda cluster bootstrap config — applied ONCE, when the data volume is | COMMENT |
| LOW | packages/core/bunfig.toml | 1 | # `bun test` configuration for @openpanel/core. | COMMENT |
| LOW | packages/core/scripts/migrate-code.ts | 1 | // Forwards to `@openpanel/db`'s code migrations for installs whose compose | COMMENT |
| LOW | packages/core/src/cacheable-per-deps.ts | 1 | // `cacheable` for a function that needs the caller's `ServiceDeps`. Passing | COMMENT |
| LOW | packages/core/src/slug-id.ts | 1 | // Slug-based primary-id generation for project/dashboard/organization rows. | COMMENT |
| LOW | packages/core/src/buffers/profile-buffer.ts | 1 | import { sql } from '@openpanel/db/src/clickhouse/sql'; | COMMENT |
| LOW | packages/core/src/http/cors.ts | 1 | // `CORS_OPERATOR_PATHS` (Basic-authenticated operator tooling) is readable | COMMENT |
| LOW | …/src/modules/notification/src/notification-dispatch.ts | 1 | // The BullMQ-producer orchestration around a rule match sits beside the rule | COMMENT |
| LOW | …rc/modules/integration/src/object-store/gcs-adapter.ts | 41 | }; | COMMENT |
| LOW | packages/core/src/modules/health/health.routes.ts | 1 | // Kubernetes liveness and readiness. | COMMENT |
| LOW | packages/core/src/modules/ingest/ingest.routes.ts | 1 | // THE HOOK ORDER IS THE CONTRACT: duplicate -> clientAuth -> isBot -> | COMMENT |
| LOW | …ckages/core/src/modules/ingest/src/producer-batcher.ts | 1 | // Amortises the produce round-trip: accumulates messages and sends them as | COMMENT |
| LOW | packages/core/src/modules/ingest/src/producer-errors.ts | 1 | // The producer's error classification, split out of `kafka.ts` so the batching | COMMENT |
| LOW | …ges/core/src/modules/ingest/src/bots/header-signals.ts | 1 | // Header-consistency bot signals. | COMMENT |
| LOW | packages/core/src/modules/ingest/src/bots/suspicion.ts | 1 | // Combines the individual bot signals into a single verdict for an event, and | COMMENT |
| LOW | packages/core/src/modules/chart/src/sql.ts | 1 | // Every ClickHouse query the chart module runs, as pure `sql` fragments. | COMMENT |
| LOW | packages/core/src/modules/mcp/mcp.routes.ts | 1 | // MCP's stateless POST transport, mounted at `/mcp`. | COMMENT |
| LOW | …ges/core/src/modules/realtime/realtime.service.test.ts | 1 | // The event buffer and the ClickHouse client are HANDED IN | COMMENT |
| LOW | packages/core/src/modules/cohort/cohort.service.ts | 41 | // Max members materialized into cohort_members per compute. Larger cohorts are | COMMENT |
| LOW | packages/core/src/modules/cohort/cohort.service.ts | 141 | // Neither can be expressed as a HAVING on the summary MVs: those hold a row | COMMENT |
| LOW | packages/core/src/modules/email/src/sequence.ts | 1 | // A day-gated email sequence runner. Each subject carries a pointer (the last | COMMENT |
| LOW | packages/sdks/web/src/init-snippet.ts | 1 | // Source: | COMMENT |
| LOW | packages/db/bunfig.toml | 1 | # `bun test` configuration for @openpanel/db. | COMMENT |
| LOW | packages/db/scripts/backfill-profile-seen.ts | 1 | // One-off backfill that reconciles `profiles.created_at` (first seen) and | COMMENT |
| LOW | packages/db/scripts/access-snapshot.ts | 1 | // Dumps what every member may do on every project of their organization, so a | COMMENT |
| LOW | …ages/db/src/code-migrations/16-restructure-profiles.ts | 1 | import { | COMMENT |
| LOW | …ages/db/src/code-migrations/16-restructure-profiles.ts | 21 | // | COMMENT |
| LOW | …ages/db/src/code-migrations/16-restructure-profiles.ts | 41 | // ANY LEFT JOIN ( | COMMENT |
| LOW | …es/db/src/code-migrations/22-add-events-inserted-at.ts | 1 | import { | COMMENT |
| LOW | .github/smoke/smoke.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | .github/smoke/docker-compose.yml | 1 | # Smoke-test stack for CI. | COMMENT |
| LOW | .github/workflows/sdks.yml | 1 | name: SDKs | COMMENT |
| LOW | apps/api/bunfig.toml | 1 | # `bun test` configuration for @openpanel/api. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | packages/core/src/modules/realtime/realtime.routes.ts | 143 | const access = await ws.data.ctx.services.auth.getProjectAccess({ | CODE |
| CRITICAL | packages/core/src/modules/realtime/realtime.routes.ts | 173 | const access = await ws.data.ctx.services.auth.getProjectAccess({ | CODE |
| CRITICAL | packages/core/src/modules/realtime/realtime.routes.ts | 213 | const access = await ws.data.ctx.services.auth.getOrganizationAccess({ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packages/core/src/shared/js-runtime/validate.test.ts | 585 | name: 'John Doe', | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 75 | user: { id: 'user-1', email: 'user@example.com', firstName: 'Alex' }, | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 128 | to: 'user@example.com', | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 268 | email: 'admin@example.com', | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 280 | expect(options).toMatchObject({ to: 'admin@example.com' }); | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 328 | to: 'user@example.com', | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 350 | to: 'user@example.com', | CODE |
| LOW | …es/core/src/modules/organization/src/wind-down.test.ts | 365 | to: 'user@example.com', | CODE |
| LOW | packages/core/src/modules/email/src/sequence.test.ts | 62 | email: 'user@example.com', | CODE |
| LOW | packages/core/src/modules/email/src/sequence.test.ts | 103 | to: 'user@example.com', | CODE |
| LOW | …core/src/modules/onboarding/onboarding.service.test.ts | 73 | user: { id: 'user-1', email: 'user@example.com', firstName: 'Alex' }, | CODE |
| LOW | …core/src/modules/onboarding/onboarding.service.test.ts | 108 | to: 'user@example.com', | CODE |
| LOW | …core/src/modules/onboarding/onboarding.service.test.ts | 145 | to: 'user@example.com', | CODE |
| LOW | …core/src/modules/onboarding/onboarding.service.test.ts | 183 | to: 'user@example.com', | CODE |
| LOW⚡ | packages/core/src/modules/share/share.service.test.ts | 43 | const ORG = { name: 'Acme Inc' }; | CODE |
| LOW | apps/testbed/src/pages/Product.tsx | 50 | Lorem ipsum dolor sit amet consectetur adipiscing elit. | CODE |
| LOW | apps/testbed/src/pages/Product.tsx | 50 | Lorem ipsum dolor sit amet consectetur adipiscing elit. | CODE |
| LOW | apps/testbed/src/pages/Login.tsx | 8 | name: 'Acme Corp', | CODE |
| LOW | apps/start/e2e/sweep-a11y.spec.ts | 60 | `${field.getAttribute('placeholder') ? '(placeholder only) ' : ''}${describe(field)}` | CODE |
| LOW | apps/start/e2e/sweep-a11y.spec.ts | 96 | element.getAttribute('placeholder') || | CODE |
| LOW | apps/start/src/modals/add-group.tsx | 76 | placeholder="Acme Corp" | CODE |
| LOW | apps/start/src/components/ui/combobox.tsx | 53 | 'items' | 'placeholder' | CODE |
| LOW | apps/start/src/routes/_steps.onboarding.project.tsx | 492 | placeholder="Acme Inc" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | apps/public/src/app/(home)/_sections/testimonials.tsx | 120 | // This creates a seamless infinite scroll effect | COMMENT |
| MEDIUM | apps/public/src/app/(home)/_sections/mcp.tsx | 48 | // Duplicate for seamless loop | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ckages/core/src/modules/insight/src/referrer-spikes.ts | 116 | // Step 1: top non-direct referrers by total range volume. Bounds the | COMMENT |
| LOW | …ckages/core/src/modules/insight/src/referrer-spikes.ts | 134 | // Step 2: per-bucket sessions for top referrers + bucket totals (including | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ckages/core/src/modules/insight/src/referrer-spikes.ts | 116 | // Step 1: top non-direct referrers by total range volume. Bounds the | COMMENT |
| LOW | …ckages/core/src/modules/insight/src/referrer-spikes.ts | 134 | // Step 2: per-bucket sessions for top referrers + bucket totals (including | COMMENT |