/k6-cloud-investigate-test
Investigate a Grafana Cloud k6 test — describe the script, list run history, identify pass/fail status, pull raw metric time-series and log lines for one or more runs, and (if asked) safely edit the test script. Use when the user asks about a specific k6 cloud test or run, gives
$ npx -y skills add grafana/skills --skill k6-cloud-investigate-test --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/k6-cloud-investigate-test
Context preview
The summary Claude sees to decide when to auto-load this skill.
Investigate a Grafana Cloud k6 test — describe the script, list run history, identify pass/fail status, pull raw metric time-series and log lines for one or more runs, and (if asked) safely edit the test script. Use when the user asks about a specific k6 cloud test or run, gives
SKILL.md
k6-cloud-investigate-test.SKILL.mdname: k6-cloud-investigate-test
description: Investigate a Grafana Cloud k6 test — describe the script, list run history, identify pass/fail status, pull raw metric time-series and log lines for one or more runs, and (if asked) safely edit the test script. Use when the user asks about a specific k6 cloud test or run, gives a `/a/k6-app/tests/<id>` or `/a/k6-app/runs/<id>` URL, asks "is this test passing", "why are my k6 tests failing", "show me metrics for run X", "show me logs for run X", or wants to add thresholds / fix a failing test. Trigger this skill even when the user doesn't explicitly say "investigate" — pasted `/a/k6-app/...` URLs, "why did run X fail", "what happened with my test", "is my test healthy", "the latest run looks weird", "checks are failing but the run says passed", or any request to diagnose a Grafana Cloud k6 run all qualify.
k6 Cloud test investigator
Structured 9-step workflow for investigating a Grafana Cloud k6 test or run.
This skill is **workflow-only**. All API calls go through `gcx api` against the plugin proxy, using v6 for REST and v5 for metrics. For the underlying mechanics (gcx auth, path conventions, endpoint discovery, log queries, script editing, threshold semantics, gotchas), see the `k6-manage` skill — every step below references it.
The content unique to this skill is:
- the ordered investigation flow (Steps 1-9 below)
- the date-alignment check ("last 7 days" ≠ "last 7 runs")
- the 3-layer pass/fail determination (`result` vs `status` vs per-check `checks` query)
- a worked example with realistic numbers (`references/worked-example.md`)
Core principles
1. **Read before write.** Always GET the script before any PUT. `gcx k6 load-tests update-script` is a *write* that replaces the live script with whatever file you pass — running it "just to see the URL it hits" has cost users their production scripts. If you need to learn URLs, run any non-mutating command with `-vvv --log-http-payload` instead. 2. **Paginate when enumerating runs.** The `/test_runs` endpoint caps at 1000 rows and `gcx k6 runs list --limit 0` does not auto-follow `@nextLink`. Use the `gcx api` loop documented in `k6-manage` §3. 3. **Verify date framing.** When the user says "last 7 days", "this week", "recent runs" — confirm the most-recent run's `created` actually falls in that window. Surface the gap if not. 4. **`check()` doesn't fail runs; only `thresholds` do.** And thresholds with zero observations are reported as ✓ pass. See "Threshold semantics" below for the full deep dive; the per-check `checks` metric query in Step 5 catches both cases.
Prerequisites
`gcx` installed and authenticated against the user's stack. See `k6-manage` §1. Verify with:
gcx --context <stack> config check # expect "✔ Connectivity: online"
Investigation workflow
Step 1: Identify the test and target run(s)
From the user's URL:
- `/a/k6-app/tests/<id>` → load test (parent of many runs)
- `/a/k6-app/runs/<id>` → a specific run
To go run → test: fetch the run via `gcx api`, see `k6-manage` §2 for the path-shape rules:
gcx --context <stack> api /api/plugins/k6-app/resources/cloud/cloud/v6/test_runs/<run_id>
and read `.test_id` from the response. To list runs for a test, see Step 3.
Step 2: Fetch test metadata and script
gcx --context <stack> k6 load-tests get <test_id> -o json
For the script, follow the GET half of the safe-edit recipe in `k6-manage` §5 — save a backup if you'll be editing later.
**Two script endpoints exist, and the difference matters for investigation.** `k6-manage` §5 documents both: the current load-test script and the per-run snapshot that was actually executed. They drift apart whenever the script is edited after a run. Whenever the question involves "what changed", "why did this run fail", or you're examining a run more than a few days old, also fetch the run-bundled snapshot(s) via `k6-manage` §5's run-script endpoint and diff against the current load-test script (or against another run's snapshot). The current load-test script is the wrong artifact to reason about a past run.
Step 3: List runs WITH pagination
Use the `gcx api` + `@nextLink` loop pattern documented in `k6-manage` §3 against `/cloud/v6/load_tests/<test_id>/test_runs`. After collecting `all_runs`:
print(f"Total: {len(all_runs)}")
runs_sorted = sorted(all_runs, key=lambda r: r['created'], reverse=True)
for r in runs_sorted[:10]:
print(f" {r['created']:30s} id={r['id']:>8} status={r['status']:<10} result={r.get('result','?')}")Report to user: total run count, date range, latest run date. **If "latest run" is more than a day old**, call it out — they may believe the schedule is firing when it isn't.
Step 4: Verify date alignment with user's intent
If the user asked for "last 7 days" / "this week" / "recent": filter by date range, not by row count — "7 most recent runs" could span a day or a year depending on how often the test runs.
last7 = [r for r in all_runs if r['created'] >= '<today_minus_7_days_iso>']
If `len(last7) == 0`: surface this to the user immediately. Don't proceed with stale data.
Step 5: Determine pass/fail status
For each run examine three independent layers:
| Layer | Field | Meaning | |---|---|---| | Run-level outcome | `result` (`passed` / `failed` / `error` / `aborted`) | Whether thresholds breached | | Run-level status | `status` (`completed` / `aborted`) | Whether the run finished orderly | | In-script checks | v5 `checks` metric, aggregated by the `check` label | Per-check success rate |
For a run that the user thinks is "failing" but reports `result: passed`: check the third layer. Common pattern: every iteration's `check()` returns false but the run still "passes" because no threshold is defined on `checks`. See "Threshold semantics" below for the full deep dive (zero-observation trap, `abortOnFail` cloud delay, operator support).
Query the per-ch
Read more
name: k6-cloud-investigate-test description: Investigate a Grafana Cloud k6 test — describe the script, list run history, identify pass/fail status, pull raw metric time-series and log lines for one or more runs, and (if asked) safely edit the test script. Use when the user asks about a specific k6 cloud test or run, gives a `/a/k6-app/tests/<id>` or `/a/k6-app/runs/<id>` URL, asks "is this test passing", "why are my k6 tests failing", "show me metrics for run X", "show me logs for run X", or wants to add thresholds / fix a failing test. Trigger this skill even when the user doesn't explicitly say "investigate" — pasted `/a/k6-app/...` URLs, "why did run X fail", "what happened with my test", "is my test healthy", "the latest run looks weird", "checks are failing but the run says passed", or any request to diagnose a Grafana Cloud k6 run all qualify.
k6 Cloud test investigator
Structured 9-step workflow for investigating a Grafana Cloud k6 test or run.
This skill is **workflow-only**. All API calls go through `gcx api` against the plugin proxy, using v6 for REST and v5 for metrics. For the underlying mechanics (gcx auth, path conventions, endpoint discovery, log queries, script editing, threshold semantics, gotchas), see the `k6-manage` skill — every step below references it.
The content unique to this skill is:
- the ordered investigation flow (Steps 1-9 below)
- the date-alignment check ("last 7 days" ≠ "last 7 runs")
- the 3-layer pass/fail determination (`result` vs `status` vs per-check `checks` query)
- a worked example with realistic numbers (`references/worked-example.md`)
Core principles
1. **Read before write.** Always GET the script before any PUT. `gcx k6 load-tests update-script` is a *write* that replaces the live script with whatever file you pass — running it "just to see the URL it hits" has cost users their production scripts. If you need to learn URLs, run any non-mutating command with `-vvv --log-http-payload` instead. 2. **Paginate when enumerating runs.** The `/test_runs` endpoint caps at 1000 rows and `gcx k6 runs list --limit 0` does not auto-follow `@nextLink`. Use the `gcx api` loop documented in `k6-manage` §3. 3. **Verify date framing.** When the user says "last 7 days", "this week", "recent runs" — confirm the most-recent run's `created` actually falls in that window. Surface the gap if not. 4. **`check()` doesn't fail runs; only `thresholds` do.** And thresholds with zero observations are reported as ✓ pass. See "Threshold semantics" below for the full deep dive; the per-check `checks` metric query in Step 5 catches both cases.
Prerequisites
`gcx` installed and authenticated against the user's stack. See `k6-manage` §1. Verify with:
gcx --context <stack> config check # expect "✔ Connectivity: online"
Investigation workflow
Step 1: Identify the test and target run(s)
From the user's URL:
- `/a/k6-app/tests/<id>` → load test (parent of many runs)
- `/a/k6-app/runs/<id>` → a specific run
To go run → test: fetch the run via `gcx api`, see `k6-manage` §2 for the path-shape rules:
gcx --context <stack> api /api/plugins/k6-app/resources/cloud/cloud/v6/test_runs/<run_id>
and read `.test_id` from the response. To list runs for a test, see Step 3.
Step 2: Fetch test metadata and script
gcx --context <stack> k6 load-tests get <test_id> -o json
For the script, follow the GET half of the safe-edit recipe in `k6-manage` §5 — save a backup if you'll be editing later.
**Two script endpoints exist, and the difference matters for investigation.** `k6-manage` §5 documents both: the current load-test script and the per-run snapshot that was actually executed. They drift apart whenever the script is edited after a run. Whenever the question involves "what changed", "why did this run fail", or you're examining a run more than a few days old, also fetch the run-bundled snapshot(s) via `k6-manage` §5's run-script endpoint and diff against the current load-test script (or against another run's snapshot). The current load-test script is the wrong artifact to reason about a past run.
Step 3: List runs WITH pagination
Use the `gcx api` + `@nextLink` loop pattern documented in `k6-manage` §3 against `/cloud/v6/load_tests/<test_id>/test_runs`. After collecting `all_runs`:
print(f"Total: {len(all_runs)}")
runs_sorted = sorted(all_runs, key=lambda r: r['created'], reverse=True)
for r in runs_sorted[:10]:
print(f" {r['created']:30s} id={r['id']:>8} status={r['status']:<10} result={r.get('result','?')}")Report to user: total run count, date range, latest run date. **If "latest run" is more than a day old**, call it out — they may believe the schedule is firing when it isn't.
Step 4: Verify date alignment with user's intent
If the user asked for "last 7 days" / "this week" / "recent": filter by date range, not by row count — "7 most recent runs" could span a day or a year depending on how often the test runs.
last7 = [r for r in all_runs if r['created'] >= '<today_minus_7_days_iso>']
If `len(last7) == 0`: surface this to the user immediately. Don't proceed with stale data.
Step 5: Determine pass/fail status
For each run examine three independent layers:
| Layer | Field | Meaning | |---|---|---| | Run-level outcome | `result` (`passed` / `failed` / `error` / `aborted`) | Whether thresholds breached | | Run-level status | `status` (`completed` / `aborted`) | Whether the run finished orderly | | In-script checks | v5 `checks` metric, aggregated by the `check` label | Per-check success rate |
For a run that the user thinks is "failing" but reports `result: passed`: check the third layer. Common pattern: every iteration's `check()` returns false but the run still "passes" because no threshold is defined on `checks`. See "Threshold semantics" below for the full deep dive (zero-observation trap, `abortOnFail` cloud delay, operator support).
Query the per-ch
Public skills for working with Grafana, Prometheus, Loki, Tempo, Pyroscope, k6, and the broader LGTM observability stack. Compatible with Claude Code, Cursor, Codex, and any tool supporting the Agent Skills open standard.
Repo: grafana/skills
Other skills on grafana-skills.
- /admission-control
Use when the user asks to "write a validator", "add validation", "implement admission control", "write a mutating webhook", "add a mutation handler", "validate incoming resources", "implement admission logic", "add admission webhooks", "write ingress validation", or asks how to
Open skill - /app-sdk-concepts
Use when starting any grafana-app-sdk work — scaffolding a Grafana app, initializing a Grafana App Platform app, picking a deployment mode (standalone operator / grafana/apps / frontend-only), wiring app-specific config, or onboarding to the SDK. Covers `grafana-app-sdk` CLI
Open skill - /cue-kind-definition
Author CUE kind definitions for grafana-app-sdk apps - schemas, versioning, field constraints, named type definitions, custom routes, and codegen configuration. Scaffolds kinds via `grafana-app-sdk project kind add`, writes spec/status schemas with type constraints (regex, enum,
Open skill - /reconciler-logic
Implement reconcilers and watchers for grafana-app-sdk apps — write `TypedReconciler[*MyKind]` reconcile functions, apply generation-based skip patterns, do conflict-safe status updates via `resource.UpdateObject`, configure `BasicReconcileOptions` (namespace, label/field
Open skill - /adaptive-metrics
Cut Grafana Cloud Metrics cost by shrinking active-series count with Adaptive Metrics aggregation rules — auto-recommendations from query history, custom exact/regex rules, label-drop config, unused-metric detection, and Alloy remote_write fallback. Use when investigating a high
Open skill - /admin
Manage Grafana Cloud accounts — organizations, stacks, RBAC roles and assignments, SSO/SAML/OAuth/GitHub auth, service accounts for CI/CD, user invites, team membership, and API-driven provisioning. Creates stacks via the Cloud API, mints service-account tokens, applies role
Open skill

