Skip to content

The risk model

Verity produces a risk band from evidence it already holds. Nothing about the model is hard-coded: the factors, their weights, the per-value scores and the tier boundaries are all account configuration.

The calculation

weight_pct(f)   = weight(f) / Σ weight(enabled factors)
factor_score(f) = the configured mapping for the observed value,
                  falling back to the factor's no_input score if nothing matched,
                  then capped by provenance
risk_score      = Σ (score × weight) / Σ weight        # stays on the 1–5 scale
risk_level      = Tier.resolve(risk_score)             # then raised by any gate floor

Five things happen in order, and each can change the answer:

  1. Observe. Read each factor's value from data on file, recording where it came from.
  2. Score. Map the value through the factor's configured rows; unmatched values take the no_input fallback rather than being skipped, because skipping would reward missing data.
  3. Cap. A weak source may raise risk but never lower it below neutral — see Provenance.
  4. Band. Resolve the weighted score against the tier boundaries — see Tiers.
  5. Floor. A triggered gate or a configured value override can raise the band. It can never lower it.

Two numbers, two questions

Verification coverageRisk band
Fieldcurrent_scorerisk_level
Scale0–100low / medium / high
QuestionHow much of the file is verified?How risky is what we found?

They are reported side by side and never combined. Weights in the coverage score are not comparable to risk amounts, and the assessment says so on screen.

What is stored

Each assessment records the score, the computed band, the final band, whether a floor applied and why, the unevidenced share, and a per-factor breakdown with each value's observed label, provenance, score, weight percentage and whether it was capped.

It also snapshots the tier thresholds it used. Move the boundaries tomorrow and an old assessment still explains itself by the numbers it was actually scored against, rather than silently re-banding.

When no band is produced

Three cases, all deliberate:

SituationResult
No factors configuredNothing is written at all. An assessment of zero factors would stamp a band on no evidence.
Every factor has zero weightNothing is written — there is nothing to average.
More than 40% of weight rests on fallbacksThe breakdown is written, the band is withheld. See Evidence threshold.

In the last case the entity keeps whatever it had, including "never assessed", and the flash says what is missing rather than announcing a verdict.

Running an assessment

Assess risk on the entity page, with entity.review.refresh. Reading the breakdown needs risk_configuration.view, which every role that can view entities is granted.

Assessment is explicit, not automatic — the band carries a timestamp so a reader can always tell how old the judgement is.