⚙️ .github/workflows/

June 22, 2026 · View on GitHub

This directory holds 50 workflow files (22 standard .yml + 14 agentic Markdown sources + 14 compiled .lock.yml siblings) that power Riksdagsmonitor's CI/CD, security, data pipeline, agentic news generation, and monitoring.

Canonical long-form workflow reference: WORKFLOWS.md at the repository root — version matrices, Mermaid pipeline diagrams, ISMS control mapping, troubleshooting, and KPIs. Agentic workflow contract (imports, analysis gate, 23-artifact baseline): .github/prompts/README.md.


📊 File inventory at a glance

File kindCountNotes
Standard GitHub Actions (*.yml, not *.lock.yml)22Run natively on the GitHub Actions runner
Agentic workflow sources (news-*.md)14Authored in Markdown with gh-aw frontmatter + prompt imports
Agentic workflow compiled lock files (news-*.lock.yml)14Auto-generated by compile-agentic-workflows.yml — these are what actually execute
Total50Verify with `ls .github/workflows/

Only the compiled .lock.yml files run. The .md sources are the source of truth and are reviewed in PRs; lock files are regenerated via the gh aw compile CLI.


🔐 Security & Compliance (5)

FileTriggerPurpose
codeql.ymlPush, PR, weeklyCodeQL SAST — javascript-typescript matrix
dependency-review.ymlPull requestsSCA gate — blocks PRs on critical/high vulnerabilities
scorecards.ymlPush to main, weeklyOpenSSF Scorecard supply-chain assessment
setup-labels.ymlManual dispatchRepository label management (.github/labeler.yml source)
labeler.ymlPull requestsAuto-label PRs from .github/labeler.yml patterns

🧪 Testing & Validation (8)

FileTriggerPurpose
javascript-testing.ymlPush/PR on TS/JS/HTML/configTypeScript type-check + Vitest (2 890 tests) + Vite build
jsdoc-validation.ymlManual dispatchTypeDoc generation + coverage report
quality-checks.ymlPush/PR to mainESLint + HTMLHint + linkinator (parallel jobs)
knip.ymlPush/PR to mainKnip dead-code detector — blocks on unused files / dependencies / binaries / duplicate exports; reports unused exports & types informationally
translation-validation.ymlPush/PR on HTML14-language completeness + RTL + hreflang
test-dashboard.ymlPush/PR on dashboardsCypress E2E for dashboard pages
test-homepage.ymlPush/PR on homepageCypress E2E for the 14 index*.html homepages
test-news.ymlPush/PR on news/**Cypress E2E for news article pages

🚀 Release & Deployment (3)

FileTriggerPurpose
release.ymlTag v*, manualSLSA provenance + SBOM + dual deploy (S3 + GitHub Pages)
deploy-s3.ymlPush to mainAWS S3 sync + CloudFront invalidation via OIDC
lighthouse-ci.ymlPush/PR, weeklyLighthouse CI: performance, a11y, SEO, best practices

📊 Data Pipeline (1)

FileTriggerPurpose
update-cia-csv-data.ymlNightly 03:30 UTC, manualRefresh every tracked data/cia/** + cia-data/** CSV from upstream Hack23/cia; refresh production-stats.json; inject counts into 14× index*.html; open a single PR on changes

🤖 Agentic News Generation (14 × 2 = 28 files)

Each agentic workflow is a pair: an authored .md source + a compiled .lock.yml. The source imports bounded-context prompt modules from .github/prompts/. The compiled lock file is hardened (SHA-pinned actions, egress firewall, five-layer safe-outputs) and is what GitHub Actions actually runs.

Article-type workflows (single-type, 23-artifact baseline)

#Source (.md)Lock (.lock.yml)SchedulePrimary MCP data
1news-committee-reports.mdnews-committee-reports.lock.ymlMon–Fri 04:00 UTCget_betankanden, search_voteringar, search_anforanden, get_propositioner
2news-propositions.mdnews-propositions.lock.ymlMon–Fri 05:00 UTCget_propositioner, search_dokument_fulltext, search_anforanden
3news-motions.mdnews-motions.lock.ymlMon–Fri 06:00 UTCget_motioner, search_dokument_fulltext, search_anforanden
4news-interpellations.mdnews-interpellations.lock.ymlMon–Fri 07:00 UTCget_interpellationer, search_anforanden, get_calendar_events

Aggregation & prospective workflows (Tier-C, 23-artifact baseline; year-ahead gate-blocking = 24, mandated = 26; election-cycle gate-blocking = 28)

#Source (.md)Lock (.lock.yml)SchedulePurpose
5news-realtime-monitor.mdnews-realtime-monitor.lock.ymlMon–Fri 10:00 + 14:00 UTC, weekends 12:00Breaking events, urgency classification
6news-evening-analysis.mdnews-evening-analysis.lock.ymlMon–Fri 18:00, Sat 16:00 UTCDaily parliamentary pulse, coalition cohesion
7news-week-ahead.mdnews-week-ahead.lock.ymlFri 07:00 UTCProspective week preview; IMF WEO T+5 economic outlook
8news-month-ahead.mdnews-month-ahead.lock.yml1st of month 08:00 UTCMonthly legislative pipeline + pinned IMF projection vintage
9news-quarter-ahead.mdnews-quarter-ahead.lock.yml1st + 15th of month 09:00 UTC90-day parliamentary-season + Riksbank/SCB calendar; long-horizon-forecasting × 1.7
10news-year-ahead.mdnews-year-ahead.lock.yml5 Jan + 5 Jul 09:00 UTC365-day annual outlook anchored in IMF WEO Apr/Oct vintage; PESTLE gate-blocking (LH-4); wildcards + SWOT mandated by registry; × 2.0
11news-election-cycle.mdnews-election-cycle.lock.ymlworkflow_dispatch (cron 0 9 13 3,9 * declared but disabled until runtime measured)Full 4-year mandate; current Tidö + next post-2026 cycle; 28-artifact contract (23 + 5 blocking supplementary via LH-4 + LH-5); × 2.5
12news-weekly-review.mdnews-weekly-review.lock.ymlSat 09:00 UTCWeek-over-week trends, throughput metrics
13news-monthly-review.mdnews-monthly-review.lock.yml28th 10:00 UTCMonthly retrospective, party productivity rankings

Manual & translation workflows

#Source (.md)Lock (.lock.yml)SchedulePurpose
14news-translate.mdnews-translate.lock.ymlDaily 09:00 + 14:00 + 19:00 UTCTranslate analysis/daily/**/executive-brief.md into executive-brief_<lang>.md for the 13 non-English target languages (default batch: 3 sources × 13 languages = 39 files/run)

Every news workflow imports the bounded-context prompt modules in this exact order (full contract in .github/prompts/README.md):

  1. ../prompts/00-base-contract.md — role, ethics, GDPR/ISMS, AI-FIRST rule
  2. ../prompts/01-bash-and-shell-safety.md — AWF-safe shell patterns, UTF-8
  3. ../prompts/02-mcp-access.md — MCP server inventory + health gate
  4. ../prompts/03-data-download.md — download pipeline, manifest
  5. ../prompts/04-analysis-pipeline.md — methodologies, templates, 23 required artifacts (Family A–D), Pass 1 + Pass 2
  6. ../prompts/05-analysis-gate.mdsingle blocking gate — no article until it passes
  7. ../prompts/06-article-generation.md — article sections, banned patterns, visualisation, translations
  8. ../prompts/07-commit-and-pr.md — stage → commit → exactly one create_pull_request
  9. (Tier-C workflows only) ../prompts/ext/tier-c-aggregation.md — depth multipliers, cross-type synthesis, higher article floor (same 23 artifacts)

Common tool surface (every news-*.md)

Every news workflow declares the same tool & runtime surface for parity, resilience, and full gh-aw v0.74.3 capability coverage:

FieldValuePurpose
runtimes.node.version"26"Pinned Node 26 for IMF CLI + render scripts
engine.id / engine.modelcopilot / claude-opus-4.8 (13 analysis/article workflows); claude-sonnet-4.6 (news-translate only)Opus reasoning model for the 23-artifact analysis pipeline; the high-volume translation fan-out keeps the faster Sonnet model. (Sonnet was the repo-wide baseline through v0.74.3; GPT-5.4 / GPT-5.4-mini eligibility resolved upstream per release notes #31695 + #32197 but not yet A/B-tested here.)
engine.mcp.session-timeout1h removedWas added in gh-aw v0.71.3 and rejected by MCP Gateway v0.3.1. v0.74.3 lock files now ship MCP Gateway v0.3.9; re-acceptance has not yet been validated on this repo, so the field stays removed until verified.
tools.github.toolsets[all]Full GitHub MCP surface (issues, PRs, repos, code-search, actions, releases, discussions, …); see github-tools.md
tools.bash / tools.edit / tools.web-fetch / tools.agentic-workflowsenabledFull local tool surface; web-fetch reaches non-MCP public sources (statskontoret.se, riksdagsmonitor.com) through the AWF firewall
tools.cache-memorykeyed by news-${workflow}-${article_date}; best-effort cache persistence aligned with a 14-day recovery windowResilience knob — analysis artifacts persisted at /tmp/gh-aw/cache-memory/; may be restored on the next run if the previous PR failed and the cache entry is still available (see 07-commit-and-pr.md §Cache-memory recovery)
tools.playwrightenabled in news-evening-analysis + news-realtime-monitor onlyLive HTML validation for tier-C aggregation runs
features.mcp-gatewaytrueRoutes all MCP traffic through the gh-aw mcp-gateway (single audit point)
timeout-minutes60Job ceiling measured from job start; agent phases target completion by agent minute 40, PR by agent minute 42 (hard 45) to reserve setup/safe-output headroom
safe-outputs.create-pull-request.fallback-as-issuetrue (explicit)If org disables Actions PR creation, fall back to an issue + branch link instead of failing
safe-outputs.create-pull-request.if-no-changeswarnEmpty patches emit a warning instead of failing the run (e.g. duplicate-date dispatches)
network.allowednode, github, defaults + explicit Docker Hub hosts (docker.io, registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com) + IMF/SCB/Riksdag/Statskontoret/site domainsEcosystem identifiers preferred per upstream network.md. The broad containers ecosystem (which would also permit ghcr.io, quay.io, gcr.io, mcr.microsoft.com, pkgs.k8s.io, …) is deliberately omitted to keep least-privilege egress; only the minimal Docker Hub hosts actually required to resolve node:26-alpine for the SCB and World Bank MCP servers are enumerated. Any future switch to ghcr.io, quay.io, or other registries must add the specific hosts and be reviewed against the egress allowlist policy before merge.
permissionscontents: read, issues: read, pull-requests: read, actions: read, discussions: read, security-events: read, copilot-requests: writeLeast-privilege agent token; write capabilities live exclusively in the safe-outputs runner job. copilot-requests: write enables GitHub Actions token-based Copilot inference (COPILOT_GITHUB_TOKEN: ${{ github.token }} in the compiled lock file) so the Copilot engine no longer needs a personal-access-token secret. Requires org-level centralized Copilot billing — see gh-aw billing reference.

Accepted compile warnings

gh aw compile reports one expected, reviewed warning per news-*.md workflow (14 total). Compilation is green — 0 error(s) — and these warnings are an accepted design decision, not a defect:

⚠ Warning: secrets expressions detected in 'steps' section may be leaked to the agent job.
  Found: ${{ secrets.IMF_SDMX_SUBSCRIPTION_KEY }}.
  Consider moving operations requiring secrets to a separate job outside the agent job.

Why it is expected. Every news workflow forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to the news-prewarm composite action via a with: input in the steps: section. The key is deliberately propagated into the agent job (exported to $GITHUB_ENV, then inherited by the firewalled agent shell via awf --env-all) because the agent's bash tool makes live authenticated IMF SDMX 3.0 calls (tsx scripts/imf-fetch.ts sdmx … for IFS / BOP / DOTS / GFS_COFOG / MFS_IR / PCPS / ER). This is the documented economic-data architecture — see .github/aw/ECONOMIC_DATA_CONTRACT.md, .github/prompts/02-mcp-access.md, and analysis/imf/agentic-integration.md.

gh-aw emits this warning unconditionally for any secrets.* reference in an injected step section when strict: false (every news workflow sets strict: false to permit the trusted custom MCP egress domain riksdag-regering-ai.onrender.com). In strict mode a with: binding on a uses: step would instead be treated as a "safe binding" and clear the warning, but strict mode also forbids the custom network domain, job write permissions, and the bash wildcard tools these workflows require — so flipping strict is not viable.

Why it is safe. The key is masked in logs (::add-mask:: inside news-prewarm) and registered in gh-aw's GH_AW_SECRET_NAMES redaction list (the compiled Redact secrets in logs step), so it is scrubbed from artifacts and run logs. It is the only non-engine secret in the agent job and is required for the workflow's core function.

If you ever need a zero-secrets-in-agent posture (gh-aw "Layer 2"), the warning can be removed legitimately only by moving all authenticated SDMX fetching into a separate pre-fetch job that uploads data/imf-*.json artifacts for the agent to consume — a re-architecture that retires agent-side live SDMX calls and requires coordinated updates to the IMF contract and prompts.

v0.74.3 capabilities — adoption status

Tracking grid for the features called out in the gh-aw v0.74.3 release notes. All 14 news-*.lock.yml files compile against v0.74.3 today; the rows below classify each new capability as adopted, planned (follow-up PR), or non-applicable.

v0.74.3 featureStatusNotes
Glob patterns in add-labels safe outputs (#32022)PlannedReplace hard-coded labels: [agentic-news, analysis-data] with agentic-* glob to allow agent-driven self-labelling of agentic-tier-c, agentic-long-horizon, agentic-election-cycle.
Issue Fields in safe outputs (#30846)PlannedMove severity / horizon-band / election-cycle metadata off labels into issue fields on uptime-monitor and PIR roll-forward issues.
Stable slash_command / label_command triggers (#32348)PlannedAdd /regen-news <date> <type> and regen-news label triggers to news-propositions / news-motions / news-committee-reports / news-interpellations.
aw-compat codemods (#32341): run-expression hoisting, engine pinning, toolset-permission synthesisAdoptedVerified clean: gh aw fix (dry-run) reports "No fixes needed" against all 14 news workflows on v0.74.3 (validated 2026-05-15). gh aw fix --list-codemods shows the highest registered codemod targeting our migration range introduced in v0.68.4 — there are no v0.71→v0.74 codemods that apply.
Warn-mode threat guardrails for safe outputs (#32399)PlannedTighten safe-outputs.threat-detection.continue-on-error: true → warn-mode with structured warning ingested into analysis-quality.md.
Agent compatibility matrix and validation (#32396)PlannedDeclare agent-compatibility: matrix: claude-sonnet-4.6 accepted; gpt-5.4, gpt-5.4-mini opt-in after A/B test.
Enhanced OTel spans + Grafana MCP shared component (#32425, #32340)PlannedAdd Grafana MCP to news-evening-analysis + news-realtime-monitor; pipe agent-phase timings and gate-pass/fail counts.
excessivefuncparams linter (#32402)PlannedRun against scripts/imf-fetch.ts, scripts/aggregate-analysis.ts, scripts/render-articles.ts; refactor opportunity, non-blocking.
experiments.* valid in runtime-import expressions (#32375)PlannedExpose experiments.tier_c_compression, experiments.lh_pestle_blocking, experiments.cycle_rollover_window.
MCP Gateway upgrade to ghcr.io/github/gh-aw-mcpg:v0.3.9AdoptedNow present in every news-*.lock.yml manifest. Field-level effects (e.g. engine.mcp.session-timeout re-acceptance) still pending re-validation.
GPT-5.4 / GPT-5.4-mini fixes (#31695, #32197)AvailableModels now compatible; not yet A/B-tested against claude-sonnet-4.6 on this repo.
gh aw compile --staged (v0.74.2)PlannedAdopt in compile-agentic-workflows.yml for PR previews of the compiled .lock.yml.
REST API for agent session task creation (v0.74.2)AdoptedDefault in compiled .lock.yml files.
Higher default max-runs (100 → 500, v0.74.2)AdoptedInherited from compiler defaults; no explicit cap needed for current scheduling fan-out.

Tracker: Article-Generation.md §"Modularization roadmap" carries the per-feature follow-up PR titles.

🛠️ Automation & Tooling (4)

FileTriggerPurpose
compile-agentic-workflows.ymlPush/PR touching news-*.md, manualRun gh aw compile → regenerate .lock.yml; enforce firewall + safe-outputs + SHA-pinning
agentics-maintenance.ymlScheduled + manualHygiene of the agentic environment: stale branch cleanup, secret-rotation hooks, runtime-cache eviction
copilot-setup-steps.ymlPush, manualBootstrap GitHub Copilot coding-agent environment for this repo

📡 Monitoring & Infrastructure (1)

FileTriggerPurpose
uptime-monitor.ymlEvery 15 minutesAvailability checks for all 14 language homepages; auto-creates/closes GitHub issues on outage/recovery; validates HSTS/CSP/X-Frame-Options headers

🔄 Triggers at a glance

flowchart LR
  subgraph "⏰ Cron"
    C1[Every 15 min → uptime-monitor]
    C2[Nightly 03:30 UTC → update-cia-csv-data]
    C3[Mon-Fri 04:00-18:00 → news-* article + analysis]
    C4[Daily 09 + 14 + 19 UTC → news-translate (exec-brief markdown)]
    C5[Fri 07:00 → news-week-ahead]
    C6[Sat 09:00 → news-weekly-review]
    C7[28th 10:00 → news-monthly-review]
    C8[1st 08:00 → news-month-ahead]
    C9[1st + 15th 09:00 → news-quarter-ahead]
    C10[5 Jan + 5 Jul 09:00 → news-year-ahead]
    C11[Weekly → codeql + scorecards + lighthouse-ci]
  end
  subgraph "🔀 Event"
    E1[push/PR → quality-checks + knip + javascript-testing + translation-validation + codeql + test-*]
    E2[Tag v*.*.* → release]
    E3[push main → deploy-s3]
    E4[PR → dependency-review + labeler]
  end
  subgraph "👆 Manual"
    M1[workflow_dispatch → any workflow]
    M2[news-election-cycle → dispatch-only initially, until runtime measured]
  end
  style C3 fill:#0a0e27,stroke:#00d9ff,color:#e0e0e0
  style E2 fill:#1a1e3d,stroke:#ffbe0b,color:#e0e0e0

🔒 Universal security posture

Every workflow in this directory implements defence-in-depth — see WORKFLOWS.md §"Workflow Security Architecture" for the full matrix.

ControlHow it's enforced
step-security/harden-runnerFirst step of every job; egress audit/allow-list
SHA-pinned uses:100 % coverage — any third-party Action pinned to commit SHA
Least-privilege permissions:Default contents: read; only required scopes added
OIDC for AWSid-token: write + role-to-assume (no long-lived keys)
Five-layer safe outputs (agentic)Sanitise → schema-validate → policy-check → human-review → merge
Squid + iptables egress firewall (agentic)Only domains in network.allowed: reach the internet

🧭 Where to go next

I want to…Read
Understand a specific pipeline stage end-to-endWORKFLOWS.md
Author or modify an agentic news workflow.github/prompts/README.md + .github/skills/gh-aw-workflow-authoring/
Understand how safe outputs and the firewall work.github/skills/gh-aw-safe-outputs/ + .github/skills/gh-aw-firewall/
Compile .md.lock.yml locallyRun gh aw compile .github/workflows/<name>.md (workflow compile-agentic-workflows.yml does this in CI)
See ISMS control mappingWORKFLOWS.md §"ISMS Compliance Mapping"
Trace the analysis artifact contractanalysis/README.md + analysis/methodologies/README.md + analysis/templates/README.md

📋 Document owner: CEO | 🏷️ Classification: Public | 🔄 Review cycle: Quarterly