Comprehensive content quality assurance system implementing The Economist-style editorial standards for political journalism. This utility validates article structure, analytical depth, source attribution, and perspective diversity to ensure intelligence reporting meets rigorous transparency requirements.
Core Functionality:
- Validates analytical depth scoring (min 0.6 threshold) assessing complexity of political analysis
- Enforces source quality standards requiring minimum 3 cross-referenced government documents/debates
- Counts unique party perspectives (min 4 parties) ensuring balanced coverage across Swedish coalition
- Detects "Why This Matters" contextual sections explaining political significance for readers
- Validates historical context references connecting current events to parliamentary timeline
- Calculates composite quality score (0.0-1.0 scale, min 0.75 threshold) for publication readiness
Intelligence Operations Integration:
- Supports ongoing parliamentary monitoring by maintaining content quality standards
- Enables identification of systematic bias in coverage across party spectrum
- Tracks journalistic methodology compliance with editorial guidelines
- Documents source diversity for audit trails and GDPR data provenance
Content Quality Standards:
- Minimum analytical depth: 0.6 (evaluates substantive policy discussion)
- Minimum cross-references: 3 (government documents, committee reports, voting records)
- Minimum party perspectives: 4 (ensures broad political spectrum coverage)
- Requires "Why This Matters" section for context and reader understanding
- Recommends historical context linking current developments to past decisions
- Minimum publication quality score: 0.75 (composite metric of all dimensions)
Integration Points:
- Consumed by news generation pipeline for automated quality gates
- Referenced in editorial workflows for manual content enhancement
- Used by CI/CD validation scripts (validate-news-translations.js, validate-articles-playwright.js)
- Feeds metrics into intelligence dashboard for quality trending
Data Handling:
- Processes publicly available parliamentary records and published journalism
- No processing of personal data (operates on aggregated article metrics)
- Complies with ISO 27001:2022 A.14.2.1 (supply chain controls on content quality)
- Supports GDPR Article 5 (transparency: all quality metrics documented)
Usage: import { enhanceArticleQuality } from './article-quality-enhancer.js'; const result = await enhanceArticleQuality(articlePath, options); // Returns: { qualityScore, analyticalDepth, partyCount, hasWhyThis, issues }
- Version:
- 2.0.0
- License:
- Apache-2.0
- Source:
- See:
-
- Issue #150 (News Realtime Monitor Enhancement)
- The Economist Editorial Standards
- GDPR Article 6(1)(e) - Public Interest Processing for political transparency
- ISO 27001:2022 A.14.2.1 - Supply chain information security
Members
(inner, constant) DEFAULT_THRESHOLDS
Default quality thresholds based on The Economist standards
(inner, constant) DOCUMENT_ID_PATTERNS
Riksdag/Regering document ID patterns
(inner, constant) PARTY_VARIANTS
Map of normalized party codes to their common name variants This prevents double-counting when both full names and abbreviations appear
Methods
(static) batchEnhanceQuality(articlePaths, thresholds) → {Array.<Object>}
Batch enhance multiple articles
Parameters:
| Name | Type | Description |
|---|---|---|
articlePaths |
Array.<string> | Array of article paths |
thresholds |
Object | Quality thresholds |
Returns:
Array of quality results
- Type
- Array.<Object>
(static) enhanceArticleQuality(articlePath, thresholds) → {Object}
Enhance article quality and validate against thresholds
Parameters:
| Name | Type | Description |
|---|---|---|
articlePath |
string | Path to article HTML file |
thresholds |
Object | Quality thresholds (optional) |
Returns:
Quality assessment result
- Type
- Object
(inner) assessAnalyticalDepth(content) → {number}
Assess analytical depth of article content
Looks for:
- Causal reasoning ("because", "therefore", "as a result")
- Comparative analysis ("compared to", "in contrast", "while")
- Trend analysis ("trend", "pattern", "shift")
- Evidence-based claims (references to data, studies, reports)
- Multiple perspectives (quotes from different actors)
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
Score 0.0-1.0
- Type
- number
(inner) calculateQualityScore(metrics) → {number}
Calculate overall quality score
Weights:
- Analytical depth: 30%
- Party perspectives: 25%
- Cross-references: 25%
- "Why This Matters": 10%
- Historical context: 5%
- International comparison: 5%
Parameters:
| Name | Type | Description |
|---|---|---|
metrics |
Object | Individual quality metrics |
Returns:
Overall score 0.0-1.0
- Type
- number
(inner) countCrossReferences(content) → {number}
Count cross-referenced Riksdag/Regering documents
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
Number of unique document IDs found
- Type
- number
(inner) countPartyPerspectives(content) → {number}
Count unique party perspectives mentioned in article
Uses PARTY_VARIANTS pattern to prevent double-counting when both full names and abbreviations appear in the same text.
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
Number of unique parties mentioned
- Type
- number
(inner) hasHistoricalContext(content) → {boolean}
Detect historical context
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
True if historical context present
- Type
- boolean
(inner) hasInternationalComparison(content) → {boolean}
Detect international comparison
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
True if international comparison present
- Type
- boolean
(inner) hasWhyThisMatters(content) → {boolean}
Detect "Why This Matters" section
Parameters:
| Name | Type | Description |
|---|---|---|
content |
string | HTML content of article |
Returns:
True if section exists
- Type
- boolean
(inner) stripHtml(html) → {string}
Strip HTML tags from content
Parameters:
| Name | Type | Description |
|---|---|---|
html |
string | HTML content |
Returns:
Plain text
- Type
- string