Skip to content

feat(workflows): report every committed workflow creation - #111727

Closed
Silthus wants to merge 2 commits into
PostHog:masterfrom
Silthus:feat/workflows-activation-coverage
Closed

Silthus wants to merge 2 commits into
PostHog:masterfrom
Silthus:feat/workflows-activation-coverage

Conversation

@Silthus

@Silthus Silthus commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The Workflows team cannot build a team activation funnel from every saved workflow.

Note

Merge risk: low. Analytics runs after commit and contains failures; each creation adds one team lookup.

Changes

  • Workflows analysts can count each committed creation with the team event workflows workflow created.
  • The model hook also counts ordinary ORM creation outside HTTP requests.
  • Updates and rolled-back creations emit no creation event.
  • Analytics failures cannot fail workflow creation.
  • Independent PRs keep creation and external delivery separately reviewable from #111267.

The change affects analytics only. The UI stays the same.

Kind Files Lines
Production 1 +19 -0
Tests 1 +53 -0
Total 2 +72 -0

Before:

flowchart LR
    A[Create workflow] --> B[Persist workflow]
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class A phYellow;
    class B phGray;
Loading

After:

flowchart LR
    A[Create workflow] --> B[Persist workflow] --> C[Commit] --> D[Team creation event]
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
    class A,D phYellow;
    class B phGray;
    class C phBlue;
Loading

How did you test this code?

Test rationale: Model tests catch duplicate events, changed metadata, incorrect groups, rollback reporting and analytics failures.
The existing receiver tests cover worker reloads, so analytics needs assertions at the persisted-model seam.

Recorded local verification
.codex/with-flox hogli test products/workflows/backend/test/test_hog_flow.py -q
9 passed in 17.20s

Hosted backend CI needs maintainer approval. Live analytics delivery remains unchecked.

Release status

  • No feature flag controls this change
  • This change is behind a feature flag and is not available to users
  • This change makes a previously flagged feature available to everyone

Automatic notifications

  • Publish to changelog?

Docs update

No existing document covers these analytics events.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: T3 Code / Codex, GPT-6.1 Sol.

Skills: tdd, writing-tests, hogli, django-startup-time, writing-pr-descriptions, writing-voice, running-ci-preflight, reviewing-with-coderabbit, qa-swarm, merge-risk, unslop.

QA strengthened the metadata, group and failure tests. CodeRabbit's import finding prompted the module-level import.
Local CodeRabbit skipped review because its CLI was signed out.

@trunk-io

trunk-io Bot commented Oct 5, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

We couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting @coderabbitai full review.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 08e8dc38-b5e2-4cce-bd05-31c8080529eb
📥 Commits

Reviewing files that changed from the base of the PR and between 40f5547 and 1089e2f.

📒 Files selected for processing (1)
  • products/workflows/backend/models/hog_flow/hog_flow.py

Limit details: You’ve used all 12 included reviews currently available.


📝 Walkthrough

Walkthrough

When a HogFlow is created, the save signal schedules a team action report to run after the transaction commits. The report includes the workflow ID, origin product, and action count. Reporting errors are logged and suppressed. Tests cover deferred reporting, captured creation values, reporting failures, and rolled-back transactions.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 1089e

Workflow creation reporting is best-effort after commit. The repository’s configured and inspected runtime paths do not establish a non-default database trigger, so no actionable merge-blocking risk remains.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 1089e

The new reporting step uses the workflow’s team identity and sends limited metadata through the existing analytics path. Reporting failures do not undo saved workflows. Delivery remains best effort, and the reviewed path showed no expansion of access privileges.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The additional reporting path applies to individual HogFlow insertions that invoke the model signal, including direct ORM callers. Its demonstrated downstream effect is team-scoped telemetry through the existing analytics helper, rather than additional workflow execution or administrative authority.

Trust Boundaries and Controls

  • observed — Analytics identity comes from the workflow’s required Team relationship: the receiver captures instance.team_id, the helper retrieves that team, and the analytics contract derives identity and groups from the Team object. Event properties do not select a different analytics identity.

Resilience and Maintainability Implications

  • observed — Lookup or reporting exceptions are logged and suppressed after commit. The failure test confirms the workflow remains persisted when analytics raises, providing containment between persistence and the reporting dependency.

Hardening Proposals

  • proposed — Before enabling non-default database creation paths, define alias-aware callback registration and team lookup, with rollback and ownership tests for that routing. The current omission is not a demonstrated production exposure in the inspected routing and callers.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description covers the problem, user-visible changes, tests and their limits, release status, docs, and agent context. The release status uses checkboxes instead of the required single plain bulle…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • 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.

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 (1)
products/workflows/backend/models/hog_flow/hog_flow.py-242-242 (1)

242-242: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Bind workflow creation reporting to the save database.

When HogFlow is saved on a non-default database, this callback can run before that transaction commits and report a creation that later rolls back. The team lookup also uses the default database. Pass the signal’s using alias to both operations.

🐛 Suggested fix
-def report_workflow_created(team_id: int, workflow_id: str, origin_product: str | None, actions_count: int) -> None:
+def report_workflow_created(
+    team_id: int, workflow_id: str, origin_product: str | None, actions_count: int, using: str
+) -> None:
...
-        team = Team.objects.get(id=team_id)
+        team = Team.objects.using(using).get(id=team_id)
...
-def hog_flow_saved(sender, instance: HogFlow, created, update_fields=None, **kwargs):
+def hog_flow_saved(sender, instance: HogFlow, created, using, update_fields=None, **kwargs):
...
-        transaction.on_commit(lambda: report_workflow_created(team_id, workflow_id, origin_product, actions_count))
+        transaction.on_commit(
+            lambda: report_workflow_created(team_id, workflow_id, origin_product, actions_count, using),
+            using=using,
+        )

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 46566e06-7ce2-4161-8126-627be6b6c069
📥 Commits

Reviewing files that changed from the base of the PR and between 275fefb and acbc1d0.

📒 Files selected for processing (2)
  • products/workflows/backend/models/hog_flow/hog_flow.py
  • products/workflows/backend/test/test_hog_flow.py

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

@Silthus

Silthus commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 GPT-6.1 Sol responding on behalf of Michael

@coderabbitai No current workflow creation writes to an alternate database: ReplicaRouter.db_for_write returns default, and the only explicit workflow .using() calls are historical migration updates. There is no supported alternate writer for this callback to bind to; that would need revisiting if such a caller is added.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C3 --type py 'class ReplicaRouter\b|def db_for_write\b' .
ast-grep outline products/workflows/backend/models/hog_flow/hog_flow.py --match 'hog_flow_saved|report_workflow_created' --view expanded
rg -n -C3 --type py '\.using\s*\(' products/workflows

Length of output: 4700


🏁 Script executed:

#!/bin/bash
ast-grep outline posthog/dbrouter.py --match ReplicaRouter --view expanded
sed -n '30,42p' posthog/dbrouter.py
sed -n '215,270p' products/workflows/backend/models/hog_flow/hog_flow.py

Length of output: 3512


@Silthus I withdraw the alternate-database finding. No change is needed for the current write paths. If an alternate workflow writer is added, bind transaction.on_commit to the signal’s using alias.

Thanks for the clarification.


✏️ Learnings added
Learnt from: Silthus
URL: https://github.com/PostHog/posthog/pull/111727

Timestamp: 2026-10-05T09:47:56.954Z
Learning: In PostHog, current workflow creation writes use the default database. ReplicaRouter.db_for_write in posthog/dbrouter.py returns "default"; explicit HogFlow.objects.using() calls under products/workflows are historical migration updates, not supported alternate creation paths. Do not require alternate-database handling for hog_flow_saved in products/workflows/backend/models/hog_flow/hog_flow.py based solely on hypothetical writers. Revisit the transaction.on_commit database alias if an alternate workflow creation writer is introduced.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@Silthus
Silthus marked this pull request as ready for review October 5, 2026 17:52
@Silthus
Silthus requested a review from a team as a code owner October 5, 2026 17:52
@parameterai

parameterai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Risk: No findings

This increment adds a capability-gated Kafka replay worker that rebuilds and re-queues invocations from the internal DLQ topic, refactors the workflow-proposal views onto team-scoped facade functions, and adds a post-commit analytics event on workflow creation. I traced every read and write path in the refactor and the replay worker and found no new security issues: proposal lookups, locks, and resolves all filter on team_id, and the replay worker routes customer bytes through the same masking, quota, and team-resolution guards as normal pipeline processing.

Sentinel reviewed 7dbc048 · Review settings

@Silthus
Silthus force-pushed the feat/workflows-activation-coverage branch from 8eea816 to 7dbc048 Compare October 7, 2026 11:34
@Silthus

Silthus commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 GPT-6.1 Sol responding on behalf of Michael

Replaced by the draft fork PR #358 in its native fork stack. @meikelmosby will start migrating the stack from the fork into PostHog/posthog for upstream review and CI. Closing this master-targeted copy to keep the handoff clear.

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