Repository navigation
feat(workflows): choose the sandbox sender in email steps - #131916
Conversation
Add the email_sandbox integration kind with credentials as its only auth type, and the two tables the sandbox sender reads: a mirror of the shared SES tenant's sending status and a staff-set organization block. Nothing reads them yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the email_sandbox step type and its server-side contract: an allowlisted config that cannot name a sender or delivery settings, an adoption flag for new steps with stored steps grandfathered, and a refusal in broadcasts, other products' workflows and templates. Adds the project's sandbox sender endpoints (status and provision), the minute poll that mirrors the sandbox SES tenant status, a staff admin for organization blocks, and the activation exclusion for workflows whose only messages go through the sandbox. Ordinary email steps can no longer newly pick a sender row that is not an email sender. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Keep the sandbox action type in the hog flow model module so the workflows facade stays off the Django startup import path. - Grandfather the wrong-kind sender rule only from the live workflow; a lenient web draft never raised it, so its draft value must not pass publish unchecked. - Compile sandbox Hog templates with the warehouse record alias when a warehouse table triggers the workflow. - Serialize the sender status DTO directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A web draft save tolerates unfinished steps, so the sender-kind rule never ran there. The sender then reached the workflow's live actions and was grandfathered when it published. A wrong-kind sender is never an unfinished edit, so every save now refuses it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ership A sandbox email step now refuses a null recipient name, subject, preheader, text or HTML, which the sender's renderer cannot take. A test run's configuration override on a workflow another product owns is now refused like a save, because the ownership check reads the flow from the context. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A test run's configuration override could claim no owning product and send a sandbox step for a workflow another product owns. The owner is set on create and never changes, so the saved value now decides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A web draft save with malformed function inputs crashed the sender-kind check before the serializer could tolerate them. The check now leaves such inputs to the serializer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The draft sender check now reaches cdp through its presentation re-exports, as the facade contract requires. The tenant poll is marked exempt from the team scope audit, because its model is platform state with no team. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The block admin prefills the staff member on the add form instead of overriding save_model, and the sender lookup returns a frozen dataclass instead of a (kind, domain) tuple. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Email steps get a sender control that lists verified own senders and, when the project can adopt it, the sandbox sender. Choosing a sender replaces the step with the matching stored type in one change, and asks first when own-only settings would be dropped. New workflows and inserted email steps use the sandbox sender when no verified own sender exists. Sandbox steps get their own panel, content validation, a verified-member test recipient, readable test results, a Channels row, and metric labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…u1-editor-sender-choice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 CI report
|
| Function | Location | Complexity | Limit |
|---|---|---|---|
onDrop |
products/workflows/frontend/Workflows/hogflows/hogFlowEditorLogic.tsx:2699 |
52 | 10 |
saveWorkflowSuccess |
products/workflows/frontend/Workflows/workflowLogic.ts:4937 |
45 | 10 |
runSave |
products/workflows/frontend/Workflows/workflowLogic.ts:3806 |
42 | 10 |
<anonymous> |
products/workflows/frontend/Workflows/workflowLogic.ts:4361 |
40 | 10 |
getIntegrationNameFromKind |
frontend/src/lib/integrations/utils.ts:146 |
28 | 10 |
handleOauthCallback |
frontend/src/lib/integrations/integrationsLogic.ts:1270 |
27 | 10 |
EmailActionTestContent |
products/workflows/frontend/Workflows/hogflows/panel/testing/HogFlowEditorNotificationPanelTest.tsx:36 |
24 | 10 |
HogFlowEditorPanel |
products/workflows/frontend/Workflows/hogflows/panel/HogFlowEditorPanel.tsx:32 |
21 | 10 |
NativeEmailIntegrationChoice |
frontend/src/scenes/hog-functions/email-templater/EmailTemplater.tsx:257 |
17 | 10 |
WorkflowRunMetrics |
products/workflows/frontend/Workflows/WorkflowMetrics.tsx:98 |
16 | 10 |
NativeEmailTemplaterForm |
frontend/src/scenes/hog-functions/email-templater/EmailTemplater.tsx:588 |
15 | 10 |
presentationFacts |
products/workflows/frontend/Workflows/hogflows/editor/tile-canvas/stepFacts.ts:212 |
14 | 10 |
triggerFacts |
products/workflows/frontend/Workflows/hogflows/editor/tile-canvas/stepFacts.ts:274 |
13 | 10 |
<anonymous> |
frontend/src/scenes/hog-functions/email-templater/emailTemplaterLogic.tsx:1080 |
12 | 10 |
BatchJobMetrics |
products/workflows/frontend/Workflows/WorkflowMetrics.tsx:299 |
12 | 10 |
ownOnlySettings |
products/workflows/frontend/Workflows/hogflows/steps/email/emailStepVariants.ts:109 |
12 | 10 |
getTriggerPreviews |
products/workflows/frontend/Workflows/hogflows/steps/HogFlowSteps.tsx:83 |
11 | 10 |
submit |
products/workflows/frontend/Workflows/workflowLogic.ts:4000 |
11 | 10 |
✅ Duplication (Python) — clean
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.
⚠️ Duplication (TypeScript) — 25 new duplicated blocks (worst 3667 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 |
|---|---|---|---|
products/workflows/frontend/Workflows/hogflows/hogFlowEditorLogic.tsx:267 |
products/workflows/frontend/Workflows/hogflows/hogFlowEditorLogic.tsx:1211 |
942 | 3667 |
products/workflows/frontend/Workflows/workflowLogic.ts:610 |
products/workflows/frontend/Workflows/workflowLogic.ts:1554 |
942 | 3667 |
products/workflows/frontend/Workflows/hogflows/steps/stepWaitUntilTimeWindowLogic.ts:439 |
products/workflows/frontend/Workflows/workflowLogic.ts:2509 |
343 | 1265 |
products/workflows/frontend/Workflows/hogflows/steps/stepDelayLogic.ts:513 |
products/workflows/frontend/Workflows/workflowLogic.ts:2945 |
341 | 1261 |
products/workflows/frontend/Workflows/hogflows/steps/stepWaitUntilTimeWindowLogic.ts:101 |
products/workflows/frontend/Workflows/hogflows/steps/stepWaitUntilTimeWindowLogic.ts:442 |
339 | 1257 |
products/workflows/frontend/Workflows/hogflows/steps/stepDelayLogic.ts:176 |
products/workflows/frontend/Workflows/hogflows/steps/stepWaitUntilTimeWindowLogic.ts:102 |
337 | 1252 |
products/workflows/frontend/Workflows/hogflows/steps/stepDelayLogic.ts:228 |
products/workflows/frontend/Workflows/hogflows/steps/stepDelayLogic.ts:573 |
66 | 253 |
frontend/src/lib/integrations/integrationsLogic.ts:386 |
frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:86 |
62 | 164 |
frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:86 |
frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:149 |
62 | 164 |
frontend/src/lib/integrations/integrationsLogic.ts:386 |
frontend/src/lib/integrations/integrationsLogic.ts:453 |
61 | 161 |
products/workflows/frontend/Workflows/hogflows/hogFlowEditorLogic.tsx:354 |
products/workflows/frontend/Workflows/hogflows/hogFlowEditorLogic.tsx:679 |
31 | 133 |
products/workflows/frontend/Workflows/workflowLogic.ts:671 |
products/workflows/frontend/Workflows/workflowLogic.ts:936 |
31 | 133 |
frontend/src/lib/integrations/integrationsLogic.ts:741 |
frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:219 |
52 | 114 |
frontend/src/lib/integrations/integrationsLogic.ts:136 |
frontend/src/scenes/settings/organization/organizationIntegrationsLogic.ts:16 |
51 | 107 |
frontend/src/lib/integrations/integrationsLogic.ts:136 |
frontend/src/lib/integrations/integrationsLogic.ts:742 |
51 | 106 |
products/workflows/frontend/Workflows/hogflows/panel/testing/HogFlowEditorNotificationPanelTest.tsx:372 |
products/workflows/frontend/Workflows/hogflows/panel/testing/HogFlowEditorPanelTest.tsx:152 |
19 | 102 |
frontend/src/lib/integrations/integrationsLogic.ts:258 |
products/data_warehouse/frontend/shared/logics/destinationModalLogic.ts:123 |
50 | 100 |
frontend/src/lib/integrations/integrationsLogic.ts:259 |
frontend/src/lib/integrations/integrationsLogic.ts:397 |
48 | 96 |
frontend/src/lib/integrations/integrationsLogic.ts:259 |
frontend/src/lib/integrations/integrationsLogic.ts:525 |
48 | 96 |
frontend/src/lib/integrations/integrationsLogic.ts:592 |
frontend/src/lib/integrations/integrationsLogic.ts:644 |
48 | 96 |
frontend/src/lib/integrations/integrationsLogic.ts:259 |
frontend/src/lib/integrations/integrationsLogic.ts:592 |
48 | 95 |
frontend/src/lib/integrations/integrationsLogic.ts:138 |
frontend/src/lib/integrations/integrationsLogic.ts:260 |
47 | 94 |
products/workflows/frontend/Workflows/hogflows/steps/stepDelayLogic.ts:271 |
products/workflows/frontend/Workflows/workflowLogic.ts:705 |
22 | 85 |
frontend/src/lib/integrations/integrationsLogic.ts:150 |
frontend/src/lib/integrations/integrationsLogic.ts:756 |
38 | 77 |
products/workflows/frontend/Workflows/hogflows/panel/testing/hogFlowEditorNotificationTestLogic.ts:222 |
products/workflows/frontend/Workflows/hogflows/panel/testing/hogFlowEditorTestLogic.ts:295 |
17 | 75 |
⚠️ Bundle size — 🔺 +10.4 KiB (+0.0%)
Uncompressed size of every built .js bundle, compared against the base branch.
Total: 79.10 MiB · 🔺 +10.4 KiB (+0.0%)
| File | Size | Δ vs base |
|---|---|---|
exporter/_parent/products/workflows/frontend/Workflows/Workflow.js |
211.1 KiB | 🔺 +6.3 KiB (+3.1%) |
render-query/src/render-query/render-query.js |
22.20 MiB | 🔺 +3.6 KiB (+0.0%) |
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.05 MiB · 25 files | no change | █████████░ 91.6% 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.87 MiB · 538 files | no change | ██████████ 99.1% of 2.89 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
3.89 MiB · 1,237 files | no change | ██████████ 99.5% of 3.91 MiB |
dashboard scenesrc/scenes/dashboard/Dashboard.tsx |
7.84 MiB · 3,026 files | 🔺 +844 B (+0.0%) | ██████████ 99.1% of 7.92 MiB |
today home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx |
4.88 MiB · 1,872 files | 🔺 +58 B (+0.0%) | ██████████ 99.9% of 4.88 MiB |
AI-first home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx |
6.10 MiB · 2,297 files | 🔺 +844 B (+0.0%) | ██████████ 99.5% of 6.13 MiB |
events scenesrc/scenes/activity/explore/EventsScene.tsx |
6.83 MiB · 2,568 files | 🔺 +786 B (+0.0%) | ██████████ 98.8% of 6.91 MiB |
web analytics scenesrc/scenes/web-analytics/WebAnalyticsScene.tsx |
7.92 MiB · 2,973 files | 🔺 +786 B (+0.0%) | ██████████ 99.5% of 7.96 MiB |
replay detail scenesrc/scenes/session-recordings/detail/SessionRecordingDetail.tsx |
7.01 MiB · 2,622 files | 🔺 +844 B (+0.0%) | ██████████ 98.9% of 7.09 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/lib/lemon-ui/LemonTable/LemonTable.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/@dnd-kit/ 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
🟢 products/conversations/frontend/components/SidePanel/sidepanelTicketsLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/zod/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/authentication/auth/loginLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/authentication/shared/passkeyLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/cohorts/CohortFilters/constants.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/persons/frontend/logics/personsLogic.tsx stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/surveys/constants.tsx 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
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/marked/ stays out of src/scenes/dashboard/Dashboard.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/dashboard/Dashboard.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/debug/HogDebug.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.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
🟢 packages/quill/packages/quill/dist/ 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/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
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/marked/ stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/activity/explore/EventsScene.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/queries/nodes/InsightViz/InsightViz.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/nodes/DataVisualization/DataVisualization.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/nodes/WebOverview/WebOverview.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/debug/HogDebug.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/marked/ stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 node_modules/frimousse/ stays out of src/scenes/web-analytics/WebAnalyticsScene.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/debug/HogDebug.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 src/queries/QueryEditor/QueryEditor.tsx stays out of src/scenes/web-analytics/WebAnalyticsScene.tsx
🟢 packages/quill/packages/quill/dist/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/@tiptap/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/prosemirror- stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
🟢 node_modules/marked/ stays out of src/scenes/session-recordings/detail/SessionRecordingDetail.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.8 KiB | src/lib/utils/bootTiming.ts |
| 1.7 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.7 KiB | src/index.tsx |
| 1.2 KiB | src/RootErrorBoundary.tsx |
| 1.1 KiB | src/lib/utils/deferredAppContext.ts |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 108.1 KiB | src/products.tsx |
| 93.2 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 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 |
| 29.4 KiB | src/lib/constants.tsx |
| 24.8 KiB | ../node_modules/.pnpm/fuse.js@7.3.0/node_modules/fuse.js/dist/fuse.mjs |
| 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 |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 108.1 KiB | src/products.tsx |
| 93.2 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 40.3 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.3.0_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.6 KiB | src/lib/utils/eventUsageLogic.ts |
| 29.4 KiB | src/lib/constants.tsx |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 116.4 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 98.2 KiB | ../packages/quill/packages/components/dist/index.js |
| 93.2 KiB | src/lib/api.ts |
| 78.8 KiB | src/scenes/dashboard/dashboardLogic.tsx |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
| Size | File |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 93.2 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 68.5 KiB | ../products/posthog_ai/frontend/logics/runStreamLogic.ts |
| 40.3 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.3.0_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 |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 93.2 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 68.5 KiB | ../products/posthog_ai/frontend/logics/runStreamLogic.ts |
| 41.7 KiB | src/scenes/hog-functions/sub-templates/sub-templates.ts |
| 40.3 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.3.0_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 |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 98.2 KiB | ../packages/quill/packages/components/dist/index.js |
| 93.2 KiB | src/lib/api.ts |
| 78.8 KiB | src/scenes/dashboard/dashboardLogic.tsx |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 68.5 KiB | ../products/posthog_ai/frontend/logics/runStreamLogic.ts |
Largest files eagerly shipped from src/scenes/web-analytics/WebAnalyticsScene.tsx
| Size | File |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_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 |
| 116.4 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_react@18.3.1/node_modules/posthog-js/dist/surveys-preview.js |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 98.2 KiB | ../packages/quill/packages/components/dist/index.js |
| 93.2 KiB | src/lib/api.ts |
| 78.8 KiB | src/scenes/dashboard/dashboardLogic.tsx |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
| Size | File |
|---|---|
| 363.5 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 329.8 KiB | ../node_modules/.pnpm/posthog-js@1.447.13_@types+react@18.3.31_react@18.3.1/node_modules/posthog-js/dist/rrweb.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 |
| 112.7 KiB | ../packages/quill/packages/primitives/dist/index.js |
| 108.1 KiB | src/products.tsx |
| 98.2 KiB | ../packages/quill/packages/components/dist/index.js |
| 93.2 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 68.5 KiB | ../products/posthog_ai/frontend/logics/runStreamLogic.ts |
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, 0 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 | 3.01 MiB | 🔺 +21 B (+0.0%) |
| shell | 2.42 MiB | no change |
| query | 56.9 KiB | no change |
| features | 274.3 KiB | no change |
Download the interactive layer graph for this PR.
Posted automatically by check-layers
✅ Toolbar bundle — eager 2.45 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.45 MiB · 19 files | no change | ████░░░░░░ 42.8% of 5.72 MiB |
| Deferred (lazy) | 2.64 MiB · 43 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 |
|---|---|
| 985.3 KiB | dist/toolbar/toolbar-app-WRRY4DD6.css |
| 739.3 KiB | dist/toolbar/chunk-chunk-HTZUGHV7.js |
| 290.5 KiB | dist/toolbar/chunk-chunk-E2SUTX3R.js |
| 137.6 KiB | dist/toolbar/chunk-chunk-VDQTCFXU.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FQJO25M6.js |
| 75.7 KiB | dist/toolbar/toolbar-app-VVJSXHEF.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-BFAXZMC5.js |
| 33.8 KiB | dist/toolbar/chunk-chunk-QPDUWEQB.js |
| 21.9 KiB | dist/toolbar/chunk-chunk-2JRYAEFH.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-RVLGRPCH.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +358.8 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1012.68 MiB · 🔺 +358.8 KiB (+0.0%)
ℹ️ MCP UI apps size — 35 app(s), 37011.6 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 1067.3 KB | 225.1 KB |
| explain-chart | 1351.3 KB | 225.1 KB |
| action | 994.5 KB | 225.1 KB |
| action-list | 1058.3 KB | 225.1 KB |
| cohort | 993.5 KB | 225.1 KB |
| cohort-list | 1057.3 KB | 225.1 KB |
| email-template | 993.4 KB | 225.1 KB |
| error-details | 998.4 KB | 225.1 KB |
| error-issue | 995.5 KB | 225.1 KB |
| error-issue-list | 1059.5 KB | 225.1 KB |
| experiment | 1055.4 KB | 225.1 KB |
| experiment-list | 1059.1 KB | 225.1 KB |
| experiment-results | 1057.4 KB | 225.1 KB |
| feature-flag | 1057.7 KB | 225.1 KB |
| feature-flag-list | 1061.4 KB | 225.1 KB |
| feature-flag-testing | 996.8 KB | 225.1 KB |
| inline-scan | 994.0 KB | 225.1 KB |
| insight-actors | 1056.8 KB | 225.1 KB |
| llm-costs | 1054.0 KB | 225.1 KB |
| session-recording | 995.8 KB | 225.1 KB |
| survey | 995.1 KB | 225.1 KB |
| survey-global-stats | 1054.1 KB | 225.1 KB |
| survey-list | 1059.0 KB | 225.1 KB |
| survey-stats | 1054.1 KB | 225.1 KB |
| trace-span | 993.9 KB | 225.1 KB |
| trace-span-list | 1058.2 KB | 225.1 KB |
| vision-observation-list | 1057.4 KB | 225.1 KB |
| workflow | 993.9 KB | 225.1 KB |
| workflow-list | 1057.6 KB | 225.1 KB |
| workflow-setup-status | 993.6 KB | 225.1 KB |
| query-results | 1320.7 KB | 225.1 KB |
| render-ui | 1427.2 KB | 225.1 KB |
| visual-review-snapshots | 998.4 KB | 225.1 KB |
| workflow-data-suggestions | 996.2 KB | 225.1 KB |
| workflow-sending-rules | 994.9 KB | 225.1 KB |
⚠️ Playwright — 1 flaky
🎭 Playwright report · View test results →
- Delete a person property (chromium)
These issues are not necessarily caused by your changes.
Annoyed by this section? Help fix flakies and failures and it will go green!
✅ Backend coverage — all changed backend lines covered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ████████████████████ 100.0% (1 / 1)
All changed backend lines are covered ✅
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
product_analytics |
███████████████████░ 95.8% |
31,522 / 32,913 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
✅ Django migration risk — no migrations to analyze
No Django migrations need risk analysis.
❌ Hogbox preview — build failed
The preview didn't come up for commit a83b55e. See the build log for the failing step. It'll retry on the next push.
Previews are optional and never block merging. A failure here is often a hogland or tailnet hiccup rather than anything in your PR, so the check stays green and this section is the status.
- Status and provisioning requests use the selected environment, not its project. - A new email step falls back to the sandbox sender only when the project has no verified sender, not while senders load or when several exist without a default. - Templates and workflows another product owns no longer offer the sandbox sender. - A sandbox test sends to the chosen member even when the step names a fixed address, and the picker always shows the address it sends to. - A mocked sandbox test no longer reads as sent. - The canvas names a sandbox step Email and previews its content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@PostHog review |
|
@Silthus PostHog Review is reviewing this pull request. |
There was a problem hiding this comment.
PostHog Review · Standard · reviewed 5b6e6eb: 1 Must fix, 2 Should fix.
See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.
Cover status, provisioning and first-run setup in an environment whose id differs from its project, and the test recipient select replacing a value that is not a verified member. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d equivalent The generated hogFlowsInvocationsCreate returns void, and the test panel needs the invocation result, as broadcastTestSendLogic already notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test submit grew past the complexity limit with the sandbox recipient override and the sandbox test event. Both now live beside the other sandbox step helpers, and the recipient override leaves the workflow untouched unless the tested step is a sandbox step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sandbox test event read the selected step after the request finished, so selecting another step mid-test dropped it. The submit now keeps the tested step from before the request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The API saves a sandbox draft without a To, so the canvas preview and the step form now read the recipient as optional instead of failing to load the workflow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # products/workflows/backend/facade/api.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
😎 This pull request was merged. |
…ions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…itor-sender-choice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ategories on sandbox steps The first-run sender check read only the first page of integrations, so a project whose verified sender sat past it got its template email steps switched to the sandbox sender. It now pages through the email senders. An API save may store a sandbox email step with null message categories, which the backend accepts. The editor schema now accepts null for both, so the step no longer shows as invalid and blocks enabling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tegories Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…classes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…test result Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #133989, which stops the starter dashboard logging an update on creation; the organization and team-deletion activity-logging tests fail without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Not approved yet — waiting on the conditions below.
Re-add the stamphog label to request another review once you have addressed this.
stamphog declined to auto-review this pull request because it failed the size gate. It has 2061 substantive lines changed (2062 across 40 files, or 3466 across 57 once docs, generated files and snapshots are counted), and the ceiling is 1200. The other gates passed, so size alone is what blocked it.
The author can ask a human reviewer to take it, which the description already suggests by pairing it with #131834. Alternatively, the work could be split into smaller pull requests. One natural split is the sandbox sender picker and email step variants, with the test panel, Channels page row and workflow metrics changes in separate ones, each under the ceiling.
- 1 of the 57 changed files are governed by
products/desktop/AGENT_APPROVALS.md.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✗ | too large for auto-review (2061L substantive in global — ceiling is 1200L; 2062L, 40F total, 3466L/57F incl. docs/generated/snapshots) |
| tier | ✓ | T1-agent / T1d-complex (3466L, 57F, cross-cutting, feat) |
| stamphog 2.8.0 | .stamphog/policy.yml @ unknown · reviewed head 7c8815b |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This pull request was merged into |
Deploy status
This table shows the |
Note
👀 Reviewed together with #131834. The team question for this change is there. Once you're happy with #131834, please approve this one too.
Stamp request: StampHog cannot auto-review this PR (2061 substantive lines, over its 1200-line limit; every other gate passed). Agents and the merge gate did the bug review, so it needs a stamp from someone on team-workflows.
Problem
Replaces #128947, #128950, #128951, #129063 (UI part), #129064, #129065, #129066, #129067.
Caution
🔴 Merge risk: high · one-way door once
workflows-sandbox-senderturns on: adoption stores sandbox sender integrations and convertedemail_sandboxsteps, and both stay after the flag turns offMessageChannels.tsx:30,SandboxEmailSenderRow.tsx:20): every visitor in both regions sends one extra status request. The sandbox sender row shows only for a team with a sandbox sender, which needs the flag; a failed request hides it. No test or base-versus-HEAD run covers it; a bug there breaks the Channels page.WorkflowMetrics.tsx:58): teams with sandbox sends, only once the flag is on, see six new metric labels. No test covers them; a bug there mislabels a metric.workflows-sandbox-sender(server side) stops new sandbox senders and steps. Validation, the picker, the test panel, and the close flush are live on deploy: fix forward.Rollout
email_sandboxsteps only in feat(workflows): edit and choose the sandbox sender through the api and mcp #132585, so the two land together and the flag stays off until both are live.Changes
welcome.email) never offer it.email_sandboxintegration kind, metrics names, and typegen.This PR builds the parts outlined in blue: the email step's sender choice and the
email_sandboxstep it saves.How did you test this code?
Test rationale: each new test guards one contract no older test checks.
Tests
emailTemplaterLogic.test.ts: closing or switching the sender mid-debounce, then a blank editor mounting, leaves the parent holding the edited design and text. Failed before the fix. A second case edits the canvas while a sender switch's export is still pending; the parent ends with the newer design. It failed before a83b55e. The other live-change tests assert the parent's stored email, notonChangecalls.emailStepVariants.test.ts: conversions keep only sandbox fields, an editor edit keeps the recipient, and a draft without one reads as empty.SandboxSenderChoiceProvider.test.tsx: the real From picker on a stored step asks before dropping settings, switches both ways from the open editor, which stays open and keeps a canvas edit still inside the export debounce, and hides the sandbox sender without adoption. Mutation-checked.emailSenderControlLogic.test.ts: the confirm and cancel paths, and when the choice shows.workflowLogic.emailValidation.test.ts: a sandbox step checks content, never a sender, and a draft saved without a recipient asks for one. Mutation-checked.hogFlowEditorLogic.test.tsandworkflowLogic.sandboxSender.test.ts: a new email step picks the sandbox sender only once the project is known to have no verified sender, also when the team turns UTM tags on by default, never in another product's workflow, and a template email with its own UTM values keeps them. Mutation-checked.sandboxSenderLogic.test.tsandworkflowLogic.sandboxSender.test.ts, against a sandbox sender fake: setup goes to the selected environment when its id differs from its project, the step reports a sender never set up, being set up, failed, blocked (also after setup), or unavailable, and a template email with a Reply-To stays on an own sender. Mutation-checked.testResultBanner.test.ts: the sandbox result copy, a mocked run, and other steps reading as before. It covers a suspended project, a paused workflow, a suspension check that timed out, a rate-limited send, an unreachable sandbox sender, and a step ID the sender can't tag, which a composed UI walk with the Node PR had shown as a raw code. An unknown reason shows its code.WORKFLOWS_SANDBOX_EMAIL_RUNTIME_ENABLED=truein Django. This PR's own UI walk ran on an earlier base that had no such setting.hogFlowEditorNotificationTestLogic.test.ts: a sandbox test goes only to the verified member the user confirmed, sends nothing when members load late or fail, waits for members before judging, says why it can't run with no verified member, and records its event after the selection moves on without showing that result on the next step. Mutation-checked.stepFacts.test.ts,workflowStepCatalog.test.tsandHogFlowSteps.test.ts: the canvas names a sandbox step Email and previews it, also without a recipient. Mutation-checked.Release status
Docs update
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)
Skills:
/writing-ui-components,/writing-tests,/writing-user-facing-copy,/writing-pr-descriptions,/merge-riskMore context for AI agents
Channels/sandboxSenderLogic, shared by the editor and channels, not in the step logic. The sandbox option reaches the shared From picker throughSandboxSenderChoiceContext; without its provider, hog function destinations render as before.email_sandboxsupport in the email patch API and the AI context.5b6e6eb): a draft without a recipient broke the canvas (fixed). The missing executor is N1's (rollout gated). A sandbox metrics overview is out of scope (labels only).withSandboxSenderOnInsertforonDrop(51 on the base, 52 now),senderErrorsandisEmailStepfor the save validator (42 on the base, 40 now), andwithRecipientEmailfor the test submit. Three rows still grow:getIntegrationNameFromKind(27 to 28) gains oneswitchcase for the new kind,ownOnlySettings(12) makes one check per setting the sandbox sender drops, andNativeEmailIntegrationChoicegoes from 13 to 17 for four sandbox decisions: the empty state, the rotation picker, Custom sender, and the hint. Its option building lives insandboxSenderOptions.tsx. The report at 7c8815b shows the bundle up 10.4 KiB: the workflow editor chunk (+6.3 KiB) and render-query (+3.6 KiB). Not traced: which import carries this PR's changes into render-query. The eager graph grows 786 B on the events, web analytics, dashboard, AI-first home and replay paths. Master already loadsEmailTemplatereagerly on those paths, and this PR adds the sandbox sender choice to it. MovingEmailTemplateroff those paths is a change of its own. Today home and the paths that include it grow 58 B, theemail_sandboxicon and name inlib/integrations/utils.ts. No root crosses its budget, and the flagged logged-out boot path shows no change, because master already fills it. The duplication scans could not run at 85bd58e and again at 7c8815b, because jscpd ran out of memory (exit 137). Each rerun found Python clean. Most of the 25 TypeScript blocks are kea typegen interfaces whose unions gainedemail_sandbox. The largest pair, 3667 tokens inhogFlowEditorLogic.tsxandworkflowLogic.ts, is theHogFlowunion that typegen writes twice forloadWorkflowSuccess, as its parameter and its return type. Master already repeats that union at 888 lines; the new variant makes it 941, so the scan counts it as new. The test-result view shared by the two test panels was duplicated before this PR, which changed one line inside it. Theemail_sandboxzod schema insteps/types.tsrepeats Node'sschema/hogflow.ts, as every action type does, since the two packages share no imports. The frontend copy also accepts null categories, which the backend allows. The PR sits in the backend Python lane only because the generated Python copy ofIntegrationKindgainedemail_sandbox. Backend coverage reports every changed line covered. The Hogbox preview is optional. Its workflow runs at 7c8815b and a83b55e passed every job, though the report shows the build failed. The flaky Playwright test at a83b55e isDelete a person propertyinplaywright/e2e/persons/persons.spec.ts. On the first attempt, the property added through the UI did not reach the persons API within the test's 10-second poll, so the delete step never started. The retry passed, and this PR changes no persons code. At 0fbdc60 it waspassword-protected insight sharing, where the shared page failed to fetch the lazyExporterInsightScenechunk; this PR changes no sharing, insight or exporter code.NativeEmailIntegrationChoiceinEmailTemplater.tsx,emailSenderControlLogic.ts, the insert path inhogFlowEditorLogic.tsx, andworkflowLogic.tsvalidation.🤖 Generated with Claude Code