Skip to content

feat(mcp-analytics): separate mcp properties in the taxonomic filter - #69575

Merged
pauldambra merged 17 commits into
masterfrom
posthog-code/mcp-properties-taxonomic-filter
Jul 10, 2026
Merged

feat(mcp-analytics): separate mcp properties in the taxonomic filter#69575
pauldambra merged 17 commits into
masterfrom
posthog-code/mcp-properties-taxonomic-filter

Conversation

@pauldambra

Copy link
Copy Markdown
Member

Problem

MCP analytics captures tool call events ($mcp_tool_call and friends) with a known $mcp_* property schema, but in the taxonomic filter that schema is buried in the generic event properties list. The target use case is building funnels between different tool calls, or user paths between tool calls, split by success or failure. We want the event and its expected properties separated out for clarity, the way autocapture separates its element properties.

Changes

  • New mcp_properties group in the core taxonomy, derived from the $mcp_* event properties (no duplication), and $mcp_tool_name marked as the primary_property of $mcp_tool_call. The primary property makes tool call rows, funnel step labels, and suggested filters describe themselves by tool name.
  • New TaxonomicFilterGroupType.MCPProperties ("MCP properties") group, defined in both the legacy picker (taxonomicFilterLogic.tsx) and the rebuild (buildTaxonomicGroups.tsx) from a shared helper (utils/mcpProperties.ts). It only materializes when the picker is scoped to canonical $mcp_* events, so nothing changes for anyone else. Options are priority ordered (tool name, category, is error, error type, duration, client, intent first) and remap to event properties on selection, so picking one produces a plain event property filter.
  • $mcp_is_error is seeded into Suggested filters when scoped to $mcp_tool_call, mirroring the autocapture text/selector seeding, so the success/failure split is one click away.
  • The group is offered ahead of Event properties in the default property picker, insight property filters (funnel step filters included), breakdown pickers, and the MCP analytics dashboard filter bar. $mcp_tool_call also gets promoted properties for event detail views.

With this, the funnel flow is: pick the "MCP tool call" event per step, filter each step by tool name from the leading MCP tab (or straight from Suggested filters), and break down by $mcp_is_error.

Note

Two decisions here need explicit sign-off per the taxonomic filter guardrails:

  1. Ordering: the MCP properties tab is placed before Event properties, but only in pickers already scoped to $mcp_* events, which is a brand-new context with no existing selection behavior to regress. Non-MCP pickers are untouched (verified by test).
  2. Three surfaces: the change is mirrored across legacy-control/legacy-pill (shared code path) and rebuild-menu (separate group table), with tests on both sides guarding drift. The rebuild arm needed an explicit MCPProperties -> Event filter type mapping because it commits with the tab's own group type.

A natural follow-up (not in this PR): an "MCP tool calls" pseudo-event group for the funnel/trends step picker that lists tool names directly and expands to $mcp_tool_call + tool name filter, like AutocaptureEvents does for element text. That needs an has_mcp_tool_call project event existence flag in the app context (cache shape change in get_default_event_info), so it's left out here.

How did you test this code?

Automated only, no manual UI verification was possible in this environment:

  • utils/mcpProperties.test.ts (new): catches the taxonomy drift that would empty or misorder the MCP tab, the gating regression that would surface it for legacy unprefixed mcp_* events, loss of the primary_property wiring, and (rebuild side) loss of the eventNames gating or the event-properties remap on options.
  • taxonomicFilterLogic.test.ts (extended): same gating assertions for the legacy variant, so a one-sided edit that diverges the two arms fails.
  • utils.test.ts (extended): the one-way MCPProperties -> PropertyFilterType.Event mapping, without which rebuild-arm selections produce a typeless filter.
  • Full TaxonomicFilter/, PropertyFilters/, BreakdownFilter/, ActionFilter/ suites pass (51 suites, 923 tests). hogli ci:preflight --fix is green.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Authored with PostHog Code (Claude). Skills invoked: /modifying-taxonomic-filter (before any change) and /writing-tests (before the tests).
  • Modeled the group on the ErrorTrackingProperties/ActivityLogProperties pattern (curated options with a group: EventProperties remap) rather than an endpoint-backed list, so the expected schema shows even before every property has been ingested; rejected moving the $mcp_* definitions out of event_properties in the taxonomy (would break existing label lookups) in favor of deriving the new group from them.
  • Considered injecting the tab via the promotion/shortcut lists like Elements, but chose eventNames-gated availability plus static call-site placement as the smaller, more predictable surface.

Created with PostHog Code

MCP analytics events ($mcp_tool_call and friends) carry a known property
schema. Surface that schema as a dedicated "MCP properties" taxonomic
filter group, the way autocapture separates its element properties:

- derive an mcp_properties group in the core taxonomy from the $mcp_*
  event properties, and mark $mcp_tool_name as the primary property of
  $mcp_tool_call so tool-call rows and funnel steps describe themselves
  by tool name
- add a TaxonomicFilterGroupType.MCPProperties group to both the legacy
  picker and the rebuild, only materialized when the picker is scoped to
  canonical $mcp_* events; options remap to event properties so selection
  produces plain event property filters
- seed $mcp_is_error into Suggested filters when scoped to $mcp_tool_call
  so success/failure splits are one click away
- offer the group (ahead of Event properties) in the default property
  picker, insight property filters, breakdowns, and the MCP analytics
  dashboard filter bar

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
@pauldambra pauldambra self-assigned this Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Hey @pauldambra! 👋

It looks like your git author email on this PR isn't your @posthog.com address (paul.dambra@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — 🟢 -1.96 MiB (-2.8%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 68.07 MiB · 🟢 -1.96 MiB (-2.8%)

File Size Δ vs base
exporter/src/exporter/scenes/ExporterNotebookScene.js 3.19 MiB 🔺 +324.4 KiB (+11.0%)
exporter/src/exporter/scenes/ExporterDashboardScene.js 272.3 KiB 🔺 +265.0 KiB (+3627.0%)
exporter/_parent/products/workflows/frontend/Workflows/WorkflowScene.js removed 🟢 -157.5 KiB (-100.0%)
exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsScene.js removed 🟢 -150.5 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/AIObservabilityTraceScene.js removed 🟢 -130.3 KiB (-100.0%)
exporter/_parent/products/customer_analytics/frontend/CustomerAnalyticsScene.js removed 🟢 -119.6 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/AIObservabilityScene.js removed 🟢 -115.2 KiB (-100.0%)
exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingIssueScene/ErrorTrackingIssueScene.js removed 🟢 -100.5 KiB (-100.0%)
exporter/_parent/products/tracing/frontend/TracingScene.js removed 🟢 -88.8 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner.js removed 🟢 -70.1 KiB (-100.0%)
exporter/_parent/products/workflows/frontend/WorkflowsScene.js removed 🟢 -60.5 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluation.js removed 🟢 -59.3 KiB (-100.0%)
exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentNewScene.js removed 🟢 -58.9 KiB (-100.0%)
exporter/_parent/products/endpoints/frontend/EndpointScene.js removed 🟢 -56.4 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClustersScene.js removed 🟢 -52.9 KiB (-100.0%)
exporter/_parent/products/engineering_analytics/frontend/scenes/EngineeringAnalyticsScene.js removed 🟢 -52.7 KiB (-100.0%)
exporter/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene.js removed 🟢 -48.6 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunScene.js removed 🟢 -46.9 KiB (-100.0%)
exporter/_parent/products/posthog_ai/frontend/scenes/TaskTracker/TaskTracker.js removed 🟢 -43.1 KiB (-100.0%)
exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingScene/ErrorTrackingScene.js removed 🟢 -42.5 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptScene.js removed 🟢 -37.7 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/playground/AIObservabilityPlaygroundScene.js removed 🟢 -36.9 KiB (-100.0%)
exporter/_parent/products/growth/frontend/IdentityMatchingScene.js removed 🟢 -35.3 KiB (-100.0%)
exporter/_parent/products/metrics/frontend/MetricsScene.js removed 🟢 -35.1 KiB (-100.0%)
exporter/_parent/products/data_warehouse/frontend/scenes/SchemaScene/SchemaScene.js removed 🟢 -33.9 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/evaluations/AIObservabilityEvaluationsScene.js removed 🟢 -32.6 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTag.js removed 🟢 -31.9 KiB (-100.0%)
exporter/_parent/products/revenue_analytics/frontend/RevenueAnalyticsScene.js removed 🟢 -29.8 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/ScannerEditorScene.js removed 🟢 -28.6 KiB (-100.0%)
exporter/_parent/products/actions/frontend/pages/Action.js removed 🟢 -28.5 KiB (-100.0%)
exporter/_parent/products/data_warehouse/DataWarehouseScene.js removed 🟢 -28.2 KiB (-100.0%)
exporter/_parent/products/endpoints/frontend/EndpointsScene.js removed 🟢 -27.4 KiB (-100.0%)
exporter/_parent/products/links/frontend/LinkScene.js removed 🟢 -25.1 KiB (-100.0%)
exporter/_parent/products/business_knowledge/frontend/scenes/BusinessKnowledgeScene.js removed 🟢 -24.5 KiB (-100.0%)
exporter/_parent/products/session_summaries/frontend/SessionGroupSummaryScene.js removed 🟢 -23.5 KiB (-100.0%)
exporter/_parent/products/logs/frontend/LogsScene.js removed 🟢 -23.0 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene.js removed 🟢 -22.6 KiB (-100.0%)
exporter/src/scenes/data-pipelines/event-filtering/EventFilterScene.js removed 🟢 -22.5 KiB (-100.0%)
exporter/_parent/products/engineering_analytics/frontend/scenes/PullRequestDetailScene.js removed 🟢 -21.6 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/clusters/AIObservabilityClusterScene.js removed 🟢 -21.5 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/observations/ReplayObservation.js removed 🟢 -21.4 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetScene.js removed 🟢 -20.5 KiB (-100.0%)
exporter/src/scenes/models/ModelsScene.js removed 🟢 -19.9 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotOverviewScene.js removed 🟢 -19.6 KiB (-100.0%)
exporter/_parent/products/live_debugger/frontend/LiveDebugger.js removed 🟢 -19.3 KiB (-100.0%)
exporter/_parent/products/subscriptions/frontend/scenes/SubscriptionScene.js removed 🟢 -19.0 KiB (-100.0%)
exporter/_parent/products/logs/frontend/scenes/LogsAlertDetailScene/LogsAlertDetailScene.js removed 🟢 -18.4 KiB (-100.0%)
exporter/_parent/products/engineering_analytics/frontend/scenes/WorkflowRunsScene.js removed 🟢 -17.6 KiB (-100.0%)
exporter/_parent/products/workflows/frontend/TemplateLibrary/MessageTemplate.js removed 🟢 -17.1 KiB (-100.0%)
exporter/_parent/products/mcp_analytics/frontend/MCPAnalyticsToolDetail.js removed 🟢 -16.1 KiB (-100.0%)
exporter/_parent/products/managed_migrations/frontend/ManagedMigration.js removed 🟢 -15.6 KiB (-100.0%)
exporter/src/scenes/models/NodeDetailScene.js removed 🟢 -14.8 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/ActionEditorScene.js removed 🟢 -14.6 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSnapshotHistoryScene.js removed 🟢 -14.2 KiB (-100.0%)
exporter/_parent/products/ai_gateway/frontend/AIGatewayScene.js removed 🟢 -13.2 KiB (-100.0%)
render-query/src/render-query/render-query.js 24.19 MiB 🔺 +12.9 KiB (+0.1%)
exporter/_parent/products/ai_observability/frontend/tags/AIObservabilityTagsScene.js removed 🟢 -12.1 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewSettingsScene.js removed 🟢 -11.6 KiB (-100.0%)
exporter/_parent/products/tracing/frontend/TracingOperationScene.js removed 🟢 -10.8 KiB (-100.0%)
exporter/_parent/products/user_interviews/frontend/UserInterview.js removed 🟢 -10.6 KiB (-100.0%)
toolbar/src/toolbar/toolbar-app.js 1.73 MiB 🔺 +9.9 KiB (+0.6%)
exporter/_parent/products/feature_flags/frontend/staff/FeatureFlagsStaffToolsScene.js removed 🟢 -9.6 KiB (-100.0%)
exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyTemplatesScene/CustomerJourneyTemplatesScene.js removed 🟢 -9.5 KiB (-100.0%)
exporter/_parent/products/logs/frontend/scenes/LogsAlertNotificationDetailScene/LogsAlertNotificationDetailScene.js removed 🟢 -9.0 KiB (-100.0%)
exporter/_parent/products/tasks/frontend/SlackTaskContextScene.js removed 🟢 -9.0 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewRunsScene.js removed 🟢 -8.3 KiB (-100.0%)
exporter/src/scenes/data-pipelines/TransformationsScene.js removed 🟢 -8.3 KiB (-100.0%)
exporter/_parent/products/user_interviews/frontend/UserInterviewResponse.js removed 🟢 -8.1 KiB (-100.0%)
exporter/_parent/products/error_tracking/frontend/scenes/ErrorTrackingFingerprintsScene/ErrorTrackingIssueFingerprintsScene.js removed 🟢 -7.9 KiB (-100.0%)
exporter/_parent/products/engineering_analytics/frontend/scenes/WorkflowRunDetailScene.js removed 🟢 -7.8 KiB (-100.0%)
exporter/_parent/products/engineering_analytics/frontend/scenes/EngineeringAnalyticsAuthorScene.js removed 🟢 -7.8 KiB (-100.0%)
exporter/_parent/products/data_warehouse/frontend/scenes/SourcesScene/SourcesScene.js removed 🟢 -7.8 KiB (-100.0%)
exporter/_parent/products/data_warehouse/frontend/scenes/SourceConnectScene/SourceConnectScene.js removed 🟢 -7.3 KiB (-100.0%)
posthog-app/src/scenes/App.js 26.7 KiB 🔺 +7.1 KiB (+36.2%)
exporter/_parent/products/customer_analytics/frontend/scenes/CustomerAnalyticsConfigurationScene/CustomerAnalyticsConfigurationScene.js removed 🟢 -7.0 KiB (-100.0%)
exporter/_parent/products/customer_analytics/frontend/scenes/CustomerJourneyBuilderScene/CustomerJourneyBuilderScene.js removed 🟢 -6.8 KiB (-100.0%)
exporter/_parent/products/feature_flags/frontend/FeatureFlagTemplatesScene.js removed 🟢 -6.8 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/VisionActionRunScene.js removed 🟢 -6.7 KiB (-100.0%)
exporter/_parent/products/subscriptions/frontend/scenes/SubscriptionsScene.js removed 🟢 -6.6 KiB (-100.0%)
exporter/_parent/products/user_interviews/frontend/UserInterviews.js removed 🟢 -6.5 KiB (-100.0%)
exporter/_parent/products/legal_documents/frontend/scenes/LegalDocumentsScene.js removed 🟢 -6.5 KiB (-100.0%)
posthog-app/src/scenes/insights/InsightScene.js 37.1 KiB 🟢 -6.3 KiB (-14.5%)
exporter/_parent/products/logs/frontend/scenes/LogsSamplingDetailScene/LogsSamplingDetailScene.js removed 🟢 -6.2 KiB (-100.0%)
exporter/_parent/products/actions/frontend/pages/Actions.js removed 🟢 -6.1 KiB (-100.0%)
exporter/_parent/products/early_access_features/frontend/EarlyAccessFeature.js removed 🟢 -6.1 KiB (-100.0%)
exporter/_parent/products/replay_vision/frontend/replay_scanners/VisionActionScene.js removed 🟢 -5.8 KiB (-100.0%)
exporter/_parent/products/games/FlappyHog/FlappyHog.js removed 🟢 -5.6 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/prompts/LLMPromptsScene.js removed 🟢 -5.6 KiB (-100.0%)
exporter/_parent/products/posthog_ai/frontend/components/tool/builtinToolRenderers.js removed 🟢 -5.6 KiB (-100.0%)
exporter/_parent/products/session_summaries/frontend/SessionGroupSummariesTable.js removed 🟢 -5.5 KiB (-100.0%)
exporter/_parent/products/conversations/frontend/scenes/settings/SupportSettingsScene.js removed 🟢 -5.4 KiB (-100.0%)
exporter/_parent/products/links/frontend/LinksScene.js removed 🟢 -5.3 KiB (-100.0%)
exporter/_parent/products/games/368Hedgehogs/368Hedgehogs.js removed 🟢 -5.2 KiB (-100.0%)
posthog-app/_parent/products/engineering_analytics/frontend/scenes/EngineeringAnalyticsScene.js 58.5 KiB 🔺 +5.0 KiB (+9.3%)
exporter/_parent/products/ai_observability/frontend/LLMASessionFeedbackDisplay.js removed 🟢 -4.7 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/datasets/AIObservabilityDatasetsScene.js removed 🟢 -4.2 KiB (-100.0%)
exporter/_parent/products/posthog_ai/frontend/components/tool/posthogCodeToolRenderers.js removed 🟢 -4.2 KiB (-100.0%)
exporter/_parent/products/early_access_features/frontend/EarlyAccessFeatures.js removed 🟢 -4.0 KiB (-100.0%)
exporter/_parent/products/ai_observability/frontend/AIObservabilityUsers.js removed 🟢 -3.8 KiB (-100.0%)
exporter/src/exporter/scenes/ExporterRecordingScene.js 2.5 KiB 🟢 -3.8 KiB (-60.5%)
exporter/_parent/products/customer_analytics/frontend/components/AccountRelationshipsInput/CyclotronJobInputAccountRelationships.js removed 🟢 -3.7 KiB (-100.0%)
exporter/_parent/products/posthog_ai/frontend/components/tool/EditDiffRenderer.js removed 🟢 -3.4 KiB (-100.0%)
exporter/_parent/products/customer_analytics/frontend/components/AccountPropertiesInput/CyclotronJobInputAccountProperties.js removed 🟢 -3.3 KiB (-100.0%)
exporter/_parent/products/logs/frontend/scenes/LogsSamplingNewScene/LogsSamplingNewScene.js removed 🟢 -3.3 KiB (-100.0%)
exporter/_parent/products/data_warehouse/frontend/scenes/NewSourceScene/NewSourceScene.js removed 🟢 -3.2 KiB (-100.0%)
exporter/_parent/products/visual_review/frontend/scenes/VisualReviewIndexScene.js removed 🟢 -3.2 KiB (-100.0%)
exporter/src/queries/nodes/WebVitals/WebVitals.js 8.7 KiB 🟢 -3.1 KiB (-26.5%)
exporter/src/exporter/scenes/ExporterInsightScene.js 4.6 KiB 🟢 -3.1 KiB (-40.6%)
exporter/src/queries/Query/Query.js 2.4 KiB 🟢 -3.1 KiB (-56.1%)
exporter/_parent/products/ai_observability/frontend/AIObservabilitySessionScene.js removed 🟢 -3.1 KiB (-100.0%)
exporter/_parent/products/data_warehouse/frontend/scenes/SourceScene/SourceScene.js removed 🟢 -3.0 KiB (-100.0%)
posthog-app/_parent/products/replay_vision/frontend/observations/ReplayObservation.js 20.9 KiB 🟢 -2.9 KiB (-12.2%)
exporter/_parent/products/conversations/frontend/components/SlaBusinessHours/CyclotronJobInputBusinessHours.js removed 🟢 -2.6 KiB (-100.0%)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScanner.js 74.2 KiB 🔺 +2.4 KiB (+3.4%)
exporter/_parent/products/conversations/frontend/scenes/tickets/SupportTicketsScene.js removed 🟢 -1.9 KiB (-100.0%)
posthog-app/_parent/products/metrics/frontend/MetricsScene.js 38.0 KiB 🔺 +1.8 KiB (+5.1%)
exporter/_parent/products/posthog_ai/frontend/components/QuestionRenderer.js removed 🟢 -1.7 KiB (-100.0%)
exporter/_parent/products/skills/frontend/LLMSkillsScene.js removed 🟢 -1.7 KiB (-100.0%)
exporter/_parent/products/skills/frontend/LLMSkillScene.js removed 🟢 -1.7 KiB (-100.0%)
exporter/_parent/products/conversations/frontend/components/Assignee/CyclotronJobInputAssignee.js removed 🟢 -1.3 KiB (-100.0%)
exporter/src/lib/components/ActivityLog/describers.js 127.1 KiB 🟢 -1.2 KiB (-1.0%)
exporter/src/queries/schema.js 1.01 MiB 🔺 +1.2 KiB (+0.1%)
posthog-app/src/queries/schema.js 1.01 MiB 🔺 +1.2 KiB (+0.1%)
exporter/_parent/products/alerts/frontend/views/EditAlertModal.js 1.4 KiB 🟢 -1.0 KiB (-42.5%)

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.21 MiB · 22 files 🔺 +259 B (+0.0%) ███░░░░░░░ 28.2% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.09 MiB · 2,974 files 🟢 -8.6 KiB (-0.1%) █████████░ 87.5% of 9.25 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
668 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
277.3 KiB ../node_modules/.pnpm/posthog-js@1.399.1/node_modules/posthog-js/dist/rrweb.js
266.9 KiB ../node_modules/.pnpm/@posthog+icons@0.37.4_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
234.6 KiB src/taxonomy/core-filter-definitions-by-group.json
221.5 KiB ../node_modules/.pnpm/posthog-js@1.399.1/node_modules/posthog-js/dist/module.js
164.0 KiB src/queries/validators.js
154.2 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
105.9 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

Dist folder size — 🟢 -157.34 MiB (-10.9%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1283.76 MiB · 🟢 -157.34 MiB (-10.9%)

⚠️ Playwright — 1 flaky

🎭 Playwright report · View test results →

⚠️ 1 flaky test:

  • service facet passes serviceNames to API (chromium)

These issues are not necessarily caused by your changes.
Annoyed by this section? Help fix flakies and failures and it will go green!

@trunk-io

trunk-io Bot commented Jul 9, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

pauldambra and others added 2 commits July 9, 2026 08:15
The new TaxonomicFilterGroupType enum value flows into the generated
frontend/src/queries/schema.json and posthog/schema_enums.py; CI's
schema freshness check (schema:build:json && git diff --exit-code)
failed without them.

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
@pauldambra pauldambra added the stamphog Request AI approval (no full review) label Jul 9, 2026
Adds a Storybook story showing the picker scoped to $mcp_tool_call
(Suggested filters leading with tool name + error state, and the
dedicated MCP properties group), and renders MCP group rows through
PropertyKeyInfo so the schema shows friendly labels instead of raw
$mcp_* keys.

Also carries pr-demo-mcp-properties.gif temporarily so a PR comment can
embed the recorded demo via a commit-pinned raw URL; removed again in
the next commit so it never reaches the merged tree.

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
The recording stays reachable through the commit-pinned raw URL on the
previous commit; the branch tree goes back to code only.

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285

Copy link
Copy Markdown
Member Author

🎥 Demo: MCP properties in the taxonomic filter (Storybook)

Recorded from the new story Filters/Taxonomic Filter → MCP Tool Call Context Leads With MCP Properties (added to this PR), driven by Playwright against a local Storybook.

What the recording walks through:

  1. The picker opens scoped to $mcp_tool_callSuggested filters leads with MCP tool name (the event's new primary_property) and MCP is error (the seeded success/failure split).
  2. Switching to the dedicated MCP properties category shows the known @posthog/mcp schema with friendly labels, priority-ordered (tool name, category, is error, error type, duration, client name, intent, then the rest), with the definition popover pulling descriptions and examples from the core taxonomy.
  3. Scrolling through the full 37-property schema.
  4. Searching error narrows to the error-state properties, and picking MCP is error commits a plain event property filter.

MCP properties taxonomic filter demo

Recording the video surfaced a real gap, fixed in the same commit: MCP group rows rendered raw $mcp_* keys because InfiniteList.renderItemContents only routes known group types through PropertyKeyInfoMCPProperties is now on that list, so the tab shows labeled schema properties.

Housekeeping: the gif rides on commit 68a1408 (pinned raw URL) and was removed from the tree in the next commit, so it never reaches the merged tree. The story also gives this setup permanent visual-regression coverage.


Created with PostHog Code


/** The properties funnels and paths between tool calls pivot on, shown first.
* The rest of the known schema follows in taxonomy (alphabetical) order. */
const PRIORITY_MCP_PROPERTIES: string[] = [

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

could this be derived from CORE_FILTER_DEFINITIONS_BY_GROUP["mcp_properties"] somehow?
might be better to have a property on those objects rather than duplicate the names here

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm review complete — four independent perspectives (qa-team specialists + generalists, paul-reviewer, xp-reviewer, security-audit). See inline comments and the summary comment.

Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Multi-perspective review: qa-team (specialists + generalists), paul-reviewer, xp-reviewer, security-audit

Verdict: 💬 APPROVE WITH NITS

Structurally sound where it matters most: the new group type never leaks into persisted data (all commit paths serialize as plain type: 'event' / breakdown_type: 'event', so saved insights and deploy-skew are safe), the group is a verified no-op in non-MCP pickers in both filter variants, all six generated enum copies are consistent, and backend consumers are inert to the mirrored group. Two MEDIUM cross-variant/UX findings are worth fixing before the taxonomic rebuild flag widens.

Key findings

  • 🟡 PRIORITY_MCP_PROPERTIES hand-duplicates POSTHOG_EVENT_PROMOTED_PROPERTIES['$mcp_tool_call'] — two identical seven-key lists with nothing keeping them in sync (flagged independently by 3 of 4 reviewers)
  • 🟡 Rebuild arm records recents + shared telemetry under mcp_properties while legacy records event_properties — duplicate Recents rows and cross-arm telemetry drift
  • 🟡 $mcp_* keys render twice (MCP tab + Event properties) in the aggregated search with no cross-group dedupe — looks broken without being broken
  • 🟢 Cluster of LOW hardening items: excluded/allowlist bypass in the MCP tab, rebuild arm missing the $mcp_tool_name suggestion its comment promises, prefix heuristic offering tool-call properties on non-tool-call $mcp_* scopes, position-sensitive Python mirror with no sync check, primary_property silently superseding team pins, missing type guard

Convergence

Independently flagged by 2+ reviewers: the duplicated priority lists (paul + xp + 3 qa-team personas), the cross-group duplicate rows (4 qa-team personas), the excluded-properties bypass (3 personas), the missing rebuild suggestion (2), the over-broad prefix heuristic (3), the unsynced taxonomy mirror (2), and the group-literal dual-write (paul + xp, who both concluded it follows the file pair's existing convention).

Findings without a diff anchor

  • frontend/src/lib/components/TaxonomicFilter/headless/AutocompleteInput.tsx (not touched by this PR): PROPERTY_GROUP_TYPE_TO_DEFINITION_TYPE wasn't extended with MCPProperties, so the rebuild's details pane resolves no propertyType (e.g. no Numeric chip for $mcp_duration_ms) for MCP-tab entries. Display-only; add [TaxonomicFilterGroupType.MCPProperties]: PropertyDefinitionType.Event.
  • Copy (pre-existing, amplified by the new tab): several $mcp_* descriptions cite bare legacy event names ("Only present on mcp_tool_call.") while the tab only appears for $-prefixed events; and $mcp_version ("MCP server version (internal)") sits beside $mcp_server_version ("MCP server version") in a list pitched as the known schema. Cheap follow-up to reword + regenerate.
  • Process: per this area's guardrails, tab ordering (MCP properties leading ahead of Event properties) and the Suggested seeding are already flagged in the PR description for explicit human sign-off — reaffirming that here.

Reviewer summaries

Reviewer Assessment
🔍 qa-team MEDIUM risk, APPROVE WITH NITS — 8 personas converged on the two cross-variant MEDIUMs; persistence/deploy-skew paths verified safe
👤 paul one real question (the two identical priority lists want one source of truth), everything else seeds — "nice, tidy change", praise for the parameterized drift-guard tests
📐 xp "solid, maintainable work… tested at the right level"; merge after deduplicating the priority list; group-literal duplication follows the file pair's existing convention
🛡 security-audit 0 findings — all displayed content is repo-controlled and React-escaped, eventNames only gates a static tab, selections yield ordinary parameterized event property filters

Automated by QA Swarm — not a human review

- derive PRIORITY_MCP_PROPERTIES from POSTHOG_EVENT_PROMOTED_PROPERTIES so the
  picker ordering and event-inspector promotion share one source of truth
- record rebuild recents under an option-declared group (mirrors legacy
  getItemGroup resolution) so MCP-tab picks don't grow near-duplicate Recent
  rows across picker variants; guarded by a hook test
- move the mcp_properties taxonomy mirror below every event_properties
  mutation and add a sync test so late additions can't silently miss it
- guard isMCPAnalyticsEventName against non-string entries, memoize
  getMCPPropertyFilterOptions, and correct the suggested-properties comment
  (the rebuild doesn't seed primary properties yet)

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
When the MCP properties tab is in a picker, the known $mcp_* schema is now
excluded from the Event properties group (server-side via the existing
excluded_properties mechanism), so each property renders in exactly one
place — mirroring how autocapture's element properties exist only in the
Elements group. Unknown $mcp_* keys a team ingests still surface under
Event properties, and pickers that don't request the MCP tab are untouched.

Applied to both picker variants via a shared helper, with parameterized
drift-guard tests on each side.

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
@pauldambra
pauldambra requested a review from a team July 9, 2026 16:04
@pauldambra
pauldambra marked this pull request as ready for review July 9, 2026 16:04
@github-actions
github-actions Bot requested a deployment to preview-pr-69575 July 9, 2026 16:05 In progress
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ✅ ready

▶ Open the preview

🔑 Login test@posthog.com / 12345678 (demo data)
🧩 Running this PR's backend and frontend, on the PostHog :master base
🔗 Link stable across rebuilds — a re-push swaps the box underneath, the URL stays
🔒 Access tailnet only (PostHog VPN)
💤 Idle sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen

commit 692b0c5 · box box-7d1ee664ad8e · ready in 517s (push → usable) · build log · rebuilds on every push, torn down on close

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 9, 2026 16:05
@pr-assigner-resolver-posthog

Copy link
Copy Markdown

👀 Auto-assigned reviewers

These soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:

  • @PostHog/team-mcp-analytics (products/mcp_analytics/**)

Soft owners come from CODEOWNERS-soft and each product's product.yaml. Generated files and lockfiles are ignored when deciding ownership.

…limit

Adding props.taxonomicGroupTypes as a 17th input to the taxonomicGroups
selector pushed it past kea's SelectorTuple type cap (max 16), so tsc failed
with TS2322 (tuple not assignable) and TS7006 (implicit any on the inline
props selector).

Fold the MCP-excluded event properties into the existing
eventNamesWithPrimaryProperties selector (already combined for this exact
reason) instead of adding a new input, keeping taxonomicGroups at 16 deps.

Generated-By: PostHog Code
Task-Id: be28193b-c899-48db-b149-f20d248054ef
@stamphog

stamphog Bot commented Jul 9, 2026

Copy link
Copy Markdown

Note

🤖 stamphog reviewed 43056bd030a4037fc0e48c9cf1fb706f574bfc10 — verdict: ESCALATE

All of the extensive "QA Swarm / paul-reviewer / xp-reviewer / security-audit" review rounds are posted under the PR author's own account (@pauldambra), not by any distinct bot or human reviewer — so despite the appearance of multi-perspective independent review, there is no genuine independent assurance here, and this PR also touches generated public API/query-schema surfaces across several products and the MCP service.

  • Author wrote 26% of the modified lines and has 390 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from chatgpt-codex-connector[bot], hex-security-app[bot].
  • Every 'review' round (4 rounds, dozens of findings, final 'approve with nits') is authored by the PR author @pauldambra themselves under a self-styled 'QA Swarm' multi-persona label — this is not independent assurance, it is the author grading their own work while presenting it as external review.
  • The PR changes frontend/src/queries/schema.json, posthog/schema_enums.py, and multiple generated api.schemas.ts/generated.ts files (including services/mcp), which are public API/query-schema contract surfaces — risky territory per policy, even though the change is additive.
  • Cross-team change (team-analytics-platform, team-mcp-analytics, team-product-analytics) with no genuine sign-off from any of the owning teams; author is only on team-mcp-analytics.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 584L, 22F substantive, 922L/30F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1d-complex (922L, 30F, cross-cutting, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ b5fc7df · reviewed head 43056bd

Updated in place — this replaces 2 earlier stamphog review(s) on this PR.

github-actions[bot]
github-actions Bot previously approved these changes Jul 9, 2026

@github-actions github-actions Bot left a comment

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.

Additive taxonomy/UI feature (new "MCP properties" picker tab) with no data model, migration, auth, billing, or CI changes; the generated schema/enum touches are just a new backwards-compatible enum literal. The prior automated review's three MEDIUM findings (duplicated priority list, cross-variant recents/telemetry drift, duplicate property listing) are all visibly fixed in the current diff and backed by new tests, and remaining LOW items are acknowledged hardening notes, not blockers.

  • Author wrote 60% of the modified lines and has 387 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from chatgpt-codex-connector[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 509L, 19F substantive, 792L/26F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1d-complex (792L, 26F, cross-cutting, feat)
stamphog 2.0.0b3 .stamphog/policy.yml @ 280e388 · reviewed head 44356e4

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm follow-up review of the delta since efd7bd5 (commits 56979d9, 5208ef9) — four independent perspectives. See inline comments and the summary comment.

Comment thread frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicFilter.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicGroupsContext.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicFilter.test.tsx Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts Outdated

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Follow-up review of the delta since efd7bd5 (56979d93 review fixes + 5208ef9b MCP-schema exclusivity): qa-team (8 personas), paul-reviewer, xp-reviewer, security-audit

Verdict: ⚠️ REQUEST CHANGES

The delta's product logic is sound — reviewers independently enumerated the scoped × requested × materialized matrix and found no reachable single-picker state that hides a known $mcp_* property from every group, the taxonomy mirror move was verified content-neutral, and the exclusion gate lines up exactly with when the MCP tab is visible. But one verified defect blocks: the new 17th taxonomicGroups selector dependency exceeds kea's 16-element SelectorTuple type, deterministically failing the frontend typecheck on the current head (jest passes only because babel strips types).

Key findings

  • 🟠 17th selector dep breaks the typecheck and skips the file's own objectsEqual stabilization convention (documented react-window error Paths don't follow users if they change distinct_id #185 precedent) — one stabilized combined-selector fix resolves both
  • 🟡 Recents remap resolves declared groups against the picker's visible tabs instead of all group definitions — the cross-variant divergence it targets stays alive on a reachable surface (activity-log hog-function filters)
  • 🟡 Rebuild's shared fetch cache doesn't key on excludedProperties, so the new tab-dependent exclusion lets same-endpoint pickers poison each other's cached page for 60s (flag-gated arm)
  • 🟡 Rebuild ctx memo gains an identity-unstable array dep — per-render group/Fuse rebuilds
  • 🟢/⚪ Test-isolation coupling in the new hook test (3 reviewers converged), stale pre-fix mcp_properties recents rows, undefined-props gate asymmetry, and three polish nits

Finding without a diff anchor

  • menu/TaxonomicFilterMenu.tsx (untouched by this PR): the delta fixes the recents write but the menu's direct taxonomic filter item selected telemetry still stamps sourceGroupType with the tab's own type — one selection now writes event_properties to recents while stamping mcp_properties on telemetry. The row-origin semantics are documented as intentional at the capture site; flagging the new internal inconsistency for a deliberate call.

Reviewer summaries

Reviewer Assessment
🔍 qa-team HIGH risk, REQUEST CHANGES — verified typecheck break + three convergent MEDIUMs; product logic itself sound
👤 paul "nothing blocking — happy for you to ship"; soft flags on module-load fragility and test coupling
📐 xp "solid, careful delta"; assert recents presence not exclusivity; memoization is mild premature optimization (optional)
🛡 security-audit 0 findings — excluded-properties param carries only repo constants; remap bounded to the picker's own groups; localStorage same-origin

Automated by QA Swarm — not a human review

- resolve the recents declared-group remap against allGroups, not the visible
  tabs, matching legacy getItemGroup for pickers that request a curated tab
  without its canonical group (reachable via the activity-log picker)
- key the rebuild's shared fetch cache on group-level excludedProperties /
  propertyAllowList, which are fetch-time params that now vary by picker
- content-key the groups-context memo dep so per-render array literals don't
  rebuild the context
- decouple the recents hook test from cross-test localStorage/timer state,
  exercise the curated-tab-only path, and pin a concrete key in the exclusion
  assertions
- soften the popover doc claim and note the undefined-group-types gate
  degrades toward benign duplication

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
@posthog

posthog Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm round-2 review of the fix delta (commits 44356e4, 1b11d4a, ca5eb24) — all LOW/NIT; the selector fold, recents refactor, cache keys, and eager const all verified sound. See inline comments and the summary comment.

Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicGroupsContext.ts Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/utils/mcpProperties.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useTaxonomicFilter.test.tsx Outdated

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Round-2 review of the fix delta (44356e4f selector fold, 1b11d4a3 review fixes, ca5eb24b simplify): qa-team (7 personas), paul-reviewer, xp-reviewer, security-audit

Verdict: 💬 APPROVE WITH NITS

Every area flagged for scrutiny verified sound: the eventNamesWithPrimaryProperties fold recomputes exactly when it must while objectsEqual restores the anti-churn stabilization the rejected 17-dep version bypassed; the nullish-chain recents refactor is behavior-identical for well-formed contexts and strictly safer for corrupted rows; the eager module const rests on a true premise (static taxonomy at import); and the new cache keys close a genuine cross-picker wrong-data bug with injective serialization. xp-reviewer and security-audit returned zero findings.

Remaining items (all LOW/NIT)

  • Stale cache-key-shape doc in frontend/src/models/cohortsModel.ts:123 (not touched by this PR): isCohortTaxonomicListKey documents the shared 'taxonomic-list' key as 9 elements; it now has 12. The predicate reads only positions 0-1, so it still works — but it's the only cross-module documentation of the key contract (flagged by 4 personas)
  • Sort-before-stringify the new cache-key entries; add a regression test pinning that different exclusions don't cross-serve; content-key input.eventNames like its sibling dep
  • Comment rescope (traffic-type analogy), unmount placement in the new test, optional IIFE hardening

Reviewer summaries

Reviewer Assessment
🔍 qa-team LOW — 7 hardening/doc items, none blocking; all four scrutiny areas verified sound
👤 paul "this delta is clean… ship as you see fit"; one consistency nit on array-comparison strategies
📐 xp zero findings — "manufacturing a nit would be exactly the crowding-out the wisdom doc warns against"
🛡 security-audit 0 findings — trust posture preserved (repo constants and caller picker config only)

Automated by QA Swarm — not a human review

- sort exclusion/allowlist sets before stringifying into the shared fetch
  cache key, and pin the keying with a regression test so dropping the
  entries can't silently cross-serve lists between pickers
- content-key eventNames in the groups-context memo like its sibling dep,
  with a note contrasting the legacy selector's stabilization strategy
- update the cohortsModel cache-key-shape doc to point at remoteKey instead
  of a stale positional enumeration
- rescope the exclusion comments to the mechanism precedent and move the
  recents test unmount into finally

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
@github-actions
github-actions Bot dismissed their stale review July 9, 2026 18:10

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Jul 9, 2026
…changes

- the invalidation predicate matched only the 'taxonomic-list' key family,
  so cohort create/rename/delete left cached 'taxonomic-list-search' results
  serving stale entries for the staleTime window on large-cohort-count teams;
  match both families and document them (flagged while reviewing the new
  exclusion-aware cache keys, which made the key contract load-bearing)
- state the backend set-semantics assumption the sorted cache keys lean on,
  and scope the dedupe claim to exclusions
- parameterize the cache-key regression test over both params and pin the
  order-independence the sort adds
- replace the stale cohort-invalidation TODO with the wired-up reality

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm round-3 review of the hardening commit 6f8b91f — one convergent MEDIUM (pre-existing cohort search-cache invalidation gap the new doc enshrined), the rest LOW/NIT refinements to the round-2 fixes. See inline comments and the summary comment.

Comment thread frontend/src/models/cohortsModel.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.test.tsx Outdated

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Round-3 review of the hardening commit 6f8b91fd: qa-team (6 personas), paul-reviewer, xp-reviewer (security and copy skipped — no surface in this delta)

Verdict: 💬 APPROVE WITH NITS

The commit's load-bearing changes all verified sound under adversarial review: the spread-copy sort is deterministic and non-mutating for everything that can flow in, the sorted-key/unsorted-URL merge cannot cross-serve wrong data against the current backends (set-conversion + fixed ORDER BY, verified server-side), three personas independently mutation-tested the regression test and confirmed it genuinely fails when the keying is dropped, and the eventNames content-keying changes no observable memo behavior.

Key findings

  • 🟡 (unanimous, 6/6) The rewritten cohortsModel cache-key doc enshrines an incomplete invariant: cohort search results also cache under the 'taxonomic-list-search' family that the invalidation predicate never matches — a pre-existing stale-search window after cohort mutations, now worth closing since the key contract became load-bearing
  • 🟢 State the backend set-semantics assumption the sorted keys lean on; scope the dedupe claim to exclusions; pin the allowlist key and the sort's order-independence in the regression test
  • ⚪ Not actioned, noted for a follow-up: the sibling memo in useTaxonomicFilter.ts still reference-keys the same props (render-perf only, no staleness or fetch churn); the eventNames content-keying is unpinned by any test (the dep line carries an explanatory comment)

Reviewer summaries

Reviewer Assessment
🔍 qa-team MEDIUM (driven by the unanimous cohort-invalidation doc/predicate finding); everything else LOW/NIT
👤 paul "reads like a solid round-2 cleanup and i'd stamp it"; one question on whether the test guards the sort it ships
📐 xp "close to a genuine 'this is fine'"; make the sort's intent executable rather than comment-only

Automated by QA Swarm — not a human review

- export the two key-family literals from useGroupList and consume them in
  the cohortsModel invalidation predicate, so a future key family can't
  silently escape invalidation the way the search family did
- collapse the cache-key test's two-stage wait into a single exact waitFor
  (fetches fire synchronously from effects, so the count is deterministic)

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285
…undone

- an undone delete restored the cohort without re-invalidating, so pickers
  kept serving the deleted-state cache for the staleTime window
- move the key-family constants next to the cache they describe
  (useTaxonomicResource), removing the models-to-hook edge
- assert the differing exclusion/allowlist params actually reach the request
  URL (coverage the parameterized rewrite had dropped) and correct the
  waitFor mechanism comment

Generated-By: PostHog Code
Task-Id: 25a24ca3-78e9-4c59-b439-c4181a705285

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm round-4 (final convergence) review of commits 492cc1a + e7bd767 — paul-reviewer and xp-reviewer returned zero findings; qa-team returned durability/test-hardening residue only. See inline comments and the summary comment.

Comment thread frontend/src/models/cohortsModel.ts
Comment thread frontend/src/models/cohortsModel.ts
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.test.tsx Outdated
Comment thread frontend/src/lib/components/TaxonomicFilter/hooks/useGroupList.ts

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Round-4 (final convergence) review of 492cc1a8 + e7bd767e: qa-team (5 personas), paul-reviewer, xp-reviewer

Verdict: 💬 APPROVE WITH NITS — quality loop converged

paul-reviewer and xp-reviewer returned zero findings ("ship it" / "this is fine — no smell survives"). qa-team verified the three scrutiny points sound — no module cycle or load-order hazard from the new import edge, the exact waitFor count is deterministic because the fetch chain fires synchronously inside act-flushed effects, and the widened predicate cannot over-invalidate beyond cohort entries — and returned five durability items, of which four were fixed in 43056bd0:

  • restored the params-reach-the-URL assertion the parameterized test had dropped
  • moved the key-family constants to useTaxonomicResource.ts (the cache module that owns key hashing and invalidation)
  • corrected the waitFor mechanism comment
  • closed the pre-existing undo-restore invalidation gap the round-3 comment had overclaimed away

Not actioned (deliberate): the family-registry suggestion — the enumeration is now type-checked through shared constants, both families are documented at the predicate, and a registry for exactly two values contradicts the same round's xp verdict ("no superfluous parts"); revisit if a third key family ever appears.

Reviewer summaries

Reviewer Assessment
🔍 qa-team LOW — production change correct; residue items actioned same round
👤 paul "ship it… no questions worth blocking on"
📐 xp "this is fine — the change improves all four rules at once without over-reaching"

Automated by QA Swarm — not a human review

@pauldambra pauldambra added the stamphog Request AI approval (no full review) label Jul 9, 2026 — with PostHog
@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Jul 9, 2026

@gesh gesh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Amazing!! 🔥

4 updated
Run: 0258c250-bf34-4bf1-88a8-2298019523f2

Co-authored-by: pauldambra <984817+pauldambra@users.noreply.github.com>
@pauldambra
pauldambra merged commit 19d248a into master Jul 10, 2026
246 checks passed
@pauldambra
pauldambra deleted the posthog-code/mcp-properties-taxonomic-filter branch July 10, 2026 19:40
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-10 20:18 UTC Run
prod-us ✅ Deployed 2026-07-10 20:28 UTC Run
prod-eu ✅ Deployed 2026-07-10 20:28 UTC Run

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.

2 participants