Repository navigation
Conversation
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael
|
The codebase scan already finds email-sending services such as Resend. Set them on the person as wizard_detected_email_providers and wizard_detected_email_provider_at, through $set on the `warehouse sources detected` event. A $set captured before login is set again at identify, so it reaches the person who uses the PostHog app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Set the person properties when the scan is shared after login, so CI, headless, warehouse and self-driving runs set them too, and drop the pre-login replay in Analytics. Count Campaign Monitor, ConvertKit, beehiiv and Drip as email providers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the new account's user after provisioning and identify it, as the OAuth login does, so a signup run's events and the detected email providers land on its person. A failed read keeps the signup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A login without a user, such as a signup whose user could not be read, has no person to set them on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7e96c5d to
ae686b9
Compare
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael Moved to #1506, a branch on PostHog/wizard so CI runs. |
|
Hey! thanks for the PR. This is really dependent on the use case and many times can result in unwanted PII being tracked. We'd like to offer this choice to the user to be added later consciously instead. |
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael
Agreed. #1506, where this work moved, no longer sets anything on the person. As of |
Problem
The Wizard's codebase scan already finds the email services a user's code sends through, such as Resend, SendGrid or Amazon SES. That fact stays in the scan and never reaches the person, so feature flags, surveys and the Workflows onboarding in the PostHog app can't tell that this user already sends email from their code.
With this PR, the logged-in person gets
wizard_detected_email_providers(the detected kinds, such as["Resend"]) andwizard_detected_email_provider_at(when the scan found them), on every program that scans: the default integration flow, interactive or CI,wizard warehouseandwizard self-driving. Awizard --signuprun now identifies the account it creates, so its events and these properties land on that account's person too.Impact
Pays into Grow Workflows through Started orgs (orgs that create their first workflow). Not measured yet: an insight in the internal project counts people with
wizard_detected_email_providersper week and how many of them reach Workflows, start its onboarding, create an email sender, or launch a workflow or broadcast. In scope: email, the Messaging category. Expected move: small, up. On its own this PR only adds the targeting signal; a follow-up such as a "We found Resend in your code" card in Workflows uses it. Run cost: n/a.Merge Danger
Note
🔵 Merge risk: low · one-way door (merge-risk rubric)
$unset.reportCodebaseScangains one call behind its existing consent, login and failed-scan checks, andAnalyticsgainssetPersonProperties. No existing event or$identifypayload changes.wizard --signupruns now callidentifyUserfor the new account, as OAuth logins already do, so their events merge onto that person instead of staying anonymous. A failed user read keeps the signup going.Changes
emailProviderPersonProperties(src/services/codebase-scan/email-providers.ts) reads the run's codebase scan and keeps the tool catalog kinds of email services:AwsSes,Beehiiv,BigMailer,Brevo,CampaignMonitor,ConvertKit,Drip,Elasticemail,EmailOctopus,Flexmail,Loops,Mailchimp,MailerLite,MailerSend,Mailgun,Mailjet,Plunk,Postmark,Resend,SendGrid,Shipmail,Smaily,SparkPost,Tinyemail. Kind names match PostHog's live/api/wizard/tool_catalog/.reportCodebaseScan, the one place a scan is cleared to leave the machine, sets both properties withanalytics.setPersonPropertieswhen it shares the scan: sharing granted, telemetry on, logged in with a known user, and the scan did not fail. A login without a user (a signup whose user read failed, or an API key withoutuser:read) has no person to set them on, so it sends nothing. The scan-share latch keeps it to once per run. Login identifies the user first, so the$setlands on the logged-in person. A scan with no email provider sends nothing, so the person keeps what an earlier run found.Analytics.setPersonPropertiessends posthog-node's$setevent on the run's identified id.askForProvisioningSignup(src/tui/auth/project-data.ts) reads the new account's user with the provisioned token, which already holdsuser:read, identifies it, and returns it as the login's user. Before, a signup run never identified anyone, so every event and the$setstayed on an anonymous person. A failed read is captured withcaptureExceptionand the signup continues unidentified.Test plan
Lane gate on
7e96c5d:pnpm typecheckgreen, prettier and eslint clean on the changed files, and the tests of every touched module (codebase-scan,detection,shared/utils,tui/auth, the integration, warehouse, self-driving programs and the program runner) green. Full gate on7e96c5d:pnpm lint(0 errors) andpnpm test(build plus the whole suite) green locally. CI: the Wiz scans pass; Build & Test, Semgrep and the commit check wait for a maintainer to approve workflows for this fork PR.Test seams:
reportCodebaseScan(store)on a CI session after a real scan of a temp project against the fixture catalog, with analytics mocked at@utils/analytics: a Resend + Stripe project, reported twice after login, sets["Resend"]and the scan time once; a Stripe-only project, a declined-sharing session, and a login without a user set nothing.Analyticsover a mockedposthog-nodeclient: afteridentifyUser,setPersonPropertiessets the properties on the identified id.getOrAskForProjectData({ signup: true })with provisioning and the API mocked: a successful signup identifies the new account and returns it as the login's user; a failed user read still returns the signed-up credentials, with no user.Proofs per qa-swarm
PROOF.md:7e96c5d), two runs of the real code with a fetch preload that logged each analytics request and answered it locally, so nothing reached the real project:logInwith the TUI's OAuth provider on a--signupsession, over real HTTP to a local server that answers the provisioning API and/api/users/@me/and serves the live tool catalog. Analytics sent$identifyon the new account's id, then$create_alias, then one$setwith["Resend"]on that id.reportCodebaseScan,SessionStoreandAnalyticsscanning a Next.js app with theresendpackage. A report before login sent nothing about the person; after login, three reports sent exactly one$seton the logged-in id.$setis a plain person update on the identified id, with no merge involved.Captured requests, signup live run on 7e96c5d (trimmed)
LLM context
Built by Claude Code (Opus 5.5) from a handoff in Michael's Workflows onboarding thread.
--signupruns identify the new account?wizard_detected_services?$seton the pre-loginwarehouse sources detectedevent, which only the interactive integration flow sends.$set, so the person keeps what an earlier run found.Involvement: no grilling rounds, no prototypes, a design pass, a cross-family review, a QA swarm panel (7 lenses across GPT-6.1 Sol and Opus 5.5, including the author's Team perspective) a narrow second round on its fixes, and two final reads, live-run proof captured.
🤖 Generated with Claude Code