Skip to main content

Repo B Audit-Grade Commission Engine Lock (v1.0)

Date: 2025-01-XX
Status: LOCKED - No further logic changes unless required by failing tests

Executive Summary

Repo B commission calculation engine is now audit-grade and stable. This document freezes the canonical rules, rounding standards, and regression test suite.

Locked Components

1. Cadence Inference Rules (CANONICAL)

Function: infer_cadence_from_member_duplication() in repo_b/output_adapter.py Rules (DO NOT CHANGE WITHOUT AUDIT APPROVAL):
  • max_dup_count == 1 → Monthly (12 pay periods)
  • max_dup_count == 2 or 3 → Bi-weekly (26 pay periods)
    • Note: 3 duplicates can occur in bi-weekly months that span 3 pay periods
  • max_dup_count == 4 → 4×/month (48) or Weekly (52) based on posted_date spacing
    • Default to 48 if spacing signal insufficient or posted_date unavailable
    • If spacing ≈ weekly (7-day intervals), use 52
  • max_dup_count >= 5 → Weekly (52 pay periods)
Scope: Strictly per (business, agent, month) - cadence inference operates on agent-specific rows. Fallbacks (for cadence inference only, not for joins):
  • Primary: member_id (string)
  • Fallback 1: member_key if member_id is null/blank
  • Fallback 2: member_first_name + member_last_name composite if both missing
  • Default: PPY=12 (Monthly) with MISSING_MEMBER_ID_FOR_CADENCE warning if all fail
Audit Fields (persisted):
  • inferred_pay_periods_per_year (int)
  • inferred_cadence_label (string)
  • mixed_cadence_flag (bool)
  • member_id_duplication_map (JSON: Member ID → count)
  • member_dup_count_distribution (JSON: {1×: x, 2×: y, 3×: z, 4×: w, 5×+: v})

2. Rounding Standard (LOCKED)

Constants:
  • CENT = Decimal("0.01") - Final money quantization unit
  • TOLERANCE = Decimal("0.05") - Reconciliation tolerance
Rules:
  • All money math uses Decimal (never float)
  • Final persisted/displayed money values are CENT-quantized via .quantize(CENT)
  • Use _money() for final values, _d_raw() for intermediate calculations
  • Float contamination guardrail: Assertions prevent float types in commission calculation paths
Implementation:
  • _d_raw(x) - Parse to Decimal WITHOUT quantization (preserves full precision)
  • _money(x) - Parse to Decimal WITH quantization to cents (for final values)

3. Row-Based Commission Invariant (ENFORCED)

Rule: Commissions use row_count (absorbed transaction rows), NEVER employee_count (distinct employees). Guardrails:
  • Hard assertion: row_count must be int (not float)
  • Hard assertion: employee_count must NEVER be used in commission calculation
  • Float contamination guardrail: pepm_rate and normalized_rate must be Decimal (not float)
TPA KEY Normalization Formula:
normalized_rate = (PEPM_monthly × 12) ÷ inferred_pay_periods_per_year
agent_commission = normalized_rate × row_count_basis
Implementation: See build_stage3_like_dataframe() in repo_b/output_adapter.py (lines 590-622).

4. UNDERFUNDED_TPA Soft-Fail (LOCKED)

Behavior: Non-blocking anomaly detection (pipeline continues, never raises). Detection:
  • agent_commissions > net_payout + TOLERANCE (where TOLERANCE = Decimal("0.05"))
  • Emits UNDERFUNDED_TPA anomaly with:
    • business_name, period_label, shortfall_amount
    • stage1_net_payout, stage3_agent_commissions
    • primary_agent, agent_names, lives
    • details_json (JSON string with full context)
Invariant Preservation:
  • Sets owner_residual = Decimal("0") to preserve CEO-level invariant
  • Tracks shortfall in anomaly (not in owner residual)
  • gross == agent_sum + owner + chargebacks still holds at CEO level
Export:
  • CSV: business_anomalies_underfunded_tpa_{period}.csv
  • BigQuery: business_anomalies_history table with anomaly_type = "UNDERFUNDED_TPA"
Implementation: See build_stage3_like_dataframe() in repo_b/output_adapter.py (lines 650-700).

Regression Test Suite (MUST PASS)

Test Files

  1. tests/test_cadence_inference.py
    • test_cadence_inference_monthly() - 1× duplicate → 12 PPY
    • test_cadence_inference_biweekly() - 2× duplicate → 26 PPY
    • test_cadence_inference_biweekly_3x() - 3× duplicate → 26 PPY
    • test_cadence_inference_4x_per_month() - 4× duplicate → 48 PPY
    • test_cadence_inference_5plus_weekly() - 5+ duplicates → 52 PPY
    • test_cadence_inference_mixed() - Multiple patterns → mixed_cadence_flag=True
    • test_commission_uses_inferred_cadence() - Commission uses inferred PPY, not Period label
    • test_decimal_purity_no_floats() - No float types in cadence inference results
  2. tests/test_row_based_commission_invariant.py
    • test_commission_uses_row_count_not_employee_count() - Commission uses row_count, not employee_count
  3. tests/test_underfunded_tpa.py
    • test_underfunded_case_emits_anomaly() - UNDERFUNDED_TPA anomaly emitted, no exception
    • test_funded_case_no_anomaly() - No anomaly when funded
    • test_tolerance_boundary_no_anomaly() - No anomaly within tolerance
    • test_business_normalization_consistency() - Business normalization handles variations
    • test_decimal_purity_anomaly_payload() - No float types in anomaly payloads
    • test_decimal_purity_ceo_snapshot() - No float types in CEO snapshot
    • test_excel_dataframe_no_floats() - Excel DataFrame uses CENT-quantized strings
Execution:
python -m pytest tests/test_cadence_inference.py tests/test_row_based_commission_invariant.py tests/test_underfunded_tpa.py -v
Requirement: All tests must pass before any logic changes or production deployment.

Repo B as Authoritative Source

Status: Repo B is the AUTHORITATIVE source of truth for:
  • Agent payouts
  • Audit narratives
  • Dispute resolution
Legacy System: Repo A is legacy/non-authoritative for commission math. Parity comparisons may show LEGACY_UNDERPAYMENT_DETECTED when Repo A payout < Repo B payout for the same business/agent/month, indicating Repo A’s historical calculation diverged from the audit-grade TPA KEY normalization. Parity Label (Informational Only):
  • LEGACY_UNDERPAYMENT_DETECTED - When Repo A payout < Repo B payout AND Repo B audit basis is supported by cadence inference + TPA KEY normalization
  • This label is informational only (no logic changes to payouts)

Story Sheets Wireframe

See repo_b/README.md section “Story Sheets Wireframe” for display requirements for cadence inference and audit fields.

Git Tag

Tag: repo-b-audit-grade-v1
Commit Message: “Lock Repo B audit-grade commission engine (cadence inference, cent rounding, tests, underfunded soft-fail)“

Change Control

Process: No logic changes to locked components unless:
  1. Regression test fails (investigate root cause)
  2. Audit approval obtained
  3. Test suite updated to cover new behavior
  4. Documentation updated
Allowed Changes:
  • Bug fixes (with test coverage)
  • Performance optimizations (preserving behavior)
  • Documentation updates
  • Export format changes (preserving calculation logic)
Prohibited Changes:
  • Cadence inference rules (without audit approval)
  • Rounding standard (without audit approval)
  • Row-based commission invariant (never change)
  • UNDERFUNDED_TPA behavior (soft-fail must remain)