CARI Methodology and Scoring Framework

Technical specification for the Community Association Risk Index (CARI) — component weights, signal sources, grade thresholds, confidence tiers, consent architecture, and immutability guarantees.

14 min read Evidence & Verification Published Jan 21, 2026

The Community Association Risk Index (CARI) is a deterministic, consent-gated index that summarizes attested governance, financial, and operational risk signals for community associations. This article documents the scoring methodology, signal sources, access controls, and integrity guarantees that govern how CARI scores are produced and consumed.

CARI is not a credit score. It does not make eligibility or lending decisions. It summarizes observable conditions from an authoritative system of record and presents them as a structured, verifiable index. For an introduction to what CARI is and why it exists, see What Is a Community Association Risk Index?.

Scoring Architecture

Every CARI Score is a weighted composite of five component sub-scores. Each component is computed independently from the signals described below, then combined using published weights.

Component Weights

Component Weight Signal Domain
Financial Health 30% The financial health signal on record
Governance 25% Governance risk coefficient and the governance signal
Vendor Risk 15% Compliance checks on vendors linked to contractor records
Enforcement Integrity 15% Block rate and approval SLA breaches over twelve months
Payment Behavior 15% Prevented loss per transaction and dispute incidence

Weights are stored in a versioned ScoreMethodology record. Only one methodology version is ACTIVE at any time. When weights change, a new version is created and the previous version is marked DEPRECATED. Historical scores always reference the methodology version that was active at computation time.

Measured, Withheld, or Never Evaluated

A component with no observation behind it is dropped from the weighting. It is never scored zero, because zero punishes an association for a measurement nobody took. Dropping a component re-weights the rest, so the re-weighting is allowed only while the measured components carry more than half of the methodology's weight. At or below half, no score is issued, and the record is marked withheld with the reason stated. When nothing was measured at all, the record is marked never evaluated. Neither state returns a zero, and an unmeasured component is stored as empty, not as 0.00.

The same rule applies to the inputs. A twelve-month window with no attempted actions records nothing, not a count of zero. A vendor roster with no linked contractor records is unmeasured, not perfectly compliant. A governance coefficient that is stale, or composed mostly of no-data defaults, is withheld by the gate that feeds the eligibility evaluator, and CARI reads the coefficient through the same gate.

Financial Health (30%)

The largest component. It reads the latest financial health signal on record for the association and inverts it, so that higher means healthier.

Signal Source Interpretation
Financial health score Financial health signal (HOARiskSignal) Inverted (100 - risk score). Higher = healthier

That signal starts from a neutral 50. The latest reserve study's percent funded moves it: 70 percent or more adds 25 points, 50 to 69 percent adds 10, 30 to 49 percent subtracts 10, and below 30 percent subtracts 25. Each active or approved special assessment subtracts 15 points, for up to two. No scheduled job refreshes the signal today, so a score reads the latest signal on record as of its date. The signal adds points for a better reserve position, and the engine reads it as risk: the component takes 100 minus the signal. A reserve that is 70 percent funded therefore lowers this component, and one below 30 percent funded raises it, as does each special assessment.

Governance (25%)

Captures the quality of board oversight and governance processes:

Signal Source Interpretation
Governance risk coefficient GovernanceRiskSnapshot, read through the eligibility gate Scaled 0-1 to 0-100. Higher = better governance
Governance score Governance signal (HOARiskSignal) Inverted (100 - risk score)

The two blend at 60 percent coefficient and 40 percent governance score. When only one is available it stands alone, and when neither is, the component is unmeasured. The governance score starts from a neutral 50 and moves with board composition: three or more admins who are board members add 20 points, two add 10, and none subtract 20. The engine reads this score as risk and takes 100 minus it, so a stronger board composition lowers the governance score part of this component.

Vendor Risk (15%)

Measures the compliance posture of the association's vendors that are linked to a contractor record:

Signal Source Interpretation
Vendor compliance rate (50%) Latest compliance check for each linked vendor Share of linked vendors whose latest check is compliant
Expired credentials (30%) Pending expired-insurance and expired-license alerts Expired credentials relative to linked vendors. Fewer = higher score
Critical alerts (20%) Pending critical compliance alerts Critical alerts relative to linked vendors. Fewer = higher score

Only linked vendors are measured. With no linked vendor, the component falls back to the inverted legacy vendor risk signal when one exists, and is otherwise unmeasured. A linked vendor with no compliance check on record counts as not compliant in the compliance rate. Contractor records are not refreshed on a schedule today.

Enforcement Integrity (15%)

Derived from the platform's own enforcement telemetry over the trailing twelve months. This component measures how well the association's financial controls are operating:

Signal Source Interpretation
Block rate Attempted-action telemetry Blocked attempts divided by all attempts. Scoring peaks near 5%
SLA breaches Approval latency records Each breach costs 2 points and each critical breach 3 more, capped at 30

This component has a non-linear relationship. A block rate below 1% scores 70, because it may mean controls are not active. From 1% to 5% the base rises from 80 to 100, from 5% to 10% it falls back to 80, from 10% to 15% it falls to 60, and from 15% to 25% it falls to 30. Above 25% it declines toward a floor of 10. An association with no attempted actions in the window is unmeasured.

Payment Behavior (15%)

Captures the association's payment loss and dispute history:

Signal Source Interpretation
Prevented loss per transaction (50%) Prevented loss snapshot and the twelve-month transaction count $0 per transaction scores 100, $100 scores 50, and $500 or more scores 10
Dispute incidence (50%) Underwriting inputs, per 1,000 payments 0 scores 100, 10 scores 70, 50 scores 30, and 100 or more scores 10

When only one part is measured, it carries the component. An association with no prevented loss snapshot has that part unmeasured, not ideal.

Grade Thresholds

CARI Scores are mapped to letter grades using published thresholds:

Grade Minimum Score Interpretation
A+ 97 Exceptional across all components
A 93 Strong performance, minor areas for improvement
A- 90 Solid performance
B+ 87 Good with some notable areas for attention
B 83 Good baseline
B- 80 Adequate with clear improvement opportunities
C+ 77 Below average, specific concerns present
C 73 Below average
C- 70 Marginal
D 60 Significant concerns across multiple components
F Below 60 Critical deficiencies

Grade thresholds are defined in the active ScoreMethodology record and versioned alongside weights.

Confidence and Data Completeness

Every CARI Score includes a confidence assessment that reflects how much source data was available at computation time.

Confidence Level Data Completeness Meaning
HIGH 80% or more of signals available The score is well-supported. All major components have strong data coverage
MEDIUM 50-79% of signals available The score is directionally reliable but some components have limited data
LOW Below 50% of signals available The score should be interpreted with caution. Significant data gaps exist

Data completeness is calculated as signals_available / signals_total * 100, where signals_total is the count of all signals the engine attempts to read and signals_available is the count that returned a value for the association being scored. Two of those signals, credential continuity and months on the platform, are not recorded anywhere yet, so they count as unknowns.

A LOW confidence score is still a valid score — it reflects what is observable. The confidence tier tells the consumer how much evidence supports the number. A score whose measured components carry too little of the methodology's weight is withheld, whatever its confidence.

CARI enforces a strict consent model. No score data is accessible to any third party without an active consent record from the HOA.

The HOA controls who can access its CARI data. Consent is granted by an authorized HOA representative and recorded as an CariConsent record.

Three consent scopes exist:

Consent Type Scope Use Case
ALL_SUBSCRIBERS Any authorized subscriber HOA opts into the index broadly
SPECIFIC_SUBSCRIBER Named subscriber only HOA authorizes a specific lender or insurer
SUBSCRIBER_TYPE All subscribers of a given type HOA authorizes all lenders, or all title companies

Each consent record specifies:

  • Permissions: What actions are authorized (score:read, report:lender, report:title, monitor)
  • Expiration: Optional expiry date after which consent automatically lapses
  • Revocation: The association can revoke consent at any time. Revocation is immediate, and no new queries are served

Every API request that accesses HOA data passes through a consent check. The check verifies:

  1. An active (non-expired, non-revoked) consent record exists for this HOA
  2. The consent covers the requesting subscriber (by identity, type, or ALL)
  3. The consent includes the required permission for the requested operation

If any check fails, the request is rejected with a 403 Forbidden response. The rejection is logged but no score data is included in the response.

API Authentication

Third-party access to CARI data uses API key authentication designed for machine-to-machine integration.

Key Lifecycle

  1. Creation: A raw API key is generated using secrets.token_urlsafe(32) with the prefix cari_key_. The full key is shown to the subscriber once at creation
  2. Storage: Only the SHA-256 hash of the key is stored. The raw key cannot be recovered
  3. Authentication: On each request, the key is hashed and compared against stored hashes. Lookup uses the 12-character prefix for efficiency, then verifies the full hash
  4. Expiration: Keys can have optional expiration dates. Expired keys are rejected at authentication time
  5. Revocation: Keys can be revoked with a documented reason. Revocation is immediate

Scoped Permissions

Each API key carries a set of scoped permissions:

Scope Grants
score:read Read CARI scores, history, and component breakdowns
report:generate Generate CARI reports (lender, insurer, title, buyer)
monitor:subscribe Create and manage score change monitors
webhook:manage Register and manage webhook endpoints

A key without score:read cannot retrieve scores. A key without report:generate cannot request reports. Permissions are checked on every request after authentication.

Rate Limiting

Rate limits are tier-based:

Tier Daily Limit Intended Use
Basic 100 requests/day Evaluation, small portfolios
Professional 1,000 requests/day Active integration, medium portfolios
Enterprise 10,000 requests/day High-volume integration, monitoring

Individual API keys can override the tier default with a custom daily limit. Rate limit state is tracked per-subscriber and enforced via middleware.

Webhook Security

Subscribers can register webhook endpoints to be notified when monitored association scores change. Scores are computed nightly, so a change arrives after the nightly run. A change from a score to a withheld state arrives as its own event, which a subscription cannot filter away. Webhook payloads are signed for integrity verification.

Signing Scheme

Every webhook delivery includes two headers:

Header Value
X-CARI-Signature sha256={hmac_hex_digest}
X-CARI-Timestamp Unix timestamp (seconds)

The HMAC-SHA256 signature is computed over the string {timestamp}.{payload_json} using the subscriber's webhook secret as the key. Recipients should:

  1. Extract the timestamp from the header
  2. Construct the signed message: {timestamp}.{raw_body}
  3. Compute HMAC-SHA256 with their stored secret
  4. Compare the computed signature to the header value
  5. Reject if the timestamp is more than 5 minutes old (replay protection)

Delivery

A delivery is attempted immediately and, on failure, retried with exponential backoff:

Attempt Delay
1 Immediate
2 1 minute
3 5 minutes
4 30 minutes
5 2 hours
6 12 hours

After the last failed attempt, the delivery is moved to DEAD_LETTER status. After 10 consecutive failures across any deliveries, the endpoint is automatically marked FAILING and delivery is paused until the subscriber re-enables it. The sweep that re-queues deliveries which stalled mid-retry is not scheduled today.

Score Immutability

CARI Scores are immutable after computation. The CariScore model rejects any attempt to update an existing record. New scores do not replace old scores — they are appended to the time series.

Deterministic Hashing

Every score includes a calculation_hash — a SHA-256 digest computed from canonical JSON serialization of:

  • HOA identifier
  • As-of date
  • Methodology version
  • All signal values (sorted by key)
  • All weights (sorted by key)

Canonical JSON uses sorted keys, minimal separators, and UTF-8 encoding. Given the same inputs and the same methodology version, the same hash is always produced. This allows independent verification that a score was computed correctly.

Version Chain

Each CARI Score references its previous_score (the most recent prior score for the same HOA). This creates an append-only chain that enables:

  • Score delta computation (current vs. previous)
  • Grade change detection
  • Historical trend analysis without relying on query ordering

Audit Trail

Every score computation records:

  • All signal values at computation time (signals_snapshot)
  • The methodology version and weights used (weights_snapshot)
  • Per-component calculation details (component_details)
  • Computation timing (computation_ms)
  • What triggered the computation (triggered_by: scheduled, enforcement_event, manual, api_request, signal_change)

This snapshot is frozen at computation time. Even if the underlying data changes later, the score's evidence is preserved exactly as it was when the score was computed.

CARI Reports

Five report types provide context-appropriate views of CARI data for different institutional consumers. All reports are generated as InstitutionalPackets using BaseAttestationService, which provides:

  • Canonical JSON serialization with deterministic SHA-256 content hashing
  • Version chain management (each report references its predecessor's hash)
  • Audit trail via PacketEvent records
  • PDF rendering
Report Audience Key Content
CARI Lender Report Mortgage underwriters Score breakdown, financial health detail, delinquency analysis, reserve adequacy, governance evaluation, peer comparison
CARI Insurer Report D&O insurance underwriters Governance risk, enforcement integrity, prevented loss history, exclusion history, claims risk factors
CARI Title Report Escrow and title companies Score, unit-level financial status, special assessments, litigation flags, financial summary
CARI Buyer Report Homebuyers Simplified score and grade in plain language, key health indicators, peer comparison. Raw signal data and enforcement internals are excluded
CARI Market Report Market analysis Anonymized aggregate statistics across monthly snapshots, nationally or by state. No individual association is identified

Each report type extends BaseAttestationService and implements its own evidence snapshot builder and scope determination logic. Reports inherit the same immutability and hash verification guarantees as all institutional packets.

Artifact Embedding

When an association has given embed consent, the CARI block is written into the evidence snapshot of its institutional artifacts, so the score contributes to the artifact's content hash and cannot be stripped or altered without invalidating the artifact. The block states its own status. A score older than 35 days is marked stale. A score resting on fewer than five signals is marked unavailable. A withheld or never-evaluated record carries no number and says which it is. The score is rendered on a printed artifact only when its status is available.

Scheduled Operations

One scheduled task maintains CARI:

Task Schedule Purpose
Nightly score computation 3:30 AM daily Compute fresh scores for every association that is not archived. Access to a score still requires the association's consent

Webhook retry sweeps and usage aggregation are not scheduled today.

How CommunityPay Enforces This
  • Every CARI Score is computed from records the platform holds. A component nobody measured is dropped, never scored zero, and a score that rests on too little of the methodology's weight is withheld
  • Scores are immutable after computation. Same inputs and same methodology version produce the same SHA-256 hash
  • No score is accessible without an active CariConsent record from the HOA — consent is verified on every API request
  • Component weights and grade thresholds are published in versioned ScoreMethodology records. Historical scores always reference the methodology version used
  • All API access is authenticated via hashed API keys with scoped permissions and tier-based rate limits
  • Webhook payloads are signed with HMAC-SHA256 and include timestamps for replay protection
  • A score older than 35 days is marked stale on embedded artifacts, and the CARI block is bound into the artifact's content hash
Login