What a Knowledge Graph Found in 1,172 Cuban Charge Sheets That No Case File Could Show Alone

What a Knowledge Graph Found in 1,172 Cuban Charge Sheets That No Case File Could Show Alone

When a government charges more than a thousand political prisoners, does it charge them all the same way? We built a formal knowledge graph over Cuba's political-prisoner registry to find out. The answer is no. There are two distinct prosecutorial playbooks, and which one a prisoner receives is not predicted by their public visibility, IACHR protection status, or political affiliation. It is predicted, modestly but significantly, by the wave of protest during which they were arrested.

DATA SNAPSHOT: corpus of 1,172 prisoners with parseable charges, drawn from the Prisoners Defenders registry at the May 2026 snapshot. Subsequent registry versions carry different totals; all figures below refer to this specific snapshot and are archived alongside the analysis scripts.
1,172
Prisoners with
parseable charges
75
Distinct criminal
charges in corpus
0.47
Modularity Q at the
recovered partition
9
Pipeline stages
fully reproducible
§ 1 · The finding

Cuba does not charge all protesters the same way. There are two distinct playbooks.

The Prisoners Defenders registry is the most comprehensive public record of Cuban political detention. We encoded every record into a formal knowledge graph and measured which charges tend to appear together across the entire population. Two clusters emerged. The government applies one set of charges to some protesters and a completely different charge to others. The two groups almost never overlap.

Playbook A
The four-charge bundle
Contempt + Public Disorder + Assault + Resistance. These four charges appear together 2.8 to 3.4 times above chance. The state applies them as a package, not individually. The bundle functions to multiply sentence exposure through charge stacking.
Typical sentence: 5 to 7 years
Playbook B
Sedition, standing alone
Sedición is charged in isolation 90% of the time. A single, heavy charge whose function is characterization: to establish on the public record that the defendant is an enemy of the constitutional order, not merely a disorderly citizen.
Typical sentence: 10 to 14 years
§ 2 · The falsification

The natural assumption is wrong.

The obvious hypothesis: Cuba assigns the harsher playbook to prisoners who are more visible, more connected, or more politically organized. A well-known dissident gets the heavier charge. An unknown protester gets the lighter bundle. We tested this. It is wrong.

Hypothesis we tested Result What the data showed
Well-documented prisoners get the heavier charge NOT SUPPORTED 28.6% vs 29.5% (n.s.)
IACHR-protected prisoners get the heavier charge NOT SUPPORTED 25.0% vs 30.5%, direction reversed
Politically affiliated prisoners get the heavier charge NOT SUPPORTED No significant association
Arrested during July 11 protests ? heavier charge SIGNIFICANT OR = 1.42, p = 0.027
The playbook a prisoner receives is not predicted by their public visibility, their IACHR protection status, or their political affiliation. It is predicted, modestly but significantly, by the wave of protest during which they were arrested. Charges applied not on the basis of individual conduct but on the basis of participation in disfavored political activity is what WGAD Category II describes.
§ 3 · Independent validation

We asked a blind algorithm to check our work. It found the same two playbooks.

A natural objection: maybe the analyst drew the boundary between the two playbooks in the wrong place. So we ran a separate test. We gave a standard grouping algorithm (Louvain community detection) the raw charge co-occurrence data and told it nothing about our hypothesis. Find the natural groups yourself.

97.2%
Playbook A: algorithm agreed with analyst for 698 of 718 prisoners
98.0%
Playbook B: algorithm agreed with analyst for 196 of 200 prisoners
100/100
Partition stable across 100 random seeds at default resolution
90.2%
Sedición standalone: 194 of 215 prisoners had no other charges
Method Louvain community detection (Blondel et al. 2008) on the charge co-occurrence graph at default resolution (? = 1.0). Algorithm given no prior knowledge of the analyst-defined partition. Convergence tested across 100 random seeds and across a resolution sweep from ? = 0.3 to ? = 3.0. Full results in 09_community_detection_results.json; script: 09_community_detection.py.
§ 4 · The pipeline

Nine reproducible stages from raw HTML to formal submission.

Each stage is a separate Python script. Each script's output is saved and verifiable. Any reviewer can re-run any step against the same data snapshot and verify every number.

01
Scrape
Download records from PD
02
Parse
Clean and tokenize charges
03
Model
OWL 2 class hierarchy
04
Populate
Per-prisoner RDF facts
05
Check
SHACL validation
06
Enrich
Cross-source verify
07
Analyze
Statistical tests
08
Package
WGAD · IACHR · UPR
09
Validate
Louvain blind test
Standards OWL 2 / RDF / SKOS / BFO / PROV-O / SHACL. Every fact carries provenance to its source URL. 451 of 1,172 prisoners independently verified via cross-source enrichment against Amnesty International, IACHR, CubaLex, OCDH, and international media.
§ 5 · Methodology note

What the method measures, and what it does not.

This section exists for the technically skeptical reader. It states what the analysis actually measures, what its limits are, and how a reviewer can independently reproduce every step. Readers who accept the finding at face value can skip to §6.

Why co-occurrence is the right signal

A single prisoner's file tells you almost nothing about prosecutorial patterns. Any single charge is just a charge. Patterns become visible only by measuring which charges the state chooses to file together, across many cases, over and over. When the state pairs charge X with charge Y at a rate far above what independent selection would produce, that pairing is a prosecutorial decision. It is a fact about the state in its office of prosecutor, not about the underlying conduct of any one defendant.

We built a weighted undirected graph: nodes are charge types, edge weights are the number of prisoners charged with both. This graph is the primary analytical object. Every subsequent finding, from the two-playbook partition to the wave-based charge assignment, derives from measuring structure in this graph.

What Louvain and modularity actually measure

Modularity Q
A number between roughly −0.5 and 1 that measures how much denser the within-community edges are than would be expected under a random null model. Values above 0.3 are conventionally read as strong community structure. The recovered partition scored Q ? 0.47.
Louvain algorithm
A greedy modularity-maximizing partitioning algorithm (Blondel et al. 2008). Fast, well-studied, does not require the number of communities to be specified in advance. Standard tool for unsupervised community detection.
Resolution ?
A parameter controlling granularity: higher ? produces more, smaller communities; lower ? produces fewer, larger ones. We used the default (? = 1.0) and then swept ? from 0.3 to 3.0 as a stability check. The two-community partition was recovered at every resolution in the sweep, indicating the finding is not an artifact of parameter choice.
Stability check
Louvain is initialization-dependent. We ran it from 100 random seeds at ? = 1.0. All 100 converged on the same two-community partition. This is the "100/100" figure. It is a statement about the algorithm's behavior on this graph, not a proxy for accuracy on ground truth.

What "independent validation" here means, and what it does not

The 97.2% and 98.0% figures compare the algorithm-derived partition to the analyst-defined bundles (Contempt + Public Disorder + Assault + Resistance versus Sedición standalone). These are agreement rates.

They do not prove that the analyst-defined bundles are the correct doctrinal frame. They prove that an algorithm, given no prior knowledge, recovers the same partition the analyst drew from separate reasoning. When two independent methods converge on the same answer, the answer is more likely to be a feature of the data than an artifact of the analyst's framing. It is corroboration, not proof.

What we did not do

  • We did not perform causal inference. The wave-based association (July 11 ? heavier bundle, OR = 1.42, p = 0.027) is a descriptive finding. Causal claims about state intent require evidence beyond this dataset.
  • We did not analyze charges outside the canonical ChargeTypes. A subset of prisoners in the source data carry charges that were not normalized into the canonical type system; those cases were excluded from the community analysis. Coverage of the eight canonical ChargeTypes covers the great majority of political-persecution prosecutions in the corpus.
  • We did not evaluate individual case merits. This is a corpus-level structural analysis. It is not a substitute for per-prisoner legal review, and no prisoner in the dataset is worse off or better off in law because of anything measured here.
  • We did not measure sentence differentials counterfactually. The 5-to-7-year and 10-to-14-year figures are the observed sentence medians per bundle, not estimates of what any given defendant would have received had the state chosen the other bundle.
  • We did not read minds. The finding is that the state applies different charge bundles to different arrest waves. Why the state does this, and whether the choice is directed from the top or emerges from local prosecutorial discretion, is beyond the reach of any co-occurrence analysis.

Reproducibility

Every stage of the pipeline is a separate Python script whose input and output are versioned. A reviewer can rebuild the corpus from the source URLs, apply the same tokenization, generate the same RDF triples, and re-run Louvain at any seed. The corpus snapshot, the parsed charge atoms, the community assignments, and the statistical test outputs are archived in the repository. If any number in this report cannot be reproduced from the archived materials, that is a bug and we will fix it.

Extension in progress A follow-on project maps each Cuban ChargeType URI to the corresponding articles of the European Convention on Human Rights via a SKOS alignment graph, and retrieves the most doctrinally analogous Strasbourg judgments per Cuban prisoner. The retrieval prototype surfaces canonical Article 18 ulterior-purpose authorities (Kavala, Gusinskiy, Merabishvili, Navalnyy, Mammadov) for the majority of Cuban political prisoners in the corpus. This is being validated with human-rights lawyers before publication.
§ 6 · Legal framework

UDHR and customary international law. Not the ICCPR.

Cuba has signed but not ratified the International Covenant on Civil and Political Rights. Most submissions to the WGAD about Cuba cite the ICCPR. Those citations are technically moot. Every legal argument in this project routes through the Universal Declaration of Human Rights and customary international law per WGAD Deliberation No. 9.

Draft submissions to three international bodies are complete: the UN Working Group on Arbitrary Detention (Categories II and III), the Inter-American Commission on Human Rights (American Declaration Articles XVIII, XXV, XXVI), and a stakeholder submission for Cuba's Fifth Cycle Universal Periodic Review in 2028. Nine verified WGAD Cuba opinions (2021 to 2025) anchor the submissions, including Opinion 63/2021 which establishes the "recurrent pattern" language the two-playbook finding directly supports.

§ 7 · What this demonstrates

A proof of concept for a class of capability.

Unstructured public records, in this case a website of prisoner profiles, can be converted into a formal knowledge graph that reveals corpus-level patterns invisible in any individual file. The two-playbook finding does not exist in any one prisoner's record. It becomes visible only when the entire population is analyzed together under a formal schema. That is the core value of structural intelligence: the pattern is in the corpus, not in the case.

The same approach applies to any domain where public records exist but are not structured for analysis: corporate registries, court dockets, sanctions lists, offshore leaks, campaign-finance filings. If the pattern interests you, or if you work in a domain where this kind of analysis could be useful, I would welcome the conversation.