Skip to content

feat(workflows): show the managed sandbox sender in channels - #127153

Closed
Silthus wants to merge 16 commits into
workflows-sandbox-product/sender-rowfrom
workflows-sandbox-product/channels-row
Closed

Silthus wants to merge 16 commits into
workflows-sandbox-product/sender-rowfrom
workflows-sandbox-product/channels-row

Conversation

@Silthus

@Silthus Silthus commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • A team in the sandbox sender trial needs to see that PostHog gives it a sender, and that the sender reaches only its organization's verified members.
  • The PR below creates the managed sender through the API only. Nothing provisions it for a team or shows it.

Warning

🟡 Merge risk: medium · two-way door (merge-risk rubric)

  • integrationsLogic is shared by every integrations surface. Its lists now read a userManagedIntegrations selector that drops the sandbox row, and its load-failure state moved into it.
  • Limited by: provisioning and the row run only with workflows-sandbox-sender. Without a sandbox row the new selectors return the same list as before.
  • Revert: turn off workflows-sandbox-sender, or git revert the merge commit.

Changes

  • A flagged project that opens Workflows › Channels gets its sandbox sender, then sees a "Sandbox sender" row below the channel grid.
  • The row shows the sender name and address, says it delivers only to verified members of the organization, and offers "Add your own sender".
  • When provisioning fails, Channels shows the error with "Try again". A failed refresh after a first load keeps the grid and shows "Couldn't refresh your channels".
  • The setup guide and the onboarding wizard no longer count the sandbox row as a connected email channel or a verified domain.
  • The own-sender lists leave the sandbox row out.
  • Channels logic calls the idempotent endpoint once per visit, and again when the flag arrives late. It drops a response from an earlier visit.
  • Mechanical: the flag constant and a story.
Flag on Flag off
Channels with the sandbox sender flag on Channels with the sandbox sender flag off

Stack

  1. feat(workflows): restrict sandbox email to verified org members #127149 member gate
  2. feat(workflows): route sandbox email through its fixed ses identity #127150 sandbox route
  3. feat(workflows): cap sandbox sends per project and recipient each day #127151 daily caps
  4. feat(workflows): provision a managed sandbox email sender #127152 sender row
  5. feat(workflows): show the managed sandbox sender in channels #127153 Channels row ← this PR

How did you test this code?

  • Live run at this head (8c56ec9cccb) on a box dev stack through the public API: provisioning twice returns one sender row and the project lists one sandbox row; a verified member gets the email through the sandbox SES tenant, configuration set and From address, with the footer closing the HTML; outside@example.com is skipped with the member message; the third send to one address in a day is skipped by the recipient cap; with the worker switch off the member send skips as unavailable. A stalled blocked-event store holds no send. Stubs: a local SES endpoint that records each request, a DNS preload that answers an MX record for example.com, workflows-sandbox-sender answered true, PersonHog off (nothing on the send path reads persons).
  • UI walk (Django and Vite on the box, invented data): with the flag on, Channels provisions the sender and shows the Sandbox sender row; with it off, Channels shows no row and does not provision. Screenshots above.
  • Prod shape: no production team has a sandbox sender, so with the flag off every team sees the same connections list as before.
  • CI: Check the PR does not mix lanes is expected to stay red until the Node layers below (feat(workflows): restrict sandbox email to verified org members #127149 to feat(workflows): cap sandbox sends per project and recipient each day #127151) land on master: this layer's diff to master still carries their Node changes. [Optional] deploy preview is not part of this stack's checks.
  • CI report: the duplication and bundle-size warnings name master code outside this stack, such as products/warehouse_sources/ and the dashboards widgets. The three complexity warnings name functions that were over the limit before this stack, and this layer's edits sit outside them.
  • Review: GPT-6.1 Sol reviewed the PR and the fixes in several final reads; each finding is fixed in a commit on this stack, and the posthog[bot] threads are answered.

Test rationale:

  • channelCatalogLogic.test.ts: provisioning runs once at mount or when the flag arrives late, exposes a 404 or 500 for retry, and keeps a list failure apart from a sandbox failure. A remount test catches an old error from an earlier visit.
  • integrationsLogic.test.ts: the own-sender lists drop the sandbox row with the flag on or off.
  • workflowsOnboardingWizardLogic.test.ts: with only the sandbox sender, the guide and wizard leave the channel and domain steps open.

Release status

  • This change is behind a feature flag and is not available to users

Docs update

  • None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5). Review by GPT-6.1 Sol.

Skills: /recreating-fork-prs, /stacking-prs, /writing-pr-descriptions, tdd, merge-risk, qa-swarm

More context for AI agents
  • Session: squashed from feat(workflows): show the managed sandbox sender in channels Silthus/posthog#602 at 5f28a0eab63 onto the sender row layer. The tree equals that fork head merged into master bf976a762be.
  • Decisions: one loader in Channels logic provisions the sender against the idempotent endpoint; integrationsLogic only derives lists.
  • Decisions: a project switch while provisioning needs no handling, because switching projects reloads the page.
  • Decisions: the loader drops a late provisioning response with breakpoint().
  • Follow-ups: the email-step option and the before-you-send copy follow in later PRs.
  • Read closely: channelCatalogLogic.ts and the selectors in integrationsLogic.ts.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Silthus Silthus added hogbox-preview Spin up a per-PR PostHog preview on a hogland hogbox posthog-review labels Nov 2, 2026
@Silthus Silthus self-assigned this Nov 2, 2026
@Silthus
Silthus added this pull request to stack #127154 November 2, 2026 07:31
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Trunk lane — backend Python lane, mixes lanes

This PR is assigned to the backend Python lane. It runs backend Python tests and may merge in parallel with PRs in other lanes.

This PR changes Python or frontend code (frontend/snapshots.yml, frontend/src/lib/constants.tsx, frontend/src/lib/integrations/IntegrationsList.tsx and 46 more) and Node or Rust code (nodejs/package.json, nodejs/src/cdp/cdp-services.ts, nodejs/src/cdp/config.ts and 15 more) together. In the merge queue, every Node or Rust PR behind it in the same lane then runs the Django and frontend suites too, so the cross-lane check fails. Split it, or add the cross-lane-change label if the halves must land together.

⚠️ Complexity (TypeScript) — 3 functions above the limit (max 27)

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

Function Location Complexity Limit
handleOauthCallback frontend/src/lib/integrations/integrationsLogic.ts:1277 27 10
<anonymous> products/workflows/frontend/setupGuide/wizard/workflowsOnboardingWizardLogic.ts:628 14 10
openFromUrl products/workflows/frontend/setupGuide/wizard/workflowsOnboardingWizardLogic.ts:671 13 10
⚠️ Duplication (Python) — 25 new duplicated blocks (worst 212 tokens)

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

First copy Second copy Lines Tokens
products/warehouse_sources/backend/temporal/data_imports/sources/mercury/mercury.py:1 products/warehouse_sources/backend/temporal/data_imports/sources/productboard/productboard.py:1 39 212
products/warehouse_sources/backend/temporal/data_imports/sources/emailoctopus/source.py:1 products/warehouse_sources/backend/temporal/data_imports/sources/lovable/source.py:1 24 181
products/warehouse_sources/backend/temporal/data_imports/sources/emailoctopus/source.py:1 products/warehouse_sources/backend/temporal/data_imports/sources/profound/source.py:1 24 181
products/product_analytics/backend/hogql_queries/lifecycle/test/test_lifecycle_data_warehouse.py:231 products/product_analytics/backend/hogql_queries/lifecycle/test/test_lifecycle_data_warehouse.py:448 19 175
products/warehouse_sources/backend/temporal/data_imports/sources/qdrant/qdrant.py:11 products/warehouse_sources/backend/temporal/data_imports/sources/slash/slash.py:8 19 170
products/warehouse_sources/backend/temporal/data_imports/sources/chargebee/chargebee.py:2 products/warehouse_sources/backend/temporal/data_imports/sources/reply_io/reply_io.py:1 30 161
products/warehouse_sources/backend/temporal/data_imports/sources/qdrant/qdrant.py:14 products/warehouse_sources/backend/temporal/data_imports/sources/semaphore/semaphore.py:13 14 125
products/warehouse_sources/backend/temporal/data_imports/sources/helicone/helicone.py:1 products/warehouse_sources/backend/temporal/data_imports/sources/plaid/plaid.py:2 16 112
products/warehouse_sources/backend/temporal/data_imports/sources/new_york_times/new_york_times.py:9 products/warehouse_sources/backend/temporal/data_imports/sources/printify/printify.py:6 14 109
products/batch_exports/backend/temporal/destinations/postgres_batch_export.py:45 products/batch_exports/backend/temporal/destinations/snowflake_batch_export.py:39 16 108
products/warehouse_sources/backend/temporal/data_imports/sources/lightfield/lightfield.py:8 products/warehouse_sources/backend/temporal/data_imports/sources/raygun/raygun.py:12 12 105
products/warehouse_sources/backend/temporal/data_imports/sources/rippling/rippling.py:201 products/warehouse_sources/backend/temporal/data_imports/sources/simplesat/simplesat.py:117 22 101
products/warehouse_sources/backend/temporal/data_imports/sources/rippling/rippling.py:201 products/warehouse_sources/backend/temporal/data_imports/sources/zendesk_sell/zendesk_sell.py:158 22 101
products/warehouse_sources/backend/temporal/data_imports/sources/gologin/gologin.py:20 products/warehouse_sources/backend/temporal/data_imports/sources/qdrant/qdrant.py:18 11 99
products/warehouse_sources/backend/temporal/data_imports/sources/rippling/rippling.py:201 products/warehouse_sources/backend/temporal/data_imports/sources/tempo/tempo.py:168 22 99
products/warehouse_sources/backend/temporal/data_imports/sources/cloudbeds/cloudbeds.py:19 products/warehouse_sources/backend/temporal/data_imports/sources/litellm/litellm.py:16 20 93
products/warehouse_sources/backend/temporal/data_imports/sources/attio/attio.py:8 products/warehouse_sources/backend/temporal/data_imports/sources/moengage/moengage.py:12 11 86
products/warehouse_sources/backend/temporal/data_imports/sources/revolut_merchant/revolut_merchant.py:17 products/warehouse_sources/backend/temporal/data_imports/sources/semgrep/semgrep.py:10 12 85
products/warehouse_sources/backend/temporal/data_imports/sources/autumn/source.py:102 products/warehouse_sources/backend/temporal/data_imports/sources/teachable/source.py:103 18 83
products/warehouse_sources/backend/temporal/data_imports/sources/rapid7_insightvm/rapid7_insightvm.py:1 products/warehouse_sources/backend/temporal/data_imports/sources/sonar_cloud/sonar_cloud.py:1 13 78
products/product_tours/backend/llm/client.py:18 products/surveys/backend/llm/client.py:29 20 76
ee/hogai/llm.py:393 ee/hogai/llm.py:470 12 72
products/warehouse_sources/backend/temporal/data_imports/sources/bamboohr/source.py:97 products/warehouse_sources/backend/temporal/data_imports/sources/raygun/source.py:130 14 71
products/warehouse_sources/backend/temporal/data_imports/sources/cloudbeds/cloudbeds.py:13 products/warehouse_sources/backend/temporal/data_imports/sources/plunk/plunk.py:27 11 71
products/warehouse_sources/backend/temporal/data_imports/sources/oncehub/oncehub.py:163 products/warehouse_sources/backend/temporal/data_imports/sources/reply_io/reply_io.py:143 11 71
⚠️ Duplication (TypeScript) — 16 new duplicated blocks (worst 2203 tokens)

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

First copy Second copy Lines Tokens
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.ts:583 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.ts:516 292 2203
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.ts:261 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.ts:262 214 1176
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.test.ts:350 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.test.ts:287 152 1047
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.test.ts:9 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.test.ts:8 130 708
frontend/src/lib/oauthScopes.generated.ts:12 services/mcp/src/lib/oauth-scopes.generated.ts:12 255 525
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.test.ts:186 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.test.ts:134 73 342
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.test.ts:309 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.test.ts:246 29 259
nodejs/src/ingestion/pipelines/sessionreplay/ai-research/image-fetch-v4/configuration-policy.ts:551 nodejs/src/ingestion/pipelines/sessionreplay/ml-mirror-image-fetch/configuration-policy.ts:484 30 232
products/workflows/frontend/Workflows/hogflows/panel/testing/HogFlowEditorNotificationPanelTest.tsx:356 products/workflows/frontend/Workflows/hogflows/panel/testing/HogFlowEditorPanelTest.tsx:145 26 151
products/product_analytics/frontend/insights/funnels/funnelDataLogic.ts:316 products/product_analytics/frontend/insights/funnels/funnelDataLogic.ts:548 23 121
frontend/src/lib/integrations/integrationsLogic.ts:721 frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:214 51 112
frontend/src/scenes/dashboard/dashboardTemplateEntities.ts:252 frontend/src/scenes/hog-functions/filters/cdpFilterSeries.ts:97 14 89
products/dashboards/frontend/widgets/experiments/editExperimentResultsWidgetModalLogic.ts:134 products/dashboards/frontend/widgets/metrics/editMetricsWidgetModalLogic.ts:116 19 79
frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts:72 frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts:101 15 74
products/data_warehouse/frontend/scenes/SourceScene/tabs/sourceSettingsLogic.ts:1508 products/data_warehouse/frontend/scenes/SourceScene/tabs/sourceSettingsLogic.ts:1535 11 73
frontend/src/scenes/insights/insightLogic.tsx:232 frontend/src/scenes/insights/insightLogic.tsx:410 13 71
⚠️ Bundle size — 🔺 +131.9 KiB (+0.2%)

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

Total: 76.21 MiB · 🔺 +131.9 KiB (+0.2%)

File Size Δ vs base
render-query/src/render-query/render-query.js 21.31 MiB 🔺 +28.6 KiB (+0.1%)
posthog-app/_parent/products/dashboards/frontend/widgets/metrics/EditMetricsWidgetModal.js 14.8 KiB 🔺 +14.8 KiB (new)
exporter/_parent/products/dashboards/frontend/widgets/metrics/EditMetricsWidgetModal.js 11.3 KiB 🔺 +11.3 KiB (new)
posthog-app/_parent/products/signals/frontend/inbox/InboxScene.js 504.8 KiB 🔺 +7.3 KiB (+1.5%)
posthog-app/_parent/products/subscriptions/frontend/components/Subscriptions/exportNudge/ExportNudgeToast.js 3.7 KiB 🔺 +3.7 KiB (new)
posthog-app/_parent/products/workflows/frontend/Workflows/WorkflowScene.js 127.7 KiB 🔺 +3.0 KiB (+2.4%)
posthog-app/_parent/products/conversations/frontend/scenes/ticket/SupportTicketScene.js 79.8 KiB 🔺 +3.0 KiB (+3.9%)
posthog-app/_parent/products/dashboards/frontend/widgets/metrics/MetricsWidget.js 3.0 KiB 🔺 +3.0 KiB (new)
posthog-app/_parent/products/subscriptions/frontend/components/Subscriptions/exportNudge/exportNudgeLogic.js 2.9 KiB 🔺 +2.9 KiB (new)
posthog-app/src/scenes/bootApp.js 14.3 KiB 🔺 +2.7 KiB (+23.6%)
exporter/src/exporter/exporter.js 36.5 KiB 🔺 +2.6 KiB (+7.7%)
exporter/_parent/products/subscriptions/frontend/components/Subscriptions/exportNudge/ExportNudgeToast.js 2.5 KiB 🔺 +2.5 KiB (new)
exporter/_parent/products/dashboards/frontend/widgets/metrics/MetricsWidget.js 2.2 KiB 🔺 +2.2 KiB (new)
posthog-app/src/scenes/billing/paymentEntryLogic.js 1.7 KiB 🔺 +1.7 KiB (new)
exporter/_parent/products/subscriptions/frontend/components/Subscriptions/exportNudge/exportNudgeLogic.js 1.7 KiB 🔺 +1.7 KiB (new)
posthog-app/_parent/products/replay_vision/frontend/replay_scanners/ReplayScannersScene.js 99.3 KiB 🔺 +1.6 KiB (+1.7%)
exporter/_parent/products/dashboards/frontend/widgets/AddWidgetModal.js 31.4 KiB 🔺 +1.5 KiB (+5.0%)
posthog-app/src/scenes/insights/utils/api.js 1.5 KiB 🔺 +1.5 KiB (new)
posthog-app/_parent/products/dashboards/frontend/widgets/AddWidgetModal.js 38.1 KiB 🔺 +1.0 KiB (+2.8%)
exporter/src/scenes/billing/paymentEntryLogic.js 1.0 KiB 🔺 +1.0 KiB (new)

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.01 MiB · 25 files 🔺 +211 B (+0.0%) █████████░ 88.1% of 1.14 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
2.98 MiB · 626 files 🔺 +448 B (+0.0%) ██████████ 98.4% of 3.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
4.00 MiB · 1,275 files 🟢 -66.1 KiB (-1.6%) ██████████ 99.7% of 4.01 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.46 MiB · 3,718 files 🟢 -201.5 KiB (-2.0%) ██████████ 96.2% of 9.84 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
4.92 MiB · 1,794 files 🟢 -53.3 KiB (-1.0%) ██████████ 99.8% of 4.93 MiB
AI-first home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
6.18 MiB · 2,289 files 🟢 -209.0 KiB (-3.2%) ██████████ 98.6% of 6.27 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
8.87 MiB · 3,440 files 🟢 -222.4 KiB (-2.4%) █████████░ 94.2% of 9.41 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
9.66 MiB · 3,717 files 🟢 -392.3 KiB (-3.8%) █████████░ 92.1% of 10.49 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
7.38 MiB · 2,678 files 🟢 -355.9 KiB (-4.5%) █████████░ 90.8% of 8.13 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 products/product_analytics/frontend/insights/activityDescriptions stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/logic/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/kea-test-utils/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/product_analytics/frontend/insights/activityDescriptions stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/panel-layout/ProjectTree/menus/SessionReplayMenuItems.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/navigation/projectNoticeLogic.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/navigation/ImpersonationNotice/ImpersonationNotice.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/cohorts/cohortSavedToast.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/wizard/frontend/runs/WizardRunDetailsDrawer.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayShell.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayContextPanelFloating.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodaySidePanel.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/TodayTopBar.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/layout/today/todayRailItems.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/subscriptions/frontend/components/Subscriptions/exportNudge/exportNudgeLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/billing/paymentEntryLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/re2js/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/react-markdown/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/Command/Command.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 packages/quill/packages/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/web-analytics-validators.js stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/re2js/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 packages/quill/packages/charts/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/VisualizationWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/components/tool/widgets/RecordingsWidget.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 products/posthog_ai/frontend/api/primitives.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/notebooks/Notebook/notebookLogic.ts stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/web-analytics-validators.js stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/re2js/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/LiveMetricsDashboard/LiveWebAnalyticsMetrics.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 products/product_analytics/frontend/insights/trends/WorldMap/countryVectors.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/queries/validators.js stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/re2js/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/scenes/settings/SettingsMap.tsx stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 @jspm/core/nodelibs/browser/fs stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/re2js/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/kea-test-utils/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/d3/src/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.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.7 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
4.0 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.9 KiB src/lib/utils/bootTiming.ts
1.7 KiB src/index.tsx
1.7 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.2 KiB src/RootErrorBoundary.tsx
949 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.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
103.9 KiB src/products.tsx
89.0 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
28.4 KiB src/lib/constants.tsx
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.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
103.9 KiB src/products.tsx
89.0 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
32.7 KiB src/lib/utils/eventUsageLogic.ts
28.6 KiB ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.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
103.9 KiB src/products.tsx
94.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.6 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
89.0 KiB src/lib/api.ts
84.9 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.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
103.9 KiB src/products.tsx
89.0 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
36.4 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.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
103.9 KiB src/products.tsx
89.0 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
68.0 KiB ../products/posthog_ai/frontend/logics/runStreamLogic.ts
41.9 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.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
103.9 KiB src/products.tsx
94.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.6 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
89.0 KiB src/lib/api.ts
76.6 KiB src/scenes/dashboard/dashboardLogic.tsx
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
144.1 KiB ../packages/quill/packages/primitives/dist/index.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
103.9 KiB src/products.tsx
94.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.6 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
89.0 KiB src/lib/api.ts
84.9 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
325.3 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
320.2 KiB ../node_modules/.pnpm/posthog-js@1.444.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
239.9 KiB ../packages/quill/packages/quill/dist/index.js
224.1 KiB ../node_modules/.pnpm/@posthog+icons@0.39.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.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
103.9 KiB src/products.tsx
94.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
92.6 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
89.0 KiB src/lib/api.ts
68.7 KiB src/lib/lemon-ui/icons/icons.tsx

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

✅ Frontend layers — no new upward imports, 4 removed

Static imports from a lower frontend layer into a higher one (layers, lowest first: kernel, shell, query, features). Compared with the base branch, so an import that a PR also adds to layer-baseline.txt still shows here. Sizes are the source bytes on the eager path of every logged-in page.

Layer Eager source bytes Δ vs base
kernel 2.96 MiB 🟢 -126.7 KiB (-4.0%)
shell 2.38 MiB 🟢 -8.0 KiB (-0.3%)
query 56.4 KiB no change
features 534.0 KiB 🟢 -165.3 KiB (-23.6%)

🟢 4 upward import(s) removed. Run hogli lint:frontend-layers --prune-baseline if CI asks.

Download the interactive layer graph for this PR.

Posted automatically by check-layers

✅ Toolbar bundle — eager 2.34 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.34 MiB · 19 files 🔺 +743 B (+0.0%) ████░░░░░░ 40.9% of 5.72 MiB
Deferred (lazy) 2.11 MiB · 42 files no change n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
945.0 KiB dist/toolbar/toolbar-app-RYR6KXND.css
696.4 KiB dist/toolbar/chunk-chunk-VIVNIAQV.js
261.2 KiB dist/toolbar/chunk-chunk-34KH2ZPV.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
130.3 KiB dist/toolbar/chunk-chunk-X5WTS7B2.js
75.7 KiB dist/toolbar/toolbar-app-DNII2O23.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
33.8 KiB dist/toolbar/chunk-chunk-NINMNU45.js
21.7 KiB dist/toolbar/chunk-chunk-J2IGNP2I.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +1.67 MiB (+0.2%)

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

Total: 970.35 MiB · 🔺 +1.67 MiB (+0.2%)

⚠️ Playwright — 2 flaky

🎭 Playwright report · View test results →

⚠️ 2 flaky tests:

  • Shows validation error if passwords do not match (chromium)
  • Save view (chromium)

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

ℹ️ Hogbox preview — building

Spinning up PostHog for this PR on a hogland hogbox. This section updates in place when it's ready (usually a few minutes).

commit 46cbb65 · build log

Silthus and others added 2 commits November 2, 2026 09:02
CI regenerates the kea types, and an untyped loader payload made the
setUpSandboxSender action require an argument that its callers never pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s-row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Silthus and others added 3 commits November 2, 2026 11:58
…g and capture cap into channels-row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…channels-row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…channels-row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hogbox-preview Spin up a per-PR PostHog preview on a hogland hogbox

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant