feat(sig): automatically start tasks from signal reports#54056
feat(sig): automatically start tasks from signal reports#54056oliverb123 wants to merge 11 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an “autonomy” workflow for Signals where agentic report research can automatically start a Tasks coding run (when actionable/priority/reviewer conditions are met) and stores the resulting task info as a report artefact.
Changes:
- Introduces
SignalAutonomyConfig(per-team) + API endpoints to manage the minimum priority threshold and opted-in users. - Extends agentic report processing to optionally auto-start a Tasks run and persist a
task_runreport artefact. - Adds
task_runas a newSignalReportArtefacttype and wires up admin + router registration.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| products/tasks/backend/models.py | Adds extra TaskRun metadata when the task originates from a signal report |
| products/signals/backend/views.py | Adds SignalAutonomyViewSet endpoints for threshold + opted-in users |
| products/signals/backend/temporal/agentic/report.py | Auto-starts Tasks runs after agentic research under specific conditions; writes task_run artefact |
| products/signals/backend/serializers.py | Adds serializers for autonomy config and opted-in users resolution |
| products/signals/backend/models.py | Adds SignalAutonomyConfig model and new artefact type TASK_RUN |
| products/signals/backend/migrations/max_migration.txt | Bumps max migration pointer |
| products/signals/backend/migrations/0014_signal_autonomy_config.py | Creates SignalAutonomyConfig table and adds task_run artefact type |
| products/signals/backend/admin.py | Registers admin UI for autonomy config |
| products/signals/ARCHITECTURE.md | Documents the auto-start flow and the autonomy config API |
| posthog/api/init.py | Registers the new signal_autonomy routes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Migration SQL ChangesHey 👋, we've detected some migrations on this PR. Here's the SQL output for each migration, make sure they make sense:
|
🔍 Migration Risk AnalysisWe've analyzed your migrations for potential risks. Summary: Run Summary: 1 Safe | 0 Needs Review | 0 Blocked ✅ SafeBrief or no lock, backwards compatible Last updated: 2026-04-15 17:14 UTC (6802d55) |
|
|
🎭 Playwright report · View test results →
These issues are not necessarily caused by your changes. |
Twixes
left a comment
There was a problem hiding this comment.
Direction is solid but a few comments from me + Josh I think worth clearing up!
| class SignalReportTaskSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = SignalReportTask | ||
| fields = ["id", "relationship", "task_id", "created_at"] | ||
| read_only_fields = fields |
There was a problem hiding this comment.
The serializer is missing task_title and task_status fields that are documented in ARCHITECTURE.md (line 605). The fields list only includes ["id", "relationship", "task_id", "created_at"] but according to the documentation, it should also expose task_title and task_status. This will cause the API to return incomplete data.
class SignalReportTaskSerializer(serializers.ModelSerializer):
task_title = serializers.CharField(source='task.title', read_only=True)
task_status = serializers.SerializerMethodField()
class Meta:
model = SignalReportTask
fields = ["id", "relationship", "task_id", "task_title", "task_status", "created_at"]
read_only_fields = fields
def get_task_status(self, obj):
# Derive from latest TaskRun via prefetch
return obj.task.latest_run.status if obj.task.latest_run else None| class SignalReportTaskSerializer(serializers.ModelSerializer): | |
| class Meta: | |
| model = SignalReportTask | |
| fields = ["id", "relationship", "task_id", "created_at"] | |
| read_only_fields = fields | |
| class SignalReportTaskSerializer(serializers.ModelSerializer): | |
| task_title = serializers.CharField(source='task.title', read_only=True) | |
| task_status = serializers.SerializerMethodField() | |
| class Meta: | |
| model = SignalReportTask | |
| fields = ["id", "relationship", "task_id", "task_title", "task_status", "created_at"] | |
| read_only_fields = fields | |
| def get_task_status(self, obj): | |
| # Derive from latest TaskRun via prefetch | |
| return obj.task.latest_run.status if obj.task.latest_run else None | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
|
Size Change: +210 B (0%) Total Size: 129 MB ℹ️ View Unchanged
|
| return Response(status=status.HTTP_404_NOT_FOUND) | ||
| return Response(SignalUserAutonomyConfigSerializer(config).data) | ||
|
|
||
| def post(self, request, user_id, **kwargs): |
There was a problem hiding this comment.
The method is named post but the ARCHITECTURE.md documentation (line 558) and REST conventions specify this should be a put method for idempotent create-or-update operations. This mismatch will cause 405 Method Not Allowed errors if clients follow the documented API contract and send PUT requests.
def put(self, request, user_id, **kwargs):| def post(self, request, user_id, **kwargs): | |
| def put(self, request, user_id, **kwargs): |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
|
⏭️ Skipped snapshot commit because branch advanced to The new commit will trigger its own snapshot update workflow. If you expected this workflow to succeed: This can happen due to concurrent commits. To get a fresh workflow run, either:
|
Query snapshots: Backend query snapshots updatedChanges: 1 snapshots (1 modified, 0 added, 0 deleted) What this means:
Next steps:
|
Automatically starts a task if:
Stores the associated task in the report artefacts.