LRC Grid Sizing — Canonical Brief

Filed: 2026-05-12 · AM: Cathal Dempsey · Live example: DS Electrical grid

Supersedes the three earlier filings on this thread:

  1. "LRC Grid UX: spacing/coverage visibility + satellite overlap detection"
  2. "LRC Grid Spacing — Bidirectional suggestion (too tight AND too wide)"
  3. "LRC Grid UX — Satellite overlap geometry check + spacing nudge (addendum 2)"

This document keeps the immediate-term slice and explicitly defers the rest.


Framing: a "satellite" isn't one operation, it's three

Intent What the AM is trying to learn Overlap with home grid
A. Extend coverage One bigger, continuous picture of where the business ranks Bad — wasted SerpAPI on points already measured
B. Separate market check Does this business also rank in a different town they service? Means the AM mis-picked — should be far from home
C. Drilldown / hotspot Why does the business rank weirdly in one corner of the home grid? Wanted — tighter sampling inside the home bbox

The three earlier briefs implicitly assumed Intent A and treated all overlap as bad. That false-positives on B (because overlap there means the town is wrong, not the grid maths) and blocks legitimate C work entirely. This brief separates them.


Immediate scope

Ship now:

  1. Coverage area surfaced on every grid (Brief 1, Problem 1)
  2. Satellite overlap detection — pre-fire, geometry-only (Brief 3)
  3. Two named resolutions: Extend vs Compact
  4. Geographic default rule that picks one and surfaces the reason
  5. AM can override the default in one sentence ("extend at 2km", "compact instead", "keep going as-is" to bypass for Intent C)

Out of scope — see "Deferred" section at the bottom.


1. Coverage area on every grid

run_serp_grid returns meta.coverage_km on every response:

coverage_width_km  = (grid_size - 1) × spacing_km
coverage_height_km = (grid_size - 1) × spacing_km

Advisor surfaces it alongside spacing in the grid-confirm message, before firing:

Grid: 5×5 at 1km spacing → covers 4km × 4km centred on Dungarvan.

Pure arithmetic, no new API call.


2. Satellite overlap detection — pre-fire, geometry-only

When the AM proposes a satellite, the advisor computes (before any worker call):

half_span_lat = ((size-1) / 2) × spacing_km / 111
half_span_lng = ((size-1) / 2) × spacing_km / (111 × cos(centre_lat))

home_bbox    = home_centre    ± (half_span_lat, half_span_lng)
sat_bbox     = sat_centre     ± (half_span_lat, half_span_lng)
D            = haversine(home_centre, sat_centre)
overlap_pct  = intersection_area(home_bbox, sat_bbox) / smaller_bbox_area × 100

Threshold for warning: overlap_pct > 25%.

When the warning fires, the advisor offers Extend or Compact with computed numbers (see §3), and declares which it's defaulting to plus why (see §4).

The worker returns meta.overlap_with_home = { overlap_pct, suggestion, clean_tile_centre } on satellite calls for belt-and-braces confirmation. The advisor's pre-fire check is the load-bearing UX; the worker's is the audit trail.


3. The two resolutions — canonical definitions

EXTEND — one bigger grid covering both points

  • Re-centre on midpoint of home_centre and sat_centre_proposed (symmetric)
  • Pick new spacing so the new grid bbox contains both points + 1km margin
  • Primary suggestion: keep size = 5, new spacing = ceil((D + 1) / 2)
  • Alternative: keep spacing, bump size 5 → 7 (or 7 → 9)
  • Drops the satellite call; re-runs the home grid once at new dimensions

Worked: D = 3.2km → new spacing = 3km → grid covers 12km × 12km, includes both Dungarvan and Tramore in one shot.

COMPACT — two smaller grids tiled side-by-side

  • Keep both centres
  • Both grids drop to spacing = D / (size - 1) so each half-span = D/2
  • Satellite centre snapped to home_centre + D in direction of travel (clean tile edge)
  • Both grids fire, edge-to-edge, no overlap, no gap

Worked: D = 3.2km, size = 5 → new spacing = 0.8km each → each grid covers 3.2km × 3.2km, edge-to-edge.


4. Geographic default rule

EXTEND when ANY of:
  county === 'Dublin'
  county === 'Cork'      AND haversine(home, 51.8985 / -8.4756) ≤ 20km
  county === 'Galway'    AND haversine(home, 53.2707 / -9.0568) ≤ 20km
  county === 'Limerick'  AND haversine(home, 52.6638 / -8.6267) ≤ 20km
  county === 'Waterford' AND haversine(home, 52.2593 / -7.1101) ≤ 20km

COMPACT otherwise (Regional).

Rationale: Dublin county and the four city metros are continuous urban catchments where businesses serve across boundaries → Extend. Outside those, towns are discrete markets → Compact preserves the "two areas" semantic.

county is already on every irish_places row, so this lands with the existing geocode. The distance check is a 4-line haversine on the home centre.

Worked through

Town County km to city Default Reason line
Tallaght Dublin Extend "Dublin county — Dublin Extended City"
Ballincollig Cork ~7 Extend "7km from Cork city — Cork Extended City"
Cobh Cork ~13 Extend "13km from Cork city — Cork Extended City"
Salthill Galway ~3 Extend "3km from Galway city — Galway Extended City"
Castletroy Limerick ~5 Extend "5km from Limerick city — Limerick Extended City"
Tramore Waterford ~11 Extend "11km from Waterford city — Waterford Extended City"
Youghal Cork ~43 Compact "Regional — outside Dublin or any city Extended City"
Dungarvan Waterford ~45 Compact "Regional — outside Dublin or any city Extended City"
Athenry Galway ~25 Compact "Regional"

5. What the AM sees

⚠️ Satellite overlap detected
Tramore (3.2km from home centre) sits inside your home grid bbox
(4km × 4km at 1km spacing).

Defaulting to: COMPACT  (home grid is in Dungarvan — Regional, outside
                        Dublin or any city Extended City — two distinct
                        areas expected)

  COMPACT (default)
    Tighten both to 5×5 at 0.8km spacing
    Each grid covers 3.2km × 3.2km, edge-to-edge, no overlap
    Fires: 2 grids (50 points total)

  EXTEND (alternative)
    One 5×5 grid at 3km spacing, re-centred at midpoint
    Covers 12km × 12km, includes Dungarvan and Tramore
    Fires: 1 grid (25 points total) — drops the satellite call

  Or type your own: "extend at 2km", "compact at 0.5km", "keep going as-is"

The bold "Defaulting to" line is non-negotiable — the AM never has to guess what the advisor picked.


Acceptance criteria

# Change Where Effort
1 Return meta.coverage_km { width, height } on every run_serp_grid response Worker Low
2 Advisor surfaces coverage area in grid-confirm message before firing Advisor system prompt Low
3 Advisor computes home bbox + satellite bbox + overlap_pct from inputs alone (no API call) Advisor Low
4 Advisor declares default per the geographic rule in §4 and surfaces the reason line Advisor system prompt Low
5 If overlap_pct > 25%, advisor presents Extend and Compact options with computed km values before firing Advisor system prompt Low
6 AM's choice routes to: 1× run_serp_grid (Extend) or 2× run_serp_grid (Compact, satellite snapped to clean tile edge) Advisor Low
7 "keep going as-is" override path — fires the satellite untouched, no warning gate (Intent C escape hatch) Advisor Low
8 Worker returns meta.overlap_with_home = { overlap_pct, suggestion, clean_tile_centre } on satellite calls for audit Worker Low

Deferred (explicitly out of immediate scope)

  • Intent C "drilldown" mode as a first-class flow — currently handled by the "keep going as-is" escape hatch. Revisit once we see how often AMs override.
  • Outer-ring saturation analysis (addendum 1 "too wide" detection: prospect_inner_appearances vs prospect_outer_appearances, outer_ring_no_map_pack_count)
  • Pre-fire spacing-vs-segment sanity check (addendum 1 segment default table)
  • Auto-suggest named alternative satellite town for Intent B (Brief 1, Item 7 — query GBP service areas / irish_places for nearest town outside home bbox)
  • Post-fire meta.warnings[] saturation flags (top competitor > 20/25, prospect > 22/25)

Each is a separate slice. Scope and file individually once this brief lands.


Live example

DS Electrical, Dungarvan (Waterford, ~45km from Waterford city → Regional → Compact default):

  • Home: Dungarvan, 5×5 at 1km → covers 4km × 4km
  • Proposed satellite: Tramore (D ≈ 30km from Dungarvan) → no overlap, fires cleanly
  • Proposed satellite: Kilmacthomas (D ≈ 12km) → overlap detected → advisor defaults to Compact, offers Extend at 7km spacing (covers 24km × 24km in one grid) or Compact at 3km each (two grids edge-to-edge)

FCR Dashboard documentation · generated from docs/ · keep counts verified, not guessed.