From 732566b55b6f9065b6f249cc2379252fce8f2c47 Mon Sep 17 00:00:00 2001 From: itdevwu Date: Fri, 24 Jul 2026 02:30:03 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20make=20xprobe=20setup=20ski?= =?UTF-8?q?ll-managed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 7 ++- CMakeLists.txt | 2 +- Cargo.lock | 12 ++-- Cargo.toml | 2 +- README.md | 30 +++------ docs/agent-integration.md | 17 ++--- docs/cli-contract.md | 2 +- docs/installation.md | 38 +++++++---- install.sh | 4 +- skills/xprobe-measure-latency/SKILL.md | 39 +++++++----- .../xprobe-measure-latency/agents/openai.yaml | 4 +- .../examples/coarse-kernel-inventory.json | 15 +++++ .../examples/coarse-memcpy-inventory.json | 15 +++++ .../references/investigation.md | 49 +++++++++++---- .../references/result-quality.md | 7 ++- .../references/setup.md | 63 +++++++++++++++++++ .../references/trace-analysis.md | 4 +- tests/agent-contract/test_contract.py | 14 ++++- 18 files changed, 236 insertions(+), 88 deletions(-) create mode 100644 skills/xprobe-measure-latency/examples/coarse-kernel-inventory.json create mode 100644 skills/xprobe-measure-latency/examples/coarse-memcpy-inventory.json create mode 100644 skills/xprobe-measure-latency/references/setup.md diff --git a/AGENTS.md b/AGENTS.md index 2d4fa85..e67d1e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,9 +36,10 @@ ## Agent workflow - Follow `skills/xprobe-measure-latency/SKILL.md` for measurement tasks. -- For an unknown workload, progress from readiness and baseline through a short - survey artifact, evidence-based selector narrowing, validation, and one - bounded measurement per stated hypothesis. Do not guess selectors. +- For an unknown workload, progress from readiness and baseline through a broad, + representative bounded inventory, evidence-based selector narrowing, + validation, and one detailed bounded measurement per stated hypothesis. Scope + breadth and capture duration are independent. Do not guess selectors. - Read evidence pairs, artifact analysis, stream identity, collection quality, and profiler overhead before interpreting latency. Summed concurrent GPU duration is not wall time. diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e3c190..e1cfaa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -project(xprobe VERSION 0.3.1 LANGUAGES C) +project(xprobe VERSION 0.3.2 LANGUAGES C) include(CTest) diff --git a/Cargo.lock b/Cargo.lock index d792b4d..2c0957a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,7 +452,7 @@ dependencies = [ [[package]] name = "xprobe-cli" -version = "0.3.1" +version = "0.3.2" dependencies = [ "clap", "serde_json", @@ -465,7 +465,7 @@ dependencies = [ [[package]] name = "xprobe-collector" -version = "0.3.1" +version = "0.3.2" dependencies = [ "libbpf-rs", "serde_json", @@ -474,7 +474,7 @@ dependencies = [ [[package]] name = "xprobe-core" -version = "0.3.1" +version = "0.3.2" dependencies = [ "nix", "object", @@ -484,7 +484,7 @@ dependencies = [ [[package]] name = "xprobe-correlator" -version = "0.3.1" +version = "0.3.2" dependencies = [ "regex", "serde_json", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "xprobe-exporter" -version = "0.3.1" +version = "0.3.2" dependencies = [ "serde_json", "xprobe-protocol", @@ -501,7 +501,7 @@ dependencies = [ [[package]] name = "xprobe-protocol" -version = "0.3.1" +version = "0.3.2" dependencies = [ "schemars", "serde", diff --git a/Cargo.toml b/Cargo.toml index 62d80aa..22f3223 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.3.1" +version = "0.3.2" edition = "2024" license = "Apache-2.0" repository = "https://github.com/itdevwu/xprobe" diff --git a/README.md b/README.md index 10d11e2..b1e32fe 100644 --- a/README.md +++ b/README.md @@ -14,33 +14,23 @@ in a process, on the CPU, NVIDIA GPU, or across both. Its bounded native profile combines eBPF uprobes and NVIDIA CUPTI with an agent-friendly CLI, strict JSON contracts, explicit correlation quality, and no daemon or server lifecycle. -## Install xprobe +## Install -```bash -curl --proto '=https' --tlsv1.2 -fsSL \ - https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.1/install.sh | sh -``` - -This installs the released CLI and CUDA 12/13 Agents under `~/.local`. xprobe -supports Linux x86_64 with glibc 2.34 or newer. NVIDIA CUDA is optional unless -GPU events are selected. See [Installation](docs/installation.md) for checksum -verification, custom prefixes, upgrades, and removal. - -## Install the Agent Skill - -Install the version-matched Skill with the open Agent Skills CLI: +Install the version-matched Skill with the open Agent Skills CLI. This is the +only installation action required from the user: ```bash npx skills@1 add \ - https://github.com/itdevwu/xprobe/tree/v0.3.1/skills/xprobe-measure-latency \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ --global ``` The installer detects Codex, Claude Code, Cursor, and other compatible agents. -Node.js is only needed for this Skill installation, not for xprobe itself. Set -`DISABLE_TELEMETRY=1` when anonymous `skills` CLI telemetry is not wanted. -The Skill guides a short survey, derives selectors from trace evidence, and -includes a deterministic multi-stream JSONL analyzer. +When invoked, the Skill checks for the matching `xprobe` CLI and installs or +repairs it under a writable prefix before profiling. It can then diagnose and +adjust path, permission, NVIDIA, CUDA, or CUPTI problems from live evidence. +Node.js is only needed for Skill installation, not for xprobe itself. See +[Installation](docs/installation.md) for direct CLI use and archive verification. ## Measure @@ -93,7 +83,7 @@ for safe reactivation. ## Support -| Surface | 0.3.1 support | +| Surface | 0.3.2 support | | --- | --- | | OS/architecture | Linux x86_64, glibc 2.34 or newer | | Host events | ELF function entry/return through PID-scoped uprobes | diff --git a/docs/agent-integration.md b/docs/agent-integration.md index 33b3bd2..783af88 100644 --- a/docs/agent-integration.md +++ b/docs/agent-integration.md @@ -11,13 +11,13 @@ sequences or correlation rules. ## Install the Skill The canonical directory follows the open Agent Skills format and is shared by -Codex, Claude Code, Cursor, and other compatible clients. Install the released -version through the `skills` CLI so client-specific discovery paths remain the -installer's responsibility: +Codex, Claude Code, Cursor, and other compatible clients. The user installs the +released Skill through the `skills` CLI; the activated Skill then bootstraps or +repairs the matching xprobe CLI itself: ```bash npx skills@1 add \ - https://github.com/itdevwu/xprobe/tree/v0.3.1/skills/xprobe-measure-latency \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ --global ``` @@ -26,8 +26,9 @@ For automation, add `--agent codex|claude-code|cursor --copy --yes`. Omit install its whole directory so its references, examples, and analysis script remain available. -The Skill moves from a short survey artifact to evidence-based selector -narrowing and includes `scripts/analyze_trace.py` for deterministic kernel, +The Skill checks, installs, and verifies the CLI before it first runs `doctor`. +It then maps a representative workload broadly, uses artifact evidence to narrow +selectors, and includes `scripts/analyze_trace.py` for deterministic kernel, copy, overlap, stream, and gap summaries. The xprobe repository tests installation with `skills` CLI 1.5.20 in isolated home directories. This pinned test protects released behavior while the @@ -45,8 +46,8 @@ The test requires the visible command set to be exactly `doctor`, `discover`, checks injection requirements, verifies schemas, exercises the bundled trace analyzer, and checks that the Skill uses only the four-command bounded workflow and inspects result quality/evidence. -The installation test uses the real third-party CLI with telemetry disabled and -verifies byte-for-byte copies for Codex, Claude Code, and Cursor. +The installation test uses the real third-party CLI in isolated home directories +and verifies byte-for-byte copies for Codex, Claude Code, and Cursor. This is interface conformance, not model evaluation. External harnesses may evaluate task success, command count, cleanup, mutation disclosure, and result diff --git a/docs/cli-contract.md b/docs/cli-contract.md index 34225f6..6366b53 100644 --- a/docs/cli-contract.md +++ b/docs/cli-contract.md @@ -1,6 +1,6 @@ # CLI contract -xprobe 0.3.1 exposes exactly four public commands: `doctor`, `discover`, +xprobe 0.3.2 exposes exactly four public commands: `doctor`, `discover`, `validate`, and `measure`. ## Common behavior diff --git a/docs/installation.md b/docs/installation.md index a2f9c99..acd8e0d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,13 +5,30 @@ contains the CLI and separate CUDA 12 and CUDA 13 CUPTI Agents. A CUDA toolkit is not required to install xprobe; NVIDIA driver and CUPTI availability matter only when measuring GPU events. -## User installation +## Agent-managed installation + +For agent use, install the version-matched Skill and let the agent bootstrap or +repair the CLI under a writable prefix. This is the only installation command a +user needs to run: + +```bash +npx skills@1 add \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ + --global +``` + +The Skill verifies `xprobe --version`, installs the matching release when needed, +then runs `doctor` before it profiles. It has the live context needed to adjust +PATH, prefix, permission, NVIDIA, CUDA, and CUPTI issues. Node.js is required +only for Skill installation. + +## Direct CLI installation The versioned bootstrap installs to `~/.local` without root access: ```bash curl --proto '=https' --tlsv1.2 -fsSL \ - https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.1/install.sh | sh + https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.2/install.sh | sh ``` The bootstrap downloads the release archive and its SHA256 file, verifies the @@ -30,7 +47,7 @@ prefix, download the script and pass `--prefix`: ```bash curl --proto '=https' --tlsv1.2 -fsSLO \ - https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.1/install.sh + https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.2/install.sh sh install.sh --prefix /opt/xprobe ``` @@ -42,7 +59,7 @@ script with `sudo`. The installer never elevates privileges itself. For a fully explicit archive workflow: ```bash -version=0.3.1 +version=0.3.2 base=https://github.com/itdevwu/xprobe/releases/download/v$version archive=xprobe-$version-linux-x86_64.tar.gz @@ -68,15 +85,14 @@ sh install.sh --prefix "$HOME/.local" --uninstall The uninstall operation removes only xprobe-owned files below `bin/xprobe`, `lib/xprobe`, `include/xprobe`, and `share/xprobe`. -## Agent Skill +## Manual Skill repair -The xprobe CLI works independently of an AI agent. To let an Agent discover, -validate, and run bounded measurements using the released contract, install the -version-matched Skill: +The xprobe CLI works independently of an AI agent. When a Skill installation is +missing or damaged, manually install the complete version-matched directory: ```bash npx skills@1 add \ - https://github.com/itdevwu/xprobe/tree/v0.3.1/skills/xprobe-measure-latency \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ --global ``` @@ -84,8 +100,8 @@ The command interactively selects among detected agents. A non-interactive installation names the target explicitly: ```bash -DISABLE_TELEMETRY=1 npx --yes skills@1 add \ - https://github.com/itdevwu/xprobe/tree/v0.3.1/skills/xprobe-measure-latency \ +npx --yes skills@1 add \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ --agent codex --global --copy --yes ``` diff --git a/install.sh b/install.sh index 45bbde6..b3f83fd 100755 --- a/install.sh +++ b/install.sh @@ -2,7 +2,7 @@ set -eu repository=${XPROBE_REPOSITORY:-itdevwu/xprobe} -version=${XPROBE_VERSION:-0.3.1} +version=${XPROBE_VERSION:-0.3.2} if [ -n "${XPROBE_PREFIX:-}" ]; then prefix=$XPROBE_PREFIX elif [ -n "${HOME:-}" ]; then @@ -19,7 +19,7 @@ Install a released xprobe binary and its CUDA Agents. Usage: install.sh [--version VERSION] [--prefix DIR] [--uninstall] Options: - --version VERSION Release to install (default: 0.3.1) + --version VERSION Release to install (default: 0.3.2) --prefix DIR Installation prefix (default: $HOME/.local) --uninstall Remove xprobe from the selected prefix -h, --help Show this help diff --git a/skills/xprobe-measure-latency/SKILL.md b/skills/xprobe-measure-latency/SKILL.md index 8a9ace0..6a37512 100644 --- a/skills/xprobe-measure-latency/SKILL.md +++ b/skills/xprobe-measure-latency/SKILL.md @@ -5,7 +5,9 @@ description: Investigate unknown Linux CPU/CUDA latency with bounded xprobe capt # Investigate latency with xprobe -Use JSON mode and move from a short survey to a narrow measurement. Read +Use JSON mode to make a wide, coarse workload inventory before measuring one +boundary narrowly and finely. Read [references/setup.md](references/setup.md) +to install or repair the CLI and this Skill. Read [references/investigation.md](references/investigation.md) before profiling an unknown workload. Read [references/result-quality.md](references/result-quality.md) before interpreting correlation, clocks, concurrency, or overhead. The exact @@ -13,9 +15,11 @@ CLI and selector syntax is in [references/cli-contract.md](references/cli-contra ## Workflow -1. Run `xprobe --version`. Require a version-matched xprobe 0.3.x CLI at 0.3.1 - or later and confirm every JSON response has `schema_version: "2.0"`; do not - assume a pre-0.3 or future protocol is compatible with this Skill. +1. Run `xprobe --version`. When the command is absent or not 0.3.2, read + [references/setup.md](references/setup.md) and install or repair the CLI + yourself; do not ask the user to perform a separate CLI installation. + Confirm every JSON response has `schema_version: "2.0"`; do not assume a + pre-0.3 or future protocol is compatible with this Skill. 2. Establish an application-level latency baseline. Wait for process readiness, CUDA context creation, JIT compilation, and warmup before discovery. Keep a repeatable request or batch trigger ready for the measurement window. @@ -25,13 +29,14 @@ CLI and selector syntax is in [references/cli-contract.md](references/cli-contra --no-color`. It returns NVML-confirmed CUDA context holders under that process tree. Choose a worker from workload, PID/start-time, command line, and GPU UUID evidence. Measure workers separately when several ranks are relevant. -5. If selectors are unknown, validate broad activity endpoints, then make one - short duration-bounded survey with `--events-out survey.jsonl`. For a kernel - inventory, use `cuda:kernel_start` to `cuda:kernel_end` with `exact`; keep the - survey short and give `--max-events` headroom. -6. Run `scripts/analyze_trace.py survey.jsonl`. Use its kernel names, selector - hints, duration aggregates, launch variants, stream distribution, busy union, - overlap factor, and adjacent gaps to form one narrow hypothesis. Read +5. Map the workload before choosing a name. Validate broad kernel, memcpy, or + memset activity endpoints, then collect one bounded, representative coarse + inventory per event family with `--events-out`. Scope breadth and collection + duration are independent: keep the selector broad, but choose a duration that + covers the workload cycle being diagnosed. Give `--max-events` headroom. +6. Run `scripts/analyze_trace.py` on each coarse artifact. Use kernel names, + selector hints, duration aggregates, launch variants, stream distribution, + busy union, overlap factor, and adjacent gaps to form one narrow hypothesis. Read [references/trace-analysis.md](references/trace-analysis.md) when interpreting the report. 7. Run `xprobe validate --pid WORKER_PID --from SELECTOR --to SELECTOR --match @@ -45,12 +50,15 @@ CLI and selector syntax is in [references/cli-contract.md](references/cli-contra 9. Check `status`, matched/unmatched/ambiguous/dropped counts, collection completeness, buffer utilization, clock alignment, estimated error, correlation method/confidence/score, warnings, and every evidence pair. -10. Repeat only with a stated reason: narrow the selector, select another worker - or stream, change an explicitly compatible policy, or test the next boundary. +10. Repeat only with a stated reason: select another event family, narrow the + selector, select another worker or stream, change an explicitly compatible + policy, or test the next boundary. Recheck application latency after profiling and report observed overhead. For completed captures, replace `--pid` with one or more `--input` arguments. -Use the [kernel duration](examples/kernel-duration.json), +Begin with the [coarse kernel inventory](examples/coarse-kernel-inventory.json) +or [coarse memcpy inventory](examples/coarse-memcpy-inventory.json), then use the +[kernel duration](examples/kernel-duration.json), [same-stream gap](examples/same-stream-kernel-gap.json), [host span](examples/host-function-span.json), and [memcpy duration](examples/memcpy-duration.json) specs, plus the @@ -69,4 +77,5 @@ hypothesis; orchestration remains the agent framework's responsibility. duration cannot explain warp stalls, cache misses, occupancy, instruction mix, or Tensor Core utilization; hand that question to NCU or PC sampling. - Avoid continuous or repeated exploratory capture in one production process. - Use short surveys, narrow formal measurements, and a post-profile baseline. + Use representative bounded inventories, narrow formal measurements, and a + post-profile baseline. diff --git a/skills/xprobe-measure-latency/agents/openai.yaml b/skills/xprobe-measure-latency/agents/openai.yaml index cb26558..87dfb4b 100644 --- a/skills/xprobe-measure-latency/agents/openai.yaml +++ b/skills/xprobe-measure-latency/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "Xprobe Latency Measurement" - short_description: "Investigate bounded CPU and GPU latency" - default_prompt: "Use $xprobe-measure-latency to survey this workload, derive evidence-based selectors, and measure the suspected latency boundary." + short_description: "Map broad CPU and GPU latency evidence" + default_prompt: "Use $xprobe-measure-latency to map this workload broadly, then measure the suspected latency boundary precisely." diff --git a/skills/xprobe-measure-latency/examples/coarse-kernel-inventory.json b/skills/xprobe-measure-latency/examples/coarse-kernel-inventory.json new file mode 100644 index 0000000..e64b0a6 --- /dev/null +++ b/skills/xprobe-measure-latency/examples/coarse-kernel-inventory.json @@ -0,0 +1,15 @@ +{ + "schema_version": "2.0", + "name": "coarse_kernel_inventory", + "target": { + "pid": 1234, + "process_start_time": 987654 + }, + "start_selector": "cuda:kernel_start", + "end_selector": "cuda:kernel_end", + "match_policy": "exact", + "samples": null, + "duration_ms": 1000, + "timeout_ms": 30000, + "max_events": 200000 +} diff --git a/skills/xprobe-measure-latency/examples/coarse-memcpy-inventory.json b/skills/xprobe-measure-latency/examples/coarse-memcpy-inventory.json new file mode 100644 index 0000000..f8ae56e --- /dev/null +++ b/skills/xprobe-measure-latency/examples/coarse-memcpy-inventory.json @@ -0,0 +1,15 @@ +{ + "schema_version": "2.0", + "name": "coarse_memcpy_inventory", + "target": { + "pid": 1234, + "process_start_time": 987654 + }, + "start_selector": "cuda:memcpy_start", + "end_selector": "cuda:memcpy_end", + "match_policy": "exact", + "samples": null, + "duration_ms": 1000, + "timeout_ms": 30000, + "max_events": 200000 +} diff --git a/skills/xprobe-measure-latency/references/investigation.md b/skills/xprobe-measure-latency/references/investigation.md index f72b7ef..8e7dfb1 100644 --- a/skills/xprobe-measure-latency/references/investigation.md +++ b/skills/xprobe-measure-latency/references/investigation.md @@ -14,10 +14,12 @@ as a candidate. Map GPU UUID and command/rank metadata to workload ownership. Measure multiple relevant workers one at a time. After a restart, rerun discovery and use PID plus procfs start time; never reuse an old PID-only choice. -## Survey before selecting +## Map broadly before selecting -When kernel names are unknown, first validate and collect all kernel activity for -a short window: +When kernel names are unknown, first validate and collect all kernel activity. +Choose `REPRESENTATIVE_WINDOW_MS` to cover one steady-state request, batch, or +iteration cycle, not an arbitrarily short interval. The capture is always +bounded; its duration must still preserve the behavior being diagnosed. ```bash xprobe validate --pid "$PID" \ @@ -26,18 +28,39 @@ xprobe validate --pid "$PID" \ xprobe measure --pid "$PID" \ --from cuda:kernel_start --to cuda:kernel_end --match exact \ - --duration-ms 250 --timeout-ms 5000 --max-events 200000 \ - --events-out survey.jsonl --format jsonl \ + --duration-ms "$REPRESENTATIVE_WINDOW_MS" --timeout-ms "$TIMEOUT_MS" \ + --max-events "$MAX_EVENTS" --events-out coarse-kernels.jsonl --format jsonl \ --json --non-interactive --no-color -skills/xprobe-measure-latency/scripts/analyze_trace.py survey.jsonl \ - > survey-analysis.json +skills/xprobe-measure-latency/scripts/analyze_trace.py coarse-kernels.jsonl \ + > coarse-kernels-analysis.json ``` -Treat these numbers as starting bounds, not universal defaults. On -`EVENT_RATE_TOO_HIGH`, inspect the written artifact and error counters. Shorten -the duration or use a simple prefix/suffix/contains selector before raising -capacity. Preserve the artifact as evidence for the change. +Map copies and memsets in separate bounded captures when they could matter: + +```bash +xprobe validate --pid "$PID" \ + --from cuda:memcpy_start --to cuda:memcpy_end --match exact \ + --json --non-interactive --no-color + +xprobe measure --pid "$PID" \ + --from cuda:memcpy_start --to cuda:memcpy_end --match exact \ + --duration-ms "$REPRESENTATIVE_WINDOW_MS" --timeout-ms "$TIMEOUT_MS" \ + --max-events "$MAX_EVENTS" --events-out coarse-memcpy.jsonl --format jsonl \ + --json --non-interactive --no-color +``` + +Do not guess a named kernel or host function in this stage. CUDA API selectors +require a concrete Runtime or Driver API name, so inventory activity first and +choose API boundaries from application, framework, or trace evidence later. +Analyze each artifact separately; busy union only describes the capture window +inside that artifact. + +Treat capacity as a consequence of observed event rate, not a universal default. +On `EVENT_RATE_TOO_HIGH`, inspect the written artifact and error counters. First +split event families or reduce selector scope while retaining a representative +cycle; reduce duration only when the remaining window is still representative. +Preserve the artifact as evidence for the change. ## Derive CUDA selectors @@ -70,7 +93,7 @@ stripped or local code, derive a file offset with `readelf`/`objdump` and use `validate`; do not infer a runtime virtual address from one process and reuse it as a file offset. -## Narrow one hypothesis +## Measure one narrow hypothesis Choose one next boundary from evidence: @@ -85,7 +108,7 @@ completed artifact with `measure --input` when only selectors or policy change; do not attach again merely to recompute pairing. ```bash -xprobe measure --input survey.jsonl \ +xprobe measure --input coarse-kernels.jsonl \ --from 'cuda:kernel_start:name~^selected_kernel$' \ --to 'cuda:kernel_end:name~^selected_kernel$' \ --match exact --samples 100 --max-events 200000 \ diff --git a/skills/xprobe-measure-latency/references/result-quality.md b/skills/xprobe-measure-latency/references/result-quality.md index b0a2f8f..f7e1391 100644 --- a/skills/xprobe-measure-latency/references/result-quality.md +++ b/skills/xprobe-measure-latency/references/result-quality.md @@ -42,9 +42,10 @@ max_events >= minimum_records + expected_unmatched_records ``` Use at least 2x headroom for stable narrow selectors and 4-10x for high-rate or -broad surveys. For a duration survey, size from a pilot artifact's observed -records per second. Increasing max-events without narrowing a noisy selector -only increases profiler work. +broad inventories. For a duration inventory, size from a pilot artifact's +observed records per second. Keep enough duration to cover a representative +cycle; increasing max-events without narrowing a noisy selector only increases +profiler work. `duration-ms` limits correlation to a window beginning at the first selected event. In live mode it also sets a collection stop from ARM completion, so finish diff --git a/skills/xprobe-measure-latency/references/setup.md b/skills/xprobe-measure-latency/references/setup.md new file mode 100644 index 0000000..3fb109c --- /dev/null +++ b/skills/xprobe-measure-latency/references/setup.md @@ -0,0 +1,63 @@ +# Setup + +Use this reference at the start of a task when the CLI is absent or its version +does not match this Skill. The user installs this Skill once; the agent performs +and verifies the CLI bootstrap. Do not ask the user to run a second installation +command unless their environment prevents the agent from writing a usable prefix. + +## Check and bootstrap xprobe + +Check the executable first. Continue only when it reports 0.3.2; otherwise run +the bootstrap below: + +```bash +if command -v xprobe >/dev/null 2>&1; then + xprobe --version +fi +``` + +Download the released bootstrap, which verifies the release archive before +installing under `~/.local`: + +```bash +curl --proto '=https' --tlsv1.2 -fsSL \ + https://raw.githubusercontent.com/itdevwu/xprobe/v0.3.2/install.sh \ + -o /tmp/xprobe-install.sh +sh /tmp/xprobe-install.sh +export PATH="$HOME/.local/bin:$PATH" +xprobe --version +xprobe doctor --json --non-interactive --no-color +``` + +Use the downloaded script's `--prefix` option for another installation root. +Export that prefix's `bin` directory into `PATH`, rerun `xprobe --version`, then +run `xprobe doctor --json --non-interactive --no-color`. Surface bootstrap, +PATH, permission, driver, CUDA, or CUPTI failures explicitly and adjust from the +reported detail; do not continue to measurement on an unverified installation. +The CLI needs no Node.js. CUDA is optional until a GPU selector is measured. + +## Repair the Skill only when needed + +The user normally installed this Skill before invoking the agent. When its files +are missing or the version is not 0.3.2, install the complete version-matched +directory through the Agent Skills CLI: + +```bash +npx skills@1 add \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ + --global +``` + +For non-interactive automation, select the host explicitly: + +```bash +npx --yes skills@1 add \ + https://github.com/itdevwu/xprobe/tree/v0.3.2/skills/xprobe-measure-latency \ + --agent codex --global --copy --yes +``` + +Replace `codex` with `claude-code` or `cursor` as needed. Omit `--global` for a +repository-scoped installation. Without Node.js, copy the full Skill directory +from the release archive into the target agent's documented Skill location; do +not copy only `SKILL.md`, because its references, examples, and analyzer are +part of the contract. diff --git a/skills/xprobe-measure-latency/references/trace-analysis.md b/skills/xprobe-measure-latency/references/trace-analysis.md index 54cd252..a745d60 100644 --- a/skills/xprobe-measure-latency/references/trace-analysis.md +++ b/skills/xprobe-measure-latency/references/trace-analysis.md @@ -28,7 +28,9 @@ Read the report in this order: `selector_hint` is exact for names shorter than the CUPTI filter bound. For long names it may be a prefix or suffix unique only among names observed in that -capture; validate it and repeat a narrow survey before treating it as stable. +capture; validate it and repeat a narrow measurement before treating it as +stable. Analyze every broad inventory separately; the report never establishes +wall-clock relationships between distinct capture windows. The analyzer reports descriptive activity timing. It does not assign work to a request, calculate kernel hardware efficiency, or turn temporal proximity into diff --git a/tests/agent-contract/test_contract.py b/tests/agent-contract/test_contract.py index 8498e22..850dc69 100755 --- a/tests/agent-contract/test_contract.py +++ b/tests/agent-contract/test_contract.py @@ -74,7 +74,8 @@ def check_skill(workspace: pathlib.Path) -> None: assert quality_field in normalized_skill for investigation_step in ( "application-level latency baseline", - "short duration-bounded survey", + "representative coarse inventory", + "Scope breadth and collection duration are independent", "scripts/analyze_trace.py", "selector hints", "busy union", @@ -107,6 +108,7 @@ def check_skill(workspace: pathlib.Path) -> None: investigation = (skill_root / "references/investigation.md").read_text() quality = (skill_root / "references/result-quality.md").read_text() trace_analysis = (skill_root / "references/trace-analysis.md").read_text() + setup = (skill_root / "references/setup.md").read_text() normalized_investigation = re.sub(r"\s+", " ", investigation) normalized_quality = re.sub(r"\s+", " ", quality) normalized_trace_analysis = re.sub(r"\s+", " ", trace_analysis) @@ -116,6 +118,8 @@ def check_skill(workspace: pathlib.Path) -> None: "EVENT_RATE_TOO_HIGH", "readelf -Ws", "NO_MATCHED_SAMPLES", + "representative cycle", + "concrete Runtime or Driver API name", ): assert required in normalized_investigation for required in ( @@ -131,8 +135,16 @@ def check_skill(workspace: pathlib.Path) -> None: "summed_activity_ns", "launch_variants", "Cross-stream", + "distinct capture windows", ): assert required in normalized_trace_analysis + for required in ( + "v0.3.2/install.sh", + "npx skills@1 add", + "xprobe --version", + "xprobe doctor", + ): + assert required in setup engineering_rules = re.sub( r"\s+", " ", (workspace / "AGENTS.md").read_text()