Skip to content

Metrics reference

This page is the reference for what each metric on the Analytics dashboard measures, where the data comes from, and how it’s aggregated.

Every analytics metric is derived from events written by one of three surfaces: the web app (during policy authoring), the browser extension, or the Mac app. Each event is timestamped, tenant-scoped, and non-user-identifiable.

EventEmitted when
violation_flaggedA violation is detected and shown to the user
violation_acceptedThe user clicks Apply fix or accepts a suggestion
violation_self_resolvedA previously-flagged violation disappears because the user edited their text
violation_dismissedThe user closes the violation card without acting
violation_ignoredSynonym for dismissed in some contexts; surfaced alongside dismissed in totals
session_activeHeartbeat sent every ~5 min while a surface is actively running
app_installedFired once per client install (extension or Mac app)

Only the violation_* events are visualized in the current dashboard. Session and install events are collected for future engagement views.

  • Definition: count of policies where status=PUBLISHED AND isActive=true AND current time falls within the effective window.
  • Trend delta: compares the current count to a snapshot taken at the start of the comparison window (stored in a PolicyActivationLog table).
  • Definition: COUNT(*) WHERE event.type = 'violation_flagged' AND event.occurredAt BETWEEN range.start AND range.end.
  • Definition: COUNT(*) WHERE event.type = 'violation_accepted' AND event.occurredAt BETWEEN range.start AND range.end.
  • Definition: COUNT(*) WHERE event.type = 'violation_self_resolved' AND event.occurredAt BETWEEN range.start AND range.end.
  • Definition: COUNT(*) WHERE event.type IN ('violation_dismissed', 'violation_ignored') AND event.occurredAt BETWEEN range.start AND range.end.

Aggregated per policy ID. Each row is one policy with event counts over the selected date range. Sorting is server-side on any displayed column; ties break on Triggers descending.

The policy’s current Policy Area and severity are shown — not the area/severity that was in effect at the time of the event. If you re-categorize a policy, its historical events move with it under the new category.

violation_flagged events, grouped by the policy’s current Policy Area. Uncategorized bar represents policies with no Area assigned.

Note: grouping uses each policy’s current Area, not the Area at event time. Re-categorizing a policy retroactively shifts its events to the new Area on this chart.

violation_flagged events, bucketed into three severity bands:

  • Low: severity 1–3
  • Medium: severity 4–7
  • High: severity 8–10
  • Unknown: events where severity couldn’t be determined (very rare; migration artifacts)

The event carries the severity value stored on the policy at the time the event was generated — so if you later change a policy’s severity, historical events retain the old value.

Events are attributed to a Division by traversing: AnalyticsEvent.policyId → Policy.policyAreaId → PolicyArea.divisionId → Division.

Each row aggregates all events for that Division over the date range:

  • Usage: total events of any type (session, violation, etc.).
  • Violations: violation_flagged count.
  • Fixed / Self-resolved / Ignored: as defined above.

A Division is only shown if at least 5 users are assigned to it. This is enforced by matching Division.name (case-insensitive) against each user’s User.department field.

If fewer than 5 users match, the entire row is omitted from the table. A footer note says how many teams were suppressed. If every Division falls below the floor, the table shows a full-page notice: “All teams suppressed by k-anonymity. Assign User.department to at least 5 users per team to surface a row.”

See Privacy & the 5-person floor for the reasoning.

Ranges are inclusive of start, exclusive of end — i.e. [start, end).

Trend deltas compare to the immediately preceding window of equivalent length:

  • Last 7 days → trend vs. the 7 days before those.
  • Last 30 days → trend vs. the previous 30 days.
  • Last 90 days → trend vs. the previous 90 days.

By design:

  • No user IDs. Events do not include userId. You cannot ask “who violated policy X?” — the system cannot answer.
  • No violation text. The content that triggered a violation is never stored. Only the policy ID, severity, and enforcement outcome.
  • No PII. Event properties fields are validated at ingestion. Any field matching a deny-list of PII-adjacent keys (text, content, message, body, subject, to, from, email, name, phone, etc.) is rejected at the boundary.
  • No IP address or geolocation. Events don’t carry client network metadata.

For admins who need more than the dashboard offers:

  • CSV export covers all policies in the current range — see Analytics overview.
  • API access to the analytics endpoints is available but undocumented in this release. Contact support if you have a reporting need the dashboard doesn’t cover.