ARCHITECTURE.md

May 30, 2026 ยท View on GitHub

Hack23 Logo

๐Ÿ—๏ธ Riksdagsmonitor โ€” System Architecture

๐Ÿ“ C4 Architecture Model for Swedish Parliament Intelligence Platform
๐Ÿ›๏ธ Context, Container, Component & Dynamic Views

Owner Version Effective Date Review Cycle

๐Ÿ“‹ Document Owner: CEO | ๐Ÿ“„ Version: 2.6 | ๐Ÿ“… Last Updated: 2026-05-28 (UTC) ๐Ÿ”„ Review Cycle: Quarterly | โฐ Next Review: 2026-08-06
๐Ÿข Owner: Hack23 AB (Org.nr 5595347807) | ๐Ÿท๏ธ Classification: Public


๐Ÿ“š Architecture Documentation Map

DocumentFocusDescription
ARCHITECTURE.md โญ๐Ÿ›๏ธ C4 ModelsSystem structure, Context/Container/Component/Dynamic views
DATA_MODEL.md๐Ÿ“Š DataEntities, schemas, relationships
FLOWCHART.md๐Ÿ”„ ProcessesBusiness process and data flows
STATEDIAGRAM.md๐Ÿ”„ BehaviorSystem state transitions and lifecycles
MINDMAP.md๐Ÿง  ConceptsSystem conceptual relationships
SWOT.md๐Ÿ’ผ StrategyStrategic analysis and positioning
FUTURE_ARCHITECTURE.md๐Ÿš€ FutureArchitectural evolution roadmap
FUTURE_DATA_MODEL.md๐Ÿ“Š FutureEnhanced data architecture plans
FUTURE_FLOWCHART.md๐Ÿ”„ FutureImproved process workflows
FUTURE_STATEDIAGRAM.md๐Ÿ“ˆ FutureAdvanced state management
FUTURE_MINDMAP.md๐Ÿง  FutureCapability expansion plans
FUTURE_SWOT.md๐Ÿ’ผ FutureFuture strategic opportunities
SECURITY_ARCHITECTURE.md๐Ÿ›ก๏ธ SecuritySecurity controls and compliance
FUTURE_SECURITY_ARCHITECTURE.md๐Ÿš€ SecuritySecurity roadmap
THREAT_MODEL.md๐ŸŽฏ ThreatsSTRIDE analysis and risk assessment
WORKFLOWS.md๐Ÿ”ง DevOpsCI/CD automation and pipelines
CRA-ASSESSMENT.mdโš–๏ธ ComplianceEU Cyber Resilience Act conformity

๐Ÿ“‹ Documentation Portfolio Matrix (ISMS continuous-improvement)

This matrix is the canonical index of every Hack23-ISMS deliverable maintained at the repository root. It is the at-a-glance complement to the long-form drift inventory in analysis/audits/documentation-portfolio-audit-2026-05-03.md, which records observed drift, remediation in this PR, and follow-up backlog.

Authority for each row flows from the master Information_Security_Policy in Hack23 ISMS-PUBLIC; per-row ISMS authority cells link to the specific policy that mandates the document.

Current-state architecture & ISMS docs

#DocumentOwnerVersionLast reviewedReview cycleNext reviewISMS authority
1ARCHITECTURE.mdCEO2.52026-05-06Quarterly2026-08-06Secure_Development_Policy ยง4
2DATA_MODEL.mdCEO1.32026-05-06Annual2027-05-06CLASSIFICATION
3FLOWCHART.mdCEO1.22026-04-20Quarterly2026-07-20Secure_Development_Policy ยง6
4STATEDIAGRAM.mdCEO1.12026-04-20Quarterly2026-07-20Change_Management ยง5
5MINDMAP.mdCEO1.42026-05-03Quarterly2026-08-03Information_Security_Policy ยง5.5
6SWOT.mdCEO1.32026-05-03Quarterly2026-08-03Information_Security_Policy ยง3
7THREAT_MODEL.mdCEO/CISO1.22026-04-20Quarterly2026-07-20Threat_Modeling
8SECURITY_ARCHITECTURE.mdCEO/CISO2.32026-05-03Annual2027-05-03Secure_Development_Policy ยง10
9WORKFLOWS.mdCEO7.32026-05-02Quarterly2026-08-02Secure_Development_Policy ยง10.1

Future-state architecture docs

#DocumentOwnerVersionLast reviewedReview cycleNext reviewISMS authority
10FUTURE_ARCHITECTURE.mdCEO2.02026-02-24Quarterly2026-05-24Information_Security_Policy ยง5.5
11FUTURE_DATA_MODEL.mdCEO2.02026-02-24Quarterly2026-05-24CLASSIFICATION
12FUTURE_FLOWCHART.mdCEO2.02026-02-24Quarterly2026-05-24Secure_Development_Policy
13FUTURE_STATEDIAGRAM.mdCEO2.02026-02-24Quarterly2026-05-24Change_Management
14FUTURE_MINDMAP.mdCEO2.02026-02-24Quarterly2026-05-24Information_Security_Policy ยง5.5
15FUTURE_SWOT.mdCEO2.02026-02-24Quarterly2026-05-24Information_Security_Policy ยง5.5
16FUTURE_THREAT_MODEL.mdCEO/CISO1.02026-02-26Quarterly2026-05-26Threat_Modeling
17FUTURE_SECURITY_ARCHITECTURE.mdCEO/CISO2.02026-02-24Quarterly2026-05-24Secure_Development_Policy
18FUTURE_WORKFLOWS.mdCEO6.02026-05-02Quarterly2026-08-02Secure_Development_Policy ยง10

Operational ISMS deliverables

#DocumentOwnerVersionLast reviewedReview cycleNext reviewISMS authority
19BCPPlan.mdCEO1.22026-04-20Annual2027-04-20Incident_Response_Plan
20CRA-ASSESSMENT.mdCEO/CISO1.32026-04-20Annual2027-04-20Open_Source_Policy, Vulnerability_Management
21End-of-Life-Strategy.mdCEO1.42026-04-20Annual2027-04-20Information_Security_Policy
22FinancialSecurityPlan.mdCEO1.22026-04-20Annual2027-04-20Information_Security_Policy
23RELEASE_PROCESS.mdCEO1.02026-02-18Quarterly2026-05-18Change_Management, Secure_Development_Policy ยง10
24TESTING.mdCEO1.02026-02 (header only)Quarterly2026-05Secure_Development_Policy ยง7
25TRANSLATION_GUIDE.mdCEO1.02026-02-10Quarterly2026-05-10Information_Security_Policy ยง3
26SECURITY.mdCEO/CISO1.02026-02-20Annual2027-02-20Vulnerability_Management
27LABELS.mdCEO1.12026-05-03Annual2027-05-03Information_Security_Policy ยง3
28SKILLS.mdCEO(auto)2026-04-22Continuousn/aSecure_Development_Policy ยง4
29AGENTS.mdCEO(auto)continuousContinuousn/aAI_Policy
30Article-Generation.mdCEO(auto)continuousContinuousn/aAI_Policy ยง4

ISMS continuous-improvement evidence: This matrix + the drift-reconciliation changes in v2.3 satisfy the continuous-improvement clause of Information_Security_Policy ยง5.5. Observed drift is documented in the audit file, high-signal stale facts are corrected immediately, and a backlog is queued for the wholesale rewrites of long documents. Per-document footers can be added in a follow-up housekeeping PR; the canonical "last reviewed" stamp for every row above is the header badge block of the linked document.


Executive Summary

Riksdagsmonitor is a web application providing Swedish Parliament intelligence through interactive dashboards (Chart.js/D3.js) and CIA platform integration. Deployed on AWS CloudFront with multi-region S3 storage (us-east-1 primary, eu-west-1 replica) and GitHub Pages disaster recovery. This document describes the system architecture using the C4 model (Context, Container, Component, Dynamic), component interactions, data flows, and design decisions aligned with Hack23 AB's ISMS standards.


๐ŸŒ C4 System Context Diagram (Level 1)

The System Context diagram shows Riksdagsmonitor's place in its environment, including users, external systems, and key relationships.

System Boundaries and External Dependencies

graph TB
    subgraph "Users"
        Users[End Users<br/>Person<br/>Global citizens, journalists,<br/>researchers, policymakers]
    end
    
    subgraph "Riksdagsmonitor System"
        System[Riksdagsmonitor<br/>Software System<br/>Swedish Parliament Intelligence Platform<br/>Static website with interactive dashboards]
    end
    
    subgraph "External Systems"
        CIA[CIA Platform<br/>External System<br/>Political intelligence data processing<br/>www.hack23.com/cia]
        
        GitHub[GitHub<br/>External System<br/>Version control & hosting<br/>GitHub Pages, Actions]
        
        AWS[AWS Infrastructure<br/>External System<br/>CloudFront CDN + S3 Storage<br/>Global content delivery]
        
        Parliament[Swedish Parliament API<br/>External System<br/>Official legislative data<br/>data.riksdagen.se]
        
        Government[Regeringen<br/>External System<br/>Government documents<br/>via g0v.se]
    end
    
    Users -->|HTTPS/TLS 1.3<br/>Browse site, view dashboards| System
    System -->|External links<br/>Deep political analysis| CIA
    System -->|Hosted on<br/>DR hosting| GitHub
    System -->|Delivered via<br/>Primary CDN| AWS
    CIA -->|Fetches data from| Parliament
    CIA -->|Fetches data from| Government
    
    style Users fill:#e1f5ff,stroke:#0277bd,stroke-width:2px,color:#000000
    style System fill:#4caf50,stroke:#2e7d32,stroke-width:3px,color:#000000
    style CIA fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff
    style GitHub fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style AWS fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Parliament fill:#ffeb3b,stroke:#f57f17,stroke-width:2px,color:#000000
    style Government fill:#ffeb3b,stroke:#f57f17,stroke-width:2px,color:#000000

Context Relationships

Actor/SystemRelationshipPurpose
End Users โ†’ RiksdagsmonitorBrowse via HTTPSAccess Swedish Parliament intelligence, view interactive dashboards
Riksdagsmonitor โ†’ CIA PlatformExternal linksDeep political analysis, data visualization
Riksdagsmonitor โ†’ AWS CloudFrontCDN deliveryPrimary content delivery, 600+ global PoPs
Riksdagsmonitor โ†’ GitHub PagesDR hostingDisaster recovery standby, secondary deployment
CIA Platform โ†’ Swedish Parliament APIAPI callsFetch legislative data, voting records, documents
CIA Platform โ†’ RegeringenAPI calls via g0v.seGovernment documents, propositions, press releases

๐Ÿ›๏ธ C4 Container Diagram (Level 2)

The Container diagram zooms into Riksdagsmonitor to show major technical components (containers) and their interactions.

Technical Containers and Technology Choices

graph TB
    subgraph "User Layer"
        Users[End Users<br/>Global Audience]
        Browsers[Web Browsers<br/>Chrome, Safari, Firefox]
    end
    
    subgraph "Content Delivery Layer"
        Route53[AWS Route 53<br/>Container: DNS Service<br/>DNS + Health Checks + Failover]
        CF[AWS CloudFront<br/>Container: CDN<br/>600+ Edge Locations<br/>DDoS Protection]
        GHCDN[GitHub Pages CDN<br/>Container: DR CDN<br/>DR Standby]
    end
    
    subgraph "Application Layer - Riksdagsmonitor"
        Static[Static Website<br/>Container: Web Application<br/>HTML5/CSS3/JavaScript<br/>14 Languages]
        
        Dashboards[Interactive Dashboards<br/>Container: Client-Side App<br/>Chart.js v4.4.1, D3.js v7.9.0<br/>Papa Parse v5.5.3]
        
        NewsEngine[Agentic News Pipeline<br/>Container: gh-aw + Node 26 scripts<br/>23 artifacts โ†’ article.md โ†’ HTML]

        PIBuilder[scripts/political-intelligence/<br/>Container: PI Catalog &amp; Daily-Streams<br/>catalog.ts ยท daily-streams.ts<br/>i18n/ ยท render/]

        AgenticGate[scripts/agentic/<br/>Container: Analysis Gate &amp; Inventory<br/>analysis-gate.ts (checks 1โ€“9b)<br/>artifact-inventory.ts (23 artifacts, Aโ€“E)]

        DashCoalition[scripts/coalition-dashboard.ts<br/>+ coalition-dashboard/<br/>Container: Coalition Renderer]
        DashCommittees[scripts/committees-dashboard.ts<br/>+ committees-dashboard/<br/>Container: Committee Renderer]
        DashPolitician[politician-dashboard.html<br/>ร— 14 languages<br/>Container: Politician Renderer]
    end

    subgraph "TypeScript Data-Source Clients (no MCP)"
        IMFClient[scripts/imf-*.ts<br/>Datamapper JSON + SDMX 3.0]
        SCBClient[scripts/scb-*.ts<br/>PxWeb v2 client]
        WBClient[scripts/world-bank-*.ts<br/>WGI + WDI client]
        RiksbankClient[scripts/riksbank-fetch.ts<br/>Policy-rate + FX]
        StatskontoretClient[scripts/statskontoret-*.ts<br/>+ fetch-statskontoret.ts<br/>Myndighetsfรถrteckning + budget outturn]
        RiRClient[scripts/rir-followups-client.ts<br/>+ fetch-rir-followups.ts<br/>RiR follow-ups]
        ParliamentaryDL[scripts/parliamentary-data/<br/>+ download-parliamentary-data.ts<br/>+ fetch-voting-records.ts<br/>+ fetch-calendar.ts<br/>data-downloader ยท data-persistence ยท pdf-converter]
    end
    
    subgraph "Storage Layer"
        S3US[S3 us-east-1<br/>Container: Object Storage<br/>Primary Storage + Versioning]
        S3EU[S3 eu-west-1<br/>Container: Object Storage<br/>Replica Storage]
    end
    
    subgraph "Data Layer"
        DataFiles[CSV/JSON Files<br/>Container: Data Store<br/>Static data files]
    end
    
    subgraph "CI/CD Layer"
        Actions[GitHub Actions<br/>Container: CI/CD Pipeline<br/>Automated workflows<br/>Quality gates]
        GitHub[Git Repository<br/>Container: Version Control<br/>Source code + history]
    end
    
    Users --> Browsers
    Browsers -->|DNS Query| Route53
    Route53 -->|DNS Response: CF Primary| Browsers
    Route53 -.->|DNS Response: GHCDN on Failover| Browsers
    Browsers -->|HTTPS/TLS 1.3| CF
    Browsers -.->|HTTPS/TLS 1.3 (DR)| GHCDN
    CF -->|Origin| S3US
    CF -.->|Origin Failover on 500+ errors| S3EU
    S3US -.->|S3 CRR (Async, <15 min target)| S3EU
    CF --> Static
    GHCDN --> Static
    Static --> Dashboards
    Static --> DataFiles
    Dashboards -->|Parse CSV| DataFiles
    
    NewsEngine -->|Generates| Static
    NewsEngine -->|Commits to| GitHub
    NewsEngine -->|Gated by| AgenticGate
    NewsEngine -->|Catalog/streams from| PIBuilder
    NewsEngine -->|Fetches macro/fiscal| IMFClient
    NewsEngine -->|Fetches Swedish stats| SCBClient
    NewsEngine -->|Fetches governance| WBClient
    NewsEngine -->|Fetches policy rates| RiksbankClient
    NewsEngine -->|Fetches admin/budget| StatskontoretClient
    NewsEngine -->|Fetches audit follow-ups| RiRClient
    NewsEngine -->|Fetches votes/cal/docs| ParliamentaryDL
    PIBuilder --> Static
    DashCoalition --> Static
    DashCommittees --> Static
    DashPolitician --> Static
    
    GitHub --> Actions
    Actions -->|Deploy| S3US
    Actions -->|Deploy| GHCDN
    
    style Users fill:#e1f5ff,color:#000000
    style CF fill:#4caf50,color:#000000
    style S3US fill:#2196f3,color:#ffffff
    style S3EU fill:#64b5f6,color:#000000
    style GHCDN fill:#90caf9,color:#000000
    style Static fill:#81c784,color:#000000
    style Dashboards fill:#ff9800,color:#000000
    style NewsEngine fill:#9c27b0,color:#ffffff
    style PIBuilder fill:#7e57c2,color:#ffffff
    style AgenticGate fill:#5e35b1,color:#ffffff
    style IMFClient fill:#00897b,color:#ffffff
    style SCBClient fill:#00acc1,color:#ffffff
    style WBClient fill:#26a69a,color:#000000
    style RiksbankClient fill:#80cbc4,color:#000000
    style StatskontoretClient fill:#4db6ac,color:#000000
    style RiRClient fill:#80deea,color:#000000
    style ParliamentaryDL fill:#b2dfdb,color:#000000
    style DashCoalition fill:#ffb74d,color:#000000
    style DashCommittees fill:#ffb74d,color:#000000
    style DashPolitician fill:#ffb74d,color:#000000
    style GitHub fill:#ff6f00,color:#000000
    style Actions fill:#00bcd4,color:#000000

Container Responsibilities

ContainerTechnologyResponsibilityStatus
Static WebsiteHTML5/CSS3/JavaScriptPresent intelligence content, 14-language supportโœ… Active
Interactive DashboardsChart.js v4.4.1, D3.js v7.9.0, Papa Parse v5.5.3Data visualization, committee analysis, coalition trackingโœ… Active
Agentic News PipelineGitHub Agentic Workflows, Node 26 scripts, riksdag-regering MCP, SCB MCP, IMF TypeScript client23-artifact analysis, deterministic article aggregation, 14-language HTML renderingโœ… Active
AWS CloudFrontAWS CDNPrimary global content delivery, DDoS protectionโœ… Active
S3 us-east-1AWS S3Primary object storage with versioningโœ… Active
S3 eu-west-1AWS S3Replica storage with cross-region replicationโœ… Active
Route 53AWS DNSDNS resolution with health checks and failoverโœ… Active
GitHub Pages CDNGitHub CDNDisaster recovery hostingโœ… Standby
GitHub ActionsCI/CD automationBuild, test, deploy workflowsโœ… Active
Git RepositoryGitHubVersion control, source of truthโœ… Active
CSV/JSON FilesStatic dataDashboard data, workflow stateโœ… Active
scripts/political-intelligence/TypeScript (Node โ‰ฅ26)PI catalog, daily-streams index, i18n (artifact/methodology/page/stream/template), render leaves (daily-day, grid, page, style)โœ… Active
scripts/agentic/TypeScript (Node โ‰ฅ26)Analysis-gate (checks 1โ€“9b, PASS2_MTIME_THRESHOLD_MS = 180_000), typed ArtifactDefinition inventory of 23 artifacts (Families Aโ€“E), 76 vitest testsโœ… Active
IMF TS clientTypeScript (Node โ‰ฅ26)Datamapper JSON v1 + SDMX 3.0 transports for WEO, FM, IFS, MFS, GFS_COFOG, DOTS โ€” not an MCP serverโœ… Active
SCB TS clientTypeScript (Node โ‰ฅ26)PxWeb v2 client for Statistics Sweden tables โ€” sibling pattern to IMF/WBโœ… Active
World Bank TS clientTypeScript (Node โ‰ฅ26)WGI / WDI client for governance + long-horizon social/education residueโœ… Active
Riksbank TS clientTypeScript (Node โ‰ฅ26)Policy-rate, FX, monetary series fetcherโœ… Active
Statskontoret TS clientTypeScript (Node โ‰ฅ26)Myndighetsfรถrteckning + ร…rsutfall + Mรฅnadsutfall download discovery and parsingโœ… Active
RiR TS clientTypeScript (Node โ‰ฅ26)Riksrevisionen audit follow-ups fetcherโœ… Active
parliamentary-data subdirTypeScript (Node โ‰ฅ26)data-downloader + data-persistence + pdf-converter primitives backing votes/calendar/document downloadsโœ… Active
Coalition DashboardTypeScript + Chart.js/D3scripts/coalition-dashboard.ts + coalition-dashboard/ โ€” coalition viability renderingโœ… Active
Committees DashboardTypeScript + Chart.js/D3scripts/committees-dashboard.ts + `committees-dashboard/$ โ€” \text{committee} \text{productivity} \text{rendering}โœ… \text{Active}
\text{Politician} \text{Dashboard}\text{Static} \text{HTML} \times 14 \text{langs}$politician-dashboard.html+politician-dashboard_.html` for SV, DA, NO, FI, DE, FR, ES, NL, AR, HE, JA, KO, ZHโœ… Active

๐Ÿงฉ C4 Component Diagram (Level 3)

The Component diagram zooms into containers to show their internal structure and key components.

Static Website Components

graph TD
    subgraph "HTML Pages"
        Index[index.html<br/>Component: Main Page<br/>English + lazy-loaded dashboards<br/>Vite ES modules]
        LangSV[index_sv.html<br/>Component: Swedish Page<br/>Coalition Dashboard]
        LangDA[index_da.html<br/>Component: Danish Page<br/>Coalition Dashboard]
        LangNO[index_no.html<br/>Component: Norwegian Page<br/>Coalition Dashboard]
        LangOther[10 other languages<br/>Component: Multi-language Pages<br/>fi, de, fr, es, nl, ar, he, ja, ko, zh]
    end
    
    subgraph "JavaScript Dashboards"
        InlineScript[risk-dashboard.js + anomaly-detection.js<br/>Component: Risk and Anomaly<br/>Lazy-loaded ESM modules]
        
        CommitteeDash[committees-dashboard.ts<br/>Component: Committee Analysis<br/>Committee performance and network]
        
        CoalitionDash[coalition-dashboard.ts<br/>Component: Coalition Analysis<br/>Coalition dynamics]
        
        ElectionDash[election-cycle.ts<br/>Component: Election Analysis<br/>Election-cycle tracking]
        
        Placeholders[5 Specialised Dashboards<br/>Component: Functional Dashboards<br/>Party, Seasonal, Pre-Election,<br/>Ministry, Politician<br/>Lazy-loaded ESM modules]
    end
    
    subgraph "Data Transformation"
        DataTransformers[data-transformers.js<br/>Component: Data Processing<br/>CSV parsing, data cleaning]
        
        HTMLUtils[html-utils.js<br/>Component: HTML Generation<br/>Template rendering, multi-language]
        
        NewsGen[aggregate-analysis.ts + render-articles.ts<br/>Component: Article Generation<br/>23 artifacts โ†’ article.md โ†’ 14-language HTML]
    end
    
    subgraph "Styling"
        CSS[styles.css<br/>Component: Styling<br/>107KB responsive design]
        Fonts[Google Fonts<br/>Component: Typography<br/>Inter, Orbitron]
    end
    
    subgraph ExtLibs["External Libraries (Hosted Locally)"]
        Chart[Chart.js v4.4.1<br/>Component: Charting Library<br/>Hosted on CloudFront/S3]
        ChartPlugin[chartjs-plugin-annotation v3.0.1<br/>Component: Chart Annotations<br/>Hosted on CloudFront/S3]
        ChartAdapter[chartjs-adapter-date-fns v3.0.0<br/>Component: Date Adapter<br/>Hosted on CloudFront/S3]
        D3[D3.js v7<br/>Component: Advanced Viz<br/>Hosted on CloudFront/S3]
        Papa[Papa Parse v5.5.3<br/>Component: CSV Parser<br/>Hosted on CloudFront/S3]
    end
    
    subgraph "Configuration"
        CNAME[CNAME<br/>Component: DNS Config<br/>riksdagsmonitor.com]
        Sitemap[sitemap.xml<br/>Component: SEO Config<br/>XML sitemap with 14-language hreflang]
        SitemapHtml[sitemap.html + sitemap_&lt;lang&gt;.html<br/>Component: Human-readable Sitemap<br/>14 localized pages, all articles date-sorted]
        Robots[robots.txt<br/>Component: Crawler Config<br/>SEO directives]
    end
    
    Index --> InlineScript
    Index --> CommitteeDash
    Index --> CoalitionDash
    Index --> ElectionDash
    Index --> Placeholders
    Index --> CSS
    
    LangSV --> CoalitionDash
    LangDA --> CoalitionDash
    LangNO --> CoalitionDash
    LangOther --> CoalitionDash
    
    InlineScript --> Chart
    InlineScript --> D3
    CommitteeDash --> Chart
    CommitteeDash --> D3
    CoalitionDash --> Chart
    CoalitionDash --> D3
    ElectionDash --> Chart
    ElectionDash --> D3
    
    CommitteeDash --> Papa
    CoalitionDash --> Papa
    ElectionDash --> Papa
    
    NewsGen --> HTMLUtils
    NewsGen --> DataTransformers
    
    CSS --> Fonts
    
    style Index fill:#4caf50,color:#000000
    style InlineScript fill:#ff9800,color:#000000
    style CommitteeDash fill:#2196f3,color:#ffffff
    style CoalitionDash fill:#2196f3,color:#ffffff
    style ElectionDash fill:#2196f3,color:#ffffff
    style Placeholders fill:#4caf50,color:#000000
    style CSS fill:#00bcd4,color:#000000
    style Chart fill:#ff9800,color:#000000
    style D3 fill:#ff9800,color:#000000
    style NewsGen fill:#9c27b0,color:#ffffff

Component Details

HTML Pages (14 Languages)

  • index.html - English main page; lazy-loads all specialised dashboard modules
  • index_sv.html - Swedish version (coalition dashboard)
  • index_da.html - Danish version (coalition dashboard)
  • index_no.html - Norwegian version (coalition dashboard)
  • index_fi.html - Finnish version
  • index_de.html - German version
  • index_fr.html - French version
  • index_es.html - Spanish version
  • index_nl.html - Dutch version
  • index_ar.html - Arabic version (RTL)
  • index_he.html - Hebrew version (RTL)
  • index_ja.html - Japanese version
  • index_ko.html - Korean version
  • index_zh.html - Chinese version

Dashboard Components

All dashboards are functional TypeScript modules under src/browser/dashboards/, bundled by Vite and lazy-loaded on demand via an IntersectionObserver โ€” each module's import() fires only when its container scrolls into view. The homepage (src/browser/main.ts) registers 11 specialised dashboards; the CIA Intelligence Dashboard page (dashboard/index*.html) is orchestrated by src/browser/cia/dashboard-init.ts.

  1. risk-dashboard.ts / anomaly-detection.ts - Risk scoring and behavioural anomaly detection
  2. committees-dashboard.ts - Committee performance and network analysis
  3. coalition-dashboard.ts / coalition-loader.ts - Coalition dynamics tracking
  4. election-cycle.ts / pre-election.ts - Election-cycle and pre-election analysis
  5. party-dashboard.ts - Party performance analysis
  6. seasonal-patterns.ts - Seasonal activity patterns with Z-score anomaly detection
  7. ministry-dashboard.ts - Ministry performance analysis
  8. politician-dashboard.ts - Individual MP profiles and metrics

Scripts and Utilities

  • scripts/aggregate-analysis.ts - Recursively regenerates analysis/daily/**/article.md from analysis artifacts
  • scripts/render-articles.ts - Renders article.md / article.<lang>.md into sanitized news/*-{lang}.html files
  • scripts/render-lib/ - Shared Markdown sanitization, article chrome, JSON-LD, source appendix, language alternates, and aggregator ordering
  • src/browser/ - TypeScript dashboard modules compiled by Vite

๐Ÿ”„ C4 Dynamic Diagram

Dynamic diagrams show how components interact in specific scenarios.

Scenario 1: User Request Flow

sequenceDiagram
    participant User
    participant Browser
    participant DNS as Route 53 DNS
    participant CDN as AWS CloudFront
    participant S3 as S3 us-east-1
    participant CIA as CIA Platform
    
    User->>Browser: Visit riksdagsmonitor.com
    Browser->>DNS: Resolve domain
    DNS-->>Browser: CloudFront endpoint
    Browser->>CDN: HTTPS/TLS 1.3 request
    CDN->>S3: Fetch index.html
    S3-->>CDN: HTML content
    CDN-->>Browser: Render page (cached at edge)
    Browser->>CDN: Fetch styles.css
    CDN->>S3: Get CSS
    S3-->>CDN: CSS content (107KB)
    CDN-->>Browser: Apply styling
    Browser->>CDN: Fetch Chart.js, D3.js, Papa Parse
    CDN-->>Browser: JavaScript libraries
    Browser->>Browser: Initialize dashboards
    Browser->>CDN: Fetch CSV data files
    CDN-->>Browser: Committee data, coalition data
    Browser->>Browser: Render interactive charts
    
    Note over Browser,CIA: User clicks CIA link
    Browser->>CIA: Navigate to external dashboard
    CIA-->>Browser: Interactive political intelligence
    
    Note over Browser: Static content cached at edge
    Note over CDN: Edge caching active (600+ PoPs)

Scenario 2: CI/CD Deployment Flow

graph LR
    A[Developer Commit] --> B[Git Push to GitHub]
    B --> C[Trigger GitHub Actions]
    
    C --> D[Quality Checks Workflow]
    C --> E[Dependency Review Workflow]
    C --> F[Security Checks Workflow]
    
    D --> G{HTML Valid?}
    D --> H{Links OK?}
    E --> I{No Vulnerabilities?}
    F --> J{CodeQL Pass?}
    
    G -->|Yes| K[Quality Gate 1 Pass]
    G -->|No| L[Block Deployment โŒ]
    H -->|Yes| K
    H -->|No| L
    I -->|Yes| M[Quality Gate 2 Pass]
    I -->|No| L
    J -->|Yes| N[Security Gate Pass]
    J -->|No| L
    
    K --> O[All Gates Passed]
    M --> O
    N --> O
    
    O --> P[Merge to Main Branch]
    P --> Q[Dual Deploy Workflow]
    Q --> R[Deploy to S3 us-east-1]
    Q --> S[Deploy to GitHub Pages]
    R --> T[CloudFront Cache Invalidation]
    S --> U[GitHub Pages Update]
    T --> V[Live on riksdagsmonitor.com โœ…]
    U --> W[DR Standby Ready โœ…]
    
    style D fill:#4caf50,color:#000000
    style E fill:#ff9800,color:#000000
    style F fill:#f44336,color:#ffffff
    style L fill:#f44336,color:#fff
    style O fill:#4caf50,color:#000000
    style V fill:#4caf50,color:#fff
    style W fill:#2196f3,color:#fff

Scenario 3: Nightly News Generation Flow

sequenceDiagram
    participant Cron as GitHub Actions Cron
    participant NewsGen as gh-aw news workflow
    participant MCP as riksdag-regering-mcp
    participant SCB as scb-mcp
    participant IMF as imf-ts-client
    participant State as workflow-state.json
    participant Git as Git Repository
    participant CI as GitHub Actions CI/CD
    
    Cron->>NewsGen: Trigger at 18:00 UTC (Evening Analysis)
    NewsGen->>State: Read last execution state
    State-->>NewsGen: Last article timestamp, recent topics
    
    NewsGen->>MCP: Query 1: Latest Riksdag documents (today)
    MCP-->>NewsGen: Motions, propositions, interpellations
    
    NewsGen->>MCP: Query 2: Latest votes (today)
    MCP-->>NewsGen: Voting records, party positions
    
    NewsGen->>MCP: Query 3: Government documents (today)
    MCP-->>NewsGen: Press releases, announcements
    
    NewsGen->>MCP: Query 4: Parliamentary calendar (tomorrow)
    MCP-->>NewsGen: Upcoming debates, votes
    
    NewsGen->>SCB: Query 5: Statistical context (optional)
    SCB-->>NewsGen: Economic indicators (unemployment, GDP, etc.)
    Note over NewsGen,SCB: SCB enrichment is optional โ€” failures do not block article generation
    
    NewsGen->>IMF: Query 6: Macro/fiscal freshness + projections (optional)
    IMF-->>NewsGen: WEO / Fiscal Monitor / IFS (2025 finals + projections to 2031)
    Note over NewsGen,IMF: IMF via pure-TS `scripts/imf-client.ts` invoked by the bash tool (no MCP);<br/>optional enrichment โ€” graceful fallback to cached `analysis/data/imf/` on failure
    
    NewsGen->>NewsGen: Produce 23 analysis artifacts + per-document files
    Note over NewsGen: AI-FIRST Pass 1 + Pass 2; no article before the analysis gate passes
    
    NewsGen->>NewsGen: Aggregate article.md and render HTML
    Note over NewsGen: aggregate-analysis.ts creates article.md; render-articles.ts emits en/sv immediately and all 14 languages during full regeneration
    
    NewsGen->>State: Update workflow state
    State-->>NewsGen: State saved (deduplication cache)
    
    NewsGen->>Git: Open safe-output PR with artifacts, article.md, and HTML
    Git->>CI: Trigger deployment workflow
    CI->>CI: Run quality checks
    CI->>S3: Deploy to CloudFront
    CI->>Pages: Deploy to GitHub Pages
    
    Note over NewsGen,Pages: Articles live in <2 minutes

๐Ÿ“š Architecture Layers

Layer 1: ๐Ÿ–ฅ๏ธ Presentation Layer

Purpose: User interface and client-side rendering

Technologies:

  • HTML5 - Semantic markup, 14-language support with proper lang attributes
  • CSS3 - 107KB responsive design, CSS Grid, Flexbox
  • JavaScript ES6+ - Modern browser features, async/await
  • Chart.js v4.4.1 - Data visualization library
  • chartjs-plugin-annotation v3.0.1 - Chart annotation plugin
  • chartjs-adapter-date-fns v3.0.0 - Time-series date adapter
  • D3.js v7 - Advanced interactive visualizations
  • Papa Parse v5.5.3 - CSV parsing for dashboard data
  • Google Fonts - Inter and Orbitron typography

Responsibilities:

  • Render HTML pages in 14 languages
  • Display interactive dashboards with Chart.js and D3.js
  • Parse CSV data files with Papa Parse
  • Apply responsive CSS styling
  • Handle user interactions (clicks, navigation)

Layer 2: ๐Ÿ“Š Data Layer

Purpose: Data storage and retrieval

Technologies:

  • CSV data files (committee data, coalition data, election data)
  • JSON configuration files (workflow-state.json)
  • Papa Parse v5.5.3 (client-side CSV parsing)
  • Git version control (immutable history)

Responsibilities:

  • Store dashboard data in CSV format
  • Maintain workflow state in JSON
  • Provide data to dashboards via client-side parsing
  • Track data versions through Git commits

Layer 3: ๐Ÿ”Œ Integration Layer

Purpose: External system integration

Technologies:

  • CIA Platform - External intelligence system (www.hack23.com/cia)
  • riksdag-regering-mcp - MCP server for political data (32 tools)
  • GitHub API - Repository management
  • Swedish Parliament API - Legislative data (data.riksdagen.se)
  • Regeringen API - Government documents (via g0v.se)

Responsibilities:

  • Link to CIA Platform for deep analysis
  • Query riksdag-regering-mcp for news generation
  • Fetch data from Swedish Parliament API (via CIA Platform)
  • Access government documents (via g0v.se)

Layer 4: ๐Ÿ”’ Security Layer

Purpose: Application security and compliance

Technologies:

  • Content Security Policy (CSP) - XSS prevention
  • Subresource Integrity (SRI) - Supply chain security for JS libraries
  • SLSA Build Attestations - Build provenance
  • GitHub OIDC - Keyless authentication for deployments
  • Dependabot - Automated dependency updates
  • CodeQL - Static application security testing (SAST)
  • Secret Scanning - Credential leak detection

Responsibilities:

  • Enforce CSP headers to prevent XSS attacks
  • Validate JS library integrity with SRI hashes
  • Generate SLSA attestations for builds
  • Authenticate deployments with OIDC tokens
  • Scan dependencies for vulnerabilities
  • Detect secrets in code

See: SECURITY_ARCHITECTURE.md for complete security controls

Layer 5: ๐Ÿ“ˆ Monitoring Layer

Purpose: Observability and operational monitoring

Technologies:

  • GitHub Actions Workflow Metrics - Build/deploy success rates
  • AWS CloudWatch - CDN and S3 metrics
  • HTMLHint - HTML validation
  • Linkinator v6 - Link integrity checking
  • Dependabot Alerts - Vulnerability notifications
  • CodeQL Alerts - Security finding notifications

Responsibilities:

  • Track workflow execution status
  • Monitor CloudFront cache hit rates
  • Validate HTML quality
  • Check link integrity
  • Alert on security findings
  • Report deployment failures

Layer 6: ๐Ÿš€ CI/CD Layer

Purpose: Build, test, and deployment automation

Technologies:

  • GitHub Actions - CI/CD orchestration
  • Vite - Build tool for optimized assets
  • HTMLHint - HTML quality validation
  • Linkinator v6 - Link checking
  • npm - Package management
  • AWS CLI - S3/CloudFront deployment
  • GitHub Pages - DR deployment

Responsibilities:

  • Run automated tests on every push
  • Validate HTML and check links
  • Build optimized production assets
  • Deploy to S3 and CloudFront (primary)
  • Deploy to GitHub Pages (DR)
  • Invalidate CDN caches

๐Ÿญ Key Design Patterns

๐Ÿ“„ Static Site Generation Pattern

Description: Pure static HTML/CSS/JS with no server-side code execution

Benefits:

  • Minimal attack surface (no server-side vulnerabilities)
  • Maximum performance (edge caching)
  • High availability (easy replication)
  • Low operational complexity
  • Cost-effective hosting

Implementation:

  • All content pre-rendered at build time
  • JavaScript libraries hosted locally on CloudFront/S3
  • Client-side CSV parsing with Papa Parse
  • No dynamic backend dependencies

๐Ÿ“Š Data Pipeline Pattern

Description: Data flows from CIA Platform โ†’ CSV files โ†’ focused TypeScript loader modules โ†’ Chart.js/D3.js rendering

Components:

  1. Data Sources - CIA Platform aggregates from Swedish Parliament API
  2. Data Export - CSV files stored in repository (cia-data/)
  3. Source Inventory (src/browser/cia/sources.ts) - 26 CSV source URL definitions + Riksdag/committee constants, side-effect free
  4. Type Definitions (src/browser/cia/types.ts) - 30+ DTO interfaces consumed by both the loader and the renderer; visualization layer imports types here directly to avoid pulling in network code
  5. CSV Helpers (src/browser/cia/csv-utils.ts) - parseCSV / loadCSV / createLoadCSV free functions with local-first + remote fallback strategy
  6. Per-Domain Loaders (src/browser/cia/loaders/*.ts) - One file per dashboard domain (overview, election, parties, top10, committees, voting, ministries, demographics, documents, risk); each is a pure function (loadCSV) => Promise<T> that can be unit-tested in isolation
  7. Orchestrator (src/browser/cia/data-loader.ts) - CIADataLoader class wiring loaders together with a shared LoadCSV closure; preserves the historical public API for dashboard-init.ts and election-predictions.ts
  8. Visualization - Chart.js/D3.js render interactive dashboards from the typed payloads

Benefits:

  • Clear data lineage with bounded module responsibilities
  • Version-controlled data
  • Fast client-side rendering
  • No database required
  • Each loader is independently testable; types are importable without the HTTP client

๐ŸŒ Multi-Language Pattern

Description: 14 separate HTML files, one per language, with proper SEO

Languages: English (en), Swedish (sv), Danish (da), Norwegian (no), Finnish (fi), German (de), French (fr), Spanish (es), Dutch (nl), Arabic (ar, RTL), Hebrew (he, RTL), Japanese (ja), Korean (ko), Chinese (zh)

Implementation:

  • Each language has dedicated HTML file (e.g., index_sv.html)
  • Proper lang attribute on <html> tag
  • hreflang tags linking all 14 versions for SEO
  • RTL support (dir="rtl") for Arabic and Hebrew
  • Language switcher component in navigation

Benefits:

  • SEO-optimized URL structure
  • Clear language separation
  • No client-side translation (faster)
  • Better crawlability for search engines

๐Ÿ”’ Progressive Enhancement Pattern

Description: CSS-first design where JavaScript enriches but is not required

Layers:

  1. Base HTML - Semantic content, accessible without JS
  2. CSS Styling - Responsive design, visual hierarchy
  3. JavaScript Enhancement - Interactive dashboards, dynamic charts

Benefits:

  • Works without JavaScript (graceful degradation)
  • Better accessibility
  • Faster initial page load
  • SEO-friendly (content visible to crawlers)

๐Ÿ“ฐ Content Generation Pattern

Description: Automated news generation using riksdag-regering-mcp and AI agents

Workflow:

  1. Data Collection - riksdag-regering-mcp queries political data
  2. Analysis - intelligence-operative agent analyzes events
  3. Writing - Generate 5 editorial pillars (Lead, Pulse, Watch, Opposition, Ahead)
  4. Quality Validation - Check analytical depth, party coverage, sources
  5. Translation - Generate 14-language versions
  6. Publication - Commit HTML files, trigger deployment

Quality Metrics:

  • Analytical depth score โ‰ฅ 0.6
  • Party coverage โ‰ฅ 6 unique parties
  • Source citations โ‰ฅ 5 references
  • Historical context score โ‰ฅ 1.0
  • International comparison (60%+ of articles)

See: ยง5.3 News Generation Architecture for details

๐Ÿ” Dual Deployment Pattern

Description: AWS CloudFront (primary) + GitHub Pages (DR) with Route 53 failover

Architecture:

  • Primary: AWS CloudFront โ†’ S3 us-east-1 (with S3 eu-west-1 replica)
  • Secondary: GitHub Pages CDN โ†’ GitHub Pages hosting
  • Orchestration: Route 53 health checks with automatic failover

Failover Logic:

  1. Route 53 health check monitors CloudFront endpoint
  2. If CloudFront returns 5xx errors for >60 seconds
  3. Route 53 updates DNS to point to GitHub Pages
  4. GitHub Pages serves identical content
  5. When CloudFront recovers, Route 53 switches back

Benefits:

  • 99.9% availability (both AWS and GitHub have 99.9% SLA)
  • Geographic redundancy (AWS multi-region + GitHub global CDN)
  • Cost optimization (GitHub Pages free, AWS pay-as-you-go)
  • Disaster recovery (independent hosting platforms)

RTO: <5 minutes (DNS TTL + health check interval)
RPO: <2 minutes (dual deploy on every commit)


๐Ÿ“Š Data Architecture

Content Structure

graph LR
    subgraph "Content Types"
        HTML[HTML Pages<br/>14 Languages<br/>index.html + 13 translations]
        CSS[Stylesheets<br/>styles.css (107KB)<br/>Responsive Design]
        JS[JavaScript<br/>Dashboard scripts<br/>Chart.js, D3.js, Papa Parse]
        Data[Data Files<br/>CSV files<br/>Committee, coalition, election data]
        Images[Images<br/>Logos, icons<br/>SVG + PNG]
        Config[Configuration<br/>sitemap.xml, sitemap*.html, rss.xml, robots.txt, CNAME]
    end
    
    subgraph "Storage"
        Git[Git Repository<br/>Version Control<br/>Immutable History]
        S3[S3 Storage<br/>Primary: us-east-1<br/>Replica: eu-west-1]
        CDN[CloudFront CDN<br/>600+ Global PoPs<br/>Edge Caching]
    end
    
    HTML --> Git
    CSS --> Git
    JS --> Git
    Data --> Git
    Images --> Git
    Config --> Git
    
    Git --> S3
    S3 --> CDN
    
    style Git fill:#ff9800,color:#000000
    style S3 fill:#2196f3,color:#ffffff
    style CDN fill:#4caf50,color:#000000

Data Sources

SourceTypeUpdate FrequencyIntegrationRisk Level
Swedish ParliamentVotes, Documents, MPs, DebatesReal-timeCIA Platform โ†’ External LinksLOW
Election AuthorityElection Results, StatisticsPost-electionCIA Platform โ†’ External LinksLOW
Financial AuthorityBudget, Government SpendingMonthlyCIA Platform โ†’ External LinksLOW
World BankCountry Indicators, Economic DataQuarterlyCIA Platform โ†’ External LinksLOW
IMF (International Monetary Fund)WEO, Fiscal Monitor, IFS, MFS, GFS_COFOG โ€” macro, fiscal, monetary, external-sector indicators + T+5 projectionsWEO (Apr/Oct), Fiscal Monitor (Apr/Oct), IFS monthly, MFS monthlyPure-TypeScript client scripts/imf-client.ts (Datamapper JSON + SDMX 3.0) โ€” not an MCP server, invoked by agentic workflows via bashLOW
riksdag-regering-mcpAggregated Political DataOn-demandMCP Server (32 tools)LOW
SCB (Statistics Sweden)1,200+ statistical tables (economy, labour, population, education, environment)Varies (monthlyโ€“quarterly)MCP Server (scb-mcp, PxWebAPI 2.0)LOW

News Generation Architecture

5 Editorial Pillars Structure

The evening analysis follows a structured 5-pillar editorial format using OSINT/INTOP-driven political intelligence analysis:

graph TD
    subgraph "Evening Analysis Structure"
        Lead[1. Lead Story<br/>400-800 words<br/>Analytical thesis<br/>Sets tone for entire article]
        Pulse[2. Parliamentary Pulse<br/>200-400 words<br/>Legislative activity summary<br/>Votes, debates, committees]
        Watch[3. Government Watch<br/>200-300 words<br/>Executive actions<br/>Propositions, announcements]
        Opposition[4. Opposition Dynamics<br/>200-300 words<br/>Cross-party analysis<br/>Coalition tensions, strategies]
        Ahead[5. Looking Ahead<br/>100-200 words<br/>Tomorrow's preview<br/>Upcoming votes, debates]
    end
    
    Lead --> Pulse
    Pulse --> Watch
    Watch --> Opposition
    Opposition --> Ahead
    
    style Lead fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Pulse fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Watch fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Opposition fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff
    style Ahead fill:#00bcd4,stroke:#00838f,stroke-width:2px,color:#000000

Pillar Definitions:

  1. Lead Story (400-800 words)

    • Opening narrative establishing the day's main theme
    • Analytical thesis in lead paragraph
    • "Why this matters" context
    • Most significant development with implications
    • Sets tone for entire article
  2. Parliamentary Pulse (200-400 words)

    • Legislative body activity summary
    • Key votes and margins
    • Committee reports published
    • Debate highlights
    • Speeches and procedural actions
  3. Government Watch (200-300 words)

    • Executive branch monitoring
    • New propositions
    • Ministerial announcements
    • Policy changes
    • Regulatory actions
  4. Opposition Dynamics (200-300 words)

    • Cross-party political analysis
    • Opposition party strategies
    • Coalition tensions
    • Cross-party collaboration patterns
    • Political maneuvering
  5. Looking Ahead (100-200 words)

    • Forward-looking preview
    • Tomorrow's parliamentary calendar
    • Upcoming votes and debates
    • Expected announcements
    • "What to watch" guidance

Quality Metrics Schema

News articles are validated against comprehensive quality metrics:

DimensionMetricTargetMeasurement
Analytical DepthScore 0.0-1.0โ‰ฅ 0.6Causal, comparative, evaluative language markers
Historical ContextScore 0-3โ‰ฅ 1.0Historical references, trends, temporal comparisons
Party CoverageCountโ‰ฅ 6Unique party mentions across all 8 Riksdag parties
Source CitationsCountโ‰ฅ 5riksdag-regering-mcp tool usage, document references
International ComparisonBoolean60%+European/global context present
Structure CompletenessBoolean100%All 5 pillars present with minimum word counts

Quality Score Calculation:

  • Structure (30%): All pillars present + minimum word counts
  • Analytical depth (20%): Marker detection (because, therefore, however, etc.)
  • Historical context (15%): Temporal references (since, previously, compared to)
  • Sources (15%): Citation count from riksdag-regering-mcp queries
  • Party perspectives (10%): Coverage breadth across political spectrum
  • Forward-looking (5%): Preview content in "Looking Ahead" pillar
  • International comparison (5%): Global context and European benchmarking

Workflow State Management

Cross-workflow coordination prevents duplication and maintains quality:

graph LR
    subgraph "Workflow State"
        State[workflow-state.json<br/>Shared state file<br/>Git-tracked coordination]
        
        Evening[Evening Analysis<br/>18:00 UTC daily<br/>5-pillar structure]
        Realtime[Realtime Monitor<br/>Every 2 hours<br/>Breaking news]
        Generator[Article Generator<br/>05:51 UTC daily<br/>Morning briefing]
    end
    
    Evening -->|Write| State
    Realtime -->|Write| State
    Generator -->|Write| State
    
    State -->|Read| Evening
    State -->|Read| Realtime
    State -->|Read| Generator
    
    style State fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Evening fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Realtime fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Generator fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff

State File Schema (workflow-state.json):

{
  "lastEveningAnalysis": "2026-02-20T18:00:00Z",
  "realtimeArticlesSinceEvening": [
    {
      "timestamp": "2026-02-20T14:30:00Z",
      "topic": "Budget vote",
      "keywords": ["budget", "vote", "coalition"]
    }
  ],
  "mcpQueryCache": {
    "query": "latest riksdag documents",
    "timestamp": "2026-02-20T17:58:00Z",
    "ttl": 7200
  },
  "eveningAnalysisMetrics": {
    "avgAnalyticalDepth": 0.72,
    "avgPartyCoverage": 7.2,
    "avgSourceCitations": 6.5
  }
}

Deduplication Logic:

  1. Calculate text similarity (word overlap) between new and recent articles
  2. If similarity > 70%, synthesize but don't repeat verbatim content
  3. Reference earlier coverage, add deeper analysis layer
  4. Update workflow state after successful generation
  5. Clear stale cache entries (TTL: 2 hours for MCP queries)

Multi-Language Content Architecture

14-language support with consistent quality across all versions:

graph TB
    subgraph "Language Generation"
        Source[Agent Generation<br/>Claude Opus 4.8<br/>English source]
        
        Nordic[Nordic Languages<br/>en, sv, da, no, fi<br/>Germanic language family]
        EU[EU Core Languages<br/>de, fr, es, nl<br/>Western European]
        Global[Global Languages<br/>ar, he, ja, ko, zh<br/>Non-Latin scripts]
    end
    
    Source --> Nordic
    Source --> EU
    Source --> Global
    
    Nordic --> Validation[Quality Validation<br/>All 14 languages<br/>Consistent analytical depth ยฑ0.5]
    EU --> Validation
    Global --> Validation
    
    Validation --> Commit[Git Commit<br/>14 HTML files<br/>news/YYYY-MM-DD-evening-analysis*.html]
    
    style Source fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff
    style Nordic fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style EU fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Global fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Validation fill:#00bcd4,stroke:#00838f,stroke-width:2px,color:#000000

Language-Specific Requirements:

RequirementImplementationValidation
HTML lang attribute<html lang="sv"> for Swedish, etc.Automated check in CI
RTL support<html dir="rtl"> for Arabic and HebrewManual review
Hreflang tagsLink all 14 versions for SEOHTMLHint validation
Schema.org NewsArticleJSON-LD in each languageSchema.org validator
Culturally appropriate toneAgent-specific language instructionsEditor review
Consistent analytical depthTarget ยฑ0.5 on 1.0 scale across languagesAutomated quality scoring

File Naming Convention:

  • news/2026-02-20-evening-analysis-en.html (English)
  • news/2026-02-20-evening-analysis-sv.html (Swedish โ€” produced by the same workflow)
  • news/2026-02-20-evening-analysis-da.html (Danish โ€” produced by news-translate)
  • ... (11 more language variants, all from news-translate)

๐Ÿ” News Generation Pipeline Architecture

Aggregate โ†’ Render Module (scripts/aggregate-analysis.ts, scripts/render-articles.ts, scripts/render-lib/)

The news pipeline is a single-pass aggregate-then-render flow. There is no scaffold-and-fill, no template placeholders, and no per-type generator class. Every article is derived 100% from real analysis artifacts under analysis/daily/$DATE/$SUB/ plus the methodology + template files under analysis/methodologies/ and analysis/templates/.

C4 Component Diagram โ€” News Subsystem

graph TD
    subgraph "Inputs (single source of truth)"
        Methodologies[analysis/methodologies/<br/>Editorial method files<br/>Static, version-controlled]
        Templates[analysis/templates/<br/>Section templates<br/>Static, version-controlled]
        Daily[analysis/daily/$DATE/$SUB/<br/>Per-day analysis artifacts<br/>9 core or 14 Tier-C files]
    end

    subgraph "scripts/aggregate-analysis.ts"
        Aggregator[Aggregator<br/>Concatenates artifacts in fixed<br/>narrative order; strips dup H1s,<br/>front-matter, admin footers;<br/>rewrites relative links to GitHub blobs]
    end

    subgraph "scripts/render-articles.ts + scripts/render-lib/"
        Renderer[render-lib/markdown.ts<br/>unified ยท remark-parse ยท remark-gfm<br/>ยท remark-rehype ยท rehype-raw<br/>ยท rehype-sanitize ยท rehype-slug<br/>ยท rehype-autolink-headings<br/>ยท rehype-stringify]
        Chrome[render-lib/chrome.ts<br/>Pure string builder:<br/>header ยท footer ยท lang switcher<br/>SEO ยท hreflang ร— 14]
        Article[render-lib/article.ts<br/>Orchestrator: parses front-matter,<br/>builds JSON-LD NewsArticle,<br/>composes head+header+body+footer]
        Constants[render-lib/constants.ts +<br/>render-lib/url-helpers.ts<br/>Zero-dep leaves]
    end

    subgraph "Outputs"
        ArticleMd[article.md<br/>Canonical aggregated markdown]
        EnHtml[news/$DATE-$SUB-en.html]
        SvHtml[news/$DATE-$SUB-sv.html]
        Sitemap[sitemap.xml + sitemap.html]
        Rss[rss.xml]
        Pi[political-intelligence_*.html]
    end

    subgraph "Out-of-band"
        Translate[news-translate workflow<br/>EN+SV โ†’ 12 other languages<br/>Decoupled, never invoked here]
    end

    Methodologies --> Aggregator
    Templates --> Aggregator
    Daily --> Aggregator
    Aggregator --> ArticleMd
    ArticleMd --> Article
    Article --> Renderer
    Article --> Chrome
    Constants -.-> Aggregator
    Constants -.-> Chrome
    Constants -.-> Article
    Article --> EnHtml
    Article --> SvHtml
    EnHtml --> Sitemap
    SvHtml --> Sitemap
    EnHtml --> Rss
    EnHtml --> Pi
    EnHtml -.-> Translate
    SvHtml -.-> Translate

    style Aggregator fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Renderer fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Chrome fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Article fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff
    style Constants fill:#607d8b,stroke:#37474f,stroke-width:2px,color:#ffffff
    style Translate fill:#9e9e9e,stroke:#616161,stroke-width:2px,color:#ffffff

Pipeline Stages

The scripts/render-lib/ directory was split (Round-4) from a single 960-LOC monolith into 6 focused leaf modules linked by a thin barrel index.ts. Each leaf has a single responsibility and zero circular dependencies. Consumers (aggregate-analysis.ts, render-articles.ts, tests, analysis-references.ts) import from the barrel only โ€” the internal layout can evolve without breaking downstream code.

StageScript / ModuleResponsibility
aggregatescripts/aggregate-analysis.ts (CLI driver) โ†’ scripts/render-lib/aggregator.tsConcatenate per-day artifacts in canonical narrative order; emit article.md. Strips leading admin bylines, ## Pass 2 โ€ฆ self-audit sections, YAML front-matter, duplicated H1s, Document control / End of template footers. Rewrites relative links to absolute GitHub blob URLs.
render-mdscripts/render-lib/markdown.tsMarkdown โ†’ sanitised HTML via unified โ†’ remark-parse โ†’ remark-gfm โ†’ remark-rehype โ†’ rehype-raw โ†’ rehype-slug โ†’ rehype-autolink-headings โ†’ rehype-sanitize โ†’ rehype-stringify. The sanitiser schema (sanitizeSchema) is the single trust boundary between AI markdown and user HTML.
chromescripts/render-lib/chrome.tsPure string builder (no I/O, no async): emits <head> (SEO + OpenGraph + hreflang for all 14 languages), <header> (tagline logo + breadcrumb + dropdown language switcher), <footer> (3-column brand/navigate/trust + always-visible secondary language row).
articlescripts/render-lib/article.tsOrchestrator: parses front-matter, calls renderMarkdownToHtml, builds Schema.org NewsArticle JSON-LD, concatenates everything via buildChrome. The only module that imports both aggregator and markdown.
driverscripts/render-articles.ts (CLI driver)Walks analysis/daily/**/article.md, populates hreflangAlternates for all 14 supported languages so the chrome language-switcher always lands on a sibling article (not the language homepage), calls renderArticleHtml per (date, subfolder, lang) tuple.
constantsscripts/render-lib/constants.ts + scripts/render-lib/url-helpers.tsZero-dependency leaves: BASE_URL, GITHUB_BLOB, GITHUB_TREE, ROOT_DIR, ANALYSIS_DIR, METHODOLOGIES_DIR, TEMPLATES_DIR, DAILY_DIR, LANGUAGES, plus buildGithubBlobUrl / buildGithubTreeUrl. Safe to import from the firewall-scanning tools and from tests that only need URL helpers.
barrelscripts/render-lib/index.tsThin re-export of every public symbol from the leaves above. Downstream code imports from the barrel only.
translatenews-translate workflow (out-of-band)Produce the 12 non-EN/SV variants from the rendered EN+SV HTML.

The 6-module split reduces worst-case import-time cost for tests: tests that only exercise the aggregator can skip the unified/remark/rehype dependency graph (~40 ms saved per test-file cold start). Test coverage is validated both via the barrel (tests/render-lib.test.ts, 137 tests) and via direct leaf imports (tests/render-lib-architecture.test.ts, 38 tests) โ€” the architecture test file proves no public-API drift exists between the barrel and the leaves.

Sanitiser Trust Boundary

The renderer's rehype-sanitize schema is the single trust boundary between AI-generated analysis markdown and user-facing HTML:

  • Allow-listed: standard markdown HTML (p, h1-h6, ul, ol, li, a[href|title], img[src|alt|title], code, pre, blockquote, table, thead, tbody, tr, th, td, figure, figcaption, details, summary).
  • Explicitly allowed extension: <pre class="mermaid">โ€ฆ</pre> survives sanitisation so client-side mermaid-init.mjs can render it.
  • Rejected: <script>, <iframe>, <object>, <embed>, inline event handlers (onclick=โ€ฆ), javascript: URIs, data: URIs except for whitelisted image MIME types.
  • GitHub-blob link rewriting: relative links inside aggregated markdown are rewritten to absolute https://github.com/Hack23/riksdagsmonitor/blob/main/... URLs so the citation chain survives copy-paste.

The trust boundary is documented in SECURITY_ARCHITECTURE.md and the corresponding STRIDE entries live in THREAT_MODEL.md.

Provenance โ€” Sources of Method

Each rendered article footer cites:

  1. Every analysis/daily/$DATE/$SUB/*.md file consumed (via aggregator manifest)
  2. Every analysis/methodologies/*.md referenced
  3. Every analysis/templates/*.md used

The citation chain is encoded in JSON-LD NewsArticle.about and NewsArticle.citation so search engines and LLMs can traverse the full evidence chain.

What is NOT in this pipeline

  • โŒ No scaffold-and-fill (generate-news-enhanced removed)
  • โŒ No <!-- AI_MUST_REPLACE: โ€ฆ --> markers (validator entry removed)
  • โŒ No scripts/article-template/, scripts/news-types/, scripts/pipeline/ (all deleted)
  • โŒ No per-type generator classes โ€” section ordering is configuration in the aggregator
  • โŒ No translation logic in the per-type workflows โ€” that lives only in news-translate

C4 Component view โ€” scripts/render-lib/ (true sub-tree)

The render-lib barrel (scripts/render-lib/index.ts) re-exports across four leaf-trees. The internal layout below is the true filesystem at v0.9.40 โ€” consumers still import only from the barrel.

graph LR
    subgraph "render-lib leaves"
        Article[article.ts<br/>+ article-types.ts]
        ChromeFacade[chrome.ts<br/>(faรงade)]
        ChromeI18n[chrome-i18n.ts]
        FaqI18n[faq-i18n.ts]
        Constants[constants.ts]
        UrlHelpers[url-helpers.ts]
        JsonLd[jsonld.ts]
        Barrel[index.ts<br/>(public surface)]
    end
    subgraph "render-lib/chrome/"
        Head[head/]
        Header[header/]
        Footer[footer/]
        Helpers[helpers/]
        Types[types/]
        ChromeIndex[index.ts]
    end
    subgraph "render-lib/aggregator/"
        AggMain[aggregate.ts<br/>+ pipeline.ts<br/>+ index.ts]
        Front[frontmatter.ts<br/>(language='en', layout='article' defaults)]
        Interfaces[interfaces.ts]
        PerDoc[per-document.ts]
        Reader[reader-guide.ts<br/>+ reader-guide-i18n.ts]
        Sources[sources-appendix.ts]
        Order[order.ts]
        subgraph "aggregator/cleaning/"
            Bylines[admin-bylines]
            Dedup[deduplication]
            Demote[heading-demotion]
            LinkRewrite[link-rewriting]
            PassTwo[pass-two]
            ProcessMeta[process-meta]
            Structural[structural]
        end
        subgraph "aggregator/seo/"
            SeoDesc[description.ts]
            SeoTitle[title.ts]
        end
    end
    subgraph "render-lib/markdown/"
        MdIndex[index.ts]
        MdPipeline[pipeline.ts]
        MermaidCanon[mermaid-canonical-theme.ts]
        MermaidPre[mermaid-preprocess.ts]
        SlugPrefixed[rehype-slug-prefixed.ts]
        WrapTables[rehype-wrap-tables.ts]
        Sanitize[sanitize-schema.ts<br/>(single trust boundary)]
    end

    Barrel --> Article
    Barrel --> ChromeFacade
    Barrel --> AggMain
    Barrel --> MdIndex
    ChromeFacade --> ChromeIndex
    ChromeIndex --> Head
    ChromeIndex --> Header
    ChromeIndex --> Footer
    ChromeIndex --> Helpers
    ChromeIndex --> Types
    AggMain --> Front
    AggMain --> Interfaces
    AggMain --> PerDoc
    AggMain --> Reader
    AggMain --> Sources
    AggMain --> Order
    AggMain --> Bylines
    AggMain --> Dedup
    AggMain --> Demote
    AggMain --> LinkRewrite
    AggMain --> PassTwo
    AggMain --> ProcessMeta
    AggMain --> Structural
    AggMain --> SeoDesc
    AggMain --> SeoTitle
    MdIndex --> MdPipeline
    MdPipeline --> MermaidCanon
    MdPipeline --> MermaidPre
    MdPipeline --> SlugPrefixed
    MdPipeline --> WrapTables
    MdPipeline --> Sanitize
    Article --> JsonLd
    Article --> ChromeFacade
    Article --> MdIndex

    style Sanitize fill:#e57373,stroke:#b71c1c,stroke-width:2px,color:#000000
    style Front fill:#fff59d,color:#000000
    style Barrel fill:#9c27b0,color:#ffffff

C4 Component view โ€” scripts/agentic/ (analysis-gate & 23-artifact inventory)

The agentic bounded context owns the analysis gate (single block point before any article render) and the typed artifact inventory that drives every newsroom check. The gate enforces nine numbered checks (1, 2, 3, 4, 5, 6, 7, 8, 9b) with PASS2_MTIME_THRESHOLD_MS = 180_000 ms separating Pass-1 from Pass-2 evidence.

graph TD
    subgraph "scripts/agentic/"
        Gate[analysis-gate.ts<br/>checks 1, 2, 3, 4, 5, 6, 7, 8, 9b<br/>PASS2_MTIME_THRESHOLD_MS = 180_000]
        Inventory[artifact-inventory.ts<br/>typed ArtifactDefinition[]<br/>23 required artifacts, Families Aโ€“E]
        AgenticIdx[index.ts<br/>(barrel)]
    end

    subgraph "Family A โ€” Core Synthesis (9)"
        A1[README.md ยท Pass-2]
        A2[executive-brief.md ยท Mermaid ยท Pass-2]
        A3[synthesis-summary.md ยท Mermaid ยท Pass-2]
        A4[significance-scoring.md ยท Mermaid ยท Pass-2]
        A5[classification-results.md ยท Mermaid ยท Pass-2]
        A6[swot-analysis.md ยท Mermaid ยท Pass-2]
        A7[risk-assessment.md ยท Mermaid ยท Pass-2]
        A8[threat-analysis.md ยท Mermaid ยท Pass-2]
        A9[stakeholder-perspectives.md ยท Mermaid ยท Pass-2]
    end
    subgraph "Family B โ€” Structural Metadata (2)"
        B1[data-download-manifest.md]
        B2[cross-reference-map.md ยท Mermaid ยท Pass-2]
    end
    subgraph "Family C โ€” Strategic Extensions (5)"
        C1[scenario-analysis.md ยท Pass-2]
        C2[comparative-international.md ยท Pass-2]
        C3[devils-advocate.md ยท Pass-2]
        C4[intelligence-assessment.md ยท Pass-2]
        C5[methodology-reflection.md ยท Pass-2]
    end
    subgraph "Family D โ€” Electoral &amp; Domain Lenses (7)"
        D1[election-2026-analysis.md ยท Mermaid ยท Pass-2]
        D2[voter-segmentation.md ยท Mermaid ยท Pass-2]
        D3[coalition-mathematics.md ยท Mermaid ยท Pass-2]
        D4[historical-parallels.md ยท Mermaid ยท Pass-2]
        D5[media-framing-analysis.md ยท Mermaid ยท Pass-2]
        D6[implementation-feasibility.md ยท Mermaid ยท Pass-2]
        D7[forward-indicators.md ยท Mermaid ยท Pass-2]
    end
    subgraph "Family E โ€” Per-document (variable)"
        E1[documents/{dok_id}-analysis.md<br/>one per source document]
    end

    AgenticIdx --> Gate
    AgenticIdx --> Inventory
    Inventory --> A1
    Inventory --> A2
    Inventory --> A3
    Inventory --> A4
    Inventory --> A5
    Inventory --> A6
    Inventory --> A7
    Inventory --> A8
    Inventory --> A9
    Inventory --> B1
    Inventory --> B2
    Inventory --> C1
    Inventory --> C2
    Inventory --> C3
    Inventory --> C4
    Inventory --> C5
    Inventory --> D1
    Inventory --> D2
    Inventory --> D3
    Inventory --> D4
    Inventory --> D5
    Inventory --> D6
    Inventory --> D7
    Inventory --> E1
    Gate --> Inventory

    style Gate fill:#e57373,stroke:#b71c1c,stroke-width:2px,color:#000000
    style Inventory fill:#7e57c2,color:#ffffff
    style AgenticIdx fill:#5e35b1,color:#ffffff

Test surface: tests/agentic/gate-checks/*.test.ts (one suite per production check module), tests/agentic/gate-shared/*.test.ts (markdown helpers, file walkers), and tests/agentic/analysis-gate-integration.test.ts (orchestrator + artifact-inventory invariants). Optional standalone driver: npx tsx scripts/validate-methodology-reflection.ts for ICD-203 audit of methodology-reflection.md.


๐Ÿง  Political Intelligence Architecture

The political-intelligence pipeline turns 18 methodology files and 39 templates into 23 per-day analysis artifacts which the analysis-gate then admits (or rejects) before article rendering. This section is the architectural complement to the data-model side under DATA_MODEL.md ยง11 "Analysis Artifact Data Model".

Methodology framework (analysis/methodologies/, 18 files)

#FileEditorial role
1ai-driven-analysis-guide.mdMaster AI-FIRST authoring contract
2analytical-supplementary-methodology.mdSupplementary analytic techniques
3artifact-catalog.mdCatalogue of every artifact and its acceptance criteria
4electoral-domain-methodology.mdElection-cycle and Family-D analysis discipline
5imf-indicator-mapping.mdIMF WEO/FM/IFS indicator โ†’ article-type mapping
6osint-tradecraft-standards.mdSource vetting, ICD 203 alignment, ACH discipline
7per-artifact-methodologies.mdPer-artifact (Aโ€“E) analytic recipes
8per-document-methodology.mdFamily-E per-document analysis recipe
9political-classification-guide.md7-dimension political classification
10political-risk-methodology.mdRisk matrix, residual risk, mitigation
11political-style-guide.md (+ .json)Editorial voice + machine-checkable style rules
12political-swot-framework.mdS/W/O/T evidence + TOWS
13political-threat-framework.mdSTRIDE-style political threat model
14reference-quality-thresholds.jsonReference-grade thresholds (machine-readable)
15strategic-extensions-methodology.mdFamily-C strategic extensions discipline
16structural-metadata-methodology.mdFamily-B structural metadata recipe
17synthesis-methodology.mdLead-story synthesis + DIW ranking recipe
18worldbank-indicator-mapping.mdWorld Bank WGI/WDI indicator โ†’ article-type mapping

(Plus README.md and the two JSON sidecars; the markdown-methodology count is 18.)

Template catalog (analysis/templates/, 39 files)

Templates fall into three architectural roles:

  • Per-artifact templates (one per Family-A/B/C/D required artifact): executive-brief, synthesis-summary, significance-scoring, swot-analysis, risk-assessment, threat-analysis, stakeholder-impact, data-download-manifest, cross-reference-map, scenario-analysis, comparative-international, devils-advocate, intelligence-assessment, methodology-reflection, election-2026-analysis, voter-segmentation, coalition-mathematics, historical-parallels, media-framing-analysis, implementation-feasibility, forward-indicators, political-classification, political-stride-assessment, quantitative-swot, pestle-analysis.
  • Pipeline templates (cross-cutting): analysis-index, cross-run-diff, cross-session-intelligence, cycle-trajectory, forward-indicators, horizon-pir-rollforward, parliamentary-season, per-file-political-intelligence, reference-analysis-quality, session-baseline, significance-scoring, synthesis-summary, wildcards-blackswans, workflow-audit, mcp-reliability-audit.
  • Election-cycle templates: election-cycle-analysis, election-2026-analysis, coalition-mathematics, voter-segmentation, parliamentary-season.

Total: 39 files including README.md.

Horizon stratification (architectural pattern)

Article generation is stratified across 7 horizon bands. Runtime context is computed by scripts/horizon-context.ts from analysis/article-types.json; every article-type targets one band so the analysis-gate, methodology selection, and template selection are deterministic at any commit.

timeline
    title Horizon stratification (T = publication time)
    T+72h    : Daily / week-ahead briefs : tactical signals
    T+7d     : Weekly review : near-term trajectory
    T+30d    : Monthly review : structural deltas
    T+90d    : Quarterly outlook : fiscal-cycle alignment
    T+365d   : Annual outlook : election-year framing
    T+1460d  : Mandate-period outlook : 4-year horizon
    election : Election special : voter segmentation + coalition math

AI-FIRST 2-pass iteration (quality constraint)

Every methodology and every Family-A/C/D artifact MUST go through two complete passes separated by โ‰ฅ 180 s wall-clock (enforced by PASS2_MTIME_THRESHOLD_MS = 180_000 in scripts/agentic/analysis-gate.ts). Pass 1 establishes the structural draft; Pass 2 re-reads every section and tightens evidence, corrects banned-phrase drift, and adds missing Mermaid diagrams. Completing early with shallow output is never acceptable โ€” this is an architectural quality gate, not a stylistic preference.

OSINT tradecraft integration

analysis/methodologies/osint-tradecraft-standards.md enforces ICD 203 (analytic standards), ACH (Analysis of Competing Hypotheses) for devils-advocate.md, and source vetting for data-download-manifest.md. The standards are referenced by every Family-A and Family-C artifact and are validated by the analysis-gate's check 9b.

Classification / SWOT / threat / PESTLE / scenario template roles

TemplateFamilyMethodology authority
political-classificationApolitical-classification-guide.md (7-dimension)
swot-analysis (+ quantitative-swot)Apolitical-swot-framework.md (+ TOWS matrix)
threat-analysis (+ political-stride-assessment)Apolitical-threat-framework.md (STRIDE-style)
pestle-analysisA/crossanalytical-supplementary-methodology.md
scenario-analysis (โ‰ฅ3 scenarios)Cstrategic-extensions-methodology.md

Election-cycle and coalition-mathematics templates

election-cycle-analysis, election-2026-analysis, coalition-mathematics, voter-segmentation, and parliamentary-season templates are the Family-D backbone for the 2026 Riksdag election cycle. They consume CIA coalition/, election-cycle/, pre-election/, voting/, and seasonal/ data subsystems alongside SCB demographic series and IMF macro context.



๐Ÿ”’ Security Architecture Integration

Defense-in-Depth Layers

graph TD
    Layer1[Layer 1: Network Security<br/>HTTPS/TLS 1.3, CDN DDoS Protection<br/>AWS Shield Standard]
    Layer2[Layer 2: Application Security<br/>Static HTML/CSS Only, No Server-Side Code<br/>CSP Headers, SRI for JS Libraries]
    Layer3[Layer 3: Access Control<br/>GitHub MFA, SSH Keys, GPG Commit Signing<br/>Branch Protection Rules]
    Layer4[Layer 4: Data Integrity<br/>Git Immutable History, S3 Versioning<br/>Branch Protection, Code Review]
    Layer5[Layer 5: Monitoring & Detection<br/>Dependabot, CodeQL, Secret Scanning<br/>GitHub Security Advisories]
    Layer6[Layer 6: Incident Response<br/>Documented Procedures, Rollback Capability<br/>RTO <17 minutes]
    
    Layer1 --> Layer2
    Layer2 --> Layer3
    Layer3 --> Layer4
    Layer4 --> Layer5
    Layer5 --> Layer6
    
    style Layer1 fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Layer2 fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Layer3 fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Layer4 fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Layer5 fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Layer6 fill:#f44336,stroke:#c62828,stroke-width:2px,color:#ffffff

Security Control Summary

LayerControlTechnologyStatus
NetworkTLS 1.3 EncryptionAWS CloudFrontโœ… Active
NetworkDDoS ProtectionAWS Shield Standardโœ… Active
ApplicationContent Security PolicyHTTP Headersโœ… Active
ApplicationSubresource IntegritySRI hashes for JS libsโœ… Active
AccessMulti-Factor AuthenticationGitHub MFAโœ… Active
AccessGPG Commit SigningGitHub GPGโœ… Active
DataS3 VersioningAWS S3โœ… Active
DataCross-Region ReplicationS3 CRRโœ… Active
MonitoringDependency ScanningDependabotโœ… Active
MonitoringSAST ScanningCodeQLโœ… Active
MonitoringSecret ScanningGitHub Secret Scanningโœ… Active
ResponseAutomated RollbackGit revert + CI/CDโœ… Active

See: SECURITY_ARCHITECTURE.md for comprehensive security controls documentation
See: THREAT_MODEL.md for STRIDE threat analysis


โšก Scalability Architecture

Traffic Handling

graph TB
    Users[End Users<br/>Global Traffic<br/>Target: 10k concurrent]
    
    subgraph "CDN Layer - 600+ Edge Locations"
        Edge1[Edge Server<br/>North America<br/>30% traffic]
        Edge2[Edge Server<br/>Europe<br/>60% traffic]
        Edge3[Edge Server<br/>Asia Pacific<br/>10% traffic]
    end
    
    subgraph "Origin Layer"
        S3US[S3 us-east-1<br/>Primary Origin<br/>99.9% availability]
        S3EU[S3 eu-west-1<br/>Replica Origin<br/>Failover target]
    end
    
    subgraph "DR Layer"
        GitHub[GitHub Pages<br/>DR Origin<br/>DNS failover]
    end
    
    Users --> Edge1
    Users --> Edge2
    Users --> Edge3
    
    Edge1 -->|Cache Miss| S3US
    Edge2 -->|Cache Miss| S3US
    Edge3 -->|Cache Miss| S3US
    
    Edge1 -->|Cache Hit 95%| Users
    Edge2 -->|Cache Hit 95%| Users
    Edge3 -->|Cache Hit 95%| Users
    
    S3US -.->|CRR Async| S3EU
    S3US -.->|Failover on 5xx| S3EU
    
    Users -.->|DNS Failover| GitHub
    
    style S3US fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style S3EU fill:#64b5f6,stroke:#1976d2,stroke-width:2px,color:#000000
    style Edge1 fill:#90caf9,stroke:#42a5f5,stroke-width:2px,color:#000000
    style Edge2 fill:#90caf9,stroke:#42a5f5,stroke-width:2px,color:#000000
    style Edge3 fill:#90caf9,stroke:#42a5f5,stroke-width:2px,color:#000000
    style GitHub fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000

Performance Characteristics

MetricTargetCurrentMethodMeasurement
First Contentful Paint (FCP)<1.5s<1sStatic files, CDN edge cachingLighthouse CI
Time to Interactive (TTI)<3s<2sMinimal JavaScript dependenciesLighthouse CI
Largest Contentful Paint (LCP)<2.5s<2sOptimized CSS, cached fontsLighthouse CI
Cumulative Layout Shift (CLS)<0.1<0.05Stable layout, no dynamic contentLighthouse CI
Total Blocking Time (TBT)<300ms<200msClient-side rendering, async scriptsLighthouse CI
CDN Cache Hit Rate>90%95%Long cache TTL (1 year for static assets)CloudWatch
Origin Request Rate<5%<5%High cache hit rateCloudWatch

Capacity Planning

ResourceCurrentMax CapacityScaling Method
CloudFront Bandwidth~10 GB/dayUnlimitedAWS auto-scaling
S3 Storage~500 MBUnlimitedAWS auto-scaling
S3 Requests~10k/day5,500 requests/secondAWS auto-scaling
GitHub Pages Bandwidth~5 GB/month100 GB/monthSoft limit, contact support
GitHub Actions Minutes~500 min/month3,000 min/month (Team plan)Upgrade plan if needed

๐Ÿ“ˆ Monitoring Architecture

Observability Stack

graph TB
    subgraph "Monitoring Sources"
        GH[GitHub Actions<br/>Workflow Results<br/>Build/Test/Deploy Status]
        Pages[GitHub Pages<br/>Deployment Status<br/>Build Logs]
        Security[GitHub Security<br/>Dependabot Alerts<br/>CodeQL Findings<br/>Secret Scanning]
        CloudFront[CloudFront Metrics<br/>Cache Hit Rate<br/>Error Rate<br/>Request Count]
        S3[S3 Metrics<br/>Storage Size<br/>Request Count<br/>Error Rate]
    end
    
    subgraph "Alerting Channels"
        Email[Email Notifications<br/>Critical alerts]
        PR[PR Comments<br/>Quality feedback]
        Dashboard[GitHub Dashboard<br/>Metrics overview]
        Slack[Slack Webhooks<br/>Team notifications]
    end
    
    subgraph "Metrics Storage"
        Quality[Quality Metrics<br/>HTML Validation, Link Check<br/>Code Coverage]
        Deps[Dependency Metrics<br/>Vulnerabilities Count<br/>Update Lag]
        Deploy[Deployment Metrics<br/>Success Rate, Duration<br/>Frequency]
        Performance[Performance Metrics<br/>CDN Cache Hit Rate<br/>Origin Request Rate]
    end
    
    GH --> Quality
    Pages --> Deploy
    Security --> Deps
    CloudFront --> Performance
    S3 --> Performance
    
    Quality --> Email
    Quality --> PR
    Deps --> PR
    Deps --> Slack
    Deploy --> Dashboard
    Performance --> Dashboard
    
    style GH fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style Security fill:#f44336,stroke:#c62828,stroke-width:2px,color:#ffffff
    style Dashboard fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Slack fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff

Metrics Collection

Tracked Metrics:

Metric CategoryMetricsFrequencyRetention
Workflow MetricsExecution success rate, duration, frequencyPer workflow run90 days
Quality MetricsHTML validation pass rate, link check failuresPer commit90 days
Security MetricsDependency vulnerability count, CodeQL findingsDailyPermanent
Performance MetricsCDN cache hit rate, origin error rateEvery 5 minutes30 days
Deployment MetricsDeploy frequency, time to deploy, rollback countPer deployment90 days

Retention Policy:

  • Workflow runs: 90 days (GitHub Actions default)
  • Artifacts: 30 days (GitHub Actions default)
  • Security findings: Permanent (GitHub Security)
  • Deployment logs: 90 days (GitHub Actions)
  • CloudWatch metrics: 30 days (AWS default)

Alerting Strategy

Alert Severity Levels:

SeverityConditionResponse TimeNotification
CriticalProduction site down, CloudFront 5xx errorsImmediateEmail + Slack
HighDeployment failure, CodeQL high-severity finding<1 hourEmail + PR comment
MediumLink check failures, Dependabot alerts<24 hoursPR comment
LowHTML validation warnings, code style issuesNext business dayPR comment

๐Ÿ› ๏ธ Technology Stack

Frontend Stack

TechnologyVersionPurposeRationaleLicense
HTML5StandardContent structureUniversal browser support, semantic markupW3C License
CSS3StandardStyling & layoutResponsive design, no framework overheadW3C License
JavaScript ES6+StandardInteractive dashboardsModern browser features, async/awaitECMA License
Chart.jsv4.4.1Data visualizationIndustry standard, 62k+ GitHub starsMIT
chartjs-plugin-annotationv3.0.1Chart annotationsOfficial Chart.js plugin for highlightingMIT
chartjs-adapter-date-fnsv3.0.0Time-series chartsOfficial date adapter with date-fns bundledMIT
D3.jsv7Advanced visualizationsPowerful, flexible, 108k+ GitHub starsBSD-3-Clause
Papa Parsev5.5.3CSV parsingReliable CSV parser, 12k+ GitHub starsMIT
Google FontsLatestTypography (Inter, Orbitron)Professional appearance, cached globallyOpen Font License

Infrastructure Stack

TechnologyVersionPurposeRationaleSLA
AWS CloudFrontLatestPrimary CDN600+ global edge locations, DDoS protection99.9%
AWS S3LatestPrimary storageReliable, scalable, versioning support, CRR99.9%
AWS Route 53LatestDNS with failoverHealth checks, automatic failover routing100%
GitHub PagesLatestDR hostingFree, reliable, global CDN99.9%
GitHub ActionsLatestCI/CDIntegrated with repository, secure OIDC99.9%
HTMLHintLatestHTML validationIndustry standard validatorMIT
Linkinatorv6Link checkingReliable, actively maintainedApache-2.0
npmLatestPackage managementJavaScript dependency managementArtistic-2.0
Vitev8.0.14Build toolFast build times, optimized outputMIT
Vitestv4.1.7Unit / integration test runnerVite-native, ESM-first, watch modeMIT
TypeScriptv6.0.3Source languageStrict typing across src/, scripts/, tests/Apache-2.0
Node.jsโ‰ฅ26Runtime baselineNative TypeScript loader, ESM, modern fetchMIT

External Dependencies

๐Ÿ“ฆ Public npm package surface (v0.9.40): riksdagsmonitor exports the typed subpaths ./, ./shared, ./shared/*, ./cia/*, ./dashboards/*, ./ui/* (package.json exports map). "type": "module" (pure ESM). "sideEffects" is restricted to ./dist/lib/shared/register-globals.js and ./src/browser/cia-entry.ts so tree-shaking works for downstream consumers. ESLint baseline: no-explicit-any = error and no-unused-vars = error are enforced repository-wide; the typed DashboardGlobals interface (src/browser/shared/global-libs.ts) replaces any for Chart.js / D3 / PapaParse browser globals.

DependencyTypeRisk LevelMitigationUpdate Strategy
AWS CloudFrontInfrastructureLOW99.9% SLA, GitHub Pages DR, Route 53 failoverManaged by AWS
AWS S3InfrastructureLOWCross-region replication, versioning, 99.9% SLAManaged by AWS
AWS Route 53InfrastructureLOW100% SLA, health checks, automatic failoverManaged by AWS
GitHub PagesInfrastructure (DR)LOW99.9% SLA, independent from AWSManaged by GitHub
Chart.js v4.4.1JavaScript LibraryLOWHosted locally on CloudFront/S3 (js/lib/), SRI hash validationDependabot automated updates
chartjs-plugin-annotation v3.0.1JavaScript LibraryLOWHosted locally on CloudFront/S3 (js/lib/), SRI hash validationDependabot automated updates
chartjs-adapter-date-fns v3.0.0JavaScript LibraryLOWHosted locally on CloudFront/S3 (js/lib/), SRI hash validationDependabot automated updates
D3.js v7JavaScript LibraryLOWHosted locally on CloudFront/S3 (js/lib/), SRI hash validationDependabot automated updates
Papa Parse v5.5.3JavaScript LibraryLOWHosted locally on CloudFront/S3 (js/lib/), SRI hash validationDependabot automated updates
Google FontsCDNLOWCached by browsers, fallback fonts available (Arial, sans-serif)Managed by Google
CIA PlatformExternal ServiceLOWIndependent service, documented external links, no API keysManual monitoring

๐Ÿš€ Deployment Architecture

Deployment Pipeline

graph LR
    Dev[Development<br/>Local changes] --> Commit[Git Commit<br/>Signed with GPG]
    Commit --> Push[Git Push<br/>to feature branch]
    Push --> PR[Pull Request<br/>Open for review]
    
    PR --> Quality[Quality Checks<br/>HTMLHint, Linkinator]
    PR --> Security[Security Checks<br/>CodeQL, Dependabot]
    PR --> Tests[Test Suite<br/>Unit tests, E2E tests]
    
    Quality --> Review[Code Review<br/>Required approval]
    Security --> Review
    Tests --> Review
    
    Review --> Merge[Merge to Main<br/>Squash commits]
    Merge --> Build[Build Assets<br/>Vite production build]
    Build --> DeployS3[Deploy to S3<br/>us-east-1 + CloudFront invalidation]
    Build --> DeployGH[Deploy to GitHub Pages<br/>DR standby]
    
    DeployS3 --> LivePrimary[Live on CloudFront<br/>riksdagsmonitor.com]
    DeployGH --> LiveDR[DR Standby on GitHub Pages<br/>riksdagsmonitor.com/DR]
    
    style Quality fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style Security fill:#f44336,stroke:#c62828,stroke-width:2px,color:#ffffff
    style Tests fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff
    style Merge fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style LivePrimary fill:#4caf50,stroke:#2e7d32,stroke-width:3px,color:#000000
    style LiveDR fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff

Deployment Strategy

Dual Deployment Process:

  1. Trigger: Merge to main branch
  2. Build: Vite production build (optimized assets)
  3. Validate: HTMLHint + Linkinator quality gates
  4. Primary Deploy: Upload to S3 us-east-1 + CloudFront invalidation
  5. DR Deploy: Publish to GitHub Pages
  6. Verify: Smoke tests on both deployments
  7. Monitor: CloudWatch metrics + GitHub Actions logs

Deployment Frequency: Multiple times per day (on-demand)
Average Deployment Time: <2 minutes (S3 + CloudFront invalidation)

Rollback Strategy

Rollback Methods:

MethodUse CaseRTOComplexity
Git RevertCode defects, broken features<5 minutesLow (1 command + CI/CD)
S3 VersioningCorrupted files, accidental deletion<2 minutesLow (restore specific version)
CloudFront InvalidationCached bad content<1 minuteLow (invalidate specific paths)
DNS Failover to GitHub PagesCloudFront outage<5 minutesAutomatic (Route 53 health checks)
Branch RollbackMultiple bad commits<10 minutesMedium (force push to main)

Rollback SLA:

  • Detection: <5 minutes (monitoring alerts + smoke tests)
  • Decision: <10 minutes (review incident, check logs)
  • Execution: <2 minutes (git revert + automated deploy)
  • Verification: <5 minutes (smoke tests, manual verification)
  • Total RTO: <22 minutes (worst case)

Rollback Procedure:

# 1. Revert commit (creates new commit)
git revert <bad-commit-sha>

# 2. Push to trigger CI/CD
git push origin main

# 3. CI/CD automatically deploys reverted code
# 4. Verify deployment with smoke tests

๐Ÿ›๏ธ Architecture Principles

Core Principles

  1. Security by Design

    • Defense-in-depth with 6 security layers
    • Dual deployment with automatic failover
    • CSP headers, SRI for JS libraries, SLSA build attestations
    • OIDC keyless authentication for deployments
  2. Defense in Depth

    • Network layer: HTTPS/TLS 1.3, CDN DDoS protection
    • Application layer: Static site (no server-side code), CSP, SRI
    • Access control: GitHub MFA, GPG signing, branch protection
    • Data integrity: Git immutable history, S3 versioning, CRR
    • Monitoring: Dependabot, CodeQL, secret scanning
    • Incident response: Documented procedures, RTO <22 minutes
  3. Resilience

    • Multi-region storage (S3 us-east-1 + eu-west-1)
    • Cross-region replication (async, <15 min target)
    • Automatic failover (Route 53 health checks + DNS failover)
    • Disaster recovery (GitHub Pages independent hosting)
    • 99.9% availability target (both AWS and GitHub SLAs)
  4. Transparency

    • Open source repository (MIT license)
    • Public ISMS documentation
    • Documented architecture (C4 model)
    • Threat model (STRIDE analysis)
    • Security controls (ISO 27001, NIST CSF 2.0, CIS Controls v8.1)
  5. Performance

    • CDN edge caching (600+ global PoPs)
    • Client-side rendering (no server-side overhead)
    • Optimized assets (Vite production build)
    • 95% cache hit rate target
    • <1s First Contentful Paint
  6. Usability

    • Interactive dashboards with Chart.js and D3.js
    • Modern visualizations (committee analysis, coalition tracking)
    • 14-language support with proper i18n
    • Responsive design (mobile-first CSS)
    • Progressive enhancement (works without JS)

Key Architectural Decisions

DecisionRationaleTrade-offs
Interactive Dashboards (Chart.js/D3.js)Rich data visualization, modern UX, industry-standard librariesIncreases attack surface (requires JavaScript), browser compatibility, larger page size
AWS CloudFront Primary600+ PoPs, DDoS protection, 99.9% SLA, mature CDNCost for high traffic (~$10-50/month), vendor lock-in, AWS dependency
GitHub Pages DRFree hosting, reliable (99.9% SLA), independent from AWS100 GB/month soft limit, Jekyll processing (disabled), GitHub dependency
External CIA PlatformReuse existing OSINT infrastructure, separation of concernsExternal service dependency, no API integration (links only)
Static Site (No Server-Side Code)Minimal attack surface, no backend vulnerabilities, easy to secureLimited dynamic features, client-side processing only, no server-side rendering
Multi-language Files (14 HTML files)SEO optimization, clear URL structure, no client-side translationFile duplication, maintenance overhead, 14x storage for content
SRI for CDN ResourcesSupply chain security, tamper detection, SLSA complianceRequires version pinning, update coordination, manual hash generation
MCP Server IntegrationSpecialized political data access, 32 tools, intelligence-operative agentHTTP-only server, external dependency, rate limiting, public data only
Dual Deployment PatternHigh availability, disaster recovery, independent hosting platformsComplexity (two deployment targets), cost (AWS + GitHub Actions minutes)

๐Ÿ”ฎ Future Architecture

Planned Enhancements

See: FUTURE_ARCHITECTURE.md for detailed roadmap

Q2 2026 Roadmap

Security Enhancements:

  • DAST scanning integration (OWASP ZAP in CI/CD)
  • Enhanced CSP with strict-dynamic
  • Security header improvements (Permissions-Policy, CORP, COOP)

Performance Improvements:

  • Lighthouse CI integration with quality gates
  • Performance budget enforcement (<100KB JS, <200KB CSS)
  • Image optimization (WebP format, lazy loading)

Automation:

  • Automated translation workflows (14 languages)
  • Content generation automation (evening analysis, morning briefing)
  • Quality metrics dashboard

Q3 2026 Roadmap

Monitoring & Observability:

  • Advanced link monitoring (broken link detection, redirect chains)
  • Real-time performance monitoring (CloudWatch RUM)
  • Error tracking and alerting (Sentry integration)

Accessibility:

  • WCAG 2.1 AA compliance
  • Screen reader testing
  • Keyboard navigation improvements

Infrastructure:

  • S3 Intelligent-Tiering for cost optimization
  • CloudFront Functions for edge logic
  • AWS WAF for advanced threat protection

Q4 2026 Roadmap

Content Generation:

  • Multi-language content generation (14 languages)
  • A/B testing framework for content
  • Personalized content recommendations

Analytics:

  • Privacy-respecting analytics (Plausible or Matomo)
  • User behavior tracking (no PII)
  • Dashboard usage metrics

Advanced Features:

  • Real-time data updates (WebSocket or Server-Sent Events)
  • Advanced data visualizations (3D charts, interactive timelines)
  • Historical trend analysis (time-series forecasting)

๐Ÿ”Œ MCP Server Integration

GitHub Copilot MCP Server Architecture

Riksdagsmonitor leverages GitHub Copilot with Model Context Protocol (MCP) servers for advanced political intelligence analysis and automation.

๐Ÿ”ข Server count (v0.9.40): 8 MCP servers are wired via .github/copilot-mcp.json: riksdag-regering, scb, world-bank, github (insiders), filesystem, memory, sequential-thinking, playwright. The IMF integration is intentionally not an MCP server โ€” it ships as the pure-TypeScript client scripts/imf-client.ts (Datamapper JSON v1 + SDMX 3.0), fully covered by the npm SBOM, with allowlisted egress hosts data.imf.org, api.imf.org, www.imf.org. Same pattern is used for SCB (scripts/scb-client.ts), World Bank (scripts/world-bank-client.ts), Riksbank (scripts/riksbank-fetch.ts), Statskontoret (scripts/statskontoret-client.ts), RiR (scripts/rir-followups-client.ts), and parliamentary-data downloads when invoked from build-time scripts.

Schema governance pipeline (schemas/ + scripts/)

Schema drift between the upstream CIA platform and Riksdagsmonitor's typed surface is governed by four scripts under scripts/, executed in order:

flowchart LR
    Sync[scripts/sync-cia-schemas.ts<br/>pulls upstream schemas/cia/]
    Validate[scripts/validate-against-cia-schemas.ts<br/>ajv 8.20.0 schema validation]
    Check[scripts/check-cia-schema-updates.ts<br/>diff vs. last sync, exit 1 on drift]
    GenTypes[scripts/generate-types-from-cia-schemas.ts<br/>emits .d.ts for ./cia/* subpath]
    Schemas[(schemas/)<br/>article-types.schema.json<br/>pir-status.schema.json<br/>rir-followups-schema.json<br/>cia/*.schema.json]
    PkgExports[package.json exports<br/>./cia/* ยท ./dashboards/* ยท ./shared/* ยท ./ui/*]

    Sync --> Schemas
    Schemas --> Validate
    Schemas --> Check
    Schemas --> GenTypes
    GenTypes --> PkgExports

MCP Server Architecture

graph TB
    subgraph "GitHub Copilot Environment"
        Agent[intelligence-operative Agent<br/>Specialized for Swedish politics]
        Skills[18 Strategic Skills<br/>Political science, OSINT, analysis]
    end
    
    subgraph "MCP Servers"
        RR[riksdag-regering-mcp<br/>HTTP: riksdag-regering-ai.onrender.com/mcp<br/>32 specialized tools]
        SCB[scb-mcp<br/>HTTPS: scb-mcp.onrender.com/mcp<br/>Statistics Sweden PxWebAPI 2.0]
        GH[GitHub MCP<br/>HTTP: api.githubcopilot.com/mcp/insiders<br/>Repository management]
        FS[Filesystem MCP<br/>Local: mcp-server-filesystem<br/>File operations]
        Mem[Memory MCP<br/>Local: mcp-server-memory<br/>Knowledge graph]
        PW[Playwright MCP<br/>Local: @playwright/mcp<br/>Browser automation]
    end
    
    subgraph "TypeScript Clients (no MCP)"
        IMF[imf-ts-client<br/>scripts/imf-client.ts<br/>HTTPS: data.imf.org / api.imf.org / www.imf.org<br/>WEO + Fiscal Monitor + SDMX 3.0]
    end
    
    subgraph "Data Sources"
        Riksdag[Riksdagen API<br/>data.riksdagen.se<br/>98.5% data completeness]
        Regering[Regeringen<br/>via g0v.se<br/>Government documents]
        SCBData[Statistics Sweden<br/>scb.se<br/>1,200+ statistical tables]
        IMFData[IMF Open Data<br/>data.imf.org<br/>WEO, Fiscal Monitor, IFS, ~155 SDMX databases]
    end
    
    Agent --> Skills
    Agent --> RR
    Agent --> SCB
    Agent --> IMF
    Agent --> GH
    Agent --> FS
    Agent --> Mem
    Agent --> PW
    
    RR --> Riksdag
    RR --> Regering
    SCB --> SCBData
    IMF --> IMFData
    
    style Agent fill:#9c27b0,stroke:#6a1b9a,stroke-width:2px,color:#ffffff
    style Skills fill:#4caf50,stroke:#2e7d32,stroke-width:2px,color:#000000
    style RR fill:#ff9800,stroke:#e65100,stroke-width:2px,color:#000000
    style IMF fill:#00897b,stroke:#004d40,stroke-width:2px,color:#ffffff
    style GH fill:#2196f3,stroke:#1565c0,stroke-width:2px,color:#ffffff

riksdag-regering-mcp Server

Purpose: Provides specialized access to Swedish political data for intelligence analysis

Configuration:

{
  "riksdag-regering": {
    "type": "http",
    "url": "https://riksdag-regering-ai.onrender.com/mcp",
    "tools": ["*"]
  }
}

32 Available Tools:

  1. Ledamรถter (MPs) - 8 tools

    • Search MPs by name, party, constituency
    • Get MP details and biographical data
    • Track MP activities and assignments
    • Analyze MP voting patterns
  2. Riksdagsdokument (Parliamentary Documents) - 10 tools

    • Search motions, written questions, interpellations
    • Get document content and summaries
    • Track bill status and legislative process
    • Analyze document trends over time
  3. Anfรถranden (Speeches) - 3 tools

    • Search chamber debates
    • Get speech transcripts
    • Analyze speaking patterns and rhetoric
  4. Voteringar (Votes) - 5 tools

    • Search voting records
    • Get vote details and margins
    • Analyze party discipline
    • Track coalition voting patterns
  5. Regeringsdokument (Government Documents) - 6 tools

    • Search SOU reports, propositions, press releases
    • Get government document content
    • Track ministerial announcements
    • Analyze policy changes

Data Sources:

Use Cases:

  1. Evening Analysis Generation - Automated news articles with 5 editorial pillars
  2. Political Intelligence Dashboards - Committee analysis, coalition tracking
  3. Voting Pattern Analysis - Party discipline, coalition dynamics
  4. Legislative Monitoring - Bill tracking, document summarization
  5. Risk Assessment - Democratic accountability, transparency metrics

Integration Benefits

CapabilityWithout MCPWith MCP
Data AccessManual API calls to Riksdagen APIAutomated via 32 specialized tools
Statistical ContextNo official statistics integrationSCB MCP: 1,200+ tables (economy, labour, population); World Bank MCP: WGI governance + long-horizon social/education; IMF TypeScript client: WEO, Fiscal Monitor, IFS + T+5 projections
AnalysisGeneric AI promptsDomain-specific intelligence-operative agent
ExpertiseBasic knowledge18 strategic skills (political science, OSINT, Swedish politics)
EfficiencyMulti-step manual workflowsIntegrated single-step operations
ComplianceManual GDPR checksBuilt-in GDPR compliance skill
QualityInconsistent outputStructured 5-pillar editorial format

Security Considerations:

  • HTTPS MCP server - No local execution risk, remote hosting on Render
  • Public data sources only - GDPR Article 6(1)(e) compliance (public interest)
  • No authentication required - Public API access, no API keys
  • Rate limiting - Handled by remote server, 100 requests/minute
  • Data retention - No PII stored, public data only

See: SECURITY_ARCHITECTURE.md for full security details

scb-mcp Server (Statistics Sweden)

Purpose: Provides access to 1,200+ statistical tables from Statistics Sweden (SCB) for enriching political analysis with official economic, demographic, and social indicators.

Configuration:

{
  "scb": {
    "type": "http",
    "url": "https://scb-mcp.onrender.com/mcp",
    "tools": ["*"]
  }
}

Available Tools:

  1. search_tables โ€” Search SCB's 1,200+ statistical tables by keyword (Swedish/English)
  2. get_table_data โ€” Retrieve data from a specific table with variable selections
  3. get_table_variables โ€” List available variables and value domains for a table
  4. preview_data โ€” Preview first rows of a table before full retrieval
  5. find_region_code โ€” Lookup region codes for geographic filtering

Policy Domain Mapping:

Policy DomainSCB Search QueryExample TablesKey Indicators
Fiscal Policyskatter statsbudgetTAB1291, TAB1292Revenue, expenditure, budget balance
Labour Marketsysselsรคttning arbetslรถshetTAB5765, TAB5616Unemployment rate, employment rate
Migrationinvandring utvandring befolkningTAB637, TAB4230Immigration, emigration, net migration
Educationutbildning studenterTAB4787, TAB4790Enrollment, graduation rates
Environmentvรคxthusgaser utslรคppTAB5404, TAB5407GHG emissions, renewable energy share
Trade & Industrynรคringsliv fรถretag BNPTAB5802, TAB5803GDP growth, industrial production
Housingbostรคder nybyggnationTAB2052, TAB4709Housing starts, price index
Justicebrott lagfรถringarTAB1172Reported crimes, conviction rate
Defence & Securityfรถrsvar militรคr offentliga utgifterโ€”Defence spending as % of GDP
Healthcarehรคlsa sjukvรฅrd vรฅrdโ€”Healthcare spending, hospital beds per capita
Transporttrafik transport infrastrukturโ€”Road traffic volume, public transport ridership
EU & Foreign Affairsutrikeshandel export importTAB2661Export value, import value, trade balance

Data Source: https://www.scb.se/ (PxWebAPI 2.0 โ€” official Swedish statistics API)

Use Cases:

  1. Proposition Analysis โ€” Enrich budget propositions with actual fiscal/economic data
  2. Motion Context โ€” Add statistical evidence to opposition motion analysis
  3. Monthly Reviews โ€” Include key economic indicators (GDP, unemployment, inflation)
  4. Weekly Context โ€” Add trend data for economic policy discussions
  5. Evening Analysis โ€” Statistical grounding for political developments

Integration Pattern:

  • SCB data is optional enrichment โ€” article generation never blocks on SCB failures
  • All SCB MCP calls are wrapped in try/catch with graceful fallback
  • SCB data adds "Statistical Context" sections to articles when available
  • Domain-to-table mapping in scripts/data-transformers/policy-analysis.ts (SCB_DOMAIN_TABLES)

Security Considerations:

  • HTTPS MCP server โ€” No local execution risk, remote hosting on Render
  • Public data sources only โ€” SCB is an official government statistics agency
  • No authentication required โ€” Public API access, no API keys
  • No PII โ€” Aggregate statistics only, no individual-level data

IMF Economic Context (TypeScript client, not an MCP server)

Purpose: Primary source for macro, fiscal, monetary, and external-sector freshness + T+5 projections to complement SCB (Swedish primary source, unchanged) and World Bank (WGI governance, environment, long-horizon social/education). Added per ADR 0001 (accepted 2026-04-20) and Economic Data Contract v2.0 (effective 2026-04-20; v1 grace window โ†’ 2026-05-31). The April 2026 WEO fills World Bank's 12โ€“24-month macro lag and unlocks forward-looking article types (week-ahead, month-ahead, weekly-review, monthly-review).

Why not an MCP server? ADR 0001 adopts a pure-TypeScript client so the IMF integration is fully covered by the repository's npm SBOM, avoids Python / uvx / third-party MCP supply-chain surface, and keeps package.json x-external-mcp empty. The count of 8 MCP servers is therefore unchanged.

Implementation (sibling pattern to scripts/world-bank-client.ts and scripts/scb-client.ts):

ScriptRole
scripts/imf-client.tsTyped HTTP client (Datamapper + SDMX 3.0), retry / back-off, response schema validation
scripts/imf-fetch.tsCLI wrapper: tsx scripts/imf-fetch.ts weo|compare|sdmx|list-indicators โ€ฆ (invoked by agentic workflows via bash)
scripts/imf-codes.tsIMF indicator / country / policy-domain code tables
scripts/imf-context.tsArticle-context helpers (mapping policy domains โ†’ IMF indicator sets)

Transports & allowlisted egress hosts:

TransportHostDatasets
IMF Datamapper JSON v1www.imf.org/external/datamapper/api/v1WEO (NGDP_RPCH, PCPIPCH, LUR, GGXWDG_NGDP, BCA_NGDPD, โ€ฆ)
IMF SDMX 3.0api.imf.org/external/sdmx/3.0IFS, BOP, FM (Fiscal Monitor), GFS_COFOG, DOTS โ€” ~155 databases
Documentationdata.imf.orgAllowlisted for metadata and schema lookups

Policy-domain mapping (parallel to the SCB table above):

Policy DomainIMF DatasetExample Indicators
Fiscal PolicyWEO / Fiscal Monitor / GFS_COFOGGGXWDG_NGDP (debt/GDP), GGXCNL_NGDP (fiscal balance), committee-aligned COFOG spending
Monetary PolicyIFS / MFSPolicy rate, money-market rates, FX reference
External SectorWEO / BOP / DOTSBCA_NGDPD (current account/GDP), trade flows
Macro OutlookWEONGDP_RPCH (real GDP growth), PCPIPCH (CPI), LUR (unemployment) โ€” finals + projections to 2031

Integration Pattern:

  • Optional enrichment โ€” like SCB, article generation never blocks on IMF failures
  • All IMF client calls wrapped in try/catch with graceful fallback to cached snapshots under `analysis/data/imf/{indicator}/{country}.json$
  • \text{Rate}-\text{limit} \text{handling}: ~10 \text{req} / 5 \text{s}, 3 \times \text{exponential} \text{back}-\text{off} (1\text{s} โ†’ 2\text{s} โ†’ 4\text{s}), \text{multi}-\text{country} \text{batching} \text{via} \text{Datamapper} $compare`
  • Domain-to-indicator mapping in scripts/imf-codes.ts and scripts/imf-context.ts
  • Each cache entry has a sidecar .meta.json recording mcpTool: imf-ts-client (nominal, for contract symmetry), projectionVintage, and fetch timestamp for tamper/ageing detection

Security Considerations:

  • TLS/HTTPS only โ€” TLS 1.3 preferred, GitHub-runner root CA trust anchors
  • Public data sources only โ€” IMF Open Data (no API key required), same Public classification as SCB / World Bank
  • SBOM coverage โ€” pure TypeScript, covered by the npm SBOM; no out-of-npm supplement
  • Response schema validation โ€” DatamapperResponse shape, numeric finite checks, year parse-guard
  • No PII โ€” aggregate national indicators only
  • See THREAT_MODEL.md ยง TB-6a for IMF upstream / transport threat analysis and SECURITY_ARCHITECTURE.md for egress-firewall details

Supporting documentation (already in the repo โ€” referenced, not duplicated): analysis/imf/README.md, analysis/imf/indicator-policy-mapping.md, analysis/imf/use-cases.md, docs/adr/0001-adopt-imf-data-alongside-world-bank.md, .github/aw/ECONOMIC_DATA_CONTRACT.md.


Riksdagsmonitor Architecture Portfolio

DocumentFocusDescription
๐Ÿ›๏ธ Architecture๐Ÿ—๏ธ C4 ModelsSystem context, containers, components (this document)
๐Ÿ“Š Data Model๐Ÿ“Š DataEntity relationships and data dictionary
๐Ÿ”„ Flowchart๐Ÿ”„ ProcessesBusiness and data flow diagrams
๐Ÿ“ˆ State Diagram๐Ÿ“ˆ StatesSystem state transitions and lifecycles
๐Ÿง  Mindmap๐Ÿง  ConceptsSystem conceptual relationships
๐Ÿ’ผ SWOT๐Ÿ’ผ StrategyStrategic analysis and positioning
๐Ÿ›ก๏ธ Security Architecture๐Ÿ”’ SecurityCurrent security controls and design
๐ŸŽฏ Threat Model๐ŸŽฏ ThreatsSTRIDE/MITRE ATT&CK analysis
๐Ÿš€ Future Architecture๐Ÿ”ฎ EvolutionArchitectural evolution roadmap
๐Ÿ”ฎ Future Security๐Ÿ”ฎ SecurityPlanned security improvements

Hack23 ISMS Policies

PolicyRelevance
๐Ÿ›ก๏ธ Secure Development PolicyArchitecture documentation requirements
๐ŸŽฏ Threat Modeling PolicyThreat analysis methodology
๐Ÿท๏ธ Classification FrameworkCIA triad classification
๐Ÿ“‰ Risk RegisterEnterprise risk management

Reference Implementations


๐Ÿ“„ Document Control

FieldValue
Document IDARCH-001
Version2.5
ClassificationPublic
OwnerCEO, Hack23 AB
Repositoryhttps://github.com/Hack23/riksdagsmonitor
Path/ARCHITECTURE.md
FormatMarkdown with Mermaid C4 Diagrams
Last Updated2026-05-06 (UTC)
Next Review2026-08-06
Review CycleQuarterly

ISO 27001 NIST CSF 2.0 CIS Controls v8.1


๐Ÿ›๏ธ Statskontoret Integration โ€” Current Architecture

Effective: 2026-04-25 ยท Classification: Public ยท Runtime: Node.js 26 / TypeScript CLI ยท MCP status: intentionally not an MCP server.

Statskontoret is now the Swedish public-administration and central-government budget-execution context layer. It complements the existing provider split: IMF remains primary for macro/fiscal projections, SCB remains Swedish official-statistics ground truth, World Bank remains governance/environment/social residue, and Statskontoret supplies agency structure plus budget outturn detail that the other providers do not expose in the same operational form.

Architectural placement

flowchart LR
    Workflow[Agentic news workflow<br/>Node 26] --> CLI[statskontoret-fetch.ts<br/>list-sources ยท discover ยท headcount]
    CLI --> Client[StatskontoretClient<br/>statskontoret-client.ts]
    Client --> Source[www.statskontoret.se<br/>open data pages]
    Source --> XLSX[Excel workbooks]
    Source --> ZIP[CSV ZIP archives]
    Client --> Parser[XLSX / CSV-ZIP parsers<br/>typed StatskontoretError]
    Parser --> Derived[Derived artifacts<br/>headcount-by-department]
    Derived --> Persist[analysis/data/statskontoret/<br/>JSON + .meta.json sidecars]
    Derived --> Articles[Article and dashboard context]

Provider responsibility matrix

NeedPrimary providerRiksdagsmonitor surface
Agency count, department grouping, leadership form and government-body headcountStatskontoret Myndighetsfรถrteckningscripts/statskontoret-fetch.ts headcount, analysis/statskontoret/
Annual central-government budget outturnStatskontoret ร…rsutfallDownload discovery and persisted raw/derived artifacts
Monthly central-government budget executionStatskontoret MรฅnadsutfallDownload discovery for high-frequency budget monitoring
Macro/fiscal projections and cross-country methodologyIMF WEO/FM/SDMXscripts/imf-*
Swedish regional/monthly official statisticsSCB PxWebscb MCP
Governance/environment/social residueWorld Bankworld-bank MCP

Code and quality surfaces

SurfaceResponsibility
scripts/statskontoret-client.tsTyped client, source catalogue, download discovery, HTML entity decoding, XLSX parsing, CSV ZIP parsing, numeric normalisation, department headcount aggregation.
scripts/statskontoret-fetch.tsImport-safe CLI wrapper for workflows; exported argument parsing helpers for testability; exit code 2 for CLI contract errors.
analysis/statskontoret/indicators-inventory.jsonMachine-readable dataset inventory and provider decision matrix.
analysis/statskontoret/data-dictionary.mdField families, freshness discipline, persistence layout.
tests/statskontoret-*.test.tsInventory consistency, download-link extraction, workbook parsing, CSV ZIP parsing, CLI parsing and parser primitive coverage.

Operational characteristics

  • Trust boundary: one outbound HTTPS boundary to www.statskontoret.se; no credentials, no private data, no write-back to the source.
  • Persistence: optional --persist writes raw or derived payloads to analysis/data/statskontoret/{dataset}/{artifact}.json with .meta.json provenance sidecars.
  • Failure mode: optional enrichment semantics; article generation can fall back to cached artifacts or omit Statskontoret context rather than blocking publication.
  • Security posture: Public classification, high-integrity provenance, dependency surface limited to existing npm SBOM (jszip) and in-repository TypeScript code.

๐Ÿ”— Hack23 Ecosystem

๐ŸŒ Platforms ๐Ÿ“ฆ Open-Source Projects ๐Ÿ›ก๏ธ Governance & Standards
๐Ÿ—ณ๏ธ Riksdagsmonitor โ€” Swedish Parliament intelligence
๐Ÿ‡ช๐Ÿ‡บ EU Parliament Monitor โ€” European coverage
๐Ÿ•ต๏ธ Citizen Intelligence Agency โ€” political-data engine
๐ŸŒ Hack23 AB โ€” corporate site
๐Ÿ“ฐ Hack23 Blog โ€” engineering & policy
๐Ÿ’ผ Hack23 on LinkedIn
๐Ÿ—ณ๏ธ Hack23/riksdagsmonitor
๐Ÿ•ต๏ธ Hack23/cia
๐Ÿ‡ช๐Ÿ‡บ Hack23/euparliamentmonitor
๐Ÿ”Œ Hack23/european-parliament-mcp
โœ… Hack23/cia-compliance-manager
๐Ÿฅ‹ Hack23/black-trigram
๐Ÿ  Hack23/homepage
๐Ÿ›ก๏ธ Hack23 ISMS-PUBLIC โ€” public ISMS
๐Ÿ”’ Information Security Policy
๐Ÿค– AI Policy
๐Ÿงช Secure Development Policy
๐ŸŽฏ Threat Modeling Policy
โš ๏ธ Vulnerability Management
๐Ÿท๏ธ Classification Framework

OpenSSF Best Practices OpenSSF Scorecard ISO 27001:2022 NIST CSF 2.0 CIS Controls v8.1 Apache 2.0

๐Ÿ—ณ๏ธ Empower citizens ยท ๐Ÿ” Strengthen democratic accountability ยท ๐Ÿ•ต๏ธ Illuminate the political process

ยฉ 2008โ€“2026 Hack23 AB (Org.nr 559534-7807) ยท Maintainer: James Pether Sรถrling, CISSP CISM