12 KiB
| title | type | status | date | origin |
|---|---|---|---|---|
| Overton Window Analysis: Improvements and Extensions | feat | active | 2026-05-26 | docs/plans/2026-05-25-001-overton-window-analysis-gaps-plan.md |
Overton Window Analysis: Improvements and Extensions
Summary
The current Overton window analysis is methodologically strong — multi-indicator, 2D extremity decomposition, causal timing, mechanism classification. But it has structural gaps that limit interpretability. This plan addresses six gaps: (1) right-wing party differentiation (PVV vs FVD vs JA21 vs SGP — who filed the motions?), (2) coalition coding fix (split 2024 into Rutte IV / Schoof periods), (3) voting margin analysis (the 96% ceiling makes pass rate useless — use actual voor/tegen percentages instead), (4) SVD temporal trajectory (plot the spatial drift over 10 annual windows), (5) mechanism classification validation (second classifier for inter-rater reliability), and (6) predictive modeling (what motion features predict centrist support?). Each unit is independent and can be executed in parallel.
Problem Frame
The synthesis report establishes that the Overton window did not shift right — right-wing parties moderated toward it. But the analysis treats right-wing parties as a bloc, uses a binary coalition coding that misattributes early 2024 motions, relies on pass rate as a success metric despite its 96% ceiling, and has no SVD visualization of the spatial drift. The mechanism classification (200 motions, single classifier) lacks inter-rater validation. Most critically, we have no predictive model: we can describe what happened but not what features predict which motions will gain centrist support.
Requirements
- R1. Break down centrist support, extremity, and mechanism patterns by right-wing party (PVV, FVD, JA21, SGP) to identify which party drives the moderation effect
- R2. Fix coalition coding by splitting 2024 into pre-Schoof (Rutte IV, Jan-Jun) and post-Schoof (Schoof, Jul-Dec) periods
- R3. Replace pass rate with voting margin analysis (actual voor/tegen percentages) as the primary success metric
- R4. Visualize SVD spatial drift over 10 annual windows showing centrist and right-wing trajectories
- R5. Validate mechanism classification with a second classifier and compute inter-rater reliability (Cohen's kappa)
- R6. Build a predictive model for centrist support using motion features (category, extremity scores, submitter party, mechanism, text features)
Scope Boundaries
- In scope: Quantitative analysis of existing data, new visualizations, predictive modeling
- Out of scope: Qualitative interviews, media analysis, public opinion data, international comparison
- Deferred: Cross-domain interaction analysis (migration × security), network/gateway motion analysis, submitter-level MP analysis
Key Technical Decisions
- Party differentiation: Use
voting_resultsJSON from motions table to extract per-party vote counts. Compute party-specific centrist support separately for PVV, FVD, JA21, SGP motions. - Coalition coding: Split 2024 at July 1, 2024 (Schoof cabinet formation). Motions dated before July 2024 use Rutte IV coalition; after use Schoof coalition.
- Voting margin: Compute
margin = (voor - tegen) / (voor + tegen + afwezig)per motion. This gives a continuous [-1, 1] scale instead of binary pass/fail. - SVD trajectory: Use existing
load_party_scores_all_windows_aligned()to get 2D positions for all parties across 10 windows. Plot as trajectory arrows. - Mechanism validation: Use a second LLM (different model or different prompt) to classify the same 200 motions. Compute Cohen's kappa.
- Predictive model: Use logistic regression or random forest with features: category, stijl_extremiteit, materiele_impact, submitter_party, mechanism, text_length, keyword_count.
Implementation Units
U1. Right-Wing Party Differentiation
Goal: Break down all key metrics by right-wing party to identify which party drives the moderation effect.
Requirements: R1
Dependencies: None
Files:
- Create:
analysis/right_wing/party_differentiation.py - Output:
reports/overton_window/party_differentiation.md - Output:
reports/overton_window/party_differentiation_figure.png
Approach:
- Parse
voting_resultsJSON from motions table to identify the submitter party for each right-wing motion - Compute per-party: motion volume, mean centrist_support, mean extremity (2D), mechanism distribution
- Stratify by period (pre vs post-2024)
- Test whether PVV's moderation is distinct from FVD/JA21/SGP
- Plot: 4-panel figure with (a) volume over time, (b) centrist support over time, (c) extremity over time, (d) mechanism distribution
Patterns to follow:
analysis/right_wing/overton_breakpoint_analysis.py— party-level analysis patternsanalysis/right_wing/classify_motions.py— submitter parsing from title
Test scenarios:
- Happy path: Script produces per-party metrics for PVV, FVD, JA21, SGP across all years
- Edge case: Multi-submitter motions (use first submitter)
- Edge case: Parties with <10 motions in a year → exclude from party-level analysis
Verification:
- Report contains per-party tables for volume, centrist support, extremity, mechanisms
- Figure shows whether moderation is PVV-specific or party-general
U2. Coalition Coding Fix
Goal: Split 2024 into pre-Schoof (Rutte IV) and post-Schoof (Schoof) periods to eliminate coalition coding ambiguity.
Requirements: R2
Dependencies: None
Files:
- Modify:
analysis/right_wing/overton_breakpoint_analysis.py(coalition coding logic) - Modify:
analysis/right_wing/temporal_trajectory.py(quarterly analysis) - Output: Updated reports with corrected coalition coding
Approach:
- Define coalition periods: Rutte IV (2022-Oct to 2024-Jul), Schoof (2024-Jul to present)
- Update
is_oppositionlogic to use motion date for period detection - Re-run opposition-only analysis with corrected coding
- Compare results with original binary coding
Patterns to follow:
analysis/right_wing/overton_breakpoint_analysis.py— existing coalition coding at line ~200
Test scenarios:
- Happy path: Opposition-only analysis shows corrected centrist support trajectory
- Edge case: Motions in July 2024 (transition month) → assign to Schoof
- Integration: Results should be consistent with temporal trajectory findings
Verification:
- Opposition-only centrist support trajectory is recalculated with corrected coding
- Report explicitly states the coding change and its impact on findings
U3. Voting Margin Analysis
Goal: Replace binary pass/fail with continuous voting margin as the primary success metric.
Requirements: R3
Dependencies: None
Files:
- Create:
analysis/right_wing/voting_margin.py - Output:
reports/overton_window/voting_margin.md - Output:
reports/overton_window/voting_margin_figure.png
Approach:
- Compute
margin = (voor - tegen) / (voor + tegen + afwezig)for each right-wing motion - Analyze margin distribution by centrist support quartile
- Test whether higher centrist support → higher margin (not just pass/fail)
- Stratify by period (pre vs post-2024)
- Plot: margin distribution by centrist support quartile, with period comparison
Patterns to follow:
analysis/right_wing/success_correlation.py— existing pass rate analysis
Test scenarios:
- Happy path: Script computes margins for all right-wing motions, produces distribution figure
- Edge case: Motions with 0 votes → exclude
- Edge case: Motions with unanimous support → margin = 1.0
Verification:
- Report contains margin distribution by centrist support quartile
- Figure shows whether centrist support predicts voting margin (continuous) better than pass rate (binary)
U4. SVD Temporal Trajectory Visualization
Goal: Visualize SVD spatial drift over 10 annual windows showing centrist and right-wing party trajectories.
Requirements: R4
Dependencies: None
Files:
- Create:
analysis/right_wing/svd_trajectory_viz.py - Output:
reports/overton_window/svd_trajectory_figure.png
Approach:
- Use
load_party_scores_all_windows_aligned()to get 2D positions for all parties across 10 windows - Plot: 2D compass with trajectory arrows for centrist parties (VVD, D66, CDA, NSC, BBB, CU) and right-wing parties (PVV, FVD, JA21, SGP)
- Color by party, arrow direction shows temporal progression
- Annotate windows with year labels
Patterns to follow:
analysis/right_wing/overton_svd_drift.py— existing SVD drift analysisexplorer.py— compass plotting with PARTY_COLOURS
Test scenarios:
- Happy path: Figure shows clear trajectory arrows for all parties
- Edge case: Missing party in a window → skip that arrow segment
Verification:
- Figure shows whether centrist parties moved left while right-wing parties moved right
- Trajectory arrows are clearly labeled with year markers
U5. Mechanism Classification Validation
Goal: Validate mechanism classification with a second classifier and compute inter-rater reliability.
Requirements: R5
Dependencies: None
Files:
- Create:
analysis/right_wing/mechanism_validation.py - Output:
reports/overton_window/mechanism_validation.md
Approach:
- Use a second LLM (different model or different prompt) to classify the same 200 motions
- Compute Cohen's kappa for inter-rater reliability
- Report disagreements and resolve them
- Update mechanism classification with validated results
Patterns to follow:
analysis/right_wing/mechanism_classification.py— existing classification
Test scenarios:
- Happy path: Second classifier produces classifications for all 200 motions
- Edge case: Disagreements → report and resolve
Verification:
- Report contains Cohen's kappa score
- Disagreements are documented and resolved
U6. Predictive Modeling
Goal: Build a predictive model for centrist support using motion features.
Requirements: R6
Dependencies: U1 (party differentiation), U3 (voting margin)
Files:
- Create:
analysis/right_wing/predictive_model.py - Output:
reports/overton_window/predictive_model.md - Output:
reports/overton_window/predictive_model_figure.png
Approach:
- Features: category, stijl_extremiteit, materiele_impact, submitter_party, mechanism, text_length, keyword_count
- Target: centrist_support (binary: >0.5 = high, <=0.5 = low)
- Models: logistic regression (interpretable), random forest (accuracy)
- Evaluate: accuracy, precision, recall, AUC-ROC
- Feature importance: which features best predict centrist support?
Patterns to follow:
analysis/right_wing/extremity_rescore_2d.py— batch processing patterns
Test scenarios:
- Happy path: Model achieves AUC-ROC > 0.7
- Edge case: Missing features → impute with median/mode
Verification:
- Report contains model performance metrics and feature importance
- Figure shows ROC curve and feature importance plot
System-Wide Impact
- No database changes: All analysis uses existing tables
- No UI changes: All outputs are markdown reports and PNG figures
- No agent_tools changes: Analysis scripts are standalone
- Reproducibility: All scripts are deterministic given the same database state
Risks & Dependencies
| Risk | Mitigation |
|---|---|
| Party differentiation may show PVV dominates everything | Report per-party sample sizes; exclude parties with <10 motions |
| Coalition coding fix may not change findings | Report both codings and compare |
| Voting margin may be correlated with pass rate | Compute correlation; if r>0.95, margin adds no value |
| SVD trajectory may be too cluttered | Use separate panels for centrist and right-wing |
| Mechanism validation may show low agreement | Report kappa; if <0.6, revise taxonomy |
| Predictive model may overfit | Use cross-validation; report train/test split |
Sources & References
- Current synthesis:
reports/overton_window/overton_window_synthesis.md - Temporal trajectory:
reports/overton_window/temporal_trajectory.md - Mechanism classification:
reports/overton_window/mechanism_classification.md - SVD drift:
analysis/right_wing/overton_svd_drift.py - Party positions:
analysis/explorer_data.py—load_party_scores_all_windows_aligned()