Skip to content
AskFlorence
Main Navigation ArchitectureFlorence AIAgentsMembersAgent PlatformValidationInfrastructure

Appearance

Sidebar Navigation

Overview

Home

Glossary

System Architecture

Consumer & Agent Flow

Florence AI

Overview

Principles

Runtime

Tool surface

Adding a tool

Tool registry

Knowledge: SBC scenarios & CSR

Voice

Evals & observability

Provider risk & portability

Outage playbook

Roadmap

Build plan

Agents

Overview

Workflows & pain points

Members

Overview

Medicaid coverage gap

Carriers

Overview

Marketplaces

Overview

Agency

Overview

Regulations

Overview

Agent Platform

Overview

Auth Architecture

MongoDB Permissioning

Compliance Model

Data Models

Data Sources

Overview

CMS Marketplace API

CMS dependency map

PUF Data

State Subsidies

SBE Ingestion Playbook

SBE State Watchouts + Decisions

CA Phase C/D Playbook

NY Phase C/D Playbook

Validation

Overview

Methodology

APTC Formula

California 2026

New York 2026

CAPS Formula

Scenario Results

Infrastructure

Account Inventory

AWS Setup Runbook

AWS Organizations

CloudTrail

GuardDuty

Security Hub

Config

CloudFront + WAFv2

Data sources & ingest

Phase 4 DNS

Change Log

Vulnerability Management

MongoDB Setup

Access Control

Data Classification

Documentation Hosting

Post-deploy Smoke

Development

Preflight (local CI mirror)

Testing strategy

Compliance

Overview (auditor entry point)

SOC 2 Control Mapping

HIPAA Control Mapping

CMS EDE Appendix A Mapping

Risk Assessment

Encryption Policy

Data Retention Policy

Privacy Impact Assessment

Consent Capture & Versioning

Incident Response Plan

Access Control Policy

Marketing vs. Portal Analytics

Vendor / Subprocessor Register

Dependency Vulnerability Policy

BAA / Compliance Evidence

Compliance-Automation Integration

Compliance-Automation Vendor Evaluation

Penetration Test Reports

Architecture

Portal entry handoff

Mobile app strategy

Deferred architecture decisions

Session cookie architecture

Share flows

Decisions (ADRs)

Index

0001 — Atlas project isolation

0002 — Append-only audit log

0003 — Narrow-scoped Mongo users

0004 — Cross-cluster Atlas PrivateLink

0005 — Delayed-job architecture

0006 — Mongo user simplification

0007 — Terraform owns ECS task def

0008 — E2E testing strategy

0009 — Self-hosted analytics + observability (superseded)

0010 — PostHog HIPAA Cloud (supersedes 0009)

Runbooks

Security Incident Response

Break-Glass Root Login

Onboard Team Member

Offboard Team Member

Atlas user provisioning

Deploy via Terraform (ENG-277)

Rollback via Terraform (ENG-277)

S3 data bucket migration (planned Phase 11)

Access Reviews

2026-Q2 Review

Session log

Index

2026-04-23 — Phase 10 DNS cutover

2026-04-22 — Phase 8 prod AWS mirror

2026-04-22 — Phase 7 Atlas VPC peering

2026-04-22 — Phase 6 CloudFront + WAF

2026-04-21 — Phase 5 staging go-live

2026-04-17 — Atlas staging

Briefs

Index

Member portal plan (ENG-187)

2026-04-16/17 handoff

2026-04-17 Atlas handoff

System briefing (2026-04-17)

Creative AdBundance proposal brief

Creative AdBundance analytics brief

ElevenLabs RN integration research

Policies

Overview

On this page

Known Gotchas — Things Learned the Hard Way ​

Non-obvious behaviors of the PUF and CMS API that bit us during validation. Document so future engineers don't repeat the same mistakes.

1. Same plan, different rates per county within the same RA = wrong RA mapping ​

The trap: CMS returned three different rates for the same Ambetter AL plan in counties all labeled "Rating Area 13" in our zip_county. We thought CMS had per-county adjustments and tried to "correct" the rates.

The truth: Per ACA regulations (45 CFR 156.255), plans MUST have one rate per rating area. If CMS shows different rates for the same plan in counties of the same RA, the RA labels are wrong, not the rates. Some counties were misassigned to RA13 when they actually belonged to RA5 or RA7.

Fix: Update zip_county.regionId to the actual RA. Don't touch plan rates.

Lesson: CMS API rates are ground truth for which RA each county belongs to. Match CMS rate → find the matching RA in PUF → that's the correct mapping.

2. PUF rate file (rate-puf.csv) is incomplete ​

The trap: Some plans serve counties (per service-area-puf.csv) but rate-puf.csv has no rate entries for the corresponding rating area.

The truth: The PUF rate file only contains rates for RAs the issuer explicitly filed. CMS supplements with rates from another source. If you reload ageRatesByArea purely from rate-puf.csv, you'll lose RAs.

Fix: Use the per-state PUF JSONs ({state}-2026-puf.json) as the authoritative list of RAs, then enrich with rates from rate-puf.csv for those RAs only. For RAs not in the CSV, CMS gap-fill is required.

3. Iterative rate corrections cause cumulative corruption ​

The trap: Running rate correction scripts multiple times applies ratios on top of previously-corrected rates, doubling the correction.

Example:

  • PUF rate: $605.95
  • Correction script run 1: × 1.0716 → $649.32
  • Correction script run 2: × 1.0308 (because new ratio computed from corrected base) → $669.34

Lesson: Rate corrections must be single-pass from a clean PUF baseline. Always restore to PUF originals before applying corrections. Store correction metadata (_cmsRatio, _originalPufAge21) for auditability.

4. Plan countiesServed derived from rating areas is WRONG ​

The trap: The original ingest derived countiesServed from rating area presence — if a plan had a premium for RA1, it claimed to serve all counties in RA1. This caused massive over-listing.

The truth: The authoritative source is service-area-puf.csv which has explicit county-level data (with FIPS codes). Plans serve specific counties, not whole rating areas.

Fix: Always derive countiesServed from service-area-puf.csv keyed by (IssuerId, ServiceAreaId). Note: ServiceAreaId is NOT globally unique — it's unique per issuer within a state.

5. ServiceAreaId is not globally unique ​

The trap: Two different issuers in the same state can both have a service area called "MIS001". If you build a global lookup keyed by ServiceAreaId, you'll merge their service areas.

Fix: Always key by ${issuerId}:${serviceAreaId}.

6. Partial county coverage ​

The trap: Some plans serve only specific zip codes within a county (e.g., Ambetter MI serves only zips 48827, 49251, 49264 of Ingham County). If you query by county name only, you'll show the plan to users in zips it doesn't actually serve.

Fix: Read PartialCounty='Yes' rows from service-area-puf.csv, capture the ZipCodes list, store as partialCountyZips: { county: [zips] }. Filter at query time:

js
$or: [
  { [`partialCountyZips.${county}`]: { $exists: false } },
  { [`partialCountyZips.${county}`]: userZip },
]

7. CMS API doesn't return APTC plans for Medicaid-eligible income ​

The trap: Querying CMS with income < 138% FPL returns plans WITHOUT APTC discounts, because CMS thinks the user should be on Medicaid. Comparing this to our DB output (which auto-adjusts income) produces false negatives.

Fix: When auditing Medicaid-income scenarios:

  1. Detect Medicaid eligibility (income < 138% FPL)
  2. Apply our auto-adjustment (138.5% FPL + $500)
  3. Query CMS with the adjusted income
  4. Compare against our DB output (which uses the same logic)

8. CMS API has a 200-plan response limit ​

The trap: Querying CMS without a metal level filter for a large county (e.g., Harris TX has 250+ plans across all metals) returns only 200 plans. The cheapest of any metal might be cut off.

Fix: Either (a) query each metal level separately with filter: { metal_levels: ['Silver'] }, or (b) paginate with offset. Per-metal queries are simpler and stay under the limit.

9. CMS zip → county mapping has multi-county zips ​

The trap: Zip code 79118 in TX returns 3 counties from CMS: Randall, Armstrong, Potter. If your zip_county has only one entry per zip, the county picker never fires for these zips and the user is silently routed to whichever county your DB happened to pick.

Fix: Allow multiple zip_county entries per zip. Drop the unique index on zip alone, replace with compound unique on (zip, countyFips). Run a CMS sweep to populate all multi-county mappings (38% of zips span multiple counties).

10. County name conventions differ between CMS and PUF ​

The trap: CMS returns "Saint Clair", PUF lists "St. Clair". Same county, different name. If you key plans by countiesServed: county and the names don't match, plans are invisible.

Known patterns:

CMS namePUF name
Saint XSt. X
Sainte GenevieveSte. Genevieve
LaPazLa Paz
LaSalleLa Salle
LaCrosseLa Crosse
LaMoureLaMoure
LagrangeLaGrange
DesotoDeSoto (or De Soto for LA)
ObrienO'Brien
JuneauJuneau City and (AK borough)
SitkaSitka City and (AK borough)
St. Louis CitySt. Louis city (lowercase city)

Fix: Normalize CMS-sourced names to PUF conventions when ingesting. Build a normalization map.

11. Plan IDs in CMS responses include CSR variant suffixes ​

The trap: Plan IDs in plan-attributes-puf.csv look like 53932AL0100012-00, -01, -02, etc. CMS API returns IDs like 53932AL0100012 (the StandardComponentId). When matching, strip the variant suffix.

Fix: Use the first 14 characters as the canonical plan ID (hiosId.slice(0, 14)).

12. Some issuers use non-standard age curves ​

The trap: ACA standard age curve (45 CFR 147.102) says age 35 should be 1.222× age 21. UT issuers use ratios closer to 1.39 — a state-specific curve allowed by regulation.

Fix: When sanity-checking age curves in Tier 4, allow state-specific curves. UT plans should pass with ratios 1.35-1.45.

13. Atlas backups are raw WiredTiger files ​

The trap: Atlas snapshot downloads aren't BSON — they're raw WiredTiger files. You can't mongorestore them directly to extract a single collection.

Fix: Use the Atlas web console or CLI to do a full cluster restore. To restore a single collection, you need to:

  1. Spin up a temporary cluster
  2. Restore the snapshot there
  3. Use mongoexport to dump the collection
  4. mongoimport into the production cluster

Or just maintain your own pre-write snapshots via atlas backups snapshots create.

Pager
Next pageHome

AskFlorence Internal Documentation. Not for public distribution.

AskFlorence

Internal Documentation

Access restricted. Not for public distribution.