# Scoring and readiness verdicts

`scripts/audit_crm.py` applies everything below. Apply it by hand when the script cannot run, and label the report "scripts not run".

The score ranks where to look; the verdicts decide readiness. Never average away a gate.

## Statuses

- FAIL: wrong data, sends or exposure without permission, broken routing, revenue or consent, or an irreversible risk, unless a dated decision is cited.
- WARN: a plausible defect that needs a decision or more evidence.
- PASS: the rule ran and found nothing, or found something correct. The reason is stated.
- NOT CHECKED: evidence unavailable or the rule's denominator is zero. The reason and the evidence that would close it are stated. It never counts as a pass.
- N/A: the rule does not apply to this CRM or business model. The reason is stated.

A rule with several findings takes its worst finding: FAIL over WARN over PASS.

## Classes, weights and credit

- Class A, weight 3: can contact people without permission, expose restricted data, corrupt revenue, ownership or consent data, or make an irreversible change likely.
- Class B, weight 2: misroutes work, breaks automation silently, or makes a key report wrong.
- Class C, weight 1: maintainability and clarity.
- Credit: PASS 1, WARN 0.5, FAIL 0.
- Three rules change class per finding, and the script records the class it used: AUTO-02 counts as class A when the erroring automation writes a routing, ownership, consent, lifecycle, stage or revenue field; FLD-05 counts as class B when its capacity FAIL fires; ACC-05 counts as class B when exposure is possible but not confirmed.

## Domain score and coverage

- Domain score = 100 x sum(weight x credit) / sum(weight), over rules rated PASS, WARN or FAIL, rounded to the nearest 5. NOT CHECKED and N/A rules are left out of the score.
- Coverage = weight of rules rated PASS, WARN or FAIL / weight of applicable rules (every rule except N/A).
- Coverage under 60%: the domain shows "insufficient evidence" and no score.
- Coverage from 60% to 84%: the score is shown and marked partial.
- Coverage of 85% or more: full.
- Class A cap: any class A FAIL caps the domain score at 60, so the domain cannot read better than At risk.

## Bands

- Healthy: 85 to 100.
- Needs work: 70 to 84.
- At risk: 50 to 69.
- Failing: below 50.
- Insufficient evidence: coverage under 60%.

## Overall score

The mean of the domain scores, equal weights unless `audit-config.json` sets `domain_weights`. It is shown only when at least six domains have a score; otherwise the report says "not computed". It ranks where to look and never decides readiness.

## Readiness verdicts

Automation readiness gates: OBJ-02, FLD-02, FLD-03, LIFE-03, AUTO-03, AUTO-06, ACC-01, ACC-02, INT-01.

Reporting readiness gates: REP-01, REP-02, REP-03, REP-04.

For each verdict, in this order:

- Any gate FAIL: "Fix gates first", listing the failing gates.
- Otherwise any gate NOT CHECKED, or a gate with a NOT CHECKED part (a critical field without history, an automation whose writes or actions are unknown, an unclassified workflow action): "Not assessable", listing what to collect. A gate that reads PASS or WARN still blocks readiness while it carries such a part, and the verdict names the part.
- Otherwise any WARN gate without an owner and a date in `gate_owners` (copied from the change list): "Not ready until owned".
- Otherwise: "Ready to automate" or "Ready to report from".

A rule with a NOT CHECKED part cannot pass: its PASS turns NOT CHECKED, while FAIL and WARN findings stand. Two kinds of part leave the status as it is and block only the verdict: an unclassified workflow action (an AUTO-06 PASS then reads "among classified actions"), and an unread automation in FLD-02, FLD-03, LIFE-03 and AUTO-09, which rate history and the automations that were read.

## Overrides

Every threshold can be overridden in `audit-config.json`, with a reason under `override_reasons` keyed by its path (for example `REP-05.lookback_days`). The report lists every override, its default and its reason; a missing reason is printed as "reason missing". A gate cannot be switched off: `not_applicable` is ignored for gates. A gate FAIL can only be downgraded per finding, in `manual_results`, citing the id of a dated `decisions.items` entry; any other reference is rejected with a warning. A downgrade replaces the findings and keeps any NOT CHECKED part.

## Worked computation (Acme Cloud, integrations domain)

```text
INT-01  A  FAIL  3 x 0    = 0
INT-02  A  FAIL  3 x 0    = 0
INT-03  B  WARN  2 x 0.5  = 1
INT-04  B  PASS  2 x 1    = 2
INT-05  B  WARN  2 x 0.5  = 1
INT-06  A  FAIL  3 x 0    = 0
INT-07  A  FAIL  3 x 0    = 0
credits 4 of 18 weighted points = 22.2, rounded to 20
class A FAIL present, cap 60 does not bite; coverage 18 of 18 = 100%; band Failing
```

The users domain in the same run shows how coverage works: ACC-05 is NOT CHECKED (the deal View access per permission set was not provided), so 12 of 15 weighted points are rated, coverage is 80%, and the score of 15 is marked partial.

A gate that is NOT CHECKED inside an otherwise passing set still blocks readiness. For example, owner and consent fields with no history export leave FLD-02 and FLD-03 NOT CHECKED, so the automation verdict reads "Not assessable" even when every other automation gate passes (fixture case R36). The same holds for a NOT CHECKED part: an owned FLD-02 WARN on a field without history (R46), a flow whose writes were never read beside one that was (R47), and an unclassified action beside an AUTO-06 PASS (R48) each keep the verdict at "Not assessable", where R45, the same portal with everything read, is "Ready to automate".

## How to present it

Verdicts first, then the scorecard as bullets (domain, score and band, coverage), then findings by status. No tables. Quote the overall score once, with the sentence that it ranks rather than decides.

## Why this design

Multiplying arbitrary sub-scores gives false precision, and grading by share of records affected hides what was never checked. Weighted credits with a visible coverage figure, a class A cap and gate-based verdicts keep the number honest: it can rank, but it cannot hide a gate.
