Skip to content

feat(tasks): replace turn_complete thread writeback with pr_created artifact messages#72857

Merged
k11kirky merged 5 commits into
masterfrom
posthog-code/thread-pr-created-artifacts
Jul 23, 2026
Merged

feat(tasks): replace turn_complete thread writeback with pr_created artifact messages#72857
k11kirky merged 5 commits into
masterfrom
posthog-code/thread-pr-created-artifacts

Conversation

@k11kirky

Copy link
Copy Markdown
Contributor

Problem

Task threads (the PostHog Code thread panel) mixed agent turn writebacks with human conversation. Threads should be a human-to-human surface, with the agent represented by the artifacts it produced. Canvases already announce themselves (canvas_created), but pull requests never did — and every background turn ended with a turn_complete agent message in the thread.

Changes

  • Removed post_turn_complete_thread_update and its call from the sandbox event relay (plus the now-dead final-message tracking in the relay loop). Background runs no longer write the agent's closing message into the thread.
  • list_thread_messages excludes legacy turn_complete rows so previously written turn messages don't resurface in clients.
  • New post_pr_created_thread_update: when a run's PR URL is recorded, an agent artifact message (event="pr_created", payload.pr_url, content [owner/repo#N](url) has been opened) lands in the task thread. Called from the run output paths (set_task_run_output, update_task_run) and the GitHub webhook backstop (_record_run_pr_url), deduped per PR URL via the task's existing pr_created rows. Same feature-flag and channel guards as the other agent thread updates.

The client side (rendering pr_created/canvas_created as artifact rows and dropping agent turn/prompt rows) is PostHog/code#3694.

How did you test this code?

Red/green: rewrote products/tasks/backend/tests/test_thread_updates.py first (failing on the missing function), then implemented. Tests I (Claude) actually ran locally, all green:

  • test_thread_updates (13 tests): pr_created content/payload, per-URL dedupe, distinct-PR handling, flag/channel/creator skip guards, canvas_created regression, turn_complete exclusion from listing
  • test_channels_api + test_webhooks (100 tests)
  • test_facade
  • test_relay_sandbox_events (53 passed; one pre-existing test errored in my sandbox because the persons-DB sqlx fixture isn't available there — unrelated to this diff)
  • ruff check / ruff format clean

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

🤖 Agent context

Autonomy: Fully autonomous

Authored by Claude (PostHog Code cloud task) together with the paired client PR. Followed red-green testing: wrote the failing tests before each implementation change. Chose DB-backed dedupe (existing pr_created rows per URL) over a Redis cooldown since the agent-output path and webhook backstop can fire arbitrarily far apart.


Created with PostHog Code

@github-actions

Copy link
Copy Markdown
Contributor

Hey @k11kirky! 👋

It looks like your git author email on this PR isn't your @posthog.com address (k11kirky@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@k11kirky
k11kirky marked this pull request as ready for review July 22, 2026 15:00
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 22, 2026 15:01
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
products/tasks/backend/facade/api.py:5501-5506
**PR Deduplication Races**

The agent-output path and GitHub webhook can both pass this `exists()` check before either creates its message. Because there is no matching database uniqueness constraint or lock around the check-and-create sequence, the same PR can appear twice in the task thread.

### Issue 2 of 2
products/tasks/backend/facade/api.py:5261-5263
**Legacy Mentions Target Hidden Messages**

Legacy `turn_complete` messages created mention records for task creators, but this filter only hides the messages from the thread API. Those records remain in the separate mentions feed, so opening an existing notification leads to a thread where the referenced message is missing.

Reviews (1): Last reviewed commit: "feat(tasks): replace turn_complete threa..." | Re-trigger Greptile

Comment thread products/tasks/backend/facade/api.py Outdated
Comment thread products/tasks/backend/facade/api.py
Comment thread products/tasks/backend/facade/api.py Outdated
@veria-ai

veria-ai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 2 · PR risk: 0/10

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

Could we ensure the announcement even when pr_url is already populated? _record_run_output_field returns False and webhook retries can never repair the missing artifact. It would be safer to idempotently ensure the artifact whenever the persisted URL matches this webhooks one.

Agree also on greptile + veria points, thanks for this!

Comment thread products/tasks/backend/facade/api.py Outdated
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Backend coverage — 98.0% of changed backend lines covered — 2 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ████████████████████ 98.0% (120 / 122)

File Patch Uncovered changed lines
products/tasks/backend/facade/api.py 94.4% 5360, 5405

🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 30046846386 -n patch-coverage), or the coverage-data block at the end of this comment.

Per-product line coverage (touched products)
Product Coverage Lines
demo ███████████░░░░░░░░░ 56.2% 1,497 / 2,663
tasks ██████████████░░░░░░ 69.4% 30,037 / 43,278
signals ████████████████░░░░ 79.9% 21,906 / 27,415
cdp ████████████████░░░░ 81.0% 3,144 / 3,881
data_modeling █████████████████░░░ 82.7% 5,547 / 6,708
notebooks █████████████████░░░ 85.3% 7,275 / 8,531
agent_platform █████████████████░░░ 86.4% 3,807 / 4,405
actions █████████████████░░░ 86.6% 717 / 828
cohorts ██████████████████░░ 87.8% 4,488 / 5,114
product_tours ██████████████████░░ 87.9% 1,303 / 1,482
exports ██████████████████░░ 88.4% 6,949 / 7,861
data_warehouse ██████████████████░░ 88.9% 11,887 / 13,378
conversations ██████████████████░░ 89.3% 16,834 / 18,848
engineering_analytics ██████████████████░░ 89.4% 6,386 / 7,145
dashboards ██████████████████░░ 89.4% 5,983 / 6,693
error_tracking ██████████████████░░ 89.7% 10,174 / 11,342
alerts ██████████████████░░ 89.9% 4,054 / 4,508
early_access_features ██████████████████░░ 90.1% 1,031 / 1,144
mcp_analytics ██████████████████░░ 90.1% 2,763 / 3,065
streamlit_apps ██████████████████░░ 90.4% 2,501 / 2,767
slack_app ██████████████████░░ 90.7% 9,028 / 9,951
marketing_analytics ██████████████████░░ 91.0% 11,792 / 12,964
stamphog ██████████████████░░ 91.1% 4,056 / 4,450
product_analytics ███████████████████░ 92.7% 5,811 / 6,268
ai_observability ███████████████████░ 92.7% 14,995 / 16,168
surveys ███████████████████░ 93.0% 5,730 / 6,163
web_analytics ███████████████████░ 93.1% 14,398 / 15,461
posthog_ai ███████████████████░ 93.2% 1,326 / 1,422
approvals ███████████████████░ 93.3% 3,437 / 3,682
reminders ███████████████████░ 93.4% 468 / 501
workflows ███████████████████░ 93.6% 6,390 / 6,826
endpoints ███████████████████░ 94.1% 8,640 / 9,177
revenue_analytics ███████████████████░ 94.6% 3,651 / 3,858
review_hog ███████████████████░ 94.7% 6,814 / 7,199
skills ███████████████████░ 94.7% 3,086 / 3,258
logs ███████████████████░ 95.4% 9,935 / 10,416
experiments ███████████████████░ 95.7% 25,036 / 26,159
replay_vision ███████████████████░ 96.2% 15,170 / 15,774
annotations ███████████████████░ 96.2% 732 / 761
feature_flags ███████████████████░ 96.5% 17,110 / 17,734
user_interviews ███████████████████░ 96.5% 2,638 / 2,734
customer_analytics ███████████████████░ 97.1% 9,047 / 9,317
warehouse_sources ███████████████████░ 97.1% 330,211 / 339,939
data_catalog ███████████████████░ 97.4% 2,367 / 2,429
pulse ████████████████████ 98.4% 2,017 / 2,049

Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.

@k11kirky
k11kirky enabled auto-merge (squash) July 23, 2026 08:12
auto-merge was automatically disabled July 23, 2026 08:43

Pull Request is not mergeable

@k11kirky
k11kirky force-pushed the posthog-code/thread-pr-created-artifacts branch from 7b6a642 to 0903d32 Compare July 23, 2026 17:56
@k11kirky
k11kirky enabled auto-merge (squash) July 23, 2026 18:10
@posthog-bot-comment-resolver

posthog-bot-comment-resolver Bot commented Jul 23, 2026

Copy link
Copy Markdown

🔀 Tried to auto-resolve conflicts with master but this one needs a human.

I won't retry until the branch or master moves.

k11kirky added 4 commits July 23, 2026 22:31
…rtifact messages

Task threads become a human-to-human surface with artifact announcements. The sandbox event relay no longer posts the agent's closing turn message into the thread, legacy turn_complete rows are excluded from the thread listing, and a pr_created agent message (deduped per PR URL) is now emitted when a run's pull request is recorded — from the agent-output paths and the GitHub webhook backstop — joining the existing canvas_created announcement.

Generated-By: PostHog Code
Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
…unsafe URLs

Address review findings: lock the task row so the agent-output path and webhook backstop can't both pass the pr_created dedupe check, reject pr_url values that aren't plain http(s) URLs before embedding them in the markdown message, and exclude legacy turn_complete mention rows from the mentions feed now that their messages are hidden from threads.

Generated-By: PostHog Code
Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
Every task has a thread panel, so PR artifact announcements no longer require the task to be filed in a channel (canvas_created already behaved this way). Each remaining skip path (unsafe URL, missing creator, flag off) now logs its reason so a missing announcement is diagnosable. Adds end-to-end tests through update_task_run and set_task_run_output — the paths the agent actually uses to attach a PR.

Generated-By: PostHog Code
Task-Id: 4ca58c61-95e3-4b36-a0df-474345b61483
Generated-By: PostHog Code
Task-Id: 3afd10d7-2202-4615-b3c8-43d7373766b4
@k11kirky
k11kirky force-pushed the posthog-code/thread-pr-created-artifacts branch from 035b802 to 3049ff4 Compare July 23, 2026 21:31
@tests-posthog
tests-posthog Bot disabled auto-merge July 23, 2026 21:36
@k11kirky
k11kirky merged commit 1e83c40 into master Jul 23, 2026
243 checks passed
@k11kirky
k11kirky deleted the posthog-code/thread-pr-created-artifacts branch July 23, 2026 22:13
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-23 22:52 UTC Run
prod-us ✅ Deployed 2026-07-23 23:08 UTC Run
prod-eu ✅ Deployed 2026-07-23 23:08 UTC Run

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.

2 participants