feat(agents): add investigation context loader module

Provides load_investigation_context() and load_investigation_for_qa()
to load investigation data from spec directories for GitHub-sourced tasks.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
This commit is contained in:
Sondre Engebråten
2026-02-16 10:51:18 +01:00
co-authored by Claude Sonnet 4.5
parent 009045629b
commit 0141459517
@@ -0,0 +1,88 @@
"""
Investigation context loading for agents.
Provides utilities to load investigation data from spec directories
for GitHub-sourced tasks.
"""
import json
from pathlib import Path
from typing import Any
def load_investigation_context(spec_dir: Path) -> dict[str, Any] | None:
"""
Load investigation context if this spec was created from a GitHub issue.
Args:
spec_dir: Path to the spec directory
Returns:
Structured investigation context with root_cause, fix_approaches,
reproducer, gotchas, and patterns_to_follow, or None if no
investigation data exists.
"""
investigation_report_path = spec_dir / "investigation_report.json"
if not investigation_report_path.exists():
return None
try:
with open(investigation_report_path) as f:
report = json.load(f)
# Structure the context for agents
return {
"root_cause": {
"summary": report.get("root_cause", {}).get("summary"),
"evidence": report.get("root_cause", {}).get("evidence", []),
"code_paths": report.get("root_cause", {}).get("code_paths", [])
},
"fix_approaches": report.get("fix_approaches", []),
"reproducer": report.get("reproducer"),
"gotchas": report.get("gotchas", []),
"patterns_to_follow": report.get("patterns_to_follow", []),
"impact": report.get("impact", {})
}
except (json.JSONDecodeError, OSError):
return None
def load_investigation_for_qa(spec_dir: Path, base_branch: str) -> dict[str, Any] | None:
"""
Load investigation context for QA validation.
Similar to load_investigation_context but includes base_branch
for QA comparison.
Args:
spec_dir: Path to the spec directory
base_branch: Base branch to compare against (e.g., 'main', 'develop')
Returns:
Structured investigation context with root_cause, reproducer,
impact, expected_outcome, and base_branch, or None if no
investigation data exists.
"""
investigation_report_path = spec_dir / "investigation_report.json"
if not investigation_report_path.exists():
return None
try:
with open(investigation_report_path) as f:
report = json.load(f)
return {
"root_cause": {
"summary": report.get("root_cause", {}).get("summary"),
"evidence": report.get("root_cause", {}).get("evidence", []),
"code_paths": report.get("root_cause", {}).get("code_paths", [])
},
"reproducer": report.get("reproducer"),
"impact": report.get("impact", {}),
"expected_outcome": report.get("expected_outcome"),
"base_branch": base_branch
}
except (json.JSONDecodeError, OSError):
return None