The tree was a debranded snapshot of upstream taken around 2026-02-20, and upstream has moved about five months since. This replaces it with upstream master, mechanically re-derived: bin/debrand does the rename, and the pipeline and squashed migrations are restored from the shipped tree. Not a merge. The previous import replaced the tree wholesale in a single commit, so there is no shared content history to merge against. Reproducing the rename on the new tree is what actually converges. What survives: .hanzo/workflows, the Dockerfiles and bin/docker* entrypoints, compose files, LLM.md, and insights/migrations. The squashed initial migration is load-bearing — the live database records it by name, so upstream's ~918 individual migrations cannot come back. Nine products are dropped as unreferenced. Twenty-one more that we do not run are kept anyway because the core app still imports them; unpicking those is a refactor and does not belong in a rebase. This base does not build yet, and the reasons are not in the rename: upstream now wants Python 3.13.13 against our 3.12.12 and Django 5.2 against our 4.2, and the dependency manifests still name upstream packages that we republish under our own names. Those are decisions, not renames.
12 KiB
Tasks Backend Instrumentation
All analytics events tracked from the tasks backend via hanzo_insights.capture().
All events include group analytics via groups() from insights.event_usage, which sets instance, organization, customer, and project groups where available.
Standard Properties
Task events
All events captured via Task.capture_event() automatically include:
| Property | Type | Description |
|---|---|---|
task_id |
str |
UUID of the task |
team_id |
int |
Team ID |
title |
str |
Task title |
description |
str |
Task description (truncated to 500 chars) |
origin_product |
str |
Origin product enum value |
repository |
str? |
Repository in org/repo format (nullable) |
TaskRun events
All events captured via TaskRun.capture_event() automatically include:
| Property | Type | Description |
|---|---|---|
task_id |
str |
UUID of the task |
run_id |
str |
UUID of the run |
team_id |
int |
Team ID |
repository |
str? |
Repository in org/repo format (nullable) |
loop_id |
str? |
UUID of the loop that spawned this run, from run state (nullable) |
loop_trigger_id |
str? |
UUID of the loop trigger that fired this run, from run state (nullable) |
environment |
str |
cloud or local (defaults to cloud) |
mode |
str |
Execution mode (e.g. background) |
Task Model Events
Source: products/tasks/backend/models.py
task_created
Tracked when a new Task is saved. Additional properties:
| Property | Type | Description |
|---|---|---|
has_json_schema |
bool |
Whether a JSON schema is attached |
task_run_created
Tracked when Task.create_run() is called. Additional properties:
| Property | Type | Description |
|---|---|---|
run_id |
str |
UUID of the created run |
mode |
str |
Execution mode |
environment |
str |
cloud or local |
is_resume |
bool |
Whether this resumes a previous run |
has_pending_message |
bool |
Whether there's a pending message |
task_deleted
Tracked when Task.soft_delete() is called. Additional properties:
| Property | Type | Description |
|---|---|---|
duration_seconds |
float |
Seconds since task creation |
TaskRun Model Events
Source: products/tasks/backend/models.py
task_run_completed
Tracked when TaskRun.mark_completed() is called. Additional properties:
| Property | Type | Description |
|---|---|---|
duration_seconds |
float |
Time from creation to completion |
task_run_failed
Captured exactly once per failed run, by whichever component performs the DB transition to FAILED:
TaskRun.mark_failed() (janitor sweeps via the facade), the update_task_run_status Temporal activity (workflow failures), the facade run PATCH path (agent-reported failures), or _terminalize_unstarted_task_run (workflow dispatch failures).
Additional properties:
| Property | Type | Description |
|---|---|---|
error_type |
str |
Stable failure source: exception class name (workflow failures), agent_reported, stale_queued_cleanup, workflow_start_failed, followup_delivery_failed, stale_run_reaped; unspecified when unknown |
error_message |
str |
Error message (truncated to the last 500 chars — the root cause sits at the tail) |
duration_seconds |
float |
Time from creation to failure |
Loop Fire Metrics
Source: products/tasks/backend/metrics.py, emitted from products/tasks/backend/logic/services/loop_runs.py::fire_loop.
Prometheus counters (not hanzo_insights.capture() events):
| Metric | Labels | Description |
|---|---|---|
insights_tasks_loop_fire_total |
reason |
One increment per fire_loop() call, labeled with the LoopFireResult.reason outcome (created, deduped, overlap_skipped, rate_capped, disabled, gate_blocked) |
insights_tasks_loop_auto_paused_total |
(none) | One increment each time a loop is auto-paused after consecutive_failures reaches the threshold |
fire_loop() also logs loop_fire_created (standard Python logger, not analytics) with loop_id, loop_trigger_id, task_id, task_run_id and actor_id on every successful fire.
Workflow Events
Source: products/tasks/backend/temporal/process_task/workflow.py
These events are tracked via _track_workflow_event() which calls the track_workflow_event Temporal activity. All workflow events include organization and project group analytics and are enriched with Temporal context properties (see Temporal Context).
task_run_started
Tracked when the workflow begins execution.
| Property | Type | Description |
|---|---|---|
run_id |
str |
UUID of the run |
task_id |
str |
UUID of the task |
repository |
str |
Repository in org/repo format |
team_id |
int |
Team ID |
sandbox_started
Tracked after sandbox and agent server are provisioned.
| Property | Type | Description |
|---|---|---|
run_id |
str |
UUID of the run |
task_id |
str |
UUID of the task |
sandbox_id |
str |
Sandbox identifier |
sandbox_url |
str |
URL of the sandbox |
used_snapshot |
bool |
Whether a snapshot was used |
repository |
str |
Repository in org/repo format |
task_run_cancelled
Tracked when the workflow is cancelled via CancelledError.
| Property | Type | Description |
|---|---|---|
run_id |
str |
UUID of the run |
task_id |
str |
UUID of the task |
repository |
str |
Repository in org/repo format |
team_id |
int |
Team ID |
task_run_failed (workflow, metrics only)
Recorded when the workflow fails with an exception — not captured as an analytics event (the update_task_run_status activity owns the analytics capture on the DB transition, see above).
The workflow emission feeds the insights_tasks_task_run_failed_total Prometheus counter and structured logging with these properties:
| Property | Type | Description |
|---|---|---|
run_id |
str |
UUID of the run |
task_id |
str |
UUID of the task |
error_type |
str |
Exception class name |
error_message |
str |
Error message (truncated to last 500 chars) |
sandbox_id |
str |
Sandbox identifier (if available) |
Webhook Events
Source: products/tasks/backend/webhooks.py
These events use TaskRun.capture_event() so include all TaskRun standard properties.
pr_created
Tracked when a GitHub pull_request.opened webhook is received. Additional properties:
| Property | Type | Description |
|---|---|---|
pr_url |
str |
GitHub PR URL |
pr_merged
Tracked when a GitHub pull_request.closed webhook is received with merged=true. Same additional properties as pr_created.
pr_closed
Tracked when a GitHub pull_request.closed webhook is received with merged=false. Same additional properties as pr_created.
API Events
Source: products/tasks/backend/api.py
code_invite_redeemed
Tracked when a user redeems a Desktop invite. Includes organization group analytics. No additional properties.
Activity Observability Events
Source: products/tasks/backend/temporal/observability.py
These events are tracked via log_activity_execution() context manager and are enriched with Temporal context properties. Groups can be passed through to track_event().
process_task_activity_started
| Property | Type | Description |
|---|---|---|
activity_name |
str |
Name of the activity |
...context |
Any |
Additional context kwargs passed to log_activity_execution() |
process_task_activity_completed
Same properties as process_task_activity_started.
process_task_activity_failed
| Property | Type | Description |
|---|---|---|
activity_name |
str |
Name of the activity |
error_type |
str |
Exception class name |
error_message |
str |
Error message (truncated to 500 chars) |
...context |
Any |
Additional context kwargs passed to log_activity_execution() |
Temporal Context Enrichment
Events tracked from Temporal activities or workflows are automatically enriched with context properties by track_event() in observability.py:
When in an activity:
| Property | Type |
|---|---|
temporal_activity_id |
str |
temporal_activity_type |
str |
temporal_workflow_id |
str |
temporal_workflow_run_id |
str |
temporal_attempt |
int |
When in a workflow (non-replay):
| Property | Type |
|---|---|
temporal_workflow_id |
str |
temporal_workflow_run_id |
str |
temporal_workflow_type |
str |