- The pricing engine never sees race or income. It sees ZIP code and device. Same earbuds, matched demand signals. High-income-ZIP, new-device cohort: $74.06. Majority-minority-ZIP, old-device cohort: $93.47. 26.2% more, no protected attribute in the model. Synthetic, seeded 🧵
- Cohort means, not two cherry-picked users: n = 2,880 and n = 3,037 decisions on one SKU (Aura Wireless Earbuds, $79.00 list) from a LinUCB contextual bandit we built as the synthetic stand-in for a retail engine. It optimizes revenue and never receives the protected label.
- Where does the gap come from? Our audit scores every pricing input three ways: |Pearson r| against the protected cohort, mutual information, and a counterfactual replay: set one input to the advantaged cohort's reference value, hold the rest, re-run the engine's own policy.
- Two proxies are obvious. Zip Income Idx: |r| 0.95, MI 1.00, counterfactual +7.8%, VIOLATION. Device Tier: 0.32, 0.08, +2.9%, VIOLATION. Both clear the 0.30 Pearson line and the 0.05 MI line. A per-feature check finds these two. Synthetic population, seeded.
- No per-feature check can see the third. Referral: |r| 0.00, MI 0.00, PASS. Dwell Time: 0.17, 0.03, PASS. Their joint mutual information with the protected class: 0.73, an interaction gain of +0.71 over the best single feature. VIOLATION on the pair, clean on each part.
- The population is built XOR-style: organic referral plus long dwell, and comparison referral plus short dwell, both mark the protected cohort; the other two pairings mark the advantaged one. Neither input alone splits the groups. The engine has referral x dwell cross-terms.
- This is why "we removed ZIP and device from the model" does not hold up. Fairness through unawareness, on this population: drop both inputs, retrain, and the four-fifths ratio moves from 0.43 to 0.59. Still a Fail against 0.80. Referral and dwell are still in the feature set.
- The gate is the EEOC four-fifths rule (29 CFR 1607.4(D)) adapted to price tiers, computed in numpy outside the agent layer. 36% of the protected cohort gets the favorable price tier vs 83% of the advantaged, a ratio of 0.43. Fail. No model decides if 0.43 is under 0.80.
- Every number here comes from one seeded synthetic population of 10,000 pricing decisions with planted proxies. On that labeled set the audit found 3 of 3 planted proxies, 0 false flags, and abstained on the one dual-use input (premium_member), routing it to legal review.
- Pricing-engine owners: does your proxy audit compute mutual information over feature PAIRS, or only per-feature correlation? Many carry cross-terms or trees. Only a pairwise check sees referral x dwell. #AIGovernance #AlgorithmicFairness #DisparateImpact #DynamicPricing
- Equity audits the engine a retailer already runs; it does not set prices or issue a legal verdict. Everything above is a synthetic engine pricing synthetic shoppers. The full breakdown, with remediation and the evidence pack: https://veriprajna.com/demos/ai-pricing-compliance
Published on X · September 12, 2026
On social media
See this post on its original platform
In our archive