Metrics
Every number Wystan shows, in the dashboard, pull request comments, Slack, MCP and reports, comes from one set of definitions. For each metric this page says what it stands for, how we compute it and where it stops being reliable. Missing evidence is shown as unavailable or not measured, never as zero.
At a glance
Journey test evidence
per user journey · read from your e2e specsWhat it meansFor each user journey, one of four answers: an end-to-end test visits it, only integration tests reach its code, no test reaches it, or it could not be measured. Journeys with no code attached and system journeys (such as background jobs) keep their own labels and are never counted as untested.
What it's forSee which user journeys have no end-to-end test before you change them.
Why it mattersBefore a change merges, reviewers see which of the journeys it reaches have no end-to-end test, with the spec file and test title as proof when one exists. A journey we could not measure is never reported as untested.
How it's computedWe never run your tests. We read your Playwright and Cypress spec files and collect the URLs each test visits or calls (page visits, URL checks and API requests), with the base URL removed and simple template strings turned into route patterns. Each journey's routes come from the scan: the entry routes of its flows. A test URL matches a journey route exactly, with parameters, or by prefix. A journey counts as end-to-end tested when a test visits one of its routes, or when one test covers at least 60% of its routes. Otherwise it counts as integration-only when integration tests reach at least 5% of its files, and as untested when nothing does. Receipts are the matching tests, written <spec>::<test title>.
Valid comparisonsWithin one repository scan only.
- It is a lower bound: pages a test reaches by clicking after its first visit are not seen.
- Only Playwright and Cypress are read; journeys in repositories with other frameworks show as not measured, never as untested.
- URLs built while the test runs cannot be read from the code; the scan counts them as unresolved instead of guessing.
- Visiting a route does not prove that the test checks the right outcome, or that it passes.
- Checked against real coverage on 3 repositories: 36 of 41 journeys it marked as end-to-end tested were confirmed (88%).
How to improve itBefore changing a journey without an end-to-end test, add one that visits it and checks its outcome. A journey that is not measured first needs Playwright or Cypress, or a test URL the parser can read: a plain string rather than one built while the test runs.
Blast radius / affected flows
per pull request · shared-file reachWhat it meansThe product features and user journeys a pull request changes, and for each product feature, how many other mapped flows share files with the flows it touches.
What it's forDecide who needs to review a pull request before it merges: which product features and user journeys it changes, and how widely the touched code is shared.
Why it mattersReviewers see the change in product terms, the parts of the product a customer could notice, and how far the touched code reaches into the rest of the map. It is structural reach from the feature map, not a probability of breakage.
How it's computedWe match the pull request's changed files against the repository's scan. A feature is affected when a changed file is one of its files, sits in one of its folders, or sits next to one of its files. A flow is touched when a changed file is its entry point or holds one of its functions; a user journey is touched when one of its flows is. Rows are grouped by product feature. For every flow, the scan records how many other mapped flows use at least one of the same files; a row shows the maximum of that number across its touched flows, and nothing when it is zero.
Valid comparisonsOne pull request against a scan of the same repository.
- Overlap is file-level: a changed file counts even when the edited lines sit outside a flow's own code.
- The number is the largest count for a single flow in the row, not a total across its flows.
- Shared files are not proven runtime dependencies, and a low or missing count does not make a change safe.
- It is only as accurate as the feature map; changed files outside every mapped feature add no reach.
How to improve itBring the owners of the touched journeys and of the most widely shared flows into the review, and add tests on the journeys the change reaches. Splitting a pull request changes its reach, not how coupled the code is.
Future fix-work rank
0–100 · rank within this repositoryWhat it meansWhere this repository's future fix work is most likely to concentrate, as a rank from 0 to 100 among its own features. It is an ordering, not a probability.
What it's forDecide where to spend review and test attention among the features of one repository in the next planning period.
Why it mattersUse it to build a review watchlist, then check the top features against test evidence, ownership and business importance. A rank of 90 does not mean a 90% chance of a defect.
How it's computedEach feature is ranked within the repository on four inputs from the scan: fix commits per file, how recently it changed, how many people worked on it, and how many commits it had. A fixed model, fitted once on the history of other repositories, combines the four ranks into one score, and features are ranked by that score. Features with fewer than five commits get no public rank.
- ·Fewer than five commits: not enough evidence to rank.
- top thirdMore future fix work expected than for most features in this repository; check the other evidence before acting.
Valid comparisonsWithin one repository scan only.
- The model was fitted to predict future fix commits, not production incidents.
- Ranks cannot be compared across repositories.
- A feature with little activity has too little evidence to rank; that does not make it safe.
How to improve itUse the rank to decide where to look first, then fix what the evidence shows. Do not try to move the rank itself.
Test evidence
per feature · separate evidence channelsWhat it meansThree separate kinds of test evidence for each product feature: runtime coverage, when a real coverage report was found; journey e2e evidence, whether an end-to-end test visits the feature's user journeys; and static test reach, whether tests import its code. They are never merged into one coverage percentage.
What it's forDecide where a feature's tests are weak or unknown before you change it.
Why it mattersYou can tell apart code that tests actually executed, journeys an end-to-end test visits, code that tests can reach, and missing data, instead of reading them as the same thing.
How it's computedA runtime line or branch percentage appears only when a coverage report from your own test run was parsed (lcov, Cobertura or Go cover); we never run tests ourselves. Without one, the feature's state comes from its user journeys: partial when any journey has an end-to-end or integration-only test, weak when every measured journey is untested. Journeys that could not be measured are left out. With no measured journey, static test reach decides. Each result keeps its source, confidence and receipts.
Valid comparisonsWithin one repository, and only between results from the same kind of evidence.
- Journey e2e evidence and static reach do not show that tests check the right things.
- Journey e2e evidence is a lower bound: pages a test reaches after its first visit are not seen.
- Missing evidence is shown as unavailable, never as 0%.
How to improve itPublish a coverage report from your test run where you can. Before changing a feature whose journeys have no end-to-end test, add one that visits the journey and checks its outcome.
Inactive-author ownership
0–100 · current lines by inactive authorsWhat it meansThe share of a feature's current lines whose last author has made no commits in this repository in the recent window (90 days by default).
What it's forFind code that mostly depends on people who no longer work in this repository, and plan the knowledge handover.
Why it mattersIt shows where knowledge may be at risk, especially in features that are still active or important. Inactive means no recent commits in this repository, not that the person left the company or cannot help.
How it's computedWe run git blame on the current code and check when each line's last author last committed anywhere in the repository. Lines written by a coding agent count toward the person named as their co-author; lines we cannot tie to a person are reported separately.
Valid comparisonsWithin one repository, with the same activity window and identity rules.
- Inactivity in a repository is not employment status.
- One person committing under several git identities can distort it.
- Authorship is only an indirect signal of who knows the code.
How to improve itAssign an active owner, rotate reviews and small changes through the area, and write down decisions while the context is still available.
Active contributors
people · scan history windowWhat it meansHow many different people changed a feature's code during the scan's history window.
What it's forFind areas where only a few people have worked recently, so knowledge may need spreading.
Why it mattersA small number is a simple warning for staffing and review planning, best read together with inactive-author ownership and recent activity.
How it's computedWe count the distinct human authors in the feature's commit history over the window, after merging known aliases of the same person.
Valid comparisonsWithin one repository.
- Counting contributors does not measure knowledge.
- It is not a bus factor.
- Shared accounts and review work that leaves no commits can distort it.
Maintenance pressure
0–100 · recent fix activityWhat it meansThe share of a product feature's recent commits that are fixes, judged by their commit messages, with the most recent weeks counting more.
What it's forFind product areas where a large share of recent work goes into fixing things.
Why it mattersIt shows where fixing is taking up the team's time right now, compared within the same repository. Read the fix commits behind it before changing priorities. It is not a quality score and it does not predict defects.
How it's computedWe read the commits in the scan's history window (180 days by default), skipping merge commits, and mark a commit as a fix when its message says so, for example "fix", "bug", "hotfix" or "revert". Commits from the last 30 days count double; older ones count gradually less, down to half. The score is the weighted fix commits divided by all weighted commits on the feature's files. The raw counts and a confidence interval are kept as receipts.
Valid comparisonsThe same repository over time, and features against each other within one scan.
- A commit message is not proof of a defect.
- A change in how the team writes commit messages can move the number.
- Features with too few commits get no headline number.
How to improve itLook at the fix commits behind the number and address what keeps needing fixes. Do not try to move the number itself.
28-day line rework
share of added lines · 28-day windowWhat it meansThe share of newly added lines that were rewritten or deleted within 28 days of landing. Only lines old enough to have had the full 28 days count.
What it's forFind recently built areas where new code is quickly rewritten, and look into why.
Why it mattersIt points to code that changes again soon after it lands. That can be healthy iteration or avoidable churn; the number alone does not tell which. The split between rewrites by the same author and by others is shown only when there is enough data.
How it's computedWe replay the repository's history in order and follow each added line for 28 days, ignoring code that was only moved and changes that only reformatted files. Commits by automation bots, such as dependency updaters, are left out.
Valid comparisonsThe same repository over time, and features against each other within one scan.
- Planned iteration and changing requirements also count as rework.
- Lines younger than 28 days are not counted yet.
- Comparisons between groups are hidden when there is too little data.
How to improve itOpen the receipts, tell planned iteration apart from avoidable churn, and change review or delivery practice only when the cause is clear.