nvidia/aicr-uat-report
| Use when reporting on UAT health across services and GPU targets — which service (EKS/GKE/AKS) x GPU (H100/GB200) x intent combinations are passing or failing in the UAT Run workflow (uat-run.yaml). Triggers on "UAT report", "/aicr-uat-report", "which UAT combos are failing", "UAT pass rate", "download the UAT debug bundle", "why did the UAT run fail", or RC/release-candidate validation prep that needs the combinations to test manually. Runs the bundled uat_report.py, classifies failures as product vs infra signal, prints a summary table plus an RC validation priority list, and can download the per-run cluster debug bundles for triage.
npx skills add https://github.com/NVIDIA/aicr --skill aicr-uat-report
Reports how the UAT Run workflow
(<https://github.com/NVIDIA/aicr/actions/workflows/uat-run.yaml>) performed
over a lookback window, aggregated by service x GPU x intent, with each
failure classified as product signal (real test failure) or infra noise.
The output feeds the release process: combinations failing on main are
the ones to test more closely during RC validation.
/aicr-uat-report (optionally with a number of days)Do NOT use this skill to re-run, dispatch, or cancel UAT runs.
"over the last week", pass --days 7. Do not ask — default to 3 when
unspecified.
main (empty aicr_version input) are reported bydefault; that is the release-process signal. Add --all-versions only
if the user explicitly asks to compare against release-tag runs.
--download-debug <dir> when the userasks why something failed, or when Step 2 classifies a failure as product
signal. Skip it for a plain pass-rate report — bundles are tens of MB.
The workflow's run-name encodes everything needed — no per-job digging:
UAT <reservation> <intent> @ <version|main>[ #dispatch_key].
Reservation names are <cloud>-<gpu> rows from
infra/uat/reservations.yaml (e.g. aws-h100, gcp-h100, azure-h100,
aws-gb200), and cloud maps to service: aws=EKS, gcp=GKE, azure=AKS,
kind=Kind (self-hosted nvkind lane). Runs before 2026-07-21 used a title
without the intent word; the script derives intent from the nightly
dispatch-key cell index (version-outer/intent-inner, training first) and
marks those rows "(intent derived)".
Each per-cloud workflow (uat-aws.yaml, uat-gcp.yaml, uat-azure.yaml,
uat-kind.yaml) runs tests/uat/<cloud>/run debug on failure — before
teardown, while the cluster is still up — and uploads
uat-<cloud>[-<intent>]-debug-<run_id> with 30-day retention. Reusable
workflows inherit the caller's run_id, so the artifact hangs off the
uat-run.yaml run the report already lists.
The upload is gated on failure() && steps.prep.outcome != 'skipped', so
no bundle exists when the cloud job died in bring-up or image build, or
when the failure was in a downstream job (evidence ingest) while the cluster
job passed. Absence is itself a classification signal, not an error.
What to open, in triage order (if-no-files-found: ignore, so any entry can
be missing; cluster-debug/ prefix omitted below):
| Open | When / what it answers |
|---|---|
| MANIFEST.yaml | Always first — runId, config, resolved recipe + criteria, and failingChecks lifted from report.json |
| report.json | Full validator results; absent if the run died before validate |
| train-logs/, serve-logs/ | A CUJ check failed (NCCL, inference-perf) |
| cr-skyhooks.yaml, node-reboot-fingerprint.txt, readiness-gate.log | Readiness-gate or tuning-race failure — Skyhook status.status, taints, bootID/kernel |
| pods-notready.txt, events.txt | Scheduling, eviction, OOM |
| logs-<namespace>.txt | The operator owning the failing resource |
| nodes*, other cr-*.yaml, ns-*.txt | Broader node and operator state |
| snapshot.yaml, recipe.yaml, dry-run.json | What was collected / resolved / deployed |
| evidence-result.json, evidence/pointer.yaml | Signed-evidence emit outcome |
python3 .agents/skills/aicr-uat-report/uat_report.py --days 3
It prints, per version, a Markdown table (`Service | GPU | Intent | Pass |
Failures`) and a "Failure detail" section listing each failing run's
timestamp, URL, and the failed job/step names. It is read-only
(gh run list / gh run view). If gh is not authenticated, stop and
tell the user to run gh auth status.
Map the failed step name to a failure nature. This drives the RC
priority ranking, so classify every failure:
| Failed step contains | Nature | Product signal? |
|---|---|---|
| UAT - validate, UAT - prep, CUJ/test phase names | Real test failure | YES — but the validate step also emits signed evidence, so confirm against report.json (Step 2b) before ranking |
| Bringup Infra, provision/actuator steps | Infra bring-up failure | no |
| Buildx, Build and push, image/GHCR steps | CI/image flake | no |
| Validate inputs, helmfile apply, install steps | Setup/install issue | maybe — recurring = investigate |
A retry that went green the same night (same combo, later timestamp,
success) downgrades the earlier failure to a flake.
Skip this step entirely for a routine pass-rate report. Run it when the
user asks *why* something failed, or when Step 2 found a test-phase
failure worth root-causing:
python3 .agents/skills/aicr-uat-report/uat_report.py --days 3 \
--download-debug /tmp/uat-debug --max-downloads 3
Prefer --run <id> (repeatable) over raising --max-downloads: usually only
the latest failure per failing combo is worth reading.
Bundles land in <dir>/<service>-<gpu>-<intent>-<run_id>/, each with a
printed digest — MANIFEST head, failing checks from report.json, and a
one-line contents summary. Read that summary for *presence*, not file names:
a missing evidence/ or report.json says the run died before that stage,
which is often the whole diagnosis. Then open files per the Debug bundles
table above.
Cite file_path:line and the run ID for every finding. Leave the download
directory in place — the user may want to keep digging.
Produce exactly two artifacts, in this order (see Output Format
Reference). Sort the table worst-first: lowest pass ratio at the top;
bold the Service/GPU/Intent cells of rows with product-signal failures.
Include run URLs as links for at least the most recent failure of each
failing combo.
A numbered priority list derived from the table:
validate-phase failures) — top manual-validation priority.
ones were infra) — deserve a close look.
note them but rank low.
nightly-intents: [],kind lane) — expected churn, call out separately.
bill is information too.
## UAT report against `main` (<start>–<end>, N runs)
| Service | GPU | Intent | Pass | Failure nature |
|---|---|---|---|---|
| **AKS** | **H100** | **training** | **0/4** | Real test failures — every run fails at "UAT - validate (all phases)" ([latest](<url>)) |
| EKS | H100 | training | 2/5 | Infra only — 2x bring-up, 1x Buildx CI flake; no test-phase failures |
| GKE | H100 | training | 4/4 | Green |
## RC validation input
1. **<Service>/<GPU>/<intent> is the clear red flag** — <pass ratio,
failure signature, latest run link, whether it also fails on release
tags (env issue) or only main (regression candidate)>.
2. ...
N. **<green combos> are solidly green** — lowest manual-testing priority.
Keep failure-nature cells to one sentence; detail beyond that belongs in
the RC list, not the table.
gh run list returns nothing — window may predate retention or theworkflow was renamed; say so rather than reporting "all green".
run-name format inuat-run.yaml changed; read the workflow's current format string and
update NEW_TITLE/OLD_TITLE in uat_report.py in the same PR.
uppercased cloud token as the service name; cross-check new rows against
infra/uat/reservations.yaml.
of declaring it broken.
(see Debug bundles). Report it as corroborating the infra classification;
do not present it as a tooling problem.
Nothing to recover; note it and work from failed step names.
cluster-debug/ missing or thin — the collector is best-effort andits cloud credentials can expire on a long failure. Say the bundle is
incomplete; do not read it as the cluster being healthy.
report.json — trust the bundle.UAT - validate (all phases) + emit signed evidence covers two concerns,
so N/N passing checks under a failed step means the evidence leg failed,
not the product. Reclassify to infra before ranking it in Step 4.
gh run view --log); it reports failedstep names and, on request, the uploaded cluster debug bundles
writes are downloaded artifacts under the --download-debug directory
Take nvidia/aicr-uat-report from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.