> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphora.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Check Reference

> Built-in check catalog with representative runnable YAML examples

GraphCheck suites are YAML files under `checks/` (or wherever `graphcheck.yml`'s `checks` path
points). A suite groups checks into three kinds — conformance, competency, and drift — plus a
shared `defaults` block for severity and tags.

Examples below are drawn from the fraud-ring fixture (`graphcheck-fraud-ring-fixture`) where a
real, planted scenario exists; a few core checks the fixture doesn't exercise use generic
illustrative data instead.

## Conformance checks

Conformance checks assert a structural rule against the graph using a built-in template. The
`check` field selects the template; `with` supplies its parameters.

| Check                | Catches                                                                        | Does not catch                                                                            |
| -------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `completeness`       | Required or high-coverage properties missing from nodes with a target label    | Whether the property value is valid, unique, or semantically correct                      |
| `cardinality`        | Nodes whose expected relationship count is not exactly the configured value    | Whether the related node is otherwise valid, or whether alternate paths satisfy the model |
| `no_orphans`         | Nodes with a required label that have no matching relationship                 | Isolated nodes that are valid by design, or missing relationships of unrelated types      |
| `dangling_rels`      | Relationship records whose endpoints cannot be resolved by the backing store   | Semantically wrong relationships whose endpoints exist                                    |
| `property_type`      | Property values whose observed runtime type differs from the declared type     | Values of the correct type but invalid format or domain                                   |
| `property_format`    | String properties that do not match the configured regular expression          | Missing properties, unless combined with `completeness`                                   |
| `value_in_set`       | Property values outside an allowed finite set                                  | Values inside the set that are stale or contextually wrong                                |
| `uniqueness`         | Duplicate values for a property expected to be unique within a label           | Missing values, or duplicates across labels unless configured separately                  |
| `hub_outlier`        | Nodes whose relationship degree is far above the configured population norm    | Legitimate hubs or low-degree anomalies                                                   |
| `label_cooccurrence` | Nodes that carry two labels declared mutually exclusive                        | Label pairs not explicitly configured                                                     |
| `rel_direction`      | Relationships whose endpoints imply the relationship is pointing the wrong way | Incorrect relationship types where the direction is otherwise valid                       |
| `temporal_sanity`    | Records where an end timestamp is earlier than its start timestamp             | Missing timestamps, or timestamps that are plausible but inaccurate                       |

`hub_outlier` is sampled and supports an optional `sample_size`; every other core check is
unsampled and requires only `read` access, except `dangling_rels`, which additionally requires
the `store_consistency` connector probe.

### No orphans and cardinality — fraud-ring fixture

The fixture plants 3 orphan accounts and 1 cardinality violation (an account with two owners):

```yaml theme={null}
conformance:
  - id: account-no-orphans
    check: no_orphans
    with:
      label: Account
  - id: account-owner-cardinality
    check: cardinality
    with:
      from_label: Account
      rel_type: OWNS
      to_label: Customer
      direction: in
      exactly: 1
```

### Completeness — fraud-ring fixture

Every base `Customer` carries `tax_id`, `email`, and `national_id`:

```yaml theme={null}
conformance:
  - id: customer-tax-id-present
    check: completeness
    with: { label: Customer, property: tax_id, threshold: 1.0 }
```

### Hub outlier — fraud-ring fixture

The fixture's `Transaction` nodes have a real degree distribution suited to hub-outlier detection:

```yaml theme={null}
conformance:
  - id: transaction-hub-outlier
    check: hub_outlier
    with:
      label: Transaction
      sample_size: 500
```

### Checks without a fixture example

The fraud-ring fixture doesn't plant scenarios for `dangling_rels`, `property_type`,
`property_format`, `value_in_set`, `uniqueness`, `label_cooccurrence`, `rel_direction`, or
`temporal_sanity`. Each takes its own `with` parameters; validation rejects an invalid
combination with an error naming the offending field, so the fastest way to explore a check's
parameters is to write it and run `graphcheck run` — nothing executes until the suite validates.
A generic example:

```yaml theme={null}
conformance:
  - id: account-balance-is-numeric
    check: property_type
    with: { label: Account, property: balance, type: integer }
```

## Competency checks

Competency checks run a Cypher query against the graph and assert the shape of its result — for
questions the graph should be able to answer, rather than structural rules.

```yaml theme={null}
competency:
  - id: customers-can-be-counted
    question: "Can customers be counted?"
    query: "MATCH (c:Customer) RETURN count(c) AS count"
    expect: { rows: { min: 1 }, columns: [count] }
```

## Drift checks

Drift checks compare a metric against a previously captured baseline and flag deviation beyond a
configured tolerance. The fraud-ring fixture's `seed-drifted.cypher` represents a documented 12%
Customer-count reduction (1,500 to 1,320) from the baseline:

```yaml theme={null}
drift:
  - id: customer-count-stable
    metric: node_count
    target: { label: Customer }
    tolerance: { max_drop_pct: 10 }
    severity: warn
```

## PII pack

The PII pack is a separate, executable heuristic pack. Findings are sampled and heuristic —
this pack never claims complete PII discovery. The fraud-ring fixture plants a name-alias field
(`email`) and value-pattern-matchable data on `national_id` (Singapore NRIC-style and Indian
Aadhaar-style, alternating per customer) — note that `national_id` itself is not a recognized
name alias, so it is only caught by `pii_value_match`, not `pii_name_match`.

| Check             | Catches                                                                                                                                                                                       | Does not catch                                                      |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `pii_name_match`  | Sampled property occurrences whose keys match known personal-data aliases (`ssn`, `dob`, `email`, `phone`, `nric`, and others in the pack's alias catalog — `national_id` is not one of them) | Personal data stored under unknown or ambiguous property names      |
| `pii_value_match` | Sampled string property values matching known PII formats and required checksums (`email`, `e164_phone`, `nric`, `aadhaar` with Verhoeff checksum, `credit_card` with Luhn checksum)          | Encoded, encrypted, unrecognized, or unsampled personal-data values |

Both checks accept an optional `label` and `sample_size`, plus an optional `patterns` list to
restrict which aliases or formats are checked; `pii_value_match` also accepts an optional
`properties` list to restrict which property keys are scanned.

Example — scanning the fraud-ring fixture's `Customer` nodes:

```yaml theme={null}
conformance:
  - id: customer-email-alias-present
    check: pii_name_match
    with:
      label: Customer
      sample_size: 200
  - id: customer-national-id-value-match
    check: pii_value_match
    with:
      label: Customer
      patterns: [nric, aadhaar]
      sample_size: 200
```

## Severity and defaults

`defaults.severity` sets the suite-wide severity (`error` or `warn`); individual checks can
override it. Suite-wide `tags` let you select subsets of checks at run time with
`graphcheck run --select tag:<name>`.

The check YAML contract is strict: duplicate keys, unknown fields, unknown check names, and
invalid `with` parameters are rejected with loud validation errors rather than silently ignored.
Built-in packs are data, not code — every pack's metadata and parameters are validated against
the same contract before any check runs.
