Skip to content

Integrate SCB MCP server for statistical enrichment of news generation#652

Merged
pethers merged 7 commits intomainfrom
copilot/improve-mews-generation-analysis
Feb 28, 2026
Merged

Integrate SCB MCP server for statistical enrichment of news generation#652
pethers merged 7 commits intomainfrom
copilot/improve-mews-generation-analysis

Conversation

Copy link
Contributor

Copilot AI commented Feb 28, 2026

Adds the SCB MCP server (Statistics Sweden, 1,200+ tables via PxWebAPI 2.0) as an optional data source for enriching political analysis with official economic, labour, demographic, and environmental statistics.

MCP Configuration

  • Added scb server (https://scb-mcp.onrender.com/mcp) to .github/copilot-mcp.json
  • All 10 news-*.md workflow files updated: network.allowed, mcp-servers, safe-outputs.allowed-domains

Data Layer

  • SCBContext / SCBIndicator types added to scripts/data-transformers/types.ts with scbContext field on ArticleContentData
  • SCBContext fields aligned with all 12 SCB_DOMAIN_TABLES domains (publicFinances, defence, emissions, education, healthcare, migration, euForeign, crime, unemployment, housing, transport, gdpGrowth) plus cross-domain indicators (inflation, population)
  • SCB_DOMAIN_TABLES constant in policy-analysis.ts maps all 12 policy domains to SCB table IDs and Swedish search queries

Workflow Enrichment Instructions

5 key workflows (evening-analysis, monthly-review, weekly-review, propositions, motions) include SCB enrichment examples with explicit guidance that SCB is optional — all calls must be try/catch wrapped, failures never block article generation.

Architecture Documentation

  • ARCHITECTURE.md: SCB added to data sources table, MCP architecture diagram, news generation sequence diagram, and a new scb-mcp server section with tools/domain mapping/security considerations
  • Policy Domain Mapping table documents all 12 domains (fiscal, labour, migration, education, environment, trade, housing, justice, defence, healthcare, transport, EU & foreign)
  • Mermaid diagram and security considerations correctly reference HTTPS transport

Tests

  • 45 new tests in tests/scb-mcp-integration.test.ts validating SCB config across all 10 workflows, type definitions, and domain mapping completeness
  • Domain mapping test isolated to SCB_DOMAIN_TABLES section to avoid false positives from DOMAIN_NAMES
  • All 98 MCP-related tests pass (53 existing + 45 new). CodeQL: 0 alerts

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 2 commits February 28, 2026 04:38
…rkflow files

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
…ntation

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions github-actions bot added documentation Documentation updates workflow GitHub Actions workflows riksdag-data Riksdag-Regering MCP data ci-cd CI/CD pipeline changes testing Test coverage refactor Code refactoring news News articles and content generation agentic-workflow Agentic workflow changes size-l Large change (250-1000 lines) labels Feb 28, 2026
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

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

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copilot AI changed the title [WIP] Analyze and implement improvements for mews generation and political analysis Integrate SCB MCP server for statistical enrichment of news generation Feb 28, 2026
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

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

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR integrates the SCB (Statistics Sweden) MCP server (scb-mcp.onrender.com/mcp) as an optional data source across all 10 news workflow agentic-workflow files, enabling political article generation to be enriched with official Swedish economic, demographic, and environmental statistics from 1,200+ SCB tables via PxWebAPI 2.0.

Changes:

  • Added SCB MCP server entry to .github/copilot-mcp.json and updated all 10 news-*.md workflow files with network allowlist, MCP server config, and safe-outputs entries; 5 key workflows received enrichment usage examples with explicit try/catch and non-blocking guidance.
  • Added SCBContext / SCBIndicator TypeScript interfaces to scripts/data-transformers/types.ts and SCB_DOMAIN_TABLES constant to scripts/data-transformers/policy-analysis.ts mapping all 12 policy domains to SCB table IDs and search queries.
  • Added 45 new integration tests in tests/scb-mcp-integration.test.ts and updated ARCHITECTURE.md with SCB data source documentation, sequence/architecture diagrams, and a detailed scb-mcp server section.

Reviewed changes

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

Show a summary per file
File Description
.github/copilot-mcp.json Adds SCB MCP server (http type, tools ["*"]) consistent with existing entries
.github/workflows/news-*.md (×10) Adds scb-mcp.onrender.com to network allowlist, mcp-servers, and safe-outputs in all 10 workflow prompt files
.github/workflows/news-evening-analysis.md Additionally includes detailed SCB usage examples with optional/try-catch guidance
.github/workflows/news-{monthly-review,weekly-review,propositions,motions}.md Adds minimal SCB enrichment comments with try/catch guidance
scripts/data-transformers/types.ts Adds SCBContext and SCBIndicator interfaces; adds scbContext? field to ArticleContentData
scripts/data-transformers/policy-analysis.ts Adds exported SCB_DOMAIN_TABLES constant mapping all 12 DomainKey values to SCB queries, tables, and indicator names
ARCHITECTURE.md Adds SCB to sequence diagrams, data sources table, MCP capability comparison, and new scb-mcp server documentation section
tests/scb-mcp-integration.test.ts New test file with 45 tests validating SCB config across all 10 workflows, type definitions, and domain mapping
Comments suppressed due to low confidence (1)

.github/workflows/news-article-generator.md:60

  • The .lock.yml files (e.g., news-article-generator.lock.yml) are the actual files executed by GitHub Actions, compiled from the .md sources. They have not been updated in this PR and still lack scb-mcp.onrender.com in the firewall allowlist (line 757) and the safe-outputs allowed domains (line 840). The SCB MCP server will therefore be blocked at runtime by the gh-aw firewall and its outputs won't be trusted, making the integration non-functional despite the correct .md configuration.

The lock files must be regenerated by running gh aw compile on the updated .md files before or as part of this PR. See .github/workflows/compile-agentic-workflows.yml for the compilation workflow (manual trigger).

mcp-servers:
  riksdag-regering:
    url: https://riksdag-regering-ai.onrender.com/mcp
  scb:
    url: https://scb-mcp.onrender.com/mcp

tools:
  github:
    toolsets:
      - all
  bash: true
  microsoft/playwright:
    command: npx
    args: ["-y", "@playwright/mcp@latest", "--headless"]
    env:

Comment on lines 166 to 187
export interface SCBContext {
/** Unemployment rate data (national/regional) */
unemployment?: SCBIndicator;
/** GDP growth data */
gdpGrowth?: SCBIndicator;
/** Inflation / CPI data */
inflation?: SCBIndicator;
/** Population statistics */
population?: SCBIndicator;
/** Immigration / emigration data */
migration?: SCBIndicator;
/** Education enrollment statistics */
education?: SCBIndicator;
/** Greenhouse gas emissions */
emissions?: SCBIndicator;
/** Housing construction / prices */
housing?: SCBIndicator;
/** Government revenue / expenditure */
publicFinances?: SCBIndicator;
/** Crime statistics */
crime?: SCBIndicator;
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The SCBContext interface in types.ts is misaligned with SCB_DOMAIN_TABLES in two ways:

  1. SCBContext includes inflation?: SCBIndicator and population?: SCBIndicator fields, but neither corresponds to any of the 12 domain keys in SCB_DOMAIN_TABLES. There is no domain mapped to inflation (CPI/KPI tables) or population data.

  2. SCB_DOMAIN_TABLES has four domains (defence, healthcare, transport, eu-foreign) that have no corresponding field in SCBContext, making them inaccessible through the typed scbContext object on ArticleContentData.

Consider either adding the missing SCBContext fields (e.g., defence, healthcare, transport, euForeign) or adding corresponding domain entries in SCB_DOMAIN_TABLES for inflation and population, to keep both structures in sync.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bac472c. SCBContext now has fields for all 12 SCB_DOMAIN_TABLES domains: publicFinances (fiscal), defence, emissions (environment), education, healthcare, migration, euForeign (eu-foreign), crime (justice), unemployment (labour), housing, transport, gdpGrowth (trade). inflation and population are retained as cross-domain indicators.

Comment on lines 145 to 154
// Should map all 12 policy domains
const domains = ['fiscal', 'defence', 'environment', 'education', 'healthcare',
'migration', 'justice', 'labour', 'housing', 'transport', 'trade'];

domains.forEach(domain => {
expect(content).toContain(`${domain}:`);
});

// eu-foreign uses quoted key syntax
expect(content).toContain("'eu-foreign':");
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The test at lines 146-154 uses a content-string search to verify all 12 domains are present in SCB_DOMAIN_TABLES. However, since policy-analysis.ts also contains the pre-existing DOMAIN_NAMES constant with the same domain keys, the test would pass even if a domain was missing from SCB_DOMAIN_TABLES (as long as it exists in DOMAIN_NAMES). For example, if healthcare: were accidentally omitted from SCB_DOMAIN_TABLES, the test would still pass because healthcare: exists at line 94 of policy-analysis.ts in DOMAIN_NAMES.

The test should narrow the search to the content after export const SCB_DOMAIN_TABLES to isolate it from the rest of the file.

Suggested change
// Should map all 12 policy domains
const domains = ['fiscal', 'defence', 'environment', 'education', 'healthcare',
'migration', 'justice', 'labour', 'housing', 'transport', 'trade'];
domains.forEach(domain => {
expect(content).toContain(`${domain}:`);
});
// eu-foreign uses quoted key syntax
expect(content).toContain("'eu-foreign':");
const scbDomainTablesIndex = content.indexOf('export const SCB_DOMAIN_TABLES');
expect(scbDomainTablesIndex).toBeGreaterThan(-1);
const scbDomainTablesContent = content.slice(scbDomainTablesIndex);
// Should map all 12 policy domains
const domains = ['fiscal', 'defence', 'environment', 'education', 'healthcare',
'migration', 'justice', 'labour', 'housing', 'transport', 'trade'];
domains.forEach(domain => {
expect(scbDomainTablesContent).toContain(`${domain}:`);
});
// eu-foreign uses quoted key syntax
expect(scbDomainTablesContent).toContain("'eu-foreign':");

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bac472c. The test now slices content from export const SCB_DOMAIN_TABLES before checking domain keys, preventing false positives from DOMAIN_NAMES.

Comment on lines 1662 to 1724

**See:** [SECURITY_ARCHITECTURE.md](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:**
```json
{
"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 Domain | SCB Search Query | Example Tables | Key Indicators |
|---------------|-----------------|----------------|----------------|
| Fiscal Policy | skatter statsbudget | TAB1291, TAB1292 | Revenue, expenditure, budget balance |
| Labour Market | sysselsättning arbetslöshet | TAB5765, TAB5616 | Unemployment rate, employment rate |
| Migration | invandring utvandring befolkning | TAB637, TAB4230 | Immigration, emigration, net migration |
| Education | utbildning studenter | TAB4787, TAB4790 | Enrollment, graduation rates |
| Environment | växthusgaser utsläpp | TAB5404, TAB5407 | GHG emissions, renewable energy share |
| Trade & Industry | näringsliv företag BNP | TAB5802, TAB5803 | GDP growth, industrial production |
| Housing | bostäder nybyggnation | TAB2052, TAB4709 | Housing starts, price index |
| Justice | brott lagföringar | TAB1172 | Reported crimes, conviction rate |

**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:**
- **HTTP-only 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

---

## 📄 Document Control
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The Last Updated date in the Document Control table is 2026-02-20 but the ARCHITECTURE.md has been modified in this PR. This date should be updated to reflect when the SCB MCP documentation was added.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bac472c. Both the header and Document Control table now show 2026-02-28 (UTC).

ARCHITECTURE.md Outdated
- Domain-to-table mapping in `scripts/data-transformers/policy-analysis.ts` (`SCB_DOMAIN_TABLES`)

**Security Considerations:**
- **HTTP-only MCP server** — No local execution risk, remote hosting on Render
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The security consideration states "HTTP-only MCP server" but the configured URL is https://scb-mcp.onrender.com/mcp, which uses HTTPS. This should be corrected to "HTTPS MCP server" or "no local execution risk" to accurately describe the security profile.

Suggested change
- **HTTP-only MCP server** — No local execution risk, remote hosting on Render
- **HTTPS MCP server** — No local execution risk, remote hosting on Render

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bac472c. Both occurrences (riksdag-regering-mcp and scb-mcp sections) now read "HTTPS MCP server".

| Environment | växthusgaser utsläpp | TAB5404, TAB5407 | GHG emissions, renewable energy share |
| Trade & Industry | näringsliv företag BNP | TAB5802, TAB5803 | GDP growth, industrial production |
| Housing | bostäder nybyggnation | TAB2052, TAB4709 | Housing starts, price index |
| Justice | brott lagföringar | TAB1172 | Reported crimes, conviction rate |
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The Policy Domain Mapping table in ARCHITECTURE.md only lists 8 out of the 12 domains defined in SCB_DOMAIN_TABLES (fiscal, labour, migration, education, environment, trade/industry, housing, justice). Four domains — defence, healthcare, transport, and eu-foreign — are omitted from this documentation table. This creates a discrepancy between the code and the architecture documentation, which could mislead developers about what domains are actually mapped.

Suggested change
| Justice | brott lagföringar | TAB1172 | Reported crimes, conviction rate |
| Justice | brott lagföringar | TAB1172 | Reported crimes, conviction rate |
| Defence & Security | försvar säkerhet totalförsvar | TAB3101, TAB3102 | Defence spending, personnel, readiness indicators |
| Healthcare | hälso- och sjukvård vårdkonsumtion | TAB2301, TAB2302 | Healthcare expenditure, hospital capacity, waiting times |
| Transport & Infrastructure | transport infrastruktur trafik | TAB2801, TAB2802 | Passenger volume, freight volume, infrastructure investment |
| EU & Foreign Policy | utrikeshandel eu politik | TAB4001, TAB4002 | Exports, imports, EU contributions, international agreements |

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bac472c. Added all 4 missing domains (Defence & Security, Healthcare, Transport, EU & Foreign Affairs) to the Policy Domain Mapping table.

@pethers
Copy link
Member

pethers commented Feb 28, 2026

@copilot apply changes based on the comments in this thread

…isolation, update ARCHITECTURE.md

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

Copilot AI commented Feb 28, 2026

@copilot apply changes based on the comments in this thread

All 5 review comments addressed in bac472c:

  • SCBContext aligned with all 12 SCB_DOMAIN_TABLES domains
  • Test narrowed to SCB_DOMAIN_TABLES section only
  • Last Updated date corrected to 2026-02-28
  • "HTTP-only" → "HTTPS" in both security sections
  • 4 missing domains added to Policy Domain Mapping table

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

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

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Comments suppressed due to low confidence (1)

.github/workflows/news-article-generator.md:56

  • The .lock.yml files (e.g., news-article-generator.lock.yml, news-evening-analysis.lock.yml, etc.) have not been regenerated after the corresponding .md files were updated to add the SCB MCP server. The .lock.yml files are the ones actually executed by GitHub Actions — they contain the inline MCP server configuration (the Start MCP Gateway step), the --allow-domains sandbox firewall list in the Execute GitHub Copilot CLI step, and the GH_AW_ALLOWED_DOMAINS environment variable. None of these currently include scb-mcp.onrender.com, so at runtime the SCB MCP server will be inaccessible (blocked by the sandbox firewall) even though the .md source files describe it. Per the project convention, lock files must be regenerated with gh aw compile after .md files change. The compile-agentic-workflows.yml workflow can be triggered manually to do this.

mcp-servers:
  riksdag-regering:
    url: https://riksdag-regering-ai.onrender.com/mcp
  scb:
    url: https://scb-mcp.onrender.com/mcp

tools:
  github:
    toolsets:
      - all
  bash: true

Comment on lines +1 to +179
/**
* Test Suite for SCB MCP Integration
*
* Validates that the SCB (Statistics Sweden) MCP server is properly
* configured across the project for enriching political analysis
* with official Swedish statistics.
*
* SCB MCP tools: search_tables, get_table_data, get_table_variables,
* preview_data, find_region_code
*
* @author Hack23 AB
* @license Apache-2.0
*/

import { describe, it, expect } from 'vitest';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const WORKFLOWS_DIR = path.join(__dirname, '..', '.github', 'workflows');

/** All news workflow .md files */
const ALL_NEWS_WORKFLOWS: readonly string[] = [
'news-article-generator.md',
'news-committee-reports.md',
'news-evening-analysis.md',
'news-month-ahead.md',
'news-monthly-review.md',
'news-motions.md',
'news-propositions.md',
'news-realtime-monitor.md',
'news-week-ahead.md',
'news-weekly-review.md',
];

describe('SCB MCP Server Configuration', () => {
it('copilot-mcp.json should include scb MCP server', () => {
const configPath = path.join(__dirname, '..', '.github', 'copilot-mcp.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));

expect(config.mcpServers).toHaveProperty('scb');
expect(config.mcpServers.scb.type).toBe('http');
expect(config.mcpServers.scb.url).toBe('https://scb-mcp.onrender.com/mcp');
});

ALL_NEWS_WORKFLOWS.forEach(workflow => {
it(`${workflow} should configure scb MCP server`, () => {
const filepath = path.join(WORKFLOWS_DIR, workflow);
const content = fs.readFileSync(filepath, 'utf-8');

// Should have scb in mcp-servers section
expect(content).toContain('scb:');
expect(content).toContain('https://scb-mcp.onrender.com/mcp');
});

it(`${workflow} should allow scb-mcp.onrender.com in network`, () => {
const filepath = path.join(WORKFLOWS_DIR, workflow);
const content = fs.readFileSync(filepath, 'utf-8');

expect(content).toContain('scb-mcp.onrender.com');
});

it(`${workflow} should include scb-mcp.onrender.com in safe-outputs`, () => {
const filepath = path.join(WORKFLOWS_DIR, workflow);
const content = fs.readFileSync(filepath, 'utf-8');

// The safe-outputs section should list scb-mcp.onrender.com
const safeOutputsSection = content.split('safe-outputs:')[1]?.split('steps:')[0] ?? '';
expect(safeOutputsSection).toContain('scb-mcp.onrender.com');
});
});
});

describe('SCB Enrichment Instructions in Key Workflows', () => {
const ENRICHED_WORKFLOWS: readonly string[] = [
'news-evening-analysis.md',
'news-monthly-review.md',
'news-weekly-review.md',
'news-propositions.md',
'news-motions.md',
];

ENRICHED_WORKFLOWS.forEach(workflow => {
it(`${workflow} should document SCB enrichment as optional`, () => {
const filepath = path.join(WORKFLOWS_DIR, workflow);
const content = fs.readFileSync(filepath, 'utf-8');

// SCB should be documented as optional enrichment (never blocking)
const hasSCBReference =
content.includes('SCB') ||
content.includes('scb') ||
content.includes('search_tables');

expect(hasSCBReference).toBe(true);
});

it(`${workflow} should instruct try/catch for SCB calls`, () => {
const filepath = path.join(WORKFLOWS_DIR, workflow);
const content = fs.readFileSync(filepath, 'utf-8');

// SCB calls should be wrapped in try/catch to avoid blocking
const hasSafetyGuidance =
content.includes('try/catch') ||
content.includes('optional') ||
content.includes('do not block');

expect(hasSafetyGuidance).toBe(true);
});
});
});

describe('SCB Data Types', () => {
it('types.ts should export SCBContext and SCBIndicator', () => {
const typesPath = path.join(__dirname, '..', 'scripts', 'data-transformers', 'types.ts');
const content = fs.readFileSync(typesPath, 'utf-8');

expect(content).toContain('export interface SCBContext');
expect(content).toContain('export interface SCBIndicator');

// SCBContext should have fields aligned with all 12 SCB_DOMAIN_TABLES domains
expect(content).toContain('publicFinances'); // fiscal
expect(content).toContain('defence'); // defence
expect(content).toContain('emissions'); // environment
expect(content).toContain('education'); // education
expect(content).toContain('healthcare'); // healthcare
expect(content).toContain('migration'); // migration
expect(content).toContain('euForeign'); // eu-foreign
expect(content).toContain('crime'); // justice
expect(content).toContain('unemployment'); // labour
expect(content).toContain('housing'); // housing
expect(content).toContain('transport'); // transport
expect(content).toContain('gdpGrowth'); // trade
// Cross-domain indicators
expect(content).toContain('inflation');
expect(content).toContain('population');
});

it('ArticleContentData should include scbContext field', () => {
const typesPath = path.join(__dirname, '..', 'scripts', 'data-transformers', 'types.ts');
const content = fs.readFileSync(typesPath, 'utf-8');

expect(content).toContain('scbContext?: SCBContext');
});
});

describe('SCB Policy Domain Mapping', () => {
it('policy-analysis.ts should export SCB_DOMAIN_TABLES', () => {
const analysisPath = path.join(__dirname, '..', 'scripts', 'data-transformers', 'policy-analysis.ts');
const content = fs.readFileSync(analysisPath, 'utf-8');

const scbDomainTablesIndex = content.indexOf('export const SCB_DOMAIN_TABLES');
expect(scbDomainTablesIndex).toBeGreaterThan(-1);
const scbDomainTablesContent = content.slice(scbDomainTablesIndex);

// Should map all 12 policy domains
const domains = ['fiscal', 'defence', 'environment', 'education', 'healthcare',
'migration', 'justice', 'labour', 'housing', 'transport', 'trade'];

domains.forEach(domain => {
expect(scbDomainTablesContent).toContain(`${domain}:`);
});

// eu-foreign uses quoted key syntax
expect(scbDomainTablesContent).toContain("'eu-foreign':");
});

it('SCB_DOMAIN_TABLES entries should have query and indicators', () => {
const analysisPath = path.join(__dirname, '..', 'scripts', 'data-transformers', 'policy-analysis.ts');
const content = fs.readFileSync(analysisPath, 'utf-8');

// Each entry should have query (Swedish search terms) and indicators
expect(content).toContain('query:');
expect(content).toContain('indicators:');
expect(content).toContain('tables:');
});
});
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The PR description claims "Add 55 tests for SCB MCP integration validation" but the test file only contains 45 test cases: 31 in describe('SCB MCP Server Configuration') (1 standalone + 10 workflows × 3 tests each), 10 in describe('SCB Enrichment Instructions in Key Workflows') (5 workflows × 2 tests each), 2 in describe('SCB Data Types'), and 2 in describe('SCB Policy Domain Mapping'). The PR description should be updated to reflect the accurate count of 45 tests.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected the PR description to accurately state 45 tests (not 55).

ARCHITECTURE.md Outdated
| **Last Updated** | 2026-02-20 (UTC) |
| **Next Review** | 2026-05-20 |
| **Last Updated** | 2026-02-28 (UTC) |
| **Next Review** | 2026-05-28 |
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The ARCHITECTURE.md document has an inconsistency in the "Next Review" date. Line 20 in the document header still reads **⏰ Next Review:** 2026-05-20, while the Document Control table at line 1740 was updated in this PR to 2026-05-28. These two dates should be consistent — both should reflect the same next review date.

Suggested change
| **Next Review** | 2026-05-28 |
| **Next Review** | 2026-05-20 |

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 301a6b5. Document Control "Next Review" reverted to 2026-05-20 to match the header at line 20.

ARCHITECTURE.md Outdated

subgraph "MCP Servers"
RR[riksdag-regering-mcp<br/>HTTP: riksdag-regering-ai.onrender.com/mcp<br/>32 specialized tools]
SCB[scb-mcp<br/>HTTP: scb-mcp.onrender.com/mcp<br/>Statistics Sweden PxWebAPI 2.0]
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The Mermaid diagram node label for the new SCB MCP server at line 1556 reads HTTP: scb-mcp.onrender.com/mcp, but the server uses HTTPS (as configured in .github/copilot-mcp.json and acknowledged in the security considerations text corrected elsewhere in this PR). The label should read HTTPS: scb-mcp.onrender.com/mcp to accurately reflect the transport protocol and be consistent with the security section.

Suggested change
SCB[scb-mcp<br/>HTTP: scb-mcp.onrender.com/mcp<br/>Statistics Sweden PxWebAPI 2.0]
SCB[scb-mcp<br/>HTTPS: scb-mcp.onrender.com/mcp<br/>Statistics Sweden PxWebAPI 2.0]

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 301a6b5. Mermaid diagram node now reads HTTPS: scb-mcp.onrender.com/mcp.

@pethers
Copy link
Member

pethers commented Feb 28, 2026

@copilot apply changes based on the comments in this thread

…agram

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

Copilot AI commented Feb 28, 2026

@copilot apply changes based on the comments in this thread

All 3 review comments addressed in 301a6b5:

  • Next Review date made consistent (2026-05-20 in both header and Document Control)
  • Mermaid diagram SCB label fixed from HTTP: to HTTPS:
  • PR description corrected to 45 tests (not 55)

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

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

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

@pethers pethers marked this pull request as ready for review February 28, 2026 05:56
@pethers pethers merged commit e798b14 into main Feb 28, 2026
21 checks passed
@pethers pethers deleted the copilot/improve-mews-generation-analysis branch February 28, 2026 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-workflow Agentic workflow changes ci-cd CI/CD pipeline changes documentation Documentation updates news News articles and content generation refactor Code refactoring riksdag-data Riksdag-Regering MCP data size-l Large change (250-1000 lines) testing Test coverage workflow GitHub Actions workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants