A reproducible pipeline for de jure comparative analysis of U.S. state constitutions, designed to support pilot state selection for studies on Fundamental Freedoms, Checks and Balances, and Democratic Protections.
This project is designed to run with Claude Code for the LLM-based evaluation step. The Claude Code project files needed for that workflow are included under .claude/.
No Excel files are committed to this repository. Any .xlsx inputs or outputs are expected to remain local only.
- South Carolina (SC)
- Tennessee (TN)
- Texas (TX)
- Utah (UT)
- Minnesota (MN)
- Ohio (OH)
The full research workflow has three stages:
┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────┐
│ Private scrape │ ───> │ Claude Code evaluates │ ───> │ 02_build_output │
│ (optional) │ │ (one-time, manual) │ │ (run anytime) │
└─────────────────┘ └──────────────────────┘ └──────────────────┘
│ │ │
v v v
data/raw/*.txt input/scores.xlsx local .xlsx outputs
(cached locally) (canonical local input) (not committed)
- Constitution text is treated as an input artifact. You can generate it with your own scraper or add it manually to
data/raw/. - LLM evaluation is non-deterministic but stable as a frozen artifact. Claude Code runs the evaluation once, producing
input/scores.xlsx. From that moment on,scores.xlsxis the canonical local source. You can edit it by hand if you disagree with any score. - Output building is deterministic. Re-run
02_build_output.pyas many times as you want; it always produces the same Excel from the same inputs.
state-constitutional-analysis/
├── .claude/ Claude Code project config
│ ├── settings.json
│ └── commands/
│ └── analyze.md Custom slash command: /analyze
├── code/
│ ├── 02_build_output.py Output builder entrypoint
│ ├── lib/ Reusable modules
│ │ └── excel_builder.py
│ ├── prompts/
│ │ └── evaluation_prompt.md The prompt Claude Code follows
│ └── tests/
│ └── test_excel_builder.py
├── input/
│ ├── indicators.xlsx Local editable codebook (gitignored)
│ ├── states.yaml Six states + scraping config
│ └── scores.xlsx Generated locally by Claude Code (gitignored)
├── data/
│ └── raw/ Constitution text inputs (gitignored)
└── outputs/ Optional local export location (gitignored)
# Clone and enter
git clone <your-repo-url>
cd state-constitutional-analysis
# Install dependencies
pip install -r requirements.txtmkdir -p data/rawAdd one plain-text file per state to data/raw/ before running the analysis:
south_carolina.txttennessee.txttexas.txtutah.txtminnesota.txtohio.txt
You can create these files with your own scraper or by manual copy-paste. They are intentionally gitignored.
Open this project in Claude Code and run:
/analyze
This triggers the custom command defined in .claude/commands/analyze.md. Claude Code will:
- Read the codebook from
input/indicators.xlsx - Read each constitution from
data/raw/ - For each (indicator × state), assign a score 0–3, a constitutional reference, and a brief note
- Write the local
input/scores.xlsxwith two sheets:scoresandanalysis
This step takes several minutes and is the most expensive part of the pipeline (LLM context tokens). Once scores.xlsx exists, treat it as the canonical local input — edit by hand if you disagree with any score.
python code/02_build_output.pyThis produces a local .xlsx workbook with the following sheets:
- Read Me First — purpose, glossary, caveats
- Executive Summary — aggregate scores by dimension and total
- FF — Comparative — Fundamental Freedoms, indicator-by-indicator
- CB — Comparative — Checks and Balances
- DP — Comparative — Democratic Protections
- Tidy Data — long format for analysis (one row per indicator × state)
- Analysis — narrative analysis from Claude Code's evaluation
- Sources — references with hyperlinks
You can re-run 02_build_output.py after any manual edit to input/scores.xlsx or input/indicators.xlsx.
The generated workbook should remain local; it is gitignored by default.
Your local input/indicators.xlsx is the source of truth for indicators. Columns:
| Column | Description |
|---|---|
id |
Stable identifier (e.g., FF01, CB03, DP07) |
dimension |
One of: Fundamental Freedoms, Checks and Balances, Democratic Protections |
indicator |
Short name of the indicator |
question |
The question Claude Code answers about each constitution |
scoring_guidance |
Explicit definition of what 0/1/2/3 means for this indicator |
To add an indicator, just add a row. To remove one, delete the row. To re-score, delete input/scores.xlsx and re-run /analyze to regenerate all scores.
- All analysis is de jure (textual only). No statutory law, case law, or implementation practice is captured.
- Scoring is ordinal 0–3 with direction defined per indicator. Higher is more democratic / more protective / more checks.
- Aggregate scores are simple sums with equal weighting. To use weighted scoring, derive new aggregates from the
Tidy Datasheet. - See the
Read Me Firstsheet in the output for the full methodology.
pytest code/tests/ -vTests cover the Excel builder output structure and formula integrity.
MIT — see LICENSE.
If you use this in published work, please cite as:
State Constitutional Analysis (2026). De jure comparative of SC, TN, TX, UT, MN, OH.
Internal research tool. https://github.com/<your-org>/state-constitutional-analysis