Failure context
Everything the agent is handed before it is allowed to make a single decision. Most wrong diagnoses come from reading the wrong thing, so this part is deterministic on purpose.
The run and the job
A GitHub Actions run is one execution of a workflow. It contains jobs, and each job contains steps. A run is red because at least one step in at least one job exited non-zero.
TraceCI resolves the target in this order: an explicit run id if you pasted a run URL, otherwise the most recent failed run on the branch you named, otherwise the most recent failed run on the repository. It then takes the first failed job in that run.
The first failing step
The first failing step matters, not the last. Once a step fails, later steps often fail as consequences — a test job that failed to install dependencies will also report that no tests were collected, and diagnosing that second message sends you somewhere useless.
The failing step name is also the strongest single hint about the category of failure. A failure at Set up Python is a configuration problem no matter what the application code looks like; a failure at Lint means nothing has executed yet.
The log window
A CI log is routinely tens of thousands of lines, and almost all of it is installation noise. Handing the whole thing to a model is impossible on token grounds and unhelpful anyway. Handing it the last N lines — the obvious approach — is worse than it sounds: a pytest run prints its summary at the end but the traceback that explains the failure can be thousands of lines earlier, and a dependency resolver prints its candidate list long before the line that says it gave up.
So the window is built in three moves:
- Clean. Timestamps, ANSI colour codes and GitHub's workflow command markers are stripped, because they consume tokens and carry nothing.
- Anchor. The window is centred on the first real error — the first line that looks like a genuine failure rather than a warning or a retry.
- Always include the tail. The final lines are appended regardless, so the summary line survives even when the anchor is far from the end.
----- step log: Run tests (4182 lines, showing 61-240 and the tail) -----
The header states the total line count and where the excerpt sits inside it. That is what makes it possible for the agent to ask for a different slice sensibly rather than paging blindly — see the agent's tools.
Expired logs
The green-to-red diff
The comparison that explains a failure is last green commit → failing commit, not previous commit → failing commit. If a branch has had four red runs in a row, the change that broke it is four commits back, and diffing against the immediately previous commit shows you an unrelated typo fix.
TraceCI walks the branch's run history to find the most recent successful run of the same workflow, takes its head SHA as the baseline, and fetches the comparison. The agent is given a summary — file names, added and deleted line counts, commit count — not the full patch, because the largest hunk in a diff is very often not the cause, and reading the whole patch first is the fastest way to anchor on the wrong file.
----- changes since the last green run ----- 2 file(s) changed across 1 commit(s), green -> red. modified app/auth.py (+4 -3) modified app/rate_limit.py (+87 -21)
In that example the large hunk is a red herring and the four-line change is the cause. The agent has to decide which to look at, which is exactly the judgement the system exists to apply.
Everything is pinned to the failing SHA
Every read the agent makes — files, directory listings, symbol searches — happens at the commit that failed, not at the branch head and not at main. This matters more than it sounds. If someone pushed the fix while you were investigating, reading the branch head shows you corrected source next to a log that describes the bug, and any diagnosis built from both is incoherent.
| Input | Where it comes from |
|---|---|
| Repository, run, job | GitHub Actions run history, filtered to failures |
| Failing step | The first step in the first failed job with a non-zero conclusion |
| Log window | The step's log: cleaned, anchored on the first real error, tail appended |
| Diff summary | Compare API, last successful run's head SHA → failing head SHA |
| Source files | Contents API, always at the failing head SHA, only when the agent asks |