Track Issues & Regressions
Navigate runs, issues, and regressions in the validation tracker.
Overview
The UluOps Validation Tracker automatically correlates issues across runs using SHA-256 fingerprinting. Every finding gets a stable fingerprint based on its file, location, and failure type — so the same issue is tracked across runs even as line numbers shift.
This guide covers how to query, manage, and analyze issues using the ops MCP server in Claude Code, with SDK alternatives for programmatic access.
Viewing Runs
Get the Latest Run
get_latest_run({ project: "my-project" })This returns the most recent validation run with all agent scores, the overall decision, and correlation data showing what changed since the previous run.
Compare Two Runs
diff_runs({
project: "my-project",
base_run: 3,
compare_run: 5
})The diff shows which issues were fixed, which are new, which remain unchanged, and how agent scores changed between runs. Useful for verifying that a fix round actually resolved the targeted issues.
SDK alternative:
const latest = await client.runs.getLatest({ project: 'my-project' });
const diff = await client.runs.diff({
project: 'my-project',
baseRun: 3,
compareRun: 5,
});Querying Issues
By Status
# All open issues
query_issues({ project: "my-project", status: "open" })
# Only critical priority
query_issues({ project: "my-project", status: "open", priority: "critical" })By Agent
query_issues({ project: "my-project", agent: "code-validator" })By Failure Domain
Filter by the failure taxonomy to focus on specific issue types:
# All open epistemic issues (assumptions, evidence gaps)
query_issues({ project: "my-project", failure_domain: "EPI" })
# Structural issues from a specific agent
query_issues({ project: "my-project", failure_domain: "STR", agent: "public-interface-validator" })Domains: STR (structural), SEM (semantic), PRA (pragmatic), EPI (epistemic).
Full-Text Search
search_issues({ query: "error handling", projects: ["my-project"] })Search works across projects and supports filtering by status, priority, severity, agents, and failure domains.
Example Response
Each issue in the query response includes an id you'll use for updates, along with the finding details:
{
"id": "a1b2c3d4-...",
"title": "Missing null check on .find() result",
"status": "open",
"priority": "suggested",
"severity": "medium",
"agent": "code-validator",
"filePath": "src/services/auth.ts",
"lineNumber": 23,
"failureCode": "SEM-COM/M",
"failureDomain": "SEM",
"failureMode": "COM",
"fingerprint": "9f21dc...",
"timesSeen": 3,
"firstSeenRunId": "...",
"lastSeenRunId": "..."
}The timesSeen field shows how many runs have flagged this issue — useful for identifying persistent problems.
SDK alternative:
const open = await client.issues.query({
project: 'my-project',
status: 'open',
priority: 'critical',
});
const results = await client.issues.search({
query: 'error handling',
projects: ['my-project'],
});Managing Issue Lifecycle
Issues move through these statuses:
| Status | Meaning | When to Use |
|---|---|---|
open | Active, needs attention | Default for new findings |
completed | Genuine defect, fixed | The fix has been verified |
wontfix | Correct observation, not worth acting on | Valid finding but doesn't warrant a change (lifecycle mismatch) |
false-positive | Agent was factually wrong | The agent misread the code — this isn't actually an issue |
observation | Valid observation, tracked separately | For analyst/forecaster findings that aren't defects |
deferred | Acknowledged, will address later | Genuine issue but not the right time to fix |
merged | Merged into another issue | Duplicate finding consolidated into a target issue |
Your labeling matters. The distinction between wontfix (correct finding, not actionable) and false-positive (agent was wrong) is what drives the Recursive Appreciation feedback loop. Accurate labeling helps the system distinguish accuracy failures from lifecycle mismatches — and the difference is significant (6.4% FP rate vs 18.0% combined rejection rate across the ecosystem).
Update Status
You can identify issues by id (preferred), fingerprint, or file_path + title:
update_status({
project: "my-project",
updates: [
{ id: "a1b2c3d4-...", status: "completed", reason: "Fixed in PR #42" },
{ id: "e5f6g7h8-...", status: "deferred", reason: "Waiting on v2 migration" }
]
})For bulk updates across many issues at once (up to 100):
bulk_update_status({
project: "my-project",
updates: [
{ id: "a1b2c3d4-...", status: "completed", reason: "Resolved in refactoring sprint" },
{ id: "e5f6g7h8-...", status: "completed", reason: "Resolved in refactoring sprint" },
{ id: "i9j0k1l2-...", status: "wontfix", reason: "Intentional pattern" }
]
})Undo a Status Change
Accidentally marked something completed? Undo the last status change:
undo_issue_status({ issue_id: "a1b2c3d4-..." })This reverts to the previous status and preserves the full status history.
Add Notes
Attach context to issues without changing their status:
add_issue_note({
issue_id: "a1b2c3d4-...",
note_type: "context",
content: "Caused by the legacy API adapter — will fix when we migrate to v2"
})Note types: context (background info), resolution (how it was fixed), blocker (what's preventing a fix).
SDK alternative:
await client.issues.updateStatus({
project: 'my-project',
updates: [
{ id: issueId, status: 'completed', reason: 'Fixed in PR #42' },
],
});
await client.issues.addNote({
issueId: issue.id,
noteType: 'context',
content: 'Caused by the legacy API adapter',
});Detecting Regressions
Regressions are automatically detected when a previously resolved fingerprint reappears in a new run. The tracker flags these in the correlation summary after each run is saved.
Check for Regressions
When you save a run (see Run a Validation), the response includes correlation data:
# Response from save_run includes:
# correlation.newIssues: 2
# correlation.recurring: 5
# correlation.regressions: 1 <- previously fixed issue came back
# correlation.resolved: 3Respond to Regressions
When regressions appear:
- Investigate the diff — use
diff_runsto see exactly which resolved issues reappeared - Check if the fix was reverted — a merge conflict or rebase may have dropped the fix
- Re-run the specific agent — confirm the regression is real, not a false positive from changed context
- If the issue is real, fix it again and add a note explaining what caused the regression
Investigate Recurring Issues
Find issues that keep appearing across runs:
query_issues({ project: "my-project", min_times_seen: 3, status: "open" })Recurring issues often indicate a systemic pattern rather than a one-off bug. Consider whether the codebase needs an architectural fix or whether the agent criteria need adjustment. See Improve Your Agents for how to iterate on criteria.
Analytics
The tracker provides several analytics tools to help you understand trends beyond individual issues.
Project Summary
Get a high-level overview with issue counts, agent stats, and trends:
get_project_summary({ project: "my-project" })Burndown
Track open issue count over time by failure domain:
get_burndown({ project: "my-project", days: 30 })A downward trend with stable scores means the team is resolving real issues, not just lowering the bar.
Velocity
See which failure modes are being resolved fastest and which are stalling:
get_velocity({ project: "my-project", days: 30 })Agent Reliability
Not all agents are equally reliable. Track false-positive rates and resolution rates per agent:
get_agent_reliability({ project: "my-project" })Low-reliability agents are candidates for recursive improvement — their ADL definitions need refinement.
Coverage Matrix
Identify blind spots in your agent ecosystem:
get_agent_matrix({ project: "my-project" })This shows which failure domains have no agent coverage (blind spots), which have only one agent (single points of failure), and which have 3+ agents detecting the same mode (overlap).
SDK alternative:
const summary = await client.projects.getSummary({ project: 'my-project' });
const burndown = await client.analytics.getBurndown({ project: 'my-project', days: 30 });
const reliability = await client.analytics.getAgentReliability({ project: 'my-project' });
const matrix = await client.analytics.getAgentMatrix({ project: 'my-project' });Automatic Resolution Detection
The /commit-push workflow in Claude Code automatically checks for resolved issues before committing:
- Queries open issues for the current project
- Matches modified files against issue
file_pathvalues - Prompts you to mark matching issues as completed
- Updates the tracker with the commit SHA as the resolution reason
This closes the loop between fixing code and updating the tracker without manual bookkeeping.
Next Steps
- Improve Your Agents — Use issue patterns to refine agent criteria
- Failure Taxonomy — Understand how issues are classified
- Fingerprinting — How stable issue identity works across runs