# Red Light Index — data dictionary

Snapshot date: 2026-09-06. Encoding: UTF-8. CSV line endings: LF. Empty strings mean
“not stated or not found”; they never mean zero. Canonical rows are sorted by their stable ID.

## Shared conventions

- `device_id` is `rli-dev:{brand-slug}:{model-slug}`.
- `claim_id` is `rli:{device}:{claim-type}:{source-token}:r{revision}`.
- `source_archive_url` is a Wayback save URL. `archive_status=pending` means the save response was not confirmed.
- Numeric fields use a dot decimal separator and no thousands separator.
- `mW` is total optical power while `mW/cm2` is irradiance; the units are never substituted.
- Dates use ISO `YYYY-MM-DD`.
- `accuracy_class`: `C0` unqualified because distance is absent, `C1` declared with distance, `C1a` means “C1 with assumed area” for a derived mask M1 only, `C2` declared with an instrument, `L` signed-report lineage, `I` attributed third-party measurement, `M` protocol-measured. An unstated statistic does not demote a distance-qualified declaration; derived M1 marks it with `statistic_unstated=true`. Wave A contains no `M` rows.
- `distance_bucket`: `contact`, `le8_cm`, `8_20_cm`, `gt20_cm`, or `not_stated`.
- `comparability_key` is `{distance_bucket}|{statistic}|{band}`. A ratio additionally requires distances within 10% and the same explicit geometry.

## Tables

### `devices.csv`

One row per retail model or explicitly separated report prototype. `source_row` is the
1-based row in the 67-row seed. `import_status` separates those 67 rows from supplemental
reconciliation devices. `aliases` preserves known naming variants without merging records.

Fields: `device_id`, `device_class`, `brand`, `model`, `slug`, `aliases`, `source_row`,
`import_status`, `demand_query`, `search_volume_us`, `has_page`, `notes`. `has_page=true`
exactly when the DataForSEO US brand+model search volume is at least 50.

### `claims.csv`

One atomic numeric or categorical statement per row. `value_num` is used only for numbers;
`value_text` retains categorical content or an area basis. `quoted_text` is a short source
fragment and `is_quote=true` marks its special lexical treatment. Irradiance claims without
distance or statistic are `C0` and carry `suppression_reason`.

Fields: `claim_id`, `device_id`, `claim_type`, `value_num`, `value_text`, `unit`,
`distance_cm`, `distance_status`, `distance_bucket`, `statistic`, `band`, `instrument_type`,
`geometry`, `source_url`, `source_archive_url`, `retrieved_at`, `accuracy_class`,
`comparability_key`, `quoted_text`, `is_quote`, `suppression_reason`, `supersedes_claim_id`.

### `prices.csv`

Append-only observations. A later observation receives a new `price_id`; it does not overwrite
an older row. `price_type=quote` suppresses price-based indices.

Fields: `price_id`, `device_id`, `price_usd`, `price_type`, `currency`, `observed_at`,
`source_url`, `source_archive_url`, `availability`, `notes`.

### `reports_and_measurements.csv`

Attribution and method details for every `L`, `I`, or future `M` claim. Total radiant flux in
watts and irradiance in `mW/cm2` are distinct measurands. A sphere total is never entered as
irradiance. `signed_report=false` is retained when the public source is an issuer summary and
the underlying signed PDF is available only on request.

Fields: `measurement_id`, `device_id`, `claim_id`, `provenance_class`, `measured_by`,
`report_number`, `report_date`, `signed_report`, `instrument_type`, `geometry`, `statistic`,
`band`, `value`, `unit`, `distance_cm`, `distance_bucket`, `source_url`,
`source_archive_url`, `retrieved_at`, `notes`.

### `fda_lineage.csv`

Retail-to-510(k) review. `match_confidence` is `direct`, `probable`, `ambiguous`, or
`no_match`. A `no_match` row states the search terms and date and does not assert a regulatory
conclusion. `mismatch_fields` is a semicolon list among `brand`, `trade_name`, `model`,
`sku_family`, `led_count`, and `wavelengths`.

Fields: `lineage_id`, `device_id`, `retail_sku`, `retail_model`, `applicant`, `k_number`,
`decision_date`, `summary_leds`, `summary_wavelengths_nm`, `retail_leds`,
`retail_wavelengths_nm`, `mismatch_fields`, `match_confidence`, `search_date`, `source_url`,
`source_archive_url`, `gudid_url`, `udi_di`, `retail_source_url`, `notes`.

### `sources.csv`

Deduplicated source register. `source_type` distinguishes vendor pages, FDA summaries,
measurement reports, reviewer measurements, program terms, and dated search records.

Fields: `source_id`, `source_url`, `source_archive_url`, `archive_status`, `source_type`,
`publisher`, `title`, `published_at`, `retrieved_at`, `notes`.

### `protocols.csv`

Version register for the measurement protocol. The public URL is relative because this task
does not build or publish the site.

Fields: `protocol_id`, `version`, `title`, `status`, `effective_date`, `protocol_url`,
`source_document`, `distance_buckets`, `formula_version`, `changelog_url`, `notes`.

### `affiliations.csv`

One documented program per brand. `rate_qualifier` preserves “up to”, range, and default-rate
semantics. A blank `cookie_days` means the public terms used here did not state it.

Fields: `affiliation_id`, `brand`, `device_classes`, `program_status`, `rate_pct`,
`rate_qualifier`, `network`, `cookie_days`, `terms_url`, `retrieved_at`, `disclosure_text`,
`notes`.

### `build/derived_metrics.csv`

Every row has stable inputs and a formula version. `input_claim_ids` is a JSON array.
`source_hash` hashes the canonical input rows. A suppressed result has blank values and an
explicit `suppression_reason`.

Metric definitions:

- M1: `irradiance × area / price × 100`; every C1/C2 irradiance with a stated distance is eligible, including rows with an unstated statistic. A mask without a factual area uses `area_basis=assumed_face_300` (300 cm2), `area_assumed=true`, and class C1a (“C1 with assumed area”). `statistic_unstated=true` preserves the vendor omission. Default hub order is M2, never M1.
- M2: count of disclosed value, distance, statistic, band, and instrument (0–5). `TNI` means solar-meter and spectroradiometer numbers coexist.
- M3: `(declared − measured) / declared × 100`; only same distance bucket, distance within 10%, statistic, band, and geometry.
- M4: lineage confidence copied from the reviewed SKU row.
- M5: `mW/cm2 × seconds / 1000 = J/cm2`; only with a declared duration and qualified irradiance.
- M6: per-class percentages for the full five-field set, stated distance, any third-party irradiance, and K-number.
- M7: snapshot date minus price observation date; `stale` when greater than 45 days.
- M8: USD per watt, only for an integrating-sphere total-flux row.
- M9: USD per factual square centimetre; assumed areas are excluded.
- M10: disclosed return window and warranty facts; no synthetic score.
- M11: 0–4 completeness for rate, network, cookie, and retrieval date.

## License and citation norm

Data are released under CC BY 4.0. A conformant citation should retain distance, instrument,
and protocol URL where those fields exist. This citation norm is not an extra license condition.
