Turn it on for a service
1
Open Code improvement
Click Code improvement in the sidebar, in the Prevent section. The page lists the
findings and, under Scan settings, your services.
2
Switch a service on
Under Scan settings, tick Scan this service for a service, open Kinds of behaviour
to untick any kind you do not want looked for, and click Save. The first scan runs within
about half an hour and then every six hours.
3
Connect a trace source if you have not
The scan reads traces from Tempo, Jaeger or X-Ray, whichever you connected first, and gauges
from Prometheus. Without any of them a window is skipped and costs nothing. See Connect your
data.
What it looks for
A finding with too little data behind it is not shown.
Read a finding
Findings are ranked by impact and confidence. Each row shows the service, the kind, how many scans have seen it, a confidence and an impact, and a What the scan measured disclosure with the numbers behind it (repeat counts, percentiles, the table or route involved). Confidence and impact rank findings against each other. They are estimates from a sample, not measurements to quote. The tabs split the list into Open, Pull request, Fixed, Ignored and Suppressed, each with its count.Act on a finding
Organization admins see these buttons:
Approve goes through the same checks as every other code fix. The finding is placed in your repository from what the trace showed (a stack frame, a code attribute, a route), and if it cannot be placed no pull request is opened. The fix must stay inside the files your repository mapping allows. Your Self-healing switches (the organization and the service allowed, the Pull requests channel on), pauses, per-repository limit of five open fix pull requests, hourly budget and confidence floor apply, with their reasons shown if one stops it. The pull request is a draft, checked in the sandbox where the repository has a verification profile (see Request a fix as a pull request).
A finding with nothing that points at code, such as a growing gauge, has no Approve button and says so. When one of the checks that needs no repository read would stop the pull request (a Self-healing switch, the confidence floor, a suppressed problem, a file type your repository mapping does not allow), Approve is shown disabled with the reason beside it.
While a finding’s pull request is open, Ignore and Suppress for 30 days are hidden; they return when the pull request ends. If a reviewer asks for changes and the revision replaces the pull request, the finding follows the revision.
After Approve, the finding moves to the Pull request tab with a link. When the pull request is merged the finding becomes Fixed. If it is closed without merging the finding returns to Open, and if the same behaviour has had two pull requests closed without merging in the last 30 days it is suppressed for 30 days instead.
After a pull request merges
Merging is not the end of a finding. When one of these pull requests is merged, the page says where the check stands under the finding:- Waiting for the next deploy of the service. A successful deploy that names the pull request is when the change took effect. If your deploys name their pull request at all, the deploy that names this one is waited for, up to the 7 days. Where no deploy names it, the first successful deploy of the service after the merge is used (a deploy that states a staging, QA or other non-production environment, or that names a different pull request, is skipped), and the page says so. If the service is not deployed within 7 days, the finding shows Not checked and says why.
- Deployed. Ten minutes after the deploy, a window of six hours begins. When it is over, the scan reads that window with the same detector that found the behaviour, and says one of:
- Confirmed. The behaviour is gone, and the sample was big enough to have shown it: at least as many traces of the same route, table or call as the scan needs to report that kind of behaviour at all (two for most kinds, five for a slow endpoint). If the behaviour is still there in fewer traces than that, it is not confirmed; the next window is read.
- Not fixed. The scan still finds it. The finding returns to Open.
- Worse. It is at least one and a half times as strong as before and at least ten points stronger. The finding returns to Open, a card is opened on your board, and a revert is proposed.
A proposed revert
A revert is only a proposal. Under the finding an organization admin sees Request the revert and Not now. Request the revert goes through the same checks as Approve and first reads the pull request from GitHub (what it changed in each file, and which files later commits changed again) and asks for a draft pull request that undoes it, naming its files so the change stays in the service’s own region. If GitHub cannot show the whole change, nothing is requested and the page says why: the pull request is gone, GitHub refuses the App access to pull requests, a file’s patch is too long to read or was left out by GitHub (a very large or binary diff), or the pull request has more files than can be read. In that last group use the Revert button on the merged pull request in GitHub, because a revert written from part of a change would undo only that part. A repository whose fixes run in your own CI or on your own fix runner gets no revert from here for the same reason; set its fix runner to the platform, or revert on GitHub. Nothing is merged for you. If the request fails, the agent declines or the revert pull request is closed, the proposal comes back and you can ask again; once the revert is merged it is marked done.Your own history changes the list
The How your pull requests fared table at the bottom of the page counts, for each kind of behaviour and repository, the pull requests that were merged, closed without merging, edited (merged after a reviewer added commits to the branch; counted where your plan reads what reviewers do to a pull request), and worse after deploy (merged, then found worse by the check; it does not count as accepted). It is your organization’s own history: nothing is learned from anyone else’s, and nothing you do here is used for anyone else.- A kind you merge ranks higher, and one you close ranks lower. Under the finding, a line says so (“Ranked lower: 1 of 5 pull requests of this kind were merged in acme/api.”).
- When the last three pull requests of a kind in one repository were all closed without merging, new findings of that kind arrive suppressed for 30 days instead of open, and the Suppressed tab says why. Reopen puts any of them back. A merged pull request ends the pattern.
Who reviews the pull request
A draft pull request from a finding asks for review from the people who know the code, and its description says who and why:- the owners of the changed files in your CODEOWNERS file (the last matching line wins; a user, or a team of the repository’s own organization);
- whoever last changed the lines the finding points at;
- whoever merged the last fixes in those files.
From an MCP client
Five tools do the same from an MCP client, with the same checks:list_code_findings, get_code_finding and list_verification_runs read; approve_code_finding and ignore_code_finding need an organization admin’s personal token, because an approval is a person’s. They are offered only where Code improvement is available.
How many scans you get
Each scan of one service’s six hour window that reads your telemetry is one scan. The page shows how many your plan includes this month, how many you used, how many are left and the day the count resets. A window with nothing to read is free, and a window scanned again does not count twice.
These numbers are starting values and will change as real usage is measured. When the allowance is spent, scans resume on the first of the next month; findings you already have stay.
What is stored
The scan keeps a finding’s kind, a hash that recognises the same behaviour on the next scan, a title that names a route, table or exception type, its confidence and impact, aggregate numbers, up to five trace ids and a short hint for placing it in code. It does not keep traces, SQL statements with their values, URLs with their query strings or exception messages. A URL path is reduced to a route template in which only common route words (api, users, orders, health) and API versions survive and every other segment, such as a user name, an organization slug or a project name, is :id; a host or address is :host or :ip; a span name keeps common words and is :id elsewhere. Every text is redacted for secrets before it is stored. Findings and the record of how their pull requests ended (which pull request, whether it merged, the numbers the check found) are deleted with the organization.
Limits
- The scan reads a sample (up to 40 traces per service per scan), so it finds behaviour that recurs, not every slow request.
- The scan uses its own request budget against your trace and metric sources: at most 60 requests a minute per organization.
- It reads traces from Tempo, Jaeger and X-Ray and gauges from Prometheus. Traces from Elasticsearch, Datadog, New Relic and Zipkin, and gauges from CloudWatch, Datadog and New Relic, are not read yet, so the resource leak kind needs Prometheus.
- It does not run for the demo organization, for a paused organization or while the platform pause is on.