Skip to content

feat(workflows): share one email sender row across email editors - #122109

Merged
trunk-io[bot] merged 2 commits into
masterfrom
posthog/email-sender-header
Nov 12, 2026
Merged

trunk-io[bot] merged 2 commits into
masterfrom
posthog/email-sender-header

Conversation

@mayteio

@mayteio mayteio commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • People writing a broadcast or a workflow email face a cluttered header: a sender multi-select with permanent help text, a "Custom sender" button that adds two more rows, and a strip of "+ Reply-To / + Cc / + Bcc / + Preheader" buttons.
  • Transactional templates got a different sender UI in an earlier PR, so the same task looks different depending on where you write the email.
  • Labels do not line up, and empty-state errors sit under the label instead of under the field.

Warning

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

  • The transactional template editor gets the new From row without a flag. A bug in the shared from handling could save a wrong sender or address, and later sends would go out from it.
  • Limits: workflow and broadcast emails stay behind workflows-email-header. fromWithSenders tests cover rotation ids and the domain move. On master and on this branch, a sender switch saved the same from.
  • Revert: git revert the merge commit. Templates saved in between keep their from, which matches what master would save.

Changes

b1828534-6707-4ac2-9645-db2f5c4b4334.mp4
  • One From row everywhere. Broadcasts, workflow email steps (side panel and full editor) and transactional templates share it.
  • Sender picker stays one click. It is a multi-select when sender rotation is on, and a single select otherwise.
  • "Custom sender" opens a popover with display name, address and reply-to, plus Clear and Done. It replaces the inline "Custom address" and "Custom name" rows and the separate Reply-To button.
  • A note under the picker shows what is custom, for example "Each run sends from one of 2 senders", "Sends as team@example.com" and "Replies go to support@example.com".
  • The address field keeps the verified domain as a suffix. For senders on different domains it is disabled and says each sender uses its own address.
  • Cc, Bcc and Preheader are quiet buttons on the To and Subject rows. Each one opens its own row with a remove button.
  • The preheader is now offered in templates too. Before, templates showed it only when the team already used one, and it shared the subject row and wrapped.
  • Every header row shares one label column, so values line up, and errors render under the value.
  • Mechanical: EmailHeaderRow, EmailSenderRow, EmailSenderPicker, AddHeaderFieldButton and OptionalHeaderFieldRow are new files. LiquidSupportedText moved out of EmailTemplater.tsx unchanged.
  • The sandbox sender stays a choice in the new row. Sandbox email steps use the new header too, without Cc, Bcc or Custom sender.
  • Existing data-attr values stay: workflow-email-sender-select, email-from-custom-sender and the transactional-email-* ones.
  • New events: email sender edited fires when the popover closes with changes, and email header field added fires when Cc, Bcc or Preheader is revealed.

Note

The new workflow and broadcast header sits behind workflows-email-header. With the flag off, those surfaces keep today's layout. Transactional and library templates get the new rows without a flag. Templates already used the compact header on master.

Demo

email-sender-demo

Before and after

Broadcast, nothing picked yet:

1-broadcast-empty

Broadcast with two senders and a custom address and reply-to:

2-broadcast-two-senders-custom-1024

Workflow email step:

3-workflow-step-1024

Workflow email editor modal:

4-workflow-modal-1024

Transactional template:

6-transactional-template-1024

Custom sender popover:

7-custom-sender-popover

How did you test this code?

  • Manual test on the local stack with the flag on, at 1440 and 1024 widths. It covered a new broadcast, a workflow email step and its modal, a library template and a transactional template.
  • The manual test exercised rotation, a custom address on the shared domain, mixed-domain senders, a reply-to, a Liquid display name, and revealing the preheader and Cc.
  • The "before" screenshots come from master on the same stack.
  • New EmailHeader story in the workflow editor panel stories covers the flagged header with a connected sender.

Test rationale: two cases extend the existing parameterized senderAddressError test.

  • A bare local part with senders on different domains must report the domain conflict, not a format error. The check order regressed once during this work.
  • An address on the domain all rotating senders share must pass.

Sender changes: transactional templates get the new picker without a flag, so seven test.each cases cover fromWithSenders, the logic behind the picker.

  • Picking one sender drops integrationIds. The send path rotates through integrationIds whenever it is set, so a stale list sends from the wrong sender.
  • A custom address moves to the new sender's domain, a templated local part included.
  • A lone Liquid expression and an off-domain address stay as typed.
  • Each case group fails when its line is broken: the rotation cases when integrationIds keeps the old list, the domain cases when the address does not move.

After merging master: the email-templater Jest folder and the frontend typecheck pass locally. A scratch Storybook story of the inline transactional template rendered on master and on this branch. Switching from an example.com sender to an example.org sender saved the same from on both: {"integrationId":2,"name":"Team","email":"team@example.org"}. Not rerun: the manual flows above.

Release status

  • No feature flag controls this change

Docs update

No existing doc under docs/ covers the email sender fields.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code (PostHog Desktop), Claude Opus 5.5

  • Skills: /writing-ui-components, /writing-user-facing-copy, /writing-tests, /writing-code-comments, /recording-demo-videos, /writing-pr-descriptions, /modernize-pr, /babysit-pr.
  • A first version replaced the picker with a summary line and moved everything into a popover. Review asked to keep one-click picking, so the picker came back and the popover now holds only the custom fields.
  • A usage check of current workflow email steps guided which fields stay visible. Cc, Bcc and rotation are rare, and the preheader and reply-to are common.
  • The diff is over the 800-line stamphog cap, kept as one PR by request.
  • Brought up to date with master on 2026-11-11 (Claude Code, Claude Opus 5.5). Master removed the floating panel layout, so the EmailInSidePanel story is gone and EmailHeader uses the one panel layout. The sender-change logic moved out of EmailSenderPicker into fromWithSenders so it can be tested directly.

Created with PostHog Desktop

🤖 Generated with Claude Code

@mayteio mayteio self-assigned this Oct 22, 2026
@trunk-io

trunk-io Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@mayteio mayteio added the reviewhog label Oct 22, 2026 — with PostHog
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

✅ Trunk lane — non-backend lane

This PR is assigned to the non-backend lane. It does not run backend Python tests and may merge in parallel with PRs in other lanes.

⚠️ Complexity (TypeScript) — 6 functions above the limit (max 22)

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
EmailSenderRow frontend/src/scenes/hog-functions/email-templater/EmailSenderRow.tsx:22 22 10
NativeEmailTemplaterForm frontend/src/scenes/hog-functions/email-templater/EmailTemplater.tsx:548 22 10
EmailSenderForm frontend/src/scenes/hog-functions/email-templater/EmailSenderForm.tsx:20 21 10
NativeEmailIntegrationChoice frontend/src/scenes/hog-functions/email-templater/EmailTemplater.tsx:263 17 10
senderAddressError frontend/src/scenes/hog-functions/email-templater/emailSenderFields.ts:101 12 10
<anonymous> frontend/src/scenes/hog-functions/email-templater/emailTemplaterLogic.tsx:1097 12 10
❌ Duplication (Python) — the duplication scan could not run

The duplication scan failed on this run (see the job log). Nothing here says whether this branch adds duplication.

❌ Duplication (TypeScript) — the duplication scan could not run

The duplication scan failed on this run (see the job log). Nothing here says whether this branch adds duplication.

⚠️ Comment density — 4% of added code lines are comments (33 of 844)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

Files with the most added comment lines:

File Comment lines Added lines
frontend/src/scenes/hog-functions/email-templater/emailSenderFields.ts 9 64
frontend/src/scenes/hog-functions/email-templater/EmailSenderRow.tsx 5 145
frontend/src/scenes/hog-functions/email-templater/EmailSenderForm.tsx 4 91
frontend/src/scenes/hog-functions/email-templater/EmailSenderPicker.tsx 3 85
frontend/src/scenes/hog-functions/email-templater/EmailTemplater.tsx 3 44
frontend/src/scenes/hog-functions/email-templater/AddHeaderFieldButton.tsx 2 26
frontend/src/scenes/hog-functions/email-templater/EmailHeaderRow.tsx 2 30
frontend/src/scenes/hog-functions/email-templater/emailTemplaterLogic.tsx 2 16

This check does not block merging. It updates on every push and clears when the share drops.

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

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

Total: 79.76 MiB · 🔺 +438 B (+0.0%)

No file changed by more than 1000 B.

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

⚠️ Eager graph — 2 over 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 · 26 files 🔺 +37 B (+0.0%) █████████░ 91.8% 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 · 539 files 🔺 +85 B (+0.0%) ██████████ 99.3% of 2.89 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
3.90 MiB · 1,238 files 🔺 +85 B (+0.0%) ██████████ 99.9% of 3.91 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
7.92 MiB · 3,056 files 🔺 +126 B (+0.0%) ██████████ 100.0% of 7.92 MiB
🟡 today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
4.90 MiB · 1,873 files 🔺 +126 B (+0.0%) ██████████ 100.4% of 4.88 MiB
🟡 AI-first home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx
6.13 MiB · 2,299 files 🔺 +126 B (+0.0%) ██████████ 100.1% of 6.13 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
6.86 MiB · 2,573 files 🔺 +126 B (+0.0%) ██████████ 99.4% of 6.91 MiB
web analytics scene
src/scenes/web-analytics/WebAnalyticsScene.tsx
7.92 MiB · 2,967 files 🔺 +126 B (+0.0%) ██████████ 99.5% of 7.96 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
7.05 MiB · 2,628 files 🔺 +126 B (+0.0%) ██████████ 99.4% 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.5 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.8 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
107.9 KiB src/products.tsx
92.6 KiB src/lib/api.ts
68.9 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.6 KiB src/lib/constants.tsx
24.7 KiB ../node_modules/.pnpm/fuse.js@7.3.0/node_modules/fuse.js/dist/fuse.mjs
24.5 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
107.9 KiB src/products.tsx
92.6 KiB src/lib/api.ts
68.9 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.6 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.7 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
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
98.3 KiB ../packages/quill/packages/components/dist/index.js
92.6 KiB src/lib/api.ts
82.5 KiB src/scenes/dashboard/dashboardLogic.tsx
68.9 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
92.6 KiB src/lib/api.ts
68.9 KiB src/lib/lemon-ui/icons/icons.tsx
68.2 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
92.6 KiB src/lib/api.ts
68.9 KiB src/lib/lemon-ui/icons/icons.tsx
68.2 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
98.3 KiB ../packages/quill/packages/components/dist/index.js
92.6 KiB src/lib/api.ts
82.5 KiB src/scenes/dashboard/dashboardLogic.tsx
68.9 KiB src/lib/lemon-ui/icons/icons.tsx
68.2 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.7 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
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
98.3 KiB ../packages/quill/packages/components/dist/index.js
92.6 KiB src/lib/api.ts
82.5 KiB src/scenes/dashboard/dashboardLogic.tsx
68.9 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.7 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
111.2 KiB ../packages/quill/packages/primitives/dist/index.js
107.9 KiB src/products.tsx
98.3 KiB ../packages/quill/packages/components/dist/index.js
92.6 KiB src/lib/api.ts
68.9 KiB src/lib/lemon-ui/icons/icons.tsx
68.2 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.02 MiB 🔺 +152 B (+0.0%)
shell 2.42 MiB no change
query 56.9 KiB no change
features 274.7 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 🔺 +85 B (+0.0%) ████░░░░░░ 42.9% 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
987.7 KiB dist/toolbar/toolbar-app-OLDNPWAN.css
739.5 KiB dist/toolbar/chunk-chunk-EILLDGMR.js
290.5 KiB dist/toolbar/chunk-chunk-LYZDKK5A.js
137.6 KiB dist/toolbar/chunk-chunk-B7S3E3Y6.js
131.8 KiB dist/toolbar/chunk-chunk-FQJO25M6.js
75.7 KiB dist/toolbar/toolbar-app-A25QJX5G.js
69.0 KiB dist/toolbar/chunk-chunk-BFAXZMC5.js
33.8 KiB dist/toolbar/chunk-chunk-VKURV753.js
21.9 KiB dist/toolbar/chunk-chunk-HVFSCS5I.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 — 🔺 +93.9 KiB (+0.0%)

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

Total: 1019.03 MiB · 🔺 +93.9 KiB (+0.0%)

✅ Playwright — all passed

All tests passed.

View test results →

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PostHog Review · Standard · reviewed 0ea73bd: 2 Should fix.

This Standard review started from the posthog-review label. Comment @posthog review --deep for a Deep review, or @posthog help to see all commands.

@posthog posthog Bot removed the reviewhog label Oct 22, 2026
@trunk-io

trunk-io Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

View Full Report ↗︎ ⋅ Docs

@mayteio
mayteio force-pushed the posthog/email-sender-header branch from 0ea73bd to e39cb61 Compare October 27, 2026 17:07
@mayteio
mayteio marked this pull request as ready for review October 27, 2026 17:07

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not approved yet — waiting on the conditions below.

Re-add the stamphog label to request another review once you have addressed this.

The size gate refused this pull request. It has 953 substantive lines of change, which is over the 800-line ceiling for auto-review, and the full diff is 1004 lines across 17 files once docs, generated files and snapshots are counted. The other gates (prerequisites, deny-list and tier) passed, so size is the only blocker.

The author can ask a human reviewer to look at it. Or they can split it into smaller pull requests, for example one that adds the shared header row components and LiquidSupportedText, and a second that moves the sender picker and custom sender popover onto them. Each part then has a chance of fitting under the ceiling.

Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✗ too large for auto-review (953L substantive in global — ceiling is 800L; 953L, 15F total, 1004L/17F incl. docs/generated/snapshots)
tier ✓ T1-agent / T1d-complex (1004L, 17F, two-areas, feat)
stamphog 2.6.1 .stamphog/policy.yml @ unknown · reviewed head e39cb61

@parameterai

parameterai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Risk: No findings

The increment since the last review adds a movedTemplate branch to fromWithSenders so a lone {{ ... }} local part previously cut from a full address reattaches to the newly selected senders' domain, plus preheader error display in OptionalHeaderFieldRow. Both are frontend form-state changes with no new security exposure.

Sentinel reviewed c4c7452 · Review settings

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team October 27, 2026 17:08
@posthog

posthog Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Visual changes approved by @mayteio — baseline updated in ffa986a.

View this run in PostHog

2 new.

Install the Visual Review Chrome extension to see visual review results at the top of your pull requests.

@mayteio
mayteio force-pushed the posthog/email-sender-header branch from ffa986a to 5193273 Compare October 30, 2026 16:49
@hosthog

hosthog Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

HostHog preview — posthog-desktop-web

The previews for this PR have been torn down and no longer serve.

@scheduled-actions-posthog

Copy link
Copy Markdown
Contributor

This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, please remove the stale label – otherwise this will be closed in another week. If you want to permanently keep it open, use the waiting label.

@veria-ai

veria-ai Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Reviews

@posthog

posthog Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

✅ Visual changes approved by @mayteio — baseline updated in 161b6ad.

View this run in PostHog

2 new.

Install the Visual Review Chrome extension to see visual review results at the top of your pull requests.

The workflow, broadcast and transactional template editors now show one From row with a sender picker and a custom sender dropdown, and Reply-To, Cc, Bcc and Preheader rows aligned under it. The sandbox sender stays a choice in the new row.
@mayteio
mayteio force-pushed the posthog/email-sender-header branch from 161b6ad to 532c29a Compare November 12, 2026 21:24

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PostHog Review · Standard · reviewed 532c29a: 2 Should fix.

@mayteio

mayteio commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 Claude Opus 5.5 responding on behalf of Harley

Live proof on the dev stack

The sender row looks and behaves the same in a broadcast email, a workflow email step and a transactional template. Each one saved the chosen sender, Reply-To and subject, and the API returned them. Run on c4c74528c28 with hogli up on this worktree's devbox, the workflows-email-header flag on, and two verified test senders on example.com.

Commands

fleet worktree-box run -- 'cd ~/posthog && hogli up -d && hogli wait'
  ok: 43 procs ready in 1m38s
python manage.py shell < seed.py   # test user, team 1, senders hello@ and news@example.com
node t3.js / t4.js / t6.js         # Playwright drives each editor in the browser

What each editor stored (GET from the API after the UI save)

broadcast (GET /api/projects/1/hog_flows/<id>/), autosaved draft
  function_email {"from": {"email": "team@example.com", "integrationId": 1}, "replyTo": "support@example.com", "subject": "Welcome aboard"}
workflow step (GET /api/projects/1/hog_flows/<id>/), after Save
  function_email {"from": {"integrationId": 2}, "replyTo": "support@example.com", "subject": "Thanks for visiting"}
transactional template (GET /api/environments/1/messaging_templates/), after "Create transactional email"
  email {"from": {"integrationId": 2}, "replyTo": "support@example.com", "subject": "Your receipt"}

Screenshots

Broadcast with no sender yet: the error sits under the From field.

broadcast-empty-sender

Broadcast after picking a sender and setting a custom address and Reply-To:

broadcast-custom-sender

Workflow email step after Save:

workflow-step-saved

Transactional template with the Custom sender dropdown open:

transactional-custom-sender

Rebase note

Master added the sandbox sender to the old From picker in #131916. The new row now offers it too: picking it saves any pending canvas edit first, and Custom sender hides while the sandbox sender is selected. SandboxSenderChoiceProvider.test.tsx now runs its sender-switch cases with the new header as well, and they fail without the save. The sandbox sender itself was not run live, because it needs the shared SES tenant.

@posthog posthog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PostHog Review · Standard · reviewed c4c7452: no findings.

@mayteio

mayteio commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 Claude Opus 5.5 responding on behalf of Harley

CI report findings on c4c74528c28, none of which block this PR:

  • Eager graph (+126 B): the new WORKFLOWS_EMAIL_HEADER key in lib/constants, which every flag needs. The two roots over budget were already over on master.
  • Complexity (TypeScript): EmailSenderRow and EmailSenderForm hold the row's branches (empty state, sandbox sender, rotation). Splitting them now would add indirection for one caller.
  • Duplication: the scan failed to run, so it reports nothing either way.
  • Bundle size and comment density: advisory only.
  • Visual Review: the storybook run has 0 changed snapshots out of 9099. The 14 changed quarantined stories are outside this PR (exporter, SQL editor, MCP analytics, side panels).

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved.

The sender configuration write path has current-head independent review, owning-team authorship, STRONG familiarity, and targeted regression tests. No concrete unresolved review concerns or other policy refusal grounds are present.

  • Author wrote 77% of the modified lines and has 28 merged PRs in these paths (familiarity STRONG).
  • PostHog Review (Standard) reviewed the current head: no findings.
  • posthog[bot] reviewed the current head.
Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 1049L, 17F substantive, 1174L/20F incl. docs/generated/snapshots — within ceiling
tier ✓ T1-agent / T1d-complex (1174L, 20F, two-areas, feat)
stamphog 2.8.0 .stamphog/policy.yml @ c4c7452 · reviewed head c4c7452

@mayteio

mayteio commented Nov 12, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@trunk-io
trunk-io Bot merged commit 1962d7c into master Nov 12, 2026
279 checks passed
@trunk-io
trunk-io Bot deleted the posthog/email-sender-header branch November 12, 2026 22:34
@deployment-status-posthog

deployment-status-posthog Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-11-12 23:07 UTC Run
prod-us ✅ Deployed 2026-11-12 23:35 UTC Run
prod-eu ✅ Deployed 2026-11-12 23:43 UTC Run

This table shows the posthog release only. Hogstation shows every service that this PR reaches, Kargo services included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant