Risk Triggers & Exclusion Enforcement

How CommunityPay detects risk conditions, creates bind blocks, and enforces exclusions with full audit trails. The underwriting hold system that prevents high-risk operations before they execute.

7 min read Governance & Controls Published Dec 30, 2024

CommunityPay evaluates risk conditions against recorded signals and creates enforcement holds — called exclusions or bind blocks — when conditions warrant intervention. This page describes how triggers are defined, how exclusions are created and managed, and what audit trail is produced at each step.

What Is an Exclusion?

An exclusion is an active enforcement hold on an entity (HOA or vendor). What a hold does depends on its effect type:

Effect Type What It Does
BLOCK The l5_exclusion guard refuses every posting for the association while the exclusion is ACTIVE. The guard cannot be overridden with an AuditOverride; the exclusion's own lifecycle — lifted, placed under appeal, overturned on appeal, or expired — is the only way out. The guard reads exclusions on the association only; an exclusion on a vendor is recorded and refuses no posting
REVIEW Recorded and flagged for manual review. No guard refuses a posting because of it
WARN Recorded as a warning. No guard refuses a posting because of it

Exclusions are not punitive. They are protective controls that prevent high-risk operations from executing before the risk condition is evaluated and addressed.

Trigger Architecture

How Triggers Are Defined

An ExclusionTrigger is a versioned definition that specifies:

  1. What to evaluate: Which signals to read from the signal registry (namespaces RISK_SIGNAL, TELEMETRY, UNDERWRITING, VENDOR_COMPLIANCE, and DEBT_SERVICE)
  2. What condition to check: A JSON expression format that references specific signal values
  3. What to do when the condition is met: Block, require review, or warn
  4. How severe the condition is: LOW, MEDIUM, HIGH, or CRITICAL
  5. How long the resulting exclusion lasts: Configurable duration in days, or indefinite until manually resolved

Trigger Types

Type Evaluation Pattern
THRESHOLD A numeric signal exceeds or falls below a defined value
PATTERN A detectable pattern across multiple signals
EVENT A single discrete event triggers the exclusion
COMPOUND Multiple conditions must be met simultaneously

Immutability of Active Triggers

When a trigger is in DRAFT status, its conditions can be modified freely. Once a trigger is activated (status = ACTIVE), its conditions become immutable.

This is enforced at the application layer:

  1. At every save, a SHA-256 hash of the conditions JSON is computed and stored in conditions_hash
  2. If an existing ACTIVE trigger is being saved and the new conditions_hash differs from the stored hash, the save is rejected with a ValueError
  3. To change an active trigger's conditions, a new version must be created (the old version is archived)

This ensures that every ExclusionTriggerHit can always reference the exact conditions that were in effect when it fired. Historical evaluation can be reconstructed precisely.

Version Management

Triggers use a correlation-based versioning model:

  • trigger_id: A stable UUID that remains constant across all versions of the same logical trigger
  • version: An incrementing integer (1, 2, 3...)
  • parent_version: A foreign key to the previous version

Only one version of a given trigger_id can be ACTIVE at any time, and a database constraint holds that line. The workflow is: archive the current version, then activate the new version.

A trigger may be ACTIVE only while every signal its conditions read has a live source. A trigger whose signals nothing writes is held: it records why it is not active and decides nothing. In production today, 0 triggers are ACTIVE and 0 eligibility rules are active.

Exclusion Lifecycle

When a trigger fires, the following sequence occurs:

1. Trigger Evaluation

The eligibility evaluator evaluates active triggers against current signal values. When conditions are met, an ExclusionTriggerHit is created. Evaluation runs when an eligibility evaluation is requested, through the eligibility API or the backfill command; no timer drives it today.

The trigger hit is an ARTIFACT — fully immutable. It captures:

  • The trigger version that fired
  • All evaluated signal values at the moment of evaluation
  • The computed result
  • The timestamp

2. Exclusion Creation

An Exclusion record is created with status ACTIVE for a BLOCK or WARN trigger, and with status PENDING for a trigger that requires review. The exclusion references:

  • The trigger hit that caused it
  • The affected entity (HOA or vendor)
  • The effect type (copied from the trigger)
  • The severity
  • The expiration date (current time + trigger's exclusion_duration_days, or null for indefinite)

3. Notification

If the trigger has auto_notify enabled, the notification service sends alerts to configured recipients. Notification events are recorded in the append-only ExclusionNotificationEvent log.

4. Enforcement

While a BLOCK exclusion is ACTIVE, the l5_exclusion guard refuses every posting for the association, in every flow and transaction type, and the refusal is recorded in the EnforcementDecision with the exclusion's identifier and the trigger that created it. REVIEW and WARN exclusions are recorded and surfaced; no guard refuses a posting for them.

5. Resolution

An exclusion leaves ACTIVE in four ways, and an exclusion under appeal no longer blocks:

Status How Audit
LIFTED A user lifts the exclusion early with a documented reason Reason, user, and timestamp recorded
APPEALED A user starts an appeal The appeal is recorded; the exclusion's status is Under Appeal
OVERTURNED The appeal succeeds Status transition and timestamp recorded
EXPIRED The exclusion's duration elapses Automatic transition by the monitoring task; timestamp recorded

All status transitions are recorded in the append-only ExclusionStatusHistory table. No status history record can be updated or deleted. The monitoring task runs every four hours: it expires exclusions past their expiry, tracks approaching deadlines, and clears finished cooldown periods.

Cooldown Periods

After an exclusion is resolved, the trigger enters a cooldown period for the affected entity. During cooldown, the same trigger cannot fire again for the same entity.

The default cooldown is 30 days, configurable per trigger. This prevents rapid cycling of exclusion creation and resolution that could indicate an unresolved underlying condition.

Escalation Chain

Unresolved exclusions follow the association's escalation rules. Each rule names the event it applies to (an exclusion pending review, an active exclusion, a compliance alert, or an expiring document), the minimum severity, who is told (the association administrator, a board member, the property manager, an executive, or an external contact), and how long to wait.

By default a rule waits three days without action before it escalates, and two more days before the chain moves to the next rule. Each escalation is recorded as an immutable event. Rules are processed every four hours, escalation chains are checked every two hours, and reminders go out at 9:00 AM.

SLA Tracking

The escalation system tracks:

  • Acknowledgment: Has the responsible party acknowledged the exclusion?
  • Response time: How long between notification and acknowledgment?
  • Resolution time: How long between creation and resolution?
  • SLA compliance: Which notified escalations were acknowledged within 48 hours?

These metrics feed into the Control Effectiveness measurement system and the Governance Controls Attestation (GCA).

Severity Classification

Each trigger and each exclusion carries a severity — LOW, MEDIUM, HIGH, or CRITICAL. An escalation rule applies from a minimum severity upward, so a board that wants a quicker chain for CRITICAL conditions writes a separate rule for them.

What This System Proves

The exclusion enforcement system creates a complete, verifiable record of risk management:

  1. Detection is deterministic: The same signal values always produce the same hits, and every hit is recorded
  2. Response is documented: Every notification, acknowledgment, and escalation is recorded
  3. Resolution is auditable: Every exclusion closure includes who resolved it, when, and why
  4. History is preserved: Trigger hits, exclusion records, and status transitions are immutable
  5. Controls are measurable: SLA tracking and escalation metrics prove that the system operates, not just that it exists

An auditor reviewing the exclusion history can reconstruct: what triggered the hold, what the signals showed at that moment, who was notified, whether they responded within SLA, how the hold was resolved, and what documentation supported the resolution.

CARI Integration

Exclusions do not enter the CARI score. The CARI Enforcement Integrity sub-score reads two signals measured near these: the enforcement block rate and approval SLA breaches over the trailing twelve months. The trigger, resolution, and escalation measures on this page are not inputs.

For published methodology and component weights, see CARI Methodology and Scoring Framework.


This describes production controls as of October 2026

How CommunityPay Enforces This
  • Trigger conditions are immutable once ACTIVE — modifications require a new version with SHA-256 hash verification
  • Three effect types grade the response: BLOCK (the l5_exclusion guard refuses every posting for the association, and no override can lift it), REVIEW (recorded for manual review), WARN (recorded as a warning)
  • Every trigger hit creates a fully immutable ExclusionTriggerHit artifact with the evaluated signals and computed values
  • Exclusions track a complete lifecycle: PENDING, ACTIVE, APPEALED, LIFTED, EXPIRED, or OVERTURNED, with append-only status history
  • Cooldown periods prevent the same trigger from firing repeatedly for the same entity within a configurable window
  • Escalation rules per association name who is told and how long to wait before the chain moves on
Login