fix(ai): document that lifecycle insights exclude anonymous users - #71883
Merged
Conversation
Lifecycle queries filter out events with $process_person_profile set to false, so lifecycle user counts are expected to be far lower than unique-user trends in projects with anonymous traffic. Teach Max's lifecycle results prompt and the MCP query-lifecycle tool description about this, remove a stale duplicate LIFECYCLE_EXAMPLE_PROMPT definition that shadowed the current one, and add a why-comment on the filter in the query runner. Generated-By: PostHog Code Task-Id: ce969ba9-98ef-43ab-88d8-7e92760ead2a
darkopia
marked this pull request as ready for review
July 17, 2026 11:49
👀 Auto-assigned reviewersThese soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:
Soft owners come from each directory's |
Scope the person-profile exclusion note to event and action series (data warehouse lifecycle series skip the filter), replace the categorical "by design, not a bug" phrasing with guidance to verify the gap via a trends-query filter before dismissing it, correct the "new" status definition to person-profile-creation semantics, and add the anonymous-user exclusion caveat to the query-lifecycle-actors tool description so actor drill-downs are covered too. Generated-By: PostHog Code Task-Id: ce969ba9-98ef-43ab-88d8-7e92760ead2a
skoob13
approved these changes
Jul 17, 2026
Contributor
🤖 CI report |
…cle-ai-anonymous-users
Generated-By: PostHog Code Task-Id: 648e45e9-5a88-44e8-8e78-aaafaad080cd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Lifecycle insights exclude anonymous (personless) users by design: the query runner filters out every event with
$process_person_profile: false, which is what anonymous visitors send under posthog-js's defaultperson_profiles: 'identified_only'. Trends unique-user counts include those visitors. So in projects with mostly anonymous traffic, lifecycle totals are expected to be a small fraction of the unique-user trend for the same event.Our AI surfaces didn't know this. In a recent support conversation, a user asked why their lifecycle insight showed a tiny fraction of the users their unique-user trend showed, and the AI speculated about bugs and data issues instead of giving the real answer. The knowledge exists only as an uncommented filter in the query runner, so nothing that reads lifecycle results for the AI can explain the gap.
Changes
ee/hogai/context/insight/prompts.py:LIFECYCLE_EXAMPLE_PROMPT(the prompt Max receives whenever it reads lifecycle query results) now explains the anonymous-user exclusion, states that lower-than-trends counts are by design, and says how to compare like-for-like (filter trends to$process_person_profile != false). Also removed a stale duplicate definition of the same constant lower in the file. Python keeps the last definition, so the stale one (old lowercase headers, no multi-series format) was shadowing the maintained one that matches the actual formatter output inee/hogai/context/insight/format/lifecycle.py.services/mcp/definitions/prompts/query-lifecycle.md: new "Anonymous users are excluded" section plus a reminder bullet, so every MCP agent planning aquery-lifecyclecall gets the same knowledge.posthog/hogql_queries/insights/lifecycle/lifecycle_query_runner.py: a short why-comment on the previously unexplained$process_person_profilefilter.Note
The MCP description is baked into
services/mcp/schema/generated-tool-definitions.json. I couldn't regenerate it locally (codegen needs a database to export the OpenAPI schema), so thecheck-openapi-typesCI job will auto-commit the regenerated definitions onto this branch.How did you test this code?
ruff checkandruff format --checkpass on the changed Python files.ee/hogai/context/insight/prompts.pyand asserted the module parses with exactly oneLIFECYCLE_EXAMPLE_PROMPTcontaining the new exclusion text and the multi-series table format.ee/hogai/context/insight/test/test_query_executor.py) assertsget_example_prompt(LifecycleQuery(...))returns the imported constant, so it is unaffected.Automatic notifications
Docs update
No
docs/page in this repo covers lifecycle insights, and the public website docs already explain anonymous vs identified events. This PR only teaches the AI surfaces and annotates the code.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Authored in a PostHog Code (Claude) session investigating a support conversation about a lifecycle-vs-trends unique users gap. I (Claude) verified the exclusion in
lifecycle_query_runner.py, traced which prompt Max actually receives viaquery_executor.get_example_prompt, and found the duplicateLIFECYCLE_EXAMPLE_PROMPTshadowing the maintained definition along the way. Skill invoked:/implementing-mcp-tools(for thedescription_fileand codegen workflow). Decision: place the knowledge at both points where an AI reasons about lifecycle, when reading results (Max) and when planning queries (MCP), rather than only one of them.Created with PostHog Code