CommunityPay evaluates eligibility for financial operations using a declarative rule framework. Rules are defined as expressions, not code. They are versioned, immutable once active, and produce deterministic results. This page describes the rule architecture, evaluation process, and the audit artifacts produced.
Design Principles
Declarative, Not Procedural
Eligibility rules are defined as expressions that reference signal values:
reserve_ratio >= 0.10
governance_score >= 50
delinquency_rate <= 0.15
These expressions are stored as data, not embedded in application code. This means: - Rules can be inspected without reading source code - Rule changes are versioned and auditable - The same rule engine evaluates all rules uniformly - Historical evaluations can be reconstructed from the stored expression and signal values
Deterministic
Given the same rule version and the same signal values, the evaluation always produces the same result. There is no randomness, no external state dependency, and no side effects.
This is critical for audit. An evaluation performed on January 15 can be reproduced exactly by loading the rule versions active on January 15 and the signal values captured at evaluation time.
Rule Structure
Each eligibility rule defines:
| Field | Purpose |
|---|---|
| code | Stable identifier (e.g., TENURE_6M, RESERVE_RATIO_MIN) |
| expression | Evaluable expression referencing signal values |
| category | TENURE, FINANCIAL, GOVERNANCE, COMPLIANCE, or VOLUME |
| effect_type | What happens when the rule fails (see below) |
| priority | Evaluation order (lower = earlier) |
| status | DRAFT, ACTIVE, DEPRECATED, or ARCHIVED |
| version | Integer version, incrementing |
| supersedes | Foreign key to the previous version |
| effective_date | When this version becomes applicable |
| sunset_date | When this version stops being evaluated (optional) |
Effect Types
Each rule specifies what happens when an entity fails the rule:
| Effect | Behavior |
|---|---|
| REQUIRE | Failure means the entity is ineligible. The operation is blocked. |
| DENY | Failure immediately marks the entity as ineligible — no further rules are evaluated. |
| PREFER | Failure is noted as a soft preference miss. The operation proceeds, but the miss is recorded. |
| REFER | Failure means a human must review. The operation is queued for manual evaluation. |
This graduated model means the rule framework can express both hard requirements and soft preferences. A REQUIRE rule enforces a minimum standard; a PREFER rule identifies optimal conditions without blocking.
Production Rules
Nine eligibility rules are active in production:
Tenure Rules
| Code | Expression | Effect | Description |
|---|---|---|---|
| TENURE_6M | platform_tenure_months >= 6 |
REQUIRE | Minimum 6 months on the platform |
| TENURE_12M | platform_tenure_months >= 12 |
PREFER | Preferred 12-month tenure (soft signal) |
Financial Health Rules
| Code | Expression | Effect | Description |
|---|---|---|---|
| RESERVE_RATIO_MIN | reserve_ratio >= 0.10 |
REQUIRE | Minimum 10% reserve ratio |
| RESERVE_RATIO_HEALTHY | reserve_ratio >= 0.25 |
PREFER | 25% reserve ratio is considered healthy |
| OPERATING_RATIO | operating_ratio <= 0.90 |
REQUIRE | Operating costs must be below 90% of revenue |
| DELINQUENCY_MAX | delinquency_rate <= 0.15 |
REQUIRE | Maximum 15% owner delinquency rate |
Governance Rules
| Code | Expression | Effect | Description |
|---|---|---|---|
| BOARD_ATTESTATION | board_attestation_current == True |
REQUIRE | Board attestation must be current |
| QUORUM_COMPLIANCE | quorum_met_rate >= 0.75 |
REFER | 75% quorum rate; failure requires human review |
| GOV_SCORE_MIN | governance_score >= 50 |
REQUIRE | Minimum governance score of 50 |
Signal Providers
Rules reference signals — real-time data values gathered from the platform. Signal providers are pluggable components organized by namespace:
| Namespace | Signals Provided |
|---|---|
| FINANCIAL | reserve_ratio, operating_ratio, delinquency_rate, cash_balance, receivables_aging |
| GOVERNANCE | governance_score, board_attestation_current, quorum_met_rate, meeting_frequency |
| COMPLIANCE | vendor_coi_status, license_status, bond_status, regulatory_filings_current |
| VOLUME | transaction_count_30d, payment_velocity_7d, payment_velocity_30d |
| TENURE | platform_tenure_months, activation_date, first_transaction_date |
Signal providers gather data from across the platform — accounting, communities, buildrated, and governance modules — and present it as a flat namespace of typed values.
Evaluation Process
When eligibility is evaluated, the following sequence executes:
1. Gather Active Rules
All rules with status=ACTIVE are loaded, filtered by applicable category, and ordered by priority (lower number = evaluated first).
2. Gather Signals
All signal providers for the referenced namespaces are invoked. Signal values are gathered into a flat dictionary.
3. Evaluate Each Rule
Each rule's expression is evaluated against the gathered signals. The result is either PASS or FAIL.
DENY short-circuit: If a DENY rule fails, evaluation stops immediately. The entity is ineligible.
For all other effect types, evaluation continues through the full rule set to capture complete results.
4. Compute Aggregate Result
The aggregate eligibility determination is computed from individual rule results: - If any REQUIRE rule failed: INELIGIBLE - If any REFER rule failed: REVIEW_REQUIRED - If only PREFER rules failed: ELIGIBLE (with notes) - If all rules passed: ELIGIBLE
5. Create Immutable Evaluation Record
An EligibilityEvaluation artifact is created with: - All rule versions that were active at evaluation time - All signal values gathered - Per-rule pass/fail results - The aggregate determination - Timestamp and correlation ID
This record is immutable — enforced by ImmutableModelMixin. It cannot be updated or deleted.
Rule Versioning
Why Versioning Matters
Consider this scenario: On January 1, the RESERVE_RATIO_MIN rule requires a 10% reserve ratio. On March 1, the requirement is updated to 15%.
Without rule versioning, an auditor reviewing a January evaluation would see the 15% rule and might incorrectly conclude that the entity was evaluated against a 15% threshold. With versioning, the January evaluation references the exact rule version that was active on January 1 — the 10% version.
How Versioning Works
- Each rule has an integer
versionfield and asupersedesforeign key to the previous version - When a rule is updated, the current ACTIVE version is moved to DEPRECATED status
- A new version is created with incremented version number and ACTIVE status
- The new version's
supersedesfield points to the old version effective_dateand optionalsunset_datedefine the temporal scope
Historical evaluations always reference the specific rule version that was active at evaluation time. The evaluation record stores rule version IDs, not rule codes — so even if a rule code is reused across versions, the evaluation references the exact version.
Integration with Enforcement
Eligibility evaluation is invoked by the FundEligibilityGuard (GUARD_006) in the enforcement guard chain. When a flow includes GUARD_006, the guard:
- Invokes the eligibility evaluator for the relevant entity
- Receives the aggregate determination
- If INELIGIBLE: Returns FAIL with the failing rule codes
- If REVIEW_REQUIRED: Returns FAIL with a referral code
- If ELIGIBLE: Returns PASS
The guard result is recorded in the EnforcementDecision alongside all other guard results. The EligibilityEvaluation artifact is linked to the decision via foreign key.
What This System Proves
The eligibility evaluation framework ensures that:
- Rules are transparent: Any auditor can inspect the rule expressions — they are data, not buried in code
- Evaluations are reproducible: The same rule version plus the same signals always produce the same result
- History is preserved: Every evaluation is stored as an immutable artifact with complete context
- Changes are traceable: Rule version chains show exactly when requirements changed and who changed them
- Graduated enforcement: The four effect types allow nuanced policy — not everything is a hard block
How CommunityPay Enforces This
- Rules are declarative expressions evaluated against real-time signal values — not hardcoded logic
- Four effect types (REQUIRE, DENY, PREFER, REFER) enable graduated enforcement from blocking to advisory
- Rule expressions are immutable once ACTIVE — changes require a new version with supersession chain
- Every evaluation produces an immutable EligibilityEvaluation artifact capturing all rule versions and signal values at evaluation time
- Signal providers are pluggable: FINANCIAL, GOVERNANCE, COMPLIANCE, VOLUME, TENURE namespaces
- Nine production rules across five categories enforce tenure, financial health, governance, compliance, and volume requirements