# `site/data/roof/` — the roof vertical data layer

Versioned JSON data files the roof calculator engine will read. Structure mirrors the glass data layer (`site/data/carrier-rate-tiers.json`): every entry carries `sourceType`, `sourceCitation`, `sourceUrl`, `verifiedOn`, `reviewOn`, and per-state/per-carrier entries are stored as **reverse-chronological arrays** so that a schedule change preserves the earlier version (index 0 is current; older entries stay in place so historical verdicts remain auditable).

## Files

| File | What it holds | Feeds |
|---|---|---|
| [`percentage-deductibles.json`](./percentage-deductibles.json) | Typical wind/hail % deductible structures, computed off Coverage A. State and carrier norms where documented. | The REAL-deductible interactive and the roof-calc engine's deductible calc. |
| [`payment-schedules.json`](./payment-schedules.json) | Roof payment schedules by age (RCV 0-10, prorated 10+, ACV 15+). Industry pattern + per-carrier extraction slots. | The roof-calc engine's covered-payout adjustment, applied *before* the deductible. |
| [`state-surcharge-rules.json`](./state-surcharge-rules.json) | Per-state surcharge / inquiry-prohibition rules ("asking is not filing"). TX flagship; NY, CA, FL seeded pending verification. | The state-law hub (`/homeowners-roof-insurance-laws/`) and the roof-calc verdict overrides. |
| [`non-renewal-risk.json`](./non-renewal-risk.json) | Regional (NAIC) and ZIP-level (Treasury FIO) non-renewal risk bands. | The non-renewal risk flag layered on every roof verdict. |

## The verification discipline

Every entry is either **verified** (has a `verifiedOn` date and a `sourceCitation` that points at a primary source we've actually read) or explicitly **unverified** (`"unverified": true` with a `null` citation and an `unverifiedNote` describing what would sharpen it). We do not invent numbers to fill fields, and we do not surface unverified entries to users as authoritative rule copy.

The convention is deliberately identical to how the glass carrier-rate-tiers.json handles pending SERFF filings — an unverified row falls back to a safer default in the engine and prints its unverified status wherever it would be cited.

Primary sources the roof files rely on:

- **Statutes**: state legislature or official state code (e.g., `statutes.capitol.texas.gov`, `nysenate.gov/legislation`).
- **State DOI bulletins and form filings**: state insurance department consumer pages and SERFF form-filing databases.
- **Carrier policy forms**: filed with state DOIs and pulled from SERFF or carrier consumer disclosure pages, not from aggregators.
- **NAIC market conduct data**: as compiled in the US Senate Budget Committee report *Next to Fall: The Climate-Driven Insurance Crisis Is Here* (December 2024).
- **US Treasury Federal Insurance Office**: *Analyses of U.S. Homeowners Insurance Markets, 2018-2022* (January 2025).
- **LexisNexis Consumer Center** and FCRA `15 U.S.C. §1681j`: for CLUE mechanics on the shared explainer at `/clue-report/`.

## Refresh cadence

- Verified state statute entries: **re-verify every 6 months** (roughly February and August). Legislatures move; a statute cited in September may have been amended by the next session.
- Carrier policy-form entries: **re-verify every 12 months**, sooner if a state DOI publishes an amendment bulletin.
- NAIC and Treasury aggregate figures: **re-verify annually** and whenever a new NAIC data call or FIO update publishes.
- Every unverified entry: **should not remain unverified past its `reviewOn` date without an owner note explaining why.**

## Adding a new entry

1. Read the primary source in full. If you can't cite a statute section number, a bulletin number, or a filed form number, do not add the entry.
2. Push the new entry to the **front** of the reverse-chron array (for a state or carrier), preserving earlier entries.
3. Set `verifiedOn` to today, `reviewOn` to a date matching the refresh cadence above.
4. If it's an update to an existing engine behavior (verdict copy, band cutoffs, or schedule shape), note the shift in `CONTEXT.md` alongside the code change, matching the glass-side discipline.

## How the engine loads these

The engine (built in prompt 5) will `fetch` each file over the wire, matching how `site/assets/app.js` loads `/data/carrier-rate-tiers.json` today. Each file has a top-level `schemaVersion`; the engine verifies the version before merging and falls back to an inline safe-default table if the file 404s or times out — so a missing or malformed data file must never crash the calculator, only degrade its precision.

The `engineHint` block inside each file names the order and rule the engine should apply. Two are load-bearing and worth repeating:

- **`payment-schedules.json`**: apply the age-banded schedule to the covered payout **before** subtracting the deductible. Reversing that order produces the wrong answer.
- **`non-renewal-risk.json`**: the risk band lives on the verdict card as a flag, **not** inside the dollar arithmetic. It never softens the green don't-file verdict.

## What is intentionally missing from the seed

Prompt 4 (this file set) seeds structure and a small verified core. What still needs to be added, in rough order of value:

1. **Per-carrier roof payment schedules** extracted from filed policy forms for the top 8 to 10 homeowners writers.
2. **Full 50-state surcharge / inquiry rule table** with primary citations, mirroring the glass state-law discipline.
3. **Per-region NAIC non-renewal rise percentages** extracted from the Senate Budget Committee source table.
4. **ZIP-level FIO bands** from the January 2025 FIO underlying data.
5. **Carrier percentage-deductible offerings** where they materially differ from state norms.

Each of these is data assembly, not engine work.
