Skip to content

Integrate document analysis framework with all content generators#1238

Merged
pethers merged 6 commits intomainfrom
copilot/add-ai-powered-document-analysis-framework
Mar 16, 2026
Merged

Integrate document analysis framework with all content generators#1238
pethers merged 6 commits intomainfrom
copilot/add-ai-powered-document-analysis-framework

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 16, 2026

  • Add guards to avoid calling analyzeDocumentsForContent() when deep analysis will not render (doc count < 2 for standard types)
  • Localize framework-rendered strings in deep analysis (PESTLE labels, risk type/severity labels, implementation labels, fallback text)
  • Align stakeholder and risk renderer behavior/comments (higher-magnitude stakeholder dedupe, burden display, risk dedupe comment)
  • Fix implementation timeline consistency by selecting timeline from the assessment that determines worst feasibility
  • Run targeted tests (analysis-integration, data-transformers) and full suite (3730/3730 pass)
  • Run TypeScript check (tsconfig.scripts.json) with no errors
  • Capture UI screenshot for this change set: https://github.com/user-attachments/assets/50e058f5-d09c-4c19-82fa-602460a02c46
  • Reply to PR comment thread with commit hash and screenshot
Original prompt

This section details on the original issue you should resolve

<issue_title>AI-Powered Comprehensive Document Analysis Framework with Multi-Stakeholder Perspectives</issue_title>
<issue_description>## 📋 Issue Type
Feature / Architecture Enhancement

🎯 Objective

Create an AI-powered Comprehensive Document Analysis Framework that ensures every parliamentary document, government proposition, and policy paper is systematically analyzed from all stakeholders' perspectives using structured analytical techniques (SWOT, PESTLE, stakeholder mapping, impact assessment) with multiple AI iterations for depth and accuracy. This framework becomes the shared analytical backbone that all content generators and agentic workflows call for consistent, high-quality political analysis.

📊 Current State

  • No unified analysis framework: Each generator implements its own ad-hoc analysis approach
  • Document analysis is superficial: generateArticleContent() formats document metadata (title, type, date) — not the document's actual policy content
  • policy-analysis.ts: Contains detectPolicyDomains() (keyword matching), assessConfidenceLevel() (heuristic), detectNarrativeFrames() (pattern matching) — useful utilities but not AI-powered analysis
  • risk-analysis.ts: Contains calculateCoalitionRiskIndex() and detectAnomalousPatterns() — formula-based, not AI-analyzed
  • No stakeholder impact assessment: Documents analyzed for what they contain, not who they affect and how
  • No PESTLE analysis: Political, Economic, Social, Technological, Legal, Environmental dimensions not systematically assessed
  • No iterative refinement: Analysis done in single pass — initial observations never deepened through reflection

🚀 Desired State

Comprehensive Analysis Framework

Every document processed through the framework receives:

  1. Executive Summary: AI-generated 2-3 paragraph overview of the document's key provisions and significance
  2. Multi-Stakeholder Impact Assessment: For each stakeholder group, AI assesses:
    • Direct impact (positive/negative/neutral)
    • Indirect/secondary effects
    • Implementation burden
    • Political positioning implications
  3. SWOT Analysis per Stakeholder: AI generates SWOT for each affected group
  4. PESTLE Dimensions: AI assesses document through Political, Economic, Social, Technological, Legal, Environmental lenses
  5. Policy Domain Mapping: AI identifies all affected policy domains (replacing keyword matching)
  6. Coalition Dynamics Analysis: AI assesses how the document affects government-opposition dynamics
  7. Historical Context: AI connects to previous legislation and policy precedents
  8. Implementation Assessment: AI evaluates implementation feasibility, timeline, resource requirements
  9. Risk Assessment: AI identifies political, implementation, and public acceptance risks
  10. Confidence Scoring: Each analytical claim gets a confidence level with evidence references

Multi-Iteration Analysis Protocol

Iteration 1 (Generation): Initial analysis from document content
Iteration 2 (Deepening): Cross-reference with related documents, challenge assumptions
Iteration 3 (Stakeholder Review): Ensure all affected parties represented, check balance
Iteration 4 (Synthesis): Create unified narrative connecting all analytical dimensions

Stakeholder Universe (Dynamic Selection)

AI selects relevant stakeholders per document from this universe:

Stakeholder Group Sub-Groups When Relevant
Government Coalition M, KD, L (+ SD support) Always
Opposition Parties S, V, C, MP (individual positions) Always
State Agencies Myndigheter affected by policy When agencies mentioned
Municipalities/Regions SKR, local governments When local implementation required
Private Sector Affected industries, employers (Svenskt Näringsliv) When economic impact
Labor Market LO, TCO, Saco trade unions When employment/labor affected
Civil Society NGOs, citizens' organizations When civil rights/services affected
International/EU EU institutions, Nordic cooperation When international obligations
Media/Press Journalism, transparency, public access When transparency/FOI involved
Academia/Research Think tanks, universities When evidence/expertise relevant
Citizens/Voters General public, specific demographics Always (ultimate stakeholder)

🔧 Implementation Approach

Step 1: Create Core Analysis Framework

// New module: scripts/ai-analysis/document-analyzer.ts
interface DocumentAnalysis {
  executiveSummary: string;
  stakeholderImpacts: StakeholderImpact[];
  pestleDimensions: PESTLEAnalysis;
  policyDomains: PolicyDomain[];
  coalitionDynamics: CoalitionAnalysis;
  historicalContext: HistoricalContext;
  implementationAssessment: ImplementationAssessment;
  riskAssessment: RiskAssessment[];
  confidenceScor...

</details>


> **Custom agent used: intelligence-operative**
> Expert in political science, intelligence analysis, OSINT, behavioral analysis, and Swedish politics with focus on exposing high risk national entities



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes Hack23/riksdagsmonitor#1165

<!-- START COPILOT CODING AGENT TIPS -->
---

 Let Copilot coding agent [set things up for you](https://github.com/Hack23/riksdagsmonitor/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

@github-actions github-actions Bot added the size-xs Extra small change (< 10 lines) label Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🏷️ Automatic Labeling Summary

This PR has been automatically labeled based on the files changed and PR metadata.

Applied Labels: size-xs

Label Categories

  • 🗳️ Content: news, dashboard, visualization, intelligence
  • 💻 Technology: html-css, javascript, workflow, security
  • 📊 Data: cia-data, riksdag-data, data-pipeline, schema
  • 🌍 I18n: i18n, translation, rtl
  • 🔒 ISMS: isms, iso-27001, nist-csf, cis-controls
  • 🏗️ Infrastructure: ci-cd, deployment, performance, monitoring
  • 🔄 Quality: testing, accessibility, documentation, refactor
  • 🤖 AI: agent, skill, agentic-workflow

For more information, see .github/labeler.yml.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

- Extended DeepAnalysisOptions with optional frameworkAnalysis parameter
- Added analyzeDocumentsForContent() bridge function in shared.ts
- Added PESTLE, stakeholder impact, risk, and implementation section
  renderers when framework analysis is available
- Updated 6 content generators to pass framework analysis through
- Added 4 new localization keys across all 14 languages
- Fixed null safety in calculateCoalitionRiskIndex for partyPerformance
- All 3711 existing tests pass

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions Bot added refactor Code refactoring size-l Large change (250-1000 lines) labels Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

- Updated analyzeDocumentsForContent() to return both framework and
  perspective analyses (6 lenses: government, opposition, citizen,
  economic, international, media)
- Extended DeepAnalysisOptions with perspectiveAnalysis field
- Added perspective insights rendering to generateDeepAnalysisSection()
- Fixed null safety for partyPerformance in government and opposition lenses
- Updated all 6 content generators to pass both analysis results through
- Added 19 comprehensive integration tests covering:
  - Bridge function returns both analysis types
  - PESTLE, stakeholder, risk, and implementation section rendering
  - 6-lens perspective insights rendering
  - Multi-language label support (en, sv, de, ja, ar)
  - HTML escaping / XSS prevention
  - Graceful degradation without framework analysis
  - Confidence scoring and iteration metadata
- All 3730 tests pass (3711 existing + 19 new)

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions Bot added the testing Test coverage label Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

- Extracted 6 named constants (MAX_PESTLE_ITEMS, MAX_STAKEHOLDER_IMPACTS,
  MAX_RISK_ITEMS, MAX_PERSPECTIVE_INSIGHTS, MAX_IMPLEMENTATION_OBSTACLES,
  MAX_AGENCIES_DISPLAYED) for improved code maintainability
- Fixed test description to match actual validation (≥3 groups)
- Fixed CIAContext fixture to satisfy strict type checking
- All 3730 tests pass, TypeScript compiles cleanly

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copilot AI changed the title [WIP] Add AI-powered comprehensive document analysis framework Integrate document analysis framework with all content generators Mar 16, 2026
Copilot AI requested a review from pethers March 16, 2026 21:00
@pethers pethers marked this pull request as ready for review March 16, 2026 21:08
Copilot AI review requested due to automatic review settings March 16, 2026 21:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR connects the existing AI document analysis framework and 6-lens perspective analysis framework to all article content generators, so deep analysis sections can be enriched with structured PESTLE, stakeholder impact, risk, implementation, and perspective insights.

Changes:

  • Added a shared bridge (analyzeDocumentsForContent()) and extended deep-analysis rendering to accept optional framework + perspective analysis inputs.
  • Updated all relevant content generators to call the bridge and pass analyses through to generateDeepAnalysisSection().
  • Expanded localization labels and added integration tests; also fixed null-safety around cia.partyPerformance.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
tests/analysis-integration.test.ts New integration coverage for bridge + enriched deep analysis rendering and localization.
scripts/types/content.ts Extends ContentLabelSet with new deep-analysis framework label keys.
scripts/data-transformers/risk-analysis.ts Null-safe guard for partyPerformance in coalition risk calculation.
scripts/data-transformers/content-generators/week-ahead.ts Uses bridge + passes framework/perspective analyses into deep analysis section.
scripts/data-transformers/content-generators/shared.ts Introduces bridge + extends generateDeepAnalysisSection() to render framework and 6-lens insights.
scripts/data-transformers/content-generators/propositions.ts Uses bridge + passes analyses into deep analysis rendering.
scripts/data-transformers/content-generators/motions.ts Uses bridge + passes analyses into deep analysis rendering.
scripts/data-transformers/content-generators/interpellations.ts Uses bridge + passes analyses into deep analysis rendering.
scripts/data-transformers/content-generators/index.ts Re-exports analyzeDocumentsForContent() from the generator barrel.
scripts/data-transformers/content-generators/generic.ts Uses bridge + passes analyses into deep analysis rendering.
scripts/data-transformers/content-generators/committee.ts Uses bridge + passes analyses into deep analysis rendering.
scripts/data-transformers/constants/content-labels-part1.ts Adds new framework label keys for part1 languages.
scripts/data-transformers/constants/content-labels-part2.ts Adds new framework label keys for part2 languages.
scripts/analysis-framework/lenses/opposition.ts Null-safe guard for cia.partyPerformance usage.
scripts/analysis-framework/lenses/government.ts Null-safe guard for cia.partyPerformance usage.

Comment on lines 266 to 275
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(allWeekDocs, lang, weekCia);
content += generateDeepAnalysisSection({
documents: allWeekDocs,
lang,
cia: weekCia,
articleType: 'week-ahead',
frameworkAnalysis,
perspectiveAnalysis,
});

Comment on lines +937 to +941
const top = [...byType.values()].slice(0, MAX_RISK_ITEMS);
const rows = top.map(r => {
const icon = r.severity === 'high' ? '🔴' : r.severity === 'medium' ? '🟡' : '🟢';
return ` <li>${icon} <strong>${escapeHtml(r.type)}</strong> (${escapeHtml(r.severity)}): ${escapeHtml(r.description)}</li>`;
});
Comment on lines +892 to +905
* Render a summary of stakeholder impacts across all analysed documents.
* Shows up to 7 stakeholder groups with their impact direction and burden.
*/
function renderStakeholderImpactSummary(analyses: DocumentAnalysis[]): string {
// Collect all stakeholder impacts, deduplicated by stakeholder name
const impactMap = new Map<string, StakeholderImpact>();
for (const a of analyses) {
for (const impact of a.stakeholderImpacts) {
// Keep the first (or higher-magnitude) impact per stakeholder
const existing = impactMap.get(impact.stakeholder);
if (!existing) {
impactMap.set(impact.stakeholder, impact);
}
}
Comment on lines +971 to +982
const parts: string[] = [];
const fIcon = highestFeasibility === 'high' ? '🟢' : highestFeasibility === 'medium' ? '🟡' : '🔴';
parts.push(` <p>${fIcon} <strong>Feasibility:</strong> ${escapeHtml(highestFeasibility)}. ${escapeHtml(assessments[0].estimatedTimeline)}</p>`);

if (allObstacles.size > 0) {
const obstacleList = [...allObstacles].slice(0, MAX_IMPLEMENTATION_OBSTACLES).map(o => `<li>${escapeHtml(o)}</li>`).join('');
parts.push(` <p><strong>Key obstacles:</strong></p>\n <ul>${obstacleList}</ul>`);
}

if (allAgencies.size > 0) {
parts.push(` <p><strong>Agencies involved:</strong> ${[...allAgencies].slice(0, MAX_AGENCIES_DISPLAYED).map(a => escapeHtml(a)).join(', ')}</p>`);
}
Comment on lines 159 to 167
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(propositions, lang, data.ciaContext);
content += generateDeepAnalysisSection({
documents: propositions,
lang,
cia: data.ciaContext,
articleType: 'propositions',
frameworkAnalysis,
perspectiveAnalysis,
});
Comment on lines +908 to +910
const impacts = [...impactMap.values()].slice(0, MAX_STAKEHOLDER_IMPACTS);
if (impacts.length === 0) return ' <p>No stakeholder impact data available.</p>';

Comment on lines +923 to +935
/**
* Render a risk assessment summary. Groups risks by type and shows up to 5.
*/
function renderRiskAssessment(risks: RiskAssessment[]): string {
// Deduplicate by type+severity, preferring higher severity
const byType = new Map<string, RiskAssessment>();
for (const r of risks) {
const key = r.type;
const existing = byType.get(key);
if (!existing || severityRank(r.severity) > severityRank(existing.severity)) {
byType.set(key, r);
}
}
Comment on lines +962 to +973

for (const ia of assessments) {
ia.keyObstacles.forEach(o => allObstacles.add(o));
ia.agenciesInvolved.forEach(a => allAgencies.add(a));
if (feasibilityRank(ia.feasibility) < feasibilityRank(highestFeasibility)) {
highestFeasibility = ia.feasibility;
}
}

const parts: string[] = [];
const fIcon = highestFeasibility === 'high' ? '🟢' : highestFeasibility === 'medium' ? '🟡' : '🔴';
parts.push(` <p>${fIcon} <strong>Feasibility:</strong> ${escapeHtml(highestFeasibility)}. ${escapeHtml(assessments[0].estimatedTimeline)}</p>`);
Comment on lines 130 to 138
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(motions, lang, data.ciaContext);
content += generateDeepAnalysisSection({
documents: motions,
lang,
cia: data.ciaContext,
articleType: 'motions',
frameworkAnalysis,
perspectiveAnalysis,
});
Comment on lines 89 to 97
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(interpellations, lang, data.ciaContext);
content += generateDeepAnalysisSection({
documents: interpellations,
lang,
cia: data.ciaContext,
articleType: 'interpellations',
frameworkAnalysis,
perspectiveAnalysis,
});
@pethers
Copy link
Copy Markdown
Member

pethers commented Mar 16, 2026

@copilot apply changes based on the comments in this thread

Copilot AI and others added 2 commits March 16, 2026 21:32
…nderers

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 16, 2026

@copilot apply changes based on the comments in this thread

Implemented the review-thread fixes in 881b7ff:

  • Guarded analyzeDocumentsForContent() calls in all affected generators so analysis is skipped when deep analysis won’t render (<2 docs for standard types).
  • Localized framework-rendered deep-analysis content (PESTLE labels, risk type/severity labels, implementation labels, fallback messages).
  • Updated stakeholder summary logic to prefer higher-magnitude impacts and include implementation burden in output.
  • Aligned risk dedupe comment/behavior and fixed implementation timeline selection to use the assessment that determines worst feasibility.

Screenshot of updated deep-analysis UI:
https://github.com/user-attachments/assets/50e058f5-d09c-4c19-82fa-602460a02c46

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@pethers pethers merged commit 1b08a72 into main Mar 16, 2026
15 checks passed
@pethers pethers deleted the copilot/add-ai-powered-document-analysis-framework branch March 16, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code refactoring size-l Large change (250-1000 lines) size-xs Extra small change (< 10 lines) testing Test coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants