| 208 | } |
| 209 | |
| 210 | func detectTaskDomain(processedRun ProcessedRun, createdItems []CreatedItemReport, toolUsage []ToolUsageInfo, awContext *AwContext) *TaskDomainInfo { |
| 211 | auditAgenticLog.Printf("Detecting task domain for run: workflow=%s event=%s", processedRun.Run.WorkflowName, processedRun.Run.Event) |
| 212 | combined := strings.ToLower(strings.Join([]string{ |
| 213 | processedRun.Run.WorkflowName, |
| 214 | processedRun.Run.WorkflowPath, |
| 215 | processedRun.Run.Event, |
| 216 | }, " ")) |
| 217 | |
| 218 | createdTypes := make([]string, 0, len(createdItems)) |
| 219 | for _, item := range createdItems { |
| 220 | createdTypes = append(createdTypes, strings.ToLower(item.Type)) |
| 221 | } |
| 222 | createdJoined := strings.Join(createdTypes, " ") |
| 223 | |
| 224 | toolNames := make([]string, 0, len(toolUsage)) |
| 225 | for _, tool := range toolUsage { |
| 226 | toolNames = append(toolNames, strings.ToLower(tool.Name)) |
| 227 | } |
| 228 | toolJoined := strings.Join(toolNames, " ") |
| 229 | |
| 230 | switch { |
| 231 | case containsAny(combined, "release", "deploy", "publish", "backport", "changelog"): |
| 232 | return &TaskDomainInfo{Name: "release_ops", Label: "Release / Ops", Reason: "Workflow metadata matches release or operational automation."} |
| 233 | case containsAny(combined, "research", "investigat", "analysis", "analy", "report", "audit"): |
| 234 | return &TaskDomainInfo{Name: "research", Label: "Research", Reason: "Workflow naming and instructions suggest exploratory analysis or reporting."} |
| 235 | case containsAny(combined, "triage", "label", "classif", "route") || containsAny(createdJoined, "add_labels", "remove_labels", "set_issue_type"): |
| 236 | return &TaskDomainInfo{Name: "triage", Label: "Triage", Reason: "The run focused on classification, routing, or issue state updates."} |
| 237 | case containsAny(combined, "fix", "patch", "repair", "refactor", "swe", "code", "review") || containsAny(createdJoined, "create_pull_request_review_comment", "submit_pull_request_review"): |
| 238 | return &TaskDomainInfo{Name: "code_fix", Label: "Code Fix", Reason: "The workflow appears oriented toward code changes or pull request review."} |
| 239 | case containsAny(combined, "cleanup", "maint", "update", "deps", "sync", "housekeeping"): |
| 240 | return &TaskDomainInfo{Name: "repo_maintenance", Label: "Repo Maintenance", Reason: "Workflow metadata matches repository maintenance or update work."} |
| 241 | case containsAny(combined, "issue", "discussion", "comment", "support", "reply") || containsAny(createdJoined, "add_comment", "create_discussion"): |
| 242 | return &TaskDomainInfo{Name: "issue_response", Label: "Issue Response", Reason: "The run is primarily interacting with issue, discussion, or comment threads."} |
| 243 | case awContext != nil: |
| 244 | return &TaskDomainInfo{Name: "delegated_automation", Label: "Delegated Automation", Reason: "The run was dispatched from an upstream workflow and is acting as a delegated task."} |
| 245 | case containsAny(toolJoined, "github_issue_read", "github-discussion-query"): |
| 246 | return &TaskDomainInfo{Name: "issue_response", Label: "Issue Response", Reason: "Tool usage centers on repository conversations and issue context."} |
| 247 | default: |
| 248 | return &TaskDomainInfo{Name: "general_automation", Label: "General Automation", Reason: "The run does not strongly match a narrower workflow domain yet."} |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | func buildBehaviorFingerprint(processedRun ProcessedRun, metrics MetricsData, toolUsage []ToolUsageInfo, createdItems []CreatedItemReport, awContext *AwContext) *BehaviorFingerprint { |
| 253 | auditAgenticLog.Printf("Building behavior fingerprint: run_id=%d turns=%d tool_types=%d created_items=%d", processedRun.Run.DatabaseID, metrics.Turns, len(toolUsage), len(createdItems)) |