1. Read the verdict at the top, not the list

    The report opens by naming its own shape: whether it found problems, found nothing, or could not look at enough to say. Those are three different results and only one of them is good news.

  2. Check the coverage sentence

    Every negative statement carries the boundary it applies to. "No orphaned rows" means nothing without the number of tables that were read to say it.

  3. Separate declared from measured from guessed

    The report marks which relationships the database enforces, which were checked by counting, and which are only name-matching. Do not act on a guessed link.

  4. Look at what was not looked at

    The section naming skipped tables and unwalked routes is the one nobody reads and the one that changes what the rest means.

The trap in the first report

A report over an empty database looks almost identical to a report over a healthy one: no problems listed, everything green. That reading is wrong, and it is the single most common misread of this kind of tool.

When this was put in front of readers, one in five read an empty report as "everything is fine". The product now states the count and the shape explicitly — 18 of the 36 tables — half of them — hold no rows — rather than leaving you to divide two numbers yourself.

An empty table is not a clean one.

The sentence the report prints when it has nothing to report

What is worth acting on

  • Rows pointing at parents that no longer exist. If a customer calls, you cannot tell who they are.
  • Constraints the catalogue declares but the database is not enforcing — marked NOT VALID. Every claim built on them is weaker than it looks.
  • A column that is unique in practice but has no unique index. It works until two requests arrive at once.
  • Sentinel values standing in for a missing link — a zero or a fixed id that means "none" and joins to nothing.

Running it again later

Each scan is kept locally, so a later run can be compared with an earlier one and you get a list of what changed rather than a fresh wall of text. That is the R in the name — npm run diff does it from the command line.