Przejdź do treści
Biblioteka skilli
Programowanie · Przegląd i audyt

report

/report

Określa, jakie dowody musi mieć ustalenie wydajności z profilu Jeffrey Microscope i jak cytować liczby.

Repozytorium
jeffrey ↗
Licencja
Apache-2.0
Ostatnia zmiana repozytorium
12.11.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
2
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 12.11.2026, bez odwołań do wycofanych modeli i API.

Licencja

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

Co robi i kiedy

Określa, jakie dowody musi mieć ustalenie wydajności z profilu Jeffrey Microscope i jak cytować liczby.

Wyzwalacze z opisu

what did you find
Oryginalny opis (EN)

The shape and the evidence rules for any performance finding drawn from a Jeffrey Microscope profile — what a finding must carry before it is worth writing down, how a figure is quoted and against what denominator, what caps a claim at medium confidence, and how the questions a recording cannot answer are reported apart from the findings. Use whenever writing up an analysis, summarising an investigation, answering "what did you find", or handing conclusions to another person or agent — after analyze-jfr, analyze-heap, compare-jfr, regression-check or optimize-code has done the reading, and jus

Jak działa

  1. The shape
  2. The evidence rule
  3. Shares and rates, with the denominator stated
  4. Confidence, honestly
  5. Absence of evidence
  6. Reproducibility
  7. What a recommendation must contain
  8. Where the report is written
  9. Never
Sekcje z nagłówków SKILL.md, w oryginale · 236 linii, 2 414 słów
Podgląd SKILL.md
---
name: report
description: The shape and the evidence rules for any performance finding drawn from a Jeffrey Microscope profile — what a finding must carry before it is worth writing down, how a figure is quoted and against what denominator, what caps a claim at medium confidence, and how the questions a recording cannot answer are reported apart from the findings. Use whenever writing up an analysis, summarising an investigation, answering "what did you find", or handing conclusions to another person or agent — after analyze-jfr, analyze-heap, compare-jfr, regression-check or optimize-code has done the reading, and just as much when the user brings findings from an earlier analysis and asks for them written up ("write that up for my team"), whose figures are read back from Jeffrey before they go into the report.
---

# Reporting a finding

A performance report is an argument, and an argument needs evidence. The standard is one sentence:
a reader who never saw a tool result must be able to re-run every number in the report. Everything
below follows from that.

## The shape

Findings ranked by impact — the share of the recording's wall clock, of its samples, or of its heap
that each one accounts for — never by how confident the wording sounds. Each in this shape:

> **Symptom** — what the user or the system observes.
>
> **Evidence** — the tool call, its arguments, and the figures exactly as the tool printed them.
>
> **Interpretation** — what the figures mean, and why this explanation rather than another.
>
> **Recommendation** — the change, at a named location; or "none yet", and what would be needed.
> When the location is in the repository the agent runs in, end it with "— apply with *Implement
> fixes*", the option that hands it to `optimize-code`.
>
> **Confidence** — high, medium or low, and what would raise it.
>
> **Link** — the `uiLink` of the answer the evidence came from, for the reader to open.

Then, separately and always: **Not assessed** — what this profile could not answer, and why.

When the analysis kept a ledger (Covered / Open leads / Not assessed, as `analyze-jfr` keeps it),
build from it: each **Covered** area that found something becomes a finding, its **Not assessed**
entries become that section, and its **Open leads** close the report as next steps the user can
choose, each with its weight — offered, not run.

Keep it short. Three findings that carry their evidence beat twelve that do not.

## The evidence rule

Every quantitative claim names the call that produced it, with the profile id and the arguments
that shaped the result:

> Threads blocked on `com.example.SessionCache` for 41.2 s in total over a 300 s recording — about
> 13 contentions a second, each 10.8 ms on average.
> Evidence: `blocking_monitors profileId=p-7c1` → `SessionCache` total 41,203 ms over 3,812
> contentions; recording length from `profiles_summary` (`startedAtEpochMs` to
> `finishedAtEpochMs`) = 300.4 s.

Blocked time is summed over threads, so it is not a share of wall clock: eight threads blocked for
the whole recording add up to eight times its length. Quote it as a total, a rate or a per-contention
average, or as a share of the time the *blocked threads* existed — never "N% of wall clock".

If you cannot name the call, you cannot make the claim. Delete it, or go and measure it.

That holds for a figure the user hands you too — "most of the CPU is in X", "it blocks for about 80
seconds". It is the question the report answers, not its evidence: when the profile is in Jeffrey,
read each figure back with the call that measures it before writing it down, and report what that
call said, even where it disagrees. The call that measures it, by kind of figure:

| The figure | Read back with |
|---|---|
| A statement's count or time ("an extra COUNT query costs 1.2 s") | `jdbc_overview`, then `jdbc_statementGroup` for its group; `code_callSites` for who issues it |
| A request step's time | `traces_operationExport` of the operation, which totals each span across its requests |
| An endpoint's latency | `traces_operations` (`sort: P95`) |
| Allocation, or "more than before" | `memory_allocations`; `compare_movements` against the baseline for a change |
| Where the CPU goes | `code_hotspots` with the repository's packages, or the CPU `flamegraph_export` |
| Lock or GC time | `blocking_monitors`; `jvm_gc` |

A count or a duration a dashboard holds is quoted from that dashboard: a flamegraph searched for a frame
shows where it ran, not the figure the user named.

A claim drawn from a file rather than a tool — an application log, a GC log or a crash file that
`connector_fetchFile` put on this machine — names the file and the line instead, so the reader can open
the same line:

> The JVM died of `SIGSEGV` in `libzip.so` while `main` was inside `Inflater.inflateBytes`.
> Evidence: `hs-jvm-err.log`, fetched from session `0199a3f2…` of instance `checkout-7d9f` by `connector_fetchFile` to
> `~/.jeffrey-microscope/artifacts/…/hs-jvm-err.log`, lines 1–12 and the `Java frames:` block
> at lines 38–46.

Tool names above omit the prefix your client puts in front of them — per host in `references/tool-prefixes.md`.

## Shares and rates, with the denominator stated

The exports already speak in shares: a frame's `total` and `self` are percentages of *that
export's* total. Quote them as such, and say what the total was — how many samples, bytes or
nanoseconds — and what shaped it: the `thresholdPct`, a `startEpochMs`/`endEpochMs` window, `useWeight`,
`excludeIdle` — the export's structured answer records every one of them. A share of a filtered export is not a share of the recording.

Everything else needs a denominator before it means anything:

- **events → per second**, using the recording length from `profiles_summary` or `profiles_get`
- **pause time → fraction of wall clock**: 200 ms of GC pause is 0.07% of a five-minute recording
  and 10% of a two-second one; the count of collections says nothing on its own
- **allocation → MB/s**, and say it is estimated from sampled weights when the source is
  `jdk.ObjectAllocationSample`
- **a heap figure → retained bytes**, never shallow; and against the heap's total

A profile built from a **window of a connector session** — `connector_download` with `startEpochMs`/`endEpochMs`
or `fileIds` — is that window, not the session. Its recording length is the span the chunks cover,
which `connector_download` reported as `coveredStartEpochMs`/`coveredEndEpochMs`; name that span with every rate drawn
from it, and never extrapolate a rate or a count across the session it was cut from. "12 GC pauses
in the 14:00–14:30 window" is a finding; "about 600 a day" is not.

Counts from two recordings of different lengths are not comparable. `compare_list` reports both
lengths and `compare_movements` scales the baseline onto the primary's; a comparison you do by hand
has to do the same, or say that it did not.

## Confidence, honestly

| Level | When |
|---|---|
| **High** | Direct measurement of the thing itself — a trace's span timings, a monitor's blocked time, a dump's retained size — with a large sample, corroborated by a second tool |
| **Medium** | A strong single-tool signal, or an inference from a well-understood mechanism |
| **Low** | A heuristic, a small sample, a correlation in time only, or a source that is known to be approximate |

Things that cap a finding at **medium** at most, and must be said out loud when they apply:

- **Sampled data.** `jdk.ExecutionSample`, `jdk.CPUTimeSample`, `profiler.WallClockSample` and
  `jdk.ObjectAllocationSample` are samples, not a census. A frame at 0.4% of 800 samples is three
  samples.
- **A lossy sampler.** `profiles_samplerHealth` reports the CPU-time samples the kernel dropped.
  Loss lands during the busiest moments, so a lossy recording *understates* its own hot paths —
  say the loss share beside any share you quote from it.
- **The auto-analysis rules.** `jvm_autoAnalysis` applies fixed thresholds that know nothing about
  this service's normal behaviour. A rule that fired is a lead worth following into the matching
  `jvm_` section for the figures (its `nextTool` is that call); it is not a diagnosis, and its
  `action` is not a recommendation until the figures support it.
- **Leak candidates.** `memory_leakCandidates` lists objects that survived collections. Survival is
  not retention: without a heap dump and a GC-root path it stays a candidate.
- **Comparison limitations from `compare_list` and `compare_quality`.** The latter returns
  evidence, not a single verdict. Different or unknown sampling settings, thin profiles and sample
  loss limit confidence in the affected event type. Duration differences require an explicit
  exposure denominator. `workloadNormalization.available=false` rules out a per-request claim
  from recorded counts alone, not a qualified hotspot-share comparison. State the limitation next
  to the affected figure; use `compare-jfr` to interpret the fields.
- **Time overlap.** "During the same window as" is concurrency, not cause. Report it as
  *concurrent with*, and prove cause with a code path or a fix that measurably helped.
- **A frame you never read in source.** Until the file has been opened — with your own tools or
  through `ide_resolve` — a finding names a frame, not a line.

## Absence of evidence

A profile can only answer what its recording captured. Read `capabilityGaps` in `profiles_summary`
before you believe a negative result, and carry every gap that touches the question into the
**Not assessed** section, with the remedy the gap names.

- "No allocation hotspots found" is wrong when the allocation group is in `notRecorded`. The true
  statement is "allocation was not assessed: the recording holds no `jdk.ObjectAllocationSample`
  events", plus how to enable it next time.
- `blocking_`, `io_` and `jvm_jit` read event types that are **threshold-gated**: a recording holds
  none either because nothing crossed the threshold or because the profiler was never asked. The
  tools answer `NOT_RECORDED` with a `reason` saying which, and the two are different sentences in
  a report. A status that says the data is missing — `NOT_RECORDED`, `NOT_COMPUTED`, `NOT_RUN_YET`,
  `NO_TRACES`, `EMPTY` — belongs under **Not assessed**, quoted with its `reason`. Statuses such as
  `COMPUTED`, `READY`, `DOWNLOADED` or `COMPLETED` are success, not gaps.
- A feature in `disabledFeatures` — traces, the HTTP or JDBC dashboards, a heap dump — was never
  instrumented or captured. Its absence is a fact about the recording, not about the application.
- A rule under `notEvaluated` in `jvm_autoAnalysis` had no events to run on. It did not pass.
- A heap report that has not been computed is built by `heap_prepare`; an empty retained ranking
  before that is a signal to prepare, never a finding that nothing retains memory.

## Reproducibility

End with the profile id — both ids for a comparison, saying which is the baseline — and the calls
in the order they were made, with their arguments, so the reader or the next agent can re-run
the whole thing:

```
profiles_summary profileId=p-7c1
blocking_overview profileId=p-7c1
blocking_monitors profileId=p-7c1
flamegraph_export profileId=p-7c1 eventType=jdk.JavaMonitorEnter useWeight=true thresholdPct=1
```

For a regression claim, the two profiles and the `compare_list` and `compare_quality` calls are the
reproduction. Where an answer's `followUp.nextTools` produced the next call, cite that entry — the
tool and its arguments exactly as the answer gave them — rather than retyping it: it carries the
ids, the epoch-millisecond window and the cursor that answer was about.

**Give the reader the link — for everything the report names.** Every answer about something
Microscope has a page for carries a `uiLink` — the same profile and view, with the same event type,
filters, window, search and baseline — and a row that names its own thing (a trace, an operation, an
exemplar) carries its own. Make each name a Markdown link marked with `↗` — `[name ↗](<its uiLink>)`,
never the bare URL, since a terminal shows the marked name as the link and hides the URL: the
finding's **Link** line, and every trace, operation, class, endpoint or page named anywhere in the
text, so nothing the reader might want to see needs looking up. Quote the `uiLinkNote` when there is one,
saying what the page does not reproduce. No link in hand for a profile page → `profiles_viewLink`;
never build or edit a URL. It is for the person reading; never fetch it or read it back. Nothing is
exported to a file: the data is in the answers, the picture is behind the link.

A profile id alone names a thing that can change under the reader — a report computed later, a
finding re-evaluated, the profile deleted. `profiles_evidence` (the MCP resource
`jeffrey://profile/{profileId}/evidence` is the same document) is the versioned snapshot to cite
beside it: the recording's identity and build, the whole-recording units and denominators, the
sampling settings it was recorded with, the findings as they were evaluated and the capability gaps
as they stood, with the `followUp` calls that re-read it and the omission counts of every bounded
collection. It is
a live snapshot rather than an archive, so save what it returned with the report; a reader can then
check the figures against what the profile said at the time rather than what it says now.

## What a recommendation must contain

Not "reduce allocations", but: the file and line, read from source; the change; the expected
effect with its basis; and how it will be verified.

> `OrderService.reprice` (`src/main/java/com/example/OrderService.java:118`) allocates a new
> `HashMap` per call inside the pricing loop and carries 34% of sampled allocation weight
> (`flamegraph_export eventType=jdk.ObjectAllocationSample useWeight=true`). Hoisting it out of the
> loop should remove most of that share. The effect is on allocation rate and young-collection
> frequency, not on p99 directly — confirm with a re-profile and `compare_movements` on the same
> event type with the same export parameters.

Keep **configuration findings** apart from code findings and labelled as such — a pool that ran
out of connections, a flag left at its ergonomic default, a container quota the scheduler
enforced. They are real, often the largest single win, and none of them is an edit; they are
verified on the application's next run, not by a test. The `optimize-code` skill has the full shape.

If you did not locate the code, say so and give the frame rather than inventing a path.

## Where the report is written

When a `jfr-analyst` or `heap-analyst` agent did the reading, it returns the findings with their
evidence in this shape and stops there: it has no file tools and makes no recommendations. Mapping a frame onto the checkout, the recommendation, and every question put to
the user belong to the session that delegated — add them there, in the same shape, before the
report goes to the reader.

## Never

- Report a number you did not see in a tool result in this session. Never estimate, round a figure
  you did not see, or carry a total from one export into another.
- Present a threshold breach as a diagnosis.
- Claim an improvement without a measured comparison. "This should be faster" is a hypothesis and
  is labelled as one; `compare_movements` on a re-profile is the measurement.
- Swap the primary and the baseline to make a result read better.
- Let a gap pass as a clean result. A question the recording could not answer is reported as such,
  in its own section, every time.
Pliki w paczce (2)
  • SKILL.md 15 KB
  • references/tool-prefixes.md 1 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · petrbouda/jeffrey100Apache-2.0
petrbouda/jeffrey100Apache-2.0
onmax/comark-ui100MIT
renzrollon/interlock100MIT
digital-stoic-org/agent-skills100MIT
90p-labs/harness100MIT
emaballarin/ccplugins100MIT
quantskills/agent-quantspace100GPL-3.0
magnifito/domain-name-engine100MIT

Migawka bazy z 13.11.2026 · wersja paczki c4301f2e75e8 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100compare-jfr
    Porównuje dwa profile JVM w Jeffrey Microscope za pomocą różnicowych flamegraphów, by sprawdzić, czy zmiana spowolniła aplikację lub zwiększyła alokacje.
  • 90help
    Wyjaśnia, co Jeffrey Microscope może zbadać w zapisie JFR i zrzucie sterty oraz które umiejętności obsłużą każdy obszar.
  • 100docker-jfr-benchmark-loop
    Prowadzi powtarzalną pętlę wydajnościową RDF4J dla jednego benchmarku JMH w Dockerze z Linux Java 26 i profilowaniem CPU w JFR: baseline, poprawka i ponowny pomiar.
  • 100docker-jfr-benchmark-loop
    Prowadzi powtarzalną pętlę wydajnościową RDF4J dla jednego benchmarku JMH w Dockerze z Linux Java 26 i profilowaniem CPU w JFR: baseline, poprawka i ponowny pomiar.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.