Staging logged Unknown GIAS code 99 (not in dictionary). Root cause: GIAS carries codes whose (name) column is blank — ReligiousCharacter 99 (3,975 schools), AdmissionsPolicy 9 (5,643), OfficialSixthForm 9 (9) — and the dictionary generator skipped blank-name pairs, so those codes fell into the Unknown (<code>) path. Regression: religious_denomination: "Unknown (99)" wrongly triggers the Faith-priority tag heuristic on ~4k schools and pollutes filter lists (old pipeline served an empty string for these).
Fix (TDD): the generator now maps blank-only codes to "" — byte-identical to the old name pipeline and falsy for UI heuristics — keeping Unknown (<code>) for genuinely new codes. Dictionaries + seed regenerated from today's live CSV; accepted_values lists extended (99 / 9). Sixth-form mart logic unchanged (code 9 already fell through to the statutory-age fallback, matching old blank behaviour). 21/21 backend tests.
Staging logged `Unknown GIAS code 99 (not in dictionary)`. Root cause: GIAS carries codes whose `(name)` column is blank — ReligiousCharacter 99 (3,975 schools), AdmissionsPolicy 9 (5,643), OfficialSixthForm 9 (9) — and the dictionary generator skipped blank-name pairs, so those codes fell into the `Unknown (<code>)` path. Regression: `religious_denomination: "Unknown (99)"` wrongly triggers the Faith-priority tag heuristic on ~4k schools and pollutes filter lists (old pipeline served an empty string for these).
Fix (TDD): the generator now maps blank-only codes to `""` — byte-identical to the old name pipeline and falsy for UI heuristics — keeping `Unknown (<code>)` for genuinely new codes. Dictionaries + seed regenerated from today's live CSV; `accepted_values` lists extended (99 / 9). Sixth-form mart logic unchanged (code 9 already fell through to the statutory-age fallback, matching old blank behaviour). 21/21 backend tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
ReligiousCharacter 99 (~4k schools) and AdmissionsPolicy 9 (~5.6k) carry a
code with a blank name in the GIAS CSV; the generator skipped them so they
hit the Unknown(<code>) path — wrongly triggering the Faith-priority tag
and polluting filters. Blank-only codes now map to "" (byte-identical to
the old name pipeline); accepted_values lists extended to match the seed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This PR fixes a regression where GIAS 'not recorded' sentinel codes (OfficialSixthForm 9, ReligiousCharacter 99, AdmissionsPolicy 9) were falling through to the 'Unknown ()' path instead of the blank string the old name-based pipeline produced. The generator script, both dictionary copies (kept byte-identical, enforced by an existing test), the dbt seed CSV, and the accepted_values tests are all updated consistently, and a new regression test locks in the blank-string behavior. The change is well-scoped and internally consistent; I found no correctness, security, or deploy/CI issues.
🟡 Minor
backend/tests/test_gias_codes.py: test_blank_name_sentinel_codes_map_to_empty_string only asserts the ReligiousCharacter(99) and AdmissionsPolicy(9) sentinels; it doesn't assert OFFICIAL_SIXTH_FORM[9] == "" even though that dictionary/seed also gained a blank-name code 9 in this diff, leaving that sentinel's regression-proofing weaker than the other two.
## 🤖 AI Code Review (Claude Code)
This PR fixes a regression where GIAS 'not recorded' sentinel codes (OfficialSixthForm 9, ReligiousCharacter 99, AdmissionsPolicy 9) were falling through to the 'Unknown (<code>)' path instead of the blank string the old name-based pipeline produced. The generator script, both dictionary copies (kept byte-identical, enforced by an existing test), the dbt seed CSV, and the accepted_values tests are all updated consistently, and a new regression test locks in the blank-string behavior. The change is well-scoped and internally consistent; I found no correctness, security, or deploy/CI issues.
### 🟡 Minor
- **backend/tests/test_gias_codes.py**: test_blank_name_sentinel_codes_map_to_empty_string only asserts the ReligiousCharacter(99) and AdmissionsPolicy(9) sentinels; it doesn't assert OFFICIAL_SIXTH_FORM[9] == "" even though that dictionary/seed also gained a blank-name code 9 in this diff, leaving that sentinel's regression-proofing weaker than the other two.
tudor
merged commit 58e90fef61 into main2026-07-09 21:21:08 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Staging logged
Unknown GIAS code 99 (not in dictionary). Root cause: GIAS carries codes whose(name)column is blank — ReligiousCharacter 99 (3,975 schools), AdmissionsPolicy 9 (5,643), OfficialSixthForm 9 (9) — and the dictionary generator skipped blank-name pairs, so those codes fell into theUnknown (<code>)path. Regression:religious_denomination: "Unknown (99)"wrongly triggers the Faith-priority tag heuristic on ~4k schools and pollutes filter lists (old pipeline served an empty string for these).Fix (TDD): the generator now maps blank-only codes to
""— byte-identical to the old name pipeline and falsy for UI heuristics — keepingUnknown (<code>)for genuinely new codes. Dictionaries + seed regenerated from today's live CSV;accepted_valueslists extended (99 / 9). Sixth-form mart logic unchanged (code 9 already fell through to the statutory-age fallback, matching old blank behaviour). 21/21 backend tests.🤖 Generated with Claude Code
🤖 AI Code Review (Claude Code)
This PR fixes a regression where GIAS 'not recorded' sentinel codes (OfficialSixthForm 9, ReligiousCharacter 99, AdmissionsPolicy 9) were falling through to the 'Unknown (
)' path instead of the blank string the old name-based pipeline produced. The generator script, both dictionary copies (kept byte-identical, enforced by an existing test), the dbt seed CSV, and the accepted_values tests are all updated consistently, and a new regression test locks in the blank-string behavior. The change is well-scoped and internally consistent; I found no correctness, security, or deploy/CI issues.🟡 Minor