HMIS data quality report

Reporting period 2025-10-01 to 2026-09-30. Generated by the toolkit's run_checks.py.

Demonstration. Every person, project and record in this report is synthetic, generated by generate_synthetic.py with known problems planted at fixed rates. No client data was used. The files follow a subset of the HUD HMIS CSV export columns (Project, Client, Enrollment, Exit), so the same checks run against a real export.

Summary

Active enrollmentsActive clientsEnrollments with no findingLoad timeCheck run timeDatabase integrityBackup restore test
913592553 (60.6%) 20 ms30 msokpass

Findings by check

CheckAreaWhat it findsFlaggedRecords checkedRate
DQ01IdentifiersName missing, unknown or refused179131.9%
DQ02IdentifiersSSN missing or not a valid SSN689137.4%
DQ03IdentifiersDate of birth missing or impossible149131.5%
DQ04Universal data elementsVeteran status missing for adults137091.8%
DQ05Universal data elementsDisabling condition missing219132.3%
DQ06Universal data elementsHousehold without exactly one head of household137261.8%
DQ07Universal data elementsPrior living situation missing257303.4%
DQ08ExitsExit destination missing6565110.0%
DQ09ExitsExit date before entry date26510.3%
DQ10TimelinessEntry recorded late9478911.9%
DQ11TimelinessExit recorded late576518.8%
DQ12ConsistencyOverlapping residential stays103822.6%
DQ13ConsistencyPossible duplicate client records127121.7%
DQ14TimelinessShelter or outreach enrollment open over 90 days318636.0%

Error rate by project

Each cell is the share of that project's checked records flagged, with the count beneath. Agencies get their own column as a monthly scorecard.

CheckDemo Emergency Shelter (entry/exit)
ES entry/exit
Demo Night-by-Night Shelter
ES night-by-night
Demo Street Outreach
Street outreach
Demo Transitional Housing
TH
Demo Permanent Supportive Housing
PH-PSH
Demo Rapid Re-Housing
PH-RRH
DQ01 Name missing, unknown or refused2.3%
7 of 298
1.0%
1 of 98
2.0%
3 of 150
2.4%
2 of 84
0.0%
0 of 119
2.4%
4 of 164
DQ02 SSN missing or not a valid SSN6.4%
19 of 298
7.1%
7 of 98
8.7%
13 of 150
7.1%
6 of 84
10.9%
13 of 119
6.1%
10 of 164
DQ03 Date of birth missing or impossible1.7%
5 of 298
1.0%
1 of 98
2.0%
3 of 150
1.2%
1 of 84
1.7%
2 of 119
1.2%
2 of 164
DQ04 Veteran status missing for adults1.9%
4 of 206
3.1%
3 of 96
2.0%
3 of 147
0.0%
0 of 61
1.2%
1 of 82
1.7%
2 of 117
DQ05 Disabling condition missing2.3%
7 of 298
3.1%
3 of 98
2.7%
4 of 150
1.2%
1 of 84
2.5%
3 of 119
1.8%
3 of 164
DQ06 Household without exactly one head of household1.9%
4 of 211
3.1%
3 of 98
1.3%
2 of 150
1.6%
1 of 62
1.2%
1 of 85
1.7%
2 of 120
DQ07 Prior living situation missing3.8%
8 of 213
4.1%
4 of 98
4.0%
6 of 150
1.6%
1 of 62
4.7%
4 of 86
1.7%
2 of 121
DQ08 Exit destination missing3.7%
9 of 244
16.3%
16 of 98
29.7%
35 of 118
0.0%
0 of 50
0.0%
0 of 40
5.0%
5 of 101
DQ09 Exit date before entry date0.0%
0 of 244
1.0%
1 of 98
0.8%
1 of 118
0.0%
0 of 50
0.0%
0 of 40
0.0%
0 of 101
DQ10 Entry recorded late12.7%
34 of 268
7.2%
7 of 97
15.5%
20 of 129
8.1%
6 of 74
8.2%
7 of 85
14.7%
20 of 136
DQ11 Exit recorded late9.0%
22 of 244
7.1%
7 of 98
9.3%
11 of 118
12.0%
6 of 50
12.5%
5 of 40
5.9%
6 of 101
DQ12 Overlapping residential stays2.7%
8 of 298
n/a
0 of 0
n/a
0 of 0
2.4%
2 of 84
n/a
0 of 0
n/a
0 of 0
DQ14 Shelter or outreach enrollment open over 90 days25.9%
14 of 54
n/a
0 of 0
53.1%
17 of 32
n/a
0 of 0
n/a
0 of 0
n/a
0 of 0

Rules

CheckRule
DQ01Name data quality is 8, 9 or 99, or first or last name is blank.
DQ02SSN data quality is 8, 9 or 99, or a "full SSN" fails format rules (000/666/9xx area, 00 group, 0000 serial, repeated or sequential digits).
DQ03DOB quality is 8, 9 or 99, DOB is blank, DOB falls after the entry date, or age at entry is over 105.
DQ04Client is 18 or older at entry and veteran status is 8, 9, 99 or blank.
DQ05Disabling condition is 8, 9, 99 or blank.
DQ06A household's active enrollments contain zero or more than one RelationshipToHoH = 1.
DQ07For heads of household and adults, prior living situation is 8, 9, 99 or blank.
DQ08An exit in the period has destination 8, 9, 99, 30 or blank.
DQ09The exit date is earlier than the enrollment's entry date.
DQ10The enrollment was created more than 4 business days after the entry date (weekends and listed holidays excluded).
DQ11The exit was created more than 4 business days after the exit date.
DQ12The same person has two emergency shelter (entry/exit), transitional housing or safe haven stays whose dates overlap.
DQ13Two PersonalIDs share a valid full SSN, or share DOB, last name and the first three letters of first name.
DQ14An emergency shelter (entry/exit) or street outreach enrollment has no exit and started more than 90 days before period end; review for a missed exit.

Missing-value codes: 8 = client doesn't know, 9 = client prefers not to answer, 99 = data not collected; 30 = no exit interview completed. Business days exclude weekends and the dates in holidays.csv.

Example flagged records

Two per check. The full list is in flagged_records.csv, one row per record, ready to split by agency.

CheckProjectRecordDetail
DQ01101E000062PersonalID C00622, name quality 99
DQ01101E000305PersonalID C00092, name quality 9
DQ02101E000031PersonalID C00198, SSN quality 8
DQ02101E000041PersonalID C00513, SSN quality 8
DQ03101E000527PersonalID C00089, DOB missing
DQ03101E000653PersonalID C00295, DOB missing
DQ04101E000318PersonalID C00658, veteran status 8
DQ04101E000776PersonalID C00371, veteran status 9
DQ05101E000077disabling condition 8
DQ05101E000114disabling condition 9
DQ06101H000820 heads of household among 1 members
DQ06101H002590 heads of household among 1 members
DQ07101E000041prior living situation 9
DQ07101E000081prior living situation 9
DQ08101E000044exit 2025-11-03, destination 99
DQ08101E000479exit 2026-04-26, destination 99
DQ09102E000184entry 2026-09-22, exit 2026-09-16
DQ09201E000613entry 2026-04-17, exit 2026-04-06
DQ10101E000018entry 2026-06-16, created 2026-07-15, 19 business days
DQ10101E000062entry 2026-07-21, created 2026-08-25, 25 business days
DQ11101E000044exit 2025-11-03, created 2025-12-08, 23 business days
DQ11101E000077exit 2026-09-27, created 2026-10-08, 9 business days
DQ12101E000144/E001034PersonalID C00559: 2025-12-07 to 2025-12-18 overlaps 2025-12-08 to open
DQ12101E000234/E001038PersonalID C00057: 2026-09-02 to open overlaps 2026-09-07 to open
DQ13C00009/C00708same DOB, last name and first-name start
DQ13C00236/C00712same SSN
DQ14101E000027entry 2026-03-23, open 191 days
DQ14101E000060entry 2026-05-31, open 122 days

Database administration checks

Read-only export snapshot. An attempted edit to a loaded client record: blocked as designed: export snapshot is read-only; correct the record in the HMIS.

Follow-up log. Changing a finding's status from open to "sent to agency" to "corrected in HMIS" wrote 2 history rows through the status trigger.

Backup and restore. The database was copied with SQLite's online backup API to hmis_reporting_2026-09-30.sqlite; the copy passed PRAGMA integrity_check (ok) and every table's row count and content hash matched the live database:

TableRowsRestore comparison
project6match
client712match
enrollment1038match
exit776match
dq_finding442match
holiday12match

Index use. Query plans for the two self-join checks:

DQ12: SCAN e; SEARCH p USING INDEX sqlite_autoindex_project_1 (ProjectID=?); SEARCH c USING COVERING INDEX sqlite_autoindex_client_1 (PersonalID=?); SEARCH x USING INDEX sqlite_autoindex_exit_2 (EnrollmentID=?) LEFT-JOIN; SEARCH c USING COVERING INDEX sqlite_autoindex_client_1 (PersonalID=?); SEARCH e USING INDEX ix_enrollment_person (PersonalID=? AND EntryDate<?); SEARCH p USING INDEX sqlite_autoindex_project_1 (ProjectID=?); SEARCH x USING INDEX sqlite_autoindex_exit_2 (EnrollmentID=?) LEFT-JOIN

DQ13: SCAN b; MULTI-INDEX OR; INDEX 1; SEARCH a USING INDEX ix_client_ssn (SSN=?); INDEX 2; SEARCH a USING INDEX ix_client_dob_name (DOB=?)

Load checks. Foreign key errors after load: 0. Source file SHA-256 hashes are stored with the load record.