# Consistency checks (/docs/indicator-apps/checks)



A [validation rule](./indicators/input.mdx) guards a single value: this number is
never negative, that one is at most 100. A **consistency check** guards a
relationship *between* datapoints: renewable plus non-renewable energy equals total
energy, diverted waste never exceeds waste generated, a share stays under 100%.

Checks are what turn "every cell is filled" into "the report holds together", so a
failing check can block a reporting period from being approved.

## Where they live [#where-they-live]

Checks are part of the app's definition, so they live in the editor. Open your
indicator app, click **Open editor**, and go to the **Checks** tab. You get the
familiar two-panel layout: a searchable list of checks on the left, the selected
check on the right. Delete lives on the row in the list.

Like everything else in the editor, a new or changed check sits in your private draft
until you **Publish**. See [Draft and publish](../overview/apps.mdx#draft-and-publish).

## Start from a common pattern [#start-from-a-common-pattern]

A new check offers **Start from a common pattern** with three ready-made shapes:

* **Breakdown sums to total** - components add up to a total.
* **Part stays within whole** - a part cannot exceed the whole.
* **Share stays under 100%** - a ratio or percentage stays in range.

Picking one fills the form in for you; you then swap in your own datapoints. Nothing
is locked, so a template is a starting point, not a constraint.

## Writing a check [#writing-a-check]

A check is a comparison with a left side, an operator, and a right side, and each side
is **built from blocks** rather than typed - the same building blocks a
[formula indicator](./indicators/formula.mdx#you-build-a-calculation-you-do-not-write-one)
uses, so there is one thing to learn and no language to remember:

* **Name** - a short label so it is easy to recognise in the list, for example
  "Totals reconcile". A technical id is filled in from the name as you type and stays
  fixed once the check is created.
* **Left side** and **Right side** - each a calculation over your datapoints. For a
  check that renewable and non-renewable energy add up, the left side is a
  **Calculation** block adding two **Reference** blocks, and the right side is a single
  Reference to total energy consumption.
* **Operator** - `=`, `!=`, `<`, `>`, `<=`, or `>=`.
* **Tolerance** - only offered for `=` and `!=`. A small allowance so a rounding
  difference of a few decimals does not trip an equality.
* **Message shown on failure** - the sentence a collector reads when the check fails,
  for example "Renewable energy cannot exceed total energy use." Ovidens offers a
  **Suggested message** derived from the comparison; **Use** accepts it.
* **Severity** - **Block** ("a failing cell blocks Approve & lock for that period")
  or **Warn** ("shows a warning; sign-off stays possible").

As you build, Ovidens asks the **same question the save asks** and shows one line:
either a &#x2A;*Reads as:** sentence restating the check in plain words - which is how you
confirm it means what you intended - or the reason it cannot be evaluated, naming the
datapoint, the cadence or the breakdown that does not line up. Beside the reads-as
line, a footprint line tells you how often it will be evaluated, for example "checked
per site, per year".

## Reading the results [#reading-the-results]

Below the form sits the **Per-slice evaluation** table: the check applied to your
real data, one row per period and breakdown slice, with the result and, for a
numeric comparison, the difference (Δ) against the tolerance.

Four chips filter it: **All**, **Fail**, **Unknown**, and **Pass**, each with its
count. **Unknown** is not a problem - it means at least one of the datapoints the
check refers to has no value yet, so there is nothing to compare. Those rows name
what is missing, and an unknown check neither blocks nor warns.

A failing row offers **Fix in Data Input**, which takes you straight to the exact
datapoint and period behind it, so you go from "these numbers disagree" to the cell
that needs correcting in one click.

## What a check does to your report [#what-a-check-does-to-your-report]

* A **Block** check that fails keeps the reporting period from being approved.
  **Approve & lock** stays disabled and the period's **Status & approval** tab lists
  what is blocking it, by datapoint and by your check message.
* A **Warn** check that fails is flagged but never blocks approval.
* Either way, collectors see the message you wrote while they are entering data, so
  the person who can fix the inconsistency is told about it at the moment it matters.

See [Review and approve a reporting period](./collection-overview.mdx#sign-off) for
the approval flow itself.
