Skip to content
Automation
Agent

04-constraint-patterns

Derived from 271 merged PRs in the ALARM fifty-states redistricting project.

From plugin
auto-empirical-research-skills
3.3k146 skills146 agents
Install
> /plugin marketplace add brycewang-stanford/Auto-Empirical-Research-Skills

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Derived from 271 merged PRs in the ALARM fifty-states redistricting project.

Agent definition

04-constraint-patterns.md

Constraint Pattern Reference

Derived from 271 merged PRs in the ALARM fifty-states redistricting project.

---

Equal Population

**Legal basis:** Federal constitutional requirement; all congressional plans. State law for state legislative.

**Encoding:**

# Set in redist_map() — not a separate constraint
map <- redist_map(shp, existing_plan = cd_2020, pop_tol = 0.005)

**Typical tolerance:** 0.005 (0.5%) for congressional; some states stricter:

  • Indiana, Tennessee, Washington: 0.0005–0.001 (strict enacted plans)
  • Minnesota: 0.001
  • Iowa: 0.0001 (statutory)

**Calibration:** When SMC acceptance rates drop quickly in final splits, increase `pop_temper` by 0.01 (e.g., from 0 to 0.01). Do not go above 0.05–0.06 without strong justification. Higher `pop_temper` trades strict equality for better mixing.

**Common mistakes:**

  • Confusing `pop_tol` (tolerance for map object) with `pop_temper` (SMC sampling parameter)
  • Loading data from wrong census year → apparent 10%+ deviations
  • Utah: state law defines 1% *total range*, implying `pop_tol = 0.005` (not 0.01 or 0.0005)

---

Contiguity

**Legal basis:** Required in all states.

**Encoding:** Enforced by redist's sampling algorithm. The prep stage must ensure a valid connected adjacency graph.

# In 01_prep: modify adjacency graph
adj <- geomander::get_adjacent(shp)

# Remove non-contiguous edges (e.g., across water/mountains)
adj <- geomander::subtract_edge(adj, which(shp$GEOID == "A"), which(shp$GEOID == "B"))

# Add edges for physically connected but non-adjacent units (e.g., ferry routes, bridges)
adj[[i]] <- c(adj[[i]], j)
adj[[j]] <- c(adj[[j]], i)

**State-specific patterns:**

  • **Oregon:** Remove edges between counties not connected by a state or federal highway (Or. Rev. Stat. § 188.010)
  • **Washington:** Remove edges across water barriers; reconnect via ferry/bridge/highway
  • **Maryland/Michigan:** Remove water-area precincts from adjacency; connect islands to nearest land precinct in same county
  • **Hawaii:** Islands manually connected (does not affect simulation contiguity, only for visualization)
  • **Multi-island states:** Remove offshore/island tracts; reallocate population to nearest mainland precinct

**Calibration:** Binary — either the graph is valid or it isn't. Run `check_plans_piece_contiguity()` after simulation to verify. Document all adjacency modifications in `01_prep_*.R`.

**Common mistakes:**

  • Disconnected precincts from water bodies create infeasible plans
  • Bay areas (e.g., Chesapeake): use `subtract_edge()` on both sides of the bay
  • Using polygon adjacency instead of piece-level adjacency → false negatives for slivers

---

County/Municipality Preservation (Pseudocounty Constraint)

**Legal basis:** Most states require avoiding splits "where practicable" or "to the extent possible."

**Encoding:** Create pseudocounties that group units, then use as the county constraint unit:

# In 02_setup: build pseudocounties
# Counties larger than the district target are split into per-municipality units
pseudo_county <- pick_county_muni(
  map,
  counties = county,
  munis = muni,
  pop_muni = get_target(map)   # split counties larger than one district
)

# In 03_sim: use in SMC
cons <- redist_constr(map) |>
  add_constr_splits(strength = 1.5, admin = pseudo_county)

**Logic:** Counties whose population exceeds the district population target are split into pseudocounties, where each municipality becomes its own unit. Counties below the target remain whole.

**State examples:**

  • Illinois: Cook + DuPage counties → each municipality as pseudocounty; all other counties whole
  • Pennsylvania: Allegheny, Montgomery, Philadelphia → per-municipality; others whole
  • California: ~15 large counties split; remainder treated as county units
  • Oklahoma: Oklahoma County → municipalities; all others whole
  • Rhode Island: State senate districts used as pseudocounties (statutory boundary requirement)
  • Iowa: County + municipal boundaries both enforced (strict statutory requirement)

**County constraint only (no pseudocounties):** Maine, Idaho, Kansas, Nevada, Nebraska (smaller states where no county exceeds district target).

**Calibration:**

  • County constraint `strength = 2.0` is the typical sweet spot; test 2.5 and 3.0 if needed
  • Strength > 2.5 often causes R-hat values > 1.05 (convergence failure)
  • The pseudocounty approach produces fewer municipality splits than a raw county constraint

**Common mistakes:**

  • Creating pseudocounties in `02_setup` but forgetting to use `pseudo_county` instead of `county` in `03_sim`
  • Not documenting which counties triggered the pseudocounty split in `doc_*.md`
  • Stating "no special techniques" when pseudocounties are actually in use

---

Compactness

**Legal basis:** Many states require "geographically compact" districts. Not always encoded as an active constraint.

**Encoding:** Measured post-hoc; seldom constrained directly:

# Validation metrics tracked automatically in summary(plans):
# comp_edge   — edge compactness
# comp_polsby — Polsby-Popper compactness

# If compactness constraint needed (rare):
cons <- cons |>
  add_constr_compactness(strength = 0.8)  # weaken for small/constrained states

**Calibration:**

  • Default compactness weight = 1.0; weaken to 0.8–0.9 for small states (Maine) where geographic constraints already limit options
  • Iowa requires two statutory compactness measures; verify both pass
  • If reviewer flags low compactness: try increasing `rho` parameter in redist_smc(), or weaken other constraints that may be forcing irregular shapes

**Common mistakes:**

  • Treating compactness as a hard constraint when state law only requires it "where practicable"
  • Leaving Iowa-specific compactness code in another state's files

---

Voting Rights Act / Majority-Minority Districts

**Legal basis:** Federal VRA §2; some states have additional minority representation requirements.

**Encoding:** Hinge Gibbs constraints encouraging minor

Read more
Ships withauto-empirical-research-skills

📌 文档结构(2026-07-22 起): 本文件是中文默认入口 —— banner + badges + 信任面 + 9 阶段流水线速览 + 76 行合集总表。 每个合集的完整描述、按用途分组、精确数字、验证方法在 docs/CONTENT_ZH.md(扩展正文,总表行内的 → 直接跳转到对应锚点)。 English version: README-en.md · 中文扩展正文:docs/CONTENT_ZH.md · README-zh-CN.md 已弃用(重定向占位) 🌐 语言: English |

Get the whole plugin