Skip to content

feat(surveys): start a follow-up workflow from a survey - #113008

Merged
trunk-io[bot] merged 4 commits into
masterfrom
posthog/message-audience-survey
Oct 8, 2026
Merged

trunk-io[bot] merged 4 commits into
masterfrom
posthog/message-audience-survey

Conversation

@dmarchuk

@dmarchuk dmarchuk commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Changes

  • The survey's side panel has a new "Start a follow-up workflow" action.
  • It opens a new workflow with the "Survey response" trigger set to this survey. The trigger has the same shape the editor's survey trigger writes, so the editor shows it as that trigger with the survey selected and "Any response", the editor's default.
  • Nothing is saved until the person creates the workflow.
  • The click is tracked as message audience clicked with source: survey, destination: workflow.
  • Broadcast to respondents is left out to keep this PR small. It would follow the static-cohort approach of feat(error-tracking): email the people affected by an issue #112998.

Survey side panel with the new action

New workflow with the Survey response trigger

How did you test this code?

Local app (project 1), Playwright in Chromium, Postgres read back:

  1. Opened the launched survey "Onboarding feedback", opened the side panel, double-clicked "Start a follow-up workflow".
  2. The workflow opened once. The trigger panel showed "Survey response", "Onboarding feedback" selected, and the question filters for that survey.
  3. posthog_hogflow count before and after opening: 716 and 716.
  4. Renamed the workflow and clicked "Create as draft". The saved trigger: events [{"id": "survey sent", "name": "Survey sent", "type": "events"}], properties [{"key": "$survey_id", "type": "event", "value": "<survey id>", "operator": "exact"}], and bytecode compiled to event = 'survey sent' and properties.$survey_id = <id>.
  5. A draft survey with a 191-character Cyrillic, emoji and German name: the trigger panel showed the full name selected, and the saved trigger had that survey id.

Not tested:

  • A real survey response running through the saved workflow.
  • The analytics event. Local dev sends no capture requests.

Test rationale: No new unit test. The trigger is a constant shape, and the browser run checks that the editor recognizes and saves it.

Release status

  • No feature flag controls this change

Docs update

None.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)

  • Skills invoked: /writing-ui-components, /writing-user-facing-copy, /writing-code-comments, /writing-pr-descriptions.
  • CodeRabbit CLI pass skipped: the CLI is signed out.
  • CodeRabbit review: the tooltip now says the workflow runs when someone submits a response, and the survey source string is pinned. Not applied: adding survey dismissed and survey abandoned to the trigger. The editor's survey trigger recognizes only the single survey sent event, so that change belongs in the editor first.
  • The trigger shape is built inline instead of importing buildProperties from the workflow trigger registry, because that module registers editor components on import.
  • CodeRabbit comments on broadcastWizardLogic.ts, broadcastAudiencePrefill.ts and broadcastWizardLogic.test.ts (invalid-link audience, entrySource across the draft URL, unknown operators, test assertions): out of scope. They target files from feat(workflows): let other products open a broadcast or workflow for an audience #112985, which merged before this PR was rebased, so they are not in this diff. The thread is resolved as outdated.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BR6LoqsDMB9Wfnftcy2KiG

@dmarchuk dmarchuk self-assigned this Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 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) — 2 functions above the limit (max 31)

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
SurveyViewRedesign frontend/src/scenes/surveys/SurveyViewRedesign/SurveyViewRedesign.tsx:87 31 10
<anonymous> frontend/src/scenes/surveys/SurveyViewRedesign/SurveyViewRedesign.tsx:178 13 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) — clean

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.

✅ Comment density — 5% of added code lines are comments (2 of 40)

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/surveys/components/SurveyFollowUpWorkflowButton.tsx 2 38

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

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

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

Total: 76.48 MiB · 🔺 +824 B (+0.0%)

No file changed by more than 1000 B.

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

✅ Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.65 MiB · 23 files 🔺 +355 B (+0.0%) █████████░ 89.6% of 1.84 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
3.78 MiB · 670 files 🔺 +594 B (+0.0%) █████████░ 93.9% of 4.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.71 MiB · 2,436 files 🔺 +603 B (+0.0%) █████████░ 92.4% of 8.34 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.91 MiB · 3,502 files 🔺 +449 B (+0.0%) █████████░ 90.8% of 10.92 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.73 MiB · 2,448 files 🔺 +603 B (+0.0%) █████████░ 90.0% of 8.58 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
9.53 MiB · 3,353 files 🔺 +603 B (+0.0%) █████████░ 90.7% of 10.51 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
12.25 MiB · 4,161 files 🔺 +603 B (+0.0%) ████████░░ 77.9% of 15.72 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers 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
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/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
🟢 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

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/index.tsx
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
839 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
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
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx
68.7 KiB src/lib/lemon-ui/icons/icons.tsx
40.7 KiB src/lib/utils/eventUsageLogic.ts
38.7 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
33.9 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.0 KiB ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
281.0 KiB src/taxonomy/core-filter-definitions-by-group.json
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
281.0 KiB src/taxonomy/core-filter-definitions-by-group.json
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
281.0 KiB src/taxonomy/core-filter-definitions-by-group.json
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
281.0 KiB src/taxonomy/core-filter-definitions-by-group.json
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
316.7 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
316.0 KiB ../node_modules/.pnpm/posthog-js@1.438.1_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
281.0 KiB src/taxonomy/core-filter-definitions-by-group.json
221.0 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.3 KiB ../packages/quill/packages/quill/dist/index.js
99.7 KiB src/lib/api.ts
93.4 KiB src/products.tsx

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

✅ Toolbar bundle — eager 2.23 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.23 MiB · 19 files 🔺 +239 B (+0.0%) ████░░░░░░ 39.0% of 5.72 MiB
Deferred (lazy) 2.11 MiB · 44 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
858.6 KiB dist/toolbar/toolbar-app-XWVKQO74.css
668.4 KiB dist/toolbar/chunk-chunk-EJYCU4VX.js
259.4 KiB dist/toolbar/chunk-chunk-5UE4YDI5.js
138.2 KiB dist/toolbar/chunk-chunk-W2NRFMBG.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
75.2 KiB dist/toolbar/toolbar-app-7O4ZS6NZ.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-GPY3KVGS.js
21.0 KiB dist/toolbar/chunk-chunk-UZJIYFJS.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

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

✅ Dist folder size — 🔺 +38.4 KiB (+0.0%)

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

Total: 1005.06 MiB · 🔺 +38.4 KiB (+0.0%)

✅ Playwright — all passed

All tests passed.

View test results →

❌ Hogbox preview — build failed

The preview didn't come up for commit 2df84c0. 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.

@trunk-io

trunk-io Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
Scenes-Other/Startup program NeedsBillingDetails smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎
Scenes-App/Notebooks/Nodes/Customer Journey AllStepsCompleted smoke-test The test timed out while waiting for an element with the class '.react-flow__node' to become visible. Logs ↗︎
Scenes-App/Project Homepage ProjectHomepage smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎
Scenes-App/OAuth/Authorize DefaultScopes smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎

View Full Report ↗︎ ⋅ Docs

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

Walkthrough

The broadcast wizard now accepts audience, name, and source values from new-broadcast links. New audience helpers generate broadcast and workflow URLs and record destination clicks. The survey action panel renders a follow-up workflow button when a transferable survey ID is available; the button opens a workflow with a “Survey sent” trigger filtered to that ID.

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description is complete and follows the repository template. It explains the problem, user-visible changes, screenshots, testing steps, test limitations, rationale, release status, do…
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch posthog/message-audience-survey
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Include partial completions in the trigger. · SurveyFollowUpWorkflowButton.tsx:15-28

frontend/src/scenes/surveys/components/SurveyFollowUpWorkflowButton.tsx:15-28
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include partial completions in the trigger.

When enable_partial_responses is false, an answered survey that a respondent dismisses or leaves emits survey dismissed or survey abandoned with $survey_partially_completed, not survey sent. The generated workflow can miss these responses even though the button says it runs each time someone responds. Keep survey sent for full submissions, and make the trigger include these partial-completion events when partial responses are disabled.


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: c5472e04-e065-472b-9fe5-2030fad81e21
📥 Commits

Reviewing files that changed from the base of the PR and between 90cd601 and 4c8a4ba.

📒 Files selected for processing (1)
  • frontend/src/scenes/surveys/components/SurveyFollowUpWorkflowButton.tsx

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 4 remain after this review.

Base automatically changed from posthog/message-audience-plumbing to master October 7, 2026 16:30
@trunk-io

trunk-io Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

😎 Merged successfully - details.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (2)
products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts (1)

669-669: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve entrySource when the draft URL replaces the new-broadcast URL.

entrySource exists only in the new wizard's state. Saving a draft replaces /broadcasts/new with the draft URL and remounts the wizard, so the normal later launch reports entry_source: null. Carry the source through that transition or persist it with the draft.

products/workflows/frontend/Broadcasts/broadcastAudiencePrefill.ts (1)

60-60: 🔒 Security & Privacy | 🛡️ Detected with Advanced Tier | 🟡 Minor | ⚡ Quick win

Reject unknown person-filter operators before accepting the prefill.

An unknown operator is accepted here and reaches backend query construction, where it raises NotImplementedError. The blast-radius request or recipient enumeration then fails instead of opening a usable broadcast. Reject unknown operators before storing the prefill.

Validate the operator
     if (type === PropertyFilterType.Cohort) {
         return typeof value === 'number' && Number.isFinite(value)
     }
+    if (typeof operator !== 'string' || !Object.values(PropertyOperator).includes(operator as PropertyOperator)) {
+        return false
+    }
     if (operator === PropertyOperator.IsSet || operator === PropertyOperator.IsNotSet) {
         return true
     }
🧹 Nitpick comments (1)
products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts (1)

141-143: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the draft and preview outcomes, not action dispatch.

The absence of ensureDraft does not prove that opening the link creates no draft. Assert that the create API was not called, and assert that the preview API received the prefilled filters. Keep the state assertions. As per coding guidelines, “Test observable behavior through the public interface ... not the choreography that produces it.”

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 26c35ac1-a797-482f-9093-e7079f7a1043
📥 Commits

Reviewing files that changed from the base of the PR and between 15793b9 and 15793b9.

📒 Files selected for processing (6)
  • products/workflows/frontend/Broadcasts/broadcastAudiencePrefill.test.ts
  • products/workflows/frontend/Broadcasts/broadcastAudiencePrefill.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.test.ts
  • products/workflows/frontend/Broadcasts/broadcastWizardLogic.ts
  • products/workflows/frontend/MessageAudience/MessageAudienceButton.tsx
  • products/workflows/frontend/MessageAudience/messageAudience.ts

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 8 remain after this review.

@dmarchuk
dmarchuk force-pushed the posthog/message-audience-survey branch from 15793b9 to ca44a13 Compare October 7, 2026 16:37
@dmarchuk
dmarchuk marked this pull request as ready for review October 7, 2026 18:22
@parameterai

parameterai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Risk: No findings

This change adds a "Start a follow-up workflow" menu action to the survey side panel that navigates to the new-workflow editor with an event trigger pre-filled for this survey's responses. The survey id comes from the user's own authorized survey view and the trigger config is validated by a zod schema (HogFlowTriggerSchema) before use, with nothing persisted until workflow creation goes through the normal workflow API permissions, so no new security risk is introduced.

Sentinel reviewed 2df84c0 · Review settings

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team October 7, 2026 18:22
@dmarchuk dmarchuk added the stamphog Request AI approval (no full review) label Oct 7, 2026

@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.

Small additive frontend menu action that navigates to a new-workflow editor with a prefilled trigger. It saves nothing, imports resolve, and it has no risky-territory impact. The CodeRabbit partial-completion note is a design choice that the author deliberately deferred.

Gate mechanics and policy version
Gate Result
prerequisites ✓ all clear
deny-list ✓ no deny categories matched
size ✓ 47L, 2F substantive — within ceiling
tier ✓ T1-agent / T1b-small (47L, 2F, single-area, feat)
stamphog 2.3.1 .stamphog/policy.yml @ 2df84c0 · reviewed head 2df84c0

@dmarchuk
dmarchuk removed the request for review from a team October 8, 2026 00:25
@dmarchuk

dmarchuk commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

/trunk merge

@trunk-io
trunk-io Bot merged commit 8898090 into master Oct 8, 2026
@trunk-io
trunk-io Bot deleted the posthog/message-audience-survey branch October 8, 2026 07:44
@deployment-status-posthog

deployment-status-posthog Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-10-08 08:09 UTC Run
prod-us ✅ Deployed 2026-10-08 08:26 UTC Run
prod-eu ✅ Deployed 2026-10-08 08:28 UTC Run

This branch had an error being deployed

1 failed deployment
preview-pr-113008 — 2df84c0f Deployed Oct 7, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant