What's wrong
In src/mrf_honest/inspect_csv.py, a CSV data row that discloses a standard charge but has no complete code|N/code|N|type pairing silently skips the mandatory-description and mandatory-setting checks that would otherwise apply to that same row, because both checks are gated on is_item, which is defined purely by code completeness:
_inspect_data_row (src/mrf_honest/inspect_csv.py:1285): is_item = complete_codes > 0 (line 1314), then _check_item_completeness(row, book, is_item=is_item, ...).
_check_item_completeness (src/mrf_honest/inspect_csv.py:1350): the description-required check (CMS_CSV_DESCRIPTION_MISSING) and the blank-setting check (CMS_CSV_SETTING_INVALID) both live inside if is_item: (line 1359) and return immediately after. The only fallback for a non-item row is elif has_description and not any_charge: (line 1391), which requires nothing when has_description is already False.
Per CMS's CSV data dictionary (corpus/cms/csv-data-dictionary.md), description and setting are both marked "Blanks Accepted: No" in the "Required Standard Charge, Item/Service, and Coding Data Elements" table — i.e. the CSV format does not accept a blank for either whenever a charge/item is disclosed, independent of whether the row's code columns happen to be populated. docs/how-we-grade.md and the finding catalog (CMS_CSV_DESCRIPTION_MISSING, CMS_CSV_SETTING_INVALID) exist specifically to catch this.
Missing codes are separately (and correctly) caught by CMS_CSV_CODE_PAIRING_MISSING (line ~1318-1322), but that finding firing makes is_item False, which then suppresses the two other findings the same row should also carry.
Why it matters
This repo's whole differentiator is that "every number on the site is generated from a committed comparison document" and every finding is deterministic/spec-cited — the published finding_matrix and the per-file finding counts (e.g. the README's "118,411 payer or plan names are encoded with no charge beside them" style numbers) are meant to be a complete, honest count of what's wrong with a file. This gap means any row with more than one defect (missing codes and missing description/setting) has its extra defects silently dropped from the count, understating exactly the kind of thing this project exists to surface. It does not flip a file's letter grade (the row is already flagged via CMS_CSV_CODE_PAIRING_MISSING, so the completeness dimension already has an error), but the evidence — the specific finding codes and occurrence counts a reader is told to trust — is incomplete.
The JSON profile (src/mrf_honest/inspect.py, _inspect_item) does not have this gap: it checks an item's description unconditionally, independent of code_information completeness. This is CSV-profile-specific, consistent with it being the newest, least-scrutinized code path (added 2026-08-19 per the CSV-cohort findings doc).
Confirmed repro
Built a minimal Tall-template CSV (general rows 1-2, header row 3, one data row with a standard_charge|gross of 150.00 and every other cell — including description, setting, and both code|1/code|1|type — blank) and ran it through inspect_hospital_csv_file:
scan_completed: True
CMS_CSV_CODE_PAIRING_MISSING ERROR - A row with a standard charge has no complete code and code-type pairing.
CSV_INTERPRETABILITY_NO_PAYER_RATES WARNING - No payer-specific rate values were observed in the streamed data rows.
completeness dimension status: FINDINGS
No CMS_CSV_DESCRIPTION_MISSING and no setting-blank finding fired, even though both description and setting were blank on a row disclosing a $150 charge.
For comparison, the existing test suite only exercises these checks in isolation — test_a_blank_setting_on_a_charged_item_row_is_a_finding and test_a_charge_without_any_code_pairing_is_incomplete (tests/test_inspect_csv.py) each blank out only one field from TALL_DOLLAR_ROW, which still has a valid code pair or a valid description respectively. Neither test covers the compound case, which is presumably how this went unnoticed.
Suggested fix
Base the description/setting-required checks on whether the row discloses a charge/item at all (e.g. any_charge, already computed in _inspect_data_row) rather than on is_item (code completeness). CMS_CSV_CODE_PAIRING_MISSING can keep firing independently — the two are separate CMS requirements and a row can violate both at once.
What's wrong
In
src/mrf_honest/inspect_csv.py, a CSV data row that discloses a standard charge but has no completecode|N/code|N|typepairing silently skips the mandatory-description and mandatory-setting checks that would otherwise apply to that same row, because both checks are gated onis_item, which is defined purely by code completeness:_inspect_data_row(src/mrf_honest/inspect_csv.py:1285):is_item = complete_codes > 0(line 1314), then_check_item_completeness(row, book, is_item=is_item, ...)._check_item_completeness(src/mrf_honest/inspect_csv.py:1350): the description-required check (CMS_CSV_DESCRIPTION_MISSING) and the blank-setting check (CMS_CSV_SETTING_INVALID) both live insideif is_item:(line 1359) andreturnimmediately after. The only fallback for a non-item row iselif has_description and not any_charge:(line 1391), which requires nothing whenhas_descriptionis alreadyFalse.Per CMS's CSV data dictionary (
corpus/cms/csv-data-dictionary.md),descriptionandsettingare both marked "Blanks Accepted: No" in the "Required Standard Charge, Item/Service, and Coding Data Elements" table — i.e. the CSV format does not accept a blank for either whenever a charge/item is disclosed, independent of whether the row's code columns happen to be populated.docs/how-we-grade.mdand the finding catalog (CMS_CSV_DESCRIPTION_MISSING,CMS_CSV_SETTING_INVALID) exist specifically to catch this.Missing codes are separately (and correctly) caught by
CMS_CSV_CODE_PAIRING_MISSING(line ~1318-1322), but that finding firing makesis_itemFalse, which then suppresses the two other findings the same row should also carry.Why it matters
This repo's whole differentiator is that "every number on the site is generated from a committed comparison document" and every finding is deterministic/spec-cited — the published finding_matrix and the per-file finding counts (e.g. the README's "118,411 payer or plan names are encoded with no charge beside them" style numbers) are meant to be a complete, honest count of what's wrong with a file. This gap means any row with more than one defect (missing codes and missing description/setting) has its extra defects silently dropped from the count, understating exactly the kind of thing this project exists to surface. It does not flip a file's letter grade (the row is already flagged via
CMS_CSV_CODE_PAIRING_MISSING, so thecompletenessdimension already has an error), but the evidence — the specific finding codes and occurrence counts a reader is told to trust — is incomplete.The JSON profile (
src/mrf_honest/inspect.py,_inspect_item) does not have this gap: it checks an item'sdescriptionunconditionally, independent ofcode_informationcompleteness. This is CSV-profile-specific, consistent with it being the newest, least-scrutinized code path (added 2026-08-19 per the CSV-cohort findings doc).Confirmed repro
Built a minimal Tall-template CSV (general rows 1-2, header row 3, one data row with a
standard_charge|grossof150.00and every other cell — includingdescription,setting, and bothcode|1/code|1|type— blank) and ran it throughinspect_hospital_csv_file:No
CMS_CSV_DESCRIPTION_MISSINGand no setting-blank finding fired, even though bothdescriptionandsettingwere blank on a row disclosing a $150 charge.For comparison, the existing test suite only exercises these checks in isolation —
test_a_blank_setting_on_a_charged_item_row_is_a_findingandtest_a_charge_without_any_code_pairing_is_incomplete(tests/test_inspect_csv.py) each blank out only one field fromTALL_DOLLAR_ROW, which still has a valid code pair or a valid description respectively. Neither test covers the compound case, which is presumably how this went unnoticed.Suggested fix
Base the description/setting-required checks on whether the row discloses a charge/item at all (e.g.
any_charge, already computed in_inspect_data_row) rather than onis_item(code completeness).CMS_CSV_CODE_PAIRING_MISSINGcan keep firing independently — the two are separate CMS requirements and a row can violate both at once.