WORKFLOWS.md
June 13, 2026 ยท View on GitHub
๐ Riksdagsmonitor โ CI/CD Workflows
๐ง DevSecOps Pipeline and Automation Documentation
๐ฏ Multi-Stage Quality Gates for Security, Quality, and Reliability
๐ Document Owner: CEO | ๐ Version: 7.6 | ๐ Last Updated: 2026-05-28 (UTC) ๐ Review Cycle: Quarterly | โฐ Next Review: 2026-08-05 ๐ข Owner: Hack23 AB (Org.nr 5595347807) | ๐ท๏ธ Classification: Public
๐ Workflow Status Badges
CI/CD & Security
Testing & Quality
Documentation & Release
๐ฏ Purpose & Scope
This document provides comprehensive documentation of the CI/CD workflows implemented in the Riksdagsmonitor project, demonstrating alignment with Hack23 ISMS Secure Development Policy ยง10.1 "CI/CD Workflow & Automation Excellence". It serves as evidence of automated security operations, pipeline transparency, and continuous security validation.
Compliance Objectives:
- ISO 27001 (A.12.1): Change management documentation and controls
- NIST CSF (DE.CM): Continuous monitoring and detection evidence
- CIS Controls (17.1): Implement and manage automated secure application deployments
- Transparency: Public demonstration of security automation and quality gates
The project has been migrated from JavaScript to TypeScript (31 modules in src/browser/) with all workflows updated accordingly. TypeScript compilation is handled by Vite (esbuild) for browser bundles and Node 26's native type-stripping for scripts.
Total Workflow Files: 54 (26 standard YAML + 14 agentic .md sources + 14 compiled .lock.yml). Each agentic workflow consists of a source .md file and its compiled .lock.yml counterpart, yielding 40 distinct workflows (26 standard + 14 agentic).
Security Compliance: 100% (all actions SHA-pinned, harden-runner enabled)
๐ ISMS Policy Alignment
Riksdagsmonitor'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), quality gates, coverage thresholds |
| ๐ Change Management | Automated testing gates, security scanning, PR review requirements |
| ๐ Vulnerability Management | Dependabot, CodeQL, OpenSSF Scorecard, security advisories |
| ๐ Open Source Policy | SLSA attestations, SBOM generation, license compliance |
| ๐ Information Security Policy | Security-hardened runners, SHA-pinned actions, least privilege permissions |
| ๐ Network Security Policy | Egress auditing via harden-runner, HTTPS-only endpoints |
| ๐ Access Control Policy | Least privilege workflow permissions, OIDC token usage |
| ๐ Cryptography Policy | TLS 1.3 enforcement, SRI for CDN assets, SLSA provenance |
๐ Related Architecture Documentation
| Document | Focus | Description | Documentation Link |
|---|---|---|---|
| Architecture | ๐๏ธ Architecture | C4 model showing current system structure | View Source |
| Future Architecture | ๐๏ธ Architecture | Architectural evolution roadmap (2026โ2037) | View Source |
| Security Architecture | ๐ก๏ธ Security | Defense-in-depth security controls | View Source |
| Threat Model | ๐ก๏ธ Security | STRIDE threat analysis and risk assessment | View Source |
| Data Model | ๐ Data | Data structures and relationships | View Source |
| Flowcharts | ๐ Process | Business process and data flows | View Source |
| State Diagrams | ๐ Behavior | System state transitions and lifecycles | View Source |
| Mindmaps | ๐ง Concept | System conceptual relationships | View Source |
| SWOT Analysis | ๐ผ Business | Strategic assessment | View Source |
| Future Workflows | ๐ง DevOps | Enhanced CI/CD vision (2026โ2037) | View Source |
| Future Security Architecture | ๐ก๏ธ Security | Security roadmap | View Source |
| CRA Assessment | ๐ก๏ธ Compliance | EU Cyber Resilience Act conformity | View Source |
| End-of-Life Strategy | ๐ Lifecycle | Maintenance and EOL planning | View Source |
๐๏ธ Pipeline Architecture
The Riksdagsmonitor project implements a comprehensive DevSecOps CI/CD pipeline with multi-stage quality gates:
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[Dual Deploy]
classDef trigger fill:#bbdefb,stroke:#1565c0,stroke-width:2px,color:black
classDef build fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px,color:black
classDef security fill:#ffccbc,stroke:#bf360c,stroke-width:2px,color:black
classDef quality fill:#fff9c4,stroke:#f57f17,stroke-width:2px,color:black
classDef attestation fill:#d1c4e9,stroke:#4a148c,stroke-width:2px,color:black
classDef deploy fill:#a5d6a7,stroke:#1b5e20,stroke-width:2px,color:black
class A trigger
class B build
class C,D security
class E quality
class F security
class G,H attestation
class I,J deploy
Pipeline Stages Summary
| Stage | Tool/Service | Trigger | Quality Gate | Duration |
|---|---|---|---|---|
| ๐๏ธ Build & Test | Vite, Vitest, Cypress | Push/PR | Tests pass, coverage thresholds enforced at the Hack23 Secure Development Policy floor (statements โฅ80 % / branches โฅ70 % / functions โฅ70 % / lines โฅ80 %; see vitest.config.js and TESTING.md for measured baseline) | ~3.4s build, ~63s test |
| ๐ฆ SCA | Dependabot, Dependency Review | Daily / PR | No critical vulnerabilities | ~2 min |
| ๐ CodeQL | GitHub CodeQL | PR, Push, Weekly | No critical/high issues | ~10 min |
| โ Quality Gate | ESLint, HTMLHint, linkinator | Every commit | Zero errors, valid HTML | ~3 min |
| ๐ Security Gate | harden-runner (enforced), Scorecard (advisory) | Every commit | Zero critical vulnerabilities in enforced checks; Scorecard advisory only | Auto |
| ๐ SBOM | Release attestation | Release | Complete SBOM generated | ~2 min |
| ๐ Attestations | GitHub Attestations | Release | SLSA provenance created | ~2 min |
| ๐ Dual Deploy | AWS S3/CloudFront + GitHub Pages | Release / Push | Successful build artifact | ~3 min |
Technology Stack
| Component | Version | Purpose |
|---|---|---|
| GitHub Actions Runner | ubuntu-26.04 | CI/CD execution environment |
| Node.js | 26 | Runtime (native TypeScript strip-types) |
| TypeScript | 6.0.3 | Type system |
| Vite | 8.0.14 | Build toolchain (esbuild) |
| Vitest | 4.1.7 | Unit testing (7,500+ tests) |
| Cypress | 15.16.0 | E2E testing (optional dependency) |
| TypeDoc | 0.28.18 | API documentation |
| ESLint | 10.x | Linting (flat config) |
๐ Agentic Workflow Daily Schedule
The agentic news workflows run on a precisely orchestrated daily schedule (all times UTC):
flowchart TD
subgraph Morning["๐
Morning Analysis"]
A["CIA Stats Update<br/>02:00 ยท 60 min"]
B["Committee Reports<br/>04:00 ยท 90 min"]
C["Government Propositions<br/>05:00 ยท 90 min"]
D["Opposition Motions<br/>06:00 ยท 90 min"]
E["Interpellation Debates<br/>07:00 ยท 90 min"]
end
subgraph Midday["๐ฐ Midday Monitoring"]
F["Realtime Monitor AM<br/>10:00 ยท 120 min"]
G["Translation Batch AM<br/>11:00 ยท 90 min"]
end
subgraph Evening["๐ Afternoon / Evening"]
H["Realtime Monitor PM<br/>14:00 ยท 120 min"]
I["Translation Batch PM<br/>17:00 ยท 90 min"]
J["Evening Analysis<br/>18:00 ยท 120 min"]
end
A --> B --> C --> D --> E --> F --> G --> H --> I --> J
Weekend Schedule Variations
| Day | Active Workflows | Schedule Difference |
|---|---|---|
| Saturday | Weekly Review (09:00) ยท Realtime Monitor (12:00) ยท Evening/Weekly Wrap-up (16:00) ยท Translation (14:00) | Reduced frequency; weekly synthesis |
| Sunday | Realtime Monitor (12:00) ยท Translation (14:00) | Minimal coverage |
| 1st of Month | Month Ahead (08:00) ยท Quarter Ahead (09:00) | Monthly + quarterly strategic outlook |
| 15th of Month | Quarter Ahead (09:00) | Mid-month quarterly refresh |
| 28th of Month | Monthly Review (10:00) | Monthly retrospective |
| Friday | Week Ahead (07:00) | Weekly prospective outlook |
| 5 Jan / 5 Jul | Year Ahead (09:00) | Semi-annual strategic outlook anchored in IMF WEO vintage |
| 13 Mar / 13 Sep | Election Cycle (dispatch-only) | Delivered: semi-annual election-cycle deep intelligence (cron declared but disabled) |
๐ Workflow Overview
The Riksdagsmonitor project uses 54 workflow files (26 standard .yml + 14 agentic .lock.yml + 14 agentic .md sources) organized into 5 functional categories:
graph TB
subgraph "๐ Security & Compliance"
SEC1["๐ก๏ธ CodeQL<br/><i>SAST scanning</i>"]
SEC2["๐ฆ Dependency Review<br/><i>Supply chain</i>"]
SEC3["๐ Scorecard<br/><i>OSSF scoring</i>"]
SEC4["๐ Quality Checks<br/><i>TypeScript lint</i>"]
SEC5["๐ท๏ธ Setup Labels<br/><i>PR labeling</i>"]
end
subgraph "๐งช Testing"
TEST1["๐ Test Homepage<br/><i>Cypress E2E</i>"]
TEST2["๐ Test Dashboard<br/><i>Cypress E2E</i>"]
TEST3["๐ฐ Test News<br/><i>Cypress E2E</i>"]
TEST4["๐ฌ JS/TS Testing<br/><i>Vitest unit</i>"]
end
subgraph "๐ Deployment"
DEP1["โ๏ธ Deploy S3<br/><i>Production</i>"]
DEP2["๐ Release<br/><i>Attestations</i>"]
DEP3["๐ Uptime Monitor<br/><i>Every 15 min</i>"]
end
subgraph "๐ Data Pipeline"
DATA1["๐ Update CIA CSV Data<br/><i>Nightly 03:30 UTC + manual</i>"]
end
subgraph "๐ฐ Agentic News (14 workflows)"
NEWS1["๐ Committee Reports<br/><i>Mon-Fri 04:00</i>"]
NEWS2["๐ Propositions<br/><i>Mon-Fri 05:00</i>"]
NEWS3["โ Motions<br/><i>Mon-Fri 06:00</i>"]
NEWS4["โ Interpellations<br/><i>Mon-Fri 07:00</i>"]
NEWS5["โก Realtime Monitor<br/><i>2-3ร daily</i>"]
NEWS6["๐ Evening Analysis<br/><i>Mon-Fri 18:00</i>"]
NEWS7["๐
Week Ahead<br/><i>Friday 07:00</i>"]
NEWS8["๐ Weekly Review<br/><i>Saturday 09:00</i>"]
NEWS9["๐
Month Ahead<br/><i>1st 08:00</i>"]
NEWS10["๐ Monthly Review<br/><i>28th 10:00</i>"]
NEWS11["๐ Translate<br/><i>2-3ร daily</i>"]
NEWS12["๐ Quarter Ahead<br/><i>1st+15th 09:00</i>"]
NEWS13["๐ Year Ahead<br/><i>5 Jan+Jul 09:00</i>"]
NEWS14["๐ณ๏ธ Election Cycle<br/><i>Dispatch only</i>"]
end
NEWS1 & NEWS2 & NEWS3 & NEWS4 & NEWS5 & NEWS6 -->|"dispatch"| NEWS11
NEWS7 & NEWS8 & NEWS9 & NEWS10 -->|"dispatch"| NEWS11
style SEC1 fill:#dc3545,color:#fff,stroke:#b02a37
style SEC2 fill:#dc3545,color:#fff,stroke:#b02a37
style SEC3 fill:#dc3545,color:#fff,stroke:#b02a37
style SEC4 fill:#dc3545,color:#fff,stroke:#b02a37
style SEC5 fill:#dc3545,color:#fff,stroke:#b02a37
style TEST1 fill:#0d6efd,color:#fff,stroke:#0a58ca
style TEST2 fill:#0d6efd,color:#fff,stroke:#0a58ca
style TEST3 fill:#0d6efd,color:#fff,stroke:#0a58ca
style TEST4 fill:#0d6efd,color:#fff,stroke:#0a58ca
style DEP1 fill:#198754,color:#fff,stroke:#146c43
style DEP2 fill:#198754,color:#fff,stroke:#146c43
style DEP3 fill:#198754,color:#fff,stroke:#146c43
style DATA1 fill:#6f42c1,color:#fff,stroke:#59359a
style DATA2 fill:#6f42c1,color:#fff,stroke:#59359a
style DATA3 fill:#6f42c1,color:#fff,stroke:#59359a
style DATA4 fill:#6f42c1,color:#fff,stroke:#59359a
style DATA5 fill:#6f42c1,color:#fff,stroke:#59359a
style NEWS1 fill:#fd7e14,color:#fff,stroke:#ca6510
style NEWS2 fill:#fd7e14,color:#fff,stroke:#ca6510
style NEWS3 fill:#fd7e14,color:#fff,stroke:#ca6510
style NEWS4 fill:#fd7e14,color:#fff,stroke:#ca6510
style NEWS5 fill:#ffc107,color:#000,stroke:#cc9a06
style NEWS6 fill:#d63384,color:#fff,stroke:#ab296a
style NEWS7 fill:#20c997,color:#000,stroke:#1aa179
style NEWS8 fill:#20c997,color:#000,stroke:#1aa179
style NEWS9 fill:#0dcaf0,color:#000,stroke:#0aa2c0
style NEWS10 fill:#0dcaf0,color:#000,stroke:#0aa2c0
style NEWS11 fill:#e9ecef,color:#212529,stroke:#adb5bd
style NEWS12 fill:#6c757d,color:#fff,stroke:#495057
Core CI/CD Workflows
- โ
Quality Checks (
.github/workflows/quality-checks.yml) โ ESLint linting, HTML validation, link checking - ๐งน Knip Dead Code Check (
.github/workflows/knip.yml) โ Detects unused files, dependencies, binaries, and duplicate exports on every PR (informational pass also reports unused exports/types) - ๐งช TypeScript & JavaScript Testing (
.github/workflows/javascript-testing.yml) โ Vitest unit tests, TypeScript type-checking, Cypress E2E - ๐ TypeDoc Validation (
.github/workflows/jsdoc-validation.yml) โ API documentation generation and coverage - ๐ Translation Validation (
.github/workflows/translation-validation.yml) โ 14-language validation with RTL and hreflang - ๐ Release with Attestations (
.github/workflows/release.yml) โ SLSA provenance, SBOM, dual deployment - โ๏ธ Deploy to S3 (
.github/workflows/deploy-s3.yml) โ AWS S3/CloudFront deployment
Security Scanning Workflows
- ๐ CodeQL Analysis (
.github/workflows/codeql.yml) โ SAST for JavaScript/TypeScript vulnerabilities - ๐ฆ Dependency Review (
.github/workflows/dependency-review.yml) โ SCA for dependency vulnerabilities - โญ Scorecard Analysis (
.github/workflows/scorecards.yml) โ OpenSSF supply chain security assessment
Testing & Monitoring Workflows
- ๐ฅ๏ธ Test Dashboard (
.github/workflows/test-dashboard.yml) โ Dashboard Cypress E2E tests - ๐ Test Homepage (
.github/workflows/test-homepage.yml) โ Homepage Cypress E2E tests - ๐ฐ Test News (
.github/workflows/test-news.yml) โ News pages Cypress E2E tests - ๐ Lighthouse CI (
.github/workflows/lighthouse-ci.yml) โ Performance, accessibility, SEO auditing - ๐ก Uptime Monitor (
.github/workflows/uptime-monitor.yml) โ 15-minute availability checks for all 14 languages
CIA Data Pipeline Workflows
- ๐ Update CIA CSV Data (
.github/workflows/update-cia-csv-data.yml) โ Nightly + manual refresh of every already-trackeddata/cia/**andcia-data/**CSV from upstreamHack23/ciaservice.data.impl/sample-data/(recursive basenameโpath index, handles sub-folders); also refreshescia-data/production-stats.jsonand injects counts intoindex*.html; opens a single PR when anything changes
Automation & Infrastructure Workflows
- ๐ท๏ธ Setup Labels (
.github/workflows/setup-labels.yml) โ Repository label management - ๐ท๏ธ PR Labeler (
.github/workflows/labeler.yml) โ Automated PR labeling - ๐ง Compile Agentic Workflows (
.github/workflows/compile-agentic-workflows.yml) โ Compile .md โ .lock.yml - ๐ค Copilot Setup Steps (
.github/workflows/copilot-setup-steps.yml) โ GitHub Copilot environment
๐ค Agentic News Workflows (14 workflows: each has a .md source + .lock.yml compiled output)
- ๐ฐ News Committee Reports โ Committee report coverage
- ๐ฐ News Propositions โ Government proposition coverage
- ๐ News Motions โ Parliamentary motion tracking
- โ News Interpellations โ Interpellation debate tracking
- ๐ News Evening Analysis โ Evening analysis reports
- ๐ก News Realtime Monitor โ Real-time political monitoring
- ๐ฎ News Week Ahead โ Upcoming week preview
- ๐ News Month Ahead โ Upcoming month preview
- ๐ News Quarter Ahead โ 90-day parliamentary-season forecast
- ๐ News Year Ahead โ 365-day annual outlook (PESTLE blocking)
- ๐ณ๏ธ News Election Cycle โ Full 4-year mandate analysis (dispatch-only)
- ๐ News Weekly Review โ Weekly political summary
- ๐ News Monthly Review โ Monthly political review
- ๐ News Translate โ Multi-language article translation
Workflow Relationships
flowchart TB
subgraph "๐ Continuous Integration"
direction TB
PR[Pull Request] --> CodeQLScan[๐ CodeQL Analysis]
PR --> DependencyReview[๐ฆ Dependency Review]
PR --> Labeler[๐ท๏ธ PR Labeler]
PR --> QualityChecks[โ
Quality Checks]
PR --> TranslationVal[๐ Translation Validation]
CodeQLScan --> SecurityEvents[๐ก๏ธ Security Events]
end
subgraph "๐งช Testing Pipeline"
direction TB
PR --> UnitTests[๐งช TypeScript & JS Testing]
UnitTests --> TypeCheck[TSC Type Check]
UnitTests --> Vitest[Vitest 7500+ Tests]
UnitTests --> CypressE2E[Cypress E2E]
PR --> DashboardE2E[๐ฅ๏ธ Dashboard E2E]
PR --> HomepageE2E[๐ Homepage E2E]
PR --> NewsE2E[๐ฐ News E2E]
end
subgraph "๐ CIA Data Pipeline"
direction TB
Schedule1[โฐ Nightly 03:30 UTC] --> CIACsv[๐ Update CIA CSV Data]
ManualTrig[๐ฑ Manual dispatch] --> CIACsv
CIACsv --> CIAPR[๐ Open PR on changes]
end
subgraph "๐ Continuous Deployment"
direction TB
Release[Release Trigger] --> Build[๐๏ธ Vite Build]
Build --> Attestations[๐ SLSA Attestations]
Attestations --> DualDeploy{Dual Deploy}
DualDeploy --> S3Deploy[โ๏ธ AWS S3/CloudFront]
DualDeploy --> GHPages[๐ GitHub Pages]
end
subgraph "๐ค Agentic News Generation"
direction TB
AgenticTrigger[โฐ Scheduled / Manual] --> NewsGen[๐ฐ 14 News Workflows]
NewsGen --> Translate[๐ Translation]
Translate --> ContentDeploy[๐ค Content Deploy]
end
subgraph "๐ก Monitoring"
direction TB
Cron15[โฐ Every 15 min] --> Uptime[๐ก Uptime Monitor]
WeeklyLH[โฐ Weekly] --> Lighthouse[๐ Lighthouse CI]
WeeklyScore[โฐ Weekly] --> Scorecard[โญ Scorecard]
end
PR -.-> |"approved & merged"| main[Main Branch]
main --> S3Deploy
main -.-> |"tag created"| Release
classDef integration fill:#a0c8e0,stroke:#1565c0,stroke-width:1.5px,color:black
classDef testing fill:#c8e6c9,stroke:#2e7d32,stroke-width:1.5px,color:black
classDef deployment fill:#bbdefb,stroke:#1565c0,stroke-width:1.5px,color:black
classDef security fill:#ffccbc,stroke:#bf360c,stroke-width:1.5px,color:black
classDef datapipeline fill:#d1c4e9,stroke:#4a148c,stroke-width:1.5px,color:black
classDef agentic fill:#e1bee7,stroke:#6a1b9a,stroke-width:1.5px,color:black
classDef monitoring fill:#ffecb3,stroke:#f57f17,stroke-width:1.5px,color:black
classDef process fill:#c8e6c9,stroke:#2e7d32,stroke-width:1.5px,color:black
class PR,CodeQLScan,DependencyReview,Labeler,QualityChecks,TranslationVal integration
class UnitTests,TypeCheck,Vitest,CypressE2E,DashboardE2E,HomepageE2E,NewsE2E testing
class Release,Build,Attestations,DualDeploy,S3Deploy,GHPages deployment
class SecurityEvents security
class Schedule1,Schedule2,CIAStats,SchemaCheck,DataValidation,SchemaSync datapipeline
class AgenticTrigger,NewsGen,Translate,ContentDeploy agentic
class Cron15,WeeklyLH,WeeklyScore,Uptime,Lighthouse,Scorecard monitoring
class main process
๐ Security Gates & Quality Thresholds
| Security Gate | Threshold | Workflow | Enforcement |
|---|---|---|---|
| TypeScript Compilation | Zero errors | javascript-testing.yml | Required โ |
| ESLint | Zero errors | quality-checks.yml | Required โ |
| HTMLHint Validation | Zero errors | quality-checks.yml | Required โ |
| Link Integrity | Zero broken internal links | quality-checks.yml | Required โ |
| Knip Dead Code (files/deps/dups) | Zero unused files, deps, binaries, or duplicate exports | knip.yml | Required โ |
| Unit Test Pass Rate | 100% (7,500+ tests) | javascript-testing.yml | Required โ |
| CodeQL SAST | No critical/high | codeql.yml | Required โ |
| Dependency Vulnerabilities | No critical/high | dependency-review.yml | Required โ |
| Translation Completeness | All 14 languages valid | translation-validation.yml | Required โ |
| OSSF Scorecard | Score > 7.0 | scorecards.yml | Advisory โน๏ธ |
| Lighthouse Performance | Score 90+ | lighthouse-ci.yml | Advisory โน๏ธ |
| Site Availability | 99.9% uptime | uptime-monitor.yml | Advisory โน๏ธ |
๐ Security Hardening Practices
Riksdagsmonitor 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 security 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 security
class AS,DS,BS,RS measures
Specific Hardening Measures
Every workflow in the Riksdagsmonitor project implements least-privilege security. The baseline minimum permission is contents: read; individual workflows add only the extra scopes they need (e.g., id-token: write for OIDC, pages: write for deployments, pull-requests: write for PR comments):
-
๐ Permissions Restriction: Explicit least-privilege permissions per workflow
# Baseline minimum โ additional scopes added per-workflow as needed permissions: contents: read -
๐ SHA Pinning: All external actions pinned to specific SHA hashes for immutability
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 -
๐ก๏ธ Runner Hardening: StepSecurity harden-runner for egress auditing
- name: Harden Runner uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 with: egress-policy: audit -
๐ SBOM Generation: Software Bill of Materials for supply chain transparency
-
๐ Build Attestations: SLSA build provenance attestations (via GitHub Attestations)
-
โฑ๏ธ Timeout Limits: Jobs use timeout limits where applicable to prevent resource exhaustion
-
๐ OIDC Tokens: Ephemeral authentication for AWS deployments
๐ Detailed Pipeline Stages
๐งช Stage 1: Quality Checks (quality-checks.yml)
Purpose: Validates code quality through ESLint linting, HTML validation, and link checking.
Trigger: Push/PR to main
Security Controls: Harden-runner with egress auditing, SHA-pinned actions, least privilege permissions (contents: read)
flowchart TD
Start[๐ Code Push/PR] --> Prepare[๐ง Setup Environment]
Prepare --> ParallelChecks[Run Checks in Parallel]
ParallelChecks --> TSLint[๐ TypeScript Lint]
ParallelChecks --> HTMLVal[๐ HTML Validation]
ParallelChecks --> LinkCheck[๐ Link Checking]
TSLint --> TSResult{ESLint Pass?}
HTMLVal --> HTMLResult{HTMLHint Pass?}
LinkCheck --> LinkResult{Links Valid?}
TSResult -->|Yes| Summary[๐ Summary]
HTMLResult -->|Yes| Summary
LinkResult -->|Yes| Summary
TSResult -->|No| FixCode[โ Fix Code]
HTMLResult -->|No| FixHTML[โ Fix HTML]
LinkResult -->|No| FixLinks[โ Fix Links]
classDef startEnd fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef process fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
classDef test fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
classDef fail fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
class Start,Summary startEnd
class Prepare,ParallelChecks process
class TSLint,HTMLVal,LinkCheck test
class TSResult,HTMLResult,LinkResult decision
class FixCode,FixHTML,FixLinks fail
Jobs:
- ๐ TypeScript Lint โ ESLint flat config with
@typescript-eslint/parseracrosstsconfig.browser.json+tsconfig.scripts.json - ๐ HTML Validation โ HTMLHint on all
*.htmlfiles (14 language versions) - ๐ Link Checking โ Vite preview server + linkinator recursive check (skip external)
๐งช Stage 2: TypeScript & JavaScript Testing (javascript-testing.yml)
Purpose: Primary test workflow โ TypeScript type-checking, Vitest unit tests, Vite build verification, and multi-language Cypress E2E.
Trigger: Push/PR on **/*.ts, **/*.js, src/browser/**, tsconfig*.json, *.html, cypress/**, package*.json
flowchart TD
CodeChange[๐ Code Change] --> PrepareJob[๐ง Prepare Environment]
PrepareJob --> TypeCheck[๐ TypeScript Type Check]
TypeCheck --> BrowserTSC[Browser: tsc --noEmit]
TypeCheck --> ScriptsTSC[Scripts: tsc --noEmit]
BrowserTSC --> UnitTests[๐งช Vitest Unit Tests]
ScriptsTSC --> UnitTests
UnitTests --> CoverageMeasurement[๐ Coverage Report]
PrepareJob --> BuildValidation[๐๏ธ Vite Build]
BuildValidation --> BuildPass{Build Success?}
BuildPass -->|Yes| E2ETests[๐ Cypress E2E Tests]
BuildPass -->|No| FixBuild[โ Fix Build]
E2ETests --> UIValidation[๐ผ๏ธ UI Validation]
CoverageMeasurement --> Report[๐ค Upload Reports]
UIValidation --> Report
classDef start fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef process fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
classDef test fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef decision fill:#9b59b6,stroke:#8e44ad,stroke-width:2px,color:white
classDef parallel fill:#e67e22,stroke:#d35400,stroke-width:2px,color:white
classDef fail fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
class CodeChange start
class PrepareJob,TypeCheck,BrowserTSC,ScriptsTSC process
class UnitTests,CoverageMeasurement,E2ETests,UIValidation test
class BuildPass decision
class BuildValidation parallel
class FixBuild fail
class Report start
TypeScript Compilation Strategy:
tsconfig.browser.jsonโ validatessrc/browser/**/*.ts(31 modules)tsconfig.scripts.jsonโ validatesscripts/**/*.ts+tests/**/*.ts- Both use
noEmit: true(Vite/esbuild handles actual compilation)
Test Coverage: 7,500+ unit tests (Vitest) + Happy-DOM environment for browser modules + V8 coverage provider
๐ Stage 3: Security Scanning
3.1 CodeQL Analysis (codeql.yml)
Tool: GitHub CodeQL
Trigger: Push to main, PR, weekly schedule
Language matrix: ["javascript-typescript"]
3.2 Dependency Review (dependency-review.yml)
Tool: actions/dependency-review-action
Trigger: Pull requests
Gate: Blocks PRs with critical/high vulnerability dependencies
3.3 OpenSSF Scorecard (scorecards.yml)
Tool: OpenSSF Scorecard Trigger: Push to main, weekly schedule Purpose: Supply chain security assessment and OSSF best practices evaluation
๐ Stage 4: Release & Deployment
flowchart TD
Trigger[๐ท๏ธ Release Trigger] --> Build[๐๏ธ Vite Build]
Build --> SBOM[๐ Generate SBOM]
SBOM --> Attestations[๐ SLSA Attestations]
Attestations --> TypeDoc[๐ Generate API Docs]
TypeDoc --> DualDeploy{๐ Dual Deploy}
DualDeploy --> S3[โ๏ธ AWS S3/CloudFront]
DualDeploy --> GHP[๐ GitHub Pages]
S3 --> CFInvalidate[๐ CloudFront Invalidation]
GHP --> GHPCdn[๐ GitHub CDN]
CFInvalidate --> Live1[โ
riksdagsmonitor.com]
GHPCdn --> Live2[โ
hack23.github.io/riksdagsmonitor]
classDef trigger fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
classDef build fill:#27ae60,stroke:#1e8449,stroke-width:1.5px,color:white
classDef security fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef deploy fill:#FF9900,stroke:#232F3E,stroke-width:1.5px,color:white
classDef complete fill:#16a085,stroke:#1abc9c,stroke-width:2px,color:white
class Trigger trigger
class Build,TypeDoc build
class SBOM,Attestations security
class DualDeploy,S3,GHP,CFInvalidate,GHPCdn deploy
class Live1,Live2 complete
Release Pipeline Features:
- ๐ท๏ธ Tag-based Releases: Automatic releases on
v*tag push - ๐ Manual Releases: Workflow dispatch with version input
- ๐ SLSA Attestations: Build provenance for supply chain security
- ๐ SBOM Generation: Software Bill of Materials
- ๐ TypeDoc: API documentation generation
- โ๏ธ Dual Deployment: AWS S3/CloudFront (primary) + GitHub Pages (DR)
S3 Sync Exclusions: .git/*, .github/*, node_modules/*, src/*, tests/*, cypress/*, builds/*, tsconfig*.json, *.config.js
๐ Stage 5: CIA Data Integration
flowchart TD
subgraph "โฐ Triggers"
Nightly[๐
Nightly 03:30 UTC] --> Refresh[๐ Update CIA CSV Data]
Manual[๐ฑ Manual dispatch<br/><i>optional ref input</i>] --> Refresh
end
subgraph "๐ CSV + Stats Refresh"
Refresh --> TreeIdx[๐ Build basenameโpath index<br/>GitHub Tree API, recursive]
TreeIdx --> Download[๐ฅ Download only already-tracked<br/>data/cia/** + cia-data/** CSVs]
Download --> Stats[๐ load-cia-stats.ts โ<br/>production-stats.json]
Stats --> Inject[๐ update-stats-from-cia.ts โ<br/>inject counts into 14ร index*.html]
Inject --> Diff{Any changes?}
Diff -->|No| NoOp[โ
No-op summary]
Diff -->|Yes| AutoPR[๐ Open single PR<br/>CSVs + stats + HTML]
end
classDef schedule fill:#ffecb3,stroke:#f57f17,stroke-width:1.5px,color:black
classDef pipeline fill:#c8e6c9,stroke:#2e7d32,stroke-width:1.5px,color:black
classDef decision fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:black
class Nightly,Manual schedule
class Refresh,TreeIdx,Download,Stats,Inject,AutoPR,NoOp pipeline
class Diff decision
Workflows:
- ๐ Update CIA CSV Data (
update-cia-csv-data.yml): Nightly at 03:30 UTC and on manual dispatch.- Source of truth for what to refresh = the set of CSVs already tracked in this repository under
data/cia/**andcia-data/**. The workflow never introduces new files. - Source of truth for where each CSV lives upstream = a
basename โ upstream-pathindex built once per run from the GitHub Tree API (/repos/Hack23/cia/git/trees/<ref>?recursive=1). This correctly resolves sub-folder CSVs (e.g.distinct_values/vote_data_party.csv,framework-validation/**,risk-rule-tests/**) โ the upstream layout is not flat. A<stem>_sample.csvalias is tried as a fallback for the handful of locally-renamed canonical files (view_riksdagen_committee_decisions.csvโ upstreamview_riksdagen_committee_decisions_sample.csv, etc.). - Stats refresh โ after the CSV step, the workflow runs
npx tsx scripts/load-cia-stats.tsto regeneratecia-data/production-stats.jsonfrom upstreamextraction_summary_report.csv, thennpx tsx scripts/update-stats-from-cia.tsto inject the refreshed counts into all 14index*.htmllanguage variants. - PR output โ a single automated pull request is opened via
peter-evans/create-pull-requestwhenever CSV content,production-stats.json, orindex*.htmlchange. Byte-levelcmpensures commits are produced only on real diffs. - Skipped paths โ locally-curated files with no upstream equivalent are never overwritten:
data/cia/ministry/sample_{influence,decision_impact,risk_levels,productivity}.csvandcia-data/election/{election_forecast,coalition_scenarios}.csv.
- Source of truth for what to refresh = the set of CSVs already tracked in this repository under
๐ค Stage 6: Agentic News Generation
Fourteen agentic workflows use the gh-aw (GitHub Agentic Workflows) framework to generate political-intelligence content following OSINT/INTOP editorial standards and the 23-artifact analysis baseline. The 13 analysis/article-generating workflows run on claude-opus-4.8 (strongest reasoning for the analysis pipeline), while the high-volume news-translate workflow stays on claude-sonnet-4.6 for translation-fan-out throughput.
flowchart TD
subgraph "๐ฐ News Generation Pipeline"
Trigger[โฐ Scheduled / Manual] --> PreAnalysis[๐ Pre-Article Analysis]
PreAnalysis --> Download[๐ฅ Download Riksdag Data]
Download --> AIAnalysis[๐ค AI Analysis - Claude Opus 4.8]
AIAnalysis --> Generate[๐ Generate Article]
Generate --> QualityCheck[โ
Quality Validation]
QualityCheck --> Translate[๐ Multi-Language Translation]
Translate --> Deploy[๐ค Commit & Deploy]
end
subgraph "๐ 14 News Workflows"
W1[๐ Committee Reports]
W2[๐๏ธ Propositions]
W3[๐ Motions]
W4[โ Interpellations]
W5[๐ก Realtime Monitor]
W6[๐
Evening Analysis]
W7[๐ฎ Week Ahead]
W8[๐
Month Ahead]
W9[๐ Quarter Ahead]
W10[๐ Year Ahead]
W11[๐ณ๏ธ Election Cycle]
W12[๐ฐ Weekly Review]
W13[๐ Monthly Review]
W14[๐ Translate]
end
classDef pipeline fill:#e1bee7,stroke:#6a1b9a,stroke-width:1.5px,color:black
classDef workflow fill:#ce93d8,stroke:#6a1b9a,stroke-width:1px,color:black
classDef ai fill:#9C27B0,stroke:#6a1b9a,stroke-width:2px,color:white
class Trigger,PreAnalysis,Download,Generate,QualityCheck,Translate,Deploy pipeline
class AIAnalysis ai
class W1,W2,W3,W4,W5,W6,W7,W8,W9,W10,W11,W12,W13,W14 workflow
MCP Tools Available:
riksdag-regering-mcp(32 tools for Swedish political data)@playwright/mcp(browser automation)@modelcontextprotocol/server-filesystem@modelcontextprotocol/server-memory
Compilation: Source .md โ .lock.yml via compile-agentic-workflows.yml
Per-Workflow Data Download & Unique Analytics
Each agentic workflow downloads data from specific MCP tools and produces unique political intelligence that only that document type can provide:
graph TB
subgraph "๐ฅ MCP Data Sources"
BET["get_betankanden<br/><i>Committee reports</i>"]
PROP["get_propositioner<br/><i>Government bills</i>"]
MOT["get_motioner<br/><i>Opposition motions</i>"]
INTERP["get_interpellationer<br/><i>Parliamentary questions</i>"]
VOTE["search_voteringar<br/><i>Voting records</i>"]
ANF["search_anforanden<br/><i>Debate speeches</i>"]
DOK["search_dokument<br/><i>Document search</i>"]
DOKFT["search_dokument_fulltext<br/><i>Full-text search</i>"]
CAL["get_calendar_events<br/><i>Parliamentary calendar</i>"]
SCB["SCB MCP<br/><i>Statistics Sweden</i>"]
WB["World Bank MCP<br/><i>International data</i>"]
IMF["IMF TypeScript client<br/><i>WEO + Fiscal Monitor + IFS<br/>pure-TS, not MCP</i>"]
end
subgraph "๐ฐ Agentic Workflows"
WF_CR["๐ Committee Reports"]
WF_PR["๐ Propositions"]
WF_MO["โ Motions"]
WF_IP["โ Interpellations"]
WF_EV["๐ Evening Analysis"]
WF_RT["โก Realtime Monitor"]
WF_WR["๐
Weekly Review"]
WF_WA["๐ฎ Week Ahead"]
end
BET --> WF_CR
VOTE --> WF_CR
ANF --> WF_CR
PROP --> WF_CR
SCB --> WF_CR
WB --> WF_EV
WB --> WF_WR
IMF --> WF_EV
IMF --> WF_WR
IMF --> WF_WA
IMF --> WF_CR
PROP --> WF_PR
DOKFT --> WF_PR
ANF --> WF_PR
MOT --> WF_MO
DOKFT --> WF_MO
ANF --> WF_MO
INTERP --> WF_IP
ANF --> WF_IP
DOKFT --> WF_IP
CAL --> WF_IP
VOTE --> WF_EV
ANF --> WF_EV
BET --> WF_EV
CAL --> WF_EV
DOK --> WF_RT
CAL --> WF_RT
VOTE --> WF_RT
ANF --> WF_RT
BET --> WF_RT
DOK --> WF_WR
ANF --> WF_WR
BET --> WF_WR
PROP --> WF_WR
MOT --> WF_WR
VOTE --> WF_WR
CAL --> WF_WA
DOK --> WF_WA
ANF --> WF_WA
INTERP --> WF_WA
style BET fill:#198754,color:#fff
style PROP fill:#0d6efd,color:#fff
style MOT fill:#fd7e14,color:#fff
style INTERP fill:#dc3545,color:#fff
style VOTE fill:#6f42c1,color:#fff
style ANF fill:#d63384,color:#fff
style DOK fill:#20c997,color:#000
style DOKFT fill:#17a589,color:#fff
style CAL fill:#0dcaf0,color:#000
style SCB fill:#ffc107,color:#000
style WB fill:#ff9800,color:#000
style IMF fill:#00897b,color:#fff,stroke:#004d40,stroke-width:2px
style WF_CR fill:#198754,color:#fff,stroke-width:2px
style WF_PR fill:#0d6efd,color:#fff,stroke-width:2px
style WF_MO fill:#fd7e14,color:#fff,stroke-width:2px
style WF_IP fill:#dc3545,color:#fff,stroke-width:2px
style WF_EV fill:#6f42c1,color:#fff,stroke-width:2px
style WF_RT fill:#d63384,color:#fff,stroke-width:2px
style WF_WR fill:#20c997,color:#000,stroke-width:2px
style WF_WA fill:#0dcaf0,color:#000,stroke-width:2px
| # | Workflow | Schedule | Primary MCP Data | Unique Analytics Produced |
|---|---|---|---|---|
| 1 | Committee Reports | MonโFri 04:00 UTC | get_betankanden, search_voteringar, search_anforanden, get_propositioner | Committee voting splits per party, reservation (dissent) analysis, committee-to-policy-domain mapping, SCB statistical enrichment per committee domain |
| 2 | Propositions | MonโFri 05:00 UTC | get_propositioner, search_dokument_fulltext, analyze_g0v_by_department, search_anforanden | Legislative pipeline tracking (referral โ committee โ vote), government legislative ambition score, budget allocation impact analysis, policy domain cascading effects |
| 3 | Motions | MonโFri 06:00 UTC | get_motioner, search_dokument_fulltext, analyze_g0v_by_department, search_anforanden | Opposition strategy analysis, motion clustering by theme, cross-party co-sponsorship detection, signalverdi (is this positioning or a real bid?) |
| 4 | Interpellations | MonโFri 07:00 UTC | get_interpellationer, search_anforanden, search_dokument_fulltext, get_calendar_events | Ministerial accountability scoring (response rate/timeliness), evasion detection, question framing analysis, party oversight strategy mapping |
| 5 | Realtime Monitor | MonโFri 10:00+14:00, Weekends 12:00 | search_dokument, get_calendar_events, search_voteringar, search_anforanden, get_betankanden | Breaking event detection, urgency classification, real-time political temperature spikes |
| 6 | Evening Analysis | MonโFri 18:00, Sat 16:00 | search_voteringar, search_anforanden, get_betankanden, get_calendar_events | Daily parliamentary pulse, party discipline metrics, coalition cohesion scoring, debate intensity index |
| 7 | Weekly Review | Sat 09:00 UTC | search_dokument, search_anforanden, get_betankanden, get_propositioner, get_motioner, search_voteringar | Week-over-week trend detection, cross-document-type pattern identification, legislative throughput metrics; IMF WEO / Fiscal Monitor projections enrich the weekly macroeconomic framing |
| 8 | Week Ahead | Fri 07:00 UTC | get_calendar_events, search_dokument, search_anforanden, get_fragor, get_interpellationer | Prospective calendar analysis, scheduled debate preview, expected vote outcomes; IMF projections (T+5 horizon) are the primary source for forward-looking economic commentary |
| 9 | Monthly Review | 28th 10:00 UTC | search_dokument, search_anforanden, get_betankanden, get_propositioner, get_motioner, search_voteringar | Monthly legislative throughput, party productivity rankings, government vs opposition scorecard; IMF IFS monthly series + WEO vintages used for fiscal/monetary context |
| 10 | Month Ahead | 1st 08:00 UTC | get_calendar_events, search_dokument, get_betankanden, get_propositioner, get_motioner | Strategic political calendar, legislative pipeline forecast, major policy decision timeline; IMF WEO / Fiscal Monitor projection vintage (projectionVintage pinned per article) anchors medium-term outlook |
| 11 | Article Generator | Manual only | Per-type (configurable) | Manual backfill/regeneration for any article type |
| 12 | Translate | MonโFri 11:00+17:00, Weekends 14:00 | N/A (text processing) | 14-language translation quality with cultural adaptation |
๐งฉ Stage 6.1: Agentic Workflow Structure & Prompt Imports
Every news-*.md source in .github/workflows/ is a gh-aw workflow โ a Markdown file whose YAML frontmatter compiles down, via gh aw compile, to a hardened GitHub Actions .lock.yml. A workflow is made up of three layers:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ news-<type>.md โ
โ โโโ Frontmatter (name, triggers, runtimes, network, tools, mcp-servers)โ
โ โโโ imports: โ
โ โ โโโ prompts/00-base-contract.md โ role, ethics, AI-FIRST โ
โ โ โโโ prompts/01-bash-and-shell-safety.md โ
โ โ โโโ prompts/02-mcp-access.md โ MCP inventory + health โ
โ โ โโโ prompts/03-data-download.md โ download pipeline โ
โ โ โโโ prompts/04-analysis-pipeline.md โ 23 artifacts (4 families), Pass 1+2 โ
โ โ โโโ prompts/05-analysis-gate.md โ BLOCKING artifact gate โ
โ โ โโโ prompts/06-article-generation.md โ sections, banned patterns โ
โ โ โโโ prompts/07-commit-and-pr.md โ stage โ commit โ PR โ
โ โโโ (Tier-C only) imports: prompts/ext/tier-c-aggregation.md โ depth multipliers โ
โ โโโ Body = per-type instructions (e.g. "generate propositions article")โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ gh aw compile
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ news-<type>.lock.yml (the only file GitHub Actions executes) โ
โ โโโ SHA-pinned actions (100%) โ
โ โโโ step-security/harden-runner with egress audit โ
โ โโโ Squid proxy + iptables firewall over network.allowed: โ
โ โโโ Five-layer safe-outputs validator โ
โ โโโ MCP servers wired: riksdag-regering, scb, world-bank โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Import order is a contract
The import order is not arbitrary โ each module builds on the previous one, and .github/prompts/05-analysis-gate.md is a single blocking gate that refuses to let the agent draft a single article sentence until all required artifacts are on disk in analysis/daily/$ARTICLE_DATE/$SUBFOLDER/ for both Pass 1 and Pass 2. The baseline is 23 artifacts; year-ahead requires 24 (23 + pestle-analysis.md via LH-4); election-cycle requires 28 (23 + 5 blocking supplementary via LH-4 + LH-5: pestle-analysis.md, cycle-trajectory.md, wildcards-blackswans.md, quantitative-swot.md, political-stride-assessment.md).
| Import # | Module | Responsibility | What fails fast if missing |
|---|---|---|---|
| 1 | 00-base-contract.md | Role, editorial ethics, GDPR, ISMS, AI-FIRST 2-pass minimum | Ethics drift, privacy leaks, shallow output |
| 2 | 01-bash-and-shell-safety.md | UTF-8 shell patterns, no eval, no shell-expansion exploits | Command injection, encoding corruption |
| 3 | 02-mcp-access.md | MCP server inventory + health probe | Wrong tool called, missing data source |
| 4 | 03-data-download.md | Download manifest, source attribution, caching | Unsourced claims |
| 5 | 04-analysis-pipeline.md | 23 required artifacts (Family AโD), methodology โ template bindings, Pass 1 + Pass 2 | Shallow analysis, template mismatch |
| 6 | 05-analysis-gate.md | Blocks article generation until artifacts are complete | Any article written before gate passes โ workflow failure |
| 7 | 06-article-generation.md | Article sections, banned hype patterns, visualisation, translations | Boilerplate content, missing charts |
| 8 | 07-commit-and-pr.md | Stage โ commit โ exactly one create_pull_request call | Orphan commits, duplicate PRs |
| 9 (Tier-C only) | ext/tier-c-aggregation.md | Depth multipliers, cross-type synthesis, higher article floor (same 23 artifacts) | Aggregation without base artifacts |
Dependency graph
flowchart TB
subgraph WF["news-<type>.md (workflow source)"]
FM[Frontmatter<br/>triggers ยท runtimes ยท network ยท mcp-servers]
BODY[Body<br/>per-type analysis instructions]
end
subgraph PROMPTS[".github/prompts/ (shared bounded contexts)"]
P00[00-base-contract]
P01[01-bash-and-shell-safety]
P02[02-mcp-access]
P03[03-data-download]
P04[04-analysis-pipeline]
P05[05-analysis-gate โ ๏ธ blocking]
P06[06-article-generation]
P07[07-commit-and-pr]
PEXT[ext/tier-c-aggregation]
end
subgraph METH["analysis/methodologies/"]
M1[ai-driven-analysis-guide]
M2[per-document-methodology]
M3[political-risk-methodology]
M4[political-swot-framework]
M5[political-threat-framework]
M6[synthesis-methodology]
end
subgraph TPL["analysis/templates/ (23 output templates)"]
T1[per-file-political-intelligence]
T2[risk-assessment]
T3[swot-analysis]
T4[threat-analysis]
T5[stakeholder-impact]
T6[scenario-analysis]
T7[significance-scoring]
T8[executive-brief]
T9[cross-reference-map]
T10[synthesis-summary]
T11[devils-advocate]
T12[methodology-reflection]
T13[โฆ + 11 more]
end
FM --> P00 --> P01 --> P02 --> P03 --> P04 --> P05 --> P06 --> P07
P04 -.binds.-> METH
P04 -.binds.-> TPL
P05 -.verifies.-> TPL
BODY --> PEXT
PEXT -. Tier-C only .-> P05
style P05 fill:#dc3545,color:#fff,stroke:#b02a37,stroke-width:3px
style PEXT fill:#fd7e14,color:#fff,stroke:#ca6510
Single-type vs. Tier-C artifact contract
All workflows produce the same 23 always-on artifacts (Family A 9 + Family B 2 + Family C 5 + Family D 7) defined in prompts/04-analysis-pipeline.md. The counts below are baseline blocking artifacts from the main gate checks and long-horizon checks (LH-4, LH-5). In addition, the gate's supplementary checks (S1โS7 in 05-analysis-gate.md) can block runs depending on tier and article type:
comprehensivetier and aggregation types (weekly-review,monthly-review):analysis-index.md,reference-analysis-quality.md,mcp-reliability-audit.md,workflow-audit.mdbecome blocking; aggregation types also requirecross-session-intelligence.mdandsession-baseline.md- Multi-run (โฅ 2 production runs of the same article type):
cross-run-diff.mdbecomes blocking
Long-horizon gates (LH-4, LH-5) additionally require analytical supplementary artifacts that are normally optional but become blocking for specific workflows:
- Year-ahead (LH-4):
pestle-analysis.mdโ total 24 baseline blocking artifacts - Election-cycle (LH-4 + LH-5):
pestle-analysis.md+cycle-trajectory.md+wildcards-blackswans.md+quantitative-swot.md+political-stride-assessment.mdโ total 28 baseline blocking artifacts
| Contract | Applies to | Baseline blocking | Depth | Source |
|---|---|---|---|---|
| Single-type | news-propositions, news-motions, news-committee-reports, news-interpellations | 23 | standard/deep | prompts/05-analysis-gate.md |
| Tier-C aggregation | news-evening-analysis, news-realtime-monitor, news-week-ahead, news-month-ahead, news-weekly-review, news-monthly-review, news-quarter-ahead | 23 (+ S1โS7 per tier/type) | ร 1.0โ1.7 | prompts/ext/tier-c-aggregation.md |
| Tier-C + year-ahead | news-year-ahead | 24 (23 + pestle-analysis.md via LH-4; + S1โS7 per tier) | ร 2.0 | prompts/ext/tier-c-aggregation.md + LH-4 |
| Tier-C + election-cycle | news-election-cycle | 28 (23 + 5 via LH-4 + LH-5; + S1โS7 per tier) | ร 2.5 | prompts/ext/tier-c-aggregation.md + LH-4 + LH-5 |
| Translation (N/A) | news-translate | N/A (catch-up only โ primary translation now happens inside each per-type run) | โ | Direct text pipeline |
All artifacts are written under analysis/daily/$ARTICLE_DATE/$SUBFOLDER/ โ see analysis/README.md for the on-disk layout and analysis/templates/README.md for the 23 canonical templates.
MCP server wiring (identical across all 14 agentic workflows)
mcp-servers:
riksdag-regering: # HTTP (hosted)
url: https://riksdag-regering-ai.onrender.com/mcp
allowed: ["*"]
scb: # Container (per-run)
container: "node:26-alpine"
entrypoint: "npx"
entrypointArgs: ["-y", "@jarib/pxweb-mcp@2.0.0",
"--url", "https://api.scb.se/OV0104/v2beta"]
allowed: ["*"]
world-bank: # Container (per-run)
container: "node:26-alpine"
entrypoint: "npx"
entrypointArgs: ["-y", "worldbank-mcp@1.0.1"]
allowed: ["*"]
In addition, every workflow activates the gh-aw-provided github (all toolsets), agentic-workflows, bash, playwright, and repo-memory tools. IMF ingestion is not an MCP server โ it is pulled by scripts/imf-client.ts (pure-TS Datamapper JSON + SDMX 3.0 client), fully covered by the npm SBOM, so the total MCP server count remains 8 (3 shared here + 5 repo-level in .github/copilot-mcp.json).
Network egress allow-list (applies to every agentic workflow)
network:
allowed:
- node # npm registry ecosystem
- github # GitHub API
- defaults # Curated dev domains
- riksdag-regering-ai.onrender.com # Riksdag MCP
- api.scb.se # Statistics Sweden
- api.worldbank.org # World Bank
- api.imf.org # IMF (for imf-client.ts)
- data.riksdagen.se # Riksdag open data
- riksdagen.se / www.riksdagen.se # Riksdag website
- regeringen.se / www.regeringen.se # Government website
- hack23.com / www.hack23.com # Hack23 platform
- riksdagsmonitor.com # This platform
- raw.githubusercontent.com # Raw GitHub content
- hack23.github.io # GitHub Pages DR
Any outbound connection not matching this allow-list is dropped at the Squid proxy / iptables layer.
Compilation lifecycle
- Author edits
news-<type>.md. - PR triggers
compile-agentic-workflows.yml. - That workflow runs
gh aw compileto regenerate the sibling.lock.yml. - Reviewer inspects the
.mdsource of truth and confirms the.lock.ymldiff. - Once merged, the next cron/dispatch runs the
.lock.ymlunder the hardened runner.
Rule: never edit a
.lock.ymlby hand โ the next compilation pass will overwrite it. All review feedback must target the.mdsource and the prompt modules it imports.
๐ฎ Stage 6.2: Long-Horizon Forward-Look Pipelines (quarter / year / election-cycle)
The three long-horizon workflows extend the forward-look family beyond week-ahead and month-ahead. They share the Tier-C aggregation contract but apply progressively higher depth multipliers and require additional prompt modules (ext/long-horizon-forecasting.md; ext/cycle-rollover.md for election-cycle only). Full horizon metadata is defined in analysis/article-types.json; editorial parameters are documented in Article-Generation.md ยง Forward-Look Horizons.
๐ 6.2.1 News Quarter Ahead (news-quarter-ahead)
Schedule: 0 9 1,15 * * (1st + 15th of month, 09:00 UTC)
Horizon: 90 days | Depth multiplier: ร 1.7 | Word floor: 2 000 | Timeout: 45 min
flowchart TD
subgraph Imports["Prompt-module imports"]
P00["00-base-contract"]
P01["01-bash-and-shell-safety"]
P02["02-mcp-access"]
P03["03-data-download"]
P04["04-analysis-pipeline"]
P05["05-analysis-gate โ"]
P06["06-article-generation"]
P07["07-commit-and-pr"]
EXT1["ext/tier-c-aggregation"]
EXT2["ext/long-horizon-forecasting"]
end
subgraph MCP["MCP-server access"]
RR["riksdag-regering<br/>(Riksdag calendar, committee schedules)"]
SCB["SCB PxWeb<br/>(quarterly NA, Riksbank rates)"]
WB["world-bank<br/>(governance residue)"]
IMF["IMF WEO/FM via bash<br/>(macro projections)"]
end
subgraph Pipeline["Pipeline stages"]
A1["๐ฅ Data download<br/>(committee schedule, prop tabling)"]
A2["๐ฌ Analysis (23 artifacts)<br/>Tier-C ร 1.7 depth"]
A3["โ Analysis gate<br/>(blocks until 23 artifacts)"]
A4["๐ Article generation<br/>(โฅ 2000 words)"]
A5["๐ Safe-outputs envelope<br/>(sanitise โ validate โ PR)"]
end
Imports --> Pipeline
MCP --> A1
A1 --> A2 --> A3 --> A4 --> A5
sequenceDiagram
participant Cron as โฐ Cron (1st/15th 09:00)
participant Runner as ๐ฅ๏ธ gh-aw Runner
participant MCP as ๐ก MCP Servers
participant Gate as โ Analysis Gate
participant SO as ๐ Safe-Outputs
Cron->>Runner: trigger news-quarter-ahead
Runner->>MCP: fetch committee schedule + propositions calendar (90d)
MCP-->>Runner: structured data
Runner->>Runner: analysis pipeline (23 artifacts, ร 1.7)
Runner->>Gate: verify 23 artifacts present
Gate-->>Runner: PASS
Runner->>Runner: render article (โฅ 2000 words EN+SV)
Runner->>SO: submit PR via safe-outputs
SO-->>Runner: PR created (human review)
Note over Runner,SO: Hard deadline: 45 min timeout
๐ 6.2.2 News Year Ahead (news-year-ahead)
Schedule: 0 9 5 1,7 * (5th of January + 5th of July, 09:00 UTC)
Horizon: 365 days | Depth multiplier: ร 2.0 | Word floor: 2 500 | Timeout: 45 min
flowchart TD
subgraph Imports["Prompt-module imports"]
P00["00-base-contract"]
P01["01-bash-and-shell-safety"]
P02["02-mcp-access"]
P03["03-data-download"]
P04["04-analysis-pipeline"]
P05["05-analysis-gate โ"]
P06["06-article-generation"]
P07["07-commit-and-pr"]
EXT1["ext/tier-c-aggregation"]
EXT2["ext/long-horizon-forecasting"]
end
subgraph MCP["MCP-server access"]
RR["riksdag-regering<br/>(Riksmรถte calendar, VPs + BPs)"]
SCB["SCB PxWeb<br/>(annual NA, demographic)"]
WB["world-bank<br/>(WGI governance)"]
IMF["IMF WEO Apr/Oct vintage<br/>(GDP, growth, fiscal)"]
end
subgraph Pipeline["Pipeline stages"]
A1["๐ฅ Data download<br/>(budget rhythm: BP autumn + VP spring)"]
A2["๐ฌ Analysis (23 + 1 gate-blocking + 2 mandated)<br/>Tier-C ร 2.0 depth + pestle-analysis.md (LH-4)<br/>+ wildcards-blackswans.md + quantitative-swot.md"]
A3["โ Analysis gate<br/>(blocks until 24: 23 baseline + pestle-analysis.md)<br/>wildcards + SWOT mandated by registry, not gate-blocking"]
A4["๐ Article generation<br/>(โฅ 2500 words, wildcards-blackswans)"]
A5["๐ Safe-outputs envelope<br/>(sanitise โ validate โ PR)"]
end
Imports --> Pipeline
MCP --> A1
A1 --> A2 --> A3 --> A4 --> A5
sequenceDiagram
participant Cron as โฐ Cron (5 Jan/Jul 09:00)
participant Runner as ๐ฅ๏ธ gh-aw Runner
participant MCP as ๐ก MCP Servers
participant IMF as ๐น IMF WEO/FM
participant Gate as โ Analysis Gate
participant SO as ๐ Safe-Outputs
Cron->>Runner: trigger news-year-ahead
Runner->>MCP: fetch Riksmรถte + budget calendar (365d)
Runner->>IMF: fetch WEO Apr/Oct vintage projections
MCP-->>Runner: parliamentary data
IMF-->>Runner: macro projections (GDP, inflation, fiscal)
Runner->>Runner: analysis pipeline (24 gate-blocking + 2 mandated: pestle + wildcards + SWOT, ร 2.0)
Runner->>Runner: LH-4: pestle-analysis.md blocking; wildcards + SWOT mandated by registry
Runner->>Gate: verify 24 gate-blocking artifacts (23 baseline + pestle-analysis.md via LH-4)
Gate-->>Runner: PASS
Runner->>Runner: render article (โฅ 2500 words EN+SV)
Runner->>SO: submit PR via safe-outputs
SO-->>Runner: PR created (human review)
Note over Runner,SO: Hard deadline: 45 min timeout
๐ณ๏ธ 6.2.3 News Election Cycle (news-election-cycle)
Schedule: workflow_dispatch only (cron 0 9 13 3,9 * declared but disabled until runtime measured)
Horizon: 1 460 days (4-year mandate) | Depth multiplier: ร 2.5 | Word floor: 3 500 | Timeout: 45 min
Extra imports: ext/cycle-rollover.md (active ยฑ30 days of election anchor 2026-09-13)
flowchart TD
subgraph Imports["Prompt-module imports (11 modules)"]
P00["00-base-contract"]
P01["01-bash-and-shell-safety"]
P02["02-mcp-access"]
P03["03-data-download"]
P04["04-analysis-pipeline"]
P05["05-analysis-gate โ"]
P06["06-article-generation"]
P07["07-commit-and-pr"]
EXT1["ext/tier-c-aggregation"]
EXT2["ext/long-horizon-forecasting"]
EXT3["ext/cycle-rollover"]
end
subgraph MCP["MCP-server access"]
RR["riksdag-regering<br/>(full mandate voting record)"]
SCB["SCB PxWeb<br/>(demographic, economic)"]
WB["world-bank<br/>(WGI governance 4-year)"]
IMF["IMF WEO multi-year<br/>(T+5 projections)"]
end
subgraph Pipeline["Pipeline stages"]
A1["๐ฅ Data download<br/>(Tidรถ scorecard + next-cycle coalition)"]
A2["๐ฌ Analysis (23 + 5 artifacts)<br/>Tier-C ร 2.5 depth + 5 blocking supplementary"]
A3["โ Analysis gate<br/>(blocks until 28: 23 baseline + pestle + cycle-trajectory + wildcards + SWOT + STRIDE)"]
A4["๐ Article generation<br/>(โฅ 3500 words, STRIDE assessment)"]
A5["๐ Safe-outputs envelope<br/>(sanitise โ validate โ PR)"]
end
Imports --> Pipeline
MCP --> A1
A1 --> A2 --> A3 --> A4 --> A5
sequenceDiagram
participant Op as ๐ค Operator (dispatch)
participant Runner as ๐ฅ๏ธ gh-aw Runner
participant MCP as ๐ก MCP Servers
participant IMF as ๐น IMF WEO T+5
participant Gate as โ Analysis Gate
participant SO as ๐ Safe-Outputs
Op->>Runner: workflow_dispatch (cycle_anchor=both)
Runner->>MCP: fetch full mandate voting record + coalition data
Runner->>IMF: fetch multi-year WEO projections
MCP-->>Runner: 4-year parliamentary data
IMF-->>Runner: T+5 macro projections
Runner->>Runner: analysis pipeline (28 artifacts: 23 + 5 blocking supplementary, ร 2.5)
Runner->>Runner: LH-4: pestle-analysis.md; LH-5: cycle-trajectory + wildcards + SWOT + STRIDE
Runner->>Gate: verify 28 artifacts (23 baseline + pestle + cycle-trajectory + wildcards-blackswans + quantitative-swot + political-stride-assessment)
Gate-->>Runner: PASS
Runner->>Runner: render article (โฅ 3500 words EN+SV)
Runner->>SO: submit PR via safe-outputs
SO-->>Runner: PR created (human review)
Note over Runner,SO: Hard deadline: 45 min timeout
๐ Long-Horizon ISMS Control Mapping
The three long-horizon workflows touch additional ISMS controls beyond the standard agentic security model:
| Control | Standard | How Applied |
|---|---|---|
| A.5.1 (Policies for information security) | ISO 27001:2022 | Long-horizon forecasts classified PUBLIC; no PII processed; GDPR DPIA short-circuit |
| A.5.30 (ICT readiness for business continuity) | ISO 27001:2022 | Graceful fallback if MCP/IMF unavailable โ uses cached vintage with annotation |
| A.8.8 (Management of technical vulnerabilities) | ISO 27001:2022 | IMF/SCB egress pins in Squid allowlist; .meta.json provenance sidecars for fetched data |
| A.8.28 (Secure coding) | ISO 27001:2022 | Prompt injection detection in safe-outputs layer; no user input reaches shell |
| A.8.30 (Outsourced development) | ISO 27001:2022 | gh-aw compiler generates hardened .lock.yml; human review mandatory |
| GV.SC (Supply chain risk management) | NIST CSF 2.0 | MCP server versions pinned; egress firewall restricts external calls |
| PR.DS (Data security) | NIST CSF 2.0 | Analysis artifacts written to branch-protected path; no secrets in output |
| DE.CM (Continuous monitoring) | NIST CSF 2.0 | Workflow timeout enforcement (45 min); GitHub Actions run-duration visible in dashboard |
| RS.AN (Incident analysis) | NIST CSF 2.0 | Failed analysis-gate logs structured error messages; workflow conclusion captured in Actions history |
| #4 (Secure configuration) | CIS Controls v8.1 | Harden-runner enforced; read-only permissions; concurrency guards |
| #16 (Application software security) | CIS Controls v8.1 | Five-layer safe-outputs validator; AI output sanitisation |
๐ Long-Horizon KPIs
| KPI | Definition | Target | Measurement |
|---|---|---|---|
| Legislative calendar coverage (quarter) | % of committee schedule + chamber sittings + proposition tabling deadlines forecast for the 90-day window | โฅ 85% | Cross-reference generated quarter-ahead against data.riksdagen.se calendar API |
| Legislative calendar coverage (year) | % of Riksmรถte + budget rhythm events forecast for 365-day window | โฅ 70% | Compare year-ahead output against known BP/VP/session dates |
| Legislative calendar coverage (cycle) | % of mandate-level milestones (elections, coalition formations, government reshuffles) forecast | โฅ 60% | Retrospective scoring after events occur |
| PIR roll-forward continuity | % of Priority Intelligence Requirements from prior horizon article with explicit obsolescence date or roll-forward in next article | โฅ 90% | Automated diff of PIR sections between consecutive articles |
| Vintage discipline rate | % of IMF WEO/FM citations that include projection-year stamp (e.g. "WEO Apr-2026 est.") | 100% | Regex validation in safe-outputs layer |
| Analysis gate pass rate | % of workflow runs that pass the analysis gate on first attempt | โฅ 80% | GitHub Actions run outcome data |
| Safe-outputs rejection rate | % of PRs rejected by safe-outputs validator | < 5% | PR merge/close statistics |
๐ก Stage 7: Monitoring & Infrastructure
flowchart LR
subgraph "๐ก Availability Monitoring"
Cron[โฐ Every 15 min] --> Check14[๐ Check 14 Languages]
Check14 --> Headers[๐ Security Headers]
Headers --> Result{Available?}
Result -->|No| CreateIssue[๐จ Create Issue]
Result -->|Yes| CloseIssue[โ
Close Issue]
end
subgraph "๐ Performance Monitoring"
Weekly[โฐ Weekly] --> LH[๐ Lighthouse CI]
LH --> Perf[โก Performance]
LH --> A11y[โฟ Accessibility]
LH --> SEO[๐ SEO]
LH --> BP[โ
Best Practices]
end
classDef schedule fill:#ffecb3,stroke:#f57f17,stroke-width:1.5px,color:black
classDef check fill:#c8e6c9,stroke:#2e7d32,stroke-width:1.5px,color:black
classDef alert fill:#ffccbc,stroke:#bf360c,stroke-width:1.5px,color:black
classDef success fill:#a5d6a7,stroke:#1b5e20,stroke-width:1.5px,color:black
class Cron,Weekly schedule
class Check14,Headers,LH,Perf,A11y,SEO,BP check
class CreateIssue alert
class CloseIssue,Result success
Uptime Monitor (uptime-monitor.yml):
- Every 15 minutes โ checks all 14 language homepages
- Validates security headers (HSTS, CSP, X-Frame-Options)
- Auto-creates/closes GitHub issues on outage/recovery
Lighthouse CI (lighthouse-ci.yml):
- Weekly + push/PR to main
- Targets: LCP < 2.5s, CLS < 0.1, Accessibility โฅ 90
๐ง Complete Workflow Inventory (54 Files โ 26 standard .yml + 14 agentic .md + 14 compiled .lock.yml)
Verification:
ls .github/workflows/yields 54 workflow files (55 entries including the directory README.md). This matches 26 standard workflow files + 14 agentic Markdown sources + 14 corresponding compiled lock files. Badges and PR checks are driven by the 26 standard.ymlplus the 14 compiled.lock.yml(GitHub Actions only executes the compiled artifacts).
๐ Security & Compliance (6 workflows)
| # | Workflow | File | Trigger | ISMS Controls |
|---|---|---|---|---|
| 1.1 | ๐ CodeQL Analysis | codeql.yml | Push, PR, Weekly | A.8.8, PR.DS-6, CIS 16.6 |
| 1.2 | ๐ฆ Dependency Review | dependency-review.yml | Pull requests | A.8.8, PR.DS-6, CIS 16.6 |
| 1.3 | โญ OpenSSF Scorecard | scorecards.yml | Push to main, Weekly | A.5.36, DE.CM-6, CIS 16.2 |
| 1.4 | ๐ท๏ธ Setup Labels | setup-labels.yml | Manual dispatch | A.5.37, PR.IP-1 |
| 1.5 | ๐ท๏ธ PR Labeler | labeler.yml | Pull requests | A.5.37, PR.IP-1 |
| 1.6 | ๐ท๏ธ ZAP DAST Scan | zap-scan.yml | Weekly schedule, manual dispatch | A.8.29, DE.CM-8, CIS 18 |
๐งช Testing & Validation (10 workflows)
| # | Workflow | File | Trigger | Coverage |
|---|---|---|---|---|
| 2.1 | ๐งช TypeScript & JS Testing | javascript-testing.yml | Push/PR (TS/JS/HTML) | TSC + Vitest + Cypress |
| 2.2 | ๐ TypeDoc Validation | jsdoc-validation.yml | Manual dispatch | TypeDoc generation + coverage |
| 2.3 | โ Quality Checks | quality-checks.yml | Push/PR to main | ESLint + HTMLHint + linkinator |
| 2.4 | ๐งน Knip Dead Code Check | knip.yml | Push/PR to main | Unused files, deps, binaries, duplicate exports (blocking); unused exports/types (informational) |
| 2.5 | ๐ Translation Validation | translation-validation.yml | Push/PR (HTML) | 14-language + RTL + hreflang |
| 2.6 | ๐ฅ๏ธ Test Dashboard | test-dashboard.yml | Push/PR (src/browser) | Dashboard Cypress E2E |
| 2.7 | ๐ Test Homepage | test-homepage.yml | Push/PR (src/browser) | Homepage Cypress E2E |
| 2.8 | ๐ฐ Test News | test-news.yml | Push/PR (news) | News pages Cypress E2E |
| 2.9 | ๐ Executive Brief Translation Checks | exec-brief-translation-checks.yml | Pull requests | Structural-parity + file-ownership merge gate for the executive-brief translation pipeline |
| 2.10 | ๐ค Test Article Headers | test-article-headers.yml | Manual dispatch | Audits rendered <head> metadata (title/description/keywords + OpenGraph/Twitter) via the shared computeArticleHeadMetadata composer |
๐ CIA Data Pipeline (1 workflow)
| # | Workflow | File | Trigger | Purpose |
|---|---|---|---|---|
| 3.1 | ๐ Update CIA CSV Data | update-cia-csv-data.yml | Nightly 03:30 UTC, manual dispatch | Refresh every already-tracked data/cia/** and cia-data/** CSV from upstream Hack23/cia sample-data (recursive basenameโpath index handles sub-folders), refresh production-stats.json, inject counts into all 14 index*.html; auto-PR on changes |
๐ Release & Deployment (3 workflows)
| # | Workflow | File | Trigger | Targets |
|---|---|---|---|---|
| 4.1 | ๐ Release with Attestations | release.yml | Push tags (v*), manual | SLSA + dual deploy |
| 4.2 | โ๏ธ Deploy to S3 | deploy-s3.yml | Push to main | AWS S3/CloudFront |
| 4.3 | ๐ Lighthouse CI | `lighthouse-ci.yml$ | \text{Push}/\text{PR}, \text{weekly} | \text{Performance} \text{audit} |
๐ค \text{Agentic} \text{Workflows} (14 \text{workflows} \times 2 \text{files} \text{each} = 28 \text{files})
\text{Each} \text{agentic} \text{workflow} \text{is} \text{authored} \text{as} \text{a} \text{Markdown} \text{source} ($.md
) and **compiled** to a hardened GitHub Actions workflow (.lock.yml) viacompile-agentic-workflows.yml. Only the.lock.ymlexecutes on the runner; the.md` is the source of truth, reviewed in PRs. Both files are SHA-pinned, run behind the Squid/iptables egress firewall, and route all write-side effects through the five-layer safe-outputs validator (sanitisation โ schema-validate โ policy-check โ human-review โ merge).Pipeline model: each per-type news workflow runs analysis โ aggregate โ translate (13 non-English languages) โ render (
--lang all, 14 HTML files) โ PR in a single agentic run. The legacy two-stepnews-article-generator(scaffold + later fill) workflow has been removed; articles are now derived directly fromanalysis/daily/$DATE/$SUB/artifacts viascripts/aggregate-analysis.tsโ per-language Markdown translation โscripts/render-articles.ts --lang all. The dedicatednews-translateworkflow is now a quality / catch-up workflow only โ it re-validates upstream translations and back-fills any language that an upstream run could not finish under its 60-min budget.
| # | Workflow | Source | Lock | Purpose |
|---|---|---|---|---|
| 5.1 | ๐ News Evening Analysis | news-evening-analysis.md | news-evening-analysis.lock.yml | Tier-C aggregation: end-of-day political analysis |
| 5.2 | ๐ก News Realtime Monitor | news-realtime-monitor.md | news-realtime-monitor.lock.yml | Tier-C aggregation: real-time political monitoring |
| 5.3 | ๐ News Motions | news-motions.md | news-motions.lock.yml | Single-type: motion tracking and reporting |
| 5.4 | ๐ News Committee Reports | news-committee-reports.md | news-committee-reports.lock.yml | Single-type: committee report coverage |
| 5.5 | ๐ฐ News Weekly Review | news-weekly-review.md | news-weekly-review.lock.yml | Tier-C aggregation: weekly political summary |
| 5.6 | ๐ News Monthly Review | news-monthly-review.md | news-monthly-review.lock.yml | Tier-C aggregation: monthly political review |
| 5.7 | ๐ฎ News Week Ahead | news-week-ahead.md | news-week-ahead.lock.yml | Tier-C aggregation: upcoming week preview |
| 5.8 | ๐ News Month Ahead | news-month-ahead.md | news-month-ahead.lock.yml | Tier-C aggregation: upcoming month preview |
| 5.9 | ๐๏ธ News Propositions | news-propositions.md | news-propositions.lock.yml | Single-type: government proposition coverage |
| 5.10 | โ News Interpellations | news-interpellations.md | news-interpellations.lock.yml | Single-type: interpellation debate tracking |
| 5.11 | ๐ News Translate (catch-up) | news-translate.md | news-translate.lock.yml | Quality / catch-up only: re-validates upstream translations, refines drift, back-fills languages an upstream run could not finish |
| 5.12 | ๐ News Quarter Ahead | news-quarter-ahead.md | news-quarter-ahead.lock.yml | Tier-C aggregation ร 1.7: 90-day parliamentary-season + Riksbank/SCB calendar |
| 5.13 | ๐ News Year Ahead | news-year-ahead.md | news-year-ahead.lock.yml | Tier-C aggregation ร 2.0: 365-day annual outlook anchored in IMF WEO Apr/Oct vintage |
| 5.14 | ๐ณ๏ธ News Election Cycle | news-election-cycle.md | news-election-cycle.lock.yml | Tier-C aggregation ร 2.5: full 4-year mandate; dispatch-only until runtime measured |
๐ ๏ธ Automation & Tooling (4 workflows)
| # | Workflow | File | Trigger | Purpose |
|---|---|---|---|---|
| 6.1 | ๐ง Compile Agentic Workflows | compile-agentic-workflows.yml | Push/PR touching news-*.md, manual | Compile .md sources โ .lock.yml via gh-aw compiler; enforces firewall + safe-outputs + SHA-pinning policy |
| 6.2 | ๐งน Agentics Maintenance | agentics-maintenance.yml | Scheduled + manual | Scheduled hygiene of agentic environment: stale branch cleanup, secret rotation hooks, runtime-cache eviction, agent-config validation |
| 6.3 | โป๏ธ Regenerate Articles | regenerate-articles.yml | Manual dispatch | Deterministic (no-AI) rebuild of every article.md (via aggregate-analysis) and every news/*.html page (via render-articles, all 14 languages) from the current analysis/daily/ tree; commits directly to main |
| 6.4 | ๐ค News Host-side PAT PR Fallback | news-pat-pr-fallback.yml | workflow_run after each news-* workflow | Single host-side recovery path for all 14 news workflows: replays the sandbox commit-handoff bundle under a host PAT to open/refresh the PR when the in-sandbox safe-outputs push could not deliver |
๐ก Monitoring & Infrastructure (2 workflows)
| # | Workflow | File | Trigger | Purpose |
|---|---|---|---|---|
| 7.1 | ๐ก Uptime Monitor | uptime-monitor.yml | Every 15 minutes | Site availability checks |
| 7.2 | ๐ค Copilot Setup Steps | copilot-setup-steps.yml | Push, manual | Agent environment setup |
๐งฉ Extracted Script Modules (scripts/agentic/)
The inline bash validation logic embedded in .github/prompts/05-analysis-gate.md has been extracted into strictly-typed TypeScript modules under scripts/agentic/. This bounded context provides:
| Module | Responsibility |
|---|---|
scripts/agentic/artifact-inventory.ts | Typed definitions for all 23 required artifacts (Families AโD), stub placeholders, evidence patterns, agency lists, dok_id patterns |
scripts/agentic/analysis-gate.ts | Gate validation checks 1โ9b: artifact existence, per-document coverage, stub detection, Mermaid validation, Family C/D structure, PIR sidecar, Statskontoret evidence |
scripts/agentic/index.ts | Barrel export โ single public surface for downstream consumers |
Key types exported:
ArtifactFamilyโ'A' | 'B' | 'C' | 'D' | 'E'ArtifactDefinitionโ filename, family, description, gate metadataGateCheckResultโ per-check pass/fail with message and artifact referenceGateValidationResultโ aggregate result with failure count
Design principles:
- Zero
anytypes โ explicit interfaces for all data structures - Gate module factored for readability (single-responsibility check functions)
- Co-located tests:
tests/agentic/gate-checks/*.test.ts(one suite per production check module),tests/agentic/gate-shared/*.test.ts(markdown helpers, file walkers), andtests/agentic/analysis-gate-integration.test.ts(end-to-end orchestrator scenarios) - ESLint clean with zero warnings
- No circular dependencies (barrel imports only)
Political Intelligence Validation Pipeline
The political intelligence generation and validation is a CI/CD concern enforced both in the prebuild chain and within agentic workflows:
Prebuild Chain (13 Steps)
generate-article-types-doc โ copy-vendor-mermaid โ aggregate-analysis โ render-articles โ
generate-news-indexes โ extract-news-metadata โ generate-sitemap-html โ
generate-political-intelligence โ generate-rss โ generate-sitemap โ
normalize-static-html-chrome โ backfill-translated-chrome โ strip-legacy-chrome-script-tags
Analysis Gate Enforcement
Every agentic news workflow MUST produce 23 analysis artifacts (Families A-D) and pass the analysis gate (scripts/agentic/analysis-gate.ts) before article rendering:
| Check | Validation | Script |
|---|---|---|
| 1 | Artifact existence (23 files) | analysis-gate.ts |
| 2 | No stub placeholders (AI_MUST_REPLACE, [REQUIRED], TODO:) | analysis-gate.ts |
| 3 | Minimum word count per artifact | analysis-gate.ts |
| 4 | Evidence citations (SWOT + significance) | analysis-gate.ts |
| 5 | Mermaid diagrams with colour configuration | analysis-gate.ts |
| 6 | Pass-2 evidence (revision proof via mtime/snapshot diff) | analysis-gate.ts |
| 7 | Cross-references between artifacts | analysis-gate.ts |
| 8 | Data-source connectivity audit | analysis-gate.ts |
| 9a | Political classification completeness | analysis-gate.ts |
| 9b | Agency evidence (Statskontoret recognised agencies) | analysis-gate.ts |
Additional Validation Scripts
| Script | Purpose | Trigger |
|---|---|---|
validate-methodology-reflection.ts | Validates methodology-reflection.md structure and required sections | Agentic workflow |
validate-quality-scores.cjs | Validates quality score thresholds | CI quality checks |
validate-article.ts | Validates article HTML structure and metadata | Prebuild + CI |
validate-news-translations.ts | Detects remaining data-translate markers | Translation validation workflow |
validate-translations.ts | Validates all translation files | CI |
Parliamentary Data Scripts
| Script | Purpose | Schedule |
|---|---|---|
download-parliamentary-data.ts | Download propositions, motions, betรคnkanden from Riksdag API | Nightly / on-demand |
fetch-voting-records.ts | Fetch voting records from Riksdag | Nightly |
fetch-calendar.ts | Fetch parliamentary calendar events | Nightly |
fetch-statskontoret.ts | Fetch Statskontoret agency data (headcount, budget) | Weekly |
fetch-rir-followups.ts | Fetch Riksrevisionen follow-up reports | Weekly |
scb-fetch.ts | Fetch SCB statistical data | On-demand |
imf-fetch.ts | Fetch IMF economic data (WEO, FM, IFS, DOTS) | On-demand |
๐ Workflow Security Architecture
Supply Chain Security
All workflows implement defense-in-depth:
flowchart TB
subgraph "๐ก๏ธ Defense-in-Depth Layers"
L1[๐ Layer 1: Permissions Hardening] --> L2[๐ Layer 2: SHA Pinning]
L2 --> L3[๐ก๏ธ Layer 3: Runner Hardening]
L3 --> L4[๐ฆ Layer 4: Dependency Scanning]
L4 --> L5[๐ Layer 5: Code Scanning]
L5 --> L6[๐ก Layer 6: Runtime Monitoring]
end
subgraph "๐ Controls per Layer"
L1 -.-> C1[Least privilege permissions]
L2 -.-> C2[Immutable action references]
L3 -.-> C3[step-security/harden-runner]
L4 -.-> C4[Dependency Review + Dependabot]
L5 -.-> C5[CodeQL + Scorecard]
L6 -.-> C6[Uptime + Lighthouse]
end
classDef layer fill:#e74c3c,stroke:#c0392b,stroke-width:1.5px,color:white
classDef control fill:#3498db,stroke:#2980b9,stroke-width:1.5px,color:white
class L1,L2,L3,L4,L5,L6 layer
class C1,C2,C3,C4,C5,C6 control
| Control | Implementation | ISMS Reference |
|---|---|---|
| ๐ Action SHA Pinning | Every uses: pinned to commit SHA | CIS 16.6 |
| ๐ก๏ธ Harden Runner | step-security/harden-runner with egress audit | NIST DE.CM-1 |
| ๐ Least Privilege | Minimal permissions: per-workflow | ISO A.8.3 |
| ๐ฆ Dependency Review | actions/dependency-review-action on PRs | CIS 16.4 |
| ๐ CodeQL Scanning | javascript-typescript language matrix | ISO A.8.8 |
| โญ Scorecard | OpenSSF Scorecard supply-chain analysis | NIST PR.DS-6 |
| ๐ Secret Scanning | Native GitHub secret scanning enabled | ISO A.8.24 |
Secrets Management
| Secret / Credential | Used By | Purpose |
|---|---|---|
GITHUB_TOKEN | Most workflows | Standard GitHub API access |
COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN | Copilot setup, agentic workflows | MCP server authentication |
AWS OIDC Role (GithubWorkFlowRole) | deploy-s3, release | Ephemeral credentials via id-token: write + role-to-assume |
| CloudFront Distribution ID | deploy-s3, release | Discovered dynamically from CloudFormation stack or origin lookup |
๐๏ธ gh-aw (GitHub Agentic Workflows) Security Architecture
Reference: gh-aw Architecture ยท SECURITY_ARCHITECTURE.md ยง Five-Layer Safe-Output Model
All 14 agentic workflows in this repository execute within the gh-aw runtime โ GitHub's purpose-built security substrate for AI-powered automation. gh-aw enforces a three-layer defense-in-depth model that contains agent actions within strict trust boundaries.
๐๏ธ Three-Layer Trust Model
flowchart TB
subgraph L1["๐ Layer 1: Substrate-Level Trust<br/>(Infrastructure โ enforced by gh-aw runtime)"]
direction LR
AWF["๐งฑ Agent Workflow Firewall<br/>(iptables + Squid proxy)"]
MCP_GW["๐ณ MCP Gateway<br/>(Docker container isolation)"]
API_P["๐ API Proxy<br/>(token-scoped access)"]
VM["๐ฅ๏ธ Runner VM<br/>(ephemeral, kernel-hardened)"]
end
subgraph L2["โ๏ธ Layer 2: Configuration-Level Trust<br/>(Compile-time โ enforced by gh aw compile)"]
direction LR
SCHEMA["๐ Schema Validation<br/>(workflow structure)"]
SHA["๐ Action SHA Pinning<br/>(immutable references)"]
SCAN["๐ Security Scanners<br/>(actionlint, zizmor, poutine)"]
STRICT["๐ Strict Mode<br/>(expression allowlisting)"]
end
subgraph L3["๐ก๏ธ Layer 3: Plan-Level Trust<br/>(Runtime โ enforced per execution)"]
direction LR
SO["๐ค SafeOutputs<br/>(buffered writes)"]
TD["๐ต๏ธ Threat Detection<br/>(AI-powered analysis)"]
CS["๐งน Content Sanitisation<br/>(@mention, URI, tag filters)"]
SR["๐ Secret Redaction<br/>(pre-upload scan)"]
end
L1 --> L2 --> L3
style L1 fill:#1a237e,color:#fff,stroke:#0d47a1,stroke-width:2px
style L2 fill:#004d40,color:#fff,stroke:#00695c,stroke-width:2px
style L3 fill:#b71c1c,color:#fff,stroke:#c62828,stroke-width:2px
๐งฑ Layer 1: Substrate-Level Trust (Infrastructure)
The gh-aw runtime provides hardware-enforced isolation for every agentic workflow run:
| Component | Icon | Function | Riksdagsmonitor Usage |
|---|---|---|---|
| Runner VM | ๐ฅ๏ธ | Ephemeral GitHub Actions VM with kernel-level isolation; destroyed after each run | All 14 agentic workflows execute in fresh VMs |
| Agent Workflow Firewall (AWF) | ๐งฑ | iptables redirects all HTTP/HTTPS through a Squid proxy with domain allowlist; non-allowlisted traffic is DROPped | 17 allowlisted domains (see Network egress allow-list) |
| MCP Gateway | ๐ณ | Each MCP server runs in an isolated Docker container; tool allowlisting; per-container network controls; secrets injected via env vars only | scb and world-bank servers in node:26-alpine containers |
| API Proxy | ๐ | Token-scoped access to GitHub APIs; prevents privilege escalation via stolen tokens | Agentic workflows get read-only repo + PR write only |
โ๏ธ Layer 2: Configuration-Level Trust (Compile-Time)
The gh aw compile command enforces security at compilation time:
| Control | Icon | What It Enforces | Riksdagsmonitor Implementation |
|---|---|---|---|
| Schema Validation | ๐ | Workflow YAML structure must conform to gh-aw schema (permissions, triggers, steps) | compile-agentic-workflows.yml validates all 14 .md sources |
| Expression Allowlisting | ๐ | Only safe expression patterns allowed in workflow definitions | Strict mode enabled; no ${{ }} in shell commands |
| Action SHA Pinning | ๐ | All uses: references pinned to immutable commit SHAs (not tags) | 100% SHA-pinned across all 54 workflow files |
| Security Scanners | ๐ | actionlint, zizmor, poutine run during compilation | Integrated into the compile workflow quality gate |
| Prompt Module Size Cap | ๐ | No single prompt module may exceed 550 lines | Enforced by compile workflow (prevents prompt injection via oversized modules) |
๐ก๏ธ Layer 3: Plan-Level Trust (Runtime)
Runtime controls that govern what the AI agent can actually do:
| Control | Icon | Mechanism | Riksdagsmonitor Implementation |
|---|---|---|---|
| SafeOutputs | ๐ค | Agent job has read-only permissions; all writes buffered as artifacts; separate detection job analyzes before execution | Five-layer validator: sanitise โ schema โ policy โ human review โ merge |
| Threat Detection Pipeline | ๐ต๏ธ | Separate job downloads agent artifacts; AI security agent analyzes for secret leaks, malicious patches, policy violations; blocking verdict gates output jobs | Analysis gate (checks 1โ9b) + methodology-reflection validator |
| Content Sanitisation | ๐งน | @mention neutralisation, bot trigger protection, XML/HTML tag conversion, URI filtering (HTTPS-only from trusted domains), content size limits (0.5 MB / 65k lines) | rehype-sanitize allow-list + Mermaid securityLevel: 'strict' |
| Integrity Filtering | ๐ | Controls which GitHub content the agent can access based on author trust and merge status | Repository scoped โ merged > approved > unapproved |
| Secret Redaction | ๐ | Automatic scanning of /tmp/gh-aw for secrets before artifact upload; partial visibility (first 3 chars + ***) | Enforced by gh-aw runtime for all 14 workflows |
๐ SafeOutputs Execution Flow
sequenceDiagram
participant Agent as ๐ค AI Agent (read-only)
participant Buffer as ๐ฆ Artifact Buffer
participant Detect as ๐ต๏ธ Threat Detection Job
participant Gate as โ Analysis Gate
participant Output as ๐ค Safe Output Jobs
participant Human as ๐ค Human Reviewer
Agent->>Buffer: Write analysis artifacts + article
Note over Agent,Buffer: Agent has NO write permissions<br/>All output buffered as workflow artifacts
Buffer->>Detect: Download artifacts for analysis
Detect->>Detect: AI security scan (secret leaks, malicious patches)
Detect->>Gate: Structural validation (checks 1โ9b)
alt Detection PASS + Gate PASS
Gate->>Output: Authorize safe output execution
Output->>Output: create_pull_request (sanitised content)
Output->>Human: PR ready for review
Human->>Human: Approve or reject
else Detection FAIL or Gate FAIL
Gate--xOutput: โ Blocked โ no PR created
Note over Gate,Output: Fail-closed: entire workflow fails
end
๐ gh-aw Security Components Applied to Riksdagsmonitor
flowchart LR
subgraph "14 Agentic News Workflows"
W1["news-propositions"]
W2["news-motions"]
W3["news-committee-reports"]
W4["โฆ + 11 more"]
end
subgraph "gh-aw Security Substrate"
FW["๐งฑ AWF<br/>Squid + iptables<br/>17 domains allowed"]
MCP["๐ณ MCP Gateway<br/>3 containerised servers"]
SO["๐ค SafeOutputs<br/>5-layer validator"]
TD["๐ต๏ธ Threat Detection<br/>AI + structural gates"]
SR["๐ Secret Redaction<br/>Pre-upload scan"]
end
subgraph "Riksdagsmonitor Controls"
AG["โ Analysis Gate<br/>Checks 1โ9b"]
MR["๐ Methodology<br/>Reflection Validator"]
PR["๐ค Human PR Review<br/>CODEOWNERS"]
end
W1 & W2 & W3 & W4 --> FW
FW --> MCP
MCP --> SO
SO --> TD
TD --> AG
AG --> MR
MR --> PR
style FW fill:#1a237e,color:#fff
style MCP fill:#004d40,color:#fff
style SO fill:#b71c1c,color:#fff
style TD fill:#e65100,color:#fff
style SR fill:#4a148c,color:#fff
style AG fill:#880e4f,color:#fff
๐ gh-aw Security Layer Summary
| Layer | Trust Boundary | Enforced By | Bypass Resistance | ISMS Mapping |
|---|---|---|---|---|
| ๐ L1: Substrate | Infrastructure | gh-aw runtime (VM + kernel + AWF + MCP Gateway) | Hardware isolation; iptables DROP rules; container sandboxing | ISO A.8.22 (Network segregation), NIST PR.AC-5, CIS #13 |
| โ๏ธ L2: Configuration | Compilation | gh aw compile + security scanners | Schema validation; SHA immutability; scanner verdicts | ISO A.8.28 (Secure coding), NIST PR.DS-6, CIS #16.6 |
| ๐ก๏ธ L3: Plan | Runtime | SafeOutputs + threat detection + sanitisation | Permission separation; AI-powered analysis; fail-closed gates | ISO A.8.25 (SDLC), NIST DE.CM-4, CIS #16.10 |
๐ ISMS Compliance Mapping
ISO 27001:2022 Controls
| Control | Workflow(s) | Implementation |
|---|---|---|
| A.5.33 โ Protection of records | update-cia-csv-data | Git audit trail, source attribution, automated PR review |
| A.5.36 โ Conformity with policies | scorecards | OpenSSF automated compliance |
| A.5.37 โ Documented procedures | All | Workflow YAML as executable documentation |
| A.8.3 โ Information lifecycle | update-cia-csv-data | Nightly upstream refresh, change-detection, PR-gated commits |
| A.8.8 โ Vulnerability management | codeql, dependency-review | Automated scanning |
| A.8.10 โ Information deletion | update-cia-csv-data | Branch auto-delete after PR merge |
| A.8.19 โ Security in use | All | HTTPS-only, SRI, CSP |
| A.8.24 โ Secret scanning | GitHub native | Automated secret detection |
| A.8.31 โ Separation of environments | release | Staging โ production pipeline |
| A.8.32 โ Change management | quality-checks, testing | Quality gates before merge |
NIST CSF 2.0 Functions
| Function | Workflow(s) | Implementation |
|---|---|---|
| GV (Govern) | setup-labels, ISMS documentation | Policy enforcement through automation |
| ID (Identify) | scorecards, dependency-review | Asset and vulnerability identification |
| PR (Protect) | codeql, harden-runner, SHA pinning | Security controls implementation |
| DE (Detect) | uptime-monitor, update-cia-csv-data | Continuous monitoring and upstream change detection |
| RS (Respond) | Incident auto-creation on outage | Automated incident response |
| RC (Recover) | Auto-close incidents on recovery | Automated recovery verification |
CIS Controls v8.1
| Control | Workflow(s) | Implementation |
|---|---|---|
| 2.2 โ Software inventory | release (SBOM) | Automated SBOM generation |
| 3.1 โ Data inventory | update-cia-csv-data | Explicit tracked-file discovery + recursive upstream index |
| 3.14 โ Data integrity | update-cia-csv-data | Byte-level diff vs upstream + PR review gate |
| 16.2 โ Software security | scorecards | Supply chain assessment |
| 16.4 โ Dependency security | dependency-review | Vulnerability scanning |
| 16.6 โ Application security | codeql | Static analysis |
| 16.10 โ Vulnerability remediation | Dependabot + codeql | Automated patching |
๐งฐ Cache and External-Registry Resilience Standard
Cache Strategy (standard workflows)
- Primary cache mechanism:
actions/setup-nodebuilt-in npm cache (cache: 'npm'), with explicitcache-dependency-pathincluding:package-lock.json- the owning workflow file path (for per-workflow cache key uniqueness)
- Single direct
actions/cacheusage: onlydependency-review.yml(apt archive cache), pinned to:actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- Cache invalidation: key version prefixes (e.g.,
-v2-) are used to force expiration of prior cache generations when strategy changes. - Cache TTL note: GitHub Actions does not support per-workflow explicit cache expiration/TTL configuration; retention is managed by the GitHub cache eviction policy and repository cache storage limits (10 GB per repository).
Resilience requirements (registry / apt / browser tooling)
- Add retry + exponential backoff for
apt-get updateandapt-get installin workflows that install system dependencies. - Add retry + npm fetch-retry tuning (
fetch-retries=5,fetch-retry-mintimeout=20000,fetch-retry-maxtimeout=120000) for global npm installs andnpm ciin setup-heavy workflows. - Add step-level
timeout-minuteson dependency-install steps most exposed to external outage/hanging behavior. - Prefer browser/binary installs without extra apt dependency fetches where possible (e.g., Playwright browser-only install).
๐ ๏ธ Workflow Troubleshooting Guide
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
| ๐ด TypeScript type-check fails | Missing module or incorrect import | Verify tsconfig.browser.json includes the file; run npx tsc --project tsconfig.browser.json --noEmit locally |
| ๐ด Workflow not triggering on TS changes | Missing path filter | Add '**/*.ts' and 'src/browser/**' to path filters |
| ๐ด Node version cannot run .ts scripts | Older Node.js version | Node 26 has native TS type-stripping; verify node -e "console.log(process.features.typescript)" outputs "strip" |
| ๐ด Harden Runner egress failures | New network endpoints accessed | Review egress report and add legitimate endpoints to allowed-endpoints |
| ๐ด Lighthouse CI failures | Performance regression | Check Lighthouse HTML report artifact; optimize images, reduce CSS, fix color contrast |
| ๐ด Data pipeline skipping fetch | Data freshness < 23 hours | Use force_refresh: true input for manual dispatch |
| ๐ด Agentic lock files outdated | .md source edited but not compiled | Run gh aw compile .github/workflows/<name>.md and commit .lock.yml |
| ๐ด Translation validation failing | Missing hreflang or language purity | Run npm run validate-translations locally |
| ๐ด Deploy-S3 CloudFront invalidation | OIDC role trust or IAM permissions misconfigured, or CloudFront distribution ID lookup from CloudFormation failed | Verify GitHub OIDC provider + role trust policy, ensure the assumed role has required CloudFront/S3/CloudFormation permissions, and confirm the workflow step that discovers the distribution ID from the CloudFormation stack/origin is succeeding |
๐ Workflow Metrics
Key Performance Indicators
| Metric | Target | Actual | Status |
|---|---|---|---|
| Test Count | > 1000 | 7,500+ | โ |
| Test Pass Rate | 100% | 100% | โ |
| TypeScript Errors | 0 | 0 | โ |
| ESLint Errors | 0 | 0 | โ |
| Build Time | < 5s | 3.4s | โ |
| Test Duration | Tracked in CI | 139s local full suite | โ |
| Action SHA Pinning | 100% | 100% | โ |
| Harden Runner | All workflows | All | โ |
| Language Coverage | 14 | 14 | โ |
| Agentic Workflows | 14 | 14 | โ |
๐ References
ISMS Documentation
- Hack23 ISMS-PUBLIC
- Secure Development Policy
- Threat Modeling
- Vulnerability Management
- Change Management
- Network Security Policy
GitHub Documentation
Related Documentation
- ARCHITECTURE.md โ C4 architecture models
- SECURITY_ARCHITECTURE.md โ Security controls
- THREAT_MODEL.md โ STRIDE threat analysis
- DATA_MODEL.md โ Data entities and relationships
- FLOWCHART.md โ Business process flows
- STATEDIAGRAM.md โ System state transitions
- MINDMAP.md โ System conceptual maps
- SWOT.md โ Strategic analysis
- CRA-ASSESSMENT.md โ EU Cyber Resilience Act conformity
- FUTURE_WORKFLOWS.md โ Future workflow projections
- AGENTS.md โ Custom agent reference (23 agents)
- SKILLS.md โ Skill definitions (92 skills)
External Tools
- step-security/harden-runner โ Workflow security
- OpenSSF Scorecard โ Supply chain security
- Lighthouse CI โ Performance monitoring
- TypeDoc โ TypeScript API documentation
๐ Document Owner: CEO | ๐ Version: 7.6 | ๐ Last Updated: 2026-06-02 (UTC) ๐ Review Cycle: Quarterly | โฐ Next Review: 2026-09-02 ๐ข Classification: Public | ๐๏ธ Owner: Hack23 AB (Org.nr 5595347807)
๐ Hack23 Ecosystem
| ๐ Platforms | ๐ฆ Open-Source Projects | ๐ก๏ธ Governance & Standards |
|---|---|---|
|
๐ณ๏ธ Riksdagsmonitor โ Swedish Parliament intelligence ๐ช๐บ EU Parliament Monitor โ European coverage ๐ต๏ธ Citizen Intelligence Agency โ political-data engine ๐ Hack23 AB โ corporate site ๐ฐ Hack23 Blog โ engineering & policy ๐ผ Hack23 on LinkedIn |
๐ณ๏ธ Hack23/riksdagsmonitor ๐ต๏ธ Hack23/cia ๐ช๐บ Hack23/euparliamentmonitor ๐ Hack23/european-parliament-mcp โ Hack23/cia-compliance-manager ๐ฅ Hack23/black-trigram ๐ Hack23/homepage |
๐ก๏ธ Hack23 ISMS-PUBLIC โ public ISMS ๐ Information Security Policy ๐ค AI Policy ๐งช Secure Development Policy ๐ฏ Threat Modeling Policy โ ๏ธ Vulnerability Management ๐ท๏ธ Classification Framework |
๐ณ๏ธ Empower citizens ยท ๐ Strengthen democratic accountability ยท ๐ต๏ธ Illuminate the political process
ยฉ 2008โ2026 Hack23 AB (Org.nr 559534-7807) ยท Maintainer: James Pether Sรถrling, CISSP CISM