Structured analytic techniques including ACH, SWOT, Devil's Advocacy, Red Team analysis for political intelligence
license
Apache-2.0
Intelligence Analysis Techniques Skill
🔴 AI FIRST Quality Principle
This skill MUST be applied with the AI FIRST principle: never accept first-pass quality. ALL analysis and content MUST go through minimum 2 complete iterations. After first pass, read ALL output back completely and systematically improve every section — strengthen evidence, deepen analysis, add specific citations, broaden perspectives. Spend ALL allocated time on real work. Single-pass output is NEVER acceptable. NO SHORTCUTS.
Purpose
This skill provides comprehensive structured analytic techniques (SATs) for intelligence analysis in the Riksdagsmonitor platform. It implements proven methodologies from the intelligence community to reduce cognitive bias, improve analytical rigor, and produce defensible intelligence assessments on Swedish political actors, parties, and democratic institutions.
When to Use This Skill
Apply this skill when:
✅ Analyzing complex political situations with multiple competing hypotheses
✅ Assessing coalition formation scenarios and government stability
✅ Evaluating politician behavior patterns and risk indicators
✅ Conducting strategic assessments of party positions
✅ Identifying analytical assumptions and challenging conventional wisdom
✅ Preparing high-confidence intelligence products for stakeholders
✅ Mitigating cognitive biases in analysis (confirmation bias, anchoring)
Do NOT use for:
❌ Simple data aggregation or reporting (use query tools instead)
❌ Situations requiring immediate answers without time for structured analysis
Structured Analytic Techniques Framework
CIA Platform Analytics Categories
graph TB
subgraph "Data Foundation"
A[OSINT Collection] --> B[Data Integration]
B --> C[Quality Validation]
end
subgraph "Structured Analytic Techniques"
C --> D[Decomposition & Visualization]
C --> E[Idea Generation]
C --> F[Hypothesis Generation & Testing]
C --> G[Scenarios & Indicators]
C --> H[Challenge Analysis]
end
subgraph "Technique Categories"
D --> D1[Key Assumptions Check]
D --> D2[Issue Redefinition]
E --> E1[Brainstorming]
E --> E2[Red Team Analysis]
F --> F1[Analysis of Competing Hypotheses]
F --> F2[Diagnostic Reasoning]
G --> G1[Alternative Futures]
G --> G2[Indicators Development]
H --> H1[Devil's Advocacy]
H --> H2[Team A/Team B]
end
subgraph "Intelligence Products"
D1 & D2 & E1 & E2 & F1 & F2 & G1 & G2 & H1 & H2 --> I[Risk Assessments]
I --> J[Political Scorecards]
I --> K[Coalition Analysis]
I --> L[Trend Reports]
end
style A fill:#e1f5ff
style F1 fill:#ffeb99
style H1 fill:#ffcccc
style I fill:#ccffcc
1. Analysis of Competing Hypotheses (ACH)
Purpose: Systematically evaluate multiple explanations to reduce confirmation bias and identify the most likely scenario.
When to Use:
Coalition formation predictions
Politician defection risk assessment
Party strategy interpretation
Policy position shifts
CIA Platform Application:
Example: Coalition Formation After 2022 Election
Question: Which coalition is most likely to form the government?
Hypotheses:
H1: Center-right coalition (M, KD, SD, L) - 176 seats
H2: Center-right minority (M, KD, L) with SD support - 116 + 73 external
H3: Center-left coalition (S, V, MP, C) - 159 seats (minority)
H4: Grand coalition (S, M, C) - 159 seats
H5: Sweden Democrats lead coalition (SD, M, KD) - 141 seats
Evidence Matrix:
-- Generate ACH Evidence Matrix from voting patterns and party statementsWITH party_alignment AS (
SELECT
p1.party as party_a,
p2.party as party_b,
COUNT(CASEWHEN p1.vote = p2.vote THEN1END) as agreement_votes,
COUNT(*) as total_votes,
ROUND(100.0*COUNT(CASEWHEN p1.vote = p2.vote THEN1END) /COUNT(*), 2) as alignment_percentage
FROM vote_data p1
JOIN vote_data p2 ON p1.ballot_id = p2.ballot_id AND p1.party < p2.party
WHERE p1.vote_date >='2022-09-11'-- Current parliamentAND p1.vote IN ('Ja', 'Nej')
AND p2.vote IN ('Ja', 'Nej')
GROUPBY p1.party, p2.party
)
SELECT*FROM party_alignment
WHERE alignment_percentage >70-- Strong alignment thresholdORDERBY alignment_percentage DESC;
ACH Implementation:
@ServicepublicclassCompetingHypothesesAnalyzer {
public ACHResult analyzeCoalitionFormation(List<Hypothesis> hypotheses, List<Evidence> evidence) {
// 1. Create evidence matrixACHMatrixmatrix=newACHMatrix(hypotheses, evidence);
// 2. Rate consistency of each evidence with each hypothesisfor (Hypothesis h : hypotheses) {
for (Evidence e : evidence) {
ConsistencyRatingrating= rateConsistency(h, e);
matrix.setCell(h, e, rating);
}
}
// 3. Calculate hypothesis scores
Map<Hypothesis, Double> scores = newHashMap<>();
for (Hypothesis h : hypotheses) {
doublescore= calculateHypothesisScore(matrix, h);
scores.put(h, score);
}
// 4. Rank hypotheses by diagnostic value
List<Hypothesis> rankedHypotheses = scores.entrySet().stream()
.sorted(Map.Entry.<Hypothesis, Double>comparingByValue().reversed())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// 5. Identify most diagnostic evidence
List<Evidence> diagnosticEvidence = identifyDiagnosticEvidence(matrix);
return ACHResult.builder()
.matrix(matrix)
.rankedHypotheses(rankedHypotheses)
.diagnosticEvidence(diagnosticEvidence)
.confidence(calculateConfidence(scores))
.build();
}
private ConsistencyRating rateConsistency(Hypothesis h, Evidence e) {
// Consistency scale:// CC (++): Consistent - expected if hypothesis is true// C (+): Somewhat consistent// N (neutral): Neither consistent nor inconsistent// I (-): Somewhat inconsistent// II (--): Inconsistent - would not expect if hypothesis is trueif (h.getName().equals("Center-right coalition") &&
e.getType().equals("VOTING_ALIGNMENT") &&
e.getParties().containsAll(Arrays.asList("M", "KD", "L"))) {
return ConsistencyRating.CONSISTENT;
}
// Additional logic for other hypothesis-evidence combinationsreturn ConsistencyRating.NEUTRAL;
}
privatedoublecalculateHypothesisScore(ACHMatrix matrix, Hypothesis h) {
// Score = sum of consistency ratings weighted by evidence credibilitydoublescore=0.0;
for (Evidence e : matrix.getEvidence()) {
ConsistencyRatingrating= matrix.getCell(h, e);
score += rating.getValue() * e.getCredibility();
}
return score;
}
}
ACH Output Example:
Evidence
H1
H2
H3
H4
H5
M-KD-L voting alignment >80%
++
++
--
+
+
SD explicitly supports M-led govt
++
++
--
--
+
S refuses SD cooperation
--
--
+
N
--
C rejects left-wing coalition
++
++
--
+
--
L historically opposed SD
N
+
N
N
--
Parliamentary math (176 seats)
++
+
--
N
--
TOTAL SCORE
+9
+7
-8
0
-4
Conclusion: H1 (Center-right coalition with SD) most consistent with evidence. Confidence: HIGH (80%).
2. SWOT Analysis
Purpose: Systematically assess Strengths, Weaknesses, Opportunities, and Threats for strategic planning.
CIA Platform Application:
Example: Party Strategic Assessment - Social Democrats (S)
-- Generate SWOT data from Riksdagsmonitor platform viewsWITH party_metrics AS (
SELECT
party,
AVG(total_days_served) as avg_experience_days,
AVG(percent_yes + percent_no) as avg_participation_rate,
COUNT(DISTINCT person_id) as party_size
FROM view_riksdagen_politician_summary
WHERE party ='S'GROUPBY party
),
party_performance AS (
SELECT
party,
AVG(percentage_won) as win_rate,
COUNT(DISTINCT ballot_id) as ballots_participated
FROM view_riksdagen_party_ballot_support_annual_summary
WHERE party ='S'AND election_year >=EXTRACT(YEARFROMCURRENT_DATE) -4GROUPBY party
),
coalition_potential AS (
SELECT'S'as party,
SUM(parliament_seats) as potential_coalition_seats
FROM sweden_political_party
WHERE party_name IN ('S', 'V', 'MP', 'C')
)
SELECT
pm.*,
pp.win_rate,
pp.ballots_participated,
cp.potential_coalition_seats
FROM party_metrics pm
JOIN party_performance pp ON pm.party = pp.party
CROSSJOIN coalition_potential cp;
═════════════════════════════════════════════════════════════
SWOT ANALYSIS: Social Democrats (S)
═════════════════════════════════════════════════════════════
STRENGTHS (Internal Positive)
─────────────────────────────────────────────────────────────
✅ Largest parliamentary party (107 seats, 30.6%)
✅ Extensive government experience (45 years total since 1970)
✅ High party discipline (96.3% voting cohesion)
✅ Strong union relationships and funding base
✅ Broad geographic support across all regions
WEAKNESSES (Internal Negative)
─────────────────────────────────────────────────────────────
❌ Declining electoral support (-3.2% since 2018)
❌ Leadership transition challenges
❌ Weak position on immigration issue (dominated by SD)
❌ Aging voter base (median age 58)
OPPORTUNITIES (External Positive)
─────────────────────────────────────────────────────────────
🔵 Coalition potential with V, MP, C = 159 seats (near majority)
🔵 Economic downturn favors welfare focus
🔵 Environmental policy increasingly salient
🔵 Potential to reclaim centrist voters from M
THREATS (External Negative)
─────────────────────────────────────────────────────────────
🔴 SD growth (20.5% in 2022, +3.1% from 2018)
🔴 Center-right coalition controls 176 seats
🔴 Fragmented left bloc (S, V, MP divergent priorities)
🔴 Policy space squeezed between left (V) and center (C)
═════════════════════════════════════════════════════════════
3. Devil's Advocacy
Purpose: Challenge prevailing assumptions by deliberately arguing against consensus position.
CIA Platform Application:
Example: Challenging Assumption of Coalition Stability
Prevailing View: "The center-right government is stable with 176 seats."
Devil's Advocate Position: "The coalition is actually fragile and may collapse within 18 months."
Challenging Arguments:
@ServicepublicclassDevilsAdvocacyAnalyzer {
public ChallengeAnalysis challengeCoalitionStability(String coalitionName) {
ChallengeAnalysisanalysis=newChallengeAnalysis();
analysis.setPrevailingView("Coalition is stable");
analysis.setChallengePosition("Coalition is fragile");
// 1. Identify hidden weaknesses
List<String> weaknesses = newArrayList<>();
// SQL: Check for voting defectionsStringsqlDefections="""
SELECT
p.party,
COUNT(CASE WHEN v.vote != modal_vote.mode THEN 1 END) as defection_count,
COUNT(*) as total_votes,
ROUND(100.0 * COUNT(CASE WHEN v.vote != modal_vote.mode THEN 1 END) / COUNT(*), 2) as defection_rate
FROM vote_data v
JOIN (
SELECT ballot_id, party, MODE() WITHIN GROUP (ORDER BY vote) as mode
FROM vote_data
GROUP BY ballot_id, party
) modal_vote ON v.ballot_id = modal_vote.ballot_id AND v.party = modal_vote.party
WHERE v.party IN ('M', 'KD', 'L')
AND v.vote_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY p.party
HAVING ROUND(100.0 * COUNT(CASE WHEN v.vote != modal_vote.mode THEN 1 END) / COUNT(*), 2) > 5.0
""";
List<PartyDisciplineMetric> defections = jdbcTemplate.query(sqlDefections,
(rs, rowNum) -> newPartyDisciplineMetric(
rs.getString("party"),
rs.getInt("defection_count"),
rs.getDouble("defection_rate")
)
);
for (PartyDisciplineMetric metric : defections) {
weaknesses.add(String.format(
"%s showing %d defections (%.2f%%) - indicates internal dissent",
metric.getParty(), metric.getDefectionCount(), metric.getDefectionRate()
));
}
// 2. Alternative interpretation of evidence
List<String> alternativeInterpretations = newArrayList<>();
// SQL: Check for close votes (thin majorities)StringsqlCloseVotes="""
SELECT
ballot_id,
ballot_label,
COUNT(CASE WHEN vote = 'Ja' THEN 1 END) as yes_votes,
COUNT(CASE WHEN vote = 'Nej' THEN 1 END) as no_votes,
ABS(COUNT(CASE WHEN vote = 'Ja' THEN 1 END) -
COUNT(CASE WHEN vote = 'Nej' THEN 1 END)) as vote_margin
FROM vote_data
WHERE vote_date >= CURRENT_DATE - INTERVAL '3 months'
AND vote IN ('Ja', 'Nej')
GROUP BY ballot_id, ballot_label
HAVING ABS(COUNT(CASE WHEN vote = 'Ja' THEN 1 END) -
COUNT(CASE WHEN vote = 'Nej' THEN 1 END)) < 10
ORDER BY vote_margin ASC
LIMIT 10
""";
List<CloseVote> closeVotes = jdbcTemplate.query(sqlCloseVotes,
(rs, rowNum) -> newCloseVote(
rs.getString("ballot_id"),
rs.getString("ballot_label"),
rs.getInt("vote_margin")
)
);
if (closeVotes.size() > 5) {
alternativeInterpretations.add(
String.format("Coalition has won %d ballots by <10 votes in last 3 months - " +
"indicates razor-thin majority vulnerable to defections", closeVotes.size())
);
}
// 3. Hypothetical scenarios that could invalidate prevailing view
List<String> invalidatingScenarios = newArrayList<>();
invalidatingScenarios.add("L party decides SD support is politically toxic, withdraws from coalition");
invalidatingScenarios.add("Internal M leadership challenge leads to policy shift away from SD cooperation");
invalidatingScenarios.add("SD makes excessive demands on immigration policy, causing L to defect");
invalidatingScenarios.add("Economic crisis requires unpopular budget cuts, fracturing coalition unity");
analysis.setIdentifiedWeaknesses(weaknesses);
analysis.setAlternativeInterpretations(alternativeInterpretations);
analysis.setInvalidatingScenarios(invalidatingScenarios);
return analysis;
}
}
Devil's Advocacy Output:
═════════════════════════════════════════════════════════════
DEVIL'S ADVOCACY: Coalition Stability Challenge
═════════════════════════════════════════════════════════════
PREVAILING VIEW: The center-right coalition is stable with 176 seats.
CHALLENGE POSITION: The coalition is actually fragile and may collapse.
HIDDEN WEAKNESSES:
─────────────────────────────────────────────────────────────
1. L showing 8 defections (6.2%) in last 6 months - internal dissent
2. M has 3 MPs with consistent voting against party line on SD-supported bills
3. KD unity high (98.1%) but only 19 MPs - vulnerable to single defection
ALTERNATIVE INTERPRETATIONS:
─────────────────────────────────────────────────────────────
1. Coalition won 12 ballots by <10 votes (razor-thin majority)
2. SD external support requires constant negotiation, creating friction
3. L party leadership under pressure from voters uncomfortable with SD ties
INVALIDATING SCENARIOS:
─────────────────────────────────────────────────────────────
1. L withdraws due to SD political toxicity (reduces coalition to 162 seats)
2. Economic crisis requires unpopular cuts, fracturing unity
3. SD demands on immigration exceed L tolerance, triggering defection
CONFIDENCE IN CHALLENGE: MEDIUM (60%)
═════════════════════════════════════════════════════════════
4. Red Team Analysis
Purpose: Simulate adversary behavior to identify vulnerabilities and blind spots.
CIA Platform Application:
Example: Opposition Party Strategy Against Government
Scenario: You are the opposition strategist (S party). How would you destabilize the center-right government?
@ServicepublicclassRedTeamAnalyzer {
public RedTeamReport simulateOppositionStrategy(String targetCoalition, String oppositionParty) {
RedTeamReportreport=newRedTeamReport();
report.setScenario("Opposition strategy to destabilize " + targetCoalition);
report.setRedTeamParty(oppositionParty);
// 1. Identify coalition vulnerabilities
List<Vulnerability> vulnerabilities = identifyCoalitionVulnerabilities(targetCoalition);
// 2. Develop exploitation strategies
List<Strategy> strategies = newArrayList<>();
// Strategy 1: Exploit ideological riftsif (vulnerabilities.stream().anyMatch(v -> v.getType() == VulnerabilityType.IDEOLOGICAL_SPLIT)) {
strategies.add(Strategy.builder()
.name("Wedge Issue Exploitation")
.description("Propose legislation that divides coalition on moral issues (e.g., immigration, LGBTQ+ rights)")
.implementation("File motion on asylum policy that forces L to choose between SD and principles")
.expectedOutcome("L votes with opposition, coalition loses vote, internal tensions rise")
.successProbability(0.65)
.build());
}
// Strategy 2: Target weak coalition membersif (vulnerabilities.stream().anyMatch(v -> v.getType() == VulnerabilityType.MEMBER_VULNERABILITY)) {
strategies.add(Strategy.builder()
.name("Individual MP Persuasion")
.description("Identify vulnerable MPs and offer political cover for defection")
.implementation("Private negotiations with L MPs facing local backlash over SD cooperation")
.expectedOutcome("1-2 MP defections, coalition loses majority")
.successProbability(0.35)
.build());
}
// Strategy 3: Force unpopular votesif (vulnerabilities.stream().anyMatch(v -> v.getType() == VulnerabilityType.UNPOPULAR_POLICY)) {
strategies.add(Strategy.builder()
.name("Force Unpopular Policy Votes")
.description("Demand votes on SD priorities that are unpopular with L voter base")
.implementation("Use interpellations to force government to defend SD positions")
.expectedOutcome("L public support declines, internal pressure to exit coalition")
.successProbability(0.55)
.build());
}
report.setVulnerabilities(vulnerabilities);
report.setStrategies(strategies);
return report;
}
private List<Vulnerability> identifyCoalitionVulnerabilities(String coalition) {
List<Vulnerability> vulnerabilities = newArrayList<>();
// SQL: Identify voting divergence between coalition partnersStringsql="""
WITH coalition_votes AS (
SELECT
ballot_id,
party,
MODE() WITHIN GROUP (ORDER BY vote) as party_position
FROM vote_data
WHERE party IN ('M', 'KD', 'L')
AND vote_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY ballot_id, party
)
SELECT
ballot_id,
COUNT(DISTINCT party_position) as position_count
FROM coalition_votes
GROUP BY ballot_id
HAVING COUNT(DISTINCT party_position) > 1
""";
IntegerdivergentVotes= jdbcTemplate.queryForObject(sql, Integer.class);
if (divergentVotes > 20) {
vulnerabilities.add(Vulnerability.builder()
.type(VulnerabilityType.IDEOLOGICAL_SPLIT)
.description("Coalition partners voted differently on " + divergentVotes + " ballots")
.severity(SeverityLevel.HIGH)
.build());
}
return vulnerabilities;
}
}
5. Key Assumptions Check
Purpose: Explicitly identify and challenge assumptions underlying analysis.
Example: Coalition Formation Assumptions
ASSUMPTION #1: "Party voting alignment predicts coalition likelihood"
├─ Validity: STRONG - Historical evidence supports (r=0.82)
├─ Dependency: Analysis depends heavily on this assumption
├─ Challenge: What if parties prioritize electoral positioning over ideology?
└─ Monitoring: Track voting alignment vs. public coalition statements
ASSUMPTION #2: "SD will support M-led government consistently"
├─ Validity: MODERATE - No formal coalition agreement
├─ Dependency: Critical for government majority
├─ Challenge: SD may withdraw support to gain concessions
└─ Monitoring: Count SD-government voting alignment monthly
ASSUMPTION #3: "No mid-term defections will occur"
├─ Validity: WEAK - Historical precedent exists (3 defections 2014-2018)
├─ Dependency: Coalition stability assumption based on this
├─ Challenge: Personal scandals or ideological conflicts could trigger defections
└─ Monitoring: Track individual MP voting patterns and public statements
6. Indicators Development
Purpose: Create observable metrics to validate or invalidate hypotheses.
Example: Government Collapse Indicators
-- Create Early Warning Indicators for Coalition CollapseCREATE MATERIALIZED VIEW coalition_stability_indicators ASWITH voting_discipline AS (
SELECT
party,
COUNT(CASEWHEN vote = modal_vote THEN1END)::decimal/COUNT(*) as discipline_rate,
DATE_TRUNC('month', vote_date) asmonthFROM vote_data v
JOIN (
SELECT ballot_id, party, MODE() WITHINGROUP (ORDERBY vote) as modal_vote
FROM vote_data
GROUPBY ballot_id, party
) mv ON v.ballot_id = mv.ballot_id AND v.party = mv.party
WHERE party IN ('M', 'KD', 'L')
AND vote_date >=CURRENT_DATE-INTERVAL'12 months'GROUPBY party, DATE_TRUNC('month', vote_date)
),
close_votes AS (
SELECT
DATE_TRUNC('month', vote_date) asmonth,
COUNT(*) as close_vote_count
FROM (
SELECT
ballot_id,
vote_date,
ABS(SUM(CASEWHEN vote ='Ja'THEN1WHEN vote ='Nej'THEN-1ELSE0END)) as margin
FROM vote_data
GROUPBY ballot_id, vote_date
) margins
WHERE margin <10GROUPBY DATE_TRUNC('month', vote_date)
),
interpellations AS (
SELECT
DATE_TRUNC('month', made_date) asmonth,
COUNT(*) as interpellation_count
FROM document_element
WHERE document_type ='ip'-- InterpellationsAND made_date >=CURRENT_DATE-INTERVAL'12 months'GROUPBY DATE_TRUNC('month', made_date)
)
SELECT
vd.month,
AVG(vd.discipline_rate) as avg_coalition_discipline,
cv.close_vote_count,
ip.interpellation_count,
CASEWHENAVG(vd.discipline_rate) <0.90THEN'🔴 CRITICAL'WHENAVG(vd.discipline_rate) <0.95THEN'🟠 WARNING'ELSE'🟢 STABLE'ENDas stability_status
FROM voting_discipline vd
LEFTJOIN close_votes cv ON vd.month = cv.month
LEFTJOIN interpellations ip ON vd.month = ip.month
GROUPBY vd.month, cv.close_vote_count, ip.interpellation_count
ORDERBY vd.month DESC;
ISMS Compliance Mapping
ISO 27001:2022 Controls
A.5.1 - Policies for Information Security
Structured analytic techniques documented and mandatory for intelligence products
Quality assurance processes for analytical rigor
A.5.7 - Threat Intelligence
Red Team analysis used to identify adversarial threats
Devil's Advocacy challenges assumptions in threat assessments
A.5.9 - Inventory of Information and Other Associated Assets
"Thinking, Fast and Slow" - Daniel Kahneman (Cognitive bias)
"Superforecasting" - Philip Tetlock (Probabilistic reasoning)
"Intelligence Analysis: A Target-Centric Approach" - Robert M. Clark
🔗 Integration with agentic workflows & analysis artifacts
This skill is consumed by the 11 agentic news workflows in .github/workflows/news-*.md. The authoritative contract lives in .github/prompts/README.md; this skill supplies domain expertise on top of that contract.
Required before any article: 9 core artifacts (14 for Tier-C) in analysis/daily/$ARTICLE_DATE/$SUBFOLDER/; 05-analysis-gate.md is the single blocking gate.