Skip to content

feat(signals): link Slack-mention tasks in report notification threads to the report #103041

Description

@andrewm4894

Problem

Signals posts inbox report notifications to Slack and invites the reader to "reply in this thread and mention @PostHog". Doing so creates a Code task, but that task has no link to the report:

  • posthog/temporal/ai/slack_app/activities/task_creation.py creates it with origin_product=SLACK and no signal_report_id.
  • Nothing writes a task_run artefact, so the task never appears in the report's Runs section in the inbox (that section reads the artefact log, see products/signals/frontend/inbox/logics/inboxReportDetailLogic.ts around reportTasks). The in-app "Ask AI" discussion does appear there because POST /tasks with origin_product=signal_report calls record_report_task(relationship="discussion").
  • No engagement is recorded either: no Inbox report action event, no SignalReportAction row, no task/report association. A Slack conversation about a report is invisible to the scout inactivity sweep (scout_harness/inactivity.py, which already exempts Slack-routed scouts for this reason) and to the report lifecycle dashboards.

Even when the Slack agent changes the report's state (dismiss/resolve), only the dismissal artefact and a signal_report_status_changed event land. The task_run link is still missing.

Example: a report was resolved through a Slack mention today. The report shows status=resolved with no linked task and no recorded action; the task shows no report.

What we need

1. Resolve the report id at mention time

Both report notification paths put the report URL in a "View report in PostHog" button:

  • products/signals/backend/slack_inbox_notifications.py (_build_message_blocks, url /project/<team>/inbox/reports/<uuid>)
  • products/signals/backend/scout_harness/slack_delivery.py (scout emissions, url /project/<team>/inbox/<uuid>)

Neither persists thread_ts, so the mention handler cannot look the report up. Options, in order of preference:

  • a. Persist a (integration, channel, thread_ts) -> report_id mapping when the notification is posted (chat_postMessage returns ts). Cleanest and survives message edits.
  • b. Parse the parent message's button URL from the thread messages the mention workflow already fetches. No schema change, but couples the handler to the URL shape.

Should also work for the evidence replies the notification posts into the same thread (they share thread_ts).

2. Link the task to the report

In task_creation.py, when the thread resolves to a report:

  • pass signal_report_id to tasks_facade.create_and_run_task (it already accepts it), so Task.signal_report_id is set and the task joins the report in analytics;
  • call products.signals.backend.task_run_artefacts.record_report_task(relationship=TASK_RUN_TYPE_DISCUSSION, run_id=...) inside the same transaction, so the task shows in the report's Runs section as "Discussion", like Ask AI. create_and_run_task does not do this itself; only the create_task REST path does.

Decisions:

  • Keep origin_product=SLACK? The Slack relay (SlackThreadTaskMapping, follow-up forwarding) keys on it, and the discussion-note forward (_forward_signals_discussion_note) and the repo-less "exempt" task shape key on SIGNAL_REPORT. Proposal: keep SLACK, write the artefact explicitly, and forward the discussion note (forward_report_discussion_note) from the Slack path too so the report's scout sees the question.
  • Does a Slack discussion count toward the report task cap (enforce_report_task_cap)? Proposal: yes, same as Ask AI.
  • Should the task file into the report's channel rather than the mentioning user's personal channel?

3. Record engagement

Once the task is linked, the discussion should count as report engagement the same way Ask AI does. Either:

  • fire a server-side Inbox report action event with action_type=discuss and surface=slack from the handler (matches the frontend contract in products/signals/frontend/inbox/inboxAnalytics.ts, needs report_id and the mentioning user's identity), or
  • treat a user-attributed task_run artefact of type discussion as engagement in the sweep and dashboards.

The first keeps one event family for all surfaces and is probably the smaller change.

4. Related: user-requested pr_merged resolutions read as automatic

When the Slack agent resolves a report at a person's request, it picks reason=pr_merged. The dismissal artefact carries user_id/user_uuid, but consumers that exclude pr_merged as an automatic transition drop it. The identity fields distinguish the two cases; the exclusion should only apply when no user identity is present. Can ship separately.

Out of scope

  • The legacy "Dismiss" button handler (products/slack_app/backend/api.py, _handle_signals_dismiss_report) already attributes its artefact to the user and is unaffected.
  • Reactions on agent replies are turn-level feedback, not report engagement.

Verification

  • Mention @PostHog in a report notification thread and ask a question. The task appears under the report's Runs section as "Discussion", Task.signal_report_id is set, and the report shows a discuss action from surface=slack.
  • Ask the agent to resolve the report from the thread. The report resolves, the task is linked, and the resolution counts as user engagement.
  • A mention in a thread that is not a report notification still creates a plain Slack task with no report link.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions