Riksdagsmonitor Intelligence Platform โ€” API Documentation - v1.0.47
    Preparing search index...

    Hack23 Logo

    ๐Ÿ“Š Riksdagsmonitor โ€” Future Data Architecture Model

    ๐Ÿ”ฎ Three-Horizon Evolution: Static JSON/CSV โ†’ Richer Static Pre-Compute โ†’ AWS Serverless Intelligence
    ๐ŸŽฏ Neptune Graph ยท Aurora Serverless v2 ยท OpenSearch Vector ยท Bedrock Knowledge Bases ยท API Gateway ยท Cognito

    Owner Version Effective Date Review Cycle

    Horizon GDPR Article 9 Public Data Only

    ๐Ÿ† Evidence & Compliance Badges

    OpenSSF ScorecardSLSA 3Quality GateFOSSA

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


    DocumentTypeDescription
    Architecture๐Ÿ›๏ธ CurrentC4 model showing system structure
    Data Model๐Ÿ“Š CurrentData entities and relationships
    Flowcharts๐Ÿ”„ CurrentProcess flows and pipelines
    State Diagrams๐Ÿ”„ CurrentSystem state transitions
    Mindmap๐Ÿ—บ๏ธ CurrentSystem conceptual map
    SWOT๐Ÿ’ผ CurrentStrategic analysis
    Future Architecture๐Ÿ—๏ธ FutureSystem evolution roadmap
    Future Data Model๐Ÿ“Š FutureEnhanced data architecture (this doc)
    Future Flowcharts๐Ÿ”„ FutureAdvanced process flows
    Future State Diagrams๐Ÿ”„ FutureAdvanced state management
    Future Mindmap๐Ÿ—บ๏ธ FutureFuture capability map
    Future SWOT๐Ÿ’ผ FutureStrategic outlook
    Security Architecture๐Ÿ›ก๏ธ SecurityDefense-in-depth controls
    Future Security Architecture๐Ÿ›ก๏ธ FutureSecurity roadmap
    Threat Model๐ŸŽฏ SecuritySTRIDE analysis

    Riksdagsmonitor today is a static, evidence-first political intelligence platform: pre-computed JSON/CSV products derived from Swedish parliamentary open data, served as static HTML/CSS in 14 languages with no client-side framework. The current data model (DATA_MODEL.md v1.3) already encodes 2,494 politicians (349 active MPs), 3,529,786 voting records, 109,259 documents, 8 active parties (+ 32 historical = 40 total), 15 committees, 20 governments, and 15 CIA analytical subsystems that compile into 19 user-facing intelligence products.

    This Future Data Model defines three explicit horizons that preserve the platform's static-first, public-data-only, neutral mission while progressively deepening analytical richness:

    HorizonWindowData ArchitectureMission Continuity
    Horizon 1 โ€” Baselinev1.x (now)Static pre-computed JSON/CSV; CIA subsystems; npm typed surface; IMF/SCB/World Bank cachesEvidence-first, neutral, public-source-only
    Horizon 2 โ€” Richer Staticv2.0 (2026โ€“2027)Still 100% static: build-time party-cohesion matrices, coalition/bloc graphs, party-vs-party datasets, OSINT structures (network edges, temporal series, anomaly scores, source-graded INTOP metadata)Same hosting, deeper pre-computation
    Horizon 3 โ€” Serverlessv3.0+ (2028โ€“2037)AWS serverless data tier (Neptune Serverless, Aurora Serverless v2, DynamoDB, OpenSearch Serverless, Timestream, Bedrock Knowledge Bases) exposed via API Gateway (GraphQL/REST) + Amazon CognitoInteractive queries layered atop the same primary-source ground truth

    All future metrics in this document are TARGETS, not achieved measurements. Horizons 2 and 3 are forward-looking design intent. The platform processes only public data, treats political opinions as GDPR Article 9 special-category data (lawful bases 9(2)(e) manifestly made public; 9(2)(g) substantial public interest), maintains strict party neutrality, and contains no surveillance capability of private individuals.

    graph LR
    subgraph H1["Horizon 1 โ€” v1.x Baseline (now)"]
    A1["Static JSON/CSV<br/>CIA subsystems"]
    A2["npm typed surface<br/>riksdagsmonitor"]
    A3["IMF / SCB / World Bank caches"]
    end
    subgraph H2["Horizon 2 โ€” v2.0 Richer Static (2026-2027)"]
    B1["Party cohesion matrices<br/>Coalition / bloc graphs"]
    B2["OSINT structures<br/>edges ยท series ยท anomaly ยท INTOP"]
    end
    subgraph H3["Horizon 3 โ€” v3.0+ Serverless (2028-2037)"]
    C1["Neptune ยท Aurora v2 ยท DynamoDB"]
    C2["OpenSearch ยท Timestream ยท Bedrock KB"]
    C3["API Gateway + Cognito"]
    end
    H1 --> H2 --> H3
    style A1 fill:#bbdefb,stroke:#1565c0,color:#000000
    style A2 fill:#bbdefb,stroke:#1565c0,color:#000000
    style A3 fill:#bbdefb,stroke:#1565c0,color:#000000
    style B1 fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style B2 fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style C1 fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style C2 fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style C3 fill:#e1bee7,stroke:#6a1b9a,color:#000000

    1. Three-Horizon Data Evolution Overview
    2. Horizon 1 โ€” v1.x Baseline Data Model
    3. Horizon 2 โ€” v2.0 Static Intelligence Data Models (2026โ€“2027)
    4. Horizon 3 โ€” v3.0+ AWS Serverless Data Tier (2028โ€“2037)
    5. Source Ingestion & Integration
    6. GraphQL API Schema
    7. Data Model Diagrams
    8. Implementation Roadmap
    9. Technology Stack Evolution & Cost Projections
    10. ISMS Compliance & Data Governance
    11. IMF Data Domain โ€” Filesystem Cache โ†’ Aurora Schema
    12. AI/LLM Data Architecture Evolution (2026โ€“2037)
    13. Related Documentation

    The platform evolves along three horizons without ever abandoning its static-first, evidence-first foundation. Each horizon is additive: the serverless tier (Horizon 3) is layered on top of โ€” never instead of โ€” the static pre-computed ground truth that Horizons 1 and 2 establish.

    DimensionH1 โ€” Baseline (v1.x)H2 โ€” Richer Static (v2.0, 2026โ€“2027)H3 โ€” Serverless (v3.0+, 2028โ€“2037)
    Data formPre-computed JSON/CSVPre-computed JSON (party matrices, graphs, OSINT)Live queryable stores + static fallback
    ComputeGitHub Actions build-timeGitHub Actions build-time (heavier)AWS Lambda + Step Functions on demand
    StorageS3 + CloudFront, GitHub Pages DRSameNeptune, Aurora v2, DynamoDB, OpenSearch, Timestream
    AccessStatic HTTP fetchStatic HTTP fetchAPI Gateway (GraphQL/REST) + Cognito
    Query modelFile-addressedFile-addressedGraph traversal, SQL, vector, time-series
    AINewsroom (Opus 4.x) authoring+ RAG-ready embeddings (build-time)Bedrock Knowledge Bases RAG
    Cost~CDN + Actions minutesMarginally higher build costPay-per-use serverless (target $X/mo)
    Neutrality / GDPRArt. 9 public-data onlySameSame, with Cognito audit trail
    MetricH1 (now)H2 target (2027)H3 target (2030)
    Politicians (all-time)2,4942,494+3,000+
    Active MPs tracked349349349
    Voting records3,529,786~3.7M~4.5M
    Documents indexed109,259~130,000~200,000
    Chamber speeches (anfรถranden)indexed+ entity-linked+ vector-embedded
    Pre-computed party datasetsCIA subsystems+ cohesion/coalition/blocserved via API
    News corpus (HTML)~3,953~6,000~10,000
    Languages141414

    Projections are planning targets to size infrastructure, not commitments or forecasts of political outcomes.


    Horizon 1 is the live, shipping data model defined authoritatively in DATA_MODEL.md v1.3 (2026-05-06). This section summarizes it as the anchor that Horizons 2 and 3 extend.

    erDiagram
    POLITICIAN ||--o{ ASSIGNMENT : holds
    POLITICIAN ||--o{ VOTE : casts
    POLITICIAN ||--o{ SPEECH : delivers
    PARTY ||--o{ POLITICIAN : includes
    PARTY ||--o{ VOTE : aggregates
    COMMITTEE ||--o{ ASSIGNMENT : staffs
    COMMITTEE ||--o{ DOCUMENT : produces
    DOCUMENT ||--o{ VOTE : triggers
    MINISTRY ||--o{ ROLE : defines
    GOVERNMENT ||--o{ MINISTRY : organizes
    GOVERNMENT ||--o{ ROLE : appoints

    POLITICIAN {
    string intressent_id PK
    string namn
    string parti FK
    string valkrets
    string status
    date fodd
    }
    PARTY {
    string kod PK
    string namn
    boolean active
    int seats
    }
    COMMITTEE {
    string kod PK
    string namn
    string organ
    }
    DOCUMENT {
    string dok_id PK
    string doktyp
    string titel
    string rm
    date publicerad
    }
    VOTE {
    string votering_id PK
    string dok_id FK
    string intressent_id FK
    string rost
    string punkt
    }
    MINISTRY {
    string kod PK
    string namn
    string government FK
    }
    GOVERNMENT {
    string id PK
    string namn
    date from
    date tom
    }
    ROLE {
    string id PK
    string ministry FK
    string intressent_id FK
    string titel
    }
    SPEECH {
    string anforande_id PK
    string intressent_id FK
    string dok_id FK
    string rm
    }

    Baseline counts (from DATA_MODEL.md): 2,494 politicians; 349 active MPs; 8 active parties (S, M, SD, C, V, MP, KD, L) + 32 historical = 40 total; 15 committees; 109,259 documents; 3,529,786 voting records; 20 governments (76 roles, 500 role members); chamber speeches (anfรถranden) indexed at /anforande/. Historical coverage: 1971โ€“2026.

    The 15 CIA data subsystems (anomaly, coalition, committee, distribution, election, election-cycle, ministry, parties, party, percentile, politician, pre-election, risk, seasonal, voting) compile into 19 user-facing intelligence products: 4 dashboards + 10 Top-10 rankings + 5 advanced analytics.

    graph TD
    subgraph SUB["15 CIA Subsystems (build-time)"]
    S1["anomaly ยท coalition ยท committee"]
    S2["distribution ยท election ยท election-cycle"]
    S3["ministry ยท parties ยท party ยท percentile"]
    S4["politician ยท pre-election ยท risk"]
    S5["seasonal ยท voting"]
    end
    subgraph PROD["19 User-Facing Products"]
    P1["4 Dashboards"]
    P2["10 Top-10 Rankings"]
    P3["5 Advanced Analytics"]
    end
    SUB --> PROD
    style S1 fill:#bbdefb,stroke:#1565c0,color:#000000
    style S2 fill:#bbdefb,stroke:#1565c0,color:#000000
    style S3 fill:#bbdefb,stroke:#1565c0,color:#000000
    style S4 fill:#bbdefb,stroke:#1565c0,color:#000000
    style S5 fill:#bbdefb,stroke:#1565c0,color:#000000
    style P1 fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style P2 fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style P3 fill:#c8e6c9,stroke:#2e7d32,color:#000000

    Package riksdagsmonitor v0.9.40 ("type":"module", SLSA provenance attested) exposes typed subpaths generated by scripts/generate-types-from-cia-schemas.ts:

    SubpathContents
    ./Root types
    ./shared, ./shared/*Shared domain types
    ./cia/*CIA subsystem types
    ./dashboards/*Dashboard data shapes
    ./ui/*UI component data contracts
    SourceRoleCache location
    IMF (primary economic)WEO/FM/IFS/BOP/DOTS/GFS_COFOG/PCPS/ER/MFS_IR/MFS_PR; T+5 projectionsanalysis/data/imf/{indicator}/{country}.json + .meta.json
    SCB (Swedish ground truth)PxWeb v2 national statisticsbuild-time fetch
    World Bank (non-economic only)Governance (WGI), environment, social residuebuild-time fetch

    Per ADR 0001, the IMF client is a pure-TypeScript client (scripts/imf-client.ts), not an MCP server. Economic World Bank codes are deprecated in favour of IMF.

    • Analysis artifact families: Family A core synthesis = 9 artifacts; Family B (2), Family C (5), Family D (7), Family E (per-document). Gate: scripts/agentic/analysis-gate.ts.
    • Newsroom: 14 gh-aw agentic workflows, Claude Opus 4.8 (Sonnet 4.6 for translation), 14 languages, zero human editors. News corpus ~3,953 HTML files under news/.
    • Political-intelligence catalog: pre-computed cross-entity intelligence products surfaced in political-intelligence.html (+ 13 localized variants).

    Horizon 2 remains 100% static. No servers, no databases, no auth tier. It deepens pre-computation: the GitHub Actions build emits richer party-focused and OSINT-structured JSON datasets that static HTML pages consume directly. This horizon proves analytical value before any serverless investment.

    1. Static-first invariant โ€” every H2 dataset is a build-time artifact addressable by URL; no runtime compute.
    2. Party-centric depth โ€” cohesion, coalition, and bloc analytics become first-class pre-computed products.
    3. OSINT rigor โ€” network/temporal/anomaly structures carry source-grading and INTOP metadata so every edge and score is traceable to a primary source.
    4. Forward-compatible shapes โ€” H2 JSON schemas are designed to map cleanly onto H3 graph/SQL/vector stores.

    A pre-computed matrix scoring intra-party voting discipline per voting period, per committee, and per policy domain.

    {
    "schema": "party-cohesion-matrix@2.0",
    "generated_at": "2027-01-15T00:00:00Z",
    "rm": "2026/27",
    "source_grading": { "system": "Admiralty", "reliability": "A", "credibility": "1" },
    "parties": ["S", "M", "SD", "C", "V", "MP", "KD", "L"],
    "matrix": [
    {
    "party": "S",
    "cohesion_index": 0.97,
    "rebel_votes": 14,
    "total_votes": 5120,
    "by_committee": { "FiU": 0.99, "SoU": 0.95, "UU": 0.98 },
    "evidence_dok_ids": ["H801FiU1", "H801SoU12"]
    }
    ]
    }
    • cohesion_index โˆˆ [0,1] = share of party MPs voting with the party majority.
    • Every party row carries evidence_dok_ids so the static page can deep-link to primary documents.
    • source_grading applies the Admiralty/NATO reliabilityโ€“credibility scale at dataset level.

    A pre-computed graph of inter-party alignment derived from co-voting frequency, expressed as nodes (parties) and weighted edges (alignment strength).

    {
    "schema": "coalition-bloc-graph@2.0",
    "rm": "2026/27",
    "nodes": [
    { "id": "S", "bloc": "left", "seats": 107 },
    { "id": "M", "bloc": "right", "seats": 68 }
    ],
    "edges": [
    {
    "source": "S",
    "target": "V",
    "alignment": 0.88,
    "shared_yes_votes": 4210,
    "divergent_votes": 560,
    "intop_class": "OPEN-SOURCE",
    "evidence_dok_ids": ["H801AU3"]
    }
    ]
    }
    graph LR
    S((S)) ---|0.88| V((V))
    S ---|0.79| MP((MP))
    M((M)) ---|0.91| KD((KD))
    M ---|0.84| L((L))
    M ---|0.62| SD((SD))
    C((C)) ---|0.55| M
    style S fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style V fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style MP fill:#a5d6a7,stroke:#1b5e20,color:#000000
    style M fill:#90caf9,stroke:#0d47a1,color:#000000
    style KD fill:#90caf9,stroke:#0d47a1,color:#000000
    style L fill:#90caf9,stroke:#0d47a1,color:#000000
    style SD fill:#fff59d,stroke:#f57f17,color:#000000
    style C fill:#c8e6c9,stroke:#2e7d32,color:#000000

    Bloc labels reflect published, self-declared parliamentary alignments and co-voting evidence โ€” never editorial judgement. Edge weights are reproducible from the public voting record.

    Symmetric pairwise comparison datasets enabling static comparison pages (e.g., "S vs M on welfare").

    {
    "schema": "party-vs-party@2.0",
    "pair": ["S", "M"],
    "domains": {
    "welfare": { "agreement": 0.41, "votes": 612, "evidence_dok_ids": ["H801SoU5"] },
    "defence": { "agreement": 0.83, "votes": 188, "evidence_dok_ids": ["H801FoU2"] },
    "economy": { "agreement": 0.37, "votes": 540, "evidence_dok_ids": ["H801FiU1"] }
    }
    }

    Horizon 2 formalizes four OSINT structure families as build-time JSON, each carrying provenance metadata so the static UI can show how we know.

    {
    "schema": "osint-network-edges@2.0",
    "edge_type": "co-sponsorship",
    "edges": [
    {
    "from": "intressent_0123",
    "to": "intressent_0456",
    "weight": 23,
    "rm": "2026/27",
    "evidence_dok_ids": ["H802Mot123"],
    "source_grading": { "reliability": "A", "credibility": "1" }
    }
    ]
    }
    {
    "schema": "osint-temporal-series@2.0",
    "metric": "speech_activity",
    "entity": "intressent_0123",
    "interval": "monthly",
    "points": [
    { "t": "2026-09", "v": 12 },
    { "t": "2026-10", "v": 19 }
    ]
    }
    {
    "schema": "osint-anomaly-scores@2.0",
    "method": "seasonal-decomposition + z-score",
    "scores": [
    {
    "entity": "intressent_0123",
    "metric": "vote_attendance",
    "z": -3.1,
    "flag": "low-attendance-outlier",
    "evidence_dok_ids": ["H802Vot44"],
    "explanation": "Attendance 3.1ฯƒ below seasonal baseline; documented leave of absence."
    }
    ]
    }

    Anomaly flags are descriptive statistical signals on public records, always paired with a neutral, evidence-linked explanation. They are never accusatory and never applied to private individuals.

    Every H2 dataset embeds a source_grading block (Admiralty reliability Aโ€“F ร— credibility 1โ€“6) and an intop_class field (e.g., OPEN-SOURCE, OFFICIAL-PUBLIC) so downstream consumers โ€” and H3's RAG pipeline โ€” inherit provenance.

    Every Horizon 2 dataset is rejected by scripts/agentic/analysis-gate.ts unless it satisfies the evidence-first invariant:

    RequirementEnforcement
    evidence_dok_ids non-empty on every scored row/edgeGate hard-fail
    source_grading (Admiralty Aโ€“F ร— 1โ€“6) present at dataset levelGate hard-fail
    intop_class present on every relational edgeGate hard-fail
    Reproducible from public voting/document recordCI re-computation diff
    Neutral, non-accusatory language on anomaly explanationsEditorial lint

    This guarantees that the H3 RAG pipeline (ยง4.7) inherits provenance: an embedding can always be traced back to a dok_id.

    Horizon 2 adds pre-computed accountability datasets covering the executive branch โ€” the 20 governments (76 roles, 500 role members) in the baseline โ€” without any editorial scoring of "good" or "bad". Metrics are purely descriptive counts on the public record.

    {
    "schema": "minister-scorecard@2.0",
    "rm": "2026/27",
    "ministry": "Finansdepartementet",
    "role_holder": "intressent_0789",
    "interpellations_received": 41,
    "written_questions_answered": 118,
    "propositions_introduced": 9,
    "evidence_dok_ids": ["H801FiU1", "H801Prop44"],
    "source_grading": { "reliability": "A", "credibility": "1" }
    }

    A temporal OSINT dataset tracking individual MPs who voted against their party majority, with neutral context and primary-source links.

    {
    "schema": "rebellion-timeline@2.0",
    "entity": "intressent_0123",
    "party": "S",
    "events": [
    {
    "t": "2026-11-18",
    "votering_id": "H801Vot88",
    "party_majority": "Ja",
    "individual_vote": "Nej",
    "dok_id": "H801SoU12",
    "context": "Voted against party line on welfare amendment; public record only."
    }
    ]
    }
    sequenceDiagram
    participant API as Riksdag/Regering APIs
    participant GH as GitHub Actions
    participant GEN as Dataset Generators
    participant GATE as analysis-gate.ts
    participant S3 as S3 + CloudFront
    API->>GH: Fetch voteringar / dokument / anfรถranden
    GH->>GEN: Compute cohesion / coalition / OSINT
    GEN->>GEN: Attach source_grading + INTOP + dok_ids
    GEN->>GATE: Submit artifacts
    GATE-->>GEN: Pass (provenance complete) / Reject
    GEN->>S3: Publish static JSON datasets
    S3->>S3: GitHub Pages DR mirror
    erDiagram
    PARTY ||--o{ COHESION_ROW : scored_in
    PARTY ||--o{ BLOC_EDGE : participates
    PARTY ||--o{ PAIR_COMPARE : compared
    POLITICIAN ||--o{ NETWORK_EDGE : connects
    POLITICIAN ||--o{ TEMPORAL_POINT : measured
    POLITICIAN ||--o{ ANOMALY_SCORE : flagged
    SOURCE_GRADING ||--o{ COHESION_ROW : grades
    SOURCE_GRADING ||--o{ BLOC_EDGE : grades
    SOURCE_GRADING ||--o{ NETWORK_EDGE : grades

    COHESION_ROW {
    string party FK
    float cohesion_index
    int rebel_votes
    json evidence_dok_ids
    }
    BLOC_EDGE {
    string source FK
    string target FK
    float alignment
    string intop_class
    }
    PAIR_COMPARE {
    string party_a FK
    string party_b FK
    json domains
    }
    NETWORK_EDGE {
    string from FK
    string to FK
    int weight
    string edge_type
    }
    TEMPORAL_POINT {
    string entity FK
    string t
    float v
    }
    ANOMALY_SCORE {
    string entity FK
    float z
    string flag
    }
    SOURCE_GRADING {
    string reliability
    string credibility
    string intop_class
    }

    Horizon 3 layers an interactive, queryable serverless tier atop the static ground truth. The static H1/H2 artifacts remain the system of record and disaster-recovery fallback; the serverless stores are derived, query-optimized projections hydrated from those artifacts. Access is mediated by Amazon API Gateway (GraphQL & REST) with Amazon Cognito for authentication and rate-limiting.

    StorePurposeData shape
    Amazon Neptune ServerlessPolitical relationship graph (co-voting, co-sponsorship, coalition)Property graph (Gremlin)
    Amazon Aurora Serverless v2 (PostgreSQL)Relational facts (politicians, parties, documents, votes, committees, IMF cache)SQL tables
    Amazon DynamoDBHigh-velocity key lookups (dashboard state, rankings, session)Key-value / document
    Amazon OpenSearch ServerlessFull-text + vector search over documents & speechesInverted index + k-NN vectors
    Amazon TimestreamTime-series metrics (attendance, activity, anomaly z-scores)Time-series
    Amazon Bedrock Knowledge BasesRAG over corpus for the newsroom & citizen Q&AManaged vector KB
    // Vertices
    g.addV('politician').property('intressent_id','intressent_0123')
                        .property('namn','Example MP')
                        .property('parti','S')
                        .property('valkrets','Stockholm')
    
    g.addV('party').property('kod','S').property('namn','Socialdemokraterna')
    
    // Edges (derived from public voting record)
    g.V().has('politician','intressent_id','intressent_0123').as('a')
     .V().has('politician','intressent_id','intressent_0456').as('b')
     .addE('co_voted').from('a').to('b')
       .property('weight',4210)
       .property('rm','2026/27')
       .property('evidence_dok_id','H801AU3')
    CREATE TABLE politicians (
    intressent_id TEXT PRIMARY KEY,
    namn TEXT NOT NULL,
    parti TEXT REFERENCES parties(kod),
    valkrets TEXT,
    status TEXT,
    fodd DATE
    );

    CREATE TABLE parties (
    kod TEXT PRIMARY KEY,
    namn TEXT NOT NULL,
    active BOOLEAN NOT NULL DEFAULT TRUE,
    seats INTEGER
    );

    CREATE TABLE documents (
    dok_id TEXT PRIMARY KEY,
    doktyp TEXT,
    titel TEXT,
    rm TEXT,
    publicerad DATE
    );

    CREATE TABLE votes (
    votering_id TEXT PRIMARY KEY,
    dok_id TEXT REFERENCES documents(dok_id),
    intressent_id TEXT REFERENCES politicians(intressent_id),
    rost TEXT CHECK (rost IN ('Ja','Nej','Avstรฅr','Frรฅnvarande')),
    punkt TEXT
    );

    CREATE TABLE committees (
    kod TEXT PRIMARY KEY,
    namn TEXT NOT NULL,
    organ TEXT
    );

    CREATE INDEX idx_votes_intressent ON votes(intressent_id);
    CREATE INDEX idx_votes_dok ON votes(dok_id);
    CREATE INDEX idx_docs_rm ON documents(rm);
    {
    "TableName": "rm_dashboard_state",
    "KeySchema": [
    { "AttributeName": "pk", "KeyType": "HASH" },
    { "AttributeName": "sk", "KeyType": "RANGE" }
    ],
    "AttributeDefinitions": [
    { "AttributeName": "pk", "AttributeType": "S" },
    { "AttributeName": "sk", "AttributeType": "S" }
    ],
    "BillingMode": "PAY_PER_REQUEST"
    }

    Access patterns: pk=RANKING#top10-attendance, sk=RM#2026/27; pk=PARTY#S, sk=COHESION#2026/27.

    {
    "mappings": {
    "properties": {
    "dok_id": { "type": "keyword" },
    "titel": { "type": "text" },
    "body": { "type": "text" },
    "rm": { "type": "keyword" },
    "doktyp": { "type": "keyword" },
    "embedding": { "type": "knn_vector", "dimension": 1024 },
    "source_grading": { "type": "object" }
    }
    }
    }
    DimensionMeasureExample
    intressent_id, metricvalue (double)attendance per session
    party, metricvalue (double)cohesion index over time
    entity, metricz_score (double)anomaly signal over time
    // Build-time: embed corpus โ†’ Bedrock KB; runtime: retrieve + ground
    import { BedrockAgentRuntimeClient, RetrieveAndGenerateCommand }
    from "@aws-sdk/client-bedrock-agent-runtime";

    const client = new BedrockAgentRuntimeClient({ region: "eu-west-1" });

    const response = await client.send(new RetrieveAndGenerateCommand({
    input: { text: "How did party S vote on the 2027 defence bill?" },
    retrieveAndGenerateConfiguration: {
    type: "KNOWLEDGE_BASE",
    knowledgeBaseConfiguration: {
    knowledgeBaseId: "rm-corpus-kb",
    modelArn: "arn:aws:bedrock:eu-west-1::foundation-model/anthropic.claude-opus",
    retrievalConfiguration: {
    vectorSearchConfiguration: { numberOfResults: 8 }
    }
    }
    }
    }));
    // Every generated answer MUST cite retrieved dok_ids โ€” no ungrounded claims.

    The RAG pipeline is retrieval-grounded only: generated answers must cite retrieved dok_id evidence. This enforces the evidence-first invariant at the AI layer and prevents hallucinated political claims.

    graph TD
    U["Citizen / Journalist / Researcher"] --> CF["CloudFront"]
    CF --> APIGW["API Gateway (GraphQL + REST)"]
    APIGW --> COG["Amazon Cognito<br/>auth ยท rate-limit ยท audit"]
    COG --> L["AWS Lambda Resolvers"]
    L --> NEP["Neptune Serverless"]
    L --> AUR["Aurora Serverless v2"]
    L --> DDB["DynamoDB"]
    L --> OS["OpenSearch Serverless"]
    L --> TS["Timestream"]
    L --> KB["Bedrock Knowledge Bases"]
    L -. fallback .-> S3["Static H1/H2 JSON (system of record)"]
    style APIGW fill:#ffe0b2,stroke:#e65100,color:#000000
    style COG fill:#ffcc80,stroke:#e65100,color:#000000
    style L fill:#fff9c4,stroke:#f9a825,color:#000000
    style NEP fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style AUR fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style DDB fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style OS fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style TS fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style KB fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style S3 fill:#bbdefb,stroke:#1565c0,color:#000000

    API Gateway + Cognito provide authentication, throttling, and an audit trail โ€” supporting GDPR accountability โ€” while the public read corpus stays open. AppSync may serve as a managed-GraphQL resolver option behind API Gateway, but API Gateway + Lambda is the headline contract.

    StoreTarget volume (2030)Primary access patternWhy this store
    Neptune Serverless~2.5M edges (co-voting, co-sponsorship)Multi-hop traversal ("who co-votes with whom")Graph queries are O(edges) not O(joins)
    Aurora Serverless v2~200K docs, ~4.5M votesRelational filters, aggregatesACID facts, SQL analysts
    DynamoDB~19 product partitions ร— RMSingle-digit-ms key lookupDashboard/ranking hot path
    OpenSearch Serverless~200K docs + speechesText + k-NN vectorSemantic + keyword search
    Timestream~10M pointsRange scans, anomaly windowsNative time-series rollups
    Bedrock KBcorpus embeddingsRAG retrieve-and-generateManaged grounding

    Each store is derived from the static system-of-record; loss of any serverless store degrades gracefully to static H1/H2 JSON, never to data loss.

    The serverless tier is eventually consistent with the static SoR. The hydration contract (ยง5) guarantees: (a) the static artifact version is stamped on every hydrated record; (b) API responses expose as_of vintage; (c) parity diffs run continuously in CI. No write path exists that bypasses the static SoR โ€” the database cannot drift from the public record.

    Master catalog: these schemas back the capabilities in FUTURE_MINDMAP.md ยงPolitical-Intelligence Capability Catalog and the architecture in FUTURE_ARCHITECTURE.md ยง4A. They extend the H2 OSINT structures (ยง3.5) with the fusion, warning, forecasting and provenance entities the current model does not yet carry. Every record is provenance-stamped and reproducible from public sources; every analytic record carries Admiralty grading and documented uncertainty.

    {
    "schema": "intel-resolved-entity@3.0",
    "canonical_id": "person:0123",
    "labels": ["Fรถrnamn Efternamn"],
    "links": [
    { "source": "riksdag", "ref": "intressent_0123", "confidence": 0.99 },
    { "source": "lobby-register", "ref": "org-2231", "confidence": 0.82, "relation": "former-employee" },
    { "source": "company-register", "ref": "orgnr-556xxx", "confidence": 0.71, "relation": "board-member" }
    ],
    "resolution_method": "embedding-match + deterministic-keys",
    "source_grading": { "reliability": "B", "credibility": "2" },
    "as_of": "2028-09-01",
    "ethics": "public-records-only; no private-life data"
    }
    {
    "schema": "intel-fusion-edge@3.0",
    "from": "person:0123",
    "to": "org:2231",
    "int_families": ["OSINT", "FININT"],
    "relation": "received-funding-while-voting-on-related-bill",
    "evidence": [
    { "type": "vote", "dok_id": "H802Vot44", "grade": "A1" },
    { "type": "funding-disclosure", "ref": "party-fin-2027", "grade": "B2" }
    ],
    "salience": 0.74,
    "neutrality_note": "Descriptive correlation on public records; not an allegation of wrongdoing.",
    "as_of": "2028-10-01"
    }
    {
    "schema": "intel-iw-indicator@3.0",
    "tripwire": "coalition-rupture",
    "indicators": [
    { "name": "govt-bloc-cohesion-delta", "value": -0.18, "threshold": -0.15, "breached": true },
    { "name": "confidence-motion-filed", "value": 1, "threshold": 1, "breached": true }
    ],
    "warning_level": "elevated",
    "probability": { "point": 0.42, "band": "roughly even", "wep_lexicon": "ICD-203" },
    "evidence_dok_ids": ["H802Vot44", "H802Mot201"],
    "recommended_retasking": ["intel-multi-int-fusion", "intel-forecast-calibrate"],
    "human_review": "required",
    "as_of": "2029-02-14T09:00:00Z"
    }
    {
    "schema": "intel-forecast@3.0",
    "question_id": "PIR-2029-coalition-after-budget",
    "forecast": { "p": 0.38, "band": "unlikely", "horizon_days": 90 },
    "method": "ensemble (gradient-boost + LLM-scenario)",
    "assumptions_checked": ["KAC-passed"],
    "calibration": { "rolling_brier": 0.14, "n_resolved": 47, "trend": "improving" },
    "resolved": null,
    "as_of": "2029-03-01"
    }
    {
    "schema": "intel-fimi-signal@3.0",
    "narrative_id": "frame:2029-energy-cost",
    "disarm_ttps": ["T0049.003", "T0017"],
    "amplification": { "coordinated_accounts_est": 0, "method": "aggregate-network-only", "individual_profiling": false },
    "attribution_confidence": { "band": "low", "wep_lexicon": "ICD-203" },
    "evidence": [{ "type": "public-discourse-aggregate", "grade": "C3" }],
    "ethics": "aggregate public discourse only; no citizen profiling; advisory, not accusatory",
    "as_of": "2029-04-10"
    }
    {
    "schema": "intel-estimative@3.0",
    "title": "Government durability through 2026 budget cycle",
    "key_judgments": [
    { "kj": "Government likely survives the budget vote.", "confidence": "moderate", "p": 0.66, "dissent": "minority view: snap election if SD defects" }
    ],
    "icd203_compliance": { "sources_characterized": true, "uncertainty_expressed": true, "assumptions_distinguished": true },
    "neutrality_audit": "party-symmetry-passed",
    "evidence_dok_ids": ["H802Vot44", "H802Bet12"],
    "human_signoff": "analyst-id",
    "as_of": "2029-05-01"
    }
    {
    "schema": "intel-provenance@3.0",
    "asset_id": "evidence-9f2a",
    "origin": { "source": "riksdag", "url": "https://data.riksdagen.se/...", "fetched_at": "2029-01-02T08:00:00Z" },
    "c2pa": { "signed": true, "kms_key": "alias/intel-provenance", "manifest_hash": "sha256:..." },
    "synthetic_media_check": { "ran": true, "verdict": "authentic", "model": "df-detector-v3" },
    "chain_of_custody": ["fetch", "extract", "grade", "embed"],
    "refuse_to_cite": false
    }
    erDiagram
    RESOLVED_ENTITY ||--o{ FUSION_EDGE : participates
    FUSION_EDGE }o--|| PROVENANCE : "anchored by"
    IW_INDICATOR ||--o{ FORECAST : "re-tasks"
    FORECAST ||--o{ ESTIMATIVE : "feeds"
    ESTIMATIVE }o--|| PROVENANCE : "cites"
    FIMI_SIGNAL }o--|| PROVENANCE : "evidenced by"
    RESOLVED_ENTITY {
    string canonical_id PK
    string source_grading
    date as_of
    }
    FUSION_EDGE {
    string from FK
    string to FK
    float salience
    }
    IW_INDICATOR {
    string tripwire
    string warning_level
    float probability
    }
    FORECAST {
    string question_id PK
    float p
    float rolling_brier
    }
    ESTIMATIVE {
    string title
    string neutrality_audit
    string human_signoff
    }
    FIMI_SIGNAL {
    string narrative_id PK
    string attribution_confidence
    }
    PROVENANCE {
    string asset_id PK
    bool refuse_to_cite
    }

    Data-governance rails. All capability entities inherit the ยง10 GDPR Article 9 posture (lawful bases 9(2)(e)/9(2)(g)), the ยง3.5.5 evidence-and-provenance invariant (no analytic record without a dok_id/primary-source anchor + Admiralty grade), and the ยง4.10 consistency contract (serverless stores never drift from the public static SoR). FININT/SOCMINT entities carry an explicit ethics field asserting public-records-only, aggregate, non-accusatory processing with no citizen profiling.


    sequenceDiagram
    participant SRC as Riksdag / Regering / IMF / SCB / WB
    participant EB as EventBridge (scheduled)
    participant ING as Lambda Ingestors
    participant SF as Step Functions
    participant ART as Static Artifacts (S3)
    participant HYD as Hydrators
    participant STORE as Serverless Stores
    EB->>ING: Trigger scheduled fetch
    ING->>SRC: Pull public data
    ING->>ART: Write versioned JSON (system of record)
    ART->>SF: Emit "artifact updated"
    SF->>HYD: Orchestrate hydration
    HYD->>STORE: Upsert Neptune / Aurora / DynamoDB / OpenSearch / Timestream
    HYD->>STORE: Embed corpus โ†’ Bedrock KB
    1. Dual-write era โ€” static artifacts remain canonical; serverless stores are hydrated copies. UI can fall back to static at any time.
    2. Read-shadow โ€” API Gateway serves reads from serverless while continuously diffed against static for parity.
    3. Promote โ€” once parity is proven, interactive features (graph traversal, vector search) are exposed; static remains DR.
    ComponentRole
    EventBridgeScheduled ingestion triggers (replaces some cron in GitHub Actions)
    Step FunctionsOrchestrates multi-store hydration with retries
    Kinesis (optional)Streaming ingestion for high-frequency updates
    LambdaStateless ingestors, hydrators, GraphQL resolvers

    Economic context blends three providers with a strict precedence rule (IMF primary, SCB ground truth, World Bank non-economic residue). Reconciliation guards against silent divergence:

    graph TD
    IMF["IMF SWE (WEO/FM)"] --> CMP{">0.3pp delta?"}
    SCB["SCB national accounts"] --> CMP
    CMP -->|No| OK["Accept; tag dual-source provenance"]
    CMP -->|Yes| REV["Editorial review flag"]
    REV --> NOTE["Footnote both values + vintages"]
    WB["World Bank (non-economic only)"] --> GOV["Governance / environment"]
    style IMF fill:#bbdefb,stroke:#1565c0,color:#000000
    style SCB fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style WB fill:#fff9c4,stroke:#f9a825,color:#000000
    style CMP fill:#ffcc80,stroke:#e65100,color:#000000
    style REV fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style OK fill:#a5d6a7,stroke:#1b5e20,color:#000000
    style NOTE fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style GOV fill:#bbdefb,stroke:#1565c0,color:#000000
    CheckRuleAction on failure
    IMF โ†” SCB GDP/inflation delta> 0.3pp triggers reviewFootnote both values + vintages
    Voting record completenessevery votering_id resolves to a dok_idReject artifact
    Party roster integrityactive parties โˆˆ {S,M,SD,C,V,MP,KD,L}Flag schema drift
    Vintage freshnessIMF vintage within one WEO cycleRe-fetch

    type Politician {
    intressentId: ID!
    namn: String!
    parti: Party!
    valkrets: String
    status: String
    votes(rm: String): [Vote!]!
    speeches(rm: String): [Speech!]!
    anomalyScores: [AnomalyScore!]!
    }

    type Party {
    kod: ID!
    namn: String!
    active: Boolean!
    seats: Int
    cohesion(rm: String!): CohesionRow!
    alignments(rm: String!): [BlocEdge!]!
    }

    type Vote {
    voteringId: ID!
    document: Document!
    politician: Politician!
    rost: String!
    punkt: String
    }

    type Document {
    dokId: ID!
    doktyp: String
    titel: String
    rm: String
    publicerad: String
    }

    type Speech {
    anforandeId: ID!
    politician: Politician!
    document: Document
    rm: String
    }

    type CohesionRow {
    party: String!
    cohesionIndex: Float!
    rebelVotes: Int!
    evidenceDokIds: [String!]!
    }

    type BlocEdge {
    source: String!
    target: String!
    alignment: Float!
    intopClass: String!
    evidenceDokIds: [String!]!
    }

    type AnomalyScore {
    entity: String!
    metric: String!
    z: Float!
    flag: String!
    explanation: String!
    }

    type Query {
    politician(intressentId: ID!): Politician
    party(kod: ID!): Party
    searchDocuments(query: String!, rm: String): [Document!]!
    ragAnswer(question: String!): GroundedAnswer!
    }

    type GroundedAnswer {
    answer: String!
    citations: [String!]! # dok_ids โ€” never empty
    }

    type Mutation {
    refreshHydration(source: String!): HydrationResult!
    }

    type HydrationResult {
    source: String!
    updatedAt: String!
    recordsUpserted: Int!
    }

    type Subscription {
    newAnomaly(party: String): AnomalyScore!
    voteAdded(rm: String!): Vote!
    }

    GroundedAnswer.citations is non-nullable and must be non-empty โ€” the schema itself enforces evidence-first AI output.


    erDiagram
    POLITICIAN ||--o{ VOTE : casts
    POLITICIAN ||--o{ SPEECH : delivers
    POLITICIAN ||--o{ NETWORK_EDGE : connects
    POLITICIAN ||--o{ ANOMALY_SCORE : flagged
    PARTY ||--o{ POLITICIAN : includes
    PARTY ||--o{ COHESION_ROW : scored
    PARTY ||--o{ BLOC_EDGE : aligns
    DOCUMENT ||--o{ VOTE : triggers
    DOCUMENT ||--o{ EMBEDDING : indexed
    COMMITTEE ||--o{ DOCUMENT : produces
    POLITICIAN {
    string intressent_id PK
    string parti FK
    }
    PARTY {
    string kod PK
    boolean active
    }
    DOCUMENT {
    string dok_id PK
    string rm
    }
    VOTE {
    string votering_id PK
    string rost
    }
    SPEECH {
    string anforande_id PK
    }
    COHESION_ROW {
    string party FK
    float cohesion_index
    }
    BLOC_EDGE {
    string source FK
    string target FK
    float alignment
    }
    NETWORK_EDGE {
    string from FK
    string to FK
    int weight
    }
    ANOMALY_SCORE {
    string entity FK
    float z
    }
    EMBEDDING {
    string dok_id FK
    int dimension
    }
    COMMITTEE {
    string kod PK
    }
    graph TB
    subgraph EDGE["Edge"]
    CF["CloudFront"]
    WAF["AWS WAF"]
    end
    subgraph ACCESS["Access Tier"]
    APIGW["API Gateway"]
    COG["Cognito"]
    end
    subgraph COMPUTE["Compute"]
    L["Lambda"]
    SF["Step Functions"]
    EB["EventBridge"]
    end
    subgraph DATA["Data Tier"]
    NEP["Neptune"]
    AUR["Aurora v2"]
    DDB["DynamoDB"]
    OS["OpenSearch"]
    TS["Timestream"]
    KB["Bedrock KB"]
    S3["S3 (static SoR)"]
    end
    CF --> WAF --> APIGW --> COG --> L
    EB --> SF --> L
    L --> NEP & AUR & DDB & OS & TS & KB
    L -. fallback .-> S3
    style CF fill:#ffe0b2,stroke:#e65100,color:#000000
    style WAF fill:#ffe0b2,stroke:#e65100,color:#000000
    style APIGW fill:#ffcc80,stroke:#e65100,color:#000000
    style COG fill:#ffcc80,stroke:#e65100,color:#000000
    style L fill:#fff9c4,stroke:#f9a825,color:#000000
    style SF fill:#fff9c4,stroke:#f9a825,color:#000000
    style EB fill:#fff9c4,stroke:#f9a825,color:#000000
    style NEP fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style AUR fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style DDB fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style OS fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style TS fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style KB fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style S3 fill:#bbdefb,stroke:#1565c0,color:#000000
    sequenceDiagram
    participant U as User
    participant CF as CloudFront
    participant GW as API Gateway
    participant C as Cognito
    participant L as Lambda
    participant N as Neptune
    participant O as OpenSearch
    participant K as Bedrock KB
    U->>CF: GraphQL query
    CF->>GW: Forward
    GW->>C: Authorize + throttle
    C-->>GW: Token OK
    GW->>L: Resolve
    L->>N: Graph traversal (co-voting)
    L->>O: Vector + text search
    L->>K: RAG retrieve (grounded)
    K-->>L: Answer + dok_id citations
    L-->>U: Response (evidence-linked)
    graph LR
    P1((MP A ยท S)) ---|co_voted 4210| P2((MP B ยท V))
    P1 ---|co_sponsored 23| P3((MP C ยท S))
    P2 ---|committee FiU| P4((MP D ยท MP))
    P3 ---|co_voted 1880| P4
    style P1 fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style P3 fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style P2 fill:#ef9a9a,stroke:#b71c1c,color:#000000
    style P4 fill:#a5d6a7,stroke:#1b5e20,color:#000000
    graph LR
    SRC["Vote / speech events"] --> ING["Lambda ingestor"]
    ING --> TS["Timestream"]
    TS --> AGG["Scheduled aggregation"]
    AGG --> ANOM["Anomaly z-scores"]
    ANOM --> API["API Gateway"]
    style SRC fill:#bbdefb,stroke:#1565c0,color:#000000
    style ING fill:#fff9c4,stroke:#f9a825,color:#000000
    style TS fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style AGG fill:#fff9c4,stroke:#f9a825,color:#000000
    style ANOM fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style API fill:#ffcc80,stroke:#e65100,color:#000000
    graph TD
    DOCS["Documents + speeches (public)"] --> CHUNK["Chunk + grade source"]
    CHUNK --> EMB["Embed (Titan / Bedrock)"]
    EMB --> KB["Knowledge Base vector store"]
    Q["Citizen question"] --> RET["Retrieve top-k"]
    KB --> RET
    RET --> GEN["Generate grounded answer"]
    GEN --> CITE["Attach dok_id citations"]
    CITE --> OUT["Answer (never ungrounded)"]
    style DOCS fill:#bbdefb,stroke:#1565c0,color:#000000
    style CHUNK fill:#fff9c4,stroke:#f9a825,color:#000000
    style EMB fill:#fff9c4,stroke:#f9a825,color:#000000
    style KB fill:#e1bee7,stroke:#6a1b9a,color:#000000
    style RET fill:#fff9c4,stroke:#f9a825,color:#000000
    style GEN fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style CITE fill:#c8e6c9,stroke:#2e7d32,color:#000000
    style OUT fill:#a5d6a7,stroke:#1b5e20,color:#000000

    gantt
    title Riksdagsmonitor Data Architecture Roadmap (2026-2037)
    dateFormat YYYY-MM-DD
    section Horizon 2 (Static)
    Party cohesion matrices :h2a, 2026-06-01, 180d
    Coalition / bloc graphs :h2b, after h2a, 150d
    OSINT structures + INTOP :h2c, 2026-09-01, 240d
    Build pipeline hardening :h2d, after h2c, 120d
    section Horizon 3 Phase 1 (Foundation)
    Aurora v2 + DynamoDB :h3a, 2028-01-01, 200d
    Ingestion (EventBridge/Step) :h3b, after h3a, 150d
    section Horizon 3 Phase 2 (Graph + Search)
    Neptune Serverless :h3c, 2029-01-01, 220d
    OpenSearch + vectors :h3d, after h3c, 180d
    section Horizon 3 Phase 3 (AI)
    Bedrock Knowledge Bases RAG :h3e, 2030-01-01, 240d
    Timestream anomaly pipeline :h3f, after h3e, 180d
    section Horizon 3 Phase 4 (Access)
    API Gateway + Cognito GA :h3g, 2031-01-01, 200d
    Interactive features GA :h3h, after h3g, 365d
    section Long Horizon
    Pre-AGI scaling :lh1, 2032-01-01, 730d
    AGI/Post-AGI data ops :lh2, 2034-01-01, 1095d
    PhaseWindowOutcome
    H2 Static2026โ€“2027Richer pre-computed party + OSINT datasets, no servers
    H3 Phase 12028Relational + KV foundation, hydration from static SoR
    H3 Phase 22029Graph traversal + vector search
    H3 Phase 32030RAG + anomaly time-series
    H3 Phase 42031+API Gateway + Cognito GA, interactive UX
    Long Horizon2032โ€“2037Pre-AGI โ†’ AGI data operations

    LayerH1H2H3
    HostingS3 + CloudFront, GH Pages DRSame+ serverless tier
    ComputeGitHub ActionsGitHub Actions (heavier)Lambda + Step Functions
    StorageJSON/CSV files+ party/OSINT JSONNeptune/Aurora/DynamoDB/OpenSearch/Timestream
    AINewsroom Opus 4.x+ build-time embeddingsBedrock KB RAG
    AccessStatic fetchStatic fetchAPI Gateway + Cognito
    HorizonCost modelNotes
    H1Near-zero marginal (CDN + Actions)Static economics
    H2Slightly higher Actions minutesNo new runtime cost
    H3Pay-per-use serverlessScales to zero; static fallback caps risk

    All serverless stores chosen for scale-to-zero / on-demand billing to preserve the platform's low-cost, sustainable, open-source posture.


    Control areaISO 27001:2022NIST CSF 2.0CIS Controls v8.1
    Access control (Cognito)A.5.15, A.5.18PR.AACIS 6
    Data classificationA.5.12ID.AMCIS 3
    Logging & audit (API GW)A.8.15DE.CMCIS 8
    Cryptography (in transit/at rest)A.8.24PR.DSCIS 3
    Supply chain (SLSA, npm)A.5.19โ€“A.5.21ID.SCCIS 16
    Secure developmentA.8.25โ€“A.8.28PR.PSCIS 16

    10.2 GDPR Article 9 Posture

    • Political opinions = special-category data; lawful bases 9(2)(e) (manifestly made public) and 9(2)(g) (substantial public interest).
    • Public data only โ€” exclusively official primary sources; no private individuals, no leaked/hacked data.
    • Data minimisation, purpose limitation, storage limitation, integrity & confidentiality applied across all horizons.
    • DPIA required before activating any H3 interactive feature processing personal data at new scale.
    ClassExamplesHandling
    PublicVotes, documents, speeches, party metadataOpen read; integrity-protected
    Derived-PublicCohesion/coalition/OSINT datasetsProvenance-tagged; reproducible
    OperationalHydration state, audit logsCognito-gated; retention-limited
    stateDiagram-v2
    [*] --> Ingested: Fetch public source
    Ingested --> Validated: analysis-gate.ts
    Validated --> Published: Static artifact (SoR)
    Published --> Hydrated: Serverless projection
    Hydrated --> Served: API Gateway + Cognito
    Served --> Archived: Retention policy
    Archived --> [*]
    Validated --> Rejected: Provenance incomplete
    Rejected --> [*]

    Stakeholders (power ร— interest, neutral framing):

    StakeholderInterestData-tier implication
    CitizensAccessible, neutral accountabilityStatic-first, 14 languages, WCAG 2.1 AA
    Journalists / researchersQueryable evidence with citationsH3 GraphQL + grounded RAG
    Parliamentary parties (all 8)Fair, equal, reproducible treatmentSymmetric datasets; no editorial scoring
    Hack23 maintainersSustainable, low-cost opsScale-to-zero serverless; static DR
    Regulators (GDPR/NIS2)Lawful, auditable processingCognito audit trail; DPIA gate

    Top data-architecture risks (target mitigations):

    RiskLikelihoodImpactMitigation
    Serverless drift from public recordLowHighStatic SoR canonical; continuous parity diff
    Source API change (Riksdag/IMF/SCB)MediumMediumVersioned ingestors; vintage stamping; allowlisted hosts
    AI ungrounded/biased outputMediumHighNon-empty dok_id citations enforced by schema; neutrality lint; human-in-loop
    Cost overrun (H3)LowMediumPay-per-use; static fallback caps blast radius
    Provenance lossLowHighsource_grading + INTOP mandatory at gate
    Perceived partisanshipLowHighSymmetric party datasets; published methodology; reproducibility

    The single most important control is the static system-of-record: because every serverless and AI output is derived from immutable, citation-tagged public artifacts, the platform cannot silently fabricate or skew the political record.


    IMF is the primary economic data domain (ADR 0001). Today it is a filesystem cache; in Horizon 3 it is projected into Aurora while the cache remains the system of record.

    • Client: scripts/imf-client.ts (pure TypeScript, not an MCP server).
    • Cache: analysis/data/imf/{indicator}/{country}.json + .meta.json sidecar.
    • Vintage labels: e.g. WEO-2026-04.
    • Dataflows: WEO, FM, IFS, BOP, DOTS, GFS_COFOG, PCPS, ER, MFS_IR, MFS_PR; T+5 projections.
    • Allowlisted hosts: data.imf.org, api.imf.org, www.imf.org.
    CREATE TABLE imf_cache (
    indicator TEXT NOT NULL,
    country TEXT NOT NULL,
    period TEXT NOT NULL,
    value DOUBLE PRECISION,
    is_projection BOOLEAN NOT NULL DEFAULT FALSE,
    vintage TEXT NOT NULL, -- e.g. 'WEO-2026-04'
    dataflow TEXT NOT NULL, -- WEO/FM/IFS/...
    fetched_at TIMESTAMPTZ NOT NULL,
    PRIMARY KEY (indicator, country, period, vintage)
    );

    CREATE TABLE article_economic_provenance (
    article_id TEXT NOT NULL,
    indicator TEXT NOT NULL,
    country TEXT NOT NULL,
    period TEXT NOT NULL,
    vintage TEXT NOT NULL,
    used_at TIMESTAMPTZ NOT NULL,
    PRIMARY KEY (article_id, indicator, country, period, vintage)
    );

    CREATE INDEX idx_imf_dataflow ON imf_cache(dataflow);
    CREATE INDEX idx_imf_country ON imf_cache(country);
    type EconomicDataSource =
    | { provider: "IMF"; dataflow: "WEO" | "FM" | "IFS" | "BOP" | "DOTS"
    | "GFS_COFOG" | "PCPS" | "ER" | "MFS_IR" | "MFS_PR"; vintage: string }
    | { provider: "SCB"; table: string } // Swedish ground truth
    | { provider: "WorldBank"; series: string; economic: false }; // non-economic only
    NeedProviderRationale
    GDP, inflation, fiscal, BoPIMFPrimary economic; T+5 projections
    Swedish national statisticsSCBAuthoritative ground truth
    Governance / environment / socialWorld BankNon-economic residue only
    Economic seriesโŒ World BankDeprecated โ€” use IMF

    IMF cache entries are Derived-Public: openly published source values, provenance-tagged with vintage + dataflow, fully reproducible, and linked to articles via article_economic_provenance for editorial accountability.


    The newsroom and analytical layer evolve with frontier-model capability. The table below translates the AI model roadmap into data-architecture implications โ€” what each capability tier demands from the data tier.

    YearModel TierStatusData-Architecture Implication
    2026Opus 4.6โ€“4.9๐ŸŸข CurrentStatic build-time authoring; corpus as files; RAG-ready embeddings begin
    2027Opus 5.x๐Ÿ”ต NearRicher H2 OSINT datasets feed model context; embeddings standardized
    2028Opus 6.x๐ŸŸฃ PlannedH3 Phase 1: relational + KV stores hydrate model retrieval
    2029Opus 7.x๐ŸŸ  ProjectedGraph + vector retrieval (Neptune + OpenSearch) for grounded synthesis
    2030Opus 8.x๐Ÿ”ด HorizonBedrock KB RAG GA; anomaly time-series inform model prompts
    2031โ€“2033Opus 9โ€“10.x / Pre-AGIโšช SpeculativeReal-time grounded Q&A via API Gateway; strict citation enforcement
    2034โ€“2037AGI / Post-AGIโญ VisionaryAutonomous evidence-bound analysis; human-in-the-loop governance retained
    timeline
    title AI โ†” Data Tier Co-Evolution
    2026 : Opus 4.x : Static authoring + embeddings
    2027 : Opus 5.x : H2 OSINT context
    2028 : Opus 6.x : Aurora + DynamoDB retrieval
    2029 : Opus 7.x : Neptune + OpenSearch grounding
    2030 : Opus 8.x : Bedrock KB RAG GA
    2031 : Pre-AGI : Real-time grounded Q&A
    2034 : AGI/Post-AGI : Autonomous evidence-bound analysis

    Governance invariant across all tiers: every AI-generated claim is retrieval-grounded and dok_id-cited, neutrality is enforced, and a human-in-the-loop governance gate is retained even at AGI tiers. Capability never overrides the evidence-first and neutrality principles.

    FieldRequirement
    answerGenerated text
    citationsNon-empty array of dok_id
    source_gradingAdmiralty reliability/credibility per retrieved chunk
    neutrality_checkPassed before publication

    DocumentRelationship
    DATA_MODEL.mdCurrent-state baseline (Horizon 1) this doc extends
    FUTURE_ARCHITECTURE.mdTarget system architecture
    FUTURE_SECURITY_ARCHITECTURE.mdTarget security controls
    FUTURE_THREAT_MODEL.mdTarget threat model
    ARCHITECTURE.mdCurrent architecture
    analysis/imf/README.mdIMF data domain reference

    FieldValue
    Document OwnerCEO
    Version3.0
    Last Updated2026-05-31 (UTC)
    Review CycleAnnual
    Next Review2027-05-31
    ClassificationPublic
    Data PosturePublic sources only; GDPR Art. 9 (9(2)(e), 9(2)(g)); strict neutrality

    Riksdagsmonitor is part of the Hack23 open-source transparency ecosystem, operated under the Hack23 ISMS-PUBLIC governance framework (ISO 27001:2022, NIST CSF 2.0, CIS Controls v8.1, GDPR, NIS2).

    Mission: empower citizens, strengthen democratic accountability, and illuminate the political process with rigorous, neutral, evidence-based intelligence drawn exclusively from public sources.

    ยฉ Hack23 ยท Public ยท Evidence-first ยท Neutral ยท Privacy-respecting