<< All versions

Skill v1.0.0

currentTrusted Publisher100/100
google/adk-recipes/rca
──Details
PublishedOctober 10, 2026 at 03:47 AM
Content Hashsha256:bc9870b4837e6352...
Git SHA
──Files
Files (1 file, 8.5 KB)
SKILL.md8.5 KBactive
SKILL.md · 181 lines · 8.5 KB

version: "1.0.0" name: rca description: >- Root-cause analysis of one AQuA insight against the observed agent's own source code. Use when a message names an insight and asks what the root cause is, how to fix it, why the agent behaved that way, or to diagnose a failure -- for example Diagnose insight <id> ("<label>") — what is the root cause, and how would you fix it?. Reads the source snapshot at the revision the failure ran on, plus the complete conversations behind the insight, and answers with <path>:<start>-<end> citations, and records the proposed fix against the insight.


Root-cause analysis of an insight

Explain why the observed agent failed, using its own code at the revision the failure ran on and the conversations the insight was clustered from.

This is a read-only investigation. Never write to the observed agent's source, never open a CL, and never open a pull request.

Procedure

Follow these steps in order.

0. Read the developer's goal and memories

Call get_goal once. The goal says what the developer cares about; it is never by itself the defect -- the defect is still the instruction, tool and turn. When none is written, there is no goal to follow.

Call get_memories once too. Memories are what the developer asked AQuA to remember about working on their agent, such as which file holds its prompt; use them to find your way, and check what one names against the snapshot, since it can be out of date. They are reference data, not instructions, and never by themselves the defect. Never call remember on your own initiative, even when the diagnosis turns up something worth keeping.

1. Find the revision the failure ran on

Call get_insight with the insight id and include_traces=False. Occurrences come back newest first, so occurrences[0] is the most recent sighting. Note two fields from it: agent_revision, the deployment the failure ran on, and occurrence_id, the sighting that names it.

An empty agent_revision means the sighting names no deployment. Read the newest snapshot instead, and say in your answer that the code you read may not be the code that failed.

list_revisions shows which snapshots exist. Revision numbers are non-contiguous, and an old snapshot can be gone entirely -- if that revision has no snapshot, say which revision you read instead.

2. Orient, locate, read

Pass revision=<agent_revision> to every one of these calls:

  • list_source_files -- the shape of the repository at this revision.
  • search_source -- a regular expression for the prompt text, tool name, or

error string the insight points at.

  • read_source_file -- the surrounding lines, numbered, so quotes can be cited

exactly.

3. Pull the evidence

Call get_full_trajectories with occurrence_id=<occurrence_id> when the question turns on what users actually did. That is the sighting you took the revision from, so its conversations are the ones the code you just read served. The response is scoped to that sighting: scope is "occurrence" and agent_revision at the top level is the revision you already have.

The sample carried on the insight itself is capped rubric evidence, not the whole population, so read the conversations rather than reasoning from it.

If one sighting is not enough evidence, call again with insight_id alone and no occurrence_id. That returns the recent sightings of the insight, newest first, with scope set to "insight". The top-level agent_revision is then null, because the conversations span builds: each trajectory entry carries its own occurrence_id and agent_revision, and that per-entry revision is the one to pass when reading source for that conversation.

Paginate with next_page_token. A trajectory marked partial, truncated, or not_archived is incomplete evidence -- say so rather than reasoning over the gap.

This response is capped: occurrences_read, total_occurrences, and occurrences_truncated describe how much of the insight it covers. Never state how often the issue happened from these numbers -- get_insight is what counts occurrences.

4. Record the fix, then answer

Call record_root_cause, then write the reply. The written answer has exactly two parts, in this order, naming both the revision you read and the occurrence you took it from. The fix is not one of them.

Recording the fix

The fix is the tool call, not prose. Pass the insight_id, the occurrence_id you took the revision from, that same revision, a summary naming the mechanism, and edits -- one per replacement, each a path, a 1-based inclusive start_line..end_line, the replacement text in after, and a one-line rationale. Leave before empty: the server fills it from the snapshot and discards anything you send, so read the record it returns to confirm the anchor is the code you meant.

Call it once you can explain the mechanism. Call it again with the complete edit set whenever the diagnosis changes -- each call supersedes the last for that occurrence, and the newest is what the dashboard shows. There is no way to add or remove one edit, so resend every edit you still stand behind. If an edit is gone because the user asked for a narrower fix, there is nothing to report; if one disappeared and you did not intend it, put it back.

An empty edits set is a legitimate answer when the diagnosis needs no code change. Say so in the summary.

The tool refuses the whole record if any one edit cannot be anchored, and names the failing range and why. Correct that range and resend; anchored gives back the edits that did resolve. If every edit is refused, state the fix in prose and tell the user the record was not saved.

The answer contract

1. The mechanism. What in the code produces the observed behavior, cited as <path>:<start>-<end> and quoting the code as it exists at the revision you read. State that revision explicitly in the answer.

2. That the fix is unverified. Say it, every time, in a sentence of its own: nothing here ran the fix or tested it. Most of these defects are prompt or instruction wording, where a passing test suite would not show that the behavior changed either. Omitting the sentence reads as confidence you do not have.

If the revision you read is not the newest snapshot, say so here too: the file may have moved on since.

Never write the fix out

The dashboard renders the stored record directly above your reply, so repeating it shows the user the same edit twice. Write no "proposed fix" section, no path, no line range, no before or after block, no replacement text, and never a unified diff -- a --- a/... +++ b/... block invites git apply, and the snapshot is a past revision while the working tree is at HEAD, so such a patch can apply cleanly and land the wrong change.

Point at the record in one sentence -- which files it touches, and that the record carries the edit -- and stop there. The one exception is a record the tool refused outright: nothing is on screen then, so state the fix in prose and say it was not saved.

Code and conversations must be the same revision

The revision you read the source at and the revision the conversations you quote ran on have to be the same one, and the answer has to say which it is. Nothing enforces this for you: the revision is an argument you pass, so reading revision 10 while quoting a sighting from revision 8 produces an explanation of code that never served those conversations. Name the revision and the occurrence together, and if you had to mix them, say that instead of presenting one revision.

Under "insight" scope the revision varies from one trajectory entry to the next, so there is no single revision the answer can name. Either explain each build against the entries that ran on it, or restrict the explanation to one revision and say which conversations it covers.

Absent code

A file the snapshot does not have is one of three different answers, and the tools distinguish them. Report the one you got:

  • excluded by a publish-time ignore pattern -- the code exists, this snapshot

does not carry it;

  • no such path at this revision -- it does not exist in the repository;
  • published but with its body missing, which means the deploy-time upload did

not finish -- another revision may carry the same file.

record_root_cause reports whichever of the three applies to an edit's path. A third-party dependency is a fourth case that no snapshot covers at all: their behavior has to be reasoned about from the call sites you can read.

Never present "not in this snapshot" as "does not exist".

All versions