[CASE STUDY]
Private Prison Portfolio Screener (PPPS)
Follow the public money into private incarceration.
Impact
- Retirement systems indexed
- 7,500+
- SEC filings parsed
- 40k+
- Flagged security identifiers tracked
- ~120
Problem Statement
Campaigns to divest public money from private prisons run on a slow, manual research loop. An organiser who wants to know whether a state teachers’ retirement fund holds shares in the two dominant private-prison operators, or in the banks that syndicate their debt, has to hand-read PDF comprehensive annual financial reports, cross-check ticker changes and post-bankruptcy reorganisations, and reconcile that against quarterly institutional holdings disclosed to the SEC. The work is redone from scratch for every fund and every news cycle, and the results are hard to cite.
PPPS was built with a non-profit divestment coalition to collapse that loop into a single searchable surface: pick a retirement system, see its exposure to a maintained list of incarceration-linked issuers, and get a linkable citation back to the underlying public filing.
Architecture & Technology Stack
The whole system is static-first and runs on Cloudflare’s edge. The public site is a pre-rendered Astro build served from Pages; there is no origin server on the read path. Structured data lives in versioned JSON and a read-only SQLite database compiled during the build and queried at the edge, so a page view is a cache hit rather than a database round trip.
The data pipeline is a scheduled Worker chain:
- Ingest — pull institutional 13F-HR submissions from the SEC EDGAR full-text and submissions APIs, plus a manually curated set of pension CAFR/ACFR source documents.
- Normalise — resolve CUSIP and ticker identifiers to a stable internal issuer id, fold in corporate-action history (renames, spin-offs, emergence from Chapter 11), and attach each row to the filing it came from.
- Screen — join holdings against a maintained watchlist of issuers tied to private prison operations, detention facility management, and detention financing.
- Publish — emit the JSON and SQLite artefacts that the next site build consumes.
R2 holds raw filing snapshots for reproducibility, KV holds small hot lookups, and a Pages Function exposes a narrow JSON endpoint for the few interactive queries the static build cannot pre-compute. Every displayed number links back to a primary source.
Agentic Workflow Breakdown
The project was delivered by a single engineer working with coding agents under a spec-then-plan-then-phase workflow. The specification defined the issuer watchlist semantics and the citation contract; the agent drafted the phased plan and then implemented one checkpoint at a time.
Agents did the heavy, tedious work: writing resilient parsers for inconsistent EDGAR document shapes, generating fixture sets from real filings for regression tests, and building the identifier-reconciliation table that maps historical tickers to current issuers. Each pipeline stage landed behind a test that asserted against a frozen sample filing, so agent-written parser changes were verifiable rather than trusted. Schema validation on the content layer meant a malformed data drop failed the build instead of shipping a wrong holding. The human stayed on the parts that carry judgement: which issuers belong on the watchlist, how to phrase an exposure claim defensibly, and what the coalition could stand behind publicly.
Key Learnings & Next Steps
Reconciling securities identities across time was the real project — the screening join is trivial once issuers are stable. Investing early in a corporate-action history table paid for itself repeatedly.
Keeping the citation link inline with every figure changed how the tool was received: reviewers could check a claim in one click, which built trust faster than any amount of methodology prose. Treating the data build as a build-time artefact, validated by the same schema layer as the content, kept bad data out of production without a running database to babysit.
Next steps under discussion with the coalition: quarter-over-quarter change tracking so a fund’s movement in or out of a position is visible, coverage of corporate debt and underwriting relationships alongside equity holdings, and a downloadable per-fund brief that organisers can attach to public comment.