Nothing was built in year 0 - #27
Merged
Merged
Conversation
This was referenced Aug 28, 2026
ChelseaKR
changed the base branch from
fix/notes-that-claim-a-denominator
to
main
August 29, 2026 00:15
ChelseaKR
force-pushed
the
fix/yearbuilt-zero-is-not-a-year
branch
from
August 29, 2026 00:29
010ff7a to
3b8c801
Compare
YEARBUILT counted the literal 0 as a recorded construction year. 12,148 of the
132,522 DINS records hold it, 9.2% of the file and 11.9% of everything that
field counted as present, and every one sat inside its 77.0% recorded share.
No structure standing in a California wildfire was built in year 0, so this
published an absence as a value.
0 is now a declared unknown marker on Basis.INFERRED. The field publishes
89,943 recorded values (67.9%) and 12,148 recorded-as-unknown. The 30,431 empty
cells do not move.
The evidence is in docs/MARKERS.md section 7 rather than here. Read off the
acquired file: the zeros are in 186 incidents, 45 counties and eight fire years;
199 of 436 incident groups hold at least one and 55 hold nothing else, the
largest being 446 of 446 records on Valley 2020; 11,779 of the 12,148 carry an
APN, so the parcel join found a parcel and the parcel had no year rather than
the join failing; and 5,527 of them (45.5%) also carry an assessed improved
value of 0, against 391 of the 89,943 records holding a real year (0.4%).
Section 7 also covers the other five numeric fields that publish recorded
zeros, including the two considered and left alone. NOOUTBUILDINGSDAMAGED,
NOOUTBUILDINGSNOTDAMAGED and NOOFCARSONPROPERTY are inspector counts where a
zero is the measurement. NUMBEROFUNITPERSTRUCTURE (58,411 zeros) and
ASSESSEDIMPROVEDVALUE (6,613) each have a reading in which the zero is real and
the file does not settle it, so neither is declared and both carry the numbers a
later reader would need to decide otherwise.
The audit gate could not have caught this. docs/MARKERS.md covers fields that
declare a vocabulary, and a numeric field deciding its zeros are values declares
nothing at all, so YEARBUILT was outside the audit by construction and the gate
reading the audit was green over a set that excluded the one field that needed
reviewing. tests/test_schema.py now fails when a numeric field publishes
recorded zeros that docs/MARKERS.md does not cover.
Measured on this tree. Against the pre-change audit the new gate fails with
[('NUMBEROFUNITPERSTRUCTURE', 58411), ('NOOUTBUILDINGSDAMAGED', 59628),
('NOOUTBUILDINGSNOTDAMAGED', 58888), ('NOOFCARSONPROPERTY', 55831),
('YEARBUILT', 12148), ('ASSESSEDIMPROVEDVALUE', 6613)] and the perimeters
artifact passes, since GIS_ACRES publishes no zeros. After section 7 it passes,
and it is separately run against a payload the audit does not cover and against
a field with no zeros to explain.
Declaring the marker without rebuilding site/ was caught by the note-drift gate
added in the previous commit, which named YEARBUILT. site/ is rebuilt from
data/raw/; the published counts move exactly where predicted.
Twenty-eight of the fifty-four measured fields now declare a vocabulary, twelve
published and sixteen inferred. README.md, docs/MARKERS.md, schema.py, render.py
and the published pages all say so, and tests/test_schema.py holds them to it.
make verify exits 0: 581 tests, 100% branch coverage, determinism byte-identical.
Closes #24. See ADR-0006.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The rebase conflict in site/dins.html was resolved by taking one side, which is not a resolution for a generated file. This is make site's output from data/raw/, so the committed HTML now matches its source rather than a merge of two independently generated copies.
ChelseaKR
force-pushed
the
fix/yearbuilt-zero-is-not-a-year
branch
from
August 29, 2026 16:43
3b8c801 to
4dea7d1
Compare
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.
Closes #24. Adds ADR-0006. Stacked on #26; base is
fix/notes-that-claim-a-denominator.What was wrong
YEARBUILTcounted the literal0as a recorded construction year. 12,148 of the 132,522 DINS records hold it, 9.2% of the file and 11.9% of everything that field counted as present, and every one sat inside its 77.0% recorded share. No structure standing in a California wildfire was built in year 0, so this published an absence as a value.0is now a declared unknown marker onBasis.INFERRED:Why the audit could not have caught it
docs/MARKERS.mdcovers every field that declares a vocabulary, andtests/test_schema.pyenforces that. A numeric field deciding that its zeros are measurements declares nothing at all: no markers, no codes, no domain.YEARBUILTwas outside the audit by construction, and the gate reading the audit was green the whole time over a set that excluded exactly the field that needed reviewing.tests/test_schema.pynow fails when a numeric field publishes recorded zeros thatdocs/MARKERS.mddoes not cover.The evidence
docs/MARKERS.mdsection 7, read off the acquired file indata/raw/(hashes inPROVENANCE.md):000Not one bad load: 186 incidents across eight fire years, scattered inside incidents as often as it takes a whole one. And it travels with the other parcel number being zero at a hundred times the rate a real year does, which is what a parcel record with nothing on file looks like. The APN is present on 97% of them, so the join found a parcel and the parcel had no year.
Confidence is high that a
0is not a construction year and moderate on what kind of absence it stands for, which is what the audit row says.Eight other records hold years that are also implausible (four
1, three89, one1543). Left as recorded values on the same reasoning asFIRE_NUM's bare0in section 5: eight cells is a scatter of typos, not a convention.The other five numeric fields
Section 7 covers all of them, including the two considered and left alone:
NOOUTBUILDINGSDAMAGEDNOOUTBUILDINGSNOTDAMAGEDNOOFCARSONPROPERTYNUMBEROFUNITPERSTRUCTUREASSESSEDIMPROVEDVALUEYEARBUILT0, inferredNUMBEROFUNITPERSTRUCTURE's zeros land on 39,438 single residences and 15,946 minor structures while its positives concentrate on multiple residences (1,443 of 2,007). A zero on a utility structure is a coherent observation; a zero on a single residence is not obviously one. The file does not settle it, so nothing is declared and the count stays published.ASSESSEDIMPROVEDVALUE's zeros travel withYEARBUILT's at a hundredfold, but a parcel assessed at zero improved value is inside the field's own range, and the zeros spread across 126 incidents and every damage band. Not declared, and flagged in the audit as the entry to revisit first.Proof each new check can fail
Measured on this tree. Against the pre-change audit:
It is separately run against a payload no audit covers (
test_the_zero_gate_rejects_a_numeric_field_nobody_reviewed) and against a numeric field with no zeros to explain (test_the_zero_gate_says_nothing_about_a_field_with_no_zeros_to_explain).Positive controls, passing identically before and after:
test_every_published_zero_in_a_numeric_field_is_written_up[perimeters-coverage.json](green in both states, becauseGIS_ACRESpublishes no zeros, so the gate is not just failing on everything) andtest_a_recorded_zero_is_counted_as_a_value_and_as_a_zero, which is the policy forNOOUTBUILDINGSDAMAGEDand is deliberately unchanged.The gate stacked underneath this one also earned its keep: declaring the marker without rebuilding
site/failedtest_the_published_note_is_the_note_the_registry_holds[dins-coverage.json], namingYEARBUILT.Gate output
Exit code read from
$?.Counts that moved with it
Twenty-eight of the fifty-four measured fields now declare a vocabulary, twelve published and sixteen inferred.
README.md,docs/MARKERS.md,schema.py,render.pyand the published pages all say so, andtests/test_schema.pyholds them to it.site/is rebuilt from the acquired files.🤖 Generated with Claude Code