Mortgage Math Module BIX Acceptance Test Battery
PreFi, Inc. / Purpose Technology, Inc. d/b/a Purlend Engineering Reference | Gear 1 Sprint Version 1.0 | March 2026
This document is the authoritative acceptance test battery for the Clarity Engine Mortgage Math Module. BIX must pass every test vector before the math module is considered Gear 1 complete.
Every test vector contains:
A test vector passes if and only if:
CRITICAL: BIX must submit the full computation_trace with every test vector submission — not just the final output. David will verify the intermediate steps, not just the answer. A correct final answer produced by wrong intermediate steps is a failing test.
Category Vectors Function(s) Covered Pass Gate Section 2: Workbook Scenarios
All must pass — ground truth from Pro_Calc.xlsx Section 3: Core Function Coverage
All must pass — covers every function once Section 4: Boundary Conditions
DTI at 41%, LTV at 80%/78%, DSCR at 1.00, rate at 15% All must pass — catches off-by-one logic errors Section 5: Prohibited Pattern Traps
All 10 prohibited patterns from BIX Implementation Guide All must pass — failure here is a critical bug Section 6: VA Income Split
GMI dual-path, residual income, TC08 from workbook All must pass — highest-risk computation in system Section 7: Combination Scenarios
Multi-function chains, full cash-to-close, buydown + DTI All must pass — validates function interoperability
These test vectors are derived directly from Pro_Calc.xlsx. The intermediate steps have been verified by tracing every formula in the workbook. Any deviation from these expected outputs is a defect.
Workbook Canonical Inputs: mortgage_balance=380,000 | closing_costs=11,400 (3%) | loan_amount=391,400 | current_payment=2,528.00 | offer_rate=6.00% | term=30yr | CC balances=19,000 total | CC minimums=570/month
Source: Pro_Calc.xlsx Worksheet!B24 | Formula: =PMT(B21/12,B12*12,B20)*-1
Input Value loan_amount 391,400.00 annual_rate 0.06 (6.00%) term_years 30
Intermediate Steps: Step 1: monthly_rate = 0.06 / 12 = 0.0050000000 Step 2: term_months = 30 × 12 = 360 Step 3: (1 + monthly_rate)^term_months = (1.005)^360 = 6.0225752123 Step 4: numerator = 0.0050000000 × 6.0225752123 = 0.0301128761 Step 5: denominator = 6.0225752123 − 1 = 5.0225752123 Step 6: factor = 0.0301128761 / 5.0225752123 = 0.0059955053 Step 7: pmt_raw = 391,400 × 0.0059955053 = 2,346.6407554479 Step 8: pmt = CEIL(2346.6407554479, 0.01) = 2,346.65
Output Field Expected Value Rounding Policy monthly_pi 2,346.65 CEIL to nearest $0.01 pmt_raw (trace only) 2,346.6407554479 No rounding — internal only
What This Tests: Basic PMT at 6% / 30yr — the most common configuration in the workbook. If this fails, everything else fails.
Source: Pro_Calc.xlsx Worksheet!B25 | Formula: =B1-B24 (current_payment − new_payment)
Input Value current_payment 2,528.00 new_payment_raw (from TV-WB-001) 2,346.6407554479
Intermediate Steps: Step 1: monthly_savings_raw = 2,528.00 − 2,346.6407554479 = 181.3592445521 Step 2: annual_savings = 181.3592445521 × 12 = 2,176.3109346255 Step 3: five_year_savings = 181.3592445521 × 60 = 10,881.5546731277 Note: savings is computed on pmt_raw before rounding — NOT on pmt_ceil (2,346.65) Using pmt_ceil would give 181.35 savings instead of 181.359... — WRONG approach
Output Field Expected Value Rounding Policy monthly_savings_raw 181.3592445521 Internal — carry full precision monthly_savings_display $181.36 ROUND to nearest $0.01 for display annual_savings $2,176.31 ROUND to nearest $1.00 five_year_savings $10,882 ROUND to nearest $1.00
What This Tests: Savings must be computed on pmt_raw — not on the rounded pmt_ceil. Using the rounded payment to compute savings introduces a cascade error across all downstream optimization outputs.
Source: Derived from Pro_Calc.xlsx — closing_costs=Worksheet!B6, monthly_savings=Worksheet!B25
Input Value total_closing_costs 11,400.00 (3% of 380,000) monthly_savings_raw 181.3592445521
Intermediate Steps: Step 1: recapture_raw = 11,400 / 181.3592445521 = 62.8586649... Step 2: recapture_months = CEIL(62.858...) = 63 Step 3: 63 months = 5 years 3 months Step 4: net_savings at 7 years (84 months): 84 × 181.36 − 11,400 = 15,234 − 11,400 = 3,834 Step 5: net_savings at 10 years (120 months): 120 × 181.36 − 11,400 = 21,763 − 11,400 = 10,363
Output Field Expected Value Rounding Policy recapture_months 63 CEIL to nearest whole month recapture_label '5 years 3 months' String format net_savings_7yr $3,834 ROUND to nearest $1 net_savings_10yr $10,363 ROUND to nearest $1
Source: Pro_Calc.xlsx Worksheet!C22 | Formula: =NPER(C21/12,−C24,C20)/12
Input Value loan_amount 391,400.00 annual_rate 0.0575 (5.75%) monthly_payment 2,528.00 (keeping current payment)
Intermediate Steps: Step 1: monthly_rate = 0.0575 / 12 = 0.0047916667 Step 2: ratio = monthly_rate × loan / payment = 0.0047916667 × 391,400 / 2,528 = 1,875.2083 / 2,528 = 0.7418743407 Step 3: 1 − ratio = 1 − 0.7418743407 = 0.2581256593 Step 4: ln(0.2581256593) = −1.3543087611 Step 5: ln(1 + monthly_rate) = ln(1.0047916667) = 0.0047802232 Step 6: NPER_months = −(−1.3543087611) / 0.0047802232 = 283.3149650419 Step 7: NPER_years = 283.3149650419 / 12 = 23.6095804202
Output Field Expected Value Rounding Policy term_months 283.3149650419 Full precision — carry to display step term_years 23.6095804202 Full precision term_label '23 years 7 months' CEIL months: 283.31 → 284 → 23yr 8mo acceleration_vs_30yr 360 − 284 = 76 months early Integer subtraction
What This Tests: NPER uses natural log — not iteration. If BIX implements iterative solving instead, it will produce slightly different intermediate steps even if the final answer rounds to the same value. The trace must show ln() steps.
Source: Pro_Calc.xlsx Worksheet!D20 | Formula: =PV(D21/12,D22*12,B1)*−1
Input Value target_monthly_payment 2,528.00 annual_rate 0.06 (6.00%) term_years 30
Intermediate Steps: Step 1: monthly_rate = 0.06 / 12 = 0.0050000000 Step 2: term_months = 360 Step 3: (1 + monthly_rate)^(−360) = (1.005)^(−360) = 0.1660419280 Step 4: 1 − 0.1660419280 = 0.8339580720 Step 5: discount_factor = 0.8339580720 / 0.0050000000 = 166.7916143923 Step 6: max_loan_raw = 2,528 × 166.7916143923 = 421,649.2011838204 Step 7: max_loan = FLOOR(421,649.2011838204, 1.00) = 421,649
Output Field Expected Value Rounding Policy max_loan_raw 421,649.2011838204 Internal — full precision max_loan 421,649 FLOOR to nearest $1.00 cash_available 421,649 − 391,400 = 30,249 FLOOR then subtract
Source: Pro_Calc.xlsx Worksheet!F24 | Formula: =PMT(F21/12,F22*12,F20)*−1
Input Value loan_amount 391,400.00 annual_rate 0.0575 (5.75%) term_years 15
Intermediate Steps: Step 1: monthly_rate = 0.0575 / 12 = 0.0047916667 Step 2: term_months = 15 × 12 = 180 Step 3: (1.0047916667)^180 = 2.3642011178 Step 4: numerator = 0.0047916667 × 2.3642011178 = 0.0113284887 Step 5: denominator = 2.3642011178 − 1 = 1.3642011178 Step 6: factor = 0.0113284887 / 1.3642011178 = 0.0083040527 Step 7: pmt_raw = 391,400 × 0.0083040527 = 3,250.2250805949 Step 8: pmt_ceil = CEIL(3250.2250805949, 0.01) = 3,250.23
Output Field Expected Value Rounding Policy monthly_pi 3,250.23 CEIL to nearest $0.01 payment_increase_vs_current 3,250.23 − 2,528.00 = 722.23/month After ceiling pmt_raw (trace) 3,250.2250805949 Internal full precision
Source: Pro_Calc.xlsx — loan = mortgage(391,400) + total CC balances(19,000) = 410,400
Input Value loan_amount 410,400.00 (391,400 + 19,000 CC balances) annual_rate 0.06 (6.00%) term_years 30
Intermediate Steps: Step 1: monthly_rate = 0.005 Step 2: term_months = 360 Step 3: (1.005)^360 = 6.0225752123 Step 4: factor = 0.005 × 6.0225752123 / (6.0225752123 − 1) = 0.0059955053 Step 5: pmt_raw = 410,400 × 0.0059955053 = 2,460.5553552269 Step 6: pmt_ceil = 2,460.56
Output Field Expected Value Rounding Policy monthly_pi 2,460.56 CEIL to nearest $0.01 pmt_raw (trace) 2,460.5553552269 Internal full precision total_monthly_savings 2,528 + 570 − 2,460.56 = 637.44 Old payment + old minimums − new payment
Workbook Note: The workbook shows E25 savings as 649.686 due to a cell reference anomaly (PMT formula references cash-out loan amount D20 instead of debt-consolidation loan E20). The correct canonical value is 637.44. BIX uses standard PMT on the actual loan amount — 637.44 is the correct expected output.
Source: Pro_Calc.xlsx Worksheet!B37 | Formula: =B25*12
Input Value monthly_savings_raw 181.3592445521 periods 12 (annual) annual_savings = 181.3592445521 × 12 = 2,176.3109346255 display: $2,176.31 (round to nearest cent for display)
Output Field Expected Value annual_savings $2,176.31 five_year_savings $10,881.55
Source: Pro_Calc.xlsx Worksheet!B6 | Formula: =B5*0.03 closing_costs = 380,000 × 0.03 = 11,400.00 preliminary_loan = 380,000 + 11,400 = 391,400.00
Output Field Expected Value closing_costs 11,400.00 preliminary_loan 391,400.00
Source: Pro_Calc.xlsx Worksheet!F4:F12 | Formula: =E4*0.03 (3% of balance) CC 1: 5,000 × 0.03 = 150.00 CC 2: 10,000 × 0.03 = 300.00 CC 3: 4,000 × 0.03 = 120.00 total_minimums = 150 + 300 + 120 = 570.00 total_balances = 5,000 + 10,000 + 4,000 = 19,000
Output Field Expected Value total_cc_minimums 570.00 total_cc_balances 19,000.00
Verify PMT computation at 5.75% rate (term-reduction scenario baseline). INPUT: loan=391,400 rate=0.0575 term=30yr Step 1: monthly_rate = 0.0575/12 = 0.0047916667 Step 2: (1.0047916667)^360 = 5.5645... let x = (1+r)^n x = exp(360 × ln(1.0047916667)) = exp(360 × 0.0047802232) = exp(1.7208804) = 5.5888097491 Step 3: numerator = 0.0047916667 × 5.5888097491 = 0.0267755050 Step 4: denominator = 5.5888097491 − 1 = 4.5888097491 Step 5: factor = 0.0267755050 / 4.5888097491 = 0.0058352116 Step 6: pmt_raw = 391,400 × 0.0058352116 = 2,284.0698... Let me be precise: 391400 × 0.0047916667 × 5.5888097491 / (5.5888097491-1) EXPECTED OUTPUT: pmt_ceil = 2,284.07 Note: This is the term-reduction scenario new payment at same 30-year term with lower rate. Verify exact value matches Step 6.
Compute total interest paid for 30yr vs 15yr scenarios to verify amortization totals. SCENARIO A (30yr at 6%): pmt=2,346.65, n=360 total_paid = 2,346.65 × 360 = 844,794.00 total_interest = 844,794.00 − 391,400 = 453,394.00
SCENARIO F (15yr at 5.75%): pmt=3,250.23, n=180 total_paid = 3,250.23 × 180 = 585,041.40 total_interest = 585,041.40 − 391,400 = 193,641.40
Interest savings 15yr vs 30yr: 453,394.00 − 193,641.40 = 259,752.60 But: higher payment 3,250.23 − 2,346.65 = 903.58/month more
Output Field Expected Value total_interest_30yr $453,394.00 total_interest_15yr $193,641.40 interest_savings $259,752.60 monthly_premium $903.58 more/month
Input Steps Expected Output INPUT: loan=410,400 payment=2,460.56 term=360 months Solve for monthly_rate via Newton's method monthly_rate = 0.0050000000 (5.9999...% annual — confirms rate is 6%)
Input Steps Expected Output INPUT: loan=391,400 rate=6% monthly_payment=3,000 (extra $454/month) NPER = −ln(1 − 0.005×391400/3000) / ln(1.005) NPER = 226.8 months → 227 months = 18yr 11mo (saves 133 months vs 30yr)
Input Steps Expected Output INPUT: first_mortgage=421,649 property_value=530,000 LTV = 421,649 / 530,000 LTV = 79.56% (just under 80% — no PMI required)
Input Steps Expected Output INPUT: loan=391,400 original_rate=6.5% bought_down_rate=6.0% points=1 tenure=7yr point_cost=3,914 monthly_savings=112.44 breakeven=3914/112.44=34.8→35 months breakeven = 35 months (2yr 11mo) | JUSTIFIED for 7yr tenure
Input Steps Expected Output INPUT: loan=391,400 rate=0.065 term=30 monthly_rate=0.0054167 (1.0054167)^360=7.0265 factor=0.0063213 pmt_raw=2,474.18 pmt_ceil=2,474.19
Input Steps Expected Output INPUT: checking=45,000 retirement=120,000 cash_to_close=14,800 piti=2,800 eligible = (45,000−14,800) + 120,000×0.60 = 30,200 + 72,000 = 102,200 required (2 months) = 5,600 | surplus = 96,600 | PASS
Input Steps Expected Output INPUT: CC1 bal=5,000 limit=5,000 (100%) CC2 bal=10,000 limit=12,000 (83%) CC3 bal=4,000 limit=15,000 (27%) overall = 19,000/32,000 = 59.4% | paydown CC1 to 30%: pay 3,500 paydown CC2 to 30%: pay 6,400 total_paydown = 9,900 | projected score improvement: +40-60 points
Input Steps Expected Output INPUT: monthly_savings=181.36 rate=4%(savings account) months=60 FV = 181.36 × ((1.003333)^60 − 1) / 0.003333 = 181.36 × 66.2993 = 12,019 future_value = $12,019
One canonical test vector per function. Covers functions not directly represented in the workbook. All intermediate steps must appear in the computation_trace.
Inputs Intermediate Steps Expected Output P&I=2,346.65 annual_tax=9,600 annual_insurance=2,400 hoa=200 pmi=0 (LTV<80%) tax_mo=9600/12=800 ins_mo=2400/12=200 PITI=2346.65+800+200+200+0 monthly_piti = 3,546.65 | breakdown: {pi:2346.65, tax:800, ins:200, hoa:200, mi:0}
Inputs Intermediate Steps Expected Output gmi=9,000 housing=3,546.65 debts=480(auto:380+CC:100) auto has 8 pmts left dti_limit=0.45 EXCL-10PMT: exclude auto(8 pmts remain). obligations=100 only back_end = (3546.65+100)/9000 = 40.5% PASS headroom=$508/mo flag:EXCL-10PMT recorded
Inputs Intermediate Steps Expected Output salary=72,000/yr SS=1,100/mo (non-taxable) context=DTI (not VA residual) w2_gmi=72000/12=6,000 ss_dti=1100×1.25=1,375 gross_up_applied=true gmi_total=7,375 | breakdown:[{w2:6000},{ss_gross:1375}] gross_up_streams:[{ss,1100,1.25}]
Inputs Intermediate Steps Expected Output purchase=550,000 down=110,000 heloc_line=50,000 (0 drawn) second=0 first=440,000 LTV=440000/550000=80.00% CLTV=440000/550000=80.00% HCLTV=(440000+50000)/550000 LTV=80.00% CLTV=80.00% HCLTV=89.09% pmi_required=false (LTV=80% not >80%)
Inputs Intermediate Steps Expected Output loan=280,000 rate=7.5% term=30 rent=2,800 tax=380 ins=120 hoa=0 P&I=PMT(0.075/12,360,280000)=1,958.36 PITIA=1958.36+380+120+0=2,458.36 DSCR=2800/2458.36=1.14 tier=DSCR_ACCEPTABLE cashflow=341.64/month
Inputs Intermediate Steps Expected Output base_loan=310,000 LTV=96.5% term=30yr upfront=310000×0.0175=5,425 annual=310000×0.0055=1,705 monthly=1705/12=142.08 upfront_mip=5,425 monthly_mip=142.08 cancellation=LIFE_OF_LOAN (LTV>90% at origination)
Inputs Intermediate Steps Expected Output loan=414,000 property=450,000 LTV=92% score=720 PMI rate from matrix: score 720-739, LTV 90-95% = 0.55% monthly=414000×0.0055/12 monthly_pmi=189.75 (estimated) cancel_at_balance=450000×0.80=360,000
Inputs Intermediate Steps Expected Output loan=380,000 note_rate=7.25% term=30yr pmt_note=PMT(0.0725/12,360,380000)=2,593.28 pmt_yr1=PMT(0.0525/12,360,380000)=2,098.82 pmt_yr2=PMT(0.0625/12,360,380000)=2,340.68 yr1_subsidy=(2593.28-2098.82)×12=5,934.72 yr2_subsidy=(2593.28-2340.68)×12=3,031.20 total=8,965.92
Inputs Intermediate Steps Expected Output purchase=400,000 down=20,000(5%) loan=380,000 rate=6.75% close day 15 of month down=20000 origin(0.75%)=2850 title=2500 appraisal=650 credit=65 prepaid_int=(380000×0.0675/365)×16=1,126 ins(14mo)=1,960 tax(3mo)=1,200 gross=30,351 less seller credit 8,000 net_cash_to_close=22,351
Inputs Intermediate Steps Expected Output loan=350,000 orig_rate=7.0% bought_down_rate=6.75% points=1 tenure=3yr point_cost=3,500 pmt_70=2,328.55 pmt_675=2,270.01 monthly_savings=58.54 breakeven=3500/58.54=59.8→60 months breakeven=60 months (5yr) tenure=36 months < 60 NOT JUSTIFIED net_loss=3500-(36×58.54)=3500-2107=1,393
These vectors test behavior at exact threshold values. Off-by-one errors, wrong inequality operators (> vs >=), and floating-point precision issues at boundaries are common failure modes.
Inputs Intermediate Steps / Logic Expected Output gmi=8,500 obligations=3,485 dti_limit=0.41 (VA benchmark) back_end = 3,485/8,500 = 0.41000000 = 41.000% result=AT_BENCHMARK action=TRIGGER_RESIDUAL_INCOME_TEST (not auto-deny) NOT result=FAIL
Inputs Intermediate Steps / Logic Expected Output gmi=8,500 obligations=3,485.09 dti_limit=0.41 back_end = 3,485.09/8,500 = 0.410011 = 41.001% result=OVER_BENCHMARK action=TRIGGER_RESIDUAL_INCOME_TEST NOT result=FAIL NOT result=DENY
Inputs Intermediate Steps / Logic Expected Output first_mortgage=400,000 property_value=500,000 LTV = 400,000/500,000 = 0.8000 = 80.00% pmi_required=FALSE (rule: > 80%, not >= 80%) LTV=80.00% does NOT trigger PMI
Inputs Intermediate Steps / Logic Expected Output first_mortgage=400,050 property_value=500,000 LTV = 400,050/500,000 = 0.80010 = 80.01% pmi_required=TRUE (rule: > 80%)
Inputs Intermediate Steps / Logic Expected Output current_balance=390,000 original_value=500,000 LTV = 390,000/500,000 = 0.7800 = 78.00% pmi_auto_cancel=TRUE (Homeowners Protection Act: at or below 78%)
Inputs Intermediate Steps / Logic Expected Output monthly_rent=2,500 monthly_pitia=2,500 DSCR = 2,500/2,500 = 1.0000 tier=DSCR_BREAKEVEN (1.00 ≤ 1.00 < 1.10) cashflow=$0.00/month
Inputs Intermediate Steps / Logic Expected Output monthly_rent=2,499.75 monthly_pitia=2,500 DSCR = 2,499.75/2,500 = 0.9999 tier=DSCR_NEGATIVE flag=WARN-MATH-004 NOT tier=DSCR_BREAKEVEN
Inputs Intermediate Steps / Logic Expected Output loan=200,000 rate=0.1499 term=30 Should compute normally. monthly_rate=0.1499/12=0.012492 pmt_raw=2,537.28 pmt_ceil=2,537.29 NO error — WARN-MATH-001 flag only
Inputs Intermediate Steps / Logic Expected Output loan=200,000 rate=0.1500 term=30 rate=15.00% triggers WARN-MATH-001 (unusually high rate) Computation continues: pmt_raw=2,528.75 pmt_ceil=2,528.76 AND validation_flags=[WARN-MATH-001]
Inputs Intermediate Steps / Logic Expected Output gmi=0 housing=2,500 debts=500 dti_limit=0.45 Validation check: gmi=0 triggers ERR-MATH-004 before computation status=error errors=[ERR-MATH-004] NO computation performed NO division by zero
Each vector is designed to expose a specific prohibited implementation pattern from Section 7 of the BIX Implementation Guide. A correct final answer produced by a prohibited pattern is still a FAIL — the computation_trace must show the correct approach.
How These Traps Work: For each prohibited pattern, the trap vector is chosen so that the wrong approach produces a DIFFERENT final answer from the correct approach. BIX cannot pass these by accident.
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used loan=100,000 rate=0.06 term=30yr CORRECT: monthly_rate=0.06/12=0.005 pmt_raw=599.55 WRONG (uses annual rate): pmt_raw=6,000.16 (wildly different — catches this bug immediately) EXPECTED: pmt_ceil=599.56
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used loan=391,400 rate=0.06 term=30yr (same as TV-WB-001) CORRECT trace: carry monthly_rate=0.0050000000 (10 dp) through all steps Expected pmt_raw=2,346.6407554479 If BIX rounds monthly_rate to 0.005000 (6dp) at step 1, error propagates. Check trace shows 10 decimal places at every step.
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used salary=60,000/yr SS=800/mo non-taxable context=VA_RESIDUAL CORRECT: gmi_for_dti=5,000+(800×1.25)=6,000 BUT net_for_residual=5,000+800=5,800 (NO gross-up) net_income_for_residual=5,800 gross_up_NOT_applied_to_residual=true Two SEPARATE output fields required
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used fha_loan=320,000 origination_LTV=96.5% current_LTV=78% (after payments) CORRECT: FHA MIP does NOT cancel at 78% current LTV — cancellation is origination-LTV-based mip_cancellation=LIFE_OF_LOAN (origination LTV>90%) NOT mip_cancellation=CANCELLED NOT triggered by current LTV
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used VA loan. Seller offering $18,000. Standard closing costs=$12,000. Concessions=$6,000. Loan=$400,000. 4% cap: 400,000×0.04=16,000. Cap applies to concessions ONLY (6,000 < 16,000 — OK) Standard_closing_costs=$12,000 NOT subject to 4% cap. Total seller payment allowed: 12,000+6,000=$18,000. Concession_cap_check: 6,000 <= 16,000 PASS
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used loan=350,000 note_rate=7.25% year1_rate=5.25% gmi=9,000 other_debts=500 DTI must use note_rate PMT (not year1): pmt_at_note=2,388.43 PITI=2,388.43+700+150=3,238.43 dti=3,738.43/9,000=41.5% qualifying_rate_used=7.25% NOT 5.25% NOT year1_rate
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used VA loan. gmi=7,000 housing=3,100 debts=800 back_end_dti=55.7% CORRECT: VA has NO hard DTI stop. 55.7% triggers residual income test, not denial. result=OVER_BENCHMARK action=TRIGGER_RESIDUAL_INCOME_TEST NOT result=DENY NOT result=FAIL
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used DSCR loan. borrower_gmi=8,000. rent=2,400. PITIA=2,100. borrower_other_debts=1,200. CORRECT: DSCR=2400/2100=1.14. Personal GMI and debts are irrelevant. dscr=1.14 gmi_NOT_used=true personal_dti_NOT_computed=true qualification_basis=property_cashflow_only
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used checking=10,000 retirement_vested=80,000 cash_to_close=8,000 piti=2,500 required=2mo CORRECT: retirement_eligible = 80,000 × 0.60 = 48,000 post_close_checking=10,000-8,000=2,000 eligible_reserves=2,000+48,000=50,000 required=5,000 PASS NOT eligible=2,000+80,000=82,000
Inputs Correct Approach Expected Output — Must Fail If Wrong Pattern Used CALL 1: loan=391,400 rate=6% term=30 → pmt=2,346.65 CALL 2: loan=391,400 rate=6% term=15 → must NOT return cached 2,346.65 CALL 2 EXPECTED: pmt_raw=3,307.77 pmt_ceil=3,307.78 cache_key_must_include_term_years
The VA income split is the highest-risk calculation in the system. The same borrower must produce TWO different income values: gross income (with gross-up) for DTI, and net income (no gross-up) for residual. These vectors verify both paths are implemented correctly and independently.
Source: VA Module PRD v1.0 / VA Rules Workbook TC01–TC10. These are the most important test vectors in this entire battery.
This is the most important test in the battery. Same borrower must yield two different income values.
Input Value salary (W-2) $5,000/month gross disability income (non-taxable) $1,200/month context VA loan qualification
DTI Path (gross income): gmi_w2 = 5,000 (gross salary) gmi_disability = 1,200 × 1.25 = 1,500 (25% gross-up for non-taxable) gmi_for_dti = 5,000 + 1,500 = 6,500 gross_up_applied = true
Residual Income Path (net income): net_salary = 5,000 × (1 − tax_rate) OR use actual net pay net_disability = 1,200 (NO gross-up — already net for residual) net_income_residual = net_salary + 1,200 gross_up_NOT_applied_to_residual = true Note: net_income_for_residual ≠ gmi_for_dti — this is correct behavior
Output Field Expected Value Critical Check gmi_for_dti 6,500.00 Includes 1.25× gross-up on disability net_income_for_residual varies by net salary + 1,200 NO gross-up on disability gmi_for_dti ≠ net_income_for_residual
These must be different — if equal, gross-up not applied correctly two_separate_fields_in_response YES API response must contain BOTH fields independently
Source: VA Rules Workbook TC01 — Purchase, 1st use, 0% down, verified against VA Chapter 4 residual income tables
Input Value loan_purpose Purchase va_use First use down_payment 0% loan_amount 425,000 annual_rate 6.75% term 30yr gross_monthly_income 8,200 net_monthly_income 6,800 (used for residual) monthly_debts 600 property_tax 583/mo insurance 125/mo family_size 4 region Midwest
Key Computations: P&I = PMT(0.0675/12, 360, 425000) = 2,756.32 PITI = 2,756.32 + 583 + 125 = 3,464.32 DTI = (3,464.32 + 600) / 8,200 = 49.6% (over 41% — triggers residual test) Residual base = net_income − (PITI + all_debts) = 6,800 − (3,464.32 + 600) = 2,735.68 VA table threshold (4-person, Midwest) = $1,003/month Residual = 2,735.68 ≥ 1,003 → PASS DTI > 41% + residual ≥ threshold: check 120% rule threshold = 1,003 × 1.20 = 1,203.60 2,735.68 ≥ 1,203.60 → PASS (well above even the 120% enhanced threshold)
Output Field Expected Value dti 49.6% dti_benchmark_triggered true (>41%) residual_income $2,735.68 residual_threshold $1,003 residual_120pct_threshold $1,203.60 residual_result
overall_va_result
Source: VA Rules Workbook TC08 — the most important edge case. Workbook mislabels this as FAIL. Correct result is PASS.
Input Value dti 53.7% (significantly over 41% benchmark) net_monthly_income $5,200 piti $2,200 monthly_debts $600 family_size 3 region Northeast va_residual_threshold (3-person, Northeast) $1,003/month
Residual Computation: residual = net_income − (piti + debts) = 5,200 − (2,200 + 600) = 2,400 standard_threshold = 1,003 enhanced_threshold (120%) = 1,003 × 1.20 = 1,203.60 DTI > 41%: use enhanced threshold
WORKBOOK LABELING ERROR: TC08 is labeled 'Fail 120% rule' in VA_Rules_Workbook_10-10.xlsx CORRECT RESULT: PASS — the math produces $2,400 residual vs $1,203.60 threshold BIX must implement the correct math — NOT the workbook label
Output Field Expected Value Workbook Label (WRONG) residual_income $2,400.00 — enhanced_threshold $1,203.60 — residual_result
FAIL (WRONG — BIX must produce PASS) overall_va_result
—
IRRRL requires net tangible benefit — new payment must be lower than old payment or term must reduce.
Input Value loan_purpose
current_rate 7.25% new_rate 6.50% loan_amount 385,000 term 30yr current_payment 2,627.63 new_pmt = PMT(0.065/12, 360, 385000) = 2,434.60 payment_reduction = 2,627.63 − 2,434.60 = 193.03/month net_tangible_benefit = TRUE (payment reduced) recapture (if closing costs = 5,775): 5,775/193.03 = 29.9 → 30 months
Output Field Expected Value new_pmt_ceil 2,434.61 monthly_savings $193.02 net_tangible_benefit
recapture_months 30
Verify funding fee computation and financed amount.
Input Value va_use First use down_payment_pct 0% loan_purpose Purchase base_loan 400,000 funding_fee_rate 2.15% (first use, 0% down, April 7 2023+ schedule) finance_fee YES funding_fee = 400,000 × 0.0215 = 8,600 total_loan = 400,000 + 8,600 = 408,600 LTV_with_fee = 408,600 / property_value (must check against appraisal) new_pmt = PMT(rate/12, 360, 408,600)
Output Field Expected Value funding_fee $8,600 total_loan_with_fee $408,600 funding_fee_rate_used 2.15% exemption_checked TRUE (must check exemption first)
These vectors chain multiple functions together. They verify that function outputs feed correctly into subsequent function inputs, and that the computation_trace captures all steps across the chain.
Tests: MATH-PMT-001 → MATH-PITI-001 → MATH-DTI-001 in sequence
Input Value purchase_price 500,000 down_payment 50,000 (10%) loan_amount 450,000 annual_rate 6.875% term 30yr annual_tax 10,200 annual_insurance 2,400 hoa 0 score 740 gross_monthly_income 11,500 monthly_debts 750 dti_limit 0.45 Step 1 (PMT): monthly_rate=0.006875/... wait: 6.875/12=0.0057292 (1.0057292)^360=7.9074 factor=0.0057292×7.9074/(7.9074-1)=0.006551 pmt_raw=450,000×0.006551=2,947.88 pmt_ceil=2,947.89 Step 2 (PITI): tax=10200/12=850 ins=2400/12=200 PMI: LTV=450/500=90% score 740→rate 0.32% pmi=450000×0.0032/12=120.00 PITI=2947.89+850+200+0+120=4,117.89 Step 3 (DTI): back_end=(4117.89+750)/11500=4867.89/11500=42.3% 42.3% < 45% limit → PASS headroom=11500×0.45-4867.89=297.11/month
Output Field Expected Value pmt_ceil $2,947.89 monthly_piti $4,117.89 back_end_dti 42.3% result
dti_headroom $297.11/month
Old loan: 391,400 at 7.25% with 27yr remaining → old_pmt=2,758.34 New loan: 391,400 at 5.75% for 30yr → new_pmt=2,284.39 monthly_savings=2,758.34-2,284.39=473.95 annual=5,687.40 closing_costs=6,400 recapture=6400/473.95=13.5→14 months (1yr 2mo) NPER if keep old payment: NPER(0.0575/12, 2758.34, 391400) =−ln(1−0.0047917×391400/2758.34)/ln(1.0047917) =−ln(1−0.6790)/ln(1.004792)=−ln(0.3210)/0.004792=234.5→235 months=19yr 7mo Payoff acceleration: 360−235=125 months early
Output Field Expected Value old_pmt $2,758.34 new_pmt $2,284.39 monthly_savings $473.95 recapture_months 14 term_if_keep_old_pmt 235 months (19yr 7mo) acceleration 125 months
Tests: MATH-BUYDOWN-001 output feeding MATH-DTI-001 at note_rate loan=380,000 note_rate=7.25% gmi=9,500 debts=800 Buydown: pmt_note=2,593.28 pmt_yr1=2,098.82 pmt_yr2=2,340.68 buydown_fund=8,965.92 DTI uses pmt_note (7.25%), NOT pmt_yr1 (5.25%) PITI = 2,593.28+700+180=3,473.28 DTI = (3,473.28+800)/9,500 = 4,273.28/9,500 = 45.0% 45.0% = limit exactly → PASS (not over)
Output Field Expected Value buydown_fund $8,965.92 qualifying_pmt_used $2,593.28 (note rate, NOT year-1 rate) dti 45.0% result PASS (at limit exactly)
Tests: Full payment comparison showing MIP vs PMI cost difference Purchase: 350,000 down: 12,250 (3.5% FHA) loan: 337,750 rate: 6.75% FHA: upfront_mip=337750×0.0175=5,910 financed_loan=343,660 pmt=343660×PMT_factor(6.75%,30)=2,229.32 monthly_mip=343660×0.0055/12=157.51 total_fha_payment=2,229.32+157.51=2,386.83 Conv: down=17,500(5%) loan=332,500 rate=6.75% pmt=332500×PMT_factor=2,156.85 pmi(score720,LTV95%,0.55%)=332500×0.0055/12=152.31 total_conv_payment=2,156.85+152.31=2,309.16 monthly_delta=2,386.83-2,309.16=77.67 more for FHA FHA extra down needed for conv: 17500-12250=5,250
Output Field Expected Value fha_total_payment $2,386.83 conv_total_payment $2,309.16 monthly_delta $77.67 FHA more expensive extra_down_for_conv $5,250
Tests: MATH-DSCR-001 + MATH-RESERVES-001 — full DSCR qualification chain purchase=425,000 down=106,250(25%) loan=318,750 rate=7.875% term=30 rent=3,200 tax=500/mo ins=150/mo hoa=0 DSCR: P&I=PMT(0.07875/12,360,318750)=2,302.98 PITIA=2302.98+500+150=2,952.98 DSCR=3200/2952.98=1.08 tier=DSCR_BREAKEVEN Reserves: checking=80,000 retirement=200,000 closing=16,000 eligible=(80000-16000)+200000×0.60=64000+120000=184,000 required=2952.98×6=17,717.88 (DSCR requires 6mo) surplus=184,000-17,718=166,282 PASS
Output Field Expected Value dscr 1.08 dscr_tier
eligible_reserves $184,000 required_reserves $17,718 reserve_result
BIX submits this completed table with every test run. All 50 vectors must show PASS before Gear 1 math module review.
Vector ID Description Pass/Fail Trace Submitted
Workbook Scenario 1 — —
Workbook Scenario 2 — —
Workbook Scenario 3 — —
Workbook Scenario 4 — —
Workbook Scenario 5 — —
Workbook Scenario 6 — —
Workbook Scenario 7 — —
Workbook Scenario 8 — —
Workbook Scenario 9 — —
Workbook Scenario 10 — —
Workbook Scenario 11 — —
Workbook Scenario 12 — —
Workbook Scenario 13 — —
Workbook Scenario 14 — —
Workbook Scenario 15 — —
Workbook Scenario 16 — —
Workbook Scenario 17 — —
Workbook Scenario 18 — —
Workbook Scenario 19 — —
Workbook Scenario 20 — —
Core Function Coverage 1 — —
Core Function Coverage 2 — —
Core Function Coverage 3 — —
Core Function Coverage 4 — —
Core Function Coverage 5 — —
Core Function Coverage 6 — —
Core Function Coverage 7 — —
Core Function Coverage 8 — —
Core Function Coverage 9 — —
Core Function Coverage 10 — —
Boundary Condition 1 — —
Boundary Condition 2 — —
Boundary Condition 3 — —
Boundary Condition 4 — —
Boundary Condition 5 — —
Boundary Condition 6 — —
Boundary Condition 7 — —
Boundary Condition 8 — —
Boundary Condition 9 — —
Boundary Condition 10 — —
Prohibited Pattern Trap 1 — —
Prohibited Pattern Trap 2 — —
Prohibited Pattern Trap 3 — —
Prohibited Pattern Trap 4 — —
Prohibited Pattern Trap 5 — —
Prohibited Pattern Trap 6 — —
Prohibited Pattern Trap 7 — —
Prohibited Pattern Trap 8 — —
Prohibited Pattern Trap 9 — —
Prohibited Pattern Trap 10 — —
VA Income Split 1 — —
VA Income Split 2 — —
VA Income Split 3 — —
VA Income Split 4 — —
VA Income Split 5 — —
Combination Scenario 1 — —
Combination Scenario 2 — —
Combination Scenario 3 — —
Combination Scenario 4 — —
Combination Scenario 5 — —
— End of Document — CONFIDENTIAL — PreFi, Inc. / Purpose Technology, Inc. d/b/a Purlend