> ## Documentation Index
> Fetch the complete documentation index at: https://docs.axiomancer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Scoring conventions

> H3 cell IDs, scoring profile weights, confidence semantics, and data-freshness commitments for Locus scoring APIs — the reference behind every cell score.

This page documents the contracts that shape every Locus scoring response. It complements the [APRS data standard](/locus/data-standards) — that page covers the underlying record envelope; this page covers the API-surface scoring semantics.

## H3 cell index

Locus uses [Uber's H3 hierarchical hexagonal grid](https://h3geo.org/) for spatial indexing. Every score, metric, and POI lookup resolves to an H3 cell.

### Resolution

| Resolution | Edge length (km) | Use case                                              |
| ---------- | ---------------- | ----------------------------------------------------- |
| **6**      | 3.7              | Metro-level summaries (San Francisco, Chicago)        |
| **8**      | 0.46             | Neighborhood-level scoring (default for `/api/score`) |
| **9**      | 0.17             | Block-level analysis (high-res scoring profiles)      |

The default scoring resolution is **H3 r8** — about 0.46 km hex edge, which roughly corresponds to a "block group" in US census terms. You can request higher resolution via the `radius` parameter — Locus aggregates child cells appropriately.

### Per-metro resolution overrides

Some low-density, large-parcel metros are scored at **H3 r7** (\~5.16 km², \~1280 m radius) instead of the default r8 (\~0.74 km², \~490 m radius). At r8 a single cell in these markets often covers only one CRE asset, which leaves signal aggregation dominated by small-n noise. Coarsening to r7 produces enough samples per cell for the score to be statistically meaningful.

Metros currently overridden to r7:

* Phoenix
* Houston
* Las Vegas
* Dallas
* San Antonio
* Nashville
* Jacksonville
* Oklahoma City
* El Paso
* Fort Worth

Every other metro continues to score at the r8 default. The override is additive — historical scores are unaffected and no migration is needed on your side.

Each row written to `cell_scores` is tagged with the resolution it was computed at via the `resolution_variant` column, so downstream consumers (rankings, MAUP ensembles, the explorer) can distinguish r7 from r8 cells. If you join scores across metros, filter or group on `resolution_variant` rather than assuming a single resolution.

### Cell IDs in API responses

Cell IDs are the standard 15-character hex strings produced by `h3-js` (e.g. `8828308281fffff`). Use these as opaque identifiers when caching scores client-side; Locus pins the H3 algorithm version and won't change cell-ID semantics without a major API version bump.

## Scoring profiles

The `profile` parameter on `/api/score` adjusts signal weights for a use case. Each profile is a fixed weighting — Locus does not auto-tune weights from your historical data (custom-tuned profiles are on the roadmap).

| Profile        | Top-weighted signals                                                                         | Underweighted signals                             |
| -------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `general`      | Development pipeline (permits), economic strength (employment, GDP), accessibility (transit) | Amenity demand, demographics, population momentum |
| `qsr`          | Foot traffic, demographics (income), competitor density                                      | Permits, real estate                              |
| `self_storage` | Population density, housing turnover, road accessibility                                     | Foot traffic, business vitality                   |
| `retail`       | Foot traffic, parking availability, complementary tenants                                    | Jobs, permits                                     |
| `office`       | Transit access, daytime population, business vitality                                        | Demographics (residential), traffic               |
| `data_center`  | Broadband, power infrastructure, environmental risk, accessibility                           | Amenity demand, business vitality                 |
| `industrial`   | Road accessibility, workforce availability, zoning, economic strength                        | Amenity demand, demographics (residential)        |

Composite scores are 0–100 with a documented confidence interval. Sub-scores per signal group are also 0–100.

### `general` profile weights

The `general` profile is tuned for generic commercial real estate (CRE) price prediction rather than any specific use case. Weights are calibrated against the empirical CRE price-correlation literature — building permit issuance, employment density change, and transit ridership are the three signals with the strongest published correlations and clearest lead times against CRE prices.

| Signal group          | Weight | Rationale                                                                                                 |
| --------------------- | ------ | --------------------------------------------------------------------------------------------------------- |
| `developmentPipeline` | 0.20   | Building permit issuance has R² ≈ 0.55 against CRE prices on a 6–12 month lead (Conference Board LEI).    |
| `economicStrength`    | 0.20   | Employment density change (LEHD) shows strong correlation with retail and office CRE on a 3–9 month lead. |
| `businessVitality`    | 0.15   | Establishment counts and payroll trends — directional but less validated than the top two.                |
| `accessibility`       | 0.12   | Transit ridership shows positive correlation with walkable commercial CRE on a 12–24 month lead.          |
| `populationMomentum`  | 0.10   | Migration and population change — long-lead but noisier in short windows.                                 |
| `demographics`        | 0.10   | Income, age mix, and education — slow-moving baseline, not a short-term price driver.                     |
| `safetyEnvironment`   | 0.08   | Crime is the peer-reviewed safety predictor; flood and environmental risk feed in as constraints.         |
| `amenityDemand`       | 0.05   | Schools, food access, and retail amenities — important for residential but a weak signal for generic CRE. |

Use a use-case profile (`qsr`, `office`, `industrial`, `retail`, `data_center`, `self_storage`) when you have a specific tenant or asset class in mind — those weights reflect industry-specific priorities rather than generic price prediction. The use-case profile weights are unchanged from prior `general` rebalances.

## Development pipeline sub-scores

The `developmentPipeline` group rolls up several permit- and construction-derived sub-signals. Each `subScores` entry returned in the API response carries a `name`, a 0–100 `score`, a `weight`, and a `source` label.

| Sub-score              | Weight | Source                      | What it measures                                                                                                                                          |
| ---------------------- | ------ | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Permit Activity        | 0.40   | Building Permits            | Cell-level permit count and total declared valuation over the trailing 6 months. Falls back to metro-wide averages when the cell itself has zero permits. |
| Construction Detection | 0.20   | Sentinel-2                  | Satellite-derived change-detection score for active construction footprints.                                                                              |
| Land Cover Change      | 0.20   | NLCD                        | Year-over-year change in the share of developed land cover.                                                                                               |
| Opportunity Zone       | 0.10   | Federal OZ                  | Binary flag for federal Qualified Opportunity Zone designation.                                                                                           |
| Permit Velocity        | 0.05   | Building Permits Trend      | Acceleration or deceleration in permit issuance vs. the prior 6-month window.                                                                             |
| Permit Volatility      | 0.05   | Building Permits Volatility | Run-to-run variance in permit issuance; high volatility lowers the sub-score.                                                                             |
| Permit Valuation Tier  | 0.10   | AXL-5                       | LLM-classified valuation tier (`transformative`, `structural`, `stabilization`) for the dominant permit mix in the cell.                                  |
| Permit Scope Quality   | 0.10   | AXL-108                     | Per-permit `scope_type` × `cost_tier` quality signal — see below.                                                                                         |

### Permit Scope Quality (AXL-108)

`Permit Scope Quality` weights every permit in the trailing 6-month window by what the permit is for, not just how many were issued. Each permit's `scope_type` and `estimated_cost_tier` — both extracted by an LLM-based permit classifier from the free-text description — are multiplied to yield a 0–100 contribution, and the cell's sub-score is the average of those contributions across the window.

**Scope-type weights:**

| `scope_type`       | Weight |
| ------------------ | ------ |
| `new_construction` | 1.0    |
| `addition`         | 0.7    |
| `demolition`       | 0.5    |
| `renovation`       | 0.3    |
| `repair`           | 0.1    |

**Cost-tier multipliers:**

| `estimated_cost_tier` | Multiplier |
| --------------------- | ---------- |
| Tier 1 (highest)      | 1.5        |
| Tier 2                | 1.0        |
| Tier 3                | 0.5        |
| Tier 4 (lowest)       | 0.25       |

A cell dominated by `new_construction` permits in the highest cost tier will trend toward 100; a cell dominated by low-cost `repair` permits will trend toward 0. The signal is designed to separate cells where permits indicate genuine new development from cells where permits mostly reflect maintenance churn.

When the LLM extractor has not yet annotated any permit in a cell, the sub-score is omitted from `subScores` and `AXL-108` appears in `sourcesMissing` for the group.

```json theme={null}
{
  "developmentPipeline": {
    "score": 71.4,
    "subScores": [
      { "name": "Permit Activity", "score": 78, "weight": 0.40, "source": "Building Permits" },
      { "name": "Permit Scope Quality", "score": 64, "weight": 0.10, "source": "AXL-108" }
    ],
    "sourcesUsed": ["Building Permits", "AXL-108"],
    "sourcesMissing": []
  }
}
```

## Safety & environment sub-scores

The `safetyEnvironment` group rolls up crime, regulatory hazard maps, realized loss history, environmental burden, air quality, and 311 service-request signals.

| Sub-score                  | Weight | Source                        | What it measures                                                                                                                     |
| -------------------------- | ------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Crime Rate                 | 0.30   | Local Police                  | Reported incidents per 1k residents in the trailing window.                                                                          |
| Flood Risk                 | 0.20   | FEMA                          | Forward-looking FEMA FIRM flood-zone designation (`X`, `A`, `AE`, `V`, etc.).                                                        |
| Flood Loss History         | 0.15   | AXL-109 (FEMA NFIP)           | Realized NFIP claim history for the cell's nearest zip — see below.                                                                  |
| Environmental Risk         | 0.15   | EPA EJScreen                  | Composite EJ index (pollution + demographic burden).                                                                                 |
| Natural Hazard Risk        | 0.15   | FEMA NRI                      | National Risk Index composite for 18 natural hazard types.                                                                           |
| Air Quality                | 0.10   | EPA AirNow                    | Trailing AQI exposure.                                                                                                               |
| Complaint Density          | 0.05   | 311 Service Requests          | Open-complaint volume per cell.                                                                                                      |
| Complaint Velocity         | 0.05   | 311 Service Requests Velocity | 30-day change in complaint volume.                                                                                                   |
| Resolution Time            | 0.05   | AXL-6                         | Average days-to-close for 311 complaints in the cell.                                                                                |
| Complaint Trend YoY        | 0.05   | AXL-107 (311 YoY)             | Year-over-year delta on the cell's trailing 30-day 311 complaint density — see below.                                                |
| Utility Complaint Density  | 0.04   | ICC                           | Illinois Commerce Commission utility-service complaint volume at the cell's nearest zip — see below.                                 |
| Nuclear Facility Proximity | 0.05   | NRC                           | Distance in km from the cell to the nearest NRC-licensed reactor site, scaled against NRC emergency-planning-zone radii — see below. |

### Flood Loss History (AXL-109)

`Flood Loss History` is a realized-loss companion to the regulatory FEMA FIRM `Flood Risk` sub-score. The two signals answer different questions:

* **Flood Risk** — *What does the regulatory map say this cell is?* Forward-looking, redrawn on a multi-year cycle.
* **Flood Loss History** — *What has actually happened here?* Backward-looking, derived from FEMA National Flood Insurance Program (NFIP) claims.

This distinction matters because repeat-loss corridors and flash-flood-prone areas frequently sit in non-`A`/`V` FIRM zones — the FIRM map is a snapshot of modeled hazard, while NFIP claims capture realized loss patterns including pluvial flooding, drainage failures, and stormwater backups that the FIRM zone often misses.

The sub-score is computed by:

1. Finding the nearest US zip centroid to the cell (single PostGIS nearest-neighbor lookup).
2. Joining that zip to the aggregated NFIP claims table (677k+ raw claims rolled up to \~17.8k zip-level records).
3. Returning a normalized exposure score in `[0, 1]` derived from claim count, repeat-loss policy share, and the most recent claim year.
4. Inverting to a 0–100 safety contribution: a zip with no historic claims scores 100, a maximum-exposure zip scores 0.

When the cell's nearest zip has no NFIP claims (common for inland low-risk geographies), the sub-score is omitted from `subScores` and `AXL-109 (FEMA NFIP)` appears in `sourcesMissing` for the group. NFIP coverage is US-only — international cells will always show this source as missing.

```json theme={null}
{
  "safetyEnvironment": {
    "score": 64.2,
    "confidence": 0.83,
    "subScores": [
      { "name": "Crime Rate", "score": 72, "weight": 0.30, "source": "Local Police" },
      { "name": "Flood Risk", "score": 80, "weight": 0.20, "source": "FEMA" },
      { "name": "Flood Loss History", "score": 78, "weight": 0.15, "source": "AXL-109 (FEMA NFIP)" },
      { "name": "Environmental Risk", "score": 61, "weight": 0.15, "source": "EPA EJScreen" }
    ],
    "sourcesUsed": ["Local Police", "FEMA", "AXL-109 (FEMA NFIP)", "EPA EJScreen"],
    "sourcesMissing": ["FEMA NRI", "EPA AirNow", "311 Service Requests"]
  }
}
```

A coastal cell in a repeat-loss corridor will typically score high on `Flood Risk` (because it sits in a regulatory `AE` or `V` zone) *and* low on `Flood Loss History` (because NFIP has paid out repeated claims there). Use both sub-scores together when ranking cells for hazard-sensitive use cases — relying on the FIRM zone alone will under-flag the worst pluvial-flood corridors.

### Complaint Trend YoY (AXL-107)

`Complaint Trend YoY` is a directional companion to the volume-based `Complaint Density` and `Complaint Velocity` sub-scores. Density measures how loud a cell is *right now*; velocity measures the 30-day change; the YoY delta measures whether that loudness is rising or falling against the same window one year ago — the slow-moving signal that volume and short-window velocity both miss.

The sub-score is computed in-app from the same `service_requests_311` rows the scorer already pulls for density and resolution time, so no additional data source is required:

1. Count 311 complaints in the trailing 30 days (`density_30d`).
2. Count 311 complaints in the matching 30-day window one year prior (the 335-to-395-day window).
3. Compute the YoY delta as `(current − prior) / max(prior, 1)`, capped at `+5×` to bound runaway ratios in cells with a near-zero prior baseline.
4. Map the delta onto a 0–100 safety contribution: `−1` (complaints down 100%) → 100, `+3` (complaints up 3×) → 0, with values above `+3×` saturating at 0.

Negative YoY (complaints trending down) lifts the cell's safety score; positive YoY (complaints rising) penalizes it. Rising 311 density is treated as a Pioneer Stage 1 signal — the same complaint-acceleration pattern that typically precedes pioneer-business clustering by 12–24 months and feeds the [Pioneer Signal](#pioneer-signal-and-early-stage-gentrification-indicator) cascade.

When both the current and prior 30-day windows are empty for a cell, the sub-score is omitted from `subScores` and `AXL-107 (311 YoY)` appears in `sourcesMissing` for the group rather than emitting a misleading "improving" signal from a quiet cell with no complaint history. Cells in metros without 311 ingestion will always show this source as missing.

```json theme={null}
{
  "safetyEnvironment": {
    "score": 67.1,
    "subScores": [
      { "name": "Crime Rate", "score": 72, "weight": 0.30, "source": "Local Police" },
      { "name": "Complaint Density", "score": 64, "weight": 0.05, "source": "311 Service Requests" },
      { "name": "Complaint Velocity", "score": 58, "weight": 0.05, "source": "311 Service Requests Velocity" },
      { "name": "Complaint Trend YoY", "score": 81, "weight": 0.05, "source": "AXL-107 (311 YoY)" }
    ],
    "sourcesUsed": ["Local Police", "311 Service Requests", "311 Service Requests Velocity", "AXL-107 (311 YoY)"]
  }
}
```

Read all four 311 sub-scores together when interpreting a cell: a cell with high `Complaint Density` *and* a high (improving) `Complaint Trend YoY` is loud-but-getting-quieter, while a cell with low density *and* a low (deteriorating) trend score is quiet-but-getting-louder — the kind of leading indicator that volume alone obscures.

### Utility Complaint Density (ICC)

`Utility Complaint Density` captures unresolved utility-service friction — outages, billing disputes, service-quality complaints — that shows up as formal filings with a state utility commission. It's a leading indicator for infrastructure stress that neither crime data nor FEMA flood maps pick up.

The sub-score is computed from the ICC (Illinois Commerce Commission) utility-complaint feed, joined to the cell via the same zip-level nearest-neighbor lookup that powers `Flood Loss History`:

1. Find the nearest US zip centroid to the cell.
2. Count ICC utility complaints at that zip in the trailing FY window.
3. Log-scale the count against the observed distribution (median 4, p90 22, p99 91 complaints/zip) and invert to a 0–100 safety contribution: 0 complaints → 100, saturating toward 0 above \~150.

The dataset is **\~91% Illinois** — this is a single-state FOIA extract, not a national commission-complaint aggregate. Cells outside Illinois will almost always show `ICC` in `sourcesMissing` rather than a misleading zero-complaint "clean" record. Treat this sub-score as an Illinois-only enrichment for now; do not infer utility health for non-IL cells from its absence.

```json theme={null}
{
  "safetyEnvironment": {
    "score": 61.8,
    "subScores": [
      { "name": "Crime Rate", "score": 72, "weight": 0.20, "source": "Local Police" },
      { "name": "Utility Complaint Density", "score": 34, "weight": 0.04, "source": "ICC" }
    ],
    "sourcesUsed": ["Local Police", "ICC"]
  }
}
```

### Nuclear Facility Proximity (NRC)

`Nuclear Facility Proximity` is a proximity penalty for cells that fall inside the NRC's emergency-planning zones (EPZs) around operating and decommissioning reactor sites. It rides alongside `Environmental Risk` and `Natural Hazard Risk` as a discrete, regulatory-anchored hazard layer that the EJScreen and NRI composites do not surface directly.

The sub-score is computed by:

1. Scanning NRC-licensed reactor sites (operating + decommissioning units, \~68 site locations) for the nearest site to the cell centroid using a haversine distance.
2. Mapping distance onto a linear decay between the NRC's two published EPZ radii:
   * **16 km (\~10 mi)** — the plume-exposure EPZ. Cells at or inside this radius score `0` (minimum safety contribution from this signal).
   * **80 km (\~50 mi)** — the ingestion-pathway planning zone. Cells at or beyond this radius score `100` (no meaningful nuclear-proximity penalty).
3. Linearly interpolating between the two anchors for cells in the 16–80 km band.

The 16/80 km anchors are the NRC's own EPZ radii, not tuned parameters. The site coordinates are backfilled at city/township precision via a plant-name → site-coordinate crosswalk (68 sites) — adequate for the EPZ-scale proximity signal, not for anything finer.

```json theme={null}
{
  "safetyEnvironment": {
    "score": 58.9,
    "subScores": [
      { "name": "Crime Rate", "score": 72, "weight": 0.20, "source": "Local Police" },
      { "name": "Nuclear Facility Proximity", "score": 42, "weight": 0.05, "source": "NRC" }
    ],
    "sourcesUsed": ["Local Police", "NRC"]
  }
}
```

Cells far from any US reactor site score at or near 100 on this sub-score — it never *rewards* proximity, only penalizes it. Use it together with `Environmental Risk` and `Natural Hazard Risk` when ranking cells for hazard-sensitive use cases (data centers, hospitals, long-hold industrial siting).

## Economic strength sub-scores

The `economicStrength` group rolls up employment, wage, GDP, banking, small-business lending, innovation, and federal-tenancy signals.

| Sub-score              | Weight | Source   | What it measures                                                              |
| ---------------------- | ------ | -------- | ----------------------------------------------------------------------------- |
| Employment Growth      | 0.24   | BLS QCEW | Trailing employment change in the cell's county.                              |
| Avg Wages              | 0.20   | BLS QCEW | Average weekly wage in the cell's county.                                     |
| GDP Growth             | 0.16   | BEA      | Metro-level real GDP change.                                                  |
| Banking Activity       | 0.13   | FDIC     | Deposits per capita in the cell's zip.                                        |
| Innovation Density     | 0.12   | USPTO    | Patent count for the cell's metro.                                            |
| Small Biz Lending      | 0.08   | SBA      | 7(a) + 504 loan volume in the cell's county.                                  |
| Federal Lease Presence | 0.07   | GSA FRPP | Federal-agency leased square footage in the cell's H3 query ring — see below. |

### Federal Lease Presence (GSA FRPP)

`Federal Lease Presence` treats federal-agency tenancy as a **positive** economic anchor. Federal leases are long-dated, credit-strong, and slow to move — a dense cluster of federal RSF (rentable square footage) around a cell is a durable institutional signal that CRE fundamentals in the area are underwritten by government tenancy, not just private demand.

The sub-score is computed from the GSA Federal Real Property Profile (FRPP) FOIA extract:

1. Sum leased RSF across every federal lease that falls inside the cell's H3 query ring (not just the exact cell — federal tenancy spills over into the immediate neighborhood).
2. Log-scale the summed RSF between **2,000 sqft** (a very small satellite office) and **750,000 sqft** (a dense multi-agency federal cluster).
3. Map onto 0–100: a single median-sized federal office lease (\~8,700 sqft) contributes \~25/100; a large multi-lease cluster saturates to 100.

Cells with no federal leases anywhere in the query ring omit the sub-score and list `GSA FRPP` in `sourcesMissing`. This is the most common state — federal-lease footprints are geographically concentrated (metro cores, agency campuses, courthouses, ports of entry), so a missing sub-score is a genuine "no federal anchor here" reading, not a data-quality gap.

```json theme={null}
{
  "economicStrength": {
    "score": 74.1,
    "subScores": [
      { "name": "Employment Growth", "score": 68, "weight": 0.24, "source": "BLS QCEW" },
      { "name": "Avg Wages", "score": 72, "weight": 0.20, "source": "BLS QCEW" },
      { "name": "Federal Lease Presence", "score": 88, "weight": 0.07, "source": "GSA FRPP" }
    ],
    "sourcesUsed": ["BLS QCEW", "GSA FRPP"]
  }
}
```

Federal leases also project into the Codex as `codex_entities` (entity\_type = `facility`) — see the Codex documentation if you need the underlying per-lease records rather than the aggregated score contribution.

## Business vitality sub-scores

The `businessVitality` group rolls up business openings/closings, category diversity, rating momentum, review activity, establishment density, health inspections, license velocity, pioneer businesses, and regulatory friction.

| Sub-score                               | Weight | Source             | What it measures                                                                                                       |
| --------------------------------------- | ------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| Growth Rate                             | 0.21   | Google Places      | Net business openings vs. closings normalized against total establishments.                                            |
| Yelp Activity                           | 0.14   | Yelp               | Composite of average rating, review velocity, and new-listing count.                                                   |
| License Velocity                        | 0.12   | Business Licenses  | New-license issuance rate in the cell's window.                                                                        |
| Category Diversity                      | 0.11   | Google Places      | Distinct business categories represented in the cell.                                                                  |
| Rating Trajectory                       | 0.11   | Google Places      | Direction of average rating change over the window.                                                                    |
| Establishment Density                   | 0.09   | Census CBP         | Establishments per cell from County Business Patterns.                                                                 |
| Pioneer Business Presence               | 0.08   | AXL-7              | Pioneer-business count feeding the [Pioneer Signal](#pioneer-signal-and-early-stage-gentrification-indicator) cascade. |
| Commercial Health                       | 0.05   | Health Inspections | Average health-inspection score in the cell.                                                                           |
| Nightlife Pipeline                      | 0.05   | Liquor Licenses    | New liquor-license issuance rate.                                                                                      |
| Broker Discipline (Regulatory Friction) | 0.04   | NY DOS             | State-level real-estate broker disciplinary consent orders — see below.                                                |

### Broker Discipline (NY DOS)

`Broker Discipline` is a **regulatory-friction penalty** on business vitality — a rising volume of formal disciplinary actions against real-estate brokers in a state signals that the transaction environment is contentious, and that some share of local CRE activity is being litigated rather than transacted cleanly.

The sub-score is computed from the NY Department of State (DOS) real-estate broker disciplinary consent-order FOIA extract:

1. Count distinct DOS disciplinary case files (`dos_file_number`) for the cell's **state**.
2. Log-scale the count between 1 and 100 disciplinary actions, then invert to a 0–100 contribution: fewer actions → higher score, more actions → lower score.

**This is a state-level join, not a per-cell signal.** The underlying FOIA snapshot has no per-record address, coordinates, or licensee zip — the field simply is not in the source. That means every cell in the same state shares the same disciplinary count, and by extension the same sub-score contribution. The weight is intentionally low (0.04) to reflect this: a flat state-wide value should never swing an individual cell's business-vitality score materially.

The current extract is a single fiscal-year, single-state (NY) sample — 62 rows across 40 distinct case files. Cells outside NY show `NY DOS` in `sourcesMissing` and pay no penalty. Do not read a missing `NY DOS` sub-score on a non-NY cell as "clean regulatory environment"; read it as "no state-level broker-discipline data available for this state."

```json theme={null}
{
  "businessVitality": {
    "score": 66.4,
    "subScores": [
      { "name": "Growth Rate", "score": 71, "weight": 0.21, "source": "Google Places" },
      { "name": "License Velocity", "score": 68, "weight": 0.12, "source": "Business Licenses" },
      { "name": "Broker Discipline (Regulatory Friction)", "score": 42, "weight": 0.04, "source": "NY DOS" }
    ],
    "sourcesUsed": ["Google Places", "Business Licenses", "NY DOS"]
  }
}
```

Broker-discipline case files also project into the Codex as `codex_events` (event\_type = `broker_disciplinary_action`) — use the Codex directly if you need per-case detail rather than the aggregated state-level score contribution.

## Confidence semantics

Every Locus response includes a `confidence` field (0.0–1.0) representing the ratio of expected data sources that returned data for the location.

```json theme={null}
{
  "composite": 78.4,
  "confidence": 0.92,
  "sourcesUsed": 36,
  "sourcesTotal": 43
}
```

* **0.9+ (high)** — almost all data sources contributed; treat as authoritative.
* **0.7–0.9 (medium)** — significant signals present; treat as directional, not exact.
* **0.5–0.7 (low)** — sparse coverage; useful for filtering but not for ranking.
* **\<0.5 (very low)** — Locus returns the score for transparency but it should not be used for production decisions.

Confidence varies by metro. Major US metros (top 50 MSAs) consistently exceed 0.85. Rural areas, US territories, and international markets often fall below 0.7.

## Coverage guards on signal groups

Some signal groups include a **minimum-source guard** to prevent a single universally-available data source from dominating the group score for cells where every other source is missing. When a group's coverage guard isn't met, the group emits a neutral **no-signal score of 50** and a `confidence` of `0`, with an empty `subScores` array — instead of returning a misleadingly high or low score derived from one input.

| Signal group        | Minimum sub-signals | Reason                                                                                                                                                                                                                                     |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `safetyEnvironment` | 2                   | FEMA flood zone is available for almost every US cell (typically `X` = 100). Without a guard, cells with no crime, EJScreen, NRI, AQI, NFIP loss history, or 311 data would score 100/100 on safety purely because of flood-zone coverage. |
| All other groups    | 1 (no guard)        | These groups don't currently have a high-scoring, universally-available source that would dominate the average.                                                                                                                            |

Example response for a rural cell where only FEMA flood zone is available:

```json theme={null}
{
  "safetyEnvironment": {
    "score": 50,
    "confidence": 0,
    "subScores": [],
    "sourcesUsed": [],
    "sourcesMissing": ["Local Police", "AXL-109 (FEMA NFIP)", "EPA EJScreen", "FEMA NRI", "EPA AirNow", "311 Service Requests"]
  }
}
```

Treat a `safetyEnvironment.score` of `50` paired with `confidence: 0` as **"no safety signal available"** — not as "neutral safety." The 50 is a placeholder so the composite score can still be computed; it is not a measurement. Use the `confidence` field to filter these cells out of safety-sensitive ranking lists.

## Pioneer Signal and early-stage gentrification indicator

Locus includes a **Pioneer Signal** detection system that identifies early signs of neighborhood transformation. The system tracks a multi-stage cascade that typically precedes gentrification by 12–24 months:

1. **Pioneer businesses** — new specialty coffee shops, art galleries, or co-working spaces appear in a previously underserved area.
2. **Council language shift** — city council meeting minutes begin referencing "revitalization," "mixed-use," or "transit-oriented development" for the area.
3. **Permit acceleration** — building permit velocity increases, particularly renovation and change-of-use permits.
4. **Rezoning activity** — formal rezoning applications or variance requests are filed.

These stages feed into the **Early-Stage Gentrification Indicator (ESGI)**, a score returned alongside the composite score in scoring responses. The ESGI combines causal edge attribution, upzoning probability, litigation risk, and spatial spillover effects to quantify how likely a cell is to experience rapid value change.

```json theme={null}
{
  "composite": 78.4,
  "esgi": {
    "score": 0.72,
    "stage": "permit_acceleration",
    "upzoning_probability": 0.45,
    "litigation_risk": 0.12,
    "spatial_spillover": 0.31
  }
}
```

| Field                       | Type   | Description                                                                                                           |
| --------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- |
| `esgi.score`                | float  | ESGI score from 0.0 to 1.0 indicating transformation likelihood.                                                      |
| `esgi.stage`                | string | Current cascade stage: `pioneer_businesses`, `council_language_shift`, `permit_acceleration`, or `rezoning_activity`. |
| `esgi.upzoning_probability` | float  | Probability that the cell will be upzoned within 12 months.                                                           |
| `esgi.litigation_risk`      | float  | Risk of development delays from litigation or community opposition.                                                   |
| `esgi.spatial_spillover`    | float  | Influence from transformation activity in neighboring cells.                                                          |

## Uncertainty quantification

Scoring responses include uncertainty metadata that helps you assess how much to trust a given score. Locus runs a Monte Carlo simulation (96 samples) with confidence-aware noise injection to produce:

* **Confidence intervals** — geo-conformal prediction intervals at 80% and 90% coverage.
* **Sobol sensitivity indices** — first-order and total-order indices showing which signal groups contribute most to score variance.
* **Epistemic flags** — signals where data is sparse or conflicting, flagged for transparency.
* **Spatial Sharpe ratio** — a risk-adjusted score metric analogous to a financial Sharpe ratio, indicating score stability relative to spatial neighbors.

Request uncertainty data by adding `include=uncertainty` to any scoring endpoint:

```bash theme={null}
curl "https://axiomlocus.io/api/score?lat=37.7749&lng=-122.4194&include=uncertainty"
```

```json theme={null}
{
  "composite": 78.4,
  "confidence": 0.92,
  "uncertainty": {
    "ci_80": [72.1, 84.7],
    "ci_90": [69.5, 87.3],
    "spatial_sharpe": 1.42,
    "sobol_first_order": {
      "businessVitality": 0.28,
      "developmentPipeline": 0.22,
      "demographics": 0.15,
      "accessibility": 0.12,
      "economicStrength": 0.10,
      "safetyEnvironment": 0.07,
      "populationMomentum": 0.04,
      "amenityDemand": 0.02
    },
    "epistemic_flags": ["populationMomentum"]
  }
}
```

| Field                           | Type   | Description                                                                                                         |
| ------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| `uncertainty.ci_80`             | array  | 80% confidence interval \[lower, upper] for the composite score.                                                    |
| `uncertainty.ci_90`             | array  | 90% confidence interval \[lower, upper].                                                                            |
| `uncertainty.spatial_sharpe`    | float  | Risk-adjusted score relative to neighboring cells. Values above 1.0 indicate the score is stable compared to peers. |
| `uncertainty.sobol_first_order` | object | First-order Sobol indices per signal group. Higher values mean that group drives more score variance.               |
| `uncertainty.epistemic_flags`   | array  | Signal groups with sparse or conflicting data.                                                                      |

## Per-cell consensus class

The `uncertainty` payload tells you how noisy a score is given the data feeding it. The **consensus class** answers a different question: *would this score still hold if Locus had aggregated to a different grid?* It is a per-cell sensitivity check against the [Modifiable Areal Unit Problem (MAUP)](https://en.wikipedia.org/wiki/Modifiable_areal_unit_problem) — the well-known finding that spatial statistics can move materially when the underlying grid changes.

Locus computes a `consensus_class` for every cell by comparing the cell's percentile rank within its metro at the default resolution against the percentile rank of the parent (coarser) hex it sits inside. When the two ranks agree the score is robust to grid choice; when they diverge the score is at least partly a grid artifact.

The classification is surfaced on `/api/cells/detail` (the endpoint that powers the Explorer's cell-detail panel) as three fields:

| Field                   | Type           | Description                                                                                                                                                                            |
| ----------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `consensus_class`       | string \| null | One of `stable_core`, `ambiguity_shell`, `stable_non_signal`, or `null` if the cell has not yet been classified.                                                                       |
| `support_stability`     | float \| null  | Agreement between the cell's resolution-8 percentile and its resolution-7 parent percentile within the metro. `1.0` = perfect agreement, `0.0` = the two supports disagree completely. |
| `consensus_computed_at` | string \| null | ISO-8601 timestamp of the most recent classification run for this cell.                                                                                                                |

### Class definitions

| Class               | When it fires                                                                        | How to read it                                                                                                                                    |
| ------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stable_core`       | `support_stability ≥ 0.80` and the cell sits above the bottom quartile of its metro. | The score is robust to grid choice. Treat as a high-confidence ranking.                                                                           |
| `ambiguity_shell`   | `0.20 ≤ support_stability < 0.80`.                                                   | The cell ranks materially differently when re-aggregated to a coarser grid. Use the score directionally and pair it with neighbors before acting. |
| `stable_non_signal` | The cell is consistently in the bottom quartile of its metro across both supports.   | Genuinely quiet. The low score is not a grid artifact — it is the same answer at every resolution.                                                |

A cell shows `consensus_class: null` until the classification job has populated its row. Treat `null` the same way you'd treat `confidence: null` — render no robustness badge rather than guessing.

### Example response

```json theme={null}
{
  "h3_index": "882a100d63fffff",
  "composite_score": 78.4,
  "support_stability": 0.92,
  "consensus_class": "stable_core",
  "consensus_computed_at": "2026-04-29T20:14:00Z"
}
```

### When to use it

* **Ranking and shortlisting.** Filter to `consensus_class = stable_core` when you need the most defensible top-N list — those cells survive a grid change.
* **Risk-flagging the long tail.** Cells in `ambiguity_shell` are the cells most worth a human review before commitment. They typically sit on tier boundaries where small grid choices flip rankings.
* **Suppressing false-positive low scores.** A `stable_non_signal` cell is genuinely low across grids — a `stable_non_signal` paired with a `composite_score` of 35 means the cell is reliably quiet, not under-sampled.

The classification is recomputed after every material scoring-engine change. The companion [Spatial Sharpe ratio](#uncertainty-quantification) gives you the same robustness intuition relative to *neighbors* rather than relative to *grid resolution* — combine both when filtering for production-grade rankings.

## Data freshness

| Source                            | Refresh cadence         | Lag                             |
| --------------------------------- | ----------------------- | ------------------------------- |
| POI inventory (Google Places)     | Weekly                  | \<7 days                        |
| Building permits (city open data) | Per-city; mostly weekly | 7-30 days depending on city     |
| Traffic patterns (state DOTs)     | Monthly                 | 30-60 days                      |
| Transit ridership (FTA NTD)       | Monthly                 | 60-90 days (FTA publishing lag) |
| USPS vacancy (HUD)                | Quarterly               | 90-120 days                     |
| Jobs (BLS QCEW)                   | Quarterly               | 90 days (BLS publishing lag)    |
| Demographics (Census ACS)         | Annual                  | 12-18 months                    |
| Real estate listings              | Daily (where available) | 1-3 days                        |
| Crime (UCR/local)                 | Monthly                 | 30-60 days                      |

The `freshness` metadata in score responses tells you the oldest source feeding a given response — useful for deciding whether to cache.

## API stability commitments

* **Cell IDs** — frozen across major API versions
* **Scoring profile names** — frozen
* **Composite + sub-score scales (0–100)** — frozen
* **Confidence semantics** — frozen
* **Sub-score names within a group** — may change with 90-day notice
* **Underlying data sources** — may change without notice (we pick the best available)
* **Weight tuning per profile** — adjusted quarterly based on backtesting; minor adjustments not announced, major rebalances get a 30-day blog post

If a profile's behavior changes meaningfully, you'll see a `profile_version` bump in the response. Pin to a specific `profile_version` if you need replicable scores across time.

## What Locus doesn't include

Locus is **non-PII**. We do not include:

* Individual person data (names, addresses, phone numbers)
* Mobile-device location traces (Locus uses aggregated patterns, not raw movements)
* Customer-specific data unless you explicitly upload it via `/api/data/upload`

Aggregations resolving to fewer than 25 people (or 5 households for residential metrics) are suppressed in responses with a `suppressed: true` flag.
