feat(ein): emit additive ein_prefixed + EIN2 columns (ADR 0036)#11
Open
Thiyaghessan wants to merge 1 commit into
Open
feat(ein): emit additive ein_prefixed + EIN2 columns (ADR 0036)#11Thiyaghessan wants to merge 1 commit into
Thiyaghessan wants to merge 1 commit into
Conversation
ADR 0036 (E1, CORE scope) — coercion-safe EIN renderings, purely additive. Emit two new columns on all CORE tiers (processed/core, processed_legacy/core, processed_merged/core) alongside the unchanged canonical dashed `ein`: ein_prefixed = ein-XX-XXXXXXX (lowercase house key, provably text) EIN2 = EIN-XX-XXXXXXX (legacy-compat alias) The canonical `ein` is externally load-bearing and is left untouched; these are extra columns, not a reformat. Both are bijective with `ein` and NA- preserving. N1 (BMF parity): ein_to_prefixed / ein_to_ein2 in R/transforms/ein.R are twins of nccs-data-bmf/R/ein.R — byte-identical casing and prefixing. The upstream canonical `ein` formatter (transform_ein) has drifted from BMF's (empty -> NA here vs "00-0000000" in BMF; CORE rejects >9-digit input); flagged for the N1 consolidation backlog, not changed here. Wiring: - 03_harmonize / 03_legacy_harmonize: add columns last in apply_transforms, after financial coercion, so the char columns are never coerced numeric. - 04_derive_combined: add to COMBINED_UNIVERSAL_COLS so they survive project_to_shared into 990combined. - merged tier: propagate automatically as shared cols (identical both sides; derived from the merge key, so no false disagreements). - 06_dictionary: disambiguating UNIVERSAL_DICTIONARY_ROWS entries (which EIN to join on), per ADR 0036. - quality/post_checks: whitelist the two from check_schema extras. - tests: unit coverage for renderings + project_to_shared propagation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sitrep — ADR 0036
conventions/ein-format.md— theein_prefixedrendering (ein-XX-XXXXXXX), shared with the BMF order; whichever lands first carries it.nccs-contracts/contracts/(core-990,core-legacy,core-panel) — gainein_prefixed+EIN2columns.nccs-contractssession.What this does
Emits two purely additive columns on every CORE tier output (
processed/core,processed_legacy/core,processed_merged/core), alongside the unchanged canonical dashedein:ein_prefixedein-XX-XXXXXXXEIN2EIN-XX-XXXXXXXBoth are bijective with
einand NA-preserving. The canonicaleinis externally load-bearing (five external surfaces per ADR 0036) and is left untouched — this is additive, not a reformat.Implementation
R/transforms/ein.R—ein_to_prefixed()/ein_to_ein2()(twins ofnccs-data-bmf/R/ein.R, byte-identical casing + prefixing) +add_ein_renderings().R/03_harmonize.R/R/03_legacy_harmonize.R— add the columns last inapply_transforms, after the blanket financial coercion, so the character columns are never coerced numeric. Covers990,990ez,990pf(SOI) and990combined,990pf(legacy).R/04_derive_combined.R— added toCOMBINED_UNIVERSAL_COLSso they surviveproject_to_sharedinto the SOI990combined.R/04_legacy_merge.R) — propagate automatically as shared columns; both sides derive them from the merge keyein, so they are always identical → no false disagreement-audit rows. (No code change needed.)R/06_dictionary.R— disambiguatingUNIVERSAL_DICTIONARY_ROWSentries stating which EIN to join on (forward →ein/ein_prefixed; legacy merge →EIN2).R/quality/post_checks.R— whitelist both fromcheck_schemaextras so they aren't flagged as unexpected columns.project_to_sharedpropagation.N1 parity note (backlog, not for this PR)
The two renderings are kept in exact parity with the BMF order. The upstream canonical
einformatter (transform_ein) has already drifted between the repos and I did not reconcile it (per the brief — consolidation is the N1 backlog item, not a unilateral call):NAhere vs"00-0000000"in BMF;NA); BMF keeps it (warns).This affects only edge-case handling of malformed/empty EINs in the base
ein, not the format/casing of the new columns.Tests
Rscript tests/run_all.R→ 257 passed, 2 failed. The 2 failures (expected_col_countfor 990pf 2022 / 990 2024) are pre-existing — they fail identically on a clean checkout ofmain(IRS var-matrix counts, unrelated to this change).🤖 Generated with Claude Code