Skip to content

feat(metrics): characterize-metric-anomaly endpoint and MCP tool#63131

Open
DanielVisca wants to merge 3 commits into
posthog-code/metrics-mcp-toolsfrom
posthog-code/metrics-mcp-characterize
Open

feat(metrics): characterize-metric-anomaly endpoint and MCP tool#63131
DanielVisca wants to merge 3 commits into
posthog-code/metrics-mcp-toolsfrom
posthog-code/metrics-mcp-characterize

Conversation

@DanielVisca

@DanielVisca DanielVisca commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Problem

"Metric X is rising — why?" starts with three questions an agent (or human) currently has to answer with many manual queries: how big is the change, when did it start, and which label values moved. One endpoint should answer all three.

Changes

  • POST /metrics/characterize + facade characterize_metric_anomaly() + engine in products/metrics/backend/anomaly.py:
    • Compares an anomaly window against a baseline (default: the equal-length window immediately before).
    • Magnitude: baseline/anomaly mean, stddev, peak, change ratio, direction (up/down/flat with 5% tolerance).
    • Onset: first bucket beyond 3 baseline stddevs (with a 50% relative floor for near-constant baselines).
    • Movers: drills into ≤4 candidate label keys (auto-discovered from the metric's attributes + service_name, or caller-provided) and ranks label values by behavior change.
    • Aggregation auto-picks from the metric's OTel type (counter → rate, gauge → avg, histogram → p95).
  • Exposed as the characterize-metric-anomaly MCP tool; its prompt tells agents how to read the report and to pivot into logs/traces at onset_time.

Known limitation (documented): change_ratio is confusing when the baseline mean is negative (seen with clock-skew message ages); direction/onset/top_movers are unaffected.

How did you test this code?

I'm an agent. Automated: hogli test products/metrics/backend/tests/test_anomaly.py (8 tests: magnitude/onset/movers on a seeded spike, auto key discovery, flat negative-control, window validation, counter auto-pick, API path). End-to-end: ran it against a real induced incident — stopped the local logs consumer ~3 min while traffic flowed, restarted it, called the tool over MCP: it reported direction up, onset within one bucket of the restart, and service_name=logs-ingestion as the only mover. Reproduce: stop ingestion-logs in the TUI for a few minutes, restart, call the tool with anomalyFrom = the stop time.

🤖 Agent context

Autonomy: Human-driven (agent-assisted) — directed by @DanielVisca

Stats are deliberately simple (mean/stddev/threshold-onset) — robust enough for triage, no model dependencies; the report shape leaves room to upgrade the detector without changing the wire contract.

DanielVisca commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

@github-actions

Copy link
Copy Markdown
Contributor

MCP UI Apps size report

App JS CSS
debug 586.6 KB 148.5 KB
action 355.0 KB 148.5 KB
action-list 520.2 KB 148.5 KB
cohort 354.0 KB 148.5 KB
cohort-list 519.1 KB 148.5 KB
error-details 375.4 KB 148.5 KB
error-issue 354.7 KB 148.5 KB
error-issue-list 520.1 KB 148.5 KB
experiment 517.0 KB 148.5 KB
experiment-list 520.9 KB 148.5 KB
experiment-results 518.8 KB 148.5 KB
feature-flag 552.8 KB 148.5 KB
feature-flag-list 556.9 KB 148.5 KB
feature-flag-testing 432.7 KB 148.5 KB
insight-actors 515.5 KB 148.5 KB
invite-email-preview 353.3 KB 148.5 KB
llm-costs 515.1 KB 148.5 KB
session-recording 355.8 KB 148.5 KB
session-summary 361.5 KB 148.5 KB
survey 355.5 KB 148.5 KB
survey-global-stats 517.8 KB 148.5 KB
survey-list 520.8 KB 148.5 KB
survey-stats 517.8 KB 148.5 KB
trace-span 354.4 KB 148.5 KB
trace-span-list 520.1 KB 148.5 KB
workflow 354.3 KB 148.5 KB
workflow-list 519.5 KB 148.5 KB
query-results 662.2 KB 148.5 KB
render-ui 621.1 KB 148.5 KB
visual-review-snapshots 359.0 KB 148.5 KB

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
products/metrics/mcp/prompts/characterize-metric-anomaly.md:7-12
Numbered lists in prompts can cause confusion for AI consumers that may interpret the numbers as part of a user response. The custom rule prefers bullet points or letters instead.

```suggestion
Read the report in this order:

- `direction` + `change_ratio` + `anomaly_peak`: how bad is it? (`flat` means the windows don't meaningfully differ — widen the anomaly window or check you have the right metric.)
- `onset_time`: when it started. Use this exact timestamp as the pivot for cross-signal correlation.
- `top_movers`: which label values changed. One label value moving alone (e.g. a single pod or shard) points at a localized culprit; everything moving together points at a shared cause upstream.
- `series`: the full baseline+anomaly time series if you need to eyeball the shape.
```

### Issue 2 of 3
products/metrics/backend/tests/test_anomaly.py:86-90
Two distinct invalid-window cases inside one test — the codebase prefers parameterised tests. Each condition (`anomaly_to <= anomaly_from` and `baseline_to > anomaly_from`) would be a separate row in a `@pytest.mark.parametrize` (or `subTest`) table, making it easier to see which guard failed when either assertion breaks.

### Issue 3 of 3
products/metrics/backend/anomaly.py:231
Candidate-key discovery queries only the anomaly window (`anomaly_from``anomaly_to`). A label value that was present during the baseline but disappeared during the anomaly — e.g. a pod that crashed or a shard that went offline — will never be discovered here, so its disappearance won't surface in `top_movers`. Extending the scan to the full combined window (`baseline_from``anomaly_to`) would catch this class of "drop to zero" signals.

Reviews (1): Last reviewed commit: "chore: update OpenAPI generated types" | Re-trigger Greptile

Comment on lines +7 to +12
Read the report in this order:

1. `direction` + `change_ratio` + `anomaly_peak`: how bad is it? (`flat` means the windows don't meaningfully differ — widen the anomaly window or check you have the right metric.)
2. `onset_time`: when it started. Use this exact timestamp as the pivot for cross-signal correlation.
3. `top_movers`: which label values changed. One label value moving alone (e.g. a single pod or shard) points at a localized culprit; everything moving together points at a shared cause upstream.
4. `series`: the full baseline+anomaly time series if you need to eyeball the shape.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Numbered lists in prompts can cause confusion for AI consumers that may interpret the numbers as part of a user response. The custom rule prefers bullet points or letters instead.

Suggested change
Read the report in this order:
1. `direction` + `change_ratio` + `anomaly_peak`: how bad is it? (`flat` means the windows don't meaningfully differ — widen the anomaly window or check you have the right metric.)
2. `onset_time`: when it started. Use this exact timestamp as the pivot for cross-signal correlation.
3. `top_movers`: which label values changed. One label value moving alone (e.g. a single pod or shard) points at a localized culprit; everything moving together points at a shared cause upstream.
4. `series`: the full baseline+anomaly time series if you need to eyeball the shape.
Read the report in this order:
- `direction` + `change_ratio` + `anomaly_peak`: how bad is it? (`flat` means the windows don't meaningfully differ — widen the anomaly window or check you have the right metric.)
- `onset_time`: when it started. Use this exact timestamp as the pivot for cross-signal correlation.
- `top_movers`: which label values changed. One label value moving alone (e.g. a single pod or shard) points at a localized culprit; everything moving together points at a shared cause upstream.
- `series`: the full baseline+anomaly time series if you need to eyeball the shape.

Rule Used: In prompts, avoid using numbers in lists to preven... (source)

Learned From
PostHog/posthog#31624

Prompt To Fix With AI
This is a comment left during a code review.
Path: products/metrics/mcp/prompts/characterize-metric-anomaly.md
Line: 7-12

Comment:
Numbered lists in prompts can cause confusion for AI consumers that may interpret the numbers as part of a user response. The custom rule prefers bullet points or letters instead.

```suggestion
Read the report in this order:

- `direction` + `change_ratio` + `anomaly_peak`: how bad is it? (`flat` means the windows don't meaningfully differ — widen the anomaly window or check you have the right metric.)
- `onset_time`: when it started. Use this exact timestamp as the pivot for cross-signal correlation.
- `top_movers`: which label values changed. One label value moving alone (e.g. a single pod or shard) points at a localized culprit; everything moving together points at a shared cause upstream.
- `series`: the full baseline+anomaly time series if you need to eyeball the shape.
```

**Rule Used:** In prompts, avoid using numbers in lists to preven... ([source](https://app.greptile.com/posthog-org-19734/-/custom-context?memory=1dd45b94-c307-4dd0-a025-5aa16059229b))

**Learned From**
[PostHog/posthog#31624](https://github.com/PostHog/posthog/pull/31624)

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +86 to +90
def test_rejects_inverted_windows(self):
with self.assertRaises(ValueError):
self._characterize(anomaly_to=self.anomaly_from - dt.timedelta(minutes=1))
with self.assertRaises(ValueError):
self._characterize(baseline_to=self.anomaly_from + dt.timedelta(minutes=5))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Two distinct invalid-window cases inside one test — the codebase prefers parameterised tests. Each condition (anomaly_to <= anomaly_from and baseline_to > anomaly_from) would be a separate row in a @pytest.mark.parametrize (or subTest) table, making it easier to see which guard failed when either assertion breaks.

Prompt To Fix With AI
This is a comment left during a code review.
Path: products/metrics/backend/tests/test_anomaly.py
Line: 86-90

Comment:
Two distinct invalid-window cases inside one test — the codebase prefers parameterised tests. Each condition (`anomaly_to <= anomaly_from` and `baseline_to > anomaly_from`) would be a separate row in a `@pytest.mark.parametrize` (or `subTest`) table, making it easier to see which guard failed when either assertion breaks.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

filters: tuple[MetricFilter, ...],
candidate_keys: tuple[str, ...] | None,
) -> tuple[MetricAnomalyDimension, ...]:
keys = candidate_keys or _discover_candidate_keys(team, metric_name, anomaly_from, anomaly_to)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Candidate-key discovery queries only the anomaly window (anomaly_fromanomaly_to). A label value that was present during the baseline but disappeared during the anomaly — e.g. a pod that crashed or a shard that went offline — will never be discovered here, so its disappearance won't surface in top_movers. Extending the scan to the full combined window (baseline_fromanomaly_to) would catch this class of "drop to zero" signals.

Prompt To Fix With AI
This is a comment left during a code review.
Path: products/metrics/backend/anomaly.py
Line: 231

Comment:
Candidate-key discovery queries only the anomaly window (`anomaly_from``anomaly_to`). A label value that was present during the baseline but disappeared during the anomaly — e.g. a pod that crashed or a shard that went offline — will never be discovered here, so its disappearance won't surface in `top_movers`. Extending the scan to the full combined window (`baseline_from``anomaly_to`) would catch this class of "drop to zero" signals.

How can I resolve this? If you propose a fix, please make it concise.

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 72.4 MB

ℹ️ View Unchanged
Filename Size
frontend/dist-report/decompression-worker/src/scenes/session-recordings/player/snapshot-processing/decompressionWorker 2.85 kB
frontend/dist-report/exporter/_chunks/chunk 6.7 MB
frontend/dist-report/exporter/_parent/products/actions/frontend/pages/Action 24.1 kB
frontend/dist-report/exporter/_parent/products/actions/frontend/pages/Actions 1.92 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityScene 117 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilitySessionScene 19.7 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityTraceScene 129 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/AIObservabilityUsers 1.54 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClusterScene 21.6 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClustersScene 54.3 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetScene 20.7 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetsScene 4.13 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation 59.6 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluationsScene 28.5 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/evaluations/EvaluationTemplates 569 B
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/LLMASessionFeedbackDisplay 4.71 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/playground/AIObservabilityPlaygroundScene 37.7 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptScene 29.8 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptsScene 5.24 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTag 28.4 kB
frontend/dist-report/exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene 8.11 kB
frontend/dist-report/exporter/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene 21.1 kB
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/Assignee/CyclotronJobInputAssignee 1.27 kB
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/SlaBusinessHours/CyclotronJobInputBusinessHours 2.59 kB
frontend/dist-report/exporter/_parent/products/conversations/frontend/components/TicketTags/CyclotronJobInputTicketTags 681 B
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/settings/SupportSettingsScene 2.48 kB
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene 34 kB
frontend/dist-report/exporter/_parent/products/conversations/frontend/scenes/tickets/SupportTicketsScene 1.75 kB
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene 80.4 kB
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/CustomerAnalyticsConfigurationScene 3.24 kB
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene 2.69 kB
frontend/dist-report/exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyTemplatesScene/CustomerJourneyTemplatesScene 8.16 kB
frontend/dist-report/exporter/_parent/products/data_warehouse/DataWarehouseScene 46.1 kB
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene 1.82 kB
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SchemaScene/SchemaScene 26.7 kB
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SourceScene/SourceScene 1.77 kB
frontend/dist-report/exporter/_parent/products/data_warehouse/frontend/scenes/SourcesScene/SourcesScene 6.57 kB
frontend/dist-report/exporter/_parent/products/early_access_features/frontend/EarlyAccessFeature 1.7 kB
frontend/dist-report/exporter/_parent/products/early_access_features/frontend/EarlyAccessFeatures 3.75 kB
frontend/dist-report/exporter/_parent/products/endpoints/frontend/EndpointScene 43.6 kB
frontend/dist-report/exporter/_parent/products/endpoints/frontend/EndpointsScene 23.8 kB
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingFingerprintsScene/ErrorTrackingIssueFingerprintsScene 7.64 kB
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene 96.7 kB
frontend/dist-report/exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingScene/ErrorTrackingScene 35.2 kB
frontend/dist-report/exporter/_parent/products/feature_flags/frontend/FeatureFlagTemplatesScene 6.8 kB
frontend/dist-report/exporter/_parent/products/games/368Hedgehogs/368Hedgehogs 5.13 kB
frontend/dist-report/exporter/_parent/products/games/FlappyHog/FlappyHog 5.6 kB
frontend/dist-report/exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentNewScene 60.6 kB
frontend/dist-report/exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentsScene 6.78 kB
frontend/dist-report/exporter/_parent/products/links/frontend/LinkScene 25.5 kB
frontend/dist-report/exporter/_parent/products/links/frontend/LinksScene 4.86 kB
frontend/dist-report/exporter/_parent/products/live_debugger/frontend/LiveDebugger 19.6 kB
frontend/dist-report/exporter/_parent/products/logs/frontend/LogsScene 18.7 kB
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsAlertDetailScene/LogsAlertDetailScene 17.9 kB
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsAlertNotificationDetailScene/LogsAlertNotificationDetailScene 8.91 kB
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsSamplingDetailScene/LogsSamplingDetailScene 5.72 kB
frontend/dist-report/exporter/_parent/products/logs/frontend/scenes/LogsSamplingNewScene/LogsSamplingNewScene 2.78 kB
frontend/dist-report/exporter/_parent/products/managed_migrations/frontend/ManagedMigration 15.3 kB
frontend/dist-report/exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene 78.4 kB
frontend/dist-report/exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsToolDetail 19 kB
frontend/dist-report/exporter/_parent/products/metrics/frontend/MetricsScene 16.1 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/stickiness/StickinessBarChart/StickinessBarChart 3.74 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/stickiness/StickinessLineChart/StickinessLineChart 3.62 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart 9.26 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsLifecycleChart/TrendsLifecycleChart 5.44 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsLineChart/TrendsLineChart 5.08 kB
frontend/dist-report/exporter/_parent/products/product_analytics/frontend/insights/trends/TrendsPieChart/TrendsPieChart 4.83 kB
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/observations/ReplayObservation 14.5 kB
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner 21.7 kB
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene 18.7 kB
frontend/dist-report/exporter/_parent/products/replay_vision/frontend/replay_scanners/ScannerEditorScene 25.8 kB
frontend/dist-report/exporter/_parent/products/revenue_analytics/frontend/revenueAnalyticsLogic 1.73 kB
frontend/dist-report/exporter/_parent/products/revenue_analytics/frontend/RevenueAnalyticsScene 26 kB
frontend/dist-report/exporter/_parent/products/session_summaries/frontend/SessionGroupSummariesTable 5.46 kB
frontend/dist-report/exporter/_parent/products/session_summaries/frontend/SessionGroupSummaryScene 19.5 kB
frontend/dist-report/exporter/_parent/products/skills/frontend/LLMSkillScene 1.57 kB
frontend/dist-report/exporter/_parent/products/skills/frontend/LLMSkillsScene 1.58 kB
frontend/dist-report/exporter/_parent/products/tasks/frontend/SlackTaskContextScene 9.39 kB
frontend/dist-report/exporter/_parent/products/tasks/frontend/TaskDetailScene 25.1 kB
frontend/dist-report/exporter/_parent/products/tasks/frontend/TaskTracker 14.6 kB
frontend/dist-report/exporter/_parent/products/tracing/frontend/TracingScene 75 kB
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterview 10.7 kB
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterviewResponse 8.14 kB
frontend/dist-report/exporter/_parent/products/user_interviews/frontend/UserInterviews 6.55 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewIndexScene 3.11 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunScene 45.9 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunsScene 7.75 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSettingsScene 11.6 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotHistoryScene 14.3 kB
frontend/dist-report/exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotOverviewScene 19.9 kB
frontend/dist-report/exporter/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate 16.9 kB
frontend/dist-report/exporter/_parent/products/workflows/frontend/Workflows/WorkflowScene 109 kB
frontend/dist-report/exporter/_parent/products/workflows/frontend/WorkflowsScene 58.9 kB
frontend/dist-report/exporter/src/exporter/exporter 42.7 kB
frontend/dist-report/exporter/src/exporter/scenes/ExporterDashboardScene 2.63 kB
frontend/dist-report/exporter/src/exporter/scenes/ExporterHeatmapScene 20.4 kB
frontend/dist-report/exporter/src/exporter/scenes/ExporterInsightScene 3.53 kB
frontend/dist-report/exporter/src/exporter/scenes/ExporterInterviewScene 310 kB
frontend/dist-report/exporter/src/exporter/scenes/ExporterNotebookScene 2.71 MB
frontend/dist-report/exporter/src/exporter/scenes/ExporterRecordingScene 1.79 kB
frontend/dist-report/exporter/src/exporterSharedChunkAnchors 1.23 kB
frontend/dist-report/exporter/src/lib/components/Cards/TextCard/TextCardMarkdownEditor 10.5 kB
frontend/dist-report/exporter/src/lib/components/MonacoDiffEditor 499 B
frontend/dist-report/exporter/src/lib/lemon-ui/LemonMarkdown/MermaidDiagram 1.89 kB
frontend/dist-report/exporter/src/lib/lemon-ui/LemonTextArea/LemonTextAreaMarkdown 688 B
frontend/dist-report/exporter/src/lib/lemon-ui/Link/Link 347 B
frontend/dist-report/exporter/src/lib/monaco/CodeEditorInline 683 B
frontend/dist-report/exporter/src/lib/monaco/vimMode 211 kB
frontend/dist-report/exporter/src/lib/ui/Button/ButtonPrimitives 411 B
frontend/dist-report/exporter/src/queries/nodes/WebVitals/WebVitals 7.86 kB
frontend/dist-report/exporter/src/queries/nodes/WebVitals/WebVitalsPathBreakdown 4.69 kB
frontend/dist-report/exporter/src/queries/Query/Query 1.48 kB
frontend/dist-report/exporter/src/queries/schema 899 kB
frontend/dist-report/exporter/src/scenes/approvals/changeRequestsLogic 520 B
frontend/dist-report/exporter/src/scenes/authentication/shared/passkeyLogic 500 B
frontend/dist-report/exporter/src/scenes/data-pipelines/event-filtering/EventFilterScene 22.4 kB
frontend/dist-report/exporter/src/scenes/data-pipelines/TransformationsScene 6.76 kB
frontend/dist-report/exporter/src/scenes/insights/views/BoxPlot/BoxPlot 5.82 kB
frontend/dist-report/exporter/src/scenes/insights/views/CalendarHeatMap/CalendarHeatMap 9.12 kB
frontend/dist-report/exporter/src/scenes/insights/views/RegionMap/RegionMap 30.1 kB
frontend/dist-report/exporter/src/scenes/insights/views/WorldMap/WorldMap 1.04 MB
frontend/dist-report/exporter/src/scenes/models/ModelsScene 19.1 kB
frontend/dist-report/exporter/src/scenes/models/NodeDetailScene 17 kB
frontend/dist-report/monaco-editor-worker/src/lib/monaco/workers/monacoEditorWorker 288 kB
frontend/dist-report/monaco-json-worker/src/lib/monaco/workers/monacoJsonWorker 419 kB
frontend/dist-report/monaco-typescript-worker/src/lib/monaco/workers/monacoTsWorker 7.02 MB
frontend/dist-report/posthog-app/_chunks/chunk 6.64 MB
frontend/dist-report/posthog-app/_parent/products/actions/frontend/pages/Action 24.9 kB
frontend/dist-report/posthog-app/_parent/products/actions/frontend/pages/Actions 2.63 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityScene 118 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilitySessionScene 20.3 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityTraceScene 130 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/AIObservabilityUsers 2.22 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/clusters/AIObservabilityClusterScene 22.3 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/clusters/AIObservabilityClustersScene 55 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetScene 21.4 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetsScene 4.81 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation 60.3 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluationsScene 29.2 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/evaluations/EvaluationTemplates 569 B
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/LLMASessionFeedbackDisplay 4.71 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/playground/AIObservabilityPlaygroundScene 38.4 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/prompts/LLMPromptScene 29.9 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/prompts/LLMPromptsScene 5.92 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTag 29 kB
frontend/dist-report/posthog-app/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene 8.79 kB
frontend/dist-report/posthog-app/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene 21.8 kB
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/Assignee/CyclotronJobInputAssignee 1.27 kB
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/SlaBusinessHours/CyclotronJobInputBusinessHours 2.6 kB
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/components/TicketTags/CyclotronJobInputTicketTags 681 B
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/settings/SupportSettingsScene 3.23 kB
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene 27.1 kB
frontend/dist-report/posthog-app/_parent/products/conversations/frontend/scenes/tickets/SupportTicketsScene 2.43 kB
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene 79.9 kB
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/CustomerAnalyticsConfigurationScene 3.99 kB
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene 3.37 kB
frontend/dist-report/posthog-app/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyTemplatesScene/CustomerJourneyTemplatesScene 8.85 kB
frontend/dist-report/posthog-app/_parent/products/data_warehouse/DataWarehouseScene 3.13 kB
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene 2.57 kB
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SchemaScene/SchemaScene 27.4 kB
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SourceScene/SourceScene 2.48 kB
frontend/dist-report/posthog-app/_parent/products/data_warehouse/frontend/scenes/SourcesScene/SourcesScene 7.25 kB
frontend/dist-report/posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeature 2.52 kB
frontend/dist-report/posthog-app/_parent/products/early_access_features/frontend/EarlyAccessFeatures 4.44 kB
frontend/dist-report/posthog-app/_parent/products/endpoints/frontend/EndpointScene 44.3 kB
frontend/dist-report/posthog-app/_parent/products/endpoints/frontend/EndpointsScene 22.5 kB
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingFingerprintsScene/ErrorTrackingIssueFingerprintsScene 8.32 kB
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene 96.5 kB
frontend/dist-report/posthog-app/_parent/products/error_tracking/frontend/scenes/ErrorTrackingScene/ErrorTrackingScene 35.9 kB
frontend/dist-report/posthog-app/_parent/products/feature_flags/frontend/FeatureFlagTemplatesScene 6.81 kB
frontend/dist-report/posthog-app/_parent/products/games/368Hedgehogs/368Hedgehogs 5.14 kB
frontend/dist-report/posthog-app/_parent/products/games/FlappyHog/FlappyHog 5.6 kB
frontend/dist-report/posthog-app/_parent/products/legal_documents/frontend/scenes/LegalDocumentNewScene 61.3 kB
frontend/dist-report/posthog-app/_parent/products/legal_documents/frontend/scenes/LegalDocumentsScene 7.46 kB
frontend/dist-report/posthog-app/_parent/products/links/frontend/LinkScene 26.2 kB
frontend/dist-report/posthog-app/_parent/products/links/frontend/LinksScene 5.54 kB
frontend/dist-report/posthog-app/_parent/products/live_debugger/frontend/LiveDebugger 20.3 kB
frontend/dist-report/posthog-app/_parent/products/logs/frontend/LogsScene 18.5 kB
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsAlertDetailScene/LogsAlertDetailScene 18.6 kB
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsAlertNotificationDetailScene/LogsAlertNotificationDetailScene 9.6 kB
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsSamplingDetailScene/LogsSamplingDetailScene 6.41 kB
frontend/dist-report/posthog-app/_parent/products/logs/frontend/scenes/LogsSamplingNewScene/LogsSamplingNewScene 3.46 kB
frontend/dist-report/posthog-app/_parent/products/managed_migrations/frontend/ManagedMigration 16 kB
frontend/dist-report/posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene 79.1 kB
frontend/dist-report/posthog-app/_parent/products/mcp_analytics/frontend/MCPAnalyticsToolDetail 19.7 kB
frontend/dist-report/posthog-app/_parent/products/metrics/frontend/MetricsScene 16.8 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/stickiness/StickinessBarChart/StickinessBarChart 4.42 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/stickiness/StickinessLineChart/StickinessLineChart 4.3 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsBarChart/TrendsBarChart 9.94 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsLifecycleChart/TrendsLifecycleChart 6.12 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsLineChart/TrendsLineChart 5.76 kB
frontend/dist-report/posthog-app/_parent/products/product_analytics/frontend/insights/trends/TrendsPieChart/TrendsPieChart 5.51 kB
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/observations/ReplayObservation 15.1 kB
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner 22.4 kB
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene 19.3 kB
frontend/dist-report/posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ScannerEditorScene 26.5 kB
frontend/dist-report/posthog-app/_parent/products/revenue_analytics/frontend/revenueAnalyticsLogic 2.41 kB
frontend/dist-report/posthog-app/_parent/products/revenue_analytics/frontend/RevenueAnalyticsScene 26.7 kB
frontend/dist-report/posthog-app/_parent/products/session_summaries/frontend/SessionGroupSummariesTable 6.14 kB
frontend/dist-report/posthog-app/_parent/products/session_summaries/frontend/SessionGroupSummaryScene 20.1 kB
frontend/dist-report/posthog-app/_parent/products/skills/frontend/LLMSkillScene 2.25 kB
frontend/dist-report/posthog-app/_parent/products/skills/frontend/LLMSkillsScene 2.26 kB
frontend/dist-report/posthog-app/_parent/products/tasks/frontend/SlackTaskContextScene 10.1 kB
frontend/dist-report/posthog-app/_parent/products/tasks/frontend/TaskDetailScene 25.9 kB
frontend/dist-report/posthog-app/_parent/products/tasks/frontend/TaskTracker 15.3 kB
frontend/dist-report/posthog-app/_parent/products/tracing/frontend/TracingScene 75.7 kB
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterview 10.8 kB
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterviewResponse 8.82 kB
frontend/dist-report/posthog-app/_parent/products/user_interviews/frontend/UserInterviews 7.24 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewIndexScene 3.79 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewRunScene 46.6 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewRunsScene 8.44 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSettingsScene 12.3 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotHistoryScene 15 kB
frontend/dist-report/posthog-app/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotOverviewScene 20.5 kB
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate 17.6 kB
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/Workflows/WorkflowScene 103 kB
frontend/dist-report/posthog-app/_parent/products/workflows/frontend/WorkflowsScene 59.7 kB
frontend/dist-report/posthog-app/src/index 61.3 kB
frontend/dist-report/posthog-app/src/layout/panel-layout/ai-first/tabs/NavTabChat 8.35 kB
frontend/dist-report/posthog-app/src/lib/components/AppShortcuts/utils/DebugCHQueriesImpl 19 kB
frontend/dist-report/posthog-app/src/lib/components/Cards/TextCard/TextCardMarkdownEditor 10.5 kB
frontend/dist-report/posthog-app/src/lib/components/MonacoDiffEditor 499 B
frontend/dist-report/posthog-app/src/lib/lemon-ui/LemonMarkdown/MermaidDiagram 1.89 kB
frontend/dist-report/posthog-app/src/lib/lemon-ui/LemonTextArea/LemonTextAreaMarkdown 688 B
frontend/dist-report/posthog-app/src/lib/lemon-ui/Link/Link 347 B
frontend/dist-report/posthog-app/src/lib/monaco/CodeEditorInline 717 B
frontend/dist-report/posthog-app/src/lib/monaco/vimMode 211 kB
frontend/dist-report/posthog-app/src/lib/ui/Button/ButtonPrimitives 414 B
frontend/dist-report/posthog-app/src/queries/nodes/WebVitals/WebVitals 8.54 kB
frontend/dist-report/posthog-app/src/queries/nodes/WebVitals/WebVitalsPathBreakdown 5.37 kB
frontend/dist-report/posthog-app/src/queries/Query/Query 2.16 kB
frontend/dist-report/posthog-app/src/queries/schema 899 kB
frontend/dist-report/posthog-app/src/scenes/activity/explore/EventsScene 4.31 kB
frontend/dist-report/posthog-app/src/scenes/activity/explore/SessionsScene 5.65 kB
frontend/dist-report/posthog-app/src/scenes/activity/live/LiveEventsTable 6.69 kB
frontend/dist-report/posthog-app/src/scenes/agentic/AgenticAuthorize 5.41 kB
frontend/dist-report/posthog-app/src/scenes/approvals/ApprovalDetail 17.6 kB
frontend/dist-report/posthog-app/src/scenes/approvals/changeRequestsLogic 520 B
frontend/dist-report/posthog-app/src/scenes/audit-logs/AdvancedActivityLogsScene 43 kB
frontend/dist-report/posthog-app/src/scenes/AuthenticatedShell 211 kB
frontend/dist-report/posthog-app/src/scenes/authentication/account/AccountConnected 2.93 kB
frontend/dist-report/posthog-app/src/scenes/authentication/account/AgenticAccountMismatch 2.32 kB
frontend/dist-report/posthog-app/src/scenes/authentication/account/credential-review/CredentialReview 4.9 kB
frontend/dist-report/posthog-app/src/scenes/authentication/cli/CLIAuthorize 11.2 kB
frontend/dist-report/posthog-app/src/scenes/authentication/cli/CLILive 3.95 kB
frontend/dist-report/posthog-app/src/scenes/authentication/email-mfa-verify/EmailMFAVerify 2.94 kB
frontend/dist-report/posthog-app/src/scenes/authentication/invite-signup/InviteSignup 1.2 kB
frontend/dist-report/posthog-app/src/scenes/authentication/login-2fa/Login2FA 4.64 kB
frontend/dist-report/posthog-app/src/scenes/authentication/login/Login 1.21 kB
frontend/dist-report/posthog-app/src/scenes/authentication/password-reset/PasswordReset 4.36 kB
frontend/dist-report/posthog-app/src/scenes/authentication/password-reset/PasswordResetComplete 2.92 kB
frontend/dist-report/posthog-app/src/scenes/authentication/shared/passkeyLogic 500 B
frontend/dist-report/posthog-app/src/scenes/authentication/signup/SignupContainer 1.18 kB
frontend/dist-report/posthog-app/src/scenes/authentication/two-factor-reset/TwoFactorReset 3.94 kB
frontend/dist-report/posthog-app/src/scenes/authentication/vercel/VercelConnect 4.92 kB
frontend/dist-report/posthog-app/src/scenes/authentication/vercel/VercelLinkError 2.2 kB
frontend/dist-report/posthog-app/src/scenes/authentication/verify-email/VerifyEmail 4.68 kB
frontend/dist-report/posthog-app/src/scenes/billing/AuthorizationStatus 662 B
frontend/dist-report/posthog-app/src/scenes/billing/Billing 615 B
frontend/dist-report/posthog-app/src/scenes/billing/BillingSection 22 kB
frontend/dist-report/posthog-app/src/scenes/cohorts/Cohort 28.7 kB
frontend/dist-report/posthog-app/src/scenes/cohorts/CohortCalculationHistory 7.83 kB
frontend/dist-report/posthog-app/src/scenes/cohorts/Cohorts 10.7 kB
frontend/dist-report/posthog-app/src/scenes/coupons/Coupons 793 B
frontend/dist-report/posthog-app/src/scenes/dashboard/Dashboard 3.03 kB
frontend/dist-report/posthog-app/src/scenes/dashboard/dashboards/Dashboards 20.4 kB
frontend/dist-report/posthog-app/src/scenes/dashboard/dashboards/templates/DashboardTemplateCopyScene 7.29 kB
frontend/dist-report/posthog-app/src/scenes/data-management/DataManagementScene 2.33 kB
frontend/dist-report/posthog-app/src/scenes/data-management/definition/DefinitionEdit 18.9 kB
frontend/dist-report/posthog-app/src/scenes/data-management/definition/DefinitionView 27.1 kB
frontend/dist-report/posthog-app/src/scenes/data-management/MaterializedColumns/MaterializedColumns 13.1 kB
frontend/dist-report/posthog-app/src/scenes/data-management/variables/SqlVariableEditScene 8.77 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/batch-exports/BatchExportScene 66.6 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/DataPipelinesNewScene 3.97 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/DestinationsScene 4.31 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/event-filtering/EventFilterScene 23.1 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/legacy-plugins/LegacyPluginScene 21.9 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/TransformationsScene 3.52 kB
frontend/dist-report/posthog-app/src/scenes/data-pipelines/WebScriptsScene 4.17 kB
frontend/dist-report/posthog-app/src/scenes/data-warehouse/DataWarehouseScene 3.11 kB
frontend/dist-report/posthog-app/src/scenes/data-warehouse/editor/EditorScene 2.78 kB
frontend/dist-report/posthog-app/src/scenes/debug/DebugScene 21.1 kB
frontend/dist-report/posthog-app/src/scenes/debug/hog/HogRepl 8.98 kB
frontend/dist-report/posthog-app/src/scenes/experiments/Experiment 211 kB
frontend/dist-report/posthog-app/src/scenes/experiments/Experiments 22.3 kB
frontend/dist-report/posthog-app/src/scenes/experiments/SharedMetrics/SharedMetric 7.56 kB
frontend/dist-report/posthog-app/src/scenes/experiments/SharedMetrics/SharedMetrics 2.25 kB
frontend/dist-report/posthog-app/src/scenes/exports/ExportsScene 5.6 kB
frontend/dist-report/posthog-app/src/scenes/feature-flags/FeatureFlag 110 kB
frontend/dist-report/posthog-app/src/scenes/feature-flags/FeatureFlags 2.44 kB
frontend/dist-report/posthog-app/src/scenes/groups/Group 16.2 kB
frontend/dist-report/posthog-app/src/scenes/groups/Groups 5.29 kB
frontend/dist-report/posthog-app/src/scenes/groups/GroupsNew 8.88 kB
frontend/dist-report/posthog-app/src/scenes/health-alerts/HealthAlertsScene 5.4 kB
frontend/dist-report/posthog-app/src/scenes/health/categoryDetail/HealthCategoryDetailScene 8.83 kB
frontend/dist-report/posthog-app/src/scenes/health/HealthScene 12.7 kB
frontend/dist-report/posthog-app/src/scenes/health/pipelineStatus/PipelineStatusScene 12.6 kB
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapNewScene 6.54 kB
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapRecordingScene 5.52 kB
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmap/HeatmapScene 8.09 kB
frontend/dist-report/posthog-app/src/scenes/heatmaps/scenes/heatmaps/HeatmapsScene 5.42 kB
frontend/dist-report/posthog-app/src/scenes/hog-functions/HogFunctionScene 55.9 kB
frontend/dist-report/posthog-app/src/scenes/inbox/InboxScene 64.1 kB
frontend/dist-report/posthog-app/src/scenes/insights/InsightQuickStart/InsightQuickStart 7.02 kB
frontend/dist-report/posthog-app/src/scenes/insights/InsightScene 35.7 kB
frontend/dist-report/posthog-app/src/scenes/insights/views/BoxPlot/BoxPlot 6.51 kB
frontend/dist-report/posthog-app/src/scenes/insights/views/CalendarHeatMap/CalendarHeatMap 9.8 kB
frontend/dist-report/posthog-app/src/scenes/insights/views/RegionMap/RegionMap 30.8 kB
frontend/dist-report/posthog-app/src/scenes/insights/views/WorldMap/WorldMap 6.18 kB
frontend/dist-report/posthog-app/src/scenes/instance/AsyncMigrations/AsyncMigrations 14.5 kB
frontend/dist-report/posthog-app/src/scenes/instance/DeadLetterQueue/DeadLetterQueue 6.94 kB
frontend/dist-report/posthog-app/src/scenes/instance/QueryPerformance/QueryPerformance 10.2 kB
frontend/dist-report/posthog-app/src/scenes/instance/SystemStatus/SystemStatus 18.3 kB
frontend/dist-report/posthog-app/src/scenes/IntegrationsRedirect/IntegrationsRedirect 752 B
frontend/dist-report/posthog-app/src/scenes/marketing-analytics/MarketingAnalyticsScene 42.4 kB
frontend/dist-report/posthog-app/src/scenes/max/Max 2.38 kB
frontend/dist-report/posthog-app/src/scenes/models/ModelsScene 19.8 kB
frontend/dist-report/posthog-app/src/scenes/models/NodeDetailScene 17.7 kB
frontend/dist-report/posthog-app/src/scenes/moveToPostHogCloud/MoveToPostHogCloud 4.4 kB
frontend/dist-report/posthog-app/src/scenes/new-tab/NewTabScene 3.17 kB
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookCanvasScene 5.08 kB
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookPanel/NotebookPanel 7.02 kB
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebookScene 10.2 kB
frontend/dist-report/posthog-app/src/scenes/notebooks/NotebooksScene 8.96 kB
frontend/dist-report/posthog-app/src/scenes/oauth/OAuthAuthorize 708 B
frontend/dist-report/posthog-app/src/scenes/onboarding/coupon/OnboardingCouponRedemption 1.23 kB
frontend/dist-report/posthog-app/src/scenes/onboarding/Onboarding 789 kB
frontend/dist-report/posthog-app/src/scenes/onboarding/sdks/SdkHealthScene 9.37 kB
frontend/dist-report/posthog-app/src/scenes/organization/ConfirmOrganization/ConfirmOrganization 4.4 kB
frontend/dist-report/posthog-app/src/scenes/organization/Create/Create 602 B
frontend/dist-report/posthog-app/src/scenes/organization/Deactivated 1.06 kB
frontend/dist-report/posthog-app/src/scenes/organization/PendingDeletion 2.1 kB
frontend/dist-report/posthog-app/src/scenes/persons/PersonScene 21 kB
frontend/dist-report/posthog-app/src/scenes/persons/PersonsScene 7.02 kB
frontend/dist-report/posthog-app/src/scenes/PreflightCheck/PreflightCheck 5.46 kB
frontend/dist-report/posthog-app/src/scenes/product-tours/ProductTour 268 kB
frontend/dist-report/posthog-app/src/scenes/product-tours/ProductTours 6.24 kB
frontend/dist-report/posthog-app/src/scenes/project-homepage/ProjectHomepage 20 kB
frontend/dist-report/posthog-app/src/scenes/project/Create/Create 795 B
frontend/dist-report/posthog-app/src/scenes/project/PendingDeletion 2.43 kB
frontend/dist-report/posthog-app/src/scenes/resource-transfer/ResourceTransfer 10.8 kB
frontend/dist-report/posthog-app/src/scenes/saved-insights/SavedInsights 2.35 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/detail/SessionRecordingDetail 3.38 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/file-playback/SessionRecordingFilePlaybackScene 5.99 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/kiosk/SessionRecordingsKiosk 11.5 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/player/snapshot-processing/DecompressionWorkerManager 323 B
frontend/dist-report/posthog-app/src/scenes/session-recordings/playlist/SessionRecordingsPlaylistScene 6.44 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/SessionRecordings 2.37 kB
frontend/dist-report/posthog-app/src/scenes/session-recordings/settings/SessionRecordingsSettingsScene 3.54 kB
frontend/dist-report/posthog-app/src/scenes/sessions/SessionProfileScene 16.5 kB
frontend/dist-report/posthog-app/src/scenes/settings/SettingsScene 5.28 kB
frontend/dist-report/posthog-app/src/scenes/sites/Site 1.47 kB
frontend/dist-report/posthog-app/src/scenes/startups/StartupProgram 21 kB
frontend/dist-report/posthog-app/src/scenes/StripeConfirmInstall/StripeConfirmInstall 3.5 kB
frontend/dist-report/posthog-app/src/scenes/subscriptions/SubscriptionScene 17.8 kB
frontend/dist-report/posthog-app/src/scenes/subscriptions/SubscriptionsScene 6.88 kB
frontend/dist-report/posthog-app/src/scenes/surveys/forms/SurveyFormBuilder 3.19 kB
frontend/dist-report/posthog-app/src/scenes/surveys/Survey 2.72 kB
frontend/dist-report/posthog-app/src/scenes/surveys/Surveys 27.4 kB
frontend/dist-report/posthog-app/src/scenes/surveys/wizard/SurveyWizard 73.1 kB
frontend/dist-report/posthog-app/src/scenes/themes/CustomCssScene 5.17 kB
frontend/dist-report/posthog-app/src/scenes/toolbar-launch/ToolbarLaunch 4.06 kB
frontend/dist-report/posthog-app/src/scenes/Unsubscribe/Unsubscribe 1.61 kB
frontend/dist-report/posthog-app/src/scenes/web-analytics/SessionAttributionExplorer/SessionAttributionExplorerScene 8.09 kB
frontend/dist-report/posthog-app/src/scenes/web-analytics/WebAnalyticsScene 16 kB
frontend/dist-report/posthog-app/src/scenes/wizard/Wizard 4.34 kB
frontend/dist-report/posthog-app/src/sharedChunkAnchors 1.29 kB
frontend/dist-report/render-query/src/render-query/render-query 27.4 MB
frontend/dist-report/toolbar/src/toolbar/toolbar 10.4 MB

compressed-size-action

@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-tools branch from 113a13f to 98f6b8e Compare June 11, 2026 21:33
@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-characterize branch from 4c1ea15 to 53cc0f6 Compare June 11, 2026 21:33
filters: tuple[MetricFilter, ...],
candidate_keys: tuple[str, ...] | None,
) -> tuple[MetricAnomalyDimension, ...]:
keys = candidate_keys or _discover_candidate_keys(team, metric_name, anomaly_from, anomaly_to)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-discovery uses only the anomaly window to find candidate keys, which will miss labels that existed in the baseline but disappeared during the anomaly. This could fail to identify the root cause when services/shards stop reporting.

# Bug: discovers from anomaly window only
keys = candidate_keys or _discover_candidate_keys(team, metric_name, anomaly_from, anomaly_to)

# Fix: discover from the full baseline+anomaly span
keys = candidate_keys or _discover_candidate_keys(team, metric_name, baseline_from, anomaly_to)

The function already has baseline_from available via the closure (line 105), so pass it instead of anomaly_from to ensure labels from both windows are considered.

Suggested change
keys = candidate_keys or _discover_candidate_keys(team, metric_name, anomaly_from, anomaly_to)
keys = candidate_keys or _discover_candidate_keys(team, metric_name, baseline_from, anomaly_to)

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-tools branch from fb9d3f3 to 56996b6 Compare June 11, 2026 22:07
@DanielVisca DanielVisca added the stamphog Request AI review from stamphog label Jun 11, 2026 — with Graphite App
Comment on lines +100 to +107
if anomaly_to <= anomaly_from:
raise ValueError("anomaly_to must be after anomaly_from")
if baseline_to is None:
baseline_to = anomaly_from
if baseline_from is None:
baseline_from = baseline_to - (anomaly_to - anomaly_from)
if baseline_to > anomaly_from:
raise ValueError("the baseline window must end at or before anomaly_from")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing validation for baseline_from < baseline_to. The code validates that anomaly_to > anomaly_from and baseline_to <= anomaly_from, but never checks if baseline_from < baseline_to.

If a caller explicitly passes baseline_from >= baseline_to, the function will:

  1. Run the query from baseline_from to anomaly_to
  2. Filter points with time < anomaly_from_iso as baseline (line 135)
  3. Produce incorrect or empty baseline_values, leading to invalid statistical calculations
if baseline_from >= baseline_to:
    raise ValueError("baseline_from must be before baseline_to")

Add this check after line 105 to prevent invalid window configurations.

Suggested change
if anomaly_to <= anomaly_from:
raise ValueError("anomaly_to must be after anomaly_from")
if baseline_to is None:
baseline_to = anomaly_from
if baseline_from is None:
baseline_from = baseline_to - (anomaly_to - anomaly_from)
if baseline_to > anomaly_from:
raise ValueError("the baseline window must end at or before anomaly_from")
if anomaly_to <= anomaly_from:
raise ValueError("anomaly_to must be after anomaly_from")
if baseline_to is None:
baseline_to = anomaly_from
if baseline_from is None:
baseline_from = baseline_to - (anomaly_to - anomaly_from)
if baseline_from >= baseline_to:
raise ValueError("baseline_from must be before baseline_to")
if baseline_to > anomaly_from:
raise ValueError("the baseline window must end at or before anomaly_from")

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-tools branch from 56996b6 to 25d58a1 Compare June 11, 2026 22:36
@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-characterize branch from 1752d82 to 06bae3f Compare June 11, 2026 22:36

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two unresolved substantive bugs flagged in inline comments: (1) candidate-key discovery only scans the anomaly window, silently missing labels that disappeared during the anomaly (root-cause blind spot); (2) no validation that baseline_from < baseline_to, which can produce silently incorrect statistical output. Both are behavioral correctness issues in new production logic, not style nits.

@stamphog stamphog Bot removed the stamphog Request AI review from stamphog label Jun 11, 2026
POST /metrics/characterize compares an anomaly window against a baseline
(default: the equal-length window immediately before) and reports
magnitude (mean/peak/change ratio), direction, the onset bucket (first
bucket beyond 3 baseline stddevs with a 50% relative floor), and the
top label-value movers — drilling into up to four candidate keys,
auto-discovered from the metric's attributes when not given. The
aggregation auto-picks from the metric's OTel type (counter -> rate,
gauge -> avg, histogram -> p95). Exposed as the
characterize-metric-anomaly MCP tool whose prompt tells the agent how
to read the report and to pivot into logs/traces at onset_time.

How to validate manually:
- hogli test products/metrics/backend/tests/test_anomaly.py (8 tests)
- POST /api/environments/:id/metrics/characterize with
  {"query": {"metricName": "metrics_rate_limiter_message_lag_seconds",
  "anomalyFrom": "<30m ago>"}} returns direction/onset/top_movers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-tools branch from 9ad6641 to a4aecc5 Compare June 11, 2026 23:43
@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-characterize branch from 79d8ba1 to eebda3f Compare June 11, 2026 23:44

# One query over the combined window keeps baseline and anomaly on a
# single grid; the interval comes from the combined span.
interval = _pick_interval(baseline_from, anomaly_to)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: Unbounded metrics scans

A user with metrics:read can submit an anomalyFrom far in the past and omit candidateKeys; this endpoint then scans the selected metric once for the series, once to discover candidate keys, and up to four more times grouped by labels. Add a maximum combined baseline/anomaly window or query cost guard before running these queries so one API/MCP request cannot monopolize the metrics ClickHouse workload.

@veria-ai

veria-ai Bot commented Jun 12, 2026

Copy link
Copy Markdown

PR overview

This PR adds a metric anomaly characterization capability, including a backend endpoint and corresponding MCP tool for analyzing anomalous metric ranges and related label candidates.

There is one open security concern around resource consumption: a user with metrics read access can request a very large historical range and trigger multiple expensive ClickHouse scans in a single request. Because no issues have been addressed yet, the PR still needs a query window or cost guard to prevent one request from monopolizing metrics infrastructure.

Open issues (1)

Fixed/addressed: 0 · PR risk: 6/10

@DanielVisca DanielVisca force-pushed the posthog-code/metrics-mcp-characterize branch from 7dca38d to eebda3f Compare June 12, 2026 01:31
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