๐ก๏ธ Automated Security Excellence Through Continuous Integration
๐ฏ Transparent Pipeline Operations Demonstrating ISMS Policy Compliance
๐ Document Owner: CEO | ๐ Version: 4.5 | ๐
Last Updated: 2026-05-08 (UTC) | ๐ฆ Release: v0.8.60
๐ Review Cycle: Quarterly | โฐ Next Review: 2026-08-06
CI/CD Pipeline Status:
Security & Quality Metrics:
EU Parliament Monitor's CI/CD workflows implement security controls mandated by Hack23 AB's ISMS framework:
| ISMS Policy | Workflow Implementation |
|---|---|
| ๐ ๏ธ Secure Development Policy | SAST (CodeQL), SCA (Dependency Review), E2E (Playwright), performance testing |
| ๐ Change Management | Automated testing gates, security scanning, PR review requirements |
| ๐ Vulnerability Management | Dependabot, CodeQL, OSSF Scorecard, npm audit, security advisories |
| ๐ Open Source Policy | SLSA attestations, SBOM generation, REUSE license compliance |
| ๐ Information Security Policy | Security-hardened runners, SHA-pinned actions, least privilege permissions |
| ๐ Access Control Policy | OIDC authentication, minimal workflow permissions, branch protection |
| ๐ Cryptography Policy | Sigstore signing, SLSA L3 provenance, build attestations |
| ๐จ Incident Response Plan | Automated rollback procedures, incident classification workflows |
| ๐พ Backup & Recovery Policy | Multi-CDN deployment (S3 + GitHub Pages DR), version control |
| ๐ค Third Party Management | SHA-pinned actions, dependency review, supply chain security |
| Framework | Version | Relevant Controls | Implementation |
|---|---|---|---|
| ISO 27001 | 2022 | A.8.25, A.8.26, A.8.27, A.8.28, A.12.1.4, A.12.6.1, A.14.2.1 | Secure development lifecycle, testing, change management |
| NIST CSF | 2.0 | PR.DS, DE.CM, ID.SC, RS.MI | Data security, monitoring, supply chain, mitigation |
| CIS Controls | v8.1 | 2.2, 4.1, 7.1, 16.1, 17.1 | Software inventory, access control, code signing, application security |
| EU CRA | 2024 | Art. 10, Art. 11 | SBOM generation, vulnerability disclosure, security updates |
| Document | Focus | Description | Documentation Link |
|---|---|---|---|
| Architecture | ๐๏ธ Architecture | C4 model showing current system structure | View Source |
| Future Architecture | ๐๏ธ Architecture | C4 model showing future system structure | View Source |
| Mindmaps | ๐ง Concept | Current system component relationships | View Source |
| Future Mindmaps | ๐ง Concept | Future capability evolution | View Source |
| SWOT Analysis | ๐ผ Business | Current strategic assessment | View Source |
| Future SWOT Analysis | ๐ผ Business | Future strategic opportunities | View Source |
| Data Model | ๐ Data | Current data structures and relationships | View Source |
| Future Data Model | ๐ Data | Enhanced European Parliament data architecture | View Source |
| Flowcharts | ๐ Process | Current data processing workflows | View Source |
| Future Flowcharts | ๐ Process | Enhanced AI-driven workflows | View Source |
| State Diagrams | ๐ Behavior | Current system state transitions | View Source |
| Future State Diagrams | ๐ Behavior | Enhanced adaptive state transitions | View Source |
| Security Architecture | ๐ก๏ธ Security | Current security implementation | View Source |
| Future Security Architecture | ๐ก๏ธ Security | Security enhancement roadmap | View Source |
| Threat Model | ๐ฏ Security | Political Threat Landscape analysis | View Source |
| Classification | ๐ท๏ธ Governance | CIA classification & BCP | View Source |
| CRA Assessment | ๐ก๏ธ Compliance | Cyber Resilience Act | View Source |
| Workflows | โ๏ธ DevOps | CI/CD documentation | View Source |
| Future Workflows | ๐ DevOps | Planned CI/CD enhancements | View Source |
| Business Continuity Plan | ๐ Resilience | Recovery planning | View Source |
| Financial Security Plan | ๐ฐ Financial | Cost & security analysis | View Source |
| End-of-Life Strategy | ๐ฆ Lifecycle | Technology EOL planning | View Source |
| Unit Test Plan | ๐งช Testing | Unit testing strategy | View Source |
| E2E Test Plan | ๐ Testing | End-to-end testing | View Source |
| Performance Testing | โก Performance | Performance benchmarks | View Source |
| Security Policy | ๐ Security | Vulnerability reporting & security policy | View Source |
EU Parliament Monitor employs a comprehensive suite of GitHub Actions workflows (~15 standard + 15 agentic โ 14 unified news-<type>.md + news-translate.md) for automated intelligence operations, quality assurance, security scanning, and release management. All workflows follow the Hack23 ISMS Secure Development Policy standards.
| # | Workflow | Purpose | Schedule / Trigger | ISMS Alignment |
|---|---|---|---|---|
| 1 | Agentic News Workflows (ร15) | AI-generated multi-language news articles (14 article-type unified news-<type>.md + news-translate) |
Varied schedules (see ยง1) | Integrity controls (Medium) |
| 2 | Test & Report | Unit + integration tests, 3026+ tests, coverage, performance | On PR/push to main | Quality assurance (ISO 27001 A.12.1.4) |
| 3 | CodeQL | SAST security scanning (JS/TS + GitHub Actions) | On PR/push + weekly Saturday | Vulnerability management (ISO 27001 A.12.6) |
| 4 | E2E Tests | End-to-end Playwright tests (Chromium) + axe-core | On PR/push + daily midnight UTC | Functional validation + WCAG 2.1 AA |
| 5 | Release | Build, attest (SLSA L3), document, publish to npm (provenance) | Manual/tag push | SLSA L3, Documentation-as-code, npm provenance |
| 6 | Dependency Review | Supply chain security scanning | On PR | Supply chain security (NIST CSF ID.SC) |
| 7 | OpenSSF Scorecard | Security posture assessment | Weekly Tuesday 07:20 UTC | Continuous improvement |
| 8 | Deploy S3 | Production deployment to AWS S3 + CloudFront (OIDC, egress: block) | Push to main | Infrastructure as Code |
| 9 | REUSE Compliance | License and copyright verification (REUSE 3.3) | On PR/push + weekly Monday | Open Source Policy |
| 10 | SLSA Provenance | Build provenance attestation (integrated in release.yml) | On release + manual | Supply chain security (SLSA L3) |
| 11 | Compile Agentic Workflows | Compile .md โ .lock.yml via gh-aw CLI (pinned GH_AW_VERSION: v0.71.4) |
Manual dispatch | Automation governance |
| 12 | Agentics Maintenance | Housekeeping for agentic workflows (stale lock cleanup, health probes) | Scheduled | Automation governance |
| 13 | Labeler | Automatic PR labeling | On pull_request_target | Workflow governance |
| 14 | Setup Labels | Repository label management | Manual dispatch | Repository governance |
| 15 | Copilot Setup Steps | GitHub Copilot agent environment setup | Push/PR to itself + manual | Agent infrastructure |
| 16 | news-translate-reconciler | Reconcile missing translation artifacts across 14 languages | Scheduled | Translation consistency |
| 17 | MCP Reliability Probe | Daily EP/IMF/WB MCP health matrix via npm run mcp:probe |
Daily + manual | Third-party data source assurance |
๐ Security Posture: All 14 standard workflows use SHA-pinned actions (100%), Harden Runner (step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0), and minimal permissions following least privilege principle. Agentic workflows add a 5-layer security model: AWF Squid firewall allowlist, sandboxed Docker with restricted shell, safe-output constraints (create-pull-request with max-patch-size), JSONL audit trail, and lock-file compilation.
graph LR
A[Code Push] --> B[Build & Test]
B --> C[SCA Scan]
C --> D[CodeQL Scan]
D --> E[Quality Gate]
E --> F[Security Gate]
F --> G[SBOM Generation]
G --> H[Attestations]
H --> I[Release]
I --> J[Deploy]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
classDef process fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef success fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class A trigger
class B process
class C,D security
class E,F decision
class G,H security
class I,J success
flowchart TB
subgraph "Continuous Integration"
direction TB
PR[Pull Request] --> CodeQLScan[CodeQL Analysis]
PR --> DependencyReview[Dependency Review]
PR --> Labeler[PR Labeler]
PR --> REUSECheck[REUSE Compliance]
CodeQLScan --> SecurityEvents[Security Events]
end
subgraph "Agentic Content Pipeline"
direction TB
Schedule1[Scheduled / Manual Triggers] --> AgenticNews[15 Agentic News Workflows]
AgenticNews --> Analysis[Political Intelligence Analysis]
Analysis --> Articles[14-Language Article Generation]
Articles --> ContentPR[Content Pull Request]
end
subgraph "Continuous Deployment"
direction TB
Release[Release Trigger] --> BuildTest[Prepare & Test]
BuildTest --> BuildPackage[Build & Package]
BuildPackage --> GenerateSBOM[Generate SBOM]
GenerateSBOM --> Attestations[Create Attestations]
Attestations --> CreateRelease[Create GitHub Release]
end
subgraph "Security Scanning"
direction TB
Weekly[Weekly Schedule] --> WeeklyScan[CodeQL Weekly Scan]
BranchProtection[Branch Protection] --> Scorecard[Scorecard Analysis]
end
PR -.-> |"approved & merged"| main[Main Branch]
ContentPR -.-> |"reviewed & merged"| main
main --> Scorecard
main --> DeployS3[Deploy to S3 + CloudFront]
main -.-> |"tag created"| Release
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
classDef process fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef success fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
class PR,CodeQLScan,DependencyReview,Labeler,REUSECheck trigger
class Release,BuildTest,BuildPackage,GenerateSBOM,Attestations,CreateRelease process
class main,DeployS3 success
class Schedule1,AgenticNews,Analysis,Articles,ContentPR decision
class SecurityEvents,Weekly,WeeklyScan,BranchProtection,Scorecard security
๐ฏ Purpose: AI-powered generation of multi-language news articles about European Parliament activities using GitHub Copilot with the claude-sonnet-4.6 model
๐ Architecture: 15 markdown source files (14 unified news-<type>.md covering 14 article types + 1 news-translate.md helper) compiled to 15 .lock.yml files via gh aw compile (GitHub Agentic Workflows CLI)
๐ Languages: 14 (en, sv, da, no, fi, de, fr, es, nl, ar, he, ja, ko, zh)
๐ Horizon registry: Every horizon's data window, cadence, mandatory artifacts, stage budgets, scenario depth and electoral overlay is defined in src/config/article-horizons.ts โ the single source of truth consumed by the aggregator, the forward-statements registry, and the drift-guard tests.
| ๐ค Workflow | ๐ File | ๐ Schedule | โฑ๏ธ Timeout |
|---|---|---|---|
| ๐จ EU Parliament Breaking News | news-breaking.lock.yml |
Every 6 hours (0 */6 * * *) |
60 min |
| ๐ฎ EU Parliament Week Ahead | news-week-ahead.lock.yml |
Friday 07:00 UTC | 60 min |
| ๐ EU Parliament Month Ahead | news-month-ahead.lock.yml |
1st of month 08:00 UTC | 60 min |
| ๐ EU Parliament Quarter Ahead | news-quarter-ahead.lock.yml |
1st of month 08:00 UTC (0 8 1 * *) |
60 min |
| ๐ฐ๏ธ EU Parliament Year Ahead | news-year-ahead.lock.yml |
Quarterly โ 2nd of Jan/Apr/Jul/Oct 08:00 UTC (0 8 2 1,4,7,10 *) |
60 min |
| ๐๏ธ EU Parliament Term Outlook | news-term-outlook.lock.yml |
Semi-annual โ 1 Jan & 1 Jul 08:00 UTC (0 8 1 1,7 *) |
60 min |
| ๐ณ๏ธ EU Parliament Election Cycle | news-election-cycle.lock.yml |
Annual โ 1 Dec 08:00 UTC (0 8 1 12 *) + T-180 / T-90 / T-30 imminent triggers |
60 min |
| ๐ EU Parliament Week in Review | news-week-in-review.lock.yml |
Saturday 09:00 UTC | 60 min |
| ๐ EU Parliament Month in Review | news-month-in-review.lock.yml |
28th of month 10:00 UTC | 60 min |
| ๐ EU Parliament Quarter in Review | news-quarter-in-review.lock.yml |
5th of month 08:00 UTC (0 8 5 * *) |
60 min |
| ๐ EU Parliament Year in Review | news-year-in-review.lock.yml |
Annual โ 15 Jan 08:00 UTC (0 8 15 1 *) |
60 min |
| ๐ณ๏ธ EU Parliament Plenary Votes & Resolutions | news-motions.lock.yml |
Weekdays (MonโFri) 06:00 UTC | 60 min |
| โ๏ธ EU Parliament Legislative Procedures | news-propositions.lock.yml |
Weekdays (MonโFri) 05:00 UTC | 60 min |
| ๐๏ธ EU Parliament Committee Activity | news-committee-reports.lock.yml |
Weekdays (MonโFri) 04:00 UTC | 60 min |
| ๐ Translate Articles | news-translate.lock.yml |
Manual dispatch only (workflow_dispatch) |
60 min |
Each
news-<type>.mdworkflow runs Stages A โ B โ C โ D โ E in one 60-minute session and produces exactly one PR containing both analysis artifacts and rendered article HTML. The earlier split-pairnews-<type>-analysis.md+news-<type>-article.mdlayout and the manualnews-article-generator.mdhelper were deleted in the April-2026 aggregator-pipeline migration. Thenews-translate.mdhelper (manual dispatch only) is the sole exemption from the single-PR rule.
| Family | Slugs | Stage budgets (A/B/C/D/E) | Stage-C exit | PR-call deadline | Electoral overlay |
|---|---|---|---|---|---|
| Standard short-form | breaking, week-ahead, month-ahead, week-in-review, month-in-review, committee-reports, motions, propositions | 5/22/4/2/2 = 35 (prospective) ยท 4/22/4/2/2 = 34 (retrospective) | minute 36 | โค 45 | โ |
| Long-horizon prospective | quarter-ahead, year-ahead | 5/24โ25/4/2/2 | minute 38โ39 | โค 45 | โ |
| Long-horizon retrospective | quarter-in-review, year-in-review | 4โ5/24โ25/4/2/2 | minute 38โ39 | โค 45 | โ |
| Electoral overlay | term-outlook, election-cycle | 5/26โ28/4/2/2 = up to 41 | minute 42 | โค 47 | โ |
Electoral-overlay invariants (enforced by Stage-C completeness gate when electoralOverlay: true in the registry):
forward-projection.md, term-arc.md, seat-projection.md, mandate-fulfilment-scorecard.md, presidency-trio-context.md, commission-wp-alignment.md, forward-indicators.md, comparative-international.md, and historical-parallels.md.forwardStatementsHorizonDays is bounded at 1500 (term-outlook) / 1825 (election-cycle) โ the registry caps it at 1825.dataWindow.anchor is next-election (constant June 2029 today), giving deterministic windowing across runs.Fallback behaviour: every horizon inherits the standard fallback chain โ empty today MCP feed โ fall back to the wider sliding window declared in the registry; failed get_voting_records for retrospective runs โ EP Open Data Portal direct fetch (see scripts/mcp-setup.sh and src/mcp/ep-mcp-client.ts). A failed long-horizon run does not fall back to a shorter horizon โ Stage-C blocks the PR and the workflow exits non-zero.
All 15 agentic workflows share a common architecture. The 14 article workflows render the committed analysis run into all 14 language-aware HTML variants in Stage D; news-translate.md is a manual helper for refreshing translated Markdown sources when needed:
graph TD
A[๐ Schedule / Manual Trigger] --> B[๐ Activation Job]
B --> C{Conditions Met?}
C -->|โ
Yes| D[๐ค Agent Job<br/>GitHub Copilot + claude-sonnet-4.6]
C -->|โ No| E[โญ๏ธ Skip]
D --> F[๐ฅ Checkout Repository]
F --> G[โ๏ธ Setup Node.js 26]
G --> H[๐ฆ Install Dependencies]
H --> I[๐ Install EP MCP Server v1.3.6+]
I --> J1[๐ฌ Analysis Stage<br/>Political Intelligence Pipeline<br/>--analysis flag]
J1 --> J1a[๐ Classification: significance, impact-matrix, actors, forces]
J1 --> J1b[๐ก๏ธ Threat Assessment: Political Threat Landscape,<br/>actor-threats, disruption]
J1 --> J1c[๐ Risk Scoring: risk-matrix, SWOT, velocity, capital-at-risk]
J1a --> J1d["๐ analysis/daily/YYYY-MM-DD/article-type/"]
J1b --> J1d
J1c --> J1d
J1d --> J[๐ฐ Generate News Articles<br/>npx tsx src/generators/news-enhanced.ts --analysis]
J --> K[๐ฌ๐ง English HTML Output]
K --> L[๐ Create Pull Request<br/>Includes analysis/ artifacts]
L --> M[โ
PR Ready for Review]
L -.-> N[๐ news-translate Workflow<br/>Generates 13 Additional Languages]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef process fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef skip fill:#95a5a6,stroke:#7f8c8d,stroke-width:1.5px,color:white
classDef analysis fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef output fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class A,B trigger
class D,F,G,H,I process
class C decision
class E skip
class J1,J1a,J1b,J1c,J1d analysis
class J,K,L,M,N output
The workflow support logic is organized into bounded contexts under src/workflows/:
src/workflows/
โโโ index.ts # Barrel export โ public API
โโโ types.ts # Shared contracts: DataMode, GateVerdict, PipelineStage
โโโ completeness-gate/ # Stage C analysis validation
โ โโโ index.ts # Public API
โ โโโ types.ts # ValidationRules, ValidatorOptions, ValidationContext
โ โโโ constants.ts # Regex patterns, thresholds (extracted from validator JS)
โ โโโ validators.ts # Pure validation functions (hasMermaid, hasWepBand, etc.)
โโโ infrastructure/ # Shell safety validation rules and utilities
โ โโโ index.ts # Public API
โ โโโ shell-safety.ts # SHELL_SAFETY_RULES[], validateShellSafety()
โโโ safe-outputs/ # Stage E PR creation constraints
โโโ index.ts # Public API
โโโ types.ts # SafeOutputsPRParams, FORBIDDEN_PHRASES, timing constraints
Design principles:
readonly fieldsindex.ts for clean importsImport pattern:
import { completenessGate, infrastructure, safeOutputs } from './workflows/index.js';
// or selectively:
import { hasPlaceholders, computeEffectiveMinLines } from './workflows/completeness-gate/index.js';
| Property | Value |
|---|---|
| Source format | Markdown (.md) compiled by gh aw compile |
| Lock format | YAML (.lock.yml) โ auto-generated, do not edit directly |
| AI Model | claude-sonnet-4.6 via GitHub Copilot CLI |
| Top-level permissions | {} (empty โ no default permissions) |
| Activation job permissions | contents: read |
| Agent job permissions | contents: write, pull-requests: write, issues: write, models: read |
| Concurrency group | gh-aw-${{ github.workflow }} |
| Node.js version | 26 |
| EP MCP Server | european-parliament-mcp-server@1.3.6 (globally installed via scripts/mcp-setup.sh, MCP gateway EP_MCP_GATEWAY_URL resolved dynamically from MCP config; default http://host.docker.internal:8080/mcp/european-parliament) |
| Data sources | European Parliament MCP Server v1.3.6+ (primary, 60+ tools โ sliding + fixed-window feeds + analytical), IMF REST SDMX 3.0 (native fetch in src/mcp/imf-mcp-client.ts, primary economic source โ WEO+FM+IFS+BOP+ER+PCPS+GFSR+EREO+FSI+GFS+DOT), World Bank Open Data MCP (non-economic only โ WDI social/health/education/environment/governance). Economic-context enforcement is editorial at the Stage-C completeness review against .github/prompts/03-analysis-completeness-gate.md and the per-artifact line floors in analysis/methodologies/reference-quality-thresholds.json โ the runtime articlePolicyHas* gates were purged in April-2026 |
| Analysis stage | Stage B writes structured Markdown artifacts under the run directory using the 10-step AI-driven analysis protocol |
| Analysis output | analysis/daily/{date}/{article-type}/ (or suffixed same-day variants) containing manifest.json, raw data, Stage-B artifacts, article.md, and article-meta.json. Article-type scoping prevents merge conflicts between concurrent workflows. |
00โ09)Every article-generating news-*.md (all except news-translate.md) executes
the same five bounded stages. This is the canonical flow; it aligns 1-to-1
with the ten-file prompt library in .github/prompts/:
| Stage | Name | Prompt file(s) | Output location |
|---|---|---|---|
| A | Data collection | 01-data-collection.md + 07-mcp-reference.md |
analysis/daily/<YYYY-MM-DD>/<type>-run<NN>/intelligence/* |
| B | Analysis (2-pass mandatory) | 02-analysis-protocol.md โ analysis/methodologies/ai-driven-analysis-guide.md (10 steps, Rules 1โ22) |
classification / threat / risk / synthesis artifacts under the same run dir |
| C | Completeness gate | 03-analysis-completeness-gate.md โ npm run validate-analysis vs analysis/methodologies/reference-quality-thresholds.json |
blocks PR if any floor is missed |
| D | Deterministic article render | 04-article-generation.md + 05-analysis-to-article-contract.md; no AI-authored HTML |
analysis/daily/<date>/<type>/article.md, article-meta.json, news/<slug>.en.md, and 14 news/<slug>-<lang>.html files |
| E | Single PR | 06-pr-and-safe-outputs.md โ one safeoutputs___create_pull_request call at end of run |
GitHub PR (max 1 per run; news-translate.md is the sole exemption โ multi-call flush for 14-language fan-out) |
Stage D's Read-Before-Write rule requires the agent to consult every artifact
produced in Stage B before drafting prose; the artifact โ article-section
map lives in 04-article-generation.md ยง 7.1.
The 39-template artifact catalogue (14 agentic-workflow templates โ which
include 6 reusable framework templates โ plus 25 per-artifact templates, and
the analysis-index.md + README.md catalogue files) is enumerated in
analysis/templates/README.md and mapped to
methodologies in analysis/methodologies/artifact-catalog.md.
Each news-*.md (except news-translate.md) uses gh-aw's imports: field
twice:
imports:
- shared/mcp/news-mcp-servers.md # frontmatter-only: MCP servers merged into frontmatter
- ../agents/news-generation.agent.md # body-only: Required Reading + Stage Contract appended to prompt
shared/mcp/news-mcp-servers.md is the single source of truth for the
mcp-servers: block (EP, World Bank, IMF, MCP Gateway mounts). Editing it
propagates to every importing workflow on next compile..github/agents/news-generation.agent.md contributes body-only content
(confirmed against gh-aw v0.71.4, 2026-04-21: imported agent frontmatter is
not merged into workflow frontmatter). It appends the canonical Required
Reading order and the 5-stage Stage Contract to every importing prompt..lock.yml by compile-agentic-workflows.yml.Every news-*.md declares:
safe-outputs:
create-pull-request:
max: 1 # default for every news-*.md
Documented exceptions:
news-translate.md uses excluded-files: and a multi-call flush
pattern with max-patch-size; it is exempt from the single-PR rule and
is the only workflow that calls safeoutputs___create_pull_request more
than once.Critical semantic: safeoutputs___create_pull_request takes a
synchronous git format-patch snapshot AT CALL TIME of the agent's working
tree. Calling it before all files are written produces a partial PR. It must
therefore be invoked exactly once at the very end of the run, after every
article, analysis artifact, and manifest has been written to disk. The
banned alternatives โ checkpoint PRs, keep-alive heartbeats, progressive safe
outputs, and safeoutputs___push_repo_memory โ are CI-lint-enforced by
scripts/lint-prompts.js / npm run lint:prompts.
See .github/prompts/README.md ยง Drift-guard Lint
for the full rule set.
Source markdown files are compiled to lock files using the GitHub Agentic Workflows CLI:
# Compile all agentic workflow definitions
gh aw compile
The compile-agentic-workflows.yml workflow automates this process (see ยง11).
| Control | Implementation | ISMS Reference |
|---|---|---|
| Input Validation | MCP data validated via schema before use | ISO 27001 A.14.2.1 |
| HTML Sanitization | Strip scripts, encode entities in generated content | OWASP Top 10 (XSS) |
| Empty Top-Level Permissions | permissions: {} โ no default permissions |
Least privilege |
| Scoped Job Permissions | Write permissions only on agent job | Least privilege |
| Concurrency Control | Single concurrent run per workflow | Resource governance |
| PR-Based Output | All generated content via PR, not direct push | Change review |
.github/workflows/news-*.lock.yml.github/workflows/news-*.mdEvery workflow downloads unique data and produces article-type-specific analytics. The following matrix shows the mandatory MCP data downloads and analytical tools unique to each workflow:
flowchart LR
subgraph "๐ด Breaking News"
B1["adopted_texts_feed\nevents_feed\nprocedures_feed\nmeps_feed"] --> B2["detect_voting_anomalies\nanalyze_coalition_dynamics\nearly_warning_system\ngenerate_political_landscape"]
end
subgraph "๐ Motions"
M1["adopted_texts_feed\nquestions_feed\nmeps_feed\nprocedures_feed"] --> M2["detect_voting_anomalies\nanalyze_coalition_dynamics\nget_voting_records\ncompare_political_groups"]
end
subgraph "๐ Propositions"
P1["procedures_feed\ndocuments_feed\nadopted_texts_feed\nplenary_docs_feed"] --> P2["search_documents\nmonitor_legislative_pipeline\ntrack_legislation\nanalyze_legislative_effectiveness"]
end
subgraph "๐๏ธ Committee Reports"
C1["committee_docs_feed\nplenary_docs_feed\nadopted_texts_feed\nprocedures_feed"] --> C2["get_committee_info\nmonitor_legislative_pipeline\nanalyze_legislative_effectiveness"]
end
style B1 fill:#dc3545,stroke:#b02a37,color:#fff
style B2 fill:#dc3545,stroke:#b02a37,color:#fff
style M1 fill:#fd7e14,stroke:#ca6510,color:#fff
style M2 fill:#fd7e14,stroke:#ca6510,color:#fff
style P1 fill:#ffc107,stroke:#cc9a06,color:#000
style P2 fill:#ffc107,stroke:#cc9a06,color:#000
style C1 fill:#198754,stroke:#146c43,color:#fff
style C2 fill:#198754,stroke:#146c43,color:#fff
| Workflow | Mandatory Feed Data | Mandatory Analytical Tools | Unique Focus |
|---|---|---|---|
| Breaking | adopted_texts, events, procedures, meps (todayโone-week) + documents, plenary_docs, committee_docs, questions | detect_voting_anomalies, analyze_coalition_dynamics, early_warning_system, generate_political_landscape | โก Only TODAY's items; 6-hour cycle |
| Motions | adopted_texts, parliamentary_questions, meps, procedures | detect_voting_anomalies, analyze_coalition_dynamics, get_voting_records, compare_political_groups | ๐ณ๏ธ Per-resolution vote breakdowns |
| Propositions | procedures, documents, adopted_texts, plenary_documents | search_documents, monitor_legislative_pipeline, track_legislation, analyze_legislative_effectiveness | ๐ Procedure stage tracking |
| Committee | committee_documents, plenary_documents, adopted_texts, procedures | get_committee_info, monitor_legislative_pipeline, analyze_legislative_effectiveness | ๐๏ธ Per-committee deep analysis |
| Week Ahead | events, procedures, plenary_documents, plenary_session_documents | get_plenary_sessions (future), get_committee_info, monitor_legislative_pipeline, generate_political_landscape | ๐ Prospective agenda analysis |
| Weekly Review | adopted_texts, procedures, plenary_documents, parliamentary_questions | get_voting_records, detect_voting_anomalies, generate_political_landscape | ๐ Retrospective outcome review |
| Month Ahead | events, procedures, plenary/committee docs, adopted_texts, session docs, meps | get_plenary_sessions, get_committee_info, monitor_pipeline, generate_landscape, compare_groups, analyze_delegation | ๐ Strategic calendar outlook |
| Monthly Review | adopted_texts, procedures, plenary_documents, parliamentary_questions | get_voting_records, detect_anomalies, generate_landscape, compare_groups, analyze_effectiveness | ๐ Comprehensive monthly trends |
| Translate | โ (manual helper) | โ | ๐ Refresh translated Markdown sources |
PRIO 1 MANDATE: Each workflow ALWAYS downloads its mandatory feed data and runs its mandatory analytical tools BEFORE deciding whether to produce an article. Data collection is NEVER skipped, even for noop runs.
๐ Files: .github/workflows/news-*.md (14 content workflows + 1 translation workflow)
๐ฏ Purpose: AI-powered news article generation using GitHub Agentic Workflows (gh-aw) with European Parliament MCP Server data
โฐ Schedule: Various (see table below)
The agentic news system uses a deterministic aggregator architecture:
This keeps political-intelligence authoring in Markdown artifacts and makes HTML generation reproducible across every language.
graph TD
A[๐ Article Workflows<br/>Stage A-E] -->|Write| B[๐ง analysis/daily run]
B -->|Render| C[๐ 14 HTML variants]
C -->|Single safe-output| D[๐ Content PR]
B -.->|Manual refresh| E[๐ news-translate.md]
E -.->|Translated Markdown sources| C
D -->|Merge + deploy| F[โ๏ธ S3 / CloudFront<br/>Language Switchers + Sitemaps]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef process fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef render fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef translation fill:#e67e22,stroke:#d35400,stroke-width:1.5px,color:white
class A trigger
class B,D process
class C,F render
class E translation
| Workflow | Article Type | Schedule | Focus |
|---|---|---|---|
| ๐ค Workflow | ๐ท๏ธ Type | ๐ Schedule | ๐ฏ Purpose |
| --- | --- | --- | --- |
news-committee-reports.md |
committee-reports | MonโFri 04:00 UTC | Committee activity analysis |
news-propositions.md |
propositions | MonโFri 05:00 UTC | Legislative pipeline tracking |
news-motions.md |
motions | MonโFri 06:00 UTC | Voting patterns & resolutions |
news-week-ahead.md |
week-ahead | Fri 07:00 UTC | Upcoming parliamentary agenda |
news-month-ahead.md |
month-ahead | 1st of month 08:00 UTC | Monthly strategic outlook |
news-week-in-review.md |
week-in-review | Sat 09:00 UTC | Week in review |
news-month-in-review.md |
month-in-review | 28th of month 10:00 UTC | Monthly retrospective |
news-breaking.md |
breaking | Every 6 hours | Real-time EP feed events |
Each
news-<type>.mdruns the full Stage AโE protocol in one ~60-minute session and produces exactly one PR with both analysis artifacts and the rendered article HTML. The earlier split-pairnews-<type>-analysis.md+news-<type>-article.mdlayout and the manualnews-article-generator.mdhelper were deleted in the April-2026 aggregator-pipeline migration (the prior legacy single-jobnews-<type>.mdwere briefly replaced by split pairs in 2025 because those exceeded the safeoutputs MCP TTL โ the unified workflows intentionally do not setengine.mcp.session-timeoutbecause the bundled MCP gateway rejects the field; the default gateway keepalive is used and the PR call lands by minute โค 45 of the 60-mintimeout-minutescap).
| Workflow | Schedule | Purpose |
|---|---|---|
news-translate.md |
Manual (workflow_dispatch) only |
Refresh or complete sv, da, no, fi, de, fr, es, nl, ar, he, ja, ko, zh translated Markdown sources; multi-call safe-output flush is allowed only here |
| English (en) | Swedish (sv) | Danish (da) | Norwegian (no) | Finnish (fi) |
|---|---|---|---|---|
| German (de) | French (fr) | Spanish (es) | Dutch (nl) | Arabic (ar) |
| Hebrew (he) | Japanese (ja) | Korean (ko) | Chinese (zh) |
Every
article.mdproduced by an agentic workflow always renders to 14 language-aware HTML files โ there is no opt-out, no subset, and no markdown-only escape hatch.
| Property | Before May 2026 | After May 2026 |
|---|---|---|
npm run generate-article -- --lang en --lang sv |
Rendered selected languages only | Rejected โ flag removed; CLI always renders all 14 |
npm run generate-article -- --markdown-only |
Skipped HTML emission | Rejected โ flag removed; HTML is always emitted |
news-translate.md languages: workflow_dispatch input (all-non-en / eu-core / nordic / comma-separated) |
Configurable subset | Removed โ every run translates to all 13 non-English languages |
Article workflows (news-<type>.md) Stage D |
Could be configured to render fewer languages via --lang |
Always render all 14 languages from the committed analysis run |
Why: per-language partial coverage created a long tail of articles where <slug>-en.html existed but <slug>-zh.html did not, and silent CLI subset selection let workflows drift from the committed product contract. Hard-wiring "always 14" at the CLI boundary makes coverage a property of every run rather than a property of every invocation choice. The aggregator's idempotent skip-write logic (mtime โฅ source artefacts) keeps re-renders cheap when only a subset of languages were actually missing.
Programmatic escape hatch: generateArticle() (called from unit / integration tests for speed) still accepts langs and markdownOnly directly on the options object โ only the CLI surface area (and therefore every workflow) is locked down.
| Control | Implementation | ISMS Reference |
|---|---|---|
| MCP Data Source | European Parliament MCP Server (live data) | ISO 27001 A.14.2.1 |
| Content Integrity | Quality validation, synthetic ID detection | Data integrity |
| Safe Outputs | gh-aw safe-outputs for PR creation | Least privilege |
| Concurrency | Shared concurrency group prevents conflicts | Resource management |
| Network Allowlist | Explicit domain allowlisting via gh-aw | Network security |
The following 14 unified article-generation workflows include mandatory analytical enhancements: news-breaking.md, news-week-ahead.md, news-month-ahead.md, news-quarter-ahead.md, news-year-ahead.md, news-term-outlook.md, news-election-cycle.md, news-week-in-review.md, news-month-in-review.md, news-quarter-in-review.md, news-year-in-review.md, news-committee-reports.md, news-propositions.md, news-motions.md. The news-translate.md workflow has complementary analysis-fidelity requirements for preserving these elements in translation.
Every major parliamentary action must be analyzed from at least 3 of 6 stakeholder perspectives:
| Perspective | Analysis Focus |
|---|---|
| EP Political Groups | Coalition dynamics, group influence, voting alliances |
| Civil Society & NGOs | Citizens' rights, democratic participation, transparency |
| Industry & Business | Regulatory burden, market effects, compliance dynamics |
| National Governments | Subsidiarity, implementation requirements, national interests |
| EU Citizens | Direct life impact, rights, services, democratic representation |
| EU Institutions | Commission, Council, ECB, Court of Justice โ inter-institutional dynamics |
Stakeholder perspective analysis is rendered by the TypeScript generator (buildStakeholderPerspectivesSection) as a card grid in each article's deep-analysis portion. Agents provide structured perspective content โ impact direction (positive/negative/neutral/mixed), severity (high/medium/low), reasoning, and evidence backed by specific EP MCP data citations โ and the generator handles the HTML markup (analysis-stakeholder-perspectives / stakeholder-perspectives-grid). Agents must NOT write raw HTML for this section. Impact and severity values must remain as canonical English enum tokens (e.g. positive, high) even in non-English articles โ the generator handles localized display labels and CSS classing from these tokens. (Note: the separate winners/losers outcomes list uses analysis-stakeholders / stakeholder-list โ that is a different section rendered by buildStakeholderSection.)
All analytical content sections follow a mandatory 4-pass refinement process:
| Pass | Activity | Output |
|---|---|---|
| Pass 1 โ Initial Assessment | Gather MCP baseline data; identify actors, actions, outcomes | Draft narrative |
| Pass 2 โ Stakeholder Challenge | Re-examine from each stakeholder angle; flag blind spots | Revised draft with gaps identified |
| Pass 3 โ Evidence Cross-Validation | Verify claims against EP documents/votes; add ๐ข/๐ก/๐ด confidence indicators | Evidenced assertions only |
| Pass 4 โ Synthesis & Scenarios | Produce balanced conclusions; provide 2โ3 forward-looking scenarios with probability labels | Final publishable analysis |
Localization requirement: All text labels โ confidence (๐ข High / ๐ก Medium / ๐ด Low), probability (likely / possible / unlikely), and significance (High / Medium / Low) โ must be rendered in the article's output language while preserving the underlying 3-level scale and keeping emoji markers (๐ข/๐ก/๐ด, โโโ) unchanged. Non-English articles must use the equivalent terms in the target language, not English labels.
In addition to the existing content quality gates (500-word minimum, no synthetic IDs, current dates), all articles must pass two new quality gate categories:
Analysis Depth Gates:
Political Intelligence Gates:
Every key EP document featured in the deep-analysis section must include structured analysis (other document references may remain as citations without full framework analysis):
Each scheduled content workflow includes a tailored intelligence module beyond the shared framework:
| Workflow | Module | Focus |
|---|---|---|
news-week-ahead.md |
๐ญ Strategic Preview Analysis | What to watch, coalitions under stress, legislative inflection points, geopolitical triggers |
news-month-ahead.md |
๐ Long-Term Trend Context | Term trajectory, policy momentum, coalition evolution, EU external context |
news-quarter-ahead.md |
๐งญ Quarterly Outlook | Coalition stability projection, policy momentum, blocking coalitions |
news-year-ahead.md |
๐ฎ Annual Forward Projection | Multi-quarter trajectory, electoral pressure, partisan/coalition shifts |
news-term-outlook.md |
๐๏ธ Term-Length Strategic Outlook | Multi-year coalition viability, mandate-fulfillment trajectory |
news-election-cycle.md |
๐ณ๏ธ Electoral-Cycle Intelligence | Cycle-position drivers, group-volatility forecast |
news-breaking.md |
โก Rapid Stakeholder Impact Assessment | Immediate winners/losers, market/policy signals, next 24โ48 hour tracking |
news-committee-reports.md |
๐๏ธ Committee Power Dynamics Analysis | Rapporteur influence, shadow rapporteur positions, amendment landscape, trilogue implications |
news-propositions.md |
๐๏ธ Legislative Pipeline Intelligence | Passage probability, amendment expectations, timeline forecast, blocking coalitions |
news-motions.md |
๐ณ๏ธ Voting Pattern Intelligence | Coalition map, abstention analysis, cross-party defections, margin analysis |
news-week-in-review.md |
๐ Week-in-Context Analysis | Parliamentary landscape shift, promises vs. delivery, surprise developments |
news-month-in-review.md |
๐บ๏ธ Monthly Trend Synthesis | Legislative productivity, coalition stability index, policy trajectory, emerging themes |
news-quarter-in-review.md |
๐ Quarterly Retrospective | Coalition stability index, productivity benchmarks |
news-year-in-review.md |
๐ Annual Retrospective | Year-long trend confirmation, accountability ledger |
The translation workflow has its own fidelity module:
| Workflow | Module | Focus |
|---|---|---|
news-translate.md |
๐ Analysis Fidelity Requirements | Stakeholder framing preservation, confidence indicator translation, EP official terminology |
๐ File: .github/workflows/test-and-report.yml
๐ฏ Purpose: Comprehensive testing with unit tests, integration tests, coverage reporting, and performance benchmarks
โฐ Trigger: On push to main, on PR to main
๐ Status:
| Test Type | Framework | Coverage Target | Current Status |
|---|---|---|---|
| Unit Tests | Vitest 4.1.5 (happy-dom) | 76 test files | โ 3026+ passing |
| Integration Tests | Vitest + MCP contract suites (test/integration/mcp-integration.test.js, test/integration/mcp/imf-mcp.test.js, test/integration/mcp/worldbank-mcp.test.js) |
IMF/WB canonical tool lists asserted via drift-guard tests; EP MCP covered by mcp-integration.test.js (no canonical EP_MCP_TOOLS export yet) |
โ All passing |
| Line Coverage | Vitest (V8) | โฅ80% | โ 82%+ |
| Branch Coverage | Vitest (V8) | โฅ75% | โ 83%+ |
| Function Coverage | Vitest (V8) | โฅ80% | โ 89%+ |
| E2E | Playwright 1.59.1 + @axe-core/playwright 4.11.3 | WCAG 2.1 AA | โ Passing |
graph LR
A[Prepare] --> B[Validation]
A --> C[Functional Tests]
A --> D[Performance]
A --> E[Security Check]
B --> F[Report]
C --> F
D --> F
E --> F
classDef prepare fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef test fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef perf fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef report fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
class A prepare
class B,C test
class D perf
class E security
class F report
| Job | Name | Purpose | Key Steps |
|---|---|---|---|
prepare |
Prepare Environment | Cache dependencies, setup Node.js 26 | Checkout, npm ci, cache |
validation |
Validate Code | ESLint, Prettier, HTMLHint, npm audit | Lint, format check, HTML validation |
functional-tests |
Functional Tests | Vitest unit + integration tests | Run tests, coverage report |
performance |
Performance Testing | Lighthouse CI + article generation benchmarks | @lhci/cli@0.15.1, performance metrics |
security-check |
Security Check | npm audit analysis | Vulnerability triage, CodeQL integration |
report |
Generate Report | Aggregate results, PR comments | Coverage summary, status checks |
| Control | Implementation | ISMS Reference |
|---|---|---|
| Code Quality | ESLint + Prettier | Code quality standards |
| Vulnerability Scanning | npm audit | ISO 27001 A.12.6.1 |
| Coverage Thresholds | 80%+ lines, 75%+ branches | Quality gates |
| Performance Benchmarks | Lighthouse CI scoring | Performance validation |
| False Positive Handling | Intelligent npm audit triage | Risk acceptance process |
๐ File: .github/workflows/knip.yml
๐ฏ Purpose: Detect unused files, exports, dependencies, and types across src/** and the hand-written scripts in scripts/** so the codebase stays lean ahead of releases.
โฐ Trigger: On push to main, on PR to main
๐ Mode: โ ๏ธ Warning-only (continue-on-error: true) until the baseline stabilises across two consecutive PR cycles, then flipped to blocking.
| Surface | Coverage |
|---|---|
| Source files | src/**/*.ts (the authoritative TypeScript tree) |
| Hand-written JS | All scripts/**/*.js files referenced from package.json scripts are auto-discovered (e.g. scripts/copy-vendor.js, scripts/lint-prompts.js, scripts/validate-analysis-completeness.js); files only invoked from agentic-workflow .md bodies (e.g. scripts/backport-article-seo.js, scripts/aggregator/forward-statements-registry.js) are listed explicitly in knip.json entry |
| Test fixtures | test/**/*.test.js, e2e/**/*.spec.js |
Compiled scripts/** |
Excluded from project (it is a 1:1 build output of src/**); CLI entry points are auto-discovered via the package.json exports map |
| Generated artefacts | analysis/**, data/**, news/**, docs/**, coverage/**, js/vendor/** โ never scanned |
The full configuration lives in knip.json. Highlights:
.github/workflows/*.md gh-aw bodies).ignoreDependencies covers runtime-spawned packages (european-parliament-mcp-server โ launched via npx by the MCP gateway, not imported), browser-vendored bundles (chart.js, d3, mermaid, chartjs-plugin-annotation, papaparse โ copied by scripts/copy-vendor.js), and config-only tooling (jscpd, lint-staged, eslint-config-prettier, ts-api-utils).european-parliament-mcp-server invoked via npx by the MCP gateway, never imported as a library) are listed in ignoreDependencies so they are not flagged as unused.npm run knip # show all unused files / exports / deps
npm run knip:production # production-only mode (skips test entries)
npm run knip:fix # auto-remove unused exports (use with care, review diff)
| Finding | Category | Action |
|---|---|---|
| Unused file | (a) should be wired up | Open follow-up issue; do not delete |
| Unused export | (b) used by workflow not detected | Refine entry/project in knip.json (preferred) or add comment-justified ignore |
| Unused dependency | (c) truly unused | Remove from package.json, run npm install, commit lockfile |
| Unused type | (c) truly unused | Delete and update tests |
Prefer fixing knip's view of the world over adding ignores. Every ignore must carry an inline $comment or a one-line rationale in the PR description.
| Job | Name | Purpose | Key Steps |
|---|---|---|---|
knip |
Knip Scan | Unused-code detection | Checkout โ setup Node 26 โ npm ci โ npm run build โ npm run knip โ write $GITHUB_STEP_SUMMARY โ upload knip-output.txt artefact (14-day retention) |
The job runs npm run build first because knip resolves imports through the package.json exports map, which points at compiled scripts/**.
| Control | Implementation | ISMS Reference |
|---|---|---|
| Hardened Runner | step-security/harden-runner (audit egress) |
ISO 27001 A.8.16 |
| Read-only permissions | contents: read, pull-requests: read |
ISO 27001 A.5.15 |
| SHA-pinned actions | All third-party actions pinned by digest | ISO 27001 A.8.30 |
| Concurrency control | cancel-in-progress: true per ref |
Resource hygiene |
๐ File: .github/workflows/codeql.yml
๐ฏ Purpose: Static Application Security Testing (SAST) for JavaScript/TypeScript and GitHub Actions
โฐ Schedule: On push to main, on PR to main, weekly Saturday 21:33 UTC
๐ Status:
| Parameter | Value |
|---|---|
| Languages | javascript-typescript, actions |
| Build Mode | none (interpreted languages) |
| Query Suite | Security Extended |
| Analysis Type | Source code + dependencies |
Vulnerability Types Detected:
| Control | Implementation | ISMS Reference |
|---|---|---|
| SAST Scanning | CodeQL security-extended (JS/TS + Actions) | ISO 27001 A.14.2.5 |
| Automated Analysis | On every PR + push | Shift-left security |
| SHA-Pinned Actions | All actions pinned to SHA | Supply chain security |
| Security Alerts | GitHub Security tab integration | Incident response |
๐ File: .github/workflows/e2e.yml
๐ฏ Purpose: End-to-end testing with Playwright across browsers
โฐ Schedule: On push to main, on PR to main, daily at midnight UTC
๐ Status:
| Control | Implementation | ISMS Reference |
|---|---|---|
| Accessibility Testing | axe-core WCAG AA compliance | Inclusive security |
| Visual Regression | Screenshot comparison | Quality assurance |
| Functional Validation | User workflow testing | Requirements validation |
| Daily Regression | Scheduled midnight UTC | Continuous validation |
๐ File: .github/workflows/release.yml
๐ฏ Purpose: Comprehensive release automation with attestations and documentation
โฐ Trigger: Manual dispatch (with version input) or tag push (v*)
๐ Status:
graph TD
A[๐ Trigger: Manual/Tag] --> B[๐ Prepare Job]
B --> C[โ
Run Tests with Coverage]
C --> D[๐ญ Run E2E Tests]
D --> E[๐ Generate API Docs]
E --> F[๐ Generate Coverage Reports]
F --> G[๐จ Generate Doc Index]
G --> H[โ
Verify Structure]
H --> I[๐พ Commit Documentation]
I --> J[๐จ Build Job]
J --> K[๐ฆ Create Release Artifacts]
K --> L[๐ Generate SBOM]
L --> M[๐ Build Provenance]
M --> N[๐ SBOM Attestation]
N --> O[๐ Release Job]
O --> P[๐ Draft Release Notes]
P --> Q[๐ Create GitHub Release]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef test fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef docs fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef build fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef release fill:#2ecc71,stroke:#27ae60,stroke-width:2px,color:white
class A trigger
class B,C,D test
class E,F,G,H,I docs
class J,K build
class L,M,N security
class O,P,Q release
| Job | Name | Key Permissions |
|---|---|---|
prepare |
Prepare Release | contents: write |
build |
Build Release Package | contents: read, id-token: write, attestations: write |
release |
Create Release | contents: write, id-token: write |
Every release automatically generates:
| Documentation | Generator | Output |
|---|---|---|
| API Documentation | JSDoc | 52 files, searchable |
| Test Coverage | Vitest HTML | Interactive reports |
| E2E Test Reports | Playwright | Screenshots, videos |
| Documentation Index | Custom script | Beautiful hub page |
| Control | Implementation | ISMS Reference |
|---|---|---|
| SLSA Level 3 | Build provenance attestation + npm provenance (--provenance flag on publish) |
Supply chain security |
| SBOM Generation | SPDX JSON format via anchore/sbom-action |
NTIA SBOM minimum elements |
| Artifact Signing | GitHub Attestations API (Sigstore, OIDC keyless) | Integrity verification |
| npm Registry | Published to registry.npmjs.org/euparliamentmonitor with Sigstore provenance |
Supply chain transparency |
| Documentation Audit Trail | Committed to main branch | Evidence trail |
| Test Validation | 3026+ unit/integration tests + E2E Playwright | Quality gates |
๐ File: .github/workflows/dependency-review.yml
๐ฏ Purpose: Supply chain security scanning for pull requests
โฐ Trigger: On pull request
๐ Status: Dependency review enabled
| Control | Implementation | ISMS Reference |
|---|---|---|
| License Compliance | Allowed licenses only | Legal compliance |
| Vulnerability Detection | Known CVEs blocked | ISO 27001 A.12.6.1 |
| Supply Chain Security | Dependency graph analysis | NIST CSF ID.SC |
๐ File: .github/workflows/scorecards.yml
๐ฏ Purpose: Security posture assessment against OpenSSF best practices
โฐ Schedule: Weekly on Tuesday 07:20 UTC, push to main, branch protection rule
๐ Status:
๐ File: .github/workflows/deploy-s3.yml
๐ฏ Purpose: Production deployment to AWS S3 + CloudFront
โฐ Trigger: Push to main
๐ Status: Production deployment
graph LR
A[Push to main] --> B[Checkout Code]
B --> C[๐ Harden Runner<br/>egress: BLOCK]
C --> D[Configure AWS OIDC]
D --> E[Sync to S3]
E --> F[Invalidate CloudFront]
F --> G[โ
Production Live]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef aws fill:#FF9900,stroke:#232F3E,stroke-width:1.5px,color:white
classDef complete fill:#27ae60,stroke:#1e8449,stroke-width:2px,color:white
class A trigger
class B,C security
class D,E,F aws
class G complete
Note:
deploy-s3.ymlis the only workflow usingegress-policy: block(all other workflows useaudit). Outbound network calls are restricted to an explicit allowlist defined in theallowed-endpointsparameter of the Harden Runner step within deploy-s3.yml.
| Control | Implementation | ISMS Reference |
|---|---|---|
| OIDC Federation | aws-actions/configure-aws-credentials with role ARN |
No long-lived secrets |
| Egress Block Mode | Harden Runner blocks all non-allowlisted endpoints | Network security |
| IAM Least Privilege | Minimal S3 + CloudFront permissions | AWS security best practices |
| HTTPS Only | CloudFront SSL/TLS distribution | Data in transit protection |
| Infrastructure as Code | GitHub Actions workflow | Reproducible deployments |
๐ File: .github/workflows/reuse.yml
๐ฏ Purpose: License and copyright compliance verification using the REUSE Specification
โฐ Schedule: On push to main, on PR to main, weekly Monday 06:00 UTC
๐ Status:
| Artifact | License | SPDX Header Required |
|---|---|---|
Source scripts (scripts/) |
Apache-2.0 | โ Yes |
Test files (test/, e2e/) |
Apache-2.0 | โ Yes |
HTML pages (index-*.html) |
Apache-2.0 | โ Yes |
Workflow files (.github/workflows/) |
Apache-2.0 | โ Yes |
| Binary assets | Declared in REUSE.toml |
Via manifest |
| Control | Implementation | ISMS Reference |
|---|---|---|
| License Verification | SPDX header validation on every file | Open Source Policy |
| Copyright Compliance | Per-file copyright tracking | IP management |
| Supply Chain Clarity | Machine-readable REUSE.toml |
NIST CSF ID.SC-4 |
| SHA-Pinned Action | fsfe/reuse-action pinned to SHA |
Supply chain security |
๐ File: .github/workflows/release.yml
๐ฏ Purpose: Generate cryptographic build provenance for supply chain integrity verification
โฐ Trigger: On tag push (v*) + manual dispatch with version input
๐ Status:
SLSA Level 3 provenance is generated as part of the release workflow build job. All attestations and SBOM are created during the build step and attached to the immutable GitHub Release in a single atomic operation.
| Artifact | Action | Verification Command |
|---|---|---|
| Build Provenance | actions/attest-build-provenance (SHA-pinned) |
gh attestation verify --owner Hack23 <file> |
| SBOM (SPDX) | anchore/sbom-action + actions/attest (SHA-pinned) |
gh attestation verify --owner Hack23 <file> |
| Distribution Archive | .zip with excluded dev files |
SHA-256 checksum |
| SBOM JSON | SPDX format | License compliance check |
| Control | Implementation | ISMS Reference |
|---|---|---|
| OIDC Keyless Signing | id-token: write + GitHub Sigstore |
SLSA Level 3 |
| Immutable Release | immutableCreate: true โ single-write release |
Integrity |
| Minimal Permissions | permissions: read-all top-level |
Least privilege |
| Harden Runner | egress audit on all outbound calls | Network security |
๐ File: .github/workflows/compile-agentic-workflows.yml
๐ฏ Purpose: Compile agentic workflow markdown source files (.md) into executable lock files (.lock.yml) using the gh-aw CLI (pinned GH_AW_VERSION: v0.71.4)
โฐ Trigger: Manual dispatch only (workflow_dispatch)
๐ Status:
Version pin contract:
GH_AW_VERSION: v0.71.4is a repository-level environment pin incompile-agentic-workflows.yml. Bumping this pin requires re-compilation of all 15.lock.ymlfiles, a full PR review, and successfulgh aw compile --validateacross the workflow set. Any.mdโ.lock.ymldrift is detected byagentics-maintenance.yml.
graph LR
A[Manual Trigger] --> B[Checkout Repository]
B --> C["Install gh-aw CLI<br/>(pinned v0.71.4)"]
C --> D["Run gh aw compile --validate<br/>Validates frontmatter + safe-outputs"]
D --> E["Commit & Push<br/>.lock.yml Files"]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef process fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef output fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class A trigger
class B,C,D process
class E output
| Gotcha | Impact | Mitigation |
|---|---|---|
| Bash Tool Call Contract | Every bash tool call in an agentic workflow MUST specify BOTH command and description parameters โ omitting description causes silent tool-call rejection |
Validator in gh aw compile --validate + agent system prompt enforcement |
| AWF Sandbox Expansion Restrictions | Dangerous shell expansions (${var@P}, chained variable assignments building command substitutions, ${!var}, eval-like constructs) are refused by the sandbox |
Agents must not attempt prompt-injection patterns; sandbox logs refused attempts |
| max-patch-size Tuning | Default create-pull-request max-patch-size is 1024 KB; news-translate.md overrides to 10240 KB at top level to accommodate 14-language fan-out patches |
Top-level YAML frontmatter in news-translate.md sets the elevated limit |
| Dynamic file resolution | Agents must not hallucinate filenames; use ls -t "news/${TODAY}-${TYPE}"*"-en.html" | head -1 pattern to resolve latest English source for translation |
Pattern documented in workflow system prompts |
| Control | Implementation | ISMS Reference |
|---|---|---|
| Manual Trigger Only | workflow_dispatch โ no automatic runs |
Change control |
| Version Pin | GH_AW_VERSION: v0.71.4 pinned at workflow env |
Supply chain integrity |
| Token Fallback | COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN with GITHUB_TOKEN fallback |
Credential management |
| Write Permissions | contents: write, pull-requests: write, actions: write, issues: write |
Least privilege for compilation |
๐ File: .github/workflows/labeler.yml
๐ฏ Purpose: Automatically label pull requests based on file paths and content
โฐ Trigger: pull_request_target (opened, synchronize, reopened, edited)
| Control | Implementation | ISMS Reference |
|---|---|---|
| Minimal Job Permissions | contents: read, pull-requests: write, issues: read |
Least privilege |
| Target Event | pull_request_target โ runs on base branch code |
Workflow security |
๐ File: .github/workflows/setup-labels.yml
๐ฏ Purpose: Create and manage repository labels for issue/PR governance
โฐ Trigger: Manual dispatch only (workflow_dispatch with recreate_all input)
| Control | Implementation | ISMS Reference |
|---|---|---|
| Manual Trigger Only | workflow_dispatch โ deliberate action required |
Change control |
| Minimal Permissions | contents: read, issues: write |
Least privilege |
๐ File: .github/workflows/copilot-setup-steps.yml
๐ฏ Purpose: Set up the development environment for GitHub Copilot coding agents
โฐ Trigger: Push/PR to copilot-setup-steps.yml file + manual dispatch
| Component | Version / Configuration |
|---|---|
| Node.js | 25 |
| EP MCP Server | european-parliament-mcp-server (global) |
| Playwright Browsers | Installed for E2E |
| Virtual Display | Xvfb (:99) |
| Control | Implementation | ISMS Reference |
|---|---|---|
| Broad Read Permissions | Multiple read scopes for agent access | Copilot agent requirement |
| Write Limited | Only pull-requests: write, issues: write |
Least privilege for agents |
| Token Management | COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN |
Credential management |
๐ File: .github/workflows/agentics-maintenance.yml
๐ฏ Purpose: Housekeeping for the agentic workflow fleet โ detect .md โ .lock.yml drift, probe MCP gateway health, prune stale analysis artifacts, verify GH_AW_VERSION: v0.71.4 is in effect.
โฐ Trigger: Scheduled (weekly) + manual dispatch
| Control | Implementation |
|---|---|
| Read-only probes | Health checks write no state to the repo |
| Drift detection | Compares gh aw compile --validate output against committed .lock.yml |
| PR on drift | Opens a PR via safe-outputs when lock drift is detected |
๐ File: .github/workflows/news-translate-reconciler.yml
๐ฏ Purpose: Sweep news/ for English articles that are missing translations in one or more of the 13 target languages (sv, da, no, fi, de, fr, es, nl, ar, he, ja, ko, zh) and enqueue backfill runs for news-translate.md.
โฐ Trigger: Scheduled (multiple times daily) + manual dispatch
flowchart LR
A[Scan news/*.html] --> B{English article exists<br/>without all 13 translations?}
B -- Yes --> C[Enqueue news-translate<br/>with article slug + date]
B -- No --> D[Log reconciled]
C --> E[news-translate produces<br/>missing languages]
classDef scan fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef action fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class A scan
class B decision
class C,E action
| Control | Implementation |
|---|---|
| Scoped dispatch | Only calls news-translate.md with a specific {slug,date} input โ no arbitrary workflow chaining |
| max-patch-size coordination | Translation runs use news-translate.md's top-level 10240 KB max-patch-size for fan-out |
| Idempotency | Skips slugs already at 14/14 language coverage |
The AI-First Quality Principle (.github/skills/ai-first-quality.md, non-negotiable) governs all agentic content generation. Workflow-level enforcement:
| Pass | Time Budget | Mandatory Outputs |
|---|---|---|
| Pass 1 (~60%) | First 60% of workflow timeout | Initial narrative draft; full MCP data fetch; first stakeholder perspective pass |
| Pass 2 (~40%) | Remaining 40% of workflow timeout | Read-back of entire draft; evidence cross-validation; gap filling; scenario elaboration |
| Workflow timeout | Minimum active time (no early exit) |
|---|---|
| 60-minute workflow | โฅ45 minutes actively engaged |
| 120-minute workflow (article-generator) | โฅ90 minutes actively engaged |
validate-analysis-completeness)Before PR creation, the agentic workflow MUST run:
node scripts/utils/validate-analysis-completeness.js --article-html="$(ls -t news/${TODAY}-${TYPE}*-en.html | head -1)"
which asserts:
[AI_ANALYSIS_REQUIRED] sentinel markers remaining.github/prompts/03-analysis-completeness-gate.mdscanHtmlForFallbackLeaks() returns empty โ no FALLBACK_TEMPLATE_PATTERNS in outputReference thresholds (analysis/methodologies/reference-quality-thresholds.json):
| Artifact | Min words | Breaking threshold |
|---|---|---|
intelligence/mcp-reliability-audit.md |
200 | 385 |
intelligence/reference-analysis-quality.md |
140 | 190 |
news-translate.md runs the validator against all English source articles before fan-out to the 13 target languages. A single failing English source blocks the entire translation run, preserving translation fidelity.
buildDefaultStakeholderPerspectives in src/templates/section-builders.ts emits AI_MARKER sentinels into the HTML template. Agents author the stakeholder/impact slots directly in rendered HTML โ the generator emits markup shells (analysis-stakeholder-perspectives / stakeholder-perspectives-grid) and the agent fills the semantic content. Agents MUST NOT write raw HTML for this section structure but MUST author the perspective text.
| Metric | Target | Current | Status |
|---|---|---|---|
| Test Success Rate | โฅ95% | 100% | โ Excellent |
| Test Execution Time | <10 min | ~3 min | โ Excellent |
| Release Frequency | As needed | Manual | โ On-demand |
| Mean Time to Deploy | <1 hour | ~15 min | โ Excellent |
| Failed Deployment Rate | <5% | 0% | โ Perfect |
| Metric | Target | Current | Status |
|---|---|---|---|
| Critical Vulnerabilities | 0 | 0 | โ Secure |
| High Vulnerabilities | 0 | 0 | โ Secure |
| Code Coverage | โฅ80% lines/functions/statements, โฅ75% branches | Enforced by vitest config | โ CI-gated |
| SHA-Pinned Actions | 100% | 100% | โ Complete |
| OpenSSF Score | โฅ8.0 | TBD | ๐ Monitoring |
EU Parliament Monitor implements industry best practices for securing CI/CD pipelines, with StepSecurity hardening for all workflows:
flowchart LR
subgraph "๐ก๏ธ Pipeline Security Hardening"
PH[Permissions Hardening] --> LAP[Least Access Principle]
PS[Pin SHA Versions] --> IDT[Immutable Dependencies]
AV[Action Verification] --> TS[Trusted Sources]
RH[Runner Hardening] --> AL[Audit Logging]
OT[OIDC Tokens] --> EF[Ephemeral Credentials]
end
subgraph "๐ Security Measures"
AS[Asset Security] --> AC[Asset Verification]
DS[Dependency Security] --> PD[Dependency Pinning]
BS[Build Security] --> BA[Build Attestations]
RS[Release Security] --> SBOM[SBOM Generation]
end
PH --> AS
PS --> DS
AV --> BS
RH --> RS
classDef practice fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef measures fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
class PH,PS,AV,RH,OT practice
class LAP,IDT,TS,AL,EF practice
class AS,DS,BS,RS measures
class AC,PD,BA,SBOM measures
The project's workflows collectively implement the following security measures (applied per workflow where applicable):
read-all or empty {} top-levelharden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 for audit logginganchore/sbom-actionactions/attest-build-provenance*.lock.yml pipelines) use explicit timeout-minutes to prevent resource exhaustion; remaining workflows rely on GitHub's default job timeouts and are monitored for anomaliesdeploy-s3 workflow uses AWS OIDC federation โ no long-lived secretsdeploy-s3 workflow uses harden-runner with egress-policy: blockEvery workflow declares explicit, minimal permissions following the principle of least privilege. Some workflows use top-level permissions: read-all with job-level write overrides where needed, while others define more restrictive explicit top-level scopes tailored to their tasks.
| Workflow | Top-Level | Job-Level Overrides | Secrets Used |
|---|---|---|---|
| codeql | contents: read |
analyze: security-events: write, packages: read, actions: read |
None |
| compile-agentic-workflows | contents: write, pull-requests: write, actions: write, issues: write |
โ | COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN |
| copilot-setup-steps | contents: read, actions: read, attestations: read, checks: read, issues: write, models: read, discussions: read, pages: read, pull-requests: write, security-events: read, statuses: read |
โ | COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN |
| dependency-review | contents: read |
โ | None |
| deploy-s3 | contents: read, id-token: write, actions: write |
โ | AWS OIDC role |
| e2e | contents: read |
e2e-tests: contents: read |
None |
| labeler | read-all |
labeler: contents: read, pull-requests: write, issues: read |
GITHUB_TOKEN |
| release | read-all |
prepare: contents: write; build: contents: read, id-token: write, attestations: write; release: contents: write, id-token: write |
GITHUB_TOKEN |
| reuse | contents: read |
โ | None |
| scorecards | read-all |
analysis: security-events: write, id-token: write, contents: read, actions: read, issues: read, pull-requests: read, checks: read |
None |
| setup-labels | contents: read, issues: write |
โ | GITHUB_TOKEN |
| test-and-report | read-all |
validation: contents: read, pull-requests: write; functional-tests: contents: read; performance: contents: read; security-check: contents: read, security-events: write; report: contents: read, pull-requests: write |
None |
| news-* (agentic ร9) | {} (empty) |
activation: contents: read; agent: contents: write, pull-requests: write, issues: write, models: read |
GITHUB_TOKEN |
graph TD
subgraph Layer1["๐ต Layer 1: Developer Workstation"]
PC[Pre-Commit Hooks<br/>gitleaks ยท eslint ยท prettier]
LS[Lint-Staged<br/>ESLint fix ยท Prettier ยท HTMLHint]
PC --> LS
end
subgraph Layer2["๐ข Layer 2: Source Control"]
BP[Branch Protection<br/>Required status checks]
CR[Code Review<br/>Required approvals]
BP --> CR
end
subgraph Layer3["๐ก Layer 3: CI Pipeline"]
HR[Harden Runner v2.15.1<br/>Egress policy: audit/block]
ST[SHA-Pinned Actions 100%<br/>Supply chain integrity]
HR --> ST
end
subgraph Layer4["๐ด Layer 4: Security Scanning"]
CQL[CodeQL SAST<br/>JS/TS + Actions analysis]
DR[Dependency Review<br/>CVE blocking on PR]
NA[npm audit<br/>CVE check]
CQL --> DR --> NA
end
subgraph Layer5["๐ฃ Layer 5: Build Integrity"]
SB[SBOM Generation<br/>CycloneDX / SPDX]
AT[Build Attestation<br/>Sigstore / SLSA L3]
SB --> AT
end
subgraph Layer6["โซ Layer 6: Deployment"]
S3[S3 Sync<br/>Cache-optimised headers]
CF[CloudFront Invalidation<br/>HTTPS-only CDN]
S3 --> CF
end
Layer1 --> Layer2 --> Layer3 --> Layer4 --> Layer5 --> Layer6
classDef layer1 fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
classDef layer2 fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef layer3 fill:#f1c40f,stroke:#f39c12,stroke-width:1.5px,color:black
classDef layer4 fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef layer5 fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef layer6 fill:#2c3e50,stroke:#1a252f,stroke-width:1.5px,color:white
class PC,LS layer1
class BP,CR layer2
class HR,ST layer3
class CQL,DR,NA layer4
class SB,AT layer5
class S3,CF layer6
The project employs two complementary pre-commit enforcement mechanisms: Husky (Node.js native) and pre-commit framework.
Configuration: .husky/pre-commit โ runs npx lint-staged
| File Pattern | Commands | Purpose |
|---|---|---|
scripts/**/*.js |
eslint --fix, prettier --write |
JS quality + formatting |
*.md |
prettier --write |
Documentation formatting |
*.html |
htmlhint |
HTML validation |
Configuration: .pre-commit-config.yaml
graph LR
A[git commit] --> B{Husky Hook Triggered}
B --> C[lint-staged]
C --> D[ESLint --fix JS]
C --> E[Prettier --write MD]
C --> F[HTMLHint HTML]
D --> G{All Pass?}
E --> G
F --> G
G -->|โ
Pass| H[Commit Proceeds]
G -->|โ Fail| I[Commit Blocked]
I --> J[Developer Fixes Issues]
J --> A
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef lint fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef pass fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef fail fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
class A trigger
class B,G decision
class C,D,E,F lint
class H pass
class I,J fail
| Hook | Version | Purpose | Security Value |
|---|---|---|---|
| gitleaks | v8.16.3 | Secret scanning | Prevent credential exposure |
| mirrors-eslint | v8.38.0 | JS linting | Code quality enforcement |
| end-of-file-fixer | pre-commit v4.4.0 | File termination | Consistency |
| trailing-whitespace | pre-commit v4.4.0 | Whitespace cleanup | Consistency |
Security Value: gitleaks scans for hardcoded secrets (API keys, tokens, passwords) before any commit reaches the remote repository, providing first-line credential leak prevention aligned with Cryptography Policy.
Supply-chain Levels for Software Artifacts (SLSA) Level 3 compliance is achieved through GitHub's native attestation infrastructure integrated into the release and SLSA provenance workflows.
| SLSA L3 Requirement | Implementation | Workflow |
|---|---|---|
| Source โ Version controlled | Git + GitHub branch protection | All |
| Source โ Verified history | Protected main branch |
All |
| Build โ Scripted build | npm ci + reproducible steps |
release.yml |
| Build โ Build service | GitHub Actions managed runners | All |
| Build โ Non-falsifiable provenance | GitHub Sigstore / OIDC keyless | release.yml |
| Build โ Isolated | GitHub-hosted Ubuntu runners | All |
| Provenance โ Available | .intoto.jsonl attached to release |
release.yml |
| Provenance โ Authenticated | OIDC id-token: write |
release.yml |
| Provenance โ Service generated | actions/attest-build-provenance |
release.yml |
| Provenance โ Non-falsifiable | Sigstore transparency log | release.yml |
graph TD
A[Developer: git tag vX.Y.Z] --> B[GitHub Actions: release.yml triggered]
B --> C[prepare job: run tests + generate docs]
C --> D[build job: npm ci - hermetic install]
D --> E[Create release-artifacts/euparliamentmonitor-vX.Y.Z.zip]
E --> F[anchore/sbom-action: SPDX JSON SBOM]
F --> G[actions/attest-build-provenance<br/>Subject: release zip file]
G --> H[GitHub Sigstore: OIDC token exchange]
H --> I[Sigstore Transparency Log Entry]
I --> J[.intoto.jsonl bundle saved]
J --> K[actions/attest-sbom<br/>Subject: release zip + SBOM path]
K --> L[GitHub Release: all artifacts attached]
L --> M[Verification: gh attestation verify --owner Hack23 file.zip]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef build fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef crypto fill:#f39c12,stroke:#e67e22,stroke-width:1.5px,color:black
classDef release fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class A trigger
class B,C,D,E build
class F,K security
class G,H,I,J crypto
class L,M release
End-users can verify artifact integrity using the GitHub CLI:
# Verify build provenance
gh attestation verify euparliamentmonitor-v1.0.0.zip --owner Hack23
# Verify SBOM attestation
gh attestation verify euparliamentmonitor-v1.0.0.spdx.json --owner Hack23
# Expected output: โ
Verification successful
# Attestation bundle verified with signer's certificate
ISMS Reference: Secure Development Policy ยง4.4 โ Supply Chain Security
Security scanning tools are integrated into the CI/CD pipeline with triggers as documented in the matrix below (e.g., push, pull request, schedule, pre-commit).
| Tool | Type | Triggers | Findings Location | Blocks Merge? |
|---|---|---|---|---|
| CodeQL | SAST | Push, PR, weekly Saturday | GitHub Security tab | Yes (via required check) |
| npm audit | SCA | Push, PR | Workflow logs | Yes (new โฅ moderate, allowlist exceptions) |
| Dependency Review | SCA | PR only | PR comments | Yes |
| ESLint | SAST Lint | Push, PR, pre-commit | Workflow logs | Yes |
| HTMLHint | Validation | Push, PR, pre-commit | Workflow logs | Warning |
| REUSE | Compliance | Push, PR, weekly Monday | Workflow logs | Yes |
| OpenSSF Scorecard | Posture | Push, weekly Tuesday | SARIF โ Security tab | Advisory |
| gitleaks | Secret Scan | Pre-commit | Terminal | Yes (pre-commit) |
graph LR
subgraph Triggers["โก Triggers"]
PR[Pull Request]
PS[Push to main]
SC[Schedule Weekly]
end
subgraph Scanning["๐ Security Scanning"]
CQL[CodeQL SAST<br/>JS/TS + Actions]
NA[npm audit<br/>CVE check]
DR[Dependency Review<br/>CVE block on PR]
RL[REUSE<br/>License compliance]
SC2[OpenSSF Scorecard<br/>Posture assessment]
end
subgraph Output["๐ Results"]
GH[GitHub Security<br/>Alerts Dashboard]
PRC[PR Comments<br/>Inline feedback]
SAR[SARIF Upload<br/>Code scanning tab]
WL[Workflow Logs<br/>Actions tab]
end
PR --> CQL & NA & DR & RL
PS --> CQL & NA & RL & SC2
CQL --> SAR
NA --> WL
DR --> PRC
RL --> WL
SC2 --> SAR
SAR --> GH
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef scanning fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef output fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
class PR,PS,SC trigger
class CQL,NA,DR,RL,SC2 scanning
class GH,PRC,SAR,WL output
Production deployment to AWS S3 + CloudFront is protected by multiple sequential security gates that must all pass before code reaches production.
graph TD
A[Developer: Push / PR] --> B{Branch Protection<br/>Rules}
B -->|Protected branch| C[Required Status Checks]
C --> D{CI Tests Pass?<br/>test-and-report.yml}
D -->|โ
Pass| E{CodeQL Scan Pass?<br/>codeql.yml}
D -->|โ Fail| BLOCK[๐ซ Merge Blocked]
E -->|โ
Pass| F{REUSE Compliance?<br/>reuse.yml}
E -->|โ Fail| BLOCK
F -->|โ
Pass| G{Code Review<br/>Approved?}
F -->|โ Fail| BLOCK
G -->|โ
Approved| H[Merge to main]
G -->|โ Pending| BLOCK
H --> I[Deploy to S3<br/>deploy-s3.yml triggered]
I --> J[Harden Runner<br/>egress: BLOCK mode]
J --> K[OIDC AWS Auth<br/>id-token: write]
K --> L[S3 Sync<br/>Cache-optimised]
L --> M[CloudFront Invalidation<br/>Cache flush]
M --> N[โ
Production Live<br/>hack23.com]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef pass fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef fail fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
classDef aws fill:#FF9900,stroke:#232F3E,stroke-width:1.5px,color:white
classDef security fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
class A trigger
class B,D,E,F,G decision
class C,H,N pass
class BLOCK fail
class I,J,K security
class L,M aws
| Control | Implementation | ISMS Reference |
|---|---|---|
| OIDC Federation | aws-actions/configure-aws-credentials with role ARN |
No long-lived secrets |
| Minimal IAM Role | GithubWorkFlowRole โ S3 + CloudFront only |
Least privilege |
| Egress Block Mode | Harden Runner blocks all non-allowlisted endpoints | Network security |
| mtime Preservation | Git commit times restored before sync | Change detection accuracy |
| Cache-Optimised Sync | Per-type cache headers (HTML: 1h, assets: 1y) | Performance + integrity |
| HTTPS Enforcement | CloudFront HTTPS-only distribution | Data in transit protection |
| TLS 1.3 | CloudFront + S3 expected to enforce TLS 1.3 (configured in AWS account) | Cryptography Policy |
All standard GitHub Actions workflows follow a single, consistent caching convention:
| Cache | Mechanism | Key Pattern | Expiry |
|---|---|---|---|
npm packages (~/.npm) |
setup-node built-in cache: 'npm' + cache-dependency-path: package-lock.json |
<runner-os>-node-<hash(package-lock.json)> |
Expires automatically when package-lock.json changes; GitHub evicts unused entries after 7 days |
Playwright browsers (~/.cache/ms-playwright) |
actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 |
<runner-os>-playwright-v2-<scope>-<hash(package-lock.json)> |
Key versioned (v2) โ increment the version prefix (e.g., v2 โ v3) to expire all existing Playwright caches and force re-download on next run |
actions/cache step for ~/.npm โ setup-node with cache: 'npm' already uses actions/cache internally. Adding a second explicit step creates two cache entries for the same data under different keys, wastes cache quota, and introduces key drift.actions/cache SHA pin (27d5ce7fโฆ v5.0.5) used for all non-npm caches. Every workflow that needs Playwright or another tool-specific cache MUST use this exact SHA to stay consistent and auditable.cache-dependency-path: package-lock.json is always set explicitly so the internal npm cache key is scoped to the exact lock-file hash (rather than a glob scan of all **/package-lock.json files).v2 prefix in Playwright cache keys ensures all caches created before this change are treated as stale and re-populated on next run.All external network installs are wrapped in retry loops to survive transient registry or mirror outages:
| Install type | Retry mechanism | Timeout |
|---|---|---|
npm ci |
3 attempts, 15 s back-off | timeout-minutes: 10 |
npx playwright install-deps (apt) |
3 attempts, 20 s back-off | timeout-minutes: 10 |
npx playwright install <browser> |
3 attempts, 20 s back-off | timeout-minutes: 20 |
apt-get install (copilot setup) |
3 attempts, 20 s back-off | timeout-minutes: 10 |
npm install -g <mcp-package> |
3 attempts, 15 s back-off via helper function | timeout-minutes: 15 |
for attempt in 1 2 3; do
if <install-command>; then
echo "โ
succeeded on attempt $attempt"
exit 0 # or break for inline steps
fi
echo "โ ๏ธ failed on attempt $attempt โ retrying in 15s"
sleep 15
done
echo "โ failed after 3 attempts"
exit 1
All install steps also set --prefer-offline for npm ci so that the warm npm cache is used in preference to the network on subsequent attempts.
| Workflow | npm cache | Playwright cache | Other caches |
|---|---|---|---|
test-and-report.yml |
setup-node built-in |
playwright-v2-chromium-* (functional-tests job) |
โ |
release.yml |
setup-node built-in |
playwright-v2-chromium-* (prepare job) |
โ |
e2e.yml |
setup-node built-in |
playwright-v2-all-* (full browser suite) |
โ |
knip.yml |
setup-node built-in |
โ | โ |
deploy-s3.yml |
setup-node built-in |
โ | โ |
compile-agentic-workflows.yml |
setup-node built-in |
โ | โ |
copilot-setup-steps.yml |
setup-node built-in |
โ | โ |
agentics-maintenance.yml (generated) |
โ | โ | activity-report-logs (custom key per run+repo) |
| Failure Type | Detection | Automated Response | Manual Action |
|---|---|---|---|
| Test failure | CI job exits non-zero | Workflow marked failed, merge blocked | Review logs, fix code, re-push |
| Security finding (CodeQL, new) | CodeQL analysis | PR comment + GitHub Security alert | Assess, fix or document false positive |
| Security finding (npm audit, new) | npm audit in test-and-report.yml |
Workflow failed, findings in logs only | Review audit output, update deps or add to allowlist per policy |
| Security finding (known / accepted) | Known GHSA in audit allowlist | Intelligent triage passes | Document in SECURITY.md and risk register |
| Deployment failure | S3 sync / CF invalidation error | Workflow failed, previous version still live | Check AWS CloudWatch, re-run |
| Attestation failure | Sigstore API / OIDC error | Release blocked | Retry workflow, check OIDC config |
| REUSE non-compliance | Missing SPDX header | PR blocked | Add SPDX-FileCopyrightText headers |
| Agentic workflow failure | Agent timeout or error | PR not created, workflow marked failed | Review agent logs, re-trigger manually |
graph TD
A[๐จ Production Incident Detected] --> B{Incident Type}
B -->|Content error| C[Re-run deploy-s3.yml<br/>from previous commit]
B -->|Security breach| D[Immediate CloudFront disable]
B -->|Dependency vuln| E[npm audit fix + re-deploy]
C --> F[git revert + push to main]
F --> G[Auto-deploy triggered]
D --> H[Revoke AWS role session]
H --> I[Investigate + patch]
I --> J[Re-enable CloudFront]
E --> K[PR with dep update]
K --> L[CI gates pass]
L --> M[Merge + auto-deploy]
G --> N[โ
Rollback Complete]
J --> N
M --> N
classDef alert fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef content fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
classDef security fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef dependency fill:#e67e22,stroke:#d35400,stroke-width:1.5px,color:white
classDef complete fill:#27ae60,stroke:#1e8449,stroke-width:2px,color:white
class A alert
class B decision
class C,F,G content
class D,H,I,J security
class E,K,L,M dependency
class N complete
| Scenario | RTO Target | Procedure |
|---|---|---|
| Broken deployment | < 15 minutes | Re-run deploy-s3.yml from last good commit |
| Content regression | < 30 minutes | git revert + auto-deploy pipeline |
| Dependency vulnerability | < 4 hours | npm audit fix + PR + deploy |
| Security incident | < 1 hour | CloudFront disable + incident response |
ISMS Reference: BCP Plan | Incident Response
Configuration: .github/dependabot.yml
Dependabot is configured with two package ecosystems, both scheduled on Monday to batch updates and reduce CI noise.
| Ecosystem | Directory | Schedule | PR Limit | Groups |
|---|---|---|---|---|
| npm | / |
Weekly, Mon 06:00 UTC | 10 | dev-deps (minor/patch), prod-deps (minor/patch) |
| github-actions | / |
Weekly, Mon 07:00 UTC | Unlimited | github-actions (minor/patch) |
graph LR
A[Dependabot Scan] --> B{Package Type?}
B -->|Development dep| C[Group: development-dependencies<br/>minor + patch updates]
B -->|Production dep| D[Group: production-dependencies<br/>minor + patch updates]
B -->|GitHub Action| E[Group: github-actions<br/>minor + patch updates]
C --> F[Single PR: all dev dep updates]
D --> G[Single PR: all prod dep updates]
E --> H[Single PR: all action SHA updates]
F --> I[CI gates validate]
G --> I
H --> I
I --> J{Pass?}
J -->|Yes| K[Auto-merge eligible]
J -->|No| L[Manual review required]
classDef scanner fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef group fill:#9b59b6,stroke:#8e44ad,stroke-width:1.5px,color:white
classDef pr fill:#e67e22,stroke:#d35400,stroke-width:1.5px,color:white
classDef pass fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef fail fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
class A scanner
class B,J decision
class C,D,E group
class F,G,H pr
class I,K pass
class L fail
| Type | Prefix | Example |
|---|---|---|
| npm dep update | build(deps): |
build(deps): bump eslint from 8.x to 9.x |
| npm dev dep | build(deps-dev): |
build(deps-dev): bump vitest from 2.x to 3.x |
| Actions update | build(deps): |
build(deps): bump actions/checkout from v4 to v5 |
Security Labels: All Dependabot PRs are labelled dependencies + javascript or github_actions for easy filtering.
All primary workflows expose real-time status badges in README.md and this document for instant visibility into pipeline health:
| Workflow | Badge | Target |
|---|---|---|
| Test & Report | Green always | |
| CodeQL | Green always | |
| E2E Tests | Green always | |
| REUSE | Green always | |
| OpenSSF Scorecard | โฅ 8.0/10 |
The following tools integrate with the GitHub Security Dashboard via SARIF or native mechanisms:
| Tool | Integration Type | Destination |
|---|---|---|
| CodeQL | SARIF via github/codeql-action/analyze |
GitHub Security Dashboard (code scanning alerts) |
| OpenSSF Scorecard | SARIF via github/codeql-action/upload-sarif |
GitHub Security Dashboard (code scanning alerts) |
| Dependabot | Native GitHub integration | GitHub Security Dashboard (Dependabot alerts) |
| Event | Alert Channel | Severity |
|---|---|---|
| Critical CVE found | GitHub Security Advisories | P1 โ Immediate |
| Workflow failure on main | GitHub email notification | P2 โ Same day |
| Scorecard score drop | Weekly scorecard badge | P3 โ Weekly review |
| Dependabot PR opened | GitHub PR notification | P4 โ Next Monday batch |
| ISMS Policy | Workflows Implementing Controls | Evidence |
|---|---|---|
| ๐ ๏ธ Secure Development Policy | All 24 workflows | This document |
| ๐ Information Security Policy | CodeQL, OpenSSF Scorecard | SECURITY_ARCHITECTURE.md |
| ๐ Access Control Policy | deploy-s3 (OIDC), release (minimal permissions) | Workflow files |
| ๐ Cryptography Policy | deploy-s3 (TLS), release (Sigstore/SLSA) | Attestations |
| ๐ Open Source Policy | REUSE compliance workflow | REUSE.toml |
| ๐ Vulnerability Management | CodeQL, npm audit, Dependency Review | GitHub Security tab, PR checks |
| ๐ Change Management | Branch protection, CI gates, PR reviews | Workflow gate enforcement |
| ๐จ Incident Response Plan | Rollback procedures, incident classification | ยงFailure Handling section |
| Policy Section | Implementation | Evidence |
|---|---|---|
| ยง3.2 Architecture Documentation | Documentation-as-code in release workflow | SECURITY_ARCHITECTURE.md |
| ยง3.3 Testing Requirements | 3026+ unit/integration tests, E2E tests, 82%+ coverage | Test & Report Workflow |
| ยง4.1 CI/CD Security | All workflows with security controls | This document |
| ยง4.3 Security Scanning | CodeQL, npm audit, Dependabot | CodeQL Workflow |
| ยง4.4 Supply Chain Security | SLSA L3, SBOM, Dependency Review, REUSE, npm provenance | Release Workflow |
| ยง10.1 CI/CD Workflow Excellence | 24 automated workflows, 100% SHA-pinned | This document |
| Framework | Version | Controls Implemented | Evidence Location |
|---|---|---|---|
| ISO 27001 | 2022 | A.8.25, A.8.26, A.8.27, A.8.28, A.12.1.4, A.12.6.1, A.14.2.1 | Workflow files + this document |
| NIST CSF | 2.0 | ID.SC (Supply Chain), DE.CM (Detection), PR.DS (Data Security) | SECURITY_ARCHITECTURE.md |
| CIS Controls | v8.1 | 2.2, 4.1, 7.1, 16.1, 16.5, 16.7, 16.12 | Scorecard |
| SLSA | L3 | Build provenance, hermetic build, non-falsifiable, authenticated | Attestations |
| OpenSSF | โ | SHA-pinned actions (100%), Harden Runner, branch protection | Scorecard Report |
| EU CRA | 2024 | SBOM generation, vulnerability disclosure, security updates | Release Workflow |
The 15 agentic news workflows collectively form a European Parliament Political Intelligence Operations Centre โ a systematic, automated pipeline that transforms raw parliamentary data into multi-language political intelligence articles published daily, weekly, monthly, quarterly, annually and across the full EP-term electoral cycle.
The following diagram shows the complete intelligence cycle from EP data collection through analysis to multi-language publication:
flowchart TD
subgraph Collection["๐ก COLLECTION<br/>(EP MCP Server v1.3.6+)"]
direction TB
C1["๐ณ๏ธ Votes &<br/>Adopted Texts"]
C2["๐ Legislative<br/>Procedures"]
C3["๐๏ธ Committee<br/>Documents"]
C4["๐ค Plenary<br/>Speeches"]
C5["โ Parliamentary<br/>Questions"]
C6["๐
Events &<br/>Meetings"]
C7["๐ค MEP Data &<br/>Declarations"]
end
subgraph Analysis["๐ฌ ANALYSIS<br/>(Political Intelligence Pipeline)"]
direction TB
A1["๐ท๏ธ Classification<br/>7-dimension taxonomy"]
A2["โ ๏ธ Risk Assessment<br/>5ร5 Likelihood ร Impact"]
A3["๐ญ Threat Landscape<br/>6 political dimensions"]
A4["๐ผ SWOT Analysis<br/>Evidence-based quadrants"]
A5["๐ Significance Scoring<br/>Publication priority"]
A6["๐ฅ Stakeholder Impact<br/>Multi-perspective"]
end
subgraph Production["๐ฐ PRODUCTION<br/>(9 Content Workflows)"]
direction TB
P1["โก Breaking News<br/>Every 6 hours"]
P2["๐ Daily Intelligence<br/>Motions + Propositions + Committees"]
P3["๐
Weekly Intelligence<br/>Week Ahead + Weekly Review"]
P4["๐ Monthly Intelligence<br/>Month Ahead + Monthly Review"]
P5["๐ฏ On-Demand<br/>Article Generator"]
end
subgraph Distribution["๐ DISTRIBUTION<br/>(14 Languages)"]
direction TB
D1["๐ฌ๐ง English<br/>(source)"]
D2["๐ธ๐ช๐ฉ๐ฐ๐ณ๐ด๐ซ๐ฎ<br/>Nordic Languages"]
D3["๐ฉ๐ช๐ซ๐ท๐ช๐ธ๐ณ๐ฑ<br/>Western European"]
D4["๐ธ๐ฆ๐ฎ๐ฑ๐ฏ๐ต๐ฐ๐ท๐จ๐ณ<br/>Global Languages"]
end
Collection --> Analysis --> Production --> D1
D1 --> |"news-translate<br/>workflow"| D2 & D3 & D4
style Collection fill:#1565C0,stroke:#0D47A1,color:#FFFFFF
style Analysis fill:#6A1B9A,stroke:#4A148C,color:#FFFFFF
style Production fill:#2E7D32,stroke:#1B5E20,color:#FFFFFF
style Distribution fill:#E65100,stroke:#BF360C,color:#FFFFFF
The political intelligence pipeline monitors six threat landscape dimensions across all parliamentary activity:
mindmap
root((๐ญ Political<br/>Threat Landscape))
๐ Coalition Shifts
Grand coalition stability
Cross-party alliance formation
Defection patterns
Group cohesion metrics
๐ Transparency Deficit
Access-to-information gaps
Lobbying disclosure failures
Declaration compliance
Procedural opacity
โช Policy Reversal
Legislative rollback risk
Position contradiction
Commitment abandonment
Implementation failure
๐๏ธ Institutional Pressure
Inter-institutional friction
Council-Parliament disputes
Commission accountability
Rule-of-law mechanisms
๐ง Legislative Obstruction
Procedure stalling
Amendment flooding
Committee bottlenecks
Trilogue deadlocks
๐ณ๏ธ Democratic Erosion
Participation decline
Representation gaps
Accountability weakening
Mandate legitimacy
The 15 agentic workflows follow a carefully orchestrated schedule to ensure continuous intelligence coverage of the European Parliament across daily / weekly / monthly / quarterly / annual / term-scoped horizons.
Note: The Gantt chart below uses sample dates (week of 2026-01-05) to illustrate the recurring weekly cadence. Mermaid's gantt format requires concrete dates; the actual schedule repeats every week.
gantt
title Weekly Agentic Workflow Cadence UTC โ Sample Week
dateFormat YYYY-MM-DD
axisFormat %a
section Daily Mon-Fri
Committee Reports 04h00 UTC :active, d1, 2026-01-05, 1d
Propositions 05h00 UTC :active, d2, 2026-01-05, 1d
Motions 06h00 UTC :active, d3, 2026-01-05, 1d
Breaking News 4x daily :crit, d4, 2026-01-05, 1d
section Weekly
Week Ahead Fri 07h00 UTC :d5, 2026-01-09, 1d
section Weekend
Weekly Review Sat 09h00 UTC :d6, 2026-01-10, 1d
section Translation
Translate Weekdays 3x daily :d7, 2026-01-05, 5d
Translate Sat 15h00 UTC :d8, 2026-01-10, 1d
section Monthly
Month Ahead 1st 08h00 UTC :d9, 2026-01-01, 1d
Monthly Review 28th 10h00 UTC :d10, 2026-01-28, 1d
flowchart LR
subgraph "๐๏ธ European Parliament"
EP["EP Open Data Portal"]
end
subgraph "๐ MCP Layer"
MCP["EP MCP Server<br/>v1.3.6+<br/>(180s timeout;<br/>60+ tools, sliding + fixed-window feeds)"]
end
subgraph "๐ค Agent Layer"
Agent["GitHub Copilot<br/>claude-sonnet-4.6"]
Analyze["Analysis Pipeline<br/>11 methodology assets<br/>39 templates"]
end
subgraph "๐ฐ Output Layer"
EN["๐ฌ๐ง English Article"]
Translate["Translation Agent"]
Multi["๐ 13 Additional<br/>Languages"]
end
subgraph "๐ Deployment"
PR["Pull Request"]
Pages["GitHub Pages"]
S3["AWS S3 CDN"]
end
EP --> MCP --> Agent --> Analyze --> EN --> PR
EN --> Translate --> Multi --> PR
PR --> |"merge"| Pages & S3
style EP fill:#003399,stroke:#002266,color:#FFFFFF
style MCP fill:#6A1B9A,stroke:#4A148C,color:#FFFFFF
style Agent fill:#1565C0,stroke:#0D47A1,color:#FFFFFF
style Analyze fill:#C62828,stroke:#B71C1C,color:#FFFFFF
style EN fill:#2E7D32,stroke:#1B5E20,color:#FFFFFF
style Translate fill:#E65100,stroke:#BF360C,color:#FFFFFF
style Multi fill:#F57F17,stroke:#F9A825,color:#000000
style PR fill:#37474F,stroke:#263238,color:#FFFFFF
style Pages fill:#00695C,stroke:#004D40,color:#FFFFFF
style S3 fill:#FF6F00,stroke:#E65100,color:#FFFFFF
Each content workflow deposits analysis artifacts in an isolated directory. Cross-article artifacts (such as ai-daily-synthesis.md) live at the date root analysis/daily/{date}/, while per-workflow artifacts are scoped under analysis/daily/{date}/{article-type}/:
analysis/daily/2026-03-31/
โโโ ai-daily-synthesis.md โ Cross-article synthesis (date root)
โโโ breaking/ โ news-breaking workflow
โ โโโ manifest.json
โ โโโ classification/
โ โโโ threat-assessment/
โ โโโ risk-scoring/
โ โโโ data/ โ EP MCP data for this workflow
โโโ committee-reports/ โ news-committee-reports workflow
โ โโโ manifest.json
โ โโโ classification/
โ โโโ data/
โโโ motions/ โ news-motions workflow
โ โโโ manifest.json
โ โโโ data/
โโโ propositions/ โ news-propositions workflow
โ โโโ manifest.json
โ โโโ data/
โโโ week-ahead/ โ news-week-ahead workflow (Fridays)
โโโ manifest.json
โโโ data/
๐จ Isolation Rule: Each workflow writes ONLY to its own
{article-type-slug}/subdirectory. Cross-workflow overwrites are prohibited. Theai-*.mdsynthesis files at the date root aggregate across all workflows.
The agentic news workflows share a common prompt library under .github/prompts/. Each file maps to a specific pipeline stage and is imported by the workflow agent at runtime:
| # | File | Pipeline Stage | Purpose |
|---|---|---|---|
| 0 | 00-scope-and-ground-rules.md |
All stages | Foundational rules, shell-safety constraints, banned patterns, time budgets |
| 1 | 01-data-collection.md |
Stage A | MCP tool invocation patterns, feed selection, data-window logic |
| 2 | 02-analysis-protocol.md |
Stage B | 10-step AI analysis protocol (Rules 1โ22), 2-pass mandatory |
| 3 | 03-analysis-completeness-gate.md |
Stage C | Completeness validator invocation, threshold enforcement |
| 4 | 04-article-generation.md |
Stage D | Artifact-to-article section map, Read-Before-Write rule |
| 5 | 05-analysis-to-article-contract.md |
Stage D | Data contract between analysis and render |
| 6 | 06-pr-and-safe-outputs.md |
Stage E | Single PR semantics, timing constraints, banned alternatives |
| 7 | 07-mcp-reference.md |
Stage A | EP MCP Server tool reference (60+ tools), IMF/World Bank guidance |
| 8 | 08-infrastructure.md |
All stages | Shell-safety long-form rules, forbidden expansion patterns |
| 9 | 09-troubleshooting.md |
All stages | Common failure modes, workarounds, timeout handling |
| 10 | 10-horizon-stage-helpers.md |
Stage B | Long-horizon-specific artifact requirements |
| 11 | 11-forward-projection.md |
Stage B | Forward-projection methodology and scenario authoring |
| 12 | 12-electoral-cycle.md |
Stage B | Electoral overlay invariants, cycle-position drivers |
npm run lint:prompts)scripts/lint-prompts.js validates every .md file in .github/prompts/ and all news-*.md workflows against banned patterns:
| Banned Pattern | Risk if Present |
|---|---|
checkpoint pr |
Partial PRs break the single-PR invariant |
keep-alive |
Idle heartbeats waste budget without output |
heartbeat |
Same as keep-alive |
progressive safe output |
Partial patches violate snapshot semantics |
push_repo_memory |
Unaudited state persistence |
The lint is wired into compile-agentic-workflows.yml and fails CI on any match. news-translate.md is exempted from the multi-call check (legitimate multi-call flush for 14-language fan-out).
All agentic workflows execute inside a sandboxed Docker container with network access restricted by a Squid proxy (AWF Firewall). Only explicitly allowlisted domains are reachable:
| Allowed Domain | Purpose |
|---|---|
data.europarl.europa.eu |
EP Open Data Portal (MCP Server backend) |
api.github.com |
GitHub API (PR creation, file operations) |
github.com |
Git operations |
registry.npmjs.org |
npm package resolution |
sdmxcentral.imf.org |
IMF SDMX API (economic data) |
api.worldbank.org |
World Bank Open Data API |
All other outbound network traffic is blocked by the Squid proxy. This prevents data exfiltration and restricts the agent's attack surface to known-good endpoints.
The 15 agentic news workflows produce political intelligence using a structured framework of 22 analysis methodologies and 60 analysis artifact templates. This section documents the complete political intelligence methodology stack.
analysis/methodologies/)The following 22 methodology files govern how political intelligence is authored:
| # | Methodology File | Domain | Key Capabilities |
|---|---|---|---|
| 1 | ai-driven-analysis-guide.md |
Core protocol | 10-step analysis protocol, Rules 1โ22, Pass-2 mandatory improvement cycle |
| 2 | osint-tradecraft-standards.md |
Tradecraft | Admiralty Code (A1โF6), WEP confidence bands, source grading, โฅ10 SATs/run |
| 3 | political-threat-framework.md |
Threat analysis | 6-dimension political threat landscape (coalition shifts, transparency deficit, policy reversal, institutional pressure, legislative obstruction, democratic erosion) |
| 4 | political-risk-methodology.md |
Risk assessment | 5ร5 likelihood ร impact matrix, residual risk, risk velocity |
| 5 | political-swot-framework.md |
Strategic | Evidence-based SWOT/TOWS, quantitative scoring, cross-domain linkage |
| 6 | political-classification-guide.md |
Classification | 7-dimension political alignment taxonomy, significance scoring |
| 7 | electoral-cycle-methodology.md |
Electoral | Cycle-position drivers, volatility forecast, turnout modelling |
| 8 | electoral-domain-methodology.md |
Electoral | Domain-specific electoral analysis (seats, mandates, coalitions) |
| 9 | forward-projection-methodology.md |
Forecasting | Multi-scenario modelling, probability bands, time-horizon calibration |
| 10 | synthesis-methodology.md |
Synthesis | Multi-source intelligence fusion, cross-artifact correlation |
| 11 | strategic-extensions-methodology.md |
Long-horizon | Quarter/year/term-scoped strategic analysis extensions |
| 12 | per-artifact-methodologies.md |
Construction rules | 34 per-artifact sections โ construction rules + quality signals for each template |
| 13 | analytical-supplementary-methodology.md |
Supplementary | Cross-session intelligence, devil's advocate, wildcards |
| 14 | per-document-methodology.md |
Document analysis | EP document deep-analysis framework (5-point structured analysis) |
| 15 | structural-metadata-methodology.md |
Metadata | Manifest structure, artifact cataloging, cross-reference mapping |
| 16 | imf-indicator-mapping.md |
Economic | IMF WEO/FM/IFS/BOP/ER/PCPS indicator โ article-section mapping |
| 17 | worldbank-indicator-mapping.md |
Economic | World Bank WDI social/health/education/governance indicators |
| 18 | political-style-guide.md |
Style | Economist-quality editorial standards, prose requirements |
| 19 | political-style-guide.json |
Style (machine) | Machine-readable style rules for automated validation |
| 20 | artifact-catalog.md |
Catalogue | Master map: artifact โ methodology + template + depth floor + Mermaid type |
| 21 | reference-quality-thresholds.json |
Quality floors | Per-artifact line-count floors enforced by Stage-C validator (v1.4.0) |
| 22 | README.md |
Index | Methodology library entry point |
analysis/templates/)The following 60 templates are used by Stage-B to produce structured intelligence artifacts. They are grouped by analytical domain:
| Template | Purpose | Key Outputs |
|---|---|---|
coalition-dynamics.md |
Coalition formation/dissolution analysis | Alliance mapping, defection patterns, cohesion metrics |
coalition-mathematics.md |
Quantitative coalition modelling | Seat arithmetic, blocking minorities, qualified majority paths |
political-capital-risk.md |
Political capital expenditure/depletion | Leadership position strength, mandate utilisation |
seat-projection.md |
Electoral seat projection modelling | Group size forecasts, majority thresholds |
voter-segmentation.md |
Voter base analysis | Demographic segments, issue salience |
voting-patterns.md |
Roll-call vote analysis | Cross-party alliances, abstention clusters, margin analysis |
| Template | Purpose | Key Outputs |
|---|---|---|
threat-analysis.md |
Structured threat identification | Threat actors, capabilities, intent |
threat-model.md |
STRIDE-based political threat modelling | Attack trees, mitigation mapping |
political-threat-landscape.md |
6-dimension threat landscape scan | Dimension severity scores, trend vectors |
risk-assessment.md |
Likelihood ร Impact risk scoring | Risk register, residual risk |
risk-matrix.md |
5ร5 risk matrix visualisation | Heat map, priority ranking |
actor-threat-profiles.md |
Per-actor threat profiles | Capability, intent, opportunity scores |
| Template | Purpose | Key Outputs |
|---|---|---|
swot-analysis.md |
Evidence-based SWOT quadrants | โฅ80 words/item, cross-domain linkage |
quantitative-swot.md |
Scored SWOT with numeric weighting | Weighted priority scores, TOWS strategies |
pestle-analysis.md |
Political-Economic-Social-Tech-Legal-Environmental | 6-dimension macro context |
forces-analysis.md |
Porter's 5 Forces adapted for politics | Competitive dynamics, barrier analysis |
scenario-forecast.md |
Multi-scenario probability modelling | 2โ4 named scenarios with WEP bands |
wildcards-blackswans.md |
Low-probability / high-impact events | Early warning signals, contingency options |
| Template | Purpose | Key Outputs |
|---|---|---|
intelligence-assessment.md |
ICD-203-style structured assessment | Key judgements, confidence levels, alternatives |
devils-advocate-analysis.md |
Challenge function for dominant hypothesis | Counter-arguments, blind-spot identification |
significance-classification.md |
Publication priority classification | High/Medium/Low + justification |
significance-scoring.md |
Multi-factor significance score | Novelty, scope, impact, urgency composite |
cross-session-intelligence.md |
Cross-run intelligence continuity | Trend tracking, hypothesis evolution |
synthesis-summary.md |
Multi-source intelligence synthesis | BLUF, evidence base, confidence assessment |
| Template | Purpose | Key Outputs |
|---|---|---|
legislative-pipeline-forecast.md |
Procedure stage tracking & timeline | Passage probability, next steps, blockers |
legislative-velocity-risk.md |
Legislative pace risk assessment | Acceleration/deceleration signals, backlog risk |
legislative-disruption.md |
Amendment flooding/obstruction detection | Disruption indicators, obstruction tactics |
mandate-fulfilment-scorecard.md |
Political programme delivery tracking | Promise vs. delivery, completion percentage |
implementation-feasibility.md |
Legislative implementation assessment | Transposition complexity, compliance burden |
parliamentary-calendar-projection.md |
Session calendar forward-projection | Sitting weeks, recess periods, crunch points |
| Template | Purpose | Key Outputs |
|---|---|---|
economic-context.md |
IMF/World Bank economic context | GDP, inflation, employment, fiscal indicators |
historical-baseline.md |
Historical norm establishment | Baseline metrics for deviation detection |
historical-parallels.md |
Precedent-based reasoning | Analogous situations, outcomes, lessons |
comparative-international.md |
Cross-jurisdiction comparison | EU vs. national parliament comparisons |
presidency-trio-context.md |
Council Presidency trio analysis | Priority alignment, legislative agenda |
commission-wp-alignment.md |
Commission Work Programme tracking | CWP delivery, legislative pipeline alignment |
term-arc.md |
EP term trajectory analysis | Term phase, momentum indicators |
| Template | Purpose | Key Outputs |
|---|---|---|
forward-indicators.md |
Leading indicator identification | Early warning signals, predictive metrics |
forward-projection.md |
Structured scenario projection | Time-horizon-calibrated WEP probability bands |
impact-matrix.md |
Multi-stakeholder impact assessment | Impact scores by stakeholder ร dimension |
consequence-trees.md |
Cascading consequence modelling | 2nd/3rd-order effects, feedback loops |
per-file-political-intelligence.md |
Per-document intelligence extraction | Document-level political significance |
| Template | Purpose | Key Outputs |
|---|---|---|
media-framing-analysis.md |
Media narrative frame identification | Dominant frames, counter-narratives |
stakeholder-impact.md |
Stakeholder impact assessment (โฅ150 words/perspective) | Multi-perspective analysis, winners/losers |
stakeholder-map.md |
Stakeholder power/interest mapping | Influence quadrant, alliance networks |
actor-mapping.md |
Political actor identification & classification | Actor profiles, motivations, capabilities |
| Template | Purpose | Key Outputs |
|---|---|---|
methodology-reflection.md |
Analysis quality self-assessment (Step 10.5) | SAT count (โฅ10), WEP coverage, improvement notes |
workflow-audit.md |
Workflow execution audit trail | Stage timings, tool calls, data coverage |
mcp-reliability-audit.md |
MCP Server reliability assessment | Tool success rates, latency, data freshness |
cross-reference-map.md |
Inter-artifact cross-reference network | Artifact dependencies, citation graph |
cross-run-diff.md |
Delta analysis between consecutive runs | Changed assessments, new signals |
data-download-manifest.md |
MCP data download record | Tools invoked, data volumes, timestamps |
reference-analysis-quality.md |
Quality benchmark comparison | Per-artifact quality scores vs. reference |
imf-vintage-audit.md |
IMF data vintage verification | Dataset recency, WEO edition, vintage dates |
session-baseline.md |
Session initial state capture | Starting conditions, prior-run context |
political-classification.md |
7-dimension political classification output | Alignment scores, taxonomy placement |
| Template | Purpose | Key Outputs |
|---|---|---|
executive-brief.md |
BLUF executive summary | Key judgements, confidence, recommendations |
deep-analysis.md |
Extended deep-analysis section | Full analytical depth, evidence chains |
intelligence-assessment.md |
ICD-203 formatted assessment | Structured intelligence product |
analysis-index.md |
Run-level artifact index | Table of contents for all run outputs |
reference-quality-thresholds.json v1.4.0)The Stage-C completeness validator (scripts/validate-analysis-completeness.js) enforces minimum line counts per artifact type:
| Category | Floor Range | Enforcement |
|---|---|---|
| Executive brief | 80โ120 lines | RED (blocking) โ PR creation blocked |
| Intelligence artifacts | 40โ100 lines | RED (blocking) |
| Risk scoring artifacts | 35โ80 lines | RED (blocking) |
| Classification artifacts | 30โ60 lines | RED (blocking) |
| Data manifests | 20โ40 lines | RED (blocking) |
DataMode reductions (when EP MCP data availability is constrained):
full (default): 100% of configured floorsdegraded-imf / degraded-voting: 85% of floorstitle-only: 75% of floorsminimal: 65% of floorsIn addition to line floors, the following tradecraft signals are always RED (blocking) regardless of --strict mode:
| Signal | Requirement | Artifacts Affected |
|---|---|---|
| WEP Band | Every headline judgement must carry a WEP (Words of Estimative Probability) confidence band + time horizon | 12 artifacts (executive-brief, scenario-forecast, forward-projection, threat-model, etc.) |
| Admiralty Grade | Every external source must carry an Admiralty Code grade (A1โF6) | 13 artifacts (intelligence assessments, comparatives, historical parallels) |
| โฅ10 SATs per run | At least 10 Structured Analytic Techniques applied and documented in methodology-reflection.md |
methodology-reflection.md ยง12 |
| Mermaid diagrams | Required structural diagrams present | Per-artifact requirements in artifact-catalog.md |
| Required sections | Template-mandated sections present | All templates with ## Required Sections headers |
The intelligence assessments follow the US Intelligence Community Directive 203 (ICD-203) confidence framework adapted for political intelligence:
| WEP Band | Probability Range | Usage |
|---|---|---|
| Almost certain | 93โ99% | Reserved for near-term procedural certainties |
| Very likely | 80โ92% | Strong evidence, limited alternatives |
| Likely | 63โ79% | Preponderance of evidence supports |
| Roughly even | 40โ62% | Evidence supports multiple outcomes equally |
| Unlikely | 20โ39% | Limited evidence against dominant view |
| Very unlikely | 5โ19% | Minimal evidence, contrarian scenarios |
| Remote | 1โ4% | Black swan / wildcard territory |
| Reliability | Credibility | Combined Grade |
|---|---|---|
| A Completely reliable | 1 Confirmed | A1 (highest) |
| B Usually reliable | 2 Probably true | B2 |
| C Fairly reliable | 3 Possibly true | C3 |
| D Not usually reliable | 4 Doubtful | D4 |
| E Unreliable | 5 Improbable | E5 |
| F Cannot be judged | 6 Cannot be judged | F6 (lowest) |
EP Official Journal and adopted texts are rated A1; MCP feed data is rated B2; press reports are rated C3 unless corroborated.
See FUTURE_WORKFLOWS.md for:
| Document | Focus | Link |
|---|---|---|
| ๐ Security Architecture | Current security implementation | SECURITY_ARCHITECTURE.md |
| ๐ Security Flowcharts | Process flows with security controls | FLOWCHART.md |
| ๐ Data Model | Data structures and flows | DATA_MODEL.md |
| ๐๏ธ Architecture | System structure (ยงAnalysis Framework) | ARCHITECTURE.md |
| ๐ Future Workflows | Planned enhancements | FUTURE_WORKFLOWS.md |
| ๐ Release Process | Release procedures | docs/RELEASE_PROCESS.md |
| ๐ก๏ธ ISMS Policy | Security policy framework | Hack23 ISMS-PUBLIC |
| ๐ฆ Dependabot Config | Automated dependency updates | .github/dependabot.yml |
| ๐ฌ Analysis Methodologies | 22 intelligence methodologies | analysis/methodologies/ |
| ๐ Analysis Templates | 60 artifact templates | analysis/templates/ |
| ๐ Prompt Library | 13-file prompt architecture | .github/prompts/ |
๐ Questions? Contact: Security Team
๐ Security Issues? See SECURITY.md for vulnerability disclosure
Last updated: 2026-05-06 by Documentation Architect / Security Architect (EU Parliament Monitor v0.8.59)