| 1487 | } |
| 1488 | |
| 1489 | func runIDForExplainTarget(db *sql.DB, target ExplainTarget) (string, error) { |
| 1490 | if target.Run != "" { |
| 1491 | return target.Run, nil |
| 1492 | } |
| 1493 | var runID string |
| 1494 | var err error |
| 1495 | switch target.Type { |
| 1496 | case "attempt": |
| 1497 | err = db.QueryRow(`SELECT r.run_id FROM fork_attempts a JOIN rollouts r ON a.rollout_id = r.id WHERE a.id = ?`, target.ID).Scan(&runID) |
| 1498 | case "tool_call": |
| 1499 | err = db.QueryRow(`SELECT COALESCE(run_id, '') FROM tool_calls WHERE id = ?`, target.ID).Scan(&runID) |
| 1500 | case "process": |
| 1501 | err = db.QueryRow(`SELECT COALESCE(s.run_id, '') FROM processes p JOIN sessions s ON p.session_id = s.id WHERE p.id = ?`, target.ID).Scan(&runID) |
| 1502 | case "event": |
| 1503 | err = db.QueryRow(`SELECT COALESCE(run_id, '') FROM events WHERE id = ?`, target.ID).Scan(&runID) |
| 1504 | case "risk": |
| 1505 | err = db.QueryRow(`SELECT COALESCE(run_id, '') FROM policy_decisions WHERE id = ?`, target.ID).Scan(&runID) |
| 1506 | case "artifact": |
| 1507 | err = db.QueryRow(`SELECT r.run_id FROM fork_attempts a JOIN rollouts r ON a.rollout_id = r.id WHERE a.artifact_result = ? ORDER BY a.created_at ASC LIMIT 1`, target.ID).Scan(&runID) |
| 1508 | default: |
| 1509 | return "", nil |
| 1510 | } |
| 1511 | if err == sql.ErrNoRows { |
| 1512 | return "", nil |
| 1513 | } |
| 1514 | return runID, err |
| 1515 | } |
| 1516 | |
| 1517 | func eventByID(db *sql.DB, eventID string) (ExplainEvent, error) { |
| 1518 | var event ExplainEvent |