Repository navigation
feat(workflows): report every committed workflow creation - #127193
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A data suggestion saved by a Celery task creates its workflow inside the worker, where the global analytics client can lose queued events when the child exits. Capture through the scoped client, which flushes on exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g/creation-event Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
😎 Merged successfully - details. |
🤖 CI report
|
| 🔑 Login | test@posthog.com / 12345678 (demo data) |
| 🧩 Running | this PR's backend on the PostHog :master base (frontend unchanged by this PR) |
| 🔗 Link | stable across rebuilds: a re-push swaps the box underneath, the URL stays |
| 🔒 Access | tailnet only (PostHog VPN) |
| 🛠️ Admin | inspect & debug state in hogland |
| 💤 Idle | sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen |
commit c1b101c · box box-7b254b842218 · ready in 2159s (push → usable) · build log · rebuilds on every push, torn down on close
There was a problem hiding this comment.
PostHog Review · Standard · reviewed fd4aa91: 1 Should fix.
This is the only automatic review while this pull request is a draft. Comment @posthog review to review new changes sooner. Otherwise, a review of the new changes runs when you mark it ready for review.
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.
HostHog preview —
|
ph_scoped_capture swallowed SDK upload errors by default, so a lost creation event left no log with its workflow. Raise them at exit into the existing handler. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The on_commit callback ran ph_scoped_capture in the request, and its shutdown() waits through upload retries, so a stalled analytics ingest held a committed workflow's create response. The callback now only enqueues report_workflow_created; a failed enqueue is logged and never fails the create. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… stable uuid A queued task would otherwise record its run time, which can move a creation into the next month, and a replayed task would count the creation twice. The task now sends the workflow's created_at as the event timestamp and a uuid5 of the workflow id as the event uuid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael Decisions from the review rounds on this PR:
|
|
Risk: No findings The change since the last review adds bounded autoretry (5 attempts, 60–600s backoff, Team.DoesNotExist excluded) to the internal Sentinel reviewed |
When analytics ingestion stayed down past the SDK's own retries, the task failed once and the committed creation never reached the metrics. It now retries up to five times with jittered exponential backoff; the stable event uuid and creation timestamp keep each retry idempotent. A missing team still fails at once. 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.
Approved.
The write-path changes have independent assurance from the owning-team author and a clean current-head review. No outstanding substantive concerns or policy refusal grounds were identified.
- 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 | ✓ | 66L, 2F substantive, 260L/4F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1c-medium (260L, 4F, single-area, feat) |
| stamphog 2.7.0 | .stamphog/policy.yml @ c1b101c · reviewed head c1b101c |
|
/trunk merge |
Problem
hog_flow_created. Only the API create view and premade data-suggestion saves (#119724) emit it.hog_flow_created; the counts stay in private proof storage.Impact
Closes a gap in two Grow Workflows leading metrics: Started orgs (organizations whose first workflow creation falls in the month) and activation rate (the share of started orgs whose first billed action comes within 30 days of that creation). Both are defined on the first
hog_flow_created, so an organization whose first workflow came from a transactional email workflow or an accepted data-suggestion draft is counted late or never. Once these metrics readworkflows workflow created, they count every creation path. Expected move: no change in product usage; Started orgs stops undercounting, and activation rate is measured from the real first creation.Merge Danger
Warning
🟡 Merge risk: medium · two-way door (merge-risk rubric)
try/exceptbehindon_commit, so it never fails or rolls back a creation, and the upload no longer runs in the request. A failed upload retries up to five times with backoff; the stable event uuid and creation timestamp keep a retry from counting twice. During the deploy, a new web pod can enqueue the task before an old worker knows it; those few events are lost, and nothing else breaks.git revertthe merge commit. Events already sent stay sent and are correct records.Changes
workflows workflow created, whatever path created it.workflow_id,origin_product,actions_count. The event carries the project and organization groups.workflows workflow created; keephog_flow_createdfor user and channel attribution.HogFlowpost_savereceiver enqueues thereport_workflow_createdCelery task withtransaction.on_commiton the signal's own connection. The request never touches the analytics client.created_atas its timestamp and a uuid5 of the workflow id as its uuid, so a delayed task keeps the creation in its month and a replayed task does not count it twice.ph_scoped_capture, which flushes on exit. The global client can lose events in a Celery worker (AGENTS.md forbids it there), and the generated data-suggestion save runs in one.region: E2Eto the US project, so per-team counts should filterregiontoUSandEU.USorEU) as itsregionproperty, like events from the global client.raise_on_error=True, so an upload error the SDK would otherwise drop with its own log line reaches Celery. The task retries it up to five times with jittered exponential backoff (60 s base, 600 s cap), like the neighbouring SES tasks, and then fails where Celery records it. A missing team fails at once, without retries.Recreates #115349 from a branch in this repository so CI can run; before that Silthus/posthog#358 and #111727 (closed).
How did you test this code?
Test rationale: two seams.
TestHogFlowinproducts/workflows/backend/test/test_hog_flow.py): a creation enqueues the task exactly once, after commit, with the values at creation time, and never builds an analytics client in the request; a failed enqueue is logged and the workflow still exists; a rolled-back creation enqueues nothing.products/workflows/backend/test/test_report_workflow_created.py): the event goes out through the scoped client with the instance region, creation timestamp, groups and properties; a replay sends the same event uuid; a failed upload is retried and the retry delivers the same event; an upload that keeps failing stops after five retries; a missing team fails after one attempt. The upload cases drive the realph_scoped_captureand the task's real Celery retry config throughapply(), with only the SDK client faked.The new tests failed before each change: the task tests before the task existed, and the two retry tests before the retry config. The tests patch
ph_scoped_captureor the task'sdelay, as the repo's other callers do.Live run at
c1b101c(this PR's head), through the real DRF API with a logged-in client on a non-atomic private test database, so every request commits andon_commitfires as in production.posthog.ph_client.is_cloudwas forced toTrueandPosthog.capturewas replaced by a recorder, so nothing reached PostHog Cloud. Test settings run Celery eagerly, so the enqueued task ran in the same process; the recorder checked that each capture ran insidereport_workflow_created:workflows workflow createdeventsPATCHa workflow written before the runPOSTa new workflow (origin_product: broadcasts, one action)PATCHthe new workflowBoth events came from the task, carried the team's UUID as
distinct_id, the project and organization groups, the right properties, the workflow'screated_atastimestampand a uuid5 of the workflow id. They went to the scoped client forus.i.posthog.comwithregion: US; the global client saw no creation event.Lane gate on
c1b101c:ruff check,ruff format --check,ty check,lint-imports,test_hog_flow.pyandtest_report_workflow_created.py(14 passed), the repo guard tests inposthog/test/repo_invariants(289 passed), repo-widemypy, andhogli ci:preflight --strict, all exit 0.Proofs owed, per the agent proof ledger:
c1b101c.c1b101c, a read-only read ofposthog_hogflowjoined tohog_flow_createdshowed which creation paths lack the event. The counts stay private.Gaps:
Release status
Docs update
None. No existing doc covers Workflows analytics events.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: T3 Code with Claude Code, Claude Opus 5.5 (
claude-opus-5-5). An earlier Codex worker (GPT-6.1 Sol) recreated the change test-first before its session dropped.report_workflow_createdCelery task enqueued fromon_commit, sending throughph_scoped_capture; replaces capturing inside the request'son_commitcallback, which held the create response (PostHog Review P2)hog_flow_createdto every path?hog_flow_createdstays for user and channel attributioncreated_atas timestamp and a uuid5 of the workflow id as uuid, so delay keeps the month and replay dedupesInvolvement: merged master on 2026-11-02 three times with no conflicts; two QA panel rounds and two final reads on the fork PR; on this PR one review round (GPT-6.1 Sol: upload failures fixed, metric and alert declined) and four final reads (creation timestamp and replay-safe uuid fixed; two findings in master-only files rejected; the last two found nothing); two PostHog Review P2 threads fixed, answered and resolved (send moved into a Celery task; bounded retries); live run and production-shape read captured at the head.
modernize-pr,qa-swarm,tdd,babysit-pr,merge-risk,pr-description,writing-voice.🤖 Generated with Claude Code