Skip to content

feat(signals): add anomaly investigation to inbox source config UI - #71533

Merged
oliverb123 merged 1 commit into
masterfrom
posthog-code/inbox-anomaly-investigation-source
Jul 16, 2026
Merged

feat(signals): add anomaly investigation to inbox source config UI#71533
oliverb123 merged 1 commit into
masterfrom
posthog-code/inbox-anomaly-investigation-source

Conversation

@oliverb123

@oliverb123 oliverb123 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Problem

Anomaly investigations run and emit signals with source_product = analytics / source_type = anomaly_investigation, but there was no way to configure that source: no SignalSourceConfig row could be created from the product because the Inbox source-config UI had no entry for it. So the signals never flowed into the inbox even when investigations happened.

Changes

  • Add a "PostHog Product Analytics" toggle to the Inbox source config UI (SourcesList.tsx), wired through signalSourcesLogic exactly like the existing health-checks source (action, optimistic reducer, config + toggling selectors, and a listener that creates/updates the SignalSourceConfig row).
  • Add analytics as a filterable source in the report list source dropdown (filterOptions.tsx).

No backend changes: the model choice, enum, migration (0062_add_analytics_anomaly_investigation_source), and generated frontend types already accept this source — the only gap was the UI.

How did you test this code?

Ran pnpm --filter=@posthog/frontend format (oxfmt left all three changed files untouched — already conformant) and typescript:check: no errors reference the changed files or the new symbols (toggleAnomalyInvestigation, anomalyInvestigationConfig, isAnomalyInvestigationToggling). kea typegen for signalSourcesLogic regenerates cleanly with the new action/selectors. No automated tests were added — this follows the established per-source toggle pattern, which has no unit coverage today. Not manually exercised in a running app.

Automatic notifications

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

Docs update

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Authored by the PostHog Slack app after a thread noticed an anomaly investigation had run but produced no inbox signals, because the SignalSourceConfig for it could not be created from the UI. Skills invoked: /signals and /inbox-exploration (to confirm no analytics/anomaly_investigation source config existed for the project and that signals were otherwise flowing). Used the Explore agent to map the source-config UI, then mirrored the health-checks source pattern across signalSourcesLogic.ts, SourcesList.tsx, and filterOptions.tsx. Chose the health-checks pattern over the session-replay one because anomaly investigation is a plain single (source_product, source_type) on/off toggle with no extra config.


Created with PostHog from a Slack thread

Adds a toggle for the Product Analytics anomaly investigation signal
source (source_product `analytics`, source_type `anomaly_investigation`)
to the Inbox source config UI, and lists it as a filterable source in
the report list. The backend model, enum, migration, and generated types
already accept this source; there was just no way to enable it from the
UI. Mirrors the existing health-checks source wiring.

Generated-By: PostHog Code
Task-Id: 5e9f9ae6-e664-4e61-be04-edcd46d519d7
@Radu-Raicea
Radu-Raicea marked this pull request as ready for review July 16, 2026 13:07
@github-actions

Copy link
Copy Markdown
Contributor

Hey @oliverb123! 👋

It looks like your git author email on this PR isn't your @posthog.com address (oliverbrowne627@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 16, 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)
🛠️ Admin inspect & debug state in hogland
💤 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 adec2dc · box box-c051a2ea4773 · ready in 803s (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 16, 2026 13:07
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(signals): add anomaly investigation..." | Re-trigger Greptile

Comment on lines +592 to +596
actions.toggleSignalSource({
sourceProduct: SignalSourceProduct.Analytics,
sourceType: SignalSourceType.AnomalyInvestigation,
enabled: desiredEnabled,
})

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.

P1 Rapid Disable Skips Persistence

When a user toggles this new source on and then off before the create request finishes, the second action sees the optimistic new_ config with enabled: false. toggleSignalSource does not update or create anything for that state, so the first request can still persist the source as enabled and the requested disable is lost.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not reachable through the UI, so resolving without a change here.

The toggle passes loading={isAnomalyInvestigationToggling}, and LemonButton sets disabled = true whenever loading is set and swallows clicks while disabled (LemonButton.tsx:207 + the onClick guard at :266). That flag flips synchronously: the toggleAnomalyInvestigation listener dispatches toggleSignalSource before it awaits anything, and toggleSignalSource is the action that adds the key to togglingSourceKeys. So the button is already disabled by the time React repaints after the first click, and stays disabled until the create resolves (loadSourceConfigs then refetches truth) — the user can't fire the second toggle mid-flight.

Two caveats:

  • The guard is purely the in-flight loading state. If the actions were dispatched programmatically (bypassing the button), the new_-config + enabled:false no-op you describe is real.
  • This is pre-existing and pattern-wide — health checks, conversations, eval reports, and session analysis all share this exact wiring. This PR doesn't introduce it.

If we want to harden against the programmatic/edge case, the right place is the shared toggleSignalSource listener (once, for all sources) rather than this per-source handler — happy to take that as a follow-up.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Bundle size — 🔺 +603 B (+0.0%)

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

Total: 64.81 MiB · 🔺 +603 B (+0.0%)

No file changed by more than 1000 B.

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.22 MiB · 22 files no change ███░░░░░░░ 28.4% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.14 MiB · 2,981 files no change █████████░ 87.9% 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
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.3 KiB ../node_modules/.pnpm/posthog-js@1.402.3/node_modules/posthog-js/dist/rrweb.js
267.7 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
235.5 KiB src/taxonomy/core-filter-definitions-by-group.json
222.9 KiB ../node_modules/.pnpm/posthog-js@1.402.3/node_modules/posthog-js/dist/module.js
164.0 KiB src/queries/validators.js
154.3 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.8 KiB src/lib/api.ts
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
92.7 KiB ../packages/quill/packages/quill/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 — 🔺 +2.7 KiB (+0.0%)

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

Total: 1315.45 MiB · 🔺 +2.7 KiB (+0.0%)

Playwright — all passed

All tests passed.

View test results →

@trunk-io

trunk-io Bot commented Jul 16, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@oliverb123
oliverb123 merged commit 1673582 into master Jul 16, 2026
299 of 345 checks passed
@oliverb123
oliverb123 deleted the posthog-code/inbox-anomaly-investigation-source branch July 16, 2026 13:52
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-16 14:34 UTC Run
prod-us ✅ Deployed 2026-07-16 14:57 UTC Run
prod-eu ✅ Deployed 2026-07-16 14:57 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